diff options
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.cpp | 6 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resource.h | 2 | ||||
-rw-r--r-- | engines/sci/gfx/res_view1.cpp | 209 |
3 files changed, 46 insertions, 171 deletions
diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp index 1a0920bcfb..9eeada7b39 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -499,8 +499,6 @@ gfxr_pic_t *GfxResManager::addToPic(int old_nr, int new_nr, int flags, int old_d return pic; } -gfxr_view_t *gfxr_draw_view11(int id, byte *resource, int size); - gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_VIEW]; gfx_resource_t *res = NULL; @@ -523,9 +521,9 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { else if (_version == SCI_VERSION_01 || !_isVGA) view = gfxr_draw_view0(resid, viewRes->data, viewRes->size, palette); else if (_version >= SCI_VERSION_01_VGA && _version <= SCI_VERSION_1_LATE) - view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, _staticPalette); + view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, _staticPalette, false); else if (_version >= SCI_VERSION_1_1) - view = gfxr_draw_view11(resid, viewRes->data, viewRes->size); + view = gfxr_draw_view1(resid, viewRes->data, viewRes->size, 0, true); if (_isVGA) { if (!view->palette) { diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h index 292fdfa327..fb05975dc0 100644 --- a/engines/sci/gfx/gfx_resource.h +++ b/engines/sci/gfx/gfx_resource.h @@ -282,7 +282,7 @@ Palette *gfxr_read_pal11(int id, byte *resource, int size); ** Returns : (Palette *) Palette with the colors */ -gfxr_view_t *gfxr_draw_view1(int id, byte *resource, int size, Palette *static_pal); +gfxr_view_t *gfxr_draw_view1(int id, byte *resource, int size, Palette *static_pal, bool isSci11); /* Calculates an SCI1 view ** Parameters: (int) id: Resource ID of the view ** (byte *) resource: Pointer to the resource to read diff --git a/engines/sci/gfx/res_view1.cpp b/engines/sci/gfx/res_view1.cpp index 64ba5d4907..3a624ce688 100644 --- a/engines/sci/gfx/res_view1.cpp +++ b/engines/sci/gfx/res_view1.cpp @@ -42,12 +42,9 @@ namespace Sci { #define V1_RLE_BG 0x40 // background fill #define V2_HEADER_SIZE 0 -#define V2_LOOPS_NUM 2 -#define V2_PALETTE_OFFSET 8 #define V2_BYTES_PER_LOOP 12 #define V2_BYTES_PER_CEL 13 -#define V2_IS_MIRROR 1 #define V2_COPY_OF_LOOP 2 #define V2_CELS_NUM 4 #define V2_LOOP_OFFSET 14 @@ -150,16 +147,8 @@ static int decompress_sci_view_amiga(int id, int loop, int cel, byte *resource, while (writepos < pixmap_size && pos < size) { int op = resource[pos++]; - int bytes; - int color; - - if (op & 0x07) { - bytes = op & 0x07; - color = op >> 3; - } else { - bytes = op >> 3; - color = color_key; - } + int bytes = (op & 0x07) ? op & 0x07 : op >> 3; + int color = (op & 0x07) ? op >> 3 : color_key; if (mirrored) { while (bytes--) { @@ -233,176 +222,64 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso return retval; } -static int gfxr_draw_loop1(gfxr_loop_t *dest, int id, int loop, int mirrored, byte *resource, int offset, int size, gfxr_view_t *view, int amiga_game) { - int i; - int cels_nr = READ_LE_UINT16(resource + offset); - - if (READ_LE_UINT16(resource + offset + 2)) { - GFXWARN("View %02x:(%d): Gray magic %04x in loop, expected white\n", id, loop, READ_LE_UINT16(resource + offset + 2)); - } - - if (cels_nr * 2 + 4 + offset > size) { - GFXERROR("View %02x:(%d): Offset array for %d cels extends beyond resource space\n", id, loop, cels_nr); - dest->cels_nr = 0; // Mark as "delete no cels" - dest->cels = NULL; - return 1; - } - - dest->cels = (gfx_pixmap_t**)malloc(sizeof(gfx_pixmap_t *) * cels_nr); - - for (i = 0; i < cels_nr; i++) { - int cel_offset = READ_LE_UINT16(resource + offset + 4 + (i << 1)); - gfx_pixmap_t *cel; - - if (cel_offset >= size) { - GFXERROR("View %02x:(%d/%d) supposed to be at illegal offset 0x%04x\n", id, loop, i, cel_offset); - cel = NULL; - } else - cel = gfxr_draw_cel1(id, loop, i, mirrored, resource + cel_offset, resource + cel_offset, size - cel_offset, view, amiga_game, false); - - if (!cel) { - dest->cels_nr = i; - return 1; - } - - dest->cels[i] = cel; - } - - dest->cels_nr = cels_nr; - - return 0; -} - -gfxr_view_t *gfxr_draw_view1(int id, byte *resource, int size, Palette *static_pal) { - int i; - int palette_offset; - gfxr_view_t *view; - int mirror_mask; +gfxr_view_t *gfxr_draw_view1(int id, byte *resource, int size, Palette *static_pal, bool isSci11) { + uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + (isSci11 ? 2 : 0)); + uint16 headerSize = isSci11 ? READ_LE_UINT16(resource + V2_HEADER_SIZE) : 0; + byte* seeker = resource + headerSize; + uint16 loopOffset = 0; int amiga_game = 0; + gfxr_view_t *view = (gfxr_view_t *)malloc(sizeof(gfxr_view_t)); - if (size < V1_FIRST_LOOP_OFFSET + 8) { - GFXERROR("Attempt to draw empty view %04x\n", id); - return NULL; - } - - view = (gfxr_view_t*)malloc(sizeof(gfxr_view_t)); view->ID = id; view->flags = 0; + view->loops_nr = READ_LE_UINT16(resource + V1_LOOPS_NR_OFFSET + (isSci11 ? 2 : 0)) & 0xFF; - view->loops_nr = resource[V1_LOOPS_NR_OFFSET]; - palette_offset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET); - mirror_mask = READ_LE_UINT16(resource + V1_MIRROR_MASK); - - if (view->loops_nr * 2 + V1_FIRST_LOOP_OFFSET > size) { - GFXERROR("View %04x: Not enough space in resource to accomodate for the claimed %d loops\n", id, view->loops_nr); - free(view); - return NULL; - } - - if (palette_offset > 0) { - if (palette_offset > size) { - GFXERROR("Palette is outside of view %04x\n", id); - free(view); - return NULL; - } - if (!(view->palette = gfxr_read_pal1(id, resource + palette_offset, size - palette_offset))) { - GFXERROR("view %04x: Palette reading failed. Aborting...\n", id); - free(view); - return NULL; - } + if (palOffset > 0) { + if (!isSci11) + view->palette = gfxr_read_pal1(id, resource + palOffset, size - palOffset); + else + view->palette = gfxr_read_pal11(id, resource + palOffset, size - palOffset); } else if (static_pal && static_pal->size() == GFX_SCI1_AMIGA_COLORS_NR) { // Assume we're running an amiga game. amiga_game = 1; view->palette = static_pal->getref(); } else { - GFXWARN("view %04x: Doesn't have a palette. Can SCI handle this?\n", view->ID); view->palette = NULL; } - view->loops = (gfxr_loop_t*)malloc(sizeof(gfxr_loop_t) * view->loops_nr); - - for (i = 0; i < view->loops_nr; i++) { - int error_token = 0; - int loop_offset = READ_LE_UINT16(resource + V1_FIRST_LOOP_OFFSET + (i << 1)); - - if (loop_offset >= size) { - GFXERROR("View %04x:(%d) supposed to be at illegal offset 0x%04x\n", id, i, loop_offset); - error_token = 1; - } - - if (error_token || gfxr_draw_loop1(view->loops + i, id, i, mirror_mask & (1 << i), resource, loop_offset, size, view, amiga_game)) { - // An error occured - view->loops_nr = i; - gfxr_free_view(view); - return NULL; - } - } - - return view; -} - -gfxr_loop_t *gfxr_draw_loop11(int id, int loop, int mirrored, byte *resource_base, byte *loop_base, int size, int cels_nr, - gfxr_loop_t *result, gfxr_view_t *view, int bytes_per_cel) { - byte *seeker = loop_base; - int i; - - result->cels_nr = cels_nr; - result->cels = (gfx_pixmap_t **)malloc(sizeof(gfx_pixmap_t *) * cels_nr); - - for (i = 0; i < cels_nr; i++) { - result->cels[i] = gfxr_draw_cel1(id, loop, i, mirrored, resource_base, seeker, size, view, 0, true); - seeker += bytes_per_cel; - } - - return result; -} - -gfxr_view_t *gfxr_draw_view11(int id, byte *resource, int size) { - gfxr_view_t *view; - int header_size = READ_LE_UINT16(resource + V2_HEADER_SIZE); - int palette_offset = READ_LE_UINT16(resource + V2_PALETTE_OFFSET); - int bytes_per_loop = resource[V2_BYTES_PER_LOOP]; - int loops_num = resource[V2_LOOPS_NUM]; - int bytes_per_cel = resource[V2_BYTES_PER_CEL]; - int i; - byte *seeker; - - view = (gfxr_view_t *)malloc(sizeof(gfxr_view_t)); - - memset(view, 0, sizeof(gfxr_view_t)); - view->ID = id; - view->flags = 0; - - view->loops_nr = loops_num; view->loops = (gfxr_loop_t *)calloc(view->loops_nr, sizeof(gfxr_loop_t)); - if (palette_offset > 0) { - // There is no indication of size here, but this is certainly large enough - view->palette = gfxr_read_pal11(id, resource + palette_offset, 1284); - } else { - // View has no palette - view->palette = NULL; - } + for (int i = 0; i < view->loops_nr; i++) { + if (!isSci11) { + bool mirrored = READ_LE_UINT16(resource + V1_MIRROR_MASK) & (1 << i); + loopOffset = READ_LE_UINT16(resource + V1_FIRST_LOOP_OFFSET + (i << 1)); + view->loops[i].cels_nr = READ_LE_UINT16(resource + loopOffset); + view->loops[i].cels = (gfx_pixmap_t**)calloc(view->loops[i].cels_nr, sizeof(gfx_pixmap_t *)); + + for (int j = 0; j < view->loops[i].cels_nr; j++) { + int cel_offset = READ_LE_UINT16(resource + loopOffset + 4 + (j << 1)); + view->loops[i].cels[j] = gfxr_draw_cel1(id, i, j, mirrored, + resource + cel_offset, + resource + cel_offset, + size - cel_offset, + view, amiga_game, false); + } + } else { + byte copy_entry = seeker[V2_COPY_OF_LOOP]; + bool mirrored = (copy_entry != 255); + byte *buf = !mirrored ? seeker : resource + headerSize + copy_entry * resource[V2_BYTES_PER_LOOP]; + loopOffset = READ_LE_UINT16(buf + V2_LOOP_OFFSET); + view->loops[i].cels_nr = buf[V2_CELS_NUM]; + view->loops[i].cels = (gfx_pixmap_t**)calloc(view->loops[i].cels_nr, sizeof(gfx_pixmap_t *)); + + byte* cellSeeker = resource + loopOffset; + for (int j = 0; j < view->loops[i].cels_nr; j++) { + view->loops[i].cels[j] = gfxr_draw_cel1(id, i, j, mirrored, resource, cellSeeker, size, view, 0, true); + cellSeeker += resource[V2_BYTES_PER_CEL]; + } - seeker = resource + header_size; - for (i = 0; i < view->loops_nr; i++) { - int loop_offset = READ_LE_UINT16(seeker + V2_LOOP_OFFSET); - int cels = seeker[V2_CELS_NUM]; - // int mirrored = seeker[V2_IS_MIRROR]; - int copy_entry = seeker[V2_COPY_OF_LOOP]; - - if (copy_entry == 255) - gfxr_draw_loop11(id, i, 0, resource, resource + loop_offset, size, cels, view->loops + i, - view, bytes_per_cel); - else { - byte *temp = resource + header_size + copy_entry * bytes_per_loop; - loop_offset = READ_LE_UINT16(temp + V2_LOOP_OFFSET); - cels = temp[V2_CELS_NUM]; - gfxr_draw_loop11(id, i, 1, resource, resource + loop_offset, size, cels, - view->loops + i, view, bytes_per_cel); + seeker += resource[V2_BYTES_PER_LOOP]; } - - seeker += bytes_per_loop; } return view; |