scummvm/scumm/resource_v7he.h
2005-10-18 01:30:26 +00:00

554 lines
14 KiB
C++

/* ScummVM - Scumm Interpreter
* Copyright (C) 2004-2005 The ScummVM project
*
* Parts of code heavily based on:
* icoutils - A set of programs dealing with MS Windows icons and cursors.
* Copyright (C) 1998-2001 Oskar Liljeblad
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* $Header$
*
*/
#if !defined(RESOURCE_V7HE_H) && !defined(DISABLE_HE)
#define RESOURCE_V7HE_H
namespace Scumm {
#define WINRES_ID_MAXLEN (256)
/*
* Definitions
*/
#define ACTION_LIST 1 /* command: list resources */
#define ACTION_EXTRACT 2 /* command: extract resources */
#define CALLBACK_STOP 0 /* results of ResourceCallback */
#define CALLBACK_CONTINUE 1
#define CALLBACK_CONTINUE_RECURS 2
#define MZ_HEADER(x) ((DOSImageHeader *)(x))
#define NE_HEADER(x) ((OS2ImageHeader *)PE_HEADER(x))
#define NE_TYPEINFO_NEXT(x) ((Win16NETypeInfo *)((byte *)(x) + sizeof(Win16NETypeInfo) + \
((Win16NETypeInfo *)x)->count * sizeof(Win16NENameInfo)))
#define NE_RESOURCE_NAME_IS_NUMERIC (0x8000)
#define STRIP_RES_ID_FORMAT(x) (x != NULL && (x[0] == '-' || x[0] == '+') ? ++x : x)
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
#define IMAGE_SIZEOF_SHORT_NAME 8
#define IMAGE_RESOURCE_NAME_IS_STRING 0x80000000
#define IMAGE_RESOURCE_DATA_IS_DIRECTORY 0x80000000
#define PE_HEADER(module) \
((Win32ImageNTHeaders*)((byte *)(module) + \
(((DOSImageHeader*)(module))->lfanew)))
#define PE_SECTIONS(module) \
((Win32ImageSectionHeader *)((byte *) &PE_HEADER(module)->optional_header + \
PE_HEADER(module)->file_header.size_of_optional_header))
#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
#define IMAGE_OS2_SIGNATURE 0x454E /* NE */
#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
#define IMAGE_OS2_SIGNATURE_LX 0x584C /* LX */
#define IMAGE_VXD_SIGNATURE 0x454C /* LE */
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
#if !defined (WIN32)
#define IMAGE_SCN_CNT_CODE 0x00000020
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
#define IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
#endif
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* (MIPS GP) */
#define IMAGE_DIRECTORY_ENTRY_TLS 9
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11
#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
#if !defined (WIN32)
#define RT_CURSOR 1
#define RT_BITMAP 2
#define RT_ICON 3
#define RT_MENU 4
#define RT_DIALOG 5
#define RT_STRING 6
#define RT_FONTDIR 7
#define RT_FONT 8
#define RT_ACCELERATOR 9
#define RT_RCDATA 10
#define RT_MESSAGELIST 11
#define RT_GROUP_CURSOR 12
#define RT_GROUP_ICON 14
#endif
#define RETURN_IF_BAD_POINTER(r, x) \
if (!check_offset(fi->memory, fi->total_size, fi->file->name(), &(x), sizeof(x))) \
return (r);
#define RETURN_IF_BAD_OFFSET(r, x, s) \
if (!check_offset(fi->memory, fi->total_size, fi->file->name(), x, s)) \
return (r);
class ResExtractor {
public:
ResExtractor(ScummEngine_v70he *scumm);
virtual ~ResExtractor();
void setCursor(int id);
virtual int extractResource(int id, byte **buf) { return 0; };
virtual int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
int *hotspot_x, int *hotspot_y, int *keycolor,
byte **palette, int *palSize) { return 0; };
enum {
MAX_CACHED_CURSORS = 10
};
struct CachedCursor {
bool valid;
int id;
byte *bitmap;
int w, h;
int hotspot_x, hotspot_y;
uint32 last_used;
byte *palette;
int palSize;
};
ScummEngine_v70he *_vm;
ResExtractor::CachedCursor *findCachedCursor(int id);
ResExtractor::CachedCursor *getCachedCursorSlot();
bool _arg_raw;
char _fileName[256];
CachedCursor _cursorCache[MAX_CACHED_CURSORS];
typedef Common::MemoryReadStream MemoryReadStream;
};
class Win32ResExtractor : public ResExtractor {
public:
Win32ResExtractor(ScummEngine_v70he *scumm);
~Win32ResExtractor() {};
int extractResource(int id, byte **data);
void setCursor(int id);
int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
private:
int extractResource_(const char *resType, char *resName, byte **data);
/*
* Structures
*/
#if !defined(__GNUC__)
#pragma START_PACK_STRUCTS
#endif
struct WinLibrary {
Common::File *file;
byte *memory;
byte *first_resource;
bool is_PE_binary;
int total_size;
};
struct WinResource {
char id[256];
void *this_;
void *children;
int level;
bool numeric_id;
bool is_directory;
};
struct Win32IconResDir {
byte width;
byte height;
byte color_count;
byte reserved;
};
struct Win32CursorDir {
uint16 width;
uint16 height;
};
struct Win32CursorIconDirEntry {
union {
Win32IconResDir icon;
Win32CursorDir cursor;
} res_info;
uint16 plane_count;
uint16 bit_count;
uint32 bytes_in_res;
uint16 res_id;
};
struct Win32CursorIconDir {
uint16 reserved;
uint16 type;
uint16 count;
Win32CursorIconDirEntry entries[1] GCC_PACK;
};
struct Win32CursorIconFileDirEntry {
byte width;
byte height;
byte color_count;
byte reserved;
uint16 hotspot_x;
uint16 hotspot_y;
uint32 dib_size;
uint32 dib_offset;
};
struct Win32CursorIconFileDir {
uint16 reserved;
uint16 type;
uint16 count;
Win32CursorIconFileDirEntry entries[1];
};
struct Win32BitmapInfoHeader {
uint32 size;
int32 width;
int32 height;
uint16 planes;
uint16 bit_count;
uint32 compression;
uint32 size_image;
int32 x_pels_per_meter;
int32 y_pels_per_meter;
uint32 clr_used;
uint32 clr_important;
};
struct Win32RGBQuad {
byte blue;
byte green;
byte red;
byte reserved;
};
struct Win32ImageResourceDirectoryEntry {
union {
struct {
#ifdef SCUMM_BIGENDIAN
unsigned name_is_string:1;
unsigned name_offset:31;
#else
unsigned name_offset:31;
unsigned name_is_string:1;
#endif
} s1;
uint32 name;
struct {
#ifdef SCUMM_BIG_ENDIAN
uint16 __pad;
uint16 id;
#else
uint16 id;
uint16 __pad;
#endif
} s2;
} u1;
union {
uint32 offset_to_data;
struct {
#ifdef SCUMM_BIG_ENDIAN
unsigned data_is_directory:1;
unsigned offset_to_directory:31;
#else
unsigned offset_to_directory:31;
unsigned data_is_directory:1;
#endif
} s;
} u2;
};
struct Win16NETypeInfo {
uint16 type_id;
uint16 count;
uint32 resloader; // FARPROC16 - smaller? uint16?
};
struct Win16NENameInfo {
uint16 offset;
uint16 length;
uint16 flags;
uint16 id;
uint16 handle;
uint16 usage;
};
struct OS2ImageHeader {
uint16 magic;
byte ver;
byte rev;
uint16 enttab;
uint16 cbenttab;
int32 crc;
uint16 flags;
uint16 autodata;
uint16 heap;
uint16 stack;
uint32 csip;
uint32 sssp;
uint16 cseg;
uint16 cmod;
uint16 cbnrestab;
uint16 segtab;
uint16 rsrctab;
uint16 restab;
uint16 modtab;
uint16 imptab;
uint32 nrestab;
uint16 cmovent;
uint16 align;
uint16 cres;
byte exetyp;
byte flagsothers;
uint16 fastload_offset;
uint16 fastload_length;
uint16 swaparea;
uint16 expver;
};
struct DOSImageHeader {
uint16 magic;
uint16 cblp;
uint16 cp;
uint16 crlc;
uint16 cparhdr;
uint16 minalloc;
uint16 maxalloc;
uint16 ss;
uint16 sp;
uint16 csum;
uint16 ip;
uint16 cs;
uint16 lfarlc;
uint16 ovno;
uint16 res[4];
uint16 oemid;
uint16 oeminfo;
uint16 res2[10];
uint32 lfanew;
};
struct Win32ImageFileHeader {
uint16 machine;
uint16 number_of_sections;
uint32 time_date_stamp;
uint32 pointer_to_symbol_table;
uint32 number_of_symbols;
uint16 size_of_optional_header;
uint16 characteristics;
};
struct Win32ImageDataDirectory {
uint32 virtual_address;
uint32 size;
};
struct Win32ImageOptionalHeader {
uint16 magic;
byte major_linker_version;
byte minor_linker_version;
uint32 size_of_code;
uint32 size_of_initialized_data;
uint32 size_of_uninitialized_data;
uint32 address_of_entry_point;
uint32 base_of_code;
uint32 base_of_data;
uint32 image_base;
uint32 section_alignment;
uint32 file_alignment;
uint16 major_operating_system_version;
uint16 minor_operating_system_version;
uint16 major_image_version;
uint16 minor_image_version;
uint16 major_subsystem_version;
uint16 minor_subsystem_version;
uint32 win32_version_value;
uint32 size_of_image;
uint32 size_of_headers;
uint32 checksum;
uint16 subsystem;
uint16 dll_characteristics;
uint32 size_of_stack_reserve;
uint32 size_of_stack_commit;
uint32 size_of_heap_reserve;
uint32 size_of_heap_commit;
uint32 loader_flags;
uint32 number_of_rva_and_sizes;
Win32ImageDataDirectory data_directory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
};
struct Win32ImageNTHeaders {
uint32 signature;
Win32ImageFileHeader file_header;
Win32ImageOptionalHeader optional_header;
};
struct Win32ImageSectionHeader {
byte name[IMAGE_SIZEOF_SHORT_NAME];
union {
uint32 physical_address;
uint32 virtual_size;
} misc;
uint32 virtual_address;
uint32 size_of_raw_data;
uint32 pointer_to_raw_data;
uint32 pointer_to_relocations;
uint32 pointer_to_linenumbers;
uint16 number_of_relocations;
uint16 number_of_linenumbers;
uint32 characteristics;
};
struct Win32ImageResourceDataEntry {
uint32 offset_to_data;
uint32 size;
uint32 code_page;
uint32 resource_handle;
};
struct Win32ImageResourceDirectory {
uint32 characteristics;
uint32 time_date_stamp;
uint16 major_version;
uint16 minor_version;
uint16 number_of_named_entries;
uint16 number_of_id_entries;
};
#if !defined(__GNUC__)
#pragma END_PACK_STRUCTS
#endif
/*
* Function Prototypes
*/
WinResource *list_resources(WinLibrary *, WinResource *, int *);
bool read_library(WinLibrary *);
WinResource *find_resource(WinLibrary *, const char *, const char *, const char *, int *);
byte *get_resource_entry(WinLibrary *, WinResource *, int *);
int do_resources(WinLibrary *, const char *, char *, char *, int, byte **);
bool compare_resource_id(WinResource *, const char *);
const char *res_type_string_to_id(const char *);
const char *res_type_id_to_string(int);
char *get_destination_name(WinLibrary *, char *, char *, char *);
byte *extract_resource(WinLibrary *, WinResource *, int *, bool *, char *, char *, bool);
int extract_resources(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, byte **);
byte *extract_group_icon_cursor_resource(WinLibrary *, WinResource *, char *, int *, bool);
bool decode_pe_resource_id(WinLibrary *, WinResource *, uint32);
bool decode_ne_resource_id(WinLibrary *, WinResource *, uint16);
WinResource *list_ne_type_resources(WinLibrary *, int *);
WinResource *list_ne_name_resources(WinLibrary *, WinResource *, int *);
WinResource *list_pe_resources(WinLibrary *, Win32ImageResourceDirectory *, int, int *);
int calc_vma_size(WinLibrary *);
int do_resources_recurs(WinLibrary *, WinResource *, WinResource *, WinResource *, WinResource *, const char *, char *, char *, int, byte **);
char *get_resource_id_quoted(WinResource *);
WinResource *find_with_resource_array(WinLibrary *, WinResource *, const char *);
bool check_offset(byte *, int, const char *, void *, int);
uint32 simple_vec(byte *data, uint32 ofs, byte size);
void fix_win32_cursor_icon_file_dir_endian(Win32CursorIconFileDir *obj);
void fix_win32_bitmap_info_header_endian(Win32BitmapInfoHeader *obj);
void fix_win32_cursor_icon_file_dir_entry_endian(Win32CursorIconFileDirEntry *obj);
void fix_win32_image_section_header(Win32ImageSectionHeader *obj);
void fix_os2_image_header_endian(OS2ImageHeader *obj);
void fix_win32_image_header_endian(Win32ImageNTHeaders *obj);
void fix_win32_image_data_directory(Win32ImageDataDirectory *obj);
};
class MacResExtractor : public ResExtractor {
public:
MacResExtractor(ScummEngine_v70he *scumm);
~MacResExtractor() { }
void setCursor(int id) ;
private:
int extractResource(int id, byte **buf);
bool init(Common::File in);
void readMap(Common::File in);
byte *getResource(Common::File in, const char *typeID, int16 resID, int *size);
int convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h,
int *hotspot_x, int *hotspot_y, int *keycolor, byte **palette, int *palSize);
struct ResMap {
int16 resAttr;
int16 typeOffset;
int16 nameOffset;
int16 numTypes;
};
struct ResType {
char id[5];
int16 items;
int16 offset;
};
struct Resource {
int16 id;
int16 nameOffset;
byte attr;
int32 dataOffset;
byte *name;
};
typedef Resource *ResPtr;
private:
int _resOffset;
int32 _dataOffset;
int32 _dataLength;
int32 _mapOffset;
int32 _mapLength;
ResMap _resMap;
ResType *_resTypes;
ResPtr *_resLists;
};
} // End of namespace Scumm
#endif