aboutsummaryrefslogtreecommitdiff
path: root/engines/sci
diff options
context:
space:
mode:
Diffstat (limited to 'engines/sci')
-rw-r--r--engines/sci/detection.cpp9
-rw-r--r--engines/sci/engine/game.cpp2
-rw-r--r--engines/sci/engine/kernel.cpp6
-rw-r--r--engines/sci/engine/klists.cpp8
-rw-r--r--engines/sci/engine/kmisc.cpp25
-rw-r--r--engines/sci/engine/kpathing.cpp2
-rw-r--r--engines/sci/engine/kscripts.cpp2
-rw-r--r--engines/sci/engine/seg_manager.cpp4
-rw-r--r--engines/sci/engine/static_selectors.cpp101
-rw-r--r--engines/sci/engine/vm.cpp22
-rw-r--r--engines/sci/gfx/gfx_resmgr.cpp39
-rw-r--r--engines/sci/gfx/gfx_resource.h17
-rw-r--r--engines/sci/gfx/res_pic.cpp38
-rw-r--r--engines/sci/gfx/res_view.cpp45
-rw-r--r--engines/sci/resource.cpp66
-rw-r--r--engines/sci/resource.h11
-rw-r--r--engines/sci/sfx/core.cpp7
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;