diff options
author | Eugene Sandulenko | 2004-06-24 20:20:35 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2004-06-24 20:20:35 +0000 |
commit | 6affa9e75afeac13afb233ba0351fc0e6e81c150 (patch) | |
tree | c17b8b4fe787f2a379f0a913912fdef6a5852c73 /scumm | |
parent | 088676cdb2ae3fc463812771de12745162c1e7a0 (diff) | |
download | scummvm-rg350-6affa9e75afeac13afb233ba0351fc0e6e81c150.tar.gz scummvm-rg350-6affa9e75afeac13afb233ba0351fc0e6e81c150.tar.bz2 scummvm-rg350-6affa9e75afeac13afb233ba0351fc0e6e81c150.zip |
Phase #3 of HE v7.0+ cursors. Now they show up correctly. Remove TODO item.
svn-id: r14034
Diffstat (limited to 'scumm')
-rw-r--r-- | scumm/resource_v7he.cpp | 82 | ||||
-rw-r--r-- | scumm/resource_v7he.h | 13 | ||||
-rw-r--r-- | scumm/script_v6.cpp | 2 |
3 files changed, 59 insertions, 38 deletions
diff --git a/scumm/resource_v7he.cpp b/scumm/resource_v7he.cpp index f0879a4383..53abdb3f60 100644 --- a/scumm/resource_v7he.cpp +++ b/scumm/resource_v7he.cpp @@ -53,19 +53,24 @@ Win32ResExtractor::Win32ResExtractor(ScummEngine *scumm) { snprintf(_fileName, 256, "%s.he3", _vm->getGameName()); } -byte *Win32ResExtractor::extractCursor(int id) { +void Win32ResExtractor::setCursor(int id) { char buf[20]; - byte *cursor = 0; + byte *cursorRes = 0, *cursor = 0; int cursorsize; + int w = 0, h = 0, hotspot_x = 0, hotspot_y = 0, keycolor = 0; snprintf(buf, 20, "%d", id); - cursorsize = extractResource("group_cursor", buf, cursor); + cursorsize = extractResource("group_cursor", buf, &cursorRes); - return 0; + convertIcons(cursorRes, cursorsize, &cursor, &w, &h, &hotspot_x, &hotspot_y, + &keycolor); + + _vm->setCursorHotspot(hotspot_x, hotspot_y); + _vm->grabCursorFromBuffer(cursor, w, h); } -int Win32ResExtractor::extractResource(const char *resType, char *resName, byte *data) { +int Win32ResExtractor::extractResource(const char *resType, char *resName, byte **data) { char *arg_language = NULL; const char *arg_type = resType; char *arg_name = resName; @@ -91,7 +96,7 @@ int Win32ResExtractor::extractResource(const char *resType, char *resName, byte fi.total_size = fi.file->size(); if (fi.total_size == -1) { - error("Cannot get size of file %s", fi.file->name()); + warning("Cannot get size of file %s", fi.file->name()); goto cleanup; } if (fi.total_size == 0) { @@ -115,10 +120,6 @@ int Win32ResExtractor::extractResource(const char *resType, char *resName, byte // verbose_printf("file is a %s\n", // fi.is_PE_binary ? "Windows NT `PE' binary" : "Windows 3.1 `NE' binary"); - /* warn about more unnecessary options */ - if (!fi.is_PE_binary && arg_language != NULL) - warning("%s: --language has no effect because file is 16-bit binary", fi.file->name()); - /* errors will be printed by the callback */ ressize = do_resources(&fi, arg_type, arg_name, arg_language, arg_action, data); @@ -170,18 +171,18 @@ const char *Win32ResExtractor::res_type_string_to_id(const char *type) { int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr, WinResource *type_wr, WinResource *name_wr, - WinResource *lang_wr, byte *data) { + WinResource *lang_wr, byte **data) { int size; bool free_it; const char *type; int32 id; - if (data) { + if (*data) { error("Win32ResExtractor::extract_resources() more than one cursor"); return 0; } - data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw); + *data = extract_resource(fi, wr, &size, &free_it, type_wr->id, (lang_wr == NULL ? NULL : lang_wr->id), _arg_raw); if (data == NULL) { warning("Win32ResExtractor::extract_resources() problem with resource extraction"); @@ -193,7 +194,7 @@ int Win32ResExtractor::extract_resources(WinLibrary *fi, WinResource *wr, if ((id = strtol(type_wr->id, 0, 10)) != 0) type = res_type_id_to_string(id); - warning("extractCursor(). Found cursor name: %s%s%s [size=%d]", + debugC(DEBUG_RESOURCE, "extractCursor(). Found cursor name: %s%s%s [size=%d]", get_resource_id_quoted(name_wr), (lang_wr->id[0] != '\0' ? " language: " : ""), get_resource_id_quoted(lang_wr), size); @@ -287,12 +288,12 @@ byte *Win32ResExtractor::extract_group_icon_cursor_resource(WinLibrary *fi, WinR if (get_resource_entry(fi, fwr, &iconsize) != NULL) { if (iconsize == 0) { - warning("%s: icon resource `%s' is empty, skipping", fi->file->name(), name); + debugC(DEBUG_RESOURCE, "%s: icon resource `%s' is empty, skipping", fi->file->name(), name); skipped++; continue; } if ((uint32)iconsize != icondir->entries[c].bytes_in_res) { - warning("%s: mismatch of size in icon resource `%s' and group (%d != %d)", + debugC(DEBUG_RESOURCE, "%s: mismatch of size in icon resource `%s' and group (%d != %d)", fi->file->name(), name, iconsize, 1, icondir->entries[c].bytes_in_res); } size += iconsize; /* size += icondir->entries[c].bytes_in_res; */ @@ -400,7 +401,7 @@ bool Win32ResExtractor::check_offset(byte *memory, int total_size, const char *n /* do_resources: * Do something for each resource matching type, name and lang. */ -int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, int action, byte *data) { +int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name, char *lang, int action, byte **data) { WinResource *type_wr; WinResource *name_wr; WinResource *lang_wr; @@ -425,7 +426,7 @@ int Win32ResExtractor::do_resources(WinLibrary *fi, const char *type, char *name int Win32ResExtractor::do_resources_recurs(WinLibrary *fi, WinResource *base, WinResource *type_wr, WinResource *name_wr, WinResource *lang_wr, - const char *type, char *name, char *lang, int action, byte *data) { + const char *type, char *name, char *lang, int action, byte **data) { int c, rescnt; WinResource *wr; uint32 size = 0; @@ -852,7 +853,8 @@ Win32ResExtractor::WinResource *Win32ResExtractor::find_resource(WinLibrary *fi, #define ROW_BYTES(bits) ((((bits) + 31) >> 5) << 2) -int Win32ResExtractor::convertIcons(byte *data, int datasize) { +int Win32ResExtractor::convertIcons(byte *data, int datasize, byte **cursor, int *w, int *h, + int *hotspot_x, int *hotspot_y, int *keycolor) { Win32CursorIconFileDir dir; Win32CursorIconFileDirEntry *entries = NULL; uint32 offset; @@ -861,7 +863,7 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { int matched = 0; MemoryReadStream *in = new MemoryReadStream(data, datasize); - if (!in->read(&dir, sizeof(Win32CursorIconFileDir))) + if (!in->read(&dir, sizeof(Win32CursorIconFileDir)- sizeof(Win32CursorIconFileDirEntry))) goto cleanup; fix_win32_cursor_icon_file_dir_endian(&dir); @@ -876,16 +878,17 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { entries = (Win32CursorIconFileDirEntry *)malloc(dir.count * sizeof(Win32CursorIconFileDirEntry)); for (c = 0; c < dir.count; c++) { - if (in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry))) + if (!in->read(&entries[c], sizeof(Win32CursorIconFileDirEntry))) goto cleanup; fix_win32_cursor_icon_file_dir_entry_endian(&entries[c]); if (entries[c].reserved != 0) warning("reserved is not zero"); } - offset = sizeof(Win32CursorIconFileDir) + dir.count * sizeof(Win32CursorIconFileDirEntry); + + offset = sizeof(Win32CursorIconFileDir) + (dir.count - 1) * (sizeof(Win32CursorIconFileDirEntry)); for (completed = 0; completed < dir.count; ) { - uint32 min_offset = (uint32)-1; + uint32 min_offset = 0x7fffffff; int previous = completed; for (c = 0; c < dir.count; c++) { @@ -898,7 +901,7 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { byte *image_data = NULL, *mask_data = NULL; byte *row = NULL; - if (in->read(&bitmap, sizeof(Win32BitmapInfoHeader))) + if (!in->read(&bitmap, sizeof(Win32BitmapInfoHeader))) goto local_cleanup; fix_win32_bitmap_info_header_endian(&bitmap); @@ -921,7 +924,7 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { if (bitmap.size != sizeof(Win32BitmapInfoHeader)) { uint32 skip = bitmap.size - sizeof(Win32BitmapInfoHeader); warning("skipping %d bytes of extended bitmap header", skip); - in->seek(skip); + in->seek(skip, SEEK_CUR); } offset += bitmap.size; @@ -940,7 +943,7 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { mask_size = height * ROW_BYTES(width); if (entries[c].dib_size != bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad)) - warning("incorrect total size of bitmap (%d specified; %d real)", + debugC(DEBUG_RESOURCE, "incorrect total size of bitmap (%d specified; %d real)", entries[c].dib_size, bitmap.size + image_size + mask_size + palette_count * sizeof(Win32RGBQuad) ); @@ -958,17 +961,34 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { completed++; matched++; + *hotspot_x = entries[c].hotspot_x; + *hotspot_y = entries[c].hotspot_y; + *w = width; + *h = height; + *keycolor = 0; + *cursor = (byte *)malloc(width * height); + row = (byte *)malloc(width * 4); for (d = 0; d < height; d++) { uint32 x; uint32 y = (bitmap.height < 0 ? d : height - d - 1); uint32 imod = y * (image_size / height) * 8 / bitmap.bit_count; - uint32 mmod = y * (mask_size / height) * 8; + //uint32 mmod = y * (mask_size / height) * 8; for (x = 0; x < width; x++) { + uint32 color = simple_vec(image_data, x + imod, bitmap.bit_count); + // FIXME?: This works only with b/w cursors and white index may be + // different. But now it's enough. + if (color) { + cursor[0][width * d + x] = 15; // white in SCUMM + } else { + cursor[0][width * d + x] = 255; // transparent + } + /* + if (bitmap.bit_count <= 16) { if (color >= palette_count) { warning("color out of range in image data"); @@ -977,6 +997,7 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { row[4*x+0] = palette[color].red; row[4*x+1] = palette[color].green; row[4*x+2] = palette[color].blue; + } else { row[4*x+0] = (color >> 16) & 0xFF; row[4*x+1] = (color >> 8) & 0xFF; @@ -986,12 +1007,11 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { row[4*x+3] = (color >> 24) & 0xFF; else row[4*x+3] = simple_vec(mask_data, x + mmod, 1) ? 0 : 0xFF; + */ } - //png_write_row(png_ptr, row); } - if (row != NULL) free(row); if (palette != NULL) @@ -1024,8 +1044,8 @@ int Win32ResExtractor::convertIcons(byte *data, int datasize) { warning("offset of bitmap header incorrect (too low)"); goto cleanup; } - warning("skipping %d bytes of garbage at %d", min_offset-offset, offset); - in->seek(min_offset - offset); + debugC(DEBUG_RESOURCE, "skipping %d bytes of garbage at %d", min_offset-offset, offset); + in->seek(min_offset - offset, SEEK_CUR); offset = min_offset; } } diff --git a/scumm/resource_v7he.h b/scumm/resource_v7he.h index 3bc144bdda..370f6d7f2c 100644 --- a/scumm/resource_v7he.h +++ b/scumm/resource_v7he.h @@ -118,9 +118,10 @@ class Win32ResExtractor { public: Win32ResExtractor(ScummEngine *scumm); ~Win32ResExtractor(); - int extractResource(const char *resType, char *resName, byte *data); - byte *extractCursor(int id); - int convertIcons(byte *data, int datasize); + int extractResource(const char *resType, char *resName, 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); private: bool _arg_raw; @@ -426,7 +427,7 @@ class Win32ResExtractor { 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 *); + 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 *); @@ -434,7 +435,7 @@ class Win32ResExtractor { 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 *); + 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); @@ -443,7 +444,7 @@ class Win32ResExtractor { 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 *); + 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 *); diff --git a/scumm/script_v6.cpp b/scumm/script_v6.cpp index ce3f5a8ea2..46e9d2077b 100644 --- a/scumm/script_v6.cpp +++ b/scumm/script_v6.cpp @@ -935,7 +935,7 @@ void ScummEngine_v6::o6_cursorCommand() { case 0x99: // SO_CURSOR_IMAGE Set cursor image { if (_heversion >= 70) { // Windows titles - _Win32ResExtractor->extractCursor(pop()); + _Win32ResExtractor->setCursor(pop()); break; } int room, obj = popRoomAndObj(&room); |