diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/detection.cpp | 9 | ||||
-rw-r--r-- | engines/sci/engine/game.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kernel.cpp | 6 | ||||
-rw-r--r-- | engines/sci/engine/klists.cpp | 8 | ||||
-rw-r--r-- | engines/sci/engine/kmisc.cpp | 25 | ||||
-rw-r--r-- | engines/sci/engine/kpathing.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/kscripts.cpp | 2 | ||||
-rw-r--r-- | engines/sci/engine/seg_manager.cpp | 4 | ||||
-rw-r--r-- | engines/sci/engine/static_selectors.cpp | 101 | ||||
-rw-r--r-- | engines/sci/engine/vm.cpp | 22 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resmgr.cpp | 39 | ||||
-rw-r--r-- | engines/sci/gfx/gfx_resource.h | 17 | ||||
-rw-r--r-- | engines/sci/gfx/res_pic.cpp | 38 | ||||
-rw-r--r-- | engines/sci/gfx/res_view.cpp | 45 | ||||
-rw-r--r-- | engines/sci/resource.cpp | 66 | ||||
-rw-r--r-- | engines/sci/resource.h | 11 | ||||
-rw-r--r-- | engines/sci/sfx/core.cpp | 7 |
17 files changed, 284 insertions, 120 deletions
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index ee9fd5fb18..4b373a76f6 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -2308,6 +2308,15 @@ static const struct SciGameDescription SciGameDescriptions[] = { 0 }, + // Quest for Glory 2 - English DOS Non-Interactive Demo + // Executable scanning reports "1.000.046" + {{"qfg2", "Demo", { + {"resource.map", 0, "e75eb86bdd517b3ef709058249986a87", 906}, + {"resource.001", 0, "9b098f9e1008abe30e56c93b896494e6", 362123}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, + 0 + }, + // Quest for Glory 3 - English DOS Non-Interactive Demo (from FRG) // Executable scanning reports "1.001.021", VERSION file reports "1.000, 0.001.059, 6.12.92" {{"qfg3", "Demo", { diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index c34ac1cf00..f649d97412 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -43,7 +43,7 @@ int _reset_graphics_input(EngineState *s) { gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 }; debug(2, "Initializing graphics"); - if (!s->resmgr->isVGA()) { + if (s->resmgr->getViewType() == kViewEga) { for (int i = 0; i < 16; i++) { if (gfxop_set_color(s->gfx_state, &(s->ega_colors[i]), gfx_sci0_image_colors[sci0_palette][i].r, gfx_sci0_image_colors[sci0_palette][i].g, gfx_sci0_image_colors[sci0_palette][i].b, 0, -1, -1)) { diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index 223e7fc1e9..a871df936f 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -820,7 +820,7 @@ void Kernel::setDefaultKernelNames() { } #ifdef ENABLE_SCI32 -static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &names) { +//static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &names) { /* 999.voc format for SCI1.1 games: [b] # of kernel functions @@ -830,7 +830,7 @@ static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &name {[w name-len][function name]} ... */ - //unsigned int size = 64, pos = 3; +/* //unsigned int size = 64, pos = 3; int len; Resource *r = resmgr->findResource(ResourceId(kResourceTypeVocab, VOCAB_RESOURCE_KNAMES), 0); if(r == NULL) // failed to open vocab.999 (happens with SCI1 demos) @@ -843,7 +843,7 @@ static void vocab_get_knames11(ResourceManager *resmgr, Common::StringList &name len = READ_LE_UINT16(r->data + off); names[i] = Common::String((char *)r->data + off + 2, len); } -} +}*/ #endif bool Kernel::loadKernelNames() { diff --git a/engines/sci/engine/klists.cpp b/engines/sci/engine/klists.cpp index 43d1f25e01..a9ae77972f 100644 --- a/engines/sci/engine/klists.cpp +++ b/engines/sci/engine/klists.cpp @@ -36,7 +36,7 @@ Node *lookup_node(EngineState *s, reg_t addr) { if (!mobj) { // FIXME: This occurs right at the beginning of SQ4, when walking north from the first screen. It doesn't // seem to have any apparent ill-effects, though, so it's been changed to non-fatal, for now - //error("%s, L%d: Attempt to use non-node %04x:%04x as list node\n", __FILE__, __LINE__, PRINT_REG(addr)); + //error("%s, L%d: Attempt to use non-node %04x:%04x as list node", __FILE__, __LINE__, PRINT_REG(addr)); warning("Attempt to use non-node %04x:%04x as list node", PRINT_REG(addr)); return NULL; } @@ -44,7 +44,7 @@ Node *lookup_node(EngineState *s, reg_t addr) { NodeTable *nt = (NodeTable *)mobj; if (!nt->isValidEntry(addr.offset)) { - error("Attempt to use non-node %04x:%04x as list node\n", PRINT_REG(addr)); + error("Attempt to use non-node %04x:%04x as list node", PRINT_REG(addr)); return NULL; } @@ -55,14 +55,14 @@ List *lookup_list(EngineState *s, reg_t addr) { MemObject *mobj = GET_SEGMENT(*s->seg_manager, addr.segment, MEM_OBJ_LISTS); if (!mobj) { - error("Attempt to use non-list %04x:%04x as list\n", PRINT_REG(addr)); + error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr)); return NULL; } ListTable *lt = (ListTable *)mobj; if (!lt->isValidEntry(addr.offset)) { - error("Attempt to use non-list %04x:%04x as list\n", PRINT_REG(addr)); + error("Attempt to use non-list %04x:%04x as list", PRINT_REG(addr)); return NULL; } diff --git a/engines/sci/engine/kmisc.cpp b/engines/sci/engine/kmisc.cpp index 2f0072ec67..90ae88b73f 100644 --- a/engines/sci/engine/kmisc.cpp +++ b/engines/sci/engine/kmisc.cpp @@ -63,14 +63,27 @@ reg_t kHaveMouse(EngineState *s, int funct_nr, int argc, reg_t *argv) { return make_reg(0, -1); } +enum kMemoryInfoFunc { + K_MEMORYINFO_LARGEST_HEAP_BLOCK = 0, // Largest heap block available + K_MEMORYINFO_FREE_HEAP = 1, // Total free heap memory + K_MEMORYINFO_LARGEST_HUNK_BLOCK = 2, // Largest available hunk memory block + K_MEMORYINFO_FREE_HUNK = 3, // Amount of free DOS paragraphs + K_MEMORYINFO_TOTAL_HUNK = 4 // Total amount of hunk memory (SCI01) +}; + reg_t kMemoryInfo(EngineState *s, int funct_nr, int argc, reg_t *argv) { + uint16 size = 0x7fff; // Must not be 0xffff, or some memory calculations will overflow + switch (argv[0].offset) { - case 0: // Total free heap memory - case 1: // Largest heap block available - case 2: // Largest available hunk memory block - case 3: // Total amount of hunk memory - case 4: // Amount of free DOS paragraphs- SCI01 - return make_reg(0, 0x7fff); // Must not be 0xffff, or some memory calculations will overflow + case K_MEMORYINFO_LARGEST_HEAP_BLOCK: + // In order to prevent "Memory fragmented" dialogs from + // popping up in some games, we must return FREE_HEAP - 2 here. + return make_reg(0, size - 2); + case K_MEMORYINFO_FREE_HEAP: + case K_MEMORYINFO_LARGEST_HUNK_BLOCK: + case K_MEMORYINFO_FREE_HUNK: + case K_MEMORYINFO_TOTAL_HUNK: + return make_reg(0, size); default: warning("Unknown MemoryInfo operation: %04x", argv[0].offset); diff --git a/engines/sci/engine/kpathing.cpp b/engines/sci/engine/kpathing.cpp index da24a388fa..ad14202257 100644 --- a/engines/sci/engine/kpathing.cpp +++ b/engines/sci/engine/kpathing.cpp @@ -1406,7 +1406,7 @@ static PathfindingState *convert_polygon_set(EngineState *s, reg_t poly_list, Co err = nearest_intersection(pf_s, start, end, &intersection); if (err == PF_FATAL) { - warning("AvoidPath: fatal error finding nearest intersecton"); + warning("AvoidPath: fatal error finding nearest intersection"); delete pf_s; return NULL; } diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 4d90dd68ac..41eb9f624d 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -74,7 +74,7 @@ int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvoc warning("Selector '%s' of object at %04x:%04x could not be invoked (%s L%d)", ((SciEngine*)g_engine)->getKernel()->getSelectorName(selector_id).c_str(), PRINT_REG(object), fname, line); if (noinvalid == kStopOnInvalidSelector) - error("[Kernel] Not recoverable: VM was halted\n"); + error("[Kernel] Not recoverable: VM was halted"); return 1; } if (slc_type == kSelectorVariable) // Swallow silently diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index a6f54c5bf7..ddcd639f3c 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -166,7 +166,7 @@ void SegManager::setScriptSize(Script &scr, int script_nr) { } if (scr.buf_size > 65535) { - error("Script and heap sizes combined exceed 64K.\n" + error("Script and heap sizes combined exceed 64K." "This means a fundamental design bug was made in SCI\n" "regarding SCI1.1 games.\nPlease report this so it can be" "fixed in the next major version"); @@ -688,7 +688,7 @@ void SegManager::scriptInitialiseObjectsSci11(SegmentId seg) { int species = READ_LE_UINT16(seeker + 10); if (species < 0 || species >= (int)_classtable.size()) { - error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d\n", + error("Invalid species %d(0x%x) not in interval [0,%d) while instantiating script %d", species, species, _classtable.size(), scr->nr); return; } diff --git a/engines/sci/engine/static_selectors.cpp b/engines/sci/engine/static_selectors.cpp index c1d0ad9bac..9c2abbfbc9 100644 --- a/engines/sci/engine/static_selectors.cpp +++ b/engines/sci/engine/static_selectors.cpp @@ -26,9 +26,6 @@ // We place selector vocab name tables here for any game that doesn't have // them. This includes the King's Quest IV Demo and LSL3 Demo. -#ifndef SCI_STATIC_SELECTORS_H -#define SCI_STATIC_SELECTORS_H - #include "sci/engine/kernel.h" namespace Sci { @@ -397,6 +394,100 @@ static const SelectorRemap iceman_demo_selectors[] = { { "setTarget", 171 } }; +// Taken from Space Quest 1 VGA (Demo) +static const SelectorRemap lsl5_demo_selectors[] = { + { "init", 103 }, + { "play", 42 }, + { "replay", 65 }, + { "x", 4 }, + { "y", 3 }, + { "z", 85 }, + { "priority", 63 }, + { "view", 5 }, + { "loop", 6 }, + { "cel", 7 }, + { "brLeft", 20 }, + { "brRight", 22 }, + { "brTop", 19 }, + { "brBottom", 21 }, + { "xStep", 54 }, + { "yStep", 55 }, + { "nsBottom", 11 }, + { "nsTop", 9 }, + { "nsLeft", 10 }, + { "nsRight", 12 }, + { "font", 33 }, + { "text", 26 }, + { "type", 34 }, + { "state", 32 }, + { "doit", 60 }, + { "delete", 84 }, + { "signal", 17 }, + { "underBits", 8 }, + { "canBeHere", 57 }, + { "client", 45 }, + { "dx", 46 }, + { "dy", 47 }, + { "xStep", 54 }, + { "yStep", 55 }, + { "b-moveCnt", 48 }, + { "b-i1", 49 }, + { "b-i2", 50 }, + { "b-di", 51 }, + { "b-xAxis", 52 }, + { "b-incr", 53 }, + { "completed", 207 }, + { "illegalBits", 18 }, + { "dispose", 104 }, + { "prevSignal", 148 }, + { "message", 40 }, + { "modifiers", 64 }, + { "cue", 135 }, + { "owner", 149 }, + { "handle", 93 }, + { "number", 43 }, + { "max", 37 }, + { "cursor", 36 }, + { "claimed", 76 }, + { "edgeHit", 308 }, + { "wordFail", 71 }, + { "syntaxFail", 72 }, + { "semanticFail", 73 }, + { "cycler", 212 }, + { "elements", 27 }, + { "lsTop", 13 }, + { "lsBottom", 15 }, + { "lsLeft", 14 }, + { "lsRight", 16 }, + { "baseSetter", 277 }, + { "who", 39 }, + { "distance", 221 }, + { "mover", 59 }, + { "looper", 62 }, + { "isBlocked", 61 }, + { "heading", 58 }, + { "mode", 30 }, + { "caller", 133 }, + { "moveDone", 100 }, + { "vol", 97 }, + { "pri", 98 }, + { "min", 94 }, + { "sec", 95 }, + { "frame", 96 }, + { "dataInc", 92 }, + { "size", 89 }, + { "palette", 91 }, + { "moveSpeed", 56 }, + { "nodePtr", 44 }, + { "flags", 150 }, + { "points", 90 }, + { "printLang", 87 }, + { "subtitleLang", 88 }, + { "parseLang", 86 }, + { "motionCue", 210 }, + { "egoMoveSpeed", 357 } +}; + // A macro for loading one of the above tables in the function below #define USE_SELECTOR_TABLE(x) \ do { \ @@ -420,10 +511,10 @@ Common::StringList Kernel::checkStaticSelectorNames() { USE_SELECTOR_TABLE(christmas1992_selectors); else if (gameID == "lsl1sci") USE_SELECTOR_TABLE(lsl1_demo_selectors); + else if (gameID == "lsl5") + USE_SELECTOR_TABLE(lsl5_demo_selectors); return names; } } // End of namespace Sci - -#endif // SCI_STATIC_SELECTORS_H diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 64ee7243fb..943a8e0354 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -79,7 +79,7 @@ static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) { if (sp >= s->stack_base && sp < s->stack_top) return sp; - error("[VM] Stack index %d out of valid range [%d..%d]\n", + error("[VM] Stack index %d out of valid range [%d..%d]", (int)(sp - s->stack_base), 0, (int)(s->stack_top - s->stack_base - 1)); return 0; } @@ -87,9 +87,9 @@ static StackPtr validate_stack_addr(EngineState *s, StackPtr sp) { static int validate_arithmetic(reg_t reg) { if (reg.segment) { if (g_debug_weak_validations) - warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); else - error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); return 0; } @@ -99,9 +99,9 @@ static int validate_arithmetic(reg_t reg) { static int signed_validate_arithmetic(reg_t reg) { if (reg.segment) { if (g_debug_weak_validations) - warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + warning("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); else - error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]\n", reg.segment); + error("[VM] Attempt to read arithmetic value from non-zero segment [%04x]", reg.segment); return 0; } @@ -214,7 +214,7 @@ ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackP int temp = s->seg_manager->validateExportFunc(pubfunct, seg); if (!temp) { - error("Request for invalid exported function 0x%x of script 0x%x\n", pubfunct, script); + error("Request for invalid exported function 0x%x of script 0x%x", pubfunct, script); return NULL; } @@ -319,7 +319,7 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPt break; } - error("Send to invalid selector 0x%x of object at %04x:%04x\n", 0xffff & selector, PRINT_REG(send_obj)); + error("Send to invalid selector 0x%x of object at %04x:%04x", 0xffff & selector, PRINT_REG(send_obj)); break; @@ -930,7 +930,7 @@ void run_vm(EngineState *s, int restoring) { } if (opparams[0] >= (int)((SciEngine*)g_engine)->getKernel()->_kernelFuncs.size()) { - error("Invalid kernel function 0x%x requested\n", opparams[0]); + error("Invalid kernel function 0x%x requested", opparams[0]); } else { int argc = ASSERT_ARITHMETIC(scriptState.xs->sp[0]); @@ -941,7 +941,7 @@ void run_vm(EngineState *s, int restoring) { && !kernel_matches_signature(s, ((SciEngine*)g_engine)->getKernel()->_kernelFuncs[opparams[0]].signature, argc, scriptState.xs->sp + 1)) { - error("[VM] Invalid arguments to kernel call %x\n", opparams[0]); + error("[VM] Invalid arguments to kernel call %x", opparams[0]); } else { s->r_acc = ((SciEngine*)g_engine)->getKernel()->_kernelFuncs[opparams[0]].fun(s, opparams[0], argc, scriptState.xs->sp + 1); @@ -1195,7 +1195,7 @@ void run_vm(EngineState *s, int restoring) { #ifndef DISABLE_VALIDATIONS if (r_temp.offset >= code_buf_size) { error("VM: lofss operation overflowed: %04x:%04x beyond end" - " of script (at %04x)\n", PRINT_REG(r_temp), code_buf_size); + " of script (at %04x)", PRINT_REG(r_temp), code_buf_size); } #endif PUSH32(r_temp); @@ -1492,7 +1492,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select if (!obj) { - error("lookup_selector(): Error while looking up Species class.\nOriginal address was %04x:%04x. Species address was %04x:%04x\n", + error("lookup_selector(): Error while looking up Species class.\nOriginal address was %04x:%04x. Species address was %04x:%04x", PRINT_REG(obj_location), PRINT_REG(obj->_variables[SCRIPT_SPECIES_SELECTOR])); return kSelectorNone; } diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp index a5596d1e4a..8ce7a50ed5 100644 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ b/engines/sci/gfx/gfx_resmgr.cpp @@ -100,7 +100,7 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic if (_version == SCI_VERSION_1_1) gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _staticPalette, _portBounds); else - gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _resManager->isVGA(), _staticPalette, _portBounds); + gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _resManager->getViewType(), _staticPalette, _portBounds); } if (scaled_pic && scaled_pic->undithered_buffer) @@ -109,9 +109,9 @@ int GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic if (_version == SCI_VERSION_1_1) gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _staticPalette, _portBounds); else - gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _resManager->isVGA(), _staticPalette, _portBounds); + gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _resManager->getViewType(), _staticPalette, _portBounds); - if (!_resManager->isVGA()) { + if (_version <= SCI_VERSION_1_EGA) { if (need_unscaled) gfxr_remove_artifacts_pic0(scaled_pic, unscaled_pic); @@ -532,28 +532,25 @@ gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { return NULL; int resid = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr); - - if (!_resManager->isVGA()) { + ViewType viewType = _resManager->getViewType(); + + if (viewType == kViewEga) { int pal = (_version <= SCI_VERSION_01) ? -1 : palette; view = getEGAView(resid, viewRes->data, viewRes->size, pal); } else { - if (_version < SCI_VERSION_1_1) - view = getVGAView(resid, viewRes->data, viewRes->size, _staticPalette, false); - else - view = getVGAView(resid, viewRes->data, viewRes->size, 0, true); - - if (!view->palette) { - view->palette = new Palette(_staticPalette->size()); - view->palette->name = "interpreter_get_view"; - } - - // Palettize view - for (unsigned i = 0; i < MIN(view->palette->size(), _staticPalette->size()); i++) { - const PaletteEntry& vc = view->palette->getColor(i); - if (vc.r == 0 && vc.g == 0 && vc.b == 0) { - const PaletteEntry& sc = _staticPalette->getColor(i); - view->palette->setColor(i, sc.r, sc.g, sc.b); + view = getVGAView(resid, viewRes->data, viewRes->size, viewType); + + if (view->palette) { + // Palettize view + for (unsigned i = 0; i < MIN(view->palette->size(), _staticPalette->size()); i++) { + const PaletteEntry& vc = view->palette->getColor(i); + if (vc.r == 0 && vc.g == 0 && vc.b == 0) { + const PaletteEntry& sc = _staticPalette->getColor(i); + view->palette->setColor(i, sc.r, sc.g, sc.b); + } } + } else { + view->palette = _staticPalette->getref(); } } diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h index 9c83cf07cd..35d7ef58d6 100644 --- a/engines/sci/gfx/gfx_resource.h +++ b/engines/sci/gfx/gfx_resource.h @@ -77,6 +77,15 @@ extern gfx_pixmap_color_t gfx_sci0_image_colors[][16]; */ extern Palette* gfx_sci0_pic_colors; + +enum ViewType { + kViewUnknown, + kViewEga, + kViewVga, + kViewVga11, + kViewAmiga +}; + struct gfxr_pic0_params_t { gfx_line_mode_t line_mode; /* one of GFX_LINE_MODE_* */ gfx_brush_mode_t brush_mode; @@ -190,13 +199,13 @@ void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size); * @param[in] resource Pointer to the resource data * @param[in] style The drawing style * @param[in] resid The resource ID - * @param[in] sci1 true if SCI1, false otherwise + * @param[in] viewType The view type for embedded views * @param[in] static_pal The static palette * @param[in] portBounds The bounds of the port being drawn to */ void gfxr_draw_pic01(gfxr_pic_t *pic, int fill_normally, int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, int sci1, + gfxr_pic0_params_t *style, int resid, ViewType viewType, Palette *static_pal, Common::Rect portBounds); /** @@ -312,9 +321,9 @@ Palette *gfxr_read_pal11(int id, byte *resource, int size); * @param[in] isSci11 true if SCI1.1, false otherwise * @return The resulting view */ -gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, bool isSci11); +gfxr_view_t *getVGAView(int id, byte *resource, int size, ViewType viewType); -gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, bool isAmiga, bool isSci11); +gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, ViewType viewType); /** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/res_pic.cpp b/engines/sci/gfx/res_pic.cpp index 6c35ad314e..09b98d12aa 100644 --- a/engines/sci/gfx/res_pic.cpp +++ b/engines/sci/gfx/res_pic.cpp @@ -1135,7 +1135,7 @@ extern gfx_pixmap_t *gfxr_draw_cel0(int id, int loop, int cel, byte *resource, i extern void _gfx_crossblit_simple(byte *dest, byte *src, int dest_line_width, int src_line_width, int xl, int yl, int bpp); void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, int sci1, Palette *static_pal, Common::Rect portBounds) { + gfxr_pic0_params_t *style, int resid, ViewType viewType, Palette *static_pal, Common::Rect portBounds) { const int default_palette_table[GFXR_PIC0_PALETTE_SIZE] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x88, @@ -1189,7 +1189,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, case PIC_OP_SET_COLOR: p0printf("Set color @%d\n", pos); - if (!sci1) { + if (viewType == kViewEga) { pal = *(resource + pos++); index = pal % GFXR_PIC0_PALETTE_SIZE; pal /= GFXR_PIC0_PALETTE_SIZE; @@ -1216,7 +1216,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, case PIC_OP_SET_PRIORITY: p0printf("Set priority @%d\n", pos); - if (!sci1) { + if (viewType == kViewEga) { pal = *(resource + pos++); index = pal % GFXR_PIC0_PALETTE_SIZE; pal /= GFXR_PIC0_PALETTE_SIZE; // Ignore pal @@ -1425,7 +1425,7 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, opx = *(resource + pos++); p0printf("OPX: "); - if (sci1) + if (viewType != kViewEga) opx += SCI1_OP_OFFSET; // See comment at the definition of SCI1_OP_OFFSET. switch (opx) { @@ -1509,11 +1509,13 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, bytesize = (*(resource + pos)) + (*(resource + pos + 1) << 8); p0printf("(%d, %d)\n", posx, posy); pos += 2; - if (!sci1 && !nodraw) - view = gfxr_draw_cel0(-1, -1, -1, resource + pos, bytesize, NULL, flags & DRAWPIC1_FLAG_MIRRORED); - else - view = gfxr_draw_cel1(-1, -1, -1, flags & DRAWPIC1_FLAG_MIRRORED, resource + pos, resource + pos, - bytesize, NULL, (static_pal && static_pal->size() == GFX_SCI1_AMIGA_COLORS_NR), false); + if (!nodraw) { + if (viewType == kViewEga) + view = gfxr_draw_cel0(-1, -1, -1, resource + pos, bytesize, NULL, flags & DRAWPIC1_FLAG_MIRRORED); + else + view = gfxr_draw_cel1(-1, -1, -1, flags & DRAWPIC1_FLAG_MIRRORED, resource + pos, resource + pos, + bytesize, NULL, viewType); + } pos += bytesize; if (nodraw) continue; @@ -1526,20 +1528,22 @@ void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, // we can only safely replace the palette if it's static // *if it's not for some reason, we should die - if (view->palette && view->palette->isShared() && !sci1) { + if (view->palette && view->palette->isShared() && (viewType == kViewEga)) { warning("gfx_draw_pic0(): can't set a non-static palette for an embedded view"); } // For SCI0, use special color mapping to copy the low // nibble of the color index to the high nibble. - if (sci1) { - if (static_pal && static_pal->size() == GFX_SCI1_AMIGA_COLORS_NR) { - // Assume Amiga game + if (viewType != kViewEga) { + if (view->palette) + view->palette->free(); + + if (viewType == kViewAmiga) { pic->visual_map->palette = static_pal->getref(); + } else { + view->palette = pic->visual_map->palette->copy(); } - if (view->palette) view->palette->free(); - view->palette = pic->visual_map->palette->copy(); } else view->palette = embedded_view_pal->getref(); @@ -1648,7 +1652,7 @@ void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, pic->visual_map->palette = gfxr_read_pal11(-1, resource + palette_data_ptr, 1284); if (has_bitmap) - view = gfxr_draw_cel1(-1, 0, 0, flags & DRAWPIC1_FLAG_MIRRORED, resource, resource + bitmap_data_ptr, size - bitmap_data_ptr, NULL, 0, true); + view = gfxr_draw_cel1(-1, 0, 0, flags & DRAWPIC1_FLAG_MIRRORED, resource, resource + bitmap_data_ptr, size - bitmap_data_ptr, NULL, kViewVga11); if (view) { view->palette = pic->visual_map->palette->getref(); @@ -1677,7 +1681,7 @@ void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, warning("[GFX] No view was contained in SCI1.1 pic resource"); } - gfxr_draw_pic01(pic, flags, default_palette, size - vector_data_ptr, resource + vector_data_ptr, style, resid, 1, static_pal, portBounds); + gfxr_draw_pic01(pic, flags, default_palette, size - vector_data_ptr, resource + vector_data_ptr, style, resid, kViewVga11, static_pal, portBounds); } void gfxr_dither_pic0(gfxr_pic_t *pic, int dmode, int pattern) { diff --git a/engines/sci/gfx/res_view.cpp b/engines/sci/gfx/res_view.cpp index d484136f8e..95f6919b0c 100644 --- a/engines/sci/gfx/res_view.cpp +++ b/engines/sci/gfx/res_view.cpp @@ -326,19 +326,19 @@ static int decompress_sci_view_amiga(int id, int loop, int cel, byte *resource, return 0; } -gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, bool isAmiga, bool isSci11) { +gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, ViewType viewType) { int xl = READ_LE_UINT16(cel_base); int yl = READ_LE_UINT16(cel_base + 2); int pixmap_size = xl * yl; - int xdisplace = isSci11 ? READ_LE_UINT16(cel_base + 4) : (int8) cel_base[4]; - int ydisplace = isSci11 ? READ_LE_UINT16(cel_base + 6) : cel_base[5]; - int runlength_offset = isSci11 ? READ_LE_UINT16(cel_base + 24) : 8; - int literal_offset = isSci11 ? READ_LE_UINT16(cel_base + 28) : 8; + int xdisplace = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 4) : (int8) cel_base[4]; + int ydisplace = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 6) : cel_base[5]; + int runlength_offset = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 24) : 8; + int literal_offset = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 28) : 8; gfx_pixmap_t *retval = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xl, yl, id, loop, cel)); byte *dest = retval->index_data; int decompress_failed; - retval->color_key = cel_base[isSci11 ? 8 : 6]; + retval->color_key = cel_base[(viewType == kViewVga11) ? 8 : 6]; retval->xoffset = mirrored ? xdisplace : -xdisplace; retval->yoffset = -ydisplace; // FIXME: In LSL5, it seems that the inventory has views without palettes (or we don't load palettes properly) @@ -350,12 +350,12 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso return NULL; } - if (!isAmiga) - decompress_failed = decompress_sci_view(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, - literal_offset, xl, yl, retval->color_key); - else + if (viewType == kViewAmiga) decompress_failed = decompress_sci_view_amiga(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, xl, yl, retval->color_key); + else + decompress_failed = decompress_sci_view(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, + literal_offset, xl, yl, retval->color_key); if (decompress_failed) { gfx_free_pixmap(retval); @@ -365,27 +365,22 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso return retval; } -gfxr_view_t *getVGAView(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; +gfxr_view_t *getVGAView(int id, byte *resource, int size, ViewType viewType) { + uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + ((viewType == kViewVga11) ? 2 : 0)); + uint16 headerSize = (viewType == kViewVga11) ? 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)); view->ID = id; view->flags = 0; - view->loops_nr = READ_LE_UINT16(resource + V1_LOOPS_NR_OFFSET + (isSci11 ? 2 : 0)) & 0xFF; + view->loops_nr = READ_LE_UINT16(resource + V1_LOOPS_NR_OFFSET + ((viewType == kViewVga11) ? 2 : 0)) & 0xFF; if (palOffset > 0) { - if (!isSci11) - view->palette = gfxr_read_pal1(id, resource + palOffset, size - palOffset); - else + if (viewType == kViewVga11) 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 + view->palette = gfxr_read_pal1(id, resource + palOffset, size - palOffset); } else { view->palette = NULL; } @@ -393,7 +388,7 @@ gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, b view->loops = (gfxr_loop_t *)calloc(view->loops_nr, sizeof(gfxr_loop_t)); for (int i = 0; i < view->loops_nr; i++) { - if (!isSci11) { + if (viewType != kViewVga11) { 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); @@ -405,7 +400,7 @@ gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, b resource + cel_offset, resource + cel_offset, size - cel_offset, - view, amiga_game, false); + view, viewType); } } else { byte copy_entry = seeker[V2_COPY_OF_LOOP]; @@ -417,7 +412,7 @@ gfxr_view_t *getVGAView(int id, byte *resource, int size, Palette *static_pal, b 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); + view->loops[i].cels[j] = gfxr_draw_cel1(id, i, j, mirrored, resource, cellSeeker, size, view, viewType); cellSeeker += resource[V2_BYTES_PER_CEL]; } diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 9b9c9ee26c..9e3bcb067e 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -510,7 +510,7 @@ void ResourceManager::init() { if (_sciVersion != SCI_VERSION_AUTODETECT) debug("Resmgr: Detected %s", versionNames[_sciVersion]); else - debug("Resmgr: Couldn't determine SCI version"); + warning("Resmgr: Couldn't determine SCI version"); switch (_viewType) { case kViewEga: @@ -521,6 +521,12 @@ void ResourceManager::init() { break; case kViewVga11: debug("Resmgr: Detected SCI1.1 VGA graphic resources"); + break; + case kViewAmiga: + debug("Resmgr: Detected Amiga graphic resources"); + break; + default: + warning("Resmgr: Couldn't determine view type"); } } @@ -904,7 +910,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType restype, patch_data_offset = 2; break; default: - warning("Resource patch unsupported special case %X\n", patch_data_offset); + warning("Resource patch unsupported special case %X", patch_data_offset); } } @@ -1016,7 +1022,7 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) { res->id = resId; res->source = getVolume(map, offset >> bShift); if (!res->source) { - warning("Could not get volume for resource %d, VolumeID %d\n", id, offset >> bShift); + warning("Could not get volume for resource %d, VolumeID %d", id, offset >> bShift); } _resMap.setVal(resId, res); } @@ -1500,22 +1506,64 @@ ResourceCompression ResourceManager::getViewCompression() { return kCompNone; } -ResourceManager::ViewType ResourceManager::detectViewType() { +ViewType ResourceManager::detectViewType() { for (int i = 0; i < 1000; i++) { Resource *res = findResource(ResourceId(kResourceTypeView, i), 0); + if (res) { - //FIXME: Amiga switch(res->data[1]) { - case 0: - return kViewEga; - default: + case 128: + // If the 2nd byte is 128, it's a VGA game return kViewVga; + case 0: + // EGA or Amiga, try to read as Amiga view + + if (res->size < 10) + return kViewUnknown; + + // Read offset of first loop + uint16 offset = READ_LE_UINT16(res->data + 8); + + if (offset + 6U >= res->size) + return kViewUnknown; + + // Read offset of first cel + offset = READ_LE_UINT16(res->data + offset + 4); + + if (offset + 4U >= res->size) + return kViewUnknown; + + // Check palette offset, amiga views have no palette + if (READ_LE_UINT16(res->data + 6) != 0) + return kViewEga; + + uint16 width = READ_LE_UINT16(res->data + offset); + offset += 2; + uint16 height = READ_LE_UINT16(res->data + offset); + offset += 6; + + // Check that the RLE data stays within bounds + int y; + for (y = 0; y < height; y++) { + int x = 0; + + while ((x < width) && (offset < res->size)) { + byte op = res->data[offset++]; + x += (op & 0x07) ? op & 0x07 : op >> 3; + } + + // Make sure we got exactly the right number of pixels for this row + if (x != width) + return kViewEga; + } + + return kViewAmiga; } } } warning("Resmgr: Couldn't find any views"); - return kViewVga; + return kViewUnknown; } SciVersion ResourceManager::detectSciVersion() { diff --git a/engines/sci/resource.h b/engines/sci/resource.h index 4250225ffe..5ba2d03beb 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -34,6 +34,8 @@ #include "sound/audiostream.h" #include "sound/mixer.h" // for SoundHandle +#include "gfx/gfx_resource.h" // for ViewType + #include "sci/decompressor.h" namespace Common { @@ -230,15 +232,10 @@ public: kResVersionSci32 }; - // TODO: Amiga - enum ViewType { - kViewEga, - kViewVga, - kViewVga11 - }; - bool isVGA() const { return (_viewType == kViewVga) || (_viewType == kViewVga11); } + ViewType getViewType() const { return _viewType; } + /** * Returns the SCI version as detected by the resource manager * @return SCI version diff --git a/engines/sci/sfx/core.cpp b/engines/sci/sfx/core.cpp index 95d79b3666..c8cf773eae 100644 --- a/engines/sci/sfx/core.cpp +++ b/engines/sci/sfx/core.cpp @@ -1060,7 +1060,7 @@ static void deDPCM16(byte *soundBuf, Common::SeekableReadStream &audioStream, ui s += tableDPCM16[b]; s = CLIP<int32>(s, -32768, 32767); - *out++ = TO_BE_16(s); + *out++ = s; } } @@ -1070,7 +1070,7 @@ static void deDPCM8Nibble(byte *soundBuf, int32 &s, byte b) { else s += tableDPCM8[b & 7]; s = CLIP<int32>(s, 0, 255); - *soundBuf = s; + *soundBuf = TO_LE_16(s); } static void deDPCM8(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { @@ -1106,7 +1106,8 @@ static byte* readSOLAudio(Common::SeekableReadStream *audioStream, uint32 &size, // Convert the SOL stream flags to our own format flags = 0; if (audioFlags & kSolFlag16Bit) - flags |= Audio::Mixer::FLAG_16BITS; + flags |= Audio::Mixer::FLAG_16BITS | Audio::Mixer::FLAG_LITTLE_ENDIAN; + if (!(audioFlags & kSolFlagIsSigned)) flags |= Audio::Mixer::FLAG_UNSIGNED; |