diff options
Diffstat (limited to 'engines/sci')
43 files changed, 3308 insertions, 2614 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 4816f87a20..2f2fbc5243 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -55,15 +55,6 @@ int g_debug_seeking = 0; // Stepping forward until some special condition is met int g_debug_seek_special = 0; // Used for special seeks int g_debug_seek_level = 0; // Used for seekers that want to check their exec stack depth -enum DebugSeeking { - kDebugSeekNothing = 0, - kDebugSeekCallk = 1, // Step forward until callk is found - kDebugSeekLevelRet = 2, // Step forward until returned from this level - kDebugSeekSpecialCallk = 3, // Step forward until a /special/ callk is found - kDebugSeekSO = 4, // Step forward until specified PC (after the send command) and stack depth - kDebugSeekGlobal = 5 // Step forward until one specified global variable is modified -}; - Console::Console(SciEngine *vm) : GUI::Debugger() { _vm = vm; @@ -152,11 +143,17 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("dissect_script", WRAP_METHOD(Console, cmdDissectScript)); DCmd_Register("set_acc", WRAP_METHOD(Console, cmdSetAccumulator)); DCmd_Register("backtrace", WRAP_METHOD(Console, cmdBacktrace)); + DCmd_Register("bt", WRAP_METHOD(Console, cmdBacktrace)); // alias DCmd_Register("step", WRAP_METHOD(Console, cmdStep)); + DCmd_Register("s", WRAP_METHOD(Console, cmdStep)); // alias DCmd_Register("step_event", WRAP_METHOD(Console, cmdStepEvent)); + DCmd_Register("se", WRAP_METHOD(Console, cmdStepEvent)); // alias DCmd_Register("step_ret", WRAP_METHOD(Console, cmdStepRet)); + DCmd_Register("sret", WRAP_METHOD(Console, cmdStepRet)); // alias DCmd_Register("step_global", WRAP_METHOD(Console, cmdStepGlobal)); + DCmd_Register("sg", WRAP_METHOD(Console, cmdStepGlobal)); // alias DCmd_Register("step_callk", WRAP_METHOD(Console, cmdStepCallk)); + DCmd_Register("snk", WRAP_METHOD(Console, cmdStepCallk)); // alias DCmd_Register("disasm", WRAP_METHOD(Console, cmdDissassemble)); DCmd_Register("disasm_addr", WRAP_METHOD(Console, cmdDissassembleAddress)); DCmd_Register("send", WRAP_METHOD(Console, cmdSend)); @@ -165,7 +162,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("bp_list", WRAP_METHOD(Console, cmdBreakpointList)); DCmd_Register("bp_del", WRAP_METHOD(Console, cmdBreakpointDelete)); DCmd_Register("bp_exec_method", WRAP_METHOD(Console, cmdBreakpointExecMethod)); + DCmd_Register("bpx", WRAP_METHOD(Console, cmdBreakpointExecMethod)); // alias DCmd_Register("bp_exec_function", WRAP_METHOD(Console, cmdBreakpointExecFunction)); + DCmd_Register("bpe", WRAP_METHOD(Console, cmdBreakpointExecFunction)); // alias // VM DCmd_Register("script_steps", WRAP_METHOD(Console, cmdScriptSteps)); DCmd_Register("vm_varlist", WRAP_METHOD(Console, cmdVMVarlist)); @@ -174,7 +173,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("value_type", WRAP_METHOD(Console, cmdValueType)); DCmd_Register("view_listnode", WRAP_METHOD(Console, cmdViewListNode)); DCmd_Register("view_reference", WRAP_METHOD(Console, cmdViewReference)); + DCmd_Register("vr", WRAP_METHOD(Console, cmdViewReference)); // alias DCmd_Register("view_object", WRAP_METHOD(Console, cmdViewObject)); + DCmd_Register("vo", WRAP_METHOD(Console, cmdViewObject)); // alias DCmd_Register("active_object", WRAP_METHOD(Console, cmdViewActiveObject)); DCmd_Register("acc_object", WRAP_METHOD(Console, cmdViewAccumulatorObject)); @@ -225,6 +226,12 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf("weak_validations: Turns some validation errors into warnings\n"); DebugPrintf("script_abort_flag: Set to 1 to abort script execution. Set to 2 to force a replay afterwards\n"); DebugPrintf("\n"); + DebugPrintf("Debug flags\n"); + DebugPrintf("-----------\n"); + DebugPrintf("debugflag_list - Lists the available debug flags and their status\n"); + DebugPrintf("debugflag_enable - Enables a debug flag\n"); + DebugPrintf("debugflag_disable - Disables a debug flag\n"); + DebugPrintf("\n"); DebugPrintf("Commands\n"); DebugPrintf("--------\n"); DebugPrintf("Kernel:\n"); @@ -310,12 +317,12 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" registers - Shows the current register values\n"); DebugPrintf(" dissect_script - Examines a script\n"); DebugPrintf(" set_acc - Sets the accumulator\n"); - DebugPrintf(" backtrace - Dumps the send/self/super/call/calle/callb stack\n"); - DebugPrintf(" step - Executes one operation (no parameters) or several operations (specified as a parameter) \n"); - DebugPrintf(" step_event - Steps forward until a SCI event is received.\n"); - DebugPrintf(" step_ret - Steps forward until ret is called on the current execution stack level.\n"); - DebugPrintf(" step_global - Steps until the global variable with the specified index is modified.\n"); - DebugPrintf(" step_callk - Steps forward until it hits the next callk operation, or a specific callk (specified as a parameter)\n"); + DebugPrintf(" backtrace / bt - Dumps the send/self/super/call/calle/callb stack\n"); + DebugPrintf(" step / s - Executes one operation (no parameters) or several operations (specified as a parameter) \n"); + DebugPrintf(" step_event / se - Steps forward until a SCI event is received.\n"); + DebugPrintf(" step_ret / sret - Steps forward until ret is called on the current execution stack level.\n"); + DebugPrintf(" step_global / sg - Steps until the global variable with the specified index is modified.\n"); + DebugPrintf(" step_callk / snk - Steps forward until it hits the next callk operation, or a specific callk (specified as a parameter)\n"); DebugPrintf(" disasm - Disassembles a method by name\n"); DebugPrintf(" disasm_addr - Disassembles one or more commands\n"); DebugPrintf(" send - Sends a message to an object\n"); @@ -324,8 +331,8 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf("Breakpoints:\n"); DebugPrintf(" bp_list - Lists the current breakpoints\n"); DebugPrintf(" bp_del - Deletes a breakpoint with the specified index\n"); - DebugPrintf(" bp_exec_method - Sets a breakpoint on the execution of the specified method\n"); - DebugPrintf(" bp_exec_function - Sets a breakpoint on the execution of the specified exported function\n"); + DebugPrintf(" bp_exec_method / bpx - Sets a breakpoint on the execution of the specified method\n"); + DebugPrintf(" bp_exec_function / bpe - Sets a breakpoint on the execution of the specified exported function\n"); DebugPrintf("\n"); DebugPrintf("VM:\n"); DebugPrintf(" script_steps - Shows the number of executed SCI operations\n"); @@ -334,8 +341,8 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" stack - Lists the specified number of stack elements\n"); DebugPrintf(" value_type - Determines the type of a value\n"); DebugPrintf(" view_listnode - Examines the list node at the given address\n"); - DebugPrintf(" view_reference - Examines an arbitrary reference\n"); - DebugPrintf(" view_object - Examines the object at the given address\n"); + DebugPrintf(" view_reference / vr - Examines an arbitrary reference\n"); + DebugPrintf(" view_object / vo - Examines the object at the given address\n"); DebugPrintf(" active_object - Shows information on the currently active object or class\n"); DebugPrintf(" acc_object - Shows information on the object or class at the address indexed by the accumulator\n"); DebugPrintf("\n"); diff --git a/engines/sci/console.h b/engines/sci/console.h index c45202de16..22b5505bf2 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -35,6 +35,15 @@ namespace Sci { class SciEngine; struct List; +enum DebugSeeking { + kDebugSeekNothing = 0, + kDebugSeekCallk = 1, // Step forward until callk is found + kDebugSeekLevelRet = 2, // Step forward until returned from this level + kDebugSeekSpecialCallk = 3, // Step forward until a /special/ callk is found + kDebugSeekSO = 4, // Step forward until specified PC (after the send command) and stack depth + kDebugSeekGlobal = 5 // Step forward until one specified global variable is modified +}; + // Refer to the "addresses" command on how to pass address parameters int parse_reg_t(EngineState *s, const char *str, reg_t *dest); int printObject(EngineState *s, reg_t pos); diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp index ac5268dd4c..bdf2c7c72a 100644 --- a/engines/sci/detection.cpp +++ b/engines/sci/detection.cpp @@ -953,9 +953,9 @@ static const struct SciGameDescription SciGameDescriptions[] = { {"resource.map", 0, "59b13619078bd47011421468959ee5d4", 954}, {"resource.001", 0, "4cfb9040db152868f7cb6a1e8151c910", 296555}, {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH}, - 0, + GF_SCI0_SCI1VOCAB, SCI_VERSION_AUTODETECT, - SCI_VERSION_01 + SCI_VERSION_0 }, // King's Quest 1 SCI Remake - English DOS (from the King's Quest Collection) @@ -969,7 +969,7 @@ static const struct SciGameDescription SciGameDescriptions[] = { {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH}, 0, SCI_VERSION_AUTODETECT, - SCI_VERSION_01 + SCI_VERSION_0 }, // King's Quest 4 - English Amiga (from www.back2roots.org) @@ -2504,6 +2504,32 @@ static const struct SciGameDescription SciGameDescriptions[] = { SCI_VERSION_0 }, + // Quest for Glory 1 - Japanese PC-98 5.25" Floppy + // Executable scanning reports "S.old.201" + {{"qfg1", "8 Colors", { + {"resource.map", 0, "5cbeb95dd2a4b7cb242b415cc6ec1c47", 6444}, + {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 859959}, + {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1136968}, + {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 769897}, + {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + 0, + SCI_VERSION_AUTODETECT, + SCI_VERSION_01 + }, + + // Quest for Glory 1 - Japanese PC-98 5.25" Floppy + // Executable scanning reports "S.old.201" + {{"qfg1", "16 Colors", { + {"resource.map", 0, "3ecaba33bf77cb434067a0b8aee15097", 6444}, + {"resource.001", 0, "a21451ef6fa8179bd4b22c4950004c44", 864754}, + {"resource.002", 0, "a21451ef6fa8179bd4b22c4950004c44", 1147121}, + {"resource.003", 0, "a21451ef6fa8179bd4b22c4950004c44", 777575}, + {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + 0, + SCI_VERSION_AUTODETECT, + SCI_VERSION_01 + }, + // Quest for Glory 1 - English Amiga // Executable scanning reports "1.002.020" // SCI interpreter version 0.000.685 @@ -3085,6 +3111,32 @@ static const struct SciGameDescription SciGameDescriptions[] = { SCI_VERSION_1 }, + // Space Quest 4 - Japanese PC-98 5.25" Floppy + // SCI interpreter version 1.000.1068 + {{"sq4", "", { + {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, + {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, + {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, + {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, + {NULL, 0, NULL, 0}}, Common::JA_JPN, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1 + }, + + // Space Quest 4 - Japanese PC-98 5.25" Floppy + // SCI interpreter version 1.000.1068 + {{"sq4", "", { + {"resource.map", 0, "ca7bba01019222b6f3e54e9051067a99", 5283}, + {"resource.000", 0, "161d719f38ed98d33f058a8cf3dc09c3", 952909}, + {"resource.001", 0, "454684e3a7a68cbca073945e50778447", 1187088}, + {"resource.002", 0, "6dc668326cc22cb9e8bd8ca9e68d2a66", 1181249}, + {NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC98, 0, GUIO_NOSPEECH}, + GF_FOR_SCI1_510_OR_LATER | GF_SCI1_EGA, + SCI_VERSION_AUTODETECT, + SCI_VERSION_1 + }, + // Space Quest 4 - English DOS CD (from the Space Quest Collection) // Executable scanning reports "1.001.064", VERSION file reports "1.0" {{"sq4", "CD", { diff --git a/engines/sci/engine/gc.h b/engines/sci/engine/gc.h index e6fa737aaf..9f9347ca18 100644 --- a/engines/sci/engine/gc.h +++ b/engines/sci/engine/gc.h @@ -45,19 +45,23 @@ struct reg_t_Hash { } }; -// The reg_t_hash_map is actually really a hashset +/* + * The reg_t_hash_map is actually really a hashset + */ typedef Common::HashMap<reg_t, bool, reg_t_Hash, reg_t_EqualTo> reg_t_hash_map; +/** + * Finds all used references and normalises them to their memory addresses + * @param s The state to gather all information from + * @return A hash map containing entries for all used references + */ reg_t_hash_map *find_all_used_references(EngineState *s); -/* Finds all used references and normalises them to their memory addresses -** Parameters: (EngineState *) s: The state to gather all information from -** Returns : (reg_t_hash_map *) A hash map containing entries for all used references -*/ +/** + * Runs garbage collection on the current system state + * @param s The state in which we should gc + */ void run_gc(EngineState *s); -/* Runs garbage collection on the current system state -** Parameters: (EngineState *) s: The state in which we should gc -*/ } // End of namespace Sci diff --git a/engines/sci/engine/intmap.h b/engines/sci/engine/intmap.h index 2cb4f69f1f..1c028975a9 100644 --- a/engines/sci/engine/intmap.h +++ b/engines/sci/engine/intmap.h @@ -83,7 +83,7 @@ public: /** * Checks whether a key is in the map, adds it if neccessary. - * @param value The key to check for/add + * @param key The key to check for/add * @param add Whether to add the key if it's not in there * @param was_added Set to non-zero if and only if the key is new, ignored if NULL. * @return The new (or old) index, or -1 if add was zero and @@ -91,6 +91,11 @@ public: */ int checkKey(int key, bool add, bool *wasAdded = 0); + /** + * Looks up a key in the map + * @parmam key The key to look for + * @return The value or -1 if not found + */ int lookupKey(int key) const; diff --git a/engines/sci/engine/kernel.cpp b/engines/sci/engine/kernel.cpp index baf45d80c7..eafc6dbd4d 100644 --- a/engines/sci/engine/kernel.cpp +++ b/engines/sci/engine/kernel.cpp @@ -945,7 +945,11 @@ bool Kernel::loadKernelNames() { switch (_resmgr->_sciVersion) { case SCI_VERSION_0: case SCI_VERSION_01: - vocab_get_knames0(_resmgr, _kernelNames); + // HACK: The KQ1 demo requires the SCI1 vocabulary. + if (((SciEngine*)g_engine)->getFlags() & GF_SCI0_SCI1VOCAB) + vocab_get_knames1(_resmgr, _kernelNames); + else + vocab_get_knames0(_resmgr, _kernelNames); break; case SCI_VERSION_01_VGA: case SCI_VERSION_01_VGA_ODD: diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 27d9df059d..46913a5b39 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -69,16 +69,17 @@ public: uint getKernelNamesSize() const { return _kernelNames.size(); } const Common::String &getKernelName(uint number) const { return _kernelNames[number]; } - /* Determines the selector ID of a selector by its name - ** (const char *) selectorName: Name of the selector to look up - ** Returns : (int) The appropriate selector ID, or -1 on error - */ + /** + * Determines the selector ID of a selector by its name + * @param selectorName Name of the selector to look up + * @return The appropriate selector ID, or -1 on error + */ int findSelector(const char *selectorName) const; - /* Detects whether a particular kernel function is required in the game - ** (const char *) functionName: The name of the desired kernel function - ** Returns : (bool) true if the kernel function is listed in the kernel table, - ** false otherwise + /** + * Detects whether a particular kernel function is required in the game + * @param functionName The name of the desired kernel function + * @return True if the kernel function is listed in the kernel table, false otherwise */ bool hasKernelFunction(const char *functionName) const; @@ -104,18 +105,18 @@ private: /** * Loads the kernel selector names. - * Returns true upon success, false otherwise. + * @return True upon success, false otherwise. */ bool loadSelectorNames(bool isOldSci0); - /* Maps special selectors - ** Returns : (void) - */ + /** + * Maps special selectors + */ void mapSelectors(); - /* Maps kernel functions - ** Returns : (void) - */ + /** + * Maps kernel functions + */ void mapFunctions(); /** @@ -127,8 +128,10 @@ private: ResourceManager *_resmgr; // Kernel-related lists - // List of opcodes, loaded from vocab.998. This list is only used for debugging - // purposes, as we hardcode the list of opcodes in the sci_opcodes enum (script.h) + /** + * List of opcodes, loaded from vocab.998. This list is only used for debugging + * purposes, as we hardcode the list of opcodes in the sci_opcodes enum (script.h) + */ Common::Array<opcode> _opcodes; Common::StringList _selectorNames; Common::StringList _kernelNames; @@ -178,61 +181,62 @@ int invoke_selector(EngineState *s, reg_t object, int selector_id, SelectorInvoc /******************** Text functionality ********************/ +/** + * Looks up text referenced by scripts + * SCI uses two values to reference to text: An address, and an index. The address + * determines whether the text should be read from a resource file, or from the heap, + * while the index either refers to the number of the string in the specified source, + * or to a relative position inside the text. + * + * @param s The current state + * @param address The address to look up + * @param index The relative index + * @return The referenced text, or NULL on error. + */ char *kernel_lookup_text(EngineState *s, reg_t address, int index); -/* Looks up text referenced by scripts -** Parameters: (EngineState *s): The current state -** (reg_t) address: The address to look up -** (int) index: The relative index -** Returns : (char *): The referenced text, or NULL on error. -** SCI uses two values to reference to text: An address, and an index. The address -** determines whether the text should be read from a resource file, or from the heap, -** while the index either refers to the number of the string in the specified source, -** or to a relative position inside the text. -*/ /******************** Debug functionality ********************/ - +/** + * Checks whether a heap address contains an object + * @param s The current state + * @parm obj The address to check + * @return True if it is an object, false otherwise + */ bool is_object(EngineState *s, reg_t obj); -/* Checks whether a heap address contains an object -** Parameters: (EngineState *) s: The current state -** (reg_t) obj: The address to check -** Returns : (bool) true if it is an object, false otherwise -*/ /******************** Kernel function parameter macros ********************/ /* Returns the parameter value or (alt) if not enough parameters were supplied */ - +/** + * Dereferences a heap pointer + * @param s The state to operate on + * @param pointer The pointer to dereference + * @parm entries The number of values expected (for checking; use 0 for strings) + * @return A physical reference to the address pointed to, or NULL on error or + * if not enugh entries were available. + * reg_t dereferenciation also assures alignedness of data. + */ reg_t *kernel_dereference_reg_pointer(EngineState *s, reg_t pointer, int entries); byte *kernel_dereference_bulk_pointer(EngineState *s, reg_t pointer, int entries); #define kernel_dereference_char_pointer(state, pointer, entries) (char*)kernel_dereference_bulk_pointer(state, pointer, entries) -/* Dereferences a heap pointer -** Parameters: (EngineState *) s: The state to operate on -** (reg_t ) pointer: The pointer to dereference -** (int) entries: The number of values expected (for checking) -** (use 0 for strings) -** Returns : (reg_t/char *): A physical reference to the address pointed -** to, or NULL on error or if not enugh entries -** were available -** reg_t dereferenciation also assures alignedness of data. -*/ /******************** Priority macros/functions ********************/ - +/** + * Finds the position of the priority band specified + * Parameters: (EngineState *) s: State to search in + * (int) band: Band to look for + * Returns : (int) Offset at which the band starts + */ int _find_priority_band(EngineState *s, int band); -/* Finds the position of the priority band specified -** Parameters: (EngineState *) s: State to search in -** (int) band: Band to look for -** Returns : (int) Offset at which the band starts -*/ +/** + * Does the opposite of _find_priority_band + * @param s Engine state + * @param y Coordinate to check + * @return The priority band y belongs to + */ int _find_view_priority(EngineState *s, int y); -/* Does the opposite of _find_priority_band -** Parameters: (EngineState *) s: State -** (int) y: Coordinate to check -** Returns : (int) The priority band y belongs to -*/ #define SCI0_VIEW_PRIORITY_14_ZONES(y) (((y) < s->priority_first)? 0 : (((y) >= s->priority_last)? 14 : 1\ + ((((y) - s->priority_first) * 14) / (s->priority_last - s->priority_first)))) @@ -249,50 +253,59 @@ int _find_view_priority(EngineState *s, int y); /******************** Dynamic view list functions ********************/ - +/** + * Determines the base rectangle of the specified view object + * @param s The state to use + * @param object The object to set + * @return The absolute base rectangle + */ Common::Rect set_base(EngineState *s, reg_t object); -/* Determines the base rectangle of the specified view object -** Parameters: (EngineState *) s: The state to use -** (reg_t) object: The object to set -** Returns : (abs_rect) The absolute base rectangle -*/ +/** + * Determines the now-seen rectangle of a view object + * @param s The state to use + * @param object The object to check + * @param clip Flag to determine wheter priority band clipping + * should be performed + * @return The absolute rectangle describing the now-seen area. + */ extern Common::Rect get_nsrect(EngineState *s, reg_t object, byte clip); -/* Determines the now-seen rectangle of a view object -** Parameters: (EngineState *) s: The state to use -** (reg_t) object: The object to check -** (byte) clip: Flag to determine wheter priority band -** clipping should be performed -** Returns : (abs_rect) The absolute rectangle describing the -** now-seen area. -*/ +/** + * Removes all views in anticipation of a new window or text + */ void _k_dyn_view_list_prepare_change(EngineState *s); -/* Removes all views in anticipation of a new window or text */ + +/** + * Redraws all views after a new window or text was added + */ void _k_dyn_view_list_accept_change(EngineState *s); -/* Redraws all views after a new window or text was added */ /******************** Misc functions ********************/ -void process_sound_events(EngineState *s); /* Get all sound events, apply their changes to the heap */ +/** + * Get all sound events, apply their changes to the heap + */ +void process_sound_events(EngineState *s); +/** + * Resolves an address into a list node + * @param s The state to operate on + * @param addr The address to resolve + * @return The list node referenced, or NULL on error + */ Node *lookup_node(EngineState *s, reg_t addr); -/* Resolves an address into a list node -** Parameters: (EngineState *) s: The state to operate on -** (reg_t) addr: The address to resolve -** Returns : (Node *) The list node referenced, or NULL on error -*/ - +/** + * Resolves a list pointer to a list + * @param s The state to operate on + * @param addr The address to resolve + * @return The list referenced, or NULL on error + */ List *lookup_list(EngineState *s, reg_t addr); -/* Resolves a list pointer to a list -** Parameters: (EngineState *) s: The state to operate on -** (reg_t) addr: The address to resolve -** Returns : (List *) The list referenced, or NULL on error -*/ /******************** Constants ********************/ diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index a26c2dbcb1..2856c76aa3 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -621,10 +621,14 @@ reg_t kGraph(EngineState *s, int funct_nr, int argc, reg_t *argv) { reg_t kTextSize(EngineState *s, int funct_nr, int argc, reg_t *argv) { int width, height; char *text = argv[1].segment ? (char *) kernel_dereference_bulk_pointer(s, argv[1], 0) : NULL; + const char *sep = NULL; reg_t *dest = kernel_dereference_reg_pointer(s, argv[0], 4); int maxwidth = (argc > 3) ? argv[3].toUint16() : 0; int font_nr = argv[2].toUint16(); + if ((argc > 4) && (argv[4].segment)) + sep = (const char *)kernel_dereference_bulk_pointer(s, argv[4], 0); + if (maxwidth < 0) maxwidth = 0; @@ -636,7 +640,7 @@ reg_t kTextSize(EngineState *s, int funct_nr, int argc, reg_t *argv) { return s->r_acc; } - GFX_ASSERT(gfxop_get_text_params(s->gfx_state, font_nr, text, maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE, + GFX_ASSERT(gfxop_get_text_params(s->gfx_state, font_nr, s->strSplit(text, sep).c_str(), maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE, &width, &height, 0, NULL, NULL, NULL)); debugC(2, kDebugLevelStrings, "GetTextSize '%s' -> %dx%d\n", text, width, height); @@ -1570,7 +1574,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { int font_nr = GET_SEL32V(obj, font); reg_t text_pos = GET_SEL32(obj, text); - char *text = text_pos.isNull() ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL); + const char *text = text_pos.isNull() ? NULL : (char *)s->seg_manager->dereference(text_pos, NULL); int view = GET_SEL32V(obj, view); int cel = sign_extend_byte(GET_SEL32V(obj, cel)); int loop = sign_extend_byte(GET_SEL32V(obj, loop)); @@ -1584,7 +1588,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { switch (type) { case K_CONTROL_BUTTON: debugC(2, kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d\n", PRINT_REG(obj), x, y); - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, text, font_nr, + ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, s->strSplit(text, NULL).c_str(), font_nr, (int8)(state & kControlStateFramed), (int8)inverse, (int8)(state & kControlStateDisabled))); break; @@ -1593,7 +1597,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { debugC(2, kDebugLevelGraphics, "drawing text %04x:%04x to %d,%d, mode=%d\n", PRINT_REG(obj), x, y, mode); - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, text, font_nr, mode, + ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, s->strSplit(text).c_str(), font_nr, mode, (int8)(!!(state & kControlStateDitherFramed)), (int8)inverse)); break; @@ -1620,8 +1624,8 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { case K_CONTROL_CONTROL: case K_CONTROL_CONTROL_ALIAS: { - char **entries_list = NULL; - char *seeker; + const char **entries_list = NULL; + const char *seeker; int entries_nr; int lsTop = GET_SEL32V(obj, lsTop) - text_pos.offset; int list_top = 0; @@ -1641,7 +1645,7 @@ static void _k_draw_control(EngineState *s, reg_t obj, int inverse) { if (entries_nr) { // determine list_top, selection, and the entries_list seeker = text; - entries_list = (char**)malloc(sizeof(char *) * entries_nr); + entries_list = (const char**)malloc(sizeof(char *) * entries_nr); for (i = 0; i < entries_nr; i++) { entries_list[i] = seeker; seeker += entry_size ; @@ -2524,10 +2528,10 @@ reg_t kNewWindow(EngineState *s, int funct_nr, int argc, reg_t *argv) { lWhite.alpha = 0; lWhite.priority = -1; lWhite.control = -1; + const char *title = argv[4 + argextra].segment ? kernel_dereference_char_pointer(s, argv[4 + argextra], 0) : NULL; window = sciw_new_window(s, gfx_rect(x, y, xl, yl), s->titlebar_port->_font, fgcolor, bgcolor, - s->titlebar_port->_font, lWhite, black, argv[4 + argextra].segment ? - kernel_dereference_char_pointer(s, argv[4 + argextra], 0) : NULL, flags); + s->titlebar_port->_font, lWhite, black, title ? s->strSplit(title, NULL).c_str() : NULL, flags); // PQ3 and SCI1.1 games have the interpreter store underBits implicitly if (argextra) @@ -3287,7 +3291,7 @@ reg_t kDisplay(EngineState *s, int funct_nr, int argc, reg_t *argv) { assert_primary_widget_lists(s); - text_handle = gfxw_new_text(s->gfx_state, area, font_nr, text, halign, ALIGN_TOP, color0, *color1, bg_color, 0); + text_handle = gfxw_new_text(s->gfx_state, area, font_nr, s->strSplit(text).c_str(), halign, ALIGN_TOP, color0, *color1, bg_color, 0); if (!text_handle) { error("Display: Failed to create text widget"); diff --git a/engines/sci/engine/ksound.cpp b/engines/sci/engine/ksound.cpp index b742c93a52..bb27589d84 100644 --- a/engines/sci/engine/ksound.cpp +++ b/engines/sci/engine/ksound.cpp @@ -975,49 +975,42 @@ reg_t kDoSound(EngineState *s, int funct_nr, int argc, reg_t *argv) { // Used for speech playback in CD games reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) { Audio::Mixer *mixer = g_system->getMixer(); - int sampleLen = 0; - - if (!s->_sound._audioResource) - s->_sound._audioResource = new AudioResource(s->resmgr, s->_version); switch (argv[0].toUint16()) { case kSciAudioWPlay: - case kSciAudioPlay: - s->_sound._audioResource->stop(); - - if (argc == 2) { // KQ5CD, KQ6 floppy - Audio::AudioStream *audioStream = s->_sound._audioResource->getAudioStream(argv[1].toUint16(), 65535, &sampleLen); - - if (audioStream) - mixer->playInputStream(Audio::Mixer::kSpeechSoundType, s->_sound._audioResource->getAudioHandle(), audioStream); - } else if (argc == 6) { // SQ4CD or newer - // Make a BE number - uint32 audioNumber = (((argv[2].toUint16() & 0xFF) << 24) & 0xFF000000) | - (((argv[3].toUint16() & 0xFF) << 16) & 0x00FF0000) | - (((argv[4].toUint16() & 0xFF) << 8) & 0x0000FF00) | - ( (argv[5].toUint16() & 0xFF) & 0x000000FF); - - Audio::AudioStream *audioStream = s->_sound._audioResource->getAudioStream(audioNumber, argv[1].toUint16(), &sampleLen); - - if (audioStream) - mixer->playInputStream(Audio::Mixer::kSpeechSoundType, s->_sound._audioResource->getAudioHandle(), audioStream); - } else { // Hopefully, this should never happen + case kSciAudioPlay: { + uint16 module; + uint32 number; + + s->_sound.stopAudio(); + + if (argc == 2) { + module = 65535; + number = argv[1].toUint16(); + } else if (argc == 6) { + module = argv[1].toUint16(); + number = ((argv[2].toUint16() & 0xff) << 24) | ((argv[3].toUint16() & 0xff) << 16) | + ((argv[4].toUint16() & 0xff) << 8) | (argv[5].toUint16() & 0xff); + } else { warning("kDoAudio: Play called with an unknown number of parameters (%d)", argc); + return NULL_REG; } - return make_reg(0, sampleLen); // return sample length in ticks + + return make_reg(0, s->_sound.startAudio(module, number)); // return sample length in ticks + } case kSciAudioStop: - s->_sound._audioResource->stop(); + s->_sound.stopAudio(); break; case kSciAudioPause: - s->_sound._audioResource->pause(); + s->_sound.pauseAudio(); break; case kSciAudioResume: - s->_sound._audioResource->resume(); + s->_sound.resumeAudio(); break; case kSciAudioPosition: - return make_reg(0, s->_sound._audioResource->getAudioPosition()); + return make_reg(0, s->_sound.getAudioPosition()); case kSciAudioRate: - s->_sound._audioResource->setAudioRate(argv[1].toUint16()); + s->_sound.setAudioRate(argv[1].toUint16()); break; case kSciAudioVolume: mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, argv[1].toUint16()); @@ -1027,7 +1020,7 @@ reg_t kDoAudio(EngineState *s, int funct_nr, int argc, reg_t *argv) { // In SCI1.1: tests for digital audio support return make_reg(0, 1); } else { - s->_sound._audioResource->setAudioLang(argv[1].toSint16()); + s->resmgr->setAudioLanguage(argv[1].toSint16()); } break; default: @@ -1042,8 +1035,10 @@ reg_t kDoSync(EngineState *s, int funct_nr, int argc, reg_t *argv) { case kSciAudioSyncStart: { ResourceId id; - if (s->_sound._soundSync) - s->resmgr->unlockResource(s->_sound._soundSync); + if (s->_sound._syncResource) { + s->resmgr->unlockResource(s->_sound._syncResource); + s->_sound._syncResource = NULL; + } // Load sound sync resource and lock it if (argc == 3) { @@ -1056,10 +1051,11 @@ reg_t kDoSync(EngineState *s, int funct_nr, int argc, reg_t *argv) { return s->r_acc; } - s->_sound._soundSync = (ResourceSync *)s->resmgr->findResource(id, 1); + s->_sound._syncResource = s->resmgr->findResource(id, 1); - if (s->_sound._soundSync) { - s->_sound._soundSync->startSync(s, argv[1]); + if (s->_sound._syncResource) { + PUT_SEL32V(argv[1], syncCue, 0); + s->_sound._syncOffset = 0; } else { warning("DoSync: failed to find resource %s", id.toString().c_str()); // Notify the scripts to stop sound sync @@ -1067,20 +1063,32 @@ reg_t kDoSync(EngineState *s, int funct_nr, int argc, reg_t *argv) { } break; } - case kSciAudioSyncNext: - if (s->_sound._soundSync) { - s->_sound._soundSync->nextSync(s, argv[1]); + case kSciAudioSyncNext: { + Resource *res = s->_sound._syncResource; + if (res && (s->_sound._syncOffset < res->size - 1)) { + int16 syncCue = -1; + int16 syncTime = (int16)READ_LE_UINT16(res->data + s->_sound._syncOffset); + + s->_sound._syncOffset += 2; + + if ((syncTime != -1) && (s->_sound._syncOffset < res->size - 1)) { + syncCue = (int16)READ_LE_UINT16(res->data + s->_sound._syncOffset); + s->_sound._syncOffset += 2; + } + + PUT_SEL32V(argv[1], syncTime, syncTime); + PUT_SEL32V(argv[1], syncCue, syncCue); } break; + } case kSciAudioSyncStop: - if (s->_sound._soundSync) { - s->_sound._soundSync->stopSync(); - s->resmgr->unlockResource(s->_sound._soundSync); - s->_sound._soundSync = NULL; + if (s->_sound._syncResource) { + s->resmgr->unlockResource(s->_sound._syncResource); + s->_sound._syncResource = NULL; } break; default: - warning("kDoSync: Unhandled case %d", argv[0].toUint16()); + warning("DoSync: Unhandled subfunction %d", argv[0].toUint16()); } return s->r_acc; diff --git a/engines/sci/engine/memobj.cpp b/engines/sci/engine/memobj.cpp index c0775ae51e..4d37d2aece 100644 --- a/engines/sci/engine/memobj.cpp +++ b/engines/sci/engine/memobj.cpp @@ -269,13 +269,6 @@ void Script::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, //-------------------- clones -------------------- -template<typename T> -void Table<T>::listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) { - for (uint i = 0; i < _table.size(); i++) - if (isValidEntry(i)) - (*note)(param, make_reg(segId, i)); -} - void CloneTable::listAllOutgoingReferences(EngineState *s, reg_t addr, void *param, NoteCallback note) { CloneTable *clone_table = this; Clone *clone; diff --git a/engines/sci/engine/memobj.h b/engines/sci/engine/memobj.h index f800695df5..50c43a0e88 100644 --- a/engines/sci/engine/memobj.h +++ b/engines/sci/engine/memobj.h @@ -502,7 +502,11 @@ public: entries_used--; } - virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note); + virtual void listAllDeallocatable(SegmentId segId, void *param, NoteCallback note) { + for (uint i = 0; i < _table.size(); i++) + if (isValidEntry(i)) + (*note)(param, make_reg(segId, i)); + } }; diff --git a/engines/sci/engine/script.cpp b/engines/sci/engine/script.cpp index a0bfdeddc9..fb094e00f6 100644 --- a/engines/sci/engine/script.cpp +++ b/engines/sci/engine/script.cpp @@ -200,6 +200,9 @@ void Kernel::mapSelectors() { FIND_SELECTOR(points); FIND_SELECTOR(syncCue); FIND_SELECTOR(syncTime); + FIND_SELECTOR(printLang); + FIND_SELECTOR(subtitleLang); + FIND_SELECTOR(parseLang); } void Kernel::dumpScriptObject(char *data, int seeker, int objsize) { diff --git a/engines/sci/engine/scriptdebug.cpp b/engines/sci/engine/scriptdebug.cpp index 63e99ad122..11c38052db 100644 --- a/engines/sci/engine/scriptdebug.cpp +++ b/engines/sci/engine/scriptdebug.cpp @@ -26,24 +26,9 @@ // Script debugger functionality. Absolutely not threadsafe. #include "sci/sci.h" +#include "sci/console.h" #include "sci/debug.h" #include "sci/engine/state.h" -#include "sci/engine/gc.h" -#include "sci/engine/kernel_types.h" -#include "sci/engine/kernel.h" -#include "sci/engine/savegame.h" -#include "sci/gfx/gfx_widgets.h" -#include "sci/gfx/gfx_gui.h" -#include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual -#include "sci/resource.h" -#include "sci/vocabulary.h" -#include "sci/sfx/iterator.h" -#include "sci/sfx/sci_midi.h" - -#include "common/util.h" -#include "common/savefile.h" - -#include "sound/audiostream.h" namespace Sci { @@ -63,13 +48,13 @@ static int *p_var_max; // May be NULL even in valid state! extern const char *selector_name(EngineState *s, int selector); -int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) { +int propertyOffsetToId(EngineState *s, int prop_ofs, reg_t objp) { Object *obj = obj_get(s, objp); byte *selectoroffset; int selectors; if (!obj) { - sciprintf("Applied prop_ofs_to_id on non-object at %04x:%04x\n", PRINT_REG(objp)); + sciprintf("Applied propertyOffsetToId on non-object at %04x:%04x\n", PRINT_REG(objp)); return -1; } @@ -86,7 +71,7 @@ int prop_ofs_to_id(EngineState *s, int prop_ofs, reg_t objp) { } if (prop_ofs < 0 || (prop_ofs >> 1) >= selectors) { - sciprintf("Applied prop_ofs_to_id to invalid property offset %x (property #%d not in [0..%d]) on object at %04x:%04x\n", + sciprintf("Applied propertyOffsetToId to invalid property offset %x (property #%d not in [0..%d]) on object at %04x:%04x\n", prop_ofs, prop_ofs >> 1, selectors - 1, PRINT_REG(objp)); return -1; } @@ -257,7 +242,7 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod if ((opcode == op_pTos) || (opcode == op_sTop) || (opcode == op_pToa) || (opcode == op_aTop) || (opcode == op_dpToa) || (opcode == op_ipToa) || (opcode == op_dpTos) || (opcode == op_ipTos)) { int prop_ofs = scr[pos.offset + 1]; - int prop_id = prop_ofs_to_id(s, prop_ofs, *p_objp); + int prop_id = propertyOffsetToId(s, prop_ofs, *p_objp); sciprintf(" (%s)", selector_name(s, prop_id)); } @@ -342,8 +327,6 @@ reg_t disassemble(EngineState *s, reg_t pos, int print_bw_tag, int print_bytecod void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *objp, int *restadjust, SegmentId *segids, reg_t **variables, reg_t **variables_base, int *variables_nr, int bp) { -// TODO: disabled till this is moved in console.cpp -#if 0 // Do we support a separate console? int old_debugstate = g_debugstate_valid; @@ -412,7 +395,6 @@ void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t * // OK, found whatever we were looking for } } -#endif g_debugstate_valid = (g_debug_step_running == 0); diff --git a/engines/sci/engine/seg_manager.cpp b/engines/sci/engine/seg_manager.cpp index 98fbd8bad7..2227167673 100644 --- a/engines/sci/engine/seg_manager.cpp +++ b/engines/sci/engine/seg_manager.cpp @@ -430,7 +430,7 @@ void SegManager::heapRelocate(reg_t block) { #define INST_LOOKUP_CLASS(id) ((id == 0xffff) ? NULL_REG : get_class_address(s, id, SCRIPT_GET_LOCK, NULL_REG)) -reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller); +reg_t get_class_address(EngineState *s, int classnr, SCRIPT_GET lock, reg_t caller); Object *SegManager::scriptObjInit0(EngineState *s, reg_t obj_pos) { Object *obj; diff --git a/engines/sci/engine/seg_manager.h b/engines/sci/engine/seg_manager.h index dc91d60e69..a41d820014 100644 --- a/engines/sci/engine/seg_manager.h +++ b/engines/sci/engine/seg_manager.h @@ -45,29 +45,38 @@ namespace Sci { class SegManager : public Common::Serializable { public: - // Initialize the segment manager + /** + * Initialize the segment manager + */ SegManager(bool sci1_1); - // Deallocate all memory associated with the segment manager + /** + * Deallocate all memory associated with the segment manager + */ ~SegManager(); virtual void saveLoadWithSerializer(Common::Serializer &ser); // 1. Scripts - // Allocate a script into the segment manager - // Parameters: (int) script_nr: number of the script to load - // (state_t *) s: The state containing resource manager handlers to load the - // script data - // Returns : (int) 0 on failure, 1 on success - // (int) *seg_id: The segment ID of the newly allocated segment, on success + /** + * Allocate a script into the segment manager + * @param s The state containing resource manager + * handlers to load the script data + * @param script_nr The number of the script to load + * @param seg_id The segment ID of the newly allocated segment, + * on success + * @return 0 on failure, 1 on success + */ Script *allocateScript(EngineState *s, int script_nr, SegmentId *seg_id); // The script must then be initialised; see section (1b.), below. - // Forcefully deallocate a previously allocated script - // Parameters: (int) script_nr: number of the script to deallocate - // Returns : (int) 1 on success, 0 on failure + /** + * Forcefully deallocate a previously allocated script + * @param script_nr number of the script to deallocate + * @return 1 on success, 0 on failure + */ int deallocateScript(int script_nr); /** @@ -76,30 +85,40 @@ public: */ bool scriptIsLoaded(SegmentId seg); - // Validate whether the specified public function is exported by the script in the specified segment - // Parameters: (int) pubfunct: Index of the function to validate - // (int) seg: Segment ID of the script the check is to be performed for - // Returns : (uint16) 0 if the public function is invalid, its offset into the script's segment - // otherwise + /** + * Validate whether the specified public function is exported by + * the script in the specified segment + * @param pubfunct Index of the function to validate + * @param seg Segment ID of the script the check is to + * be performed for + * @return NULL if the public function is invalid, its + * offset into the script's segment otherwise + */ uint16 validateExportFunc(int pubfunct, SegmentId seg); - // Get the segment ID associated with a script number - // Parameters: (int) script_nr: Number of the script to look up - // Returns : (int) The associated segment ID, or -1 if no matching segment exists + /** + * Get the segment ID associated with a script number + * @param script_nr Number of the script to look up + * @return The associated segment ID, or -1 if no + * matching segment exists + */ SegmentId segGet(int script_nr) const; /** - * Return a pointer to the specified script. If the id is invalid, does not refer - * to a script or the script is not loaded, this will invoke error(). + * Return a pointer to the specified script. + * If the id is invalid, does not refer to a script or the script is + * not loaded, this will invoke error(). * @param seg ID of the script segment to check for - * @return pointer to the Script object + * @return A pointer to the Script object */ Script *getScript(SegmentId seg); /** - * Return a pointer to the specified script. If the id is invalid, does not refer + * Return a pointer to the specified script. + * If the id is invalid, does not refer to a script, or + * the script is not loaded, this will return NULL * @param seg ID of the script segment to check for - * @return pointer to the Script object, or NULL + * @return A pointer to the Script object, or NULL */ Script *getScriptIfLoaded(SegmentId seg); @@ -112,51 +131,70 @@ public: // to be used during script instantiation, // i.e. loading and linking. - // Initializes a script's local variable block - // Parameters: (SegmentId) seg: Segment containing the script to initialize - // (int) nr: Number of local variables to allocate - // All variables are initialized to zero. + /** + * Initializes a script's local variable block + * All variables are initialized to zero. + * @param seg Segment containing the script to initialize + * @param nr Number of local variables to allocate + */ void scriptInitialiseLocalsZero(SegmentId seg, int nr); - // Initializes a script's local variable block according to a prototype - // Parameters: (reg_t) location: Location to initialize from + /** + * Initializes a script's local variable block according to a prototype + * @param location Location to initialize from + */ void scriptInitialiseLocals(reg_t location); - // Initializes an object within the segment manager - // Parameters: (reg_t) obj_pos: Location (segment, offset) of the object - // Returns : (Object *) A newly created Object describing the object - // obj_pos must point to the beginning of the script/class block (as opposed - // to what the VM considers to be the object location) - // The corresponding Object is stored within the relevant script. + /** + * Initializes an object within the segment manager + * @param obj_pos Location (segment, offset) of the object. It must + * point to the beginning of the script/class block + * (as opposed to what the VM considers to be the + * object location) + * @returns A newly created Object describing the object, + * stored within the relevant script + */ Object *scriptObjInit(EngineState *s, reg_t obj_pos); - // Informs the segment manager that a code block must be relocated - // Parameters: (reg_t) location: Start of block to relocate + /** + * Informs the segment manager that a code block must be relocated + * @param location Start of block to relocate + */ void scriptAddCodeBlock(reg_t location); - // Tells the segment manager whether exports are wide (32-bit) or not. - // Parameters: (int) flag: 1 if exports are wide, 0 otherwise + /** + * Tells the segment manager whether exports are wide (32-bit) or not. + * @param flag 1 if exports are wide, 0 otherwise + */ void setExportWidth(int flag); - // Processes a relocation block witin a script - // Parameters: (reg_t) obj_pos: Location (segment, offset) of the block - // Returns : (Object *) Location of the relocation block - // This function is idempotent, but it must only be called after all - // objects have been instantiated, or a run-time error will occur. + /** + * Processes a relocation block witin a script + * This function is idempotent, but it must only be called after all + * objects have been instantiated, or a run-time error will occur. + * @param obj_pos Location (segment, offset) of the block + * @return Location of the relocation block + */ void scriptRelocate(reg_t block); - // Determines whether the script referenced by the indicated segment is marked as being deleted. - // Parameters: (SegmentId) Segment ID of the script to investigate - // Returns : (int) 1 iff seg points to a script and the segment is deleted, 0 otherwise - // Will return 0 when applied to an invalid or non-script seg. + /** + * Determines whether the script referenced by the indicated segment + * is marked as being deleted. + * Will return 0 when applied to an invalid or non-script seg. + * @param seg Segment ID of the script to investigate + * @return 1 iff seg points to a script and the segment is + * deleted, 0 otherwise + */ bool scriptIsMarkedAsDeleted(SegmentId seg); // 2. Clones - // Allocate a fresh clone - // Returns : (Clone*): Reference to the memory allocated for the clone - // (reg_t) *addr: The offset of the freshly allocated clone + /** + * Allocate a fresh clone + * @param addr The offset of the freshly allocated clone + * @return Reference to the memory allocated for the clone + */ Clone *alloc_Clone(reg_t *addr); @@ -166,76 +204,96 @@ public: // 4. Stack - // Allocates a data stack - // Parameters: (int) size: Number of stack entries to reserve - // Returns : (DataStack *): The physical stack - // (SegmentId) segid: Segment ID of the stack + /** + * Allocates a data stack + * @param size Number of stack entries to reserve + * @param segid Segment ID of the stack + * @return The physical stack + */ DataStack *allocateStack(int size, SegmentId *segid); // 5. System Strings - // Allocates a system string table - // Returns : (DataStack *): The physical stack - // (SegmentId) segid: Segment ID of the stack - // See also sys_string_acquire(); + /** + * Allocates a system string table + * See also sys_string_acquire(); + * @param[in] segid Segment ID of the stack + * @returns The physical stack + */ SystemStrings *allocateSysStrings(SegmentId *segid); // 5. System Strings - // Allocates a string fragments segment - // Returns : (SegmentId): Segment ID to use for string fragments - // See also stringfrag.h + /** + * Allocates a string fragments segment + * See also stringfrag.h + * @return Segment ID to use for string fragments + */ SegmentId allocateStringFrags(); // 6, 7. Lists and Nodes - // Allocate a fresh list - // Returns : (listY_t*): Reference to the memory allocated for the list - // (reg_t) *addr: The offset of the freshly allocated list + /** + * Allocate a fresh list + * @param[in] addr The offset of the freshly allocated list + * @return Reference to the memory allocated for the list + */ List *alloc_List(reg_t *addr); - // Allocate a fresh node - // Returns : (node_t*): Reference to the memory allocated for the node - // (reg_t) *addr: The offset of the freshly allocated node + /** + * Allocate a fresh node + * @param[in] addr The offset of the freshly allocated node + * @return Reference to the memory allocated for the node + */ Node *alloc_Node(reg_t *addr); // 8. Hunk Memory - // Allocate a fresh chunk of the hunk - // Parameters: (int) size: Number of bytes to allocate for the hunk entry - // (const char *) hunk_type: A descriptive string for the hunk entry, - // for debugging purposes - // Returns : (Hunk *): Reference to the memory allocated for the hunk piece - // (reg_t) *addr: The offset of the freshly allocated hunk entry + /** + * Allocate a fresh chunk of the hunk + * @param[in] size Number of bytes to allocate for the hunk entry + * @param[in] hunk_type A descriptive string for the hunk entry, for + * debugging purposes + * @param[out] addr The offset of the freshly allocated hunk entry + * @return Reference to the memory allocated for the hunk + * piece + */ Hunk *alloc_hunk_entry(const char *hunk_type, int size, reg_t *addr); - // Deallocates a hunk entry - // Parameters: (reg_t) addr: Offset of the hunk entry to delete + /** + * Deallocates a hunk entry + * @param[in] addr Offset of the hunk entry to delete + */ void free_hunk_entry(reg_t addr); // 9. Dynamic Memory - // Allocate some dynamic memory - // Parameters: (int) size: Number of bytes to allocate - // (const char_ *) description: A descriptive string, - // for debugging purposes - // Returns : (unsigned char*): Raw pointer into the allocated dynamic memory - // (reg_t) *addr: The offset of the freshly allocated X + /** + * Allocate some dynamic memory + * @param[in] size Number of bytes to allocate + * @param[in] description A descriptive string for debugging purposes + * @param[out] addr The offset of the freshly allocated X + * @return Raw pointer into the allocated dynamic + * memory + */ unsigned char *allocDynmem(int size, const char *description, reg_t *addr); - // Deallocates a piece of dynamic memory - // Parameters: (reg_t) addr: Offset of the dynmem chunk to free + /** + * Deallocates a piece of dynamic memory + * @param[in] addr Offset of the dynmem chunk to free + */ int freeDynmem(reg_t addr); - // Gets the description of a dynmem segment - // Parameters: (reg_t) addr: Segment to describe - // Returns : (const char *): Pointer to the descriptive string set in - // allocDynmem + /** + * Gets the description of a dynmem segment + * @param[in] addr Segment to describe + * @return Pointer to the descriptive string set in allocDynmem + */ const char *getDescription(reg_t addr); @@ -251,10 +309,12 @@ public: // Generic Operations on Segments and Addresses - // Dereferences a raw memory pointer - // Parameters: (reg_t) reg: The reference to dereference - // Returns : (byte *) The data block referenced - // (int) size: (optionally) the theoretical maximum size of it + /** + * Dereferences a raw memory pointer + * @param[in] reg The reference to dereference + * @param[out] size (optional) The theoretical maximum size + * @return The data block referenced + */ byte *dereference(reg_t reg, int *size); @@ -266,17 +326,17 @@ public: int initialiseScript(Script &scr, EngineState *s, int script_nr); private: - IntMapper *id_seg_map; // id - script id; seg - index of heap + IntMapper *id_seg_map; ///< id - script id; seg - index of heap public: // TODO: make private Common::Array<MemObject *> _heap; int reserved_id; int exports_wide; bool isSci1_1; - SegmentId Clones_seg_id; // ID of the (a) clones segment - SegmentId Lists_seg_id; // ID of the (a) list segment - SegmentId Nodes_seg_id; // ID of the (a) node segment - SegmentId Hunks_seg_id; // ID of the (a) hunk segment + SegmentId Clones_seg_id; ///< ID of the (a) clones segment + SegmentId Lists_seg_id; ///< ID of the (a) list segment + SegmentId Nodes_seg_id; ///< ID of the (a) node segment + SegmentId Hunks_seg_id; ///< ID of the (a) hunk segment private: MemObject *allocNonscriptSegment(MemObjectType type, SegmentId *segid); @@ -295,11 +355,12 @@ private: Object *scriptObjInit0(EngineState *s, reg_t obj_pos); Object *scriptObjInit11(EngineState *s, reg_t obj_pos); - /* Check segment validity - ** Parameters: (int) seg: The segment to validate - ** Returns : (bool) false if 'seg' is an invalid segment - ** true if 'seg' is a valid segment - */ + /** + * Check segment validity + * @param[in] seg The segment to validate + * @return false if 'seg' is an invalid segment, true if + * 'seg' is a valid segment + */ bool check(SegmentId seg); void dbgPrint(const char* msg, void *i); // for debug only diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index e35530700e..e618077d54 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -126,4 +126,73 @@ uint16 EngineState::currentRoomNumber() const { return script_000->locals_block->_locals[13].toUint16(); } +kLanguage EngineState::charToLanguage(const char c) const { + switch (c) { + case 'F': + return K_LANG_FRENCH; + case 'S': + return K_LANG_SPANISH; + case 'I': + return K_LANG_ITALIAN; + case 'G': + return K_LANG_GERMAN; + case 'J': + case 'j': + return K_LANG_JAPANESE; + case 'P': + return K_LANG_PORTUGUESE; + default: + return K_LANG_NONE; + } +} + +Common::String EngineState::getLanguageString(const char *str, kLanguage lang) const { + kLanguage secondLang = K_LANG_NONE; + + const char *seeker = str; + while (*seeker) { + if ((*seeker == '%') || (*seeker == '#')) { + secondLang = charToLanguage(*(seeker + 1)); + + if (secondLang != K_LANG_NONE) + break; + } + + seeker++; + } + + if ((secondLang == K_LANG_JAPANESE) && (*(seeker + 1) == 'J')) { + // FIXME: Add Kanji support + lang = K_LANG_ENGLISH; + } + + if (secondLang == lang) + return Common::String(seeker + 2); + + if (seeker) + return Common::String(str, seeker - str); + else + return Common::String(str); +} + +Common::String EngineState::strSplit(const char *str, const char *sep) { + EngineState *s = this; + + kLanguage lang = (kLanguage)GET_SEL32V(s->game_obj, printLang); + kLanguage subLang = (kLanguage)GET_SEL32V(s->game_obj, subtitleLang); + + // Use English when no language settings are present in the game + if (lang == K_LANG_NONE) + lang = K_LANG_ENGLISH; + + Common::String retval = getLanguageString(str, lang); + + if ((subLang != K_LANG_NONE) && (sep != NULL)) { + retval += sep; + retval += getLanguageString(str, subLang); + } + + return retval; +} + } // End of namespace Sci diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index 15c1c2e63e..ecfb9fe6f7 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -88,6 +88,18 @@ enum { SCI_GAME_WAS_RESTARTED_AT_LEAST_ONCE = 4 }; +/** Supported languages */ +enum kLanguage { + K_LANG_NONE = 0, + K_LANG_ENGLISH = 1, + K_LANG_FRENCH = 33, + K_LANG_SPANISH = 34, + K_LANG_ITALIAN = 39, + K_LANG_GERMAN = 49, + K_LANG_JAPANESE = 81, + K_LANG_PORTUGUESE = 351 +}; + struct drawn_pic_t { int nr; int palette; @@ -209,6 +221,16 @@ public: uint16 currentRoomNumber() const; + /** + * Processes a multilanguage string based on the current language settings and + * returns a string that is ready to be displayed. + * @param str the multilanguage string + * @param sep optional seperator between main language and subtitle language, + * if NULL is passed no subtitle will be added to the returned string + * @return processed string + */ + Common::String strSplit(const char *str, const char *sep = "\r----------\r"); + /* Debugger data: */ Breakpoint *bp_list; /**< List of breakpoints */ int have_bp; /**< Bit mask specifying which types of breakpoints are used in bp_list */ @@ -239,6 +261,10 @@ public: Kernel *_kernel; EngineState *successor; /**< Successor of this state: Used for restoring */ + +private: + kLanguage charToLanguage(const char c) const; + Common::String getLanguageString(const char *str, kLanguage lang) const; }; /** diff --git a/engines/sci/engine/vm.cpp b/engines/sci/engine/vm.cpp index 0b84c0ef3c..cbd0b0cfbb 100644 --- a/engines/sci/engine/vm.cpp +++ b/engines/sci/engine/vm.cpp @@ -193,7 +193,7 @@ int script_error(EngineState *s, const char *file, int line, const char *reason) } #define CORE_ERROR(area, msg) script_error(s, "[" area "] " __FILE__, __LINE__, msg) -reg_t get_class_address(EngineState *s, int classnr, int lock, reg_t caller) { +reg_t get_class_address(EngineState *s, int classnr, SCRIPT_GET lock, reg_t caller) { if (NULL == s) { warning("vm.c: get_class_address(): NULL passed for \"s\""); @@ -1550,7 +1550,7 @@ SelectorType lookup_selector(EngineState *s, reg_t obj_location, Selector select return _lookup_selector_function(s, obj_location.segment, obj, selector_id, fptr); } -SegmentId script_get_segment(EngineState *s, int script_nr, int load) { +SegmentId script_get_segment(EngineState *s, int script_nr, SCRIPT_GET load) { SegmentId segment; if ((load & SCRIPT_GET_LOAD) == SCRIPT_GET_LOAD) diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index dfbbc39780..a3fabbe44b 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -198,7 +198,11 @@ struct selector_map_t { Selector points; /**< Used by AvoidPath() */ Selector syncCue; /**< Used by DoSync() */ - Selector syncTime; /**< Used by DoSync() */ + Selector syncTime; + + Selector printLang; /**< Used for i18n */ + Selector subtitleLang; + Selector parseLang; }; // A reference to an object's variable. @@ -287,8 +291,8 @@ struct Breakpoint { }; /** - * Set this to 1 to abort script execution immediately. Aborting will leave the - * debug exec stack intact. + * Set this to 1 to abort script execution immediately. Aborting will + * leave the debug exec stack intact. * Set it to 2 to force a replay afterwards. */ extern int script_abort_flag; @@ -307,31 +311,36 @@ extern int script_step_counter; /** * Executes function pubfunct of the specified script. - * Parameters: (EngineState *) s: The state which is to be executed with - * (uint16) script: The script which is called - * (uint16) pubfunct: The exported script function which is to be called - * (StackPtr) sp: Stack pointer position - * (reg_t) calling_obj: The heap address of the object which executed the call - * (uint16) argc: Number of arguments supplied - * (StackPtr) argp: Pointer to the first supplied argument - * Returns : (ExecStack *): A pointer to the new exec stack TOS entry + * @param[in] s The state which is to be executed with + * @param[in] script The script which is called + * @param[in] pubfunct The exported script function which is to + * be called + * @param[in] sp Stack pointer position + * @param[in] calling_obj The heap address of the object that + * executed the call + * @param[in] argc Number of arguments supplied + * @param[in] argp Pointer to the first supplied argument + * @return A pointer to the new exec stack TOS entry */ -ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, StackPtr sp, reg_t calling_obj, - uint16 argc, StackPtr argp); +ExecStack *execute_method(EngineState *s, uint16 script, uint16 pubfunct, + StackPtr sp, reg_t calling_obj, uint16 argc, StackPtr argp); /** * Executes a "send" or related operation to a selector. - * Parameters: (EngineState *) s: The EngineState to operate on - * (reg_t) send_obj: Heap address of the object to send to - * (reg_t) work_obj: Heap address of the object initiating the send - * (StackPtr) sp: Stack pointer position - * (int) framesize: Size of the send as determined by the "send" operation - * (StackPtr) argp: Pointer to the beginning of the heap block containing the - * data to be sent. This area is a succession of one or more - * sequences of [selector_number][argument_counter] and then - * "argument_counter" word entries with the parameter values. - * Returns : (ExecStack *): A pointer to the new execution stack TOS entry + * @param[in] s The EngineState to operate on + * @param[in] send_obj Heap address of the object to send to + * @param[in] work_obj Heap address of the object initiating the send + * @param[in] sp Stack pointer position + * @param[in] framesize Size of the send as determined by the "send" + * operation + * @param[in] argp Pointer to the beginning of the heap block + * containing the data to be sent. This area is a + * succession of one or more sequences of + * [selector_number][argument_counter] and then + * "argument_counter" word entries with the + * parameter values. + * @return A pointer to the new execution stack TOS entry */ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, StackPtr sp, int framesize, StackPtr argp); @@ -342,267 +351,300 @@ ExecStack *send_selector(EngineState *s, reg_t send_obj, reg_t work_obj, /** * Adds an entry to the top of the execution stack. * - * @param s The state with which to execute - * @param pc The initial program counter - * @param sp The initial stack pointer - * @param objp Pointer to the beginning of the current object - * @param argc Number of parameters to call with - * @param argp Heap pointer to the first parameter - * @param selector The selector by which it was called or - * NULL_SELECTOR if n.a. For debugging. - * @param sendp Pointer to the object which the message was sent to. - * Equal to objp for anything but super. - * @param origin Number of the execution stack element this entry was created by - * (usually the current TOS number, except for multiple sends). - * @param local_segment The segment to use for local variables, - * or SCI_XS_CALLEE_LOCALS to use obj's segment. - * @return a pointer to the new exec stack TOS entry - */ -ExecStack *add_exec_stack_entry(EngineState *s, reg_t pc, StackPtr sp, reg_t objp, int argc, - StackPtr argp, Selector selector, reg_t sendp, int origin, SegmentId local_segment); + * @param[in] s The state with which to execute + * @param[in] pc The initial program counter + * @param[in] sp The initial stack pointer + * @param[in] objp Pointer to the beginning of the current object + * @param[in] argc Number of parameters to call with + * @param[in] argp Heap pointer to the first parameter + * @param[in] selector The selector by which it was called or + * NULL_SELECTOR if n.a. For debugging. + * @param[in] sendp Pointer to the object which the message was + * sent to. Equal to objp for anything but super. + * @param[in] origin Number of the execution stack element this + * entry was created by (usually the current TOS + * number, except for multiple sends). + * @param[in] local_segment The segment to use for local variables, + * or SCI_XS_CALLEE_LOCALS to use obj's segment. + * @return A pointer to the new exec stack TOS entry + */ +ExecStack *add_exec_stack_entry(EngineState *s, reg_t pc, StackPtr sp, + reg_t objp, int argc, StackPtr argp, Selector selector, + reg_t sendp, int origin, SegmentId local_segment); /** * Adds one varselector access to the execution stack. - * Parameters: (EngineState *) s: The EngineState to use - * (reg_t) objp: Pointer to the object owning the selector - * (int) argc: 1 for writing, 0 for reading - * (StackPtr) argp: Pointer to the address of the data to write -2 - * (int) selector: Selector name - * (ObjVarRef& ) address: Heap address of the selector - * (int) origin: Stack frame which the access originated from - * Returns : (ExecStack *): Pointer to the new exec-TOS element * This function is called from send_selector only. + * @param[in] s The EngineState to use + * @param[in] objp Pointer to the object owning the selector + * @param[in] argc 1 for writing, 0 for reading + * @param[in] argp Pointer to the address of the data to write -2 + * @param[in] selector Selector name + * @param[in] address Heap address of the selector + * @param[in] origin Stack frame which the access originated from + * @return Pointer to the new exec-TOS element */ -ExecStack *add_exec_stack_varselector(EngineState *s, reg_t objp, int argc, StackPtr argp, - Selector selector, const ObjVarRef& address, int origin); - +ExecStack *add_exec_stack_varselector(EngineState *s, reg_t objp, int argc, + StackPtr argp, Selector selector, const ObjVarRef& address, + int origin); +/** + * This function executes SCI bytecode + * It executes the code on s->heap[pc] until it hits a 'ret' operation + * while (stack_base == stack_pos). Requires s to be set up correctly. + * @param[in] s The state to use + * @param[in] restoring 1 if s has just been restored, 0 otherwise + */ void run_vm(EngineState *s, int restoring); -/* Executes the code on s->heap[pc] until it hits a 'ret' operation while (stack_base == stack_pos) -** Parameters: (EngineState *) s: The state to use -** (int) restoring: 1 if s has just been restored, 0 otherwise -** Returns : (void) -** This function will execute SCI bytecode. It requires s to be set up -** correctly. -*/ +/** + * Handles a fatal error condition + * @param[in] s The state to recover from + * @param[in] line Source code line number the error occured in + * @param[in] file File the error occured in + */ void vm_handle_fatal_error(EngineState *s, int line, const char *file); -/* Handles a fatal error condition -** Parameters: (EngineState *) s: The state to recover from -** (int) line: Source code line number the error occured in -** (const char *) file: File the error occured in -*/ - - -void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, reg_t *objp, - int *restadjust, SegmentId *segids, reg_t **variables, reg_t **variables_base, - int *variables_nr, int bp); -/* Debugger functionality -** Parameters: (EngineState *) s: The state at which debugging should take place -** (reg_t *) pc: Pointer to the program counter -** (StackPtr *) sp: Pointer to the stack pointer -** (StackPtr *) pp: Pointer to the frame pointer -** (reg_t *) objp: Pointer to the object base pointer -** (int *) restadjust: Pointer to the &rest adjustment value -** (SegmentId *) segids: four-element array containing segment IDs for locals etc. -** (reg_t **) variables: four-element array referencing registers for globals etc. -** (reg_t **) variables_base: four-element array referencing -** register bases for temps etc. -** (int *) variables_nr: four-element array giving sizes for params etc. (may be NULL) -** (int) bp: Flag, set to 1 when a breakpoint is triggered -** Returns : (void) -*/ + +/** + * Debugger functionality + * @param[in] s The state at which debugging should take + * place + * @param[in] pc Pointer to the program counter + * @param[in] sp Pointer to the stack pointer + * @param[in] pp Pointer to the frame pointer + * @param[in] objp Pointer to the object base pointer + * @param[in] restadjust Pointer to the &rest adjustment value + * @param[in] segids four-element array containing segment IDs + * for locals etc. + * @param[in] variables four-element array referencing registers + * for globals etc. + * @param[in] variables_base four-element array referencing register + * bases for temps etc. + * @param[in] variables_nr four-element array giving sizes for params + * etc. (may be NULL) + * @param[in] bp Flag, set to 1 when a breakpoint is + * triggered + */ +void script_debug(EngineState *s, reg_t *pc, StackPtr *sp, StackPtr *pp, + reg_t *objp, int *restadjust, SegmentId *segids, reg_t **variables, + reg_t **variables_base, int *variables_nr, int bp); + +/** + * Initializes a EngineState block + * @param[in] s The state to initialize + * @return 0 on success, 1 if vocab.996 (the class table) is missing + * or corrupted + */ int script_init_engine(EngineState *s); -/* Initializes a EngineState block -** Parameters: (EngineState *) s: The state to initialize -** Returns : 0 on success, 1 if vocab.996 (the class table) is missing or corrupted -*/ +/** + * Sets the gamestate's save_dir to the parameter path + * @param[in] s The state to set + * @param[in] path Path where save_dir will point to + */ void script_set_gamestate_save_dir(EngineState *s, const char *path); -/* Sets the gamestate's save_dir to the parameter path -** Parameters: (EngineState *) s: The state to set -** (const char *) path: Path where save_dir will point to -** Returns : (void) -*/ +/** + * Frees all additional memory associated with a EngineState block + * @param[in] s The EngineState whose elements should be cleared + */ void script_free_engine(EngineState *s); -/* Frees all additional memory associated with a EngineState block -** Parameters: (EngineState *) s: The EngineState whose elements should be cleared -** Returns : (void) -*/ +/** + * Frees all script memory (heap, hunk, and class tables). + * This operation is implicit in script_free_engine(), but is required for + * restoring the game state. + * @param[in] s The EngineState to free + */ void script_free_vm_memory(EngineState *s); -/* Frees all script memory (heap, hunk, and class tables). -** Parameters: (EngineState *) s: The EngineState to free -** Returns : (void) -** This operation is implicit in script_free_engine(), but is required for restoring -** the game state. -*/ - - -SelectorType lookup_selector(EngineState *s, reg_t obj, Selector selectorid, ObjVarRef *varp, reg_t *fptr); -/* Looks up a selector and returns its type and value -** Parameters: (EngineState *) s: The EngineState to use -** (reg_t) obj: Address of the object to look the selector up in -** (Selector) selectorid: The selector to look up -** Returns : (SelectorType) kSelectorNone if the selector was not found in the object or its superclasses. -** kSelectorVariable if the selector represents an object-relative variable -** kSelectorMethod if the selector represents a method -** (ObjVarRef *) *varp: A reference to the selector, if -** it is a variable -** (reg_t) *fptr: A reference to the function described by that selector, if it is -** a valid function selector. -** *varindex is written to iff it is non-NULL and the selector indicates a property of the object. -** *fptr is written to iff it is non-NULL and the selector indicates a member function of that object. -*/ -enum { +/** + * Looks up a selector and returns its type and value + * varindex is written to iff it is non-NULL and the selector indicates a property of the object. + * @param[in] s The EngineState to use + * @param[in] obj Address of the object to look the selector up in + * @param[in] selectorid The selector to look up + * @param[out] varp A reference to the selector, if it is a + * variable. + * @param[out] fptr A reference to the function described by that + * selector, if it is a valid function selector. + * fptr is written to iff it is non-NULL and the + * selector indicates a member function of that + * object. + * @return kSelectorNone if the selector was not found in + * the object or its superclasses. + * kSelectorVariable if the selector represents an + * object-relative variable. + * kSelectorMethod if the selector represents a + * method + */ +SelectorType lookup_selector(EngineState *s, reg_t obj, Selector selectorid, + ObjVarRef *varp, reg_t *fptr); + +/** + * Parameters for script_get_segment() + */ +typedef enum { SCRIPT_GET_DONT_LOAD = 0, /**< Fail if not loaded */ SCRIPT_GET_LOAD = 1, /**< Load, if neccessary */ SCRIPT_GET_LOCK = 3 /**< Load, if neccessary, and lock */ -}; +} SCRIPT_GET; -SegmentId script_get_segment(EngineState *s, int script_id, int load); -/* Determines the segment occupied by a certain script -** Parameters: (EngineState *) s: The state to operate on -** (int) script_id: The script in question -** (int) load: One of SCRIPT_GET_* -** Returns : The script's segment, or 0 on failure -*/ +/** + * Determines the segment occupied by a certain script + * @param[in] s The state to operate on + * @param[in] script_id The script in question + * @param[in] load One of SCRIPT_GET_* + * @return The script's segment, or 0 on failure + */ +SegmentId script_get_segment(EngineState *s, int script_id, SCRIPT_GET load); +/** + * Looks up an entry of the exports table of a script + * @param[in] s The state to operate on + * @param[in] script_nr The script to look up in + * @param[out] export_index The index of the export entry to look up + * @return The handle + */ reg_t script_lookup_export(EngineState *s, int script_nr, int export_index); -/* Looks up an entry of the exports table of a script -** Parameters: (EngineState *) s: The state to operate on -** (int) script_nr: The script to look up in -** Returns : (int) export_index: index of the export entry to look up -*/ +/** + * Makes sure that a script and its superclasses get loaded to the heap. + * If the script already has been loaded, only the number of lockers is + * increased. All scripts containing superclasses of this script are loaded + * recursively as well, unless 'recursive' is set to zero. The + * complementary function is "script_uninstantiate()" below. + * @param[in] s The state to operate on + * @param[in] script_nr The script number to load + * @return The script's segment ID or 0 if out of heap + */ int script_instantiate(EngineState *s, int script_nr); -/* Makes sure that a script and its superclasses get loaded to the heap -** Parameters: (EngineState *) s: The state to operate on -** (int) script_nr: The script number to load -** Returns : (int) The script's segment ID or 0 if out of heap -** If the script already has been loaded, only the number of lockers is increased. -** All scripts containing superclasses of this script aret loaded recursively as well, -** unless 'recursive' is set to zero. -** The complementary function is "script_uninstantiate()" below. -*/ - +/** + * Decreases the numer of lockers of a script and unloads it if that number + * reaches zero. + * This function will recursively unload scripts containing its + * superclasses, if those aren't locked by other scripts as well. + * @param[in] s The state to operate on + * @param[in] script_nr The script number that is requestet to be unloaded + */ void script_uninstantiate(EngineState *s, int script_nr); -/* Decreases the numer of lockers of a script and unloads it if that number reaches zero -** Parameters: (EngineState *) s: The state to operate on -** (int) script_nr: The script number that is requestet to be unloaded -** Returns : (void) -** This function will recursively unload scripts containing its superclasses, if those -** aren't locked by other scripts as well. -*/ - +/** + * Initializes an SCI game + * This function must be run before script_run() is executed. Graphics data + * is initialized iff s->gfx_state != NULL. + * @param[in] s The state to operate on + * @return 0 on success, 1 if an error occured. + */ int game_init(EngineState *s); -/* Initializes an SCI game -** Parameters: (EngineState *) s: The state to operate on -** Returns : (int): 0 on success, 1 if an error occured. -** This function must be run before script_run() is executed. -** Graphics data is initialized iff s->gfx_state != NULL. -*/ +/** + * Initializes the graphics part of an SCI game + * This function may only be called if game_init() did not initialize + * the graphics data. + * @param[in] s The state to initialize the graphics in + * @return 0 on success, 1 if an error occured + */ int game_init_graphics(EngineState *s); -/* Initializes the graphics part of an SCI game -** Parameters: (EngineState *) s: The state to initialize the graphics in -** Returns : (int) 0 on success, 1 if an error occured -** This function may only be called if game_init() did not initialize -** the graphics data. -*/ +/** + * Initializes the sound part of an SCI game + * This function may only be called if game_init() did not initialize + * the sound data. + * @param[in] s The state to initialize the sound in + * @param[in] sound_flags Flags to pass to the sound subsystem + * @return 0 on success, 1 if an error occured + */ int game_init_sound(EngineState *s, int sound_flags); -/* Initializes the sound part of an SCI game -** Parameters: (EngineState *) s: The state to initialize the sound in -** (int) sound_flags: Flags to pass to the sound subsystem -** Returns : (int) 0 on success, 1 if an error occured -** This function may only be called if game_init() did not initialize -** the graphics data. -*/ - +/** + * Runs an SCI game + * This is the main function for SCI games. It takes a valid state, loads + * script 0 to it, finds the game object, allocates a stack, and runs the + * init method of the game object. In layman's terms, this runs an SCI game. + * Note that, EngineState *s may be changed during the game, e.g. if a game + * state is restored. + * @param[in] s Pointer to the pointer of the state to operate on + * @return 0 on success, 1 if an error occured. + */ int game_run(EngineState **s); -/* Runs an SCI game -** Parameters: (EngineState **) s: Pointer to the pointer of the state to operate on -** Returns : (int): 0 on success, 1 if an error occured. -** This is the main function for SCI games. It takes a valid state, loads script 0 to it, -** finds the game object, allocates a stack, and runs the init method of the game object. -** In layman's terms, this runs an SCI game. -** By the way, *s may be changed during the game, e.g. if a game state is restored. -*/ +/** + * Restores an SCI game state and runs the game + * This restores a savegame; otherwise, it behaves just like game_run(). + * @param[in] s Pointer to the pointer of the state to + * operate on + * @param[in] savegame_name Name of the savegame to restore + * @return 0 on success, 1 if an error occured. + */ int game_restore(EngineState **s, char *savegame_name); -/* Restores an SCI game state and runs the game -** Parameters: (EngineState **) s: Pointer to the pointer of the state to operate on -** (char *) savegame_name: Name of the savegame to restore -** Returns : (int): 0 on success, 1 if an error occured. -** This restores a savegame; otherwise, it behaves just like game_run(). -*/ +/** + * Uninitializes an initialized SCI game + * This function should be run after each script_run() call. + * @param[in] s The state to operate on + * @return 0 on success, 1 if an error occured. + */ int game_exit(EngineState *s); -/* Uninitializes an initialized SCI game -** Parameters: (EngineState *) s: The state to operate on -** Returns : (int): 0 on success, 1 if an error occured. -** This function should be run after each script_run() call. -*/ +/** + * Instructs the virtual machine to abort + */ void quit_vm(); -/* Instructs the virtual machine to abort -** Paramteres: (void) -** Returns : (void) -*/ +/** + * Allocates "kernel" memory and returns a handle suitable to be passed on + * to SCI scripts + * @param[in] s Pointer to the EngineState to operate on + * @param[in] type A free-form type description string (static) + * @param[in] space The space to allocate + * @return The handle + */ reg_t kalloc(EngineState *s, const char *type, int space); -/* Allocates "kernel" memory and returns a handle suitable to be passed on to SCI scripts -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (const char *) type: A free-form type description string (static) -** (int) space: The space to allocate -** Returns : (reg_t) The handle -*/ +/** + * Returns a pointer to "kernel" memory based on the handle + * @param[in] s Pointer to the EngineState to operate on + * @param[in] handle The handle to use + * @return A pointer to the allocated memory + */ byte *kmem(EngineState *s, reg_t handle); -/* Returns a pointer to "kernel" memory based on the handle -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) handle: The handle to use -** Returns : (byte *) A pointer to the allocated memory -*/ - +/** + * Frees all "kernel" memory associated with a handle + * @param[in] s Pointer to the EngineState to operate on + * @param[in] handle The handle to free + * @return 0 on success, 1 otherwise + */ int kfree(EngineState *s, reg_t handle); -/* Frees all "kernel" memory associated with a handle -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) handle: The handle to free -** Returns : (int) 0 on success, 1 otherwise -*/ +/** + * Determines the name of an object + * @param[in] s Pointer to the EngineState to operate on + * @param[in] pos Location of the object whose name we want to inspect + * @return A name for that object, or a string describing an error + * that occured while looking it up. The string is stored + * in a static buffer and need not be freed (neither may + * it be modified). + */ const char *obj_get_name(EngineState *s, reg_t pos); -/* Determines the name of an object -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) pos: Location of the object whose name we want to -** inspect -** Returns : (const char *) A name for that object, or a string describing -** an error that occured while looking it up -** The string is stored in a static buffer and need not be freed (neither -** may it be modified). -*/ +/** + * Retrieves an object from the specified location + * @param[in] s Pointer to the EngineState to operate on + * @param[in] offset The object's offset + * @return The object in question, or NULL if there is none + */ Object *obj_get(EngineState *s, reg_t offset); -/* Retrieves an object from the specified location -** Parameters: (EngineState *) s: Pointer to the EngineState to operate on -** (reg_t) offset: The object's offset -** Returns : (Object *) The object in question, or NULL if there is none -*/ +/** + * Shrink execution stack to size. + * Contains an assert it is not already smaller. + */ void shrink_execution_stack(EngineState *s, uint size); -/* Shrink execution stack to size. -** Contains an assert it is not already smaller. -*/ } // End of namespace Sci diff --git a/engines/sci/gfx/font.h b/engines/sci/gfx/font.h index 935414f550..fe0d81d135 100644 --- a/engines/sci/gfx/font.h +++ b/engines/sci/gfx/font.h @@ -30,6 +30,8 @@ namespace Sci { +/** @name Font operations and stuctures */ +/** @{ */ struct TextFragment { const char *offset; @@ -39,90 +41,109 @@ struct TextFragment { TextFragment(const char *o) : offset(o), length(0) {} }; - -struct gfx_bitmap_font_t { /* gfx_bitmap_font_t: Bitmap font information */ - int ID; /* Unique resource ID */ - - int chars_nr; /* Numer of available characters */ - - int *widths; /* chars_nr character widths, in pixels */ - - int row_size; /* Byte size of each pixel row. For unscaled fonts, this is - ** always 1, 2, or 4. Otherwise, it's a multiple of 4. - */ - - int line_height; /* Height of each text line (usually identical to height) */ - int height; /* Height for all characters, in pixel rows */ - int char_size; /* Amount of memory occupied by one character in data */ - - byte *data; /* Font data, consisting of 'chars_nr' entries of 'height' rows - ** of 'row_size' bytes. For each character ch, its first byte - ** (the topmost row) is located at (data + (charsize * ch)), and - ** its pixel width is widths[ch], provided that (ch < chars_nr). - */ - +/** + * Bitmap font information. + */ +struct gfx_bitmap_font_t { + int ID; /**< Unique resource ID */ + int chars_nr; /**< Numer of available characters */ + int *widths; /**< chars_nr character widths, in pixels */ + int row_size; /** + * Byte size of each pixel row. For unscaled fonts, + * this is always 1, 2, or 4. Otherwise, it's a + * multiple of 4. + */ + int line_height; /** + * Height of each text line (usually identical to + * height) + */ + int height; /**< Height for all characters, in pixel rows */ + int char_size; /** + * Amount of memory occupied by one character + * in data + */ + byte *data; /** + * Font data, consisting of 'chars_nr' entries + * of 'height' rows of 'row_size' bytes. For each + * character ch, its first byte (the topmost row) + * is located at (data + (charsize * ch)), and its + * pixel width is widths[ch], provided that + * (ch < chars_nr). + */ }; -/*******************/ -/* Font operations */ -/*******************/ - -/* SCI0, SCI01 and SCI1 all use the same font format. */ +/** + * Font handling flags. + * + * SCI0, SCI01 and SCI1 all use the same font format. + */ enum fontFlags { - kFontCountWhitespace = 1 << 0, // In SQ3, whitespace is included in text size - kFontNoNewlines = 1 << 1, // Don't treat newline characters - kFontIgnoreLF = 1 << 2 // Interpret CR LF sequences as a single newline, rather than two + kFontCountWhitespace = 1 << 0, //!< In SQ3, whitespace is included in text size + kFontNoNewlines = 1 << 1, //!< Don't treat newline characters + kFontIgnoreLF = 1 << 2 //!< Interpret CR LF sequences as a single newline, rather than two }; +/** + * Generates a bitmap font data structure from a resource. + * + * @param[in] id Resource ID of the resulting font + * @param[in] resource Pointer to the resource data + * @param[in] size Size of the resource block + * @return The resulting font structure, or NULL on error + */ gfx_bitmap_font_t *gfxr_read_font(int id, byte *resource, int size); -/* Generates a bitmap font data structure from a resource -** Parameters: (int) id: Resource ID of the resulting font -** (byte *) resource: Pointer to the resource data -** (int) size: Size of the resource block -** Returns : (gfx_bitmap_font_t *) The resulting font structure, or -** NULL on error -*/ +/** + * Frees a previously allocated font structure. + * + * @param font The font to free + */ void gfxr_free_font(gfx_bitmap_font_t *font); -/* Frees a previously allocated font structure -** Parameters: (gfx_bitmap_font_t *) font: The font to free -** Returns : (void) -*/ +/** + * Calculates the size that would be occupied by drawing a specified + * text. + * + * This function assumes 320x200 mode. + * + * @param[in] font The font to calculate with + * @param[in] max_width Maximum pixel width allowed for the output + * @param[in] text The text to calculate for + * @param[in] flags Any text formatting flags + * @param[out] fragments A newly allocated array of text_fragments, + * containing the start and size of each string + * segment. + * @param[out] width The resulting width + * @param[out] height The resulting height + * @param[out] line_height Pixel height of a single line of text + * @param[out] last_offset Pixel offset after the last drawn line + * @return true if successful, false otherwise + */ bool gfxr_font_calculate_size(Common::Array<TextFragment> &fragments, gfx_bitmap_font_t *font, int max_width, const char *text, int *width, int *height, int *line_height, int *last_offset, int flags); -/* Calculates the size that would be occupied by drawing a specified text -** Parameters: (gfx_bitmap_font_t *) font: The font to calculate with -** (int) max_width: Maximum pixel width allowed for the output -** (const char *) text: The text to calculate for -** (int) flags: Any text formatting flags -** Returns : (text_fragment *) a newly allocated array of text_fragments, -** containing the start and size of each string -** segment -** (int) *width: The resulting width -** (int) *height: The resulting height -** (int) *line_height: Pixel height of a single line of text -** (int) *last_offset: Pixel offset after the last drawn line -** This function assumes 320x200 mode. -*/ - -gfx_pixmap_t *gfxr_draw_font(gfx_bitmap_font_t *font, const char *text, int characters, - PaletteEntry *fg0, PaletteEntry *fg1, PaletteEntry *bg); -/* Draws text in a specific font to a pixmap -** Parameters: (gfx_bitmap_font_t *) font: The font to use for drawing -** (char *) text: The start of the text to draw -** (int) characters: The number of characters to draw -** (gfx_pixmap_color_t *) fg0: The first foreground color -** (gfx_pixmap_color_t *) fg1: The second foreground color -** (gfx_pixmap_color_t *) bg: The background color -** Returns : (gfx_pixmap_t *) The result pixmap, or NULL on error -** The results are written to the pixmap's index buffer. Contents of the -** foreground and background fields are copied into a newly allocated font -** structure, so that the pixmap may be translated directly. -** If any of the colors is null, it will be assumed to be transparent. -** In color index mode, the specified colors have to be preallocated. -*/ + +/** + * Draws text in a specific font to a pixmap. + * + * The results are written to the pixmap's index buffer. Contents of the + * foreground and background fields are copied into a newly allocated font + * structure, so that the pixmap may be translated directly. If any of the + * colors is null, it will be assumed to be transparent. + * In color index mode, the specified colors have to be preallocated. + * + * @param[in] font The font to use for drawing + * @param[in] text The start of the text to draw + * @param[in] characters The number of characters to draw + * @param[in] fg0 The first foreground color + * @param[in] fg1 The second foreground color + * @param[in] bg The background color + * @return The result pixmap, or NULL on error + */ +gfx_pixmap_t *gfxr_draw_font(gfx_bitmap_font_t *font, const char *text, + int characters, PaletteEntry *fg0, PaletteEntry *fg1, + PaletteEntry *bg); +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_driver.h b/engines/sci/gfx/gfx_driver.h index b74511de77..f7cbd0b6c2 100644 --- a/engines/sci/gfx/gfx_driver.h +++ b/engines/sci/gfx/gfx_driver.h @@ -38,171 +38,202 @@ enum gfx_buffer_t { }; -/* Principial graphics driver architecture -** --------------------------------------- -** -** All graphics drivers must provide -** - One visual front buffer (the actually visible thing) -** - Two dynamic back buffers: -** + visual -** + priority -** - Two static buffers (containing the background image and picviews): -** + visual -** + priority -** -** The control buffer is handled outside the graphics driver architecture. -** Graphics are drawn by first setting the static buffers, then updating -** the back buffers (from the static buffers), adding all picviews and other -** widgets, and finally updating the front buffer. -** -** All coordinates refer to the scaled coordinate system. -** Invalid parameters should produce an error message. -** Support for some valid parameter values is optional (like different line -** modes). If an unsupported but valid parameter is specified, the function -** must use a reasonable default value. -*/ - +/** + * Graphics driver. + * + * Principial graphics driver architecture: + * + * All graphics drivers must provide + * - One visual front buffer (the actually visible thing) + * - Two dynamic back buffers: + * - visual + * - priority + * - Two static buffers (containing the background image and picviews): + * - visual + * - priority + * + * The control buffer is handled outside the graphics driver architecture. + * Graphics are drawn by first setting the static buffers, then updating + * the back buffers (from the static buffers), adding all picviews and other + * widgets, and finally updating the front buffer. + * + * All coordinates refer to the scaled coordinate system. + * Invalid parameters should produce an error message. + * Support for some valid parameter values is optional (like different line + * modes). If an unsupported but valid parameter is specified, the function + * must use a reasonable default value. + */ class GfxDriver { public: - /*** Initialization ***/ - + /** @name Initialization */ + /** @{ */ + /** + * Attempts to initialize a specific graphics mode. + * + * The scaling factors apply to the standard SCI resolution of 320x200 + * pixels and is used for internal representation of graphical data. + * The physical resolution set by the graphics driver may be different + * for practical reasons. + * Must also set _mode, preferably with the gfx_new_mode() function + * specified in gfx_tools.h. + * + * @param[in] xfact Horizontal scaling factor + * @param[in] yfact Vertical scaling factor + * @param[in] bytespp Any of GFX_COLOR_MODE_*. GFX_COLOR_MODE_INDEX + * implies color index mode. + * @return GFX_OK on success, GFX_ERROR if the mode could + * not be set, or GFX_FATAL if the graphics target + * is unuseable. + */ GfxDriver(int xfact, int yfact, int bytespp); - /* Attempts to initialize a specific graphics mode - ** Parameters: (int x int) xres, yres: Horizontal and vertical scaling - ** factors - ** (int) bytespp: Any of GFX_COLOR_MODE_*. GFX_COLOR_MODE_INDEX - ** implies color index mode. - ** Returns : (int) GFX_OK on success, GFX_ERROR if the mode could not be - ** set, or GFX_FATAL if the graphics target is unuseable. - ** The scaling factors apply to the standard SCI resolution of 320x200 pixels - ** and is used for internal representation of graphical data. The physical - ** resolution set by the graphics driver may be different for practical - ** reasons. - ** Must also set _mode, preferably with the gfx_new_mode() function - ** specified in gfx_tools.h. - */ + /** + * Uninitializes the current graphics mode. + * + * This function frees all memory allocated by the graphics driver, + * including mode and palette information, uninstalls all console + * commands introduced by preceeding init() or init_specific() + * commands, and does any clean-up work (like closing visuals or + * returning to text mode) required by the graphics infrastructure used. + */ ~GfxDriver(); - /* Uninitializes the current graphics mode - ** This function frees all memory allocated by the graphics driver, - ** including mode and palette information, uninstalls all console commands - ** introduced by preceeding init() or init_specific() commands, and does any - ** clean-up work (like closing visuals or returning to text mode) required by - ** the graphics infrastructure used. - */ - - - /*** Drawing operations ***/ - + /** @} */ + + /** @name Drawing operations */ + /** @{ */ + + /** + * Draws a single line to the back buffer. + * + * Note that color.priority is relevant and must be drawn if + * (color.mask & GFX_MASK_PRIORITY). Support for line modes other than + * GFX_LINE_MODE_FAST is optional. For non-fine lines, the coordinates + * provided describe the upper left corner of the pixels of the line + * to draw.line_style support is optional, if + * GFX_CAPABILITY_STIPPLED_LINES is not set. + * + * @param[in] start Starting point of the line to draw + * @param[in] end End point of the line to draw + * @param[in] color The color to draw with + * @param[in] line_mode Any of the line modes + * @param[in] line_style Any of the line styles + * @return GFX_OK or GFX_FATAL + */ int drawLine(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); - /* Draws a single line to the back buffer. - ** Parameters: (Common::Point) start: Starting point of the line to draw - ** (Common::Point) end: End point of the line to draw - ** (gfx_color_t *) color: The color to draw with - ** (int) line_mode: Any of the line modes - ** (int) line_style: Any of the line styles - ** Returns : (int) GFX_OK or GFX_FATAL - ** Note that color.priority is relevant and must be drawn if - ** (color.mask & GFX_MASK_PRIORITY). - ** Support for line modes other than GFX_LINE_MODE_FAST is optional. - ** For non-fine lines, the coordinates provided describe the upper left - ** corner of the pixels of the line to draw. - ** line_style support is optional, if GFX_CAPABILITY_STIPPLED_LINES is not - ** set. - */ + /** + * Draws a single filled and possibly shaded rectangle to the back + * buffer. + * + * Note that color.priority is relevant and must be drawn if + * (color.mask & GFX_MASK_PRIORITY). color2 is relevant only if + * shade_mode is not GFX_SHADE_FLAT. Support for shade modes other + * than GFX_SHADE_FLAT is optional. + * + * @param[in] rect The rectangle to draw + * @param[in] color1 The first color to draw with + * @param[in] color2 The second color to draw with + * @param[in] shade_mode Any of GFX_SHADE_*. + * @return GFX_OK or GFX_FATAL + */ int drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color2, gfx_rectangle_fill_t shade_mode); - /* Draws a single filled and possibly shaded rectangle to the back buffer. - ** Parameters: (rect_t *) rect: The rectangle to draw - ** (gfx_color_t *) color1, color2: The colors to draw with - ** (int) shade_mode: Any of GFX_SHADE_*. - ** Returns : (int) GFX_OK or GFX_FATAL - ** Note that color.priority is relevant and must be drawn if - ** (color.mask & GFX_MASK_PRIORITY). - ** color2 is relevant only if shade_mode is not GFX_SHADE_FLAT. - ** Support for shade modes other than GFX_SHADE_FLAT is optional. - */ - - /*** Pixmap operations ***/ - + /** @} */ + + /** @name Pixmap operations */ + /** @{ */ + + /** + * Draws part of a pixmap to the static or back buffer. + * + * @param[in] pxm The pixmap to draw + * @param[in] priority The priority to draw with, or GFX_NO_PRIORITY + * to draw on top of everything without setting the + * priority back buffer. + * @param[in] src The pixmap-relative source rectangle + * @param[in] dest The destination rectangle + * @param[in] buffer One of GFX_BUFFER_STATIC and GFX_BUFFER_BACK + * @return GFX_OK or GFX_FATAL, or GFX_ERROR if pxm was + * not (but should have been) registered. + */ int drawPixmap(gfx_pixmap_t *pxm, int priority, rect_t src, rect_t dest, gfx_buffer_t buffer); - /* Draws part of a pixmap to the static or back buffer - ** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw - ** (int) priority: The priority to draw with, or GFX_NO_PRIORITY - ** to draw on top of everything without setting the - ** priority back buffer - ** (rect_t) src: The pixmap-relative source rectangle - ** (rect_t) dest: The destination rectangle - ** (int) buffer: One of GFX_BUFFER_STATIC and GFX_BUFFER_BACK - ** Returns : (int) GFX_OK or GFX_FATAL, or GFX_ERROR if pxm was not - ** (but should have been) registered. - */ + /** + * Grabs an image from the visual or priority back buffer. + * + * This function is now mandatory. + * + * @param[in] src The rectangle to grab + * @param[in] pxm The pixmap structure the data is to be written to + * @param[in] map GFX_MASK_VISUAL or GFX_MASK_PRIORITY + * @return GFX_OK, GFX_FATAL, or GFX_ERROR for invalid map + * values pxm may be assumed to be empty and + * pre-allocated with an appropriate memory size. + */ int grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map); - /* Grabs an image from the visual or priority back buffer - ** Parameters: (rect_t) src: The rectangle to grab - ** (gfx_pixmap_t *) pxm: The pixmap structure the data is to - ** be written to - ** (int) map: GFX_MASK_VISUAL or GFX_MASK_PRIORITY - ** Returns : (int) GFX_OK, GFX_FATAL, or GFX_ERROR for invalid map values - ** pxm may be assumed to be empty and pre-allocated with an appropriate - ** memory size. - ** This function is now mandatory. - */ - - - /*** Buffer operations ***/ - + /** @} */ + + /** @name Buffer operations */ + /** @{ */ + + /** + * Updates the front buffer or the back buffers. + * + * This function updates either the visual front buffer, or the two + * back buffers, by copying the specified source region to the + * destination region. + * For heuristical reasons, it may be assumed that the x and y fields + * of src and dest will be identical in /most/ cases.If they aren't, + * the priority map will not be required to be copied. + * + * @param[in] src: Source rectangle + * @param[in] dest: Destination point + * @param[in] buffer: One of GFX_BUFFER_FRONT or GFX_BUFFER_BACK + * @return GFX_OK, GFX_ERROR or GFX_FATAL + */ int update(rect_t src, Common::Point dest, gfx_buffer_t buffer); - /* Updates the front buffer or the back buffers - ** Parameters: (rect_t) src: Source rectangle - ** (Common::Point) dest: Destination point - ** (int) buffer: One of GFX_BUFFER_FRONT or GFX_BUFFER_BACK - ** Returns : (int) GFX_OK, GFX_ERROR or GFX_FATAL - ** This function updates either the visual front buffer, or the two back - ** buffers, by copying the specified source region to the destination - ** region. - ** For heuristical reasons, it may be assumed that the x and y fields of - ** src and dest will be identical in /most/ cases. - ** If they aren't, the priority map will not be required to be copied. - */ + /** + * Sets the contents of the static visual and priority buffers. + * + * pic and priority may be modified or written to freely. They may also + * be used as the actual static buffers, since they are not freed and + * reallocated between calls to set_static_buffer() and update(), + * unless exit() was called in between. + * Note that later version of the driver interface may disallow + * modifying pic and priority. pic and priority are always scaled to + * the appropriate resolution + * + * @param[in] pic The image defining the new content of the + * visual back buffer + * @param[in] priority The priority map containing the new content of + * the priority back buffer in the index buffer + * @return GFX_OK or GFX_FATAL + */ int setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority); - /* Sets the contents of the static visual and priority buffers - ** Parameters: (gfx_pixmap_t *) pic: The image defining the new content - ** of the visual back buffer - ** (gfx_pixmap_t *) priority: The priority map containing - ** the new content of the priority back buffer - ** in the index buffer - ** Returns : (int) GFX_OK or GFX_FATAL - ** pic and priority may be modified or written to freely. They may also be - ** used as the actual static buffers, since they are not freed and re- - ** allocated between calls to set_static_buffer() and update(), unless - ** exit() was called in between. - ** Note that later version of the driver interface may disallow modifying - ** pic and priority. - ** pic and priority are always scaled to the appropriate resolution - */ - - - /*** Mouse pointer operations ***/ - + /** @} */ + + /** @name Mouse pointer operations */ + /** @{ */ + + /** + * Sets a new mouse pointer. + * + * If pointer is not NULL, it will have been scaled to the appropriate + * size and registered as a pixmap (if neccessary) beforehand. If this + * function is called for a target that supports only two-color + * pointers, the image is a color index image, where only color index + * values 0, 1, and GFX_COLOR_INDEX_TRANSPARENT are used. + * + * @param[in] pointer The pointer to set, or NULL to set no pointer. + * @param[in] hotspot The coordinates of the hotspot, or NULL to set + * no pointer. + * @return GFX_OK or GFX_FATAL + */ int setPointer(gfx_pixmap_t *pointer, Common::Point *hotspot); - /* Sets a new mouse pointer. - ** Parameters: (gfx_pixmap_t *) pointer: The pointer to set, or NULL to set - ** no pointer - ** (Common::Point *) hotspot: The coordinates of the hotspot, - ** or NULL to set no pointer - ** Returns : (int) GFX_OK or GFX_FATAL - ** If pointer is not NULL, it will have been scaled to the appropriate - ** size and registered as a pixmap (if neccessary) beforehand. - ** If this function is called for a target that supports only two-color - ** pointers, the image is a color index image, where only color index values - ** 0, 1, and GFX_COLOR_INDEX_TRANSPARENT are used. - */ + /** @} */ gfx_mode_t *getMode() { return _mode; } byte *getVisual0() { return _visual[0]; } @@ -212,7 +243,7 @@ private: gfx_pixmap_t *_priority[2]; byte *_visual[2]; - gfx_mode_t *_mode; /* Currently active mode, NULL if no mode is active */ + gfx_mode_t *_mode; /**< Currently active mode, NULL if no mode is active */ }; } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_gui.cpp b/engines/sci/gfx/gfx_gui.cpp index f73a13d6dd..fb05c0fe29 100644 --- a/engines/sci/gfx/gfx_gui.cpp +++ b/engines/sci/gfx/gfx_gui.cpp @@ -266,7 +266,7 @@ static rect_t _move_and_extend_rect(rect_t rect, Common::Point point, int yplus) return gfx_rect(rect.x + point.x, rect.y + point.y, rect.width + 1, rect.height + yplus); } -GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, char *text, +GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, const char *text, int font, gfx_alignment_t align, char framed, char inverse, int flags, char gray_text) { gfx_color_t *color1, *color2, *bgcolor; @@ -294,7 +294,7 @@ GfxList *_sciw_add_text_to_list(GfxList *list, GfxPort *port, rect_t zone, char return list; } -GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, char selected, char inverse, char grayed_out) { +GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, char selected, char inverse, char grayed_out) { gfx_color_t *frame_col = (inverse) ? &(port->_bgcolor) : &(port->_color); GfxList *list; @@ -332,7 +332,7 @@ GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, char *tex return list; } -GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, +GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, gfx_alignment_t align, char framed, char inverse) { GfxList *list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 2), 0); @@ -344,7 +344,7 @@ GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, char *text, return _sciw_add_text_to_list(list, port, zone, text, font, align, framed, inverse, 0, port->gray_text); } -GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, unsigned int cursor, +GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, const char *text, int font, unsigned int cursor, char inverse) { GfxText *text_handle; @@ -440,7 +440,7 @@ GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, int view, i return list; } -GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, char **entries_list, +GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, const char **entries_list, int entries_nr, int list_top, int selection, char inverse) { GfxList *list; diff --git a/engines/sci/gfx/gfx_gui.h b/engines/sci/gfx/gfx_gui.h index e712d30660..68342aa0c0 100644 --- a/engines/sci/gfx/gfx_gui.h +++ b/engines/sci/gfx/gfx_gui.h @@ -23,8 +23,6 @@ * */ -/* SCI-specific widget handling */ - #ifndef SCI_INCLUDE_SCI_WIDGETS_H #define SCI_INCLUDE_SCI_WIDGETS_H @@ -34,152 +32,196 @@ namespace Sci { class Menu; -// The following flags are applicable to windows in SCI0 +/* SCI-specific widget handling */ + +/** + * Flags for windows in SCI0. + */ enum windowFlags { - kWindowTransparent = 0x01, // 0000 0001 - kWindowNoFrame = 0x02, // 0000 0010 - a window without a frame - // Add title bar to window (10 pixels high, framed, text is centered and written in white on dark gray) - kWindowTitle = 0x04, // 0000 0100 - // bits 3-6 are unused - kWindowDontDraw = 0x80, // 1000 0000 - don't draw anything - kWindowNoDropShadow = 0x1000000, // 0001 0000 0000 0000 0000 0000 0000 (not in SCI) + kWindowTransparent = 0x01, //!< 0000 0001 + kWindowNoFrame = 0x02, //!< 0000 0010 - a window without a frame + kWindowTitle = 0x04, /** + * 0000 0100 - Add title bar to + * window (10 pixels high, framed, + * text is centered and written in + * white on dark gray), bits 3-6 + * are unused + */ + kWindowDontDraw = 0x80, //!< 1000 0000 - don't draw anything + kWindowNoDropShadow = 0x1000000, //!< 0001 0000 0000 0000 0000 0000 0000 (not in SCI) kWindowAutoRestore = 0x2000000 }; +/** Button and frame control flags. */ enum controlStateFlags { - kControlStateEnabled = 0x0001, // 0001 - enabled buttons (used by the interpreter) - kControlStateDisabled = 0x0004, // 0010 - grayed out buttons (used by the interpreter) - kControlStateFramed = 0x0008, // 1000 - widgets surrounded by a frame (used by the interpreter) - kControlStateDitherFramed = 0x1000 // 0001 0000 0000 0000 - widgets surrounded by a dithered frame (used in kgraphics) + kControlStateEnabled = 0x0001, //!< 0001 - enabled buttons (used by the interpreter) + kControlStateDisabled = 0x0004, //!< 0010 - grayed out buttons (used by the interpreter) + kControlStateFramed = 0x0008, //!< 1000 - widgets surrounded by a frame (used by the interpreter) + kControlStateDitherFramed = 0x1000 //!< 0001 0000 0000 0000 - widgets surrounded by a dithered frame (used in kgraphics) }; -void sciw_set_status_bar(EngineState *s, GfxPort *status_bar, const Common::String &text, int fgcolor, int bgcolor); -/* Sets the contents of a port used as status bar -** Parmeters: (EngineState *) s: The affected game state -** (GfxPort *) status_bar: The status bar port -** (const char *) text: The text to draw -** Returns : (void) -*/ - -GfxPort *sciw_new_window(EngineState *s, rect_t area, int font, gfx_color_t color, gfx_color_t bgcolor, - int title_font, gfx_color_t title_color, gfx_color_t title_bg_color, - const char *title, int flags); -/* Creates a new SCI style window -** Parameters: (EngineState *) s: The affected game state -** (rect_t) area: The screen area to frame (not including a potential window title) -** (int) font: Default font number to use -** (gfx_color_t) color: The foreground color to use for drawing -** (gfx_color_t) bgcolor: The background color to use -** (int) title_font: The font to use for the title bar (if any) -** (gfx_color_t) title_color: Color to use for the title bar text -** (gfx_color_t) title_bg_color: Color to use for the title bar background -** (const char *) title: The text to write into the title bar -** (int) flags: Any ORred combination of window flags -** Returns : (GfxPort *) A newly allocated port with the requested characteristics -*/ - -/*---------------------*/ -/*** Control widgets ***/ -/*---------------------*/ - -GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, char selected, char inverse, char gray); -/* Creates a new button control list -** Parameters: (GfxPort *) port: The port containing the color values to use for the -** button (the button is /not/ appended to the port there) -** (reg_t) ID: Button's ID -** (rect_t) zone: The area occupied by the button -** (char *) text: The text to write into the button -** (int) font: The font to use for the button -** (char) selected: Whether the button should be marked as being selected by the keyboard focus -** (char) inverse: Whether to inverse the color scheme -** (char) gray: Whether the button should be grayed out -** Returns : (GfxList *) The button -*/ - -GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, - gfx_alignment_t align, char frame, char inverse); -/* Creates a new text control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (reg_t) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (char *) text: The text -** (int) font: The font the text is to be drawn in -** (gfx_alignment_t) align: Horizontal text alignment to use -** (char) frame: Whether a dithered frame should surround the text -** (char) inverse: Whether the text colors should be inversed -** Returns : (GfxList *) The text control widget list -*/ - -GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, char *text, int font, unsigned int cursor, - char inverse); -/* Creates a new edit control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (reg_t) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (char *) text: The text -** (int) font: The font the text is to be drawn in -** (int) cursor: Cursor position -** (char) inverse: Whether the edit widget should be reversed -** Returns : (GfxList *) An appropriate widget list -*/ - -GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, int view, int loop, int cel, - char frame, char inverse); -/* Creates a new icon control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (reg_t) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (int x int x int) view, loop, cel: The cel to display -** (char) frame: Whether the widget should be surrounded by a frame -** (char) lina inverse: Whether colors should be inversed -** Returns : (GfxList *) An appropriate widget list -*/ - -GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, int font_nr, char **entries_list, - int entries_nr, int list_top, int selection, char inverse); -/* Creates a new list control list -** Parameters: (GfxPort *) port: The port containing the color values to use -** (int) ID: Text widget ID -** (rect_t) zone: Area occupied by the text -** (int) font_nr: number of the font to use -** (char **) entries_list: List of strings to contain within the list -** (int) entries_nr: Number of entries in entries_list -** (int) list_top: First list item that is visible -** (int) selection: The list item that is selected -** (char) invserse: The usual meaning -** Returns : (GfxList *) An appropriate widget list -*/ - -/*---------------------*/ -/*** Menubar widgets ***/ -/*---------------------*/ - -void sciw_set_menubar(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection); -/* Draws the menu bar -** Parameters: (EngineState *) s: The state to operate on -** (GfxPort *) status_bar: The status bar port to modify -** (Menubar *) menubar: The menu bar to use -** (int) selection: Number of the menu to hightlight, or -1 for 'none' -** Returns : (void) -*/ - -GfxPort *sciw_new_menu(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection); -/* Creates a menu port -** Parameters: (EngineState *) s: The state to operate on -** (GfxPort *) status_bar: The status bar -** (Menubar *) menubar: The menu bar to use -** (int) selection: Number of the menu to interpret -** Returns : (GfxPort *) The result port -*/ - -GfxPort *sciw_toggle_item(GfxPort *menu_port, Menu *menu, int selection, bool selected); -/* Toggle the selection of a menu item from a menu port -** Parameters: (GfxPort *) menu_port: The port to modify -** (Menu *) menu: The menu the menu port corresponds to -** (int) selection: Number of the menu entry to unselect, or -1 to do a NOP -** (bool) selected: Whether to set the item's state to selected or not -** Returns : (GfxPort *) The modified menu -*/ +/** + * Sets the contents of a port used as status bar. + * + * @param[in] s The affected EngineState + * @param[in] status_bar The status bar port + * @param[in] text The text to draw + * @param[in] fgcolor The foreground color + * @param[in] bgcolor The background color + */ +void sciw_set_status_bar(EngineState *s, GfxPort *status_bar, + const Common::String &text, int fgcolor, int bgcolor); + +/** + * Creates a new SCI style window. + * + * @param[in] s The affected EngineState + * @param[in] area The screen area to frame (not including a + * potential window title) + * @param[in] font Default font number to use + * @param[in] color The foreground color to use for drawing + * @param[in] bgcolor The background color to use + * @param[in] title_font The font to use for the title bar (if any) + * @param[in] title_color Color to use for the title bar text + * @param[in] title_bg_color Color to use for the title bar background + * @param[in] title The text to write into the title bar + * @param[in] flags Any ORred combination of window flags + * @return A newly allocated port with the requested characteristics + */ +GfxPort *sciw_new_window(EngineState *s, rect_t area, int font, + gfx_color_t color, gfx_color_t bgcolor, int title_font, + gfx_color_t title_color, gfx_color_t title_bg_color, + const char *title, int flags); + + +/** @name Control widgets */ +/** @{ */ +/** + * Creates a new button control list. + * + * @param[in] port The port containing the color values to use for the + * button (the button is /not/ appended to the port + * there) + * @param[in] ID Button's ID + * @param[in] zone The area occupied by the button + * @param[in] text The text to write into the button + * @param[in] font The font to use for the button + * @param[in] selected Whether the button should be marked as being + * selected by the keyboard focus + * @param[in] inverse Whether to inverse the color scheme + * @param[in] gray Whether the button should be grayed out + * @return The button + */ +GfxList *sciw_new_button_control(GfxPort *port, reg_t ID, rect_t zone, + const char *text, int font, char selected, char inverse, char gray); + +/** + * Creates a new text control list. + * + * @param[in] port The port containing the color values to use + * @param[in] ID Text widget ID + * @param[in] zone Area occupied by the text + * @param[in] text The text + * @param[in] font The font the text is to be drawn in + * @param[in] align Horizontal text alignment to use + * @param[in] frame Whether a dithered frame should surround the text + * @param[in] inverse Whether the text colors should be inversed + * @return The text control widget list + */ +GfxList *sciw_new_text_control(GfxPort *port, reg_t ID, rect_t zone, + const char *text, int font, gfx_alignment_t align, char frame, + char inverse); + +/** + * Creates a new edit control list. + * + * @param[in] port The port containing the color values to use + * @param[in] ID Text widget ID + * @param[in] zone Area occupied by the text + * @param[in] text The text + * @param[in] font The font the text is to be drawn in + * @param[in] cursor Cursor position + * @param[in] inverse Whether the edit widget should be reversed + * @return An appropriate widget list + */ +GfxList *sciw_new_edit_control(GfxPort *port, reg_t ID, rect_t zone, + const char *text, int font, unsigned int cursor, char inverse); + +/** + * Creates a new icon control list. + * + * @param[in] port The port containing the color values to use + * @param[in] ID Text widget ID + * @param[in] zone Area occupied by the text + * @param[in] view The view index + * @param[in] loop The loop index + * @param[in] cel The cel to display + * @param[in] frame Whether the widget should be surrounded by a frame + * @param[in] inverse Whether colors should be inversed + * @return An appropriate widget list + */ +GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, + int view, int loop, int cel, char frame, char inverse); + +/** + * Creates a new list control list. + * + * @param[in] port: The port containing the color values to use + * @param[in] ID: Text widget ID + * @param[in] zone: Area occupied by the text + * @param[in] font_nr: Number of the font to use + * @param[in] entries_list: List of strings to contain within the list + * @param[in] entries_nr: Number of entries in entries_list + * @param[in] list_top: First list item that is visible + * @param[in] selection: The list item that is selected + * @param[in] inverse: The usual meaning + * @return An appropriate widget list + */ +GfxList *sciw_new_list_control(GfxPort *port, reg_t ID, rect_t zone, + int font_nr, const char **entries_list, int entries_nr, + int list_top, int selection, char inverse); +/** @} */ + +/** @name Menubar widgets */ +/** @{ */ + +/** + * Draws the menu bar. + * + * @param[in] s: The EngineState to operate on + * @param[in] status_bar: The status bar port to modify + * @param[in] menubar: The menu bar to use + * @param[in] selection: Number of the menu to hightlight, or -1 for + * 'none' + */ +void sciw_set_menubar(EngineState *s, GfxPort *status_bar, Menubar *menubar, + int selection); + +/** + * Creates a menu port. + * + * @param[in] s The state to operate on + * @param[in] status_bar The status bar + * @param[in] menubar The menu bar to use + * @param[in] selection Number of the menu to interpret + * @return The result port + */ +GfxPort *sciw_new_menu(EngineState *s, GfxPort *status_bar, + Menubar *menubar, int selection); + +/** + * Toggle the selection of a menu item from a menu port. + * + * @param[in] menu_port The port to modify + * @param[in] menu The menu the menu port corresponds to + * @param[in] selection Number of the menu entry to unselect, or -1 to do + * a NOP + * @param[in] selected Whether to set the item's state to selected or not + * @return The modified menu + */ +GfxPort *sciw_toggle_item(GfxPort *menu_port, Menu *menu, int selection, + bool selected); +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_options.h b/engines/sci/gfx/gfx_options.h index 393627a1a2..2e2b853562 100644 --- a/engines/sci/gfx/gfx_options.h +++ b/engines/sci/gfx/gfx_options.h @@ -42,20 +42,20 @@ namespace Sci { -/* Dirty rectangle heuristics: */ - -/* One: Redraw one rectangle surrounding the dirty area (insert is O(1)) */ -#define GFXOP_DIRTY_FRAMES_ONE 1 - -/* Clusters: Accumulate dirty rects, merging those that overlap (insert is O(n)) */ -#define GFXOP_DIRTY_FRAMES_CLUSTERS 2 +/** Dirty rectangle heuristics. */ +enum { + GFXOP_DIRTY_FRAMES_ONE = 1, /**< One: Redraw one rectangle surrounding the dirty area (insert is O(1)) */ + GFXOP_DIRTY_FRAMES_CLUSTERS = 2 /**< Clusters: Accumulate dirty rects, merging those that overlap (insert is O(n)) */ +}; +/** + * All user options to the rendering pipeline + * + * See note in sci_conf.h for config_entry_t before changing types of + * variables + */ struct gfx_options_t { #ifdef CUSTOM_GRAPHICS_OPTIONS - /* gfx_options_t: Contains all user options to the rendering pipeline */ - /* See note in sci_conf.h for config_entry_t before changing types of - ** variables */ - int buffer_pics_nr; /* Number of unused pics to buffer */ /* SCI0 pic resource options */ diff --git a/engines/sci/gfx/gfx_res_options.h b/engines/sci/gfx/gfx_res_options.h index f01f93d21b..a595c56606 100644 --- a/engines/sci/gfx/gfx_res_options.h +++ b/engines/sci/gfx/gfx_res_options.h @@ -23,8 +23,6 @@ * */ -/* Configuration options for per-resource customisations */ - #ifndef SCI_GFX_GFX_RES_OPTIONS_H #define SCI_GFX_GFX_RES_OPTIONS_H @@ -35,13 +33,16 @@ #include "sci/gfx/gfx_resmgr.h" namespace Sci { +/** @name Configuration options for per-resource customisations */ +/** @{ */ struct gfx_res_pattern_t { int min, max; }; -/* GFX resource assignments */ - +/** + * GFX resource assignments. + */ struct gfx_res_assign_t { union { struct { @@ -52,23 +53,24 @@ struct gfx_res_assign_t { }; -/* GFX resource modifications */ - +/** + * GFX resource modifications/ + */ struct gfx_res_conf_t { - int type; /* Resource type-- only one allowed */ + int type; /**< Resource type-- only one allowed */ /* If any of the following is 0, it means that there is no restriction. ** Otherwise, one of the patterns associated with them must match. */ - int patterns_nr; /* Number of patterns (only 'view' patterns for views) */ - int loops_nr, cels_nr; /* Number of loop/cel patterns, for views only. + int patterns_nr; /**< Number of patterns (only 'view' patterns for views) */ + int loops_nr, cels_nr; /**< Number of loop/cel patterns, for views only. ** For pics, loops_nr identifies the palette. */ gfx_res_pattern_t *patterns; union { gfx_res_assign_t assign; - byte factor[3]; /* divide by 16 to retrieve factor */ - } conf; /* The actual configuration */ + byte factor[3]; /**< divide by 16 to retrieve factor */ + } conf; /**< The actual configuration */ gfx_res_conf_t *next; }; @@ -84,16 +86,20 @@ struct gfx_res_fullconf_t { struct gfx_options_t; +/** + * Configures a graphical pixmap according to config options. + * + * Modifies pxm as considered appropriate by configuration options. Does + * not do anything in colour index mode. + * + * @param[in] options The options according to which configuration + * should be performed + * @param[in] pxm The pixmap to configure + * @return 0 on success, non-zero otherwise + */ int gfx_get_res_config(gfx_options_t *options, gfx_pixmap_t *pxm); -/* Configures a graphical pixmap according to config options -** Parameters: (gfx_options_t *) options: The options according to which -** configuration should be performed -** (gfx_resource_type_t) pxm: The pixmap to configure -** Returns : (int) 0 on success, non-zero otherwise -** Modifies pxm as considered appropriate by configuration options. Does -** not do anything in colour index mode. -*/ +/** @} */ } // End of namespace Sci #endif diff --git a/engines/sci/gfx/gfx_resmgr.h b/engines/sci/gfx/gfx_resmgr.h index c5878bf529..1f0f58dce9 100644 --- a/engines/sci/gfx/gfx_resmgr.h +++ b/engines/sci/gfx/gfx_resmgr.h @@ -49,7 +49,7 @@ enum gfx_resource_type_t { GFX_RESOURCE_TYPE_PALETTE, /* FIXME: Add PAL resource */ - GFX_RESOURCE_TYPES_NR /* Number of resource types that are to be supported */ + GFX_RESOURCE_TYPES_NR /**< Number of resource types that are to be supported */ }; #define GFX_RESOURCE_TYPE_0 GFX_RESOURCE_TYPE_VIEW @@ -58,12 +58,13 @@ enum gfx_resource_type_t { #define GFXR_RES_TYPE(id) (id >> 16) #define GFXR_RES_NR(id) (id & 0xffff) - +/** Graphics resource */ struct gfx_resource_t { - int ID; /* Resource ID */ - int lock_sequence_nr; /* See description of lock_counter in GfxResManager */ - int mode; /* A mode type hash */ + int ID; /**< Resource ID */ + int lock_sequence_nr; /**< See description of lock_counter in GfxResManager */ + int mode; /**< A mode type hash */ + /** Scaled pic */ union { gfx_pixmap_t *pointer; gfxr_view_t *view; @@ -71,6 +72,7 @@ struct gfx_resource_t { gfxr_pic_t *pic; } scaled_data; + /** Original pic */ union { gfx_pixmap_t *pointer; gfxr_view_t *view; @@ -85,152 +87,204 @@ struct gfx_options_t; typedef Common::HashMap<int, gfx_resource_t *> IntResMap; - +/** Graphics resource manager */ class GfxResManager { public: - GfxResManager(int version, bool isVGA, gfx_options_t *options, GfxDriver *driver, ResourceManager *resManager); + GfxResManager(int version, bool isVGA, gfx_options_t *options, + GfxDriver *driver, ResourceManager *resManager); ~GfxResManager(); - /* Calculates a unique hash value for the specified options/type setup - ** Parameters: (gfx_resource_type_t) type: The type the hash is to be generated for - ** Returns : (int) A hash over the values of the options entries, covering entries iff - ** they are relevant for the specified type - ** Covering more entries than relevant may slow down the system when options are changed, - ** while covering less may result in invalid cached data being used. - ** Only positive values may be returned, as negative values are used internally by the generic - ** resource manager code. - ** Also, only the lower 20 bits are available to the interpreter. - ** (Yes, this isn't really a "hash" in the traditional sense...) - */ + /** + * Calculates a unique hash value for the specified options/type + * setup. + * + * Covering more entries than relevant may slow down the system when + * options are changed, while covering less may result in invalid + * cached data being used. + * Only positive values may be returned, as negative values are used + * internally by the generic resource manager code. + * Also, only the lower 20 bits are available to the interpreter. + * (Yes, this isn't really a "hash" in the traditional sense...) + * + * @param[in] type The type the hash is to be generated for + * @return A hash over the values of the options entries, + * covering entries iff they are relevant for the + * specified type. + */ int getOptionsHash(gfx_resource_type_t type); - /* 'Tags' all resources for deletion - ** Paramters: (void) - ** Returns : (void) - ** Tagged resources are untagged if they are referenced. - */ + /** + * 'Tags' all resources for deletion. + * + * Tagged resources are untagged if they are referenced. + */ void tagResources() { _tagLockCounter++; } - /* Retrieves an SCI0/SCI01 mouse cursor - ** Parameters: (int) num: The cursor number - ** Returns : (gfx_font_t *) The approprate cursor as a pixmap, or NULL on error - */ + /** + * Retrieves an SCI0/SCI01 mouse cursor. + * + * @param[in] num The cursor number + * @return The approprate cursor as a pixmap, or NULL on error + */ gfx_pixmap_t *getCursor(int num); - /* Retrieves the static palette from the interpreter-specific code - ** Parameters: (int *) colors_nr: Number of colors to use - ** (int) nr: The palette to read - ** Returns : (Palette *) static palette - ** if a static palette must be used, NULL otherwise - */ + /** + * Retrieves the static palette from the interpreter-specific code. + * + * @param[in] colors_nr Number of colors to use + * @param[in] num The palette to read + * @return Static palette if a static palette must be + * used, NULL otherwise + */ Palette *getPalette(int *colors_nr, int num = 999); - /* Retrieves a font - ** Parameters: (int) nr: The font number - ** (int) scaled: Whether the font should be font-scaled - ** Returns : (gfx_font_t *) The appropriate font, or NULL on error - */ + /** + * Retrieves a font. + * + * @param[in] num The font number + * @param[in] scaled Whether the font should be font-scaled + * @return The appropriate font, or NULL on error + */ gfx_bitmap_font_t *getFont(int num, bool scaled = false); - /* Retrieves a translated view cel - ** Parameters: - ** (int) nr: The view number - ** (int *) loop: Pointer to a variable containing the loop number - ** (int *) cel: Pointer to a variable containing the cel number - ** (int) palette: The palette to use - ** Returns : (gfx_view_t *) The relevant view, or NULL if nr was invalid - ** loop and cel are given as pointers in order to allow the underlying variables to be - ** modified if they are invalid (this is relevant for SCI version 0, where invalid - ** loop and cel numbers have to be interpreted as 'maximum' or 'minimum' by the interpreter) - */ + /** + * Retrieves a translated view cel. + * + * @param[in] nr The view number + * @param[in] loop Pointer to a variable containing the loop number + * @param[in] cel Pointer to a variable containing the cel number + * @param[in] palette The palette to use + * @return The relevant view, or NULL if nr was invalid + * loop and cel are given as pointers in order to + * allow the underlying variables to be modified + * if they are invalid (this is relevant for SCI + * version 0, where invalid loop and cel numbers + * have to be interpreted as 'maximum' or 'minimum' + * by the interpreter) + */ gfxr_view_t *getView(int nr, int *loop, int *cel, int palette); - /* Retrieves a displayable (translated) pic resource - ** Parameters: (int) nr: Number of the pic resource - ** (int) maps: The maps to translate (ORred GFX_MASK_*) - ** (int) flags: Interpreter-dependant pic flags - ** (int) default_palette: The default palette to use for drawing (if applicable) - ** (bool) scaled: Whether to return the scaled maps, or the unscaled - ** ones (which may be identical) for some special operations. - ** Returns : (gfxr_pic_t *) The appropriate pic resource with all maps as index (but not - ** neccessarily translated) data. - */ - gfxr_pic_t *getPic(int num, int maps, int flags, int default_palette, bool scaled = false); - - - /* Retrieves a displayable (translated) pic resource written ontop of an existing pic - ** Parameters: (int) old_nr: Number of the pic resource to write on - ** (int) new_nr: Number of the pic resource that is to be added - ** (int) flags: Interpreter-dependant pic flags - ** (int) default_palette: The default palette to use for drawing (if applicable) - ** (int) scaled: Whether to return the scaled maps, or the unscaled - ** ones (which may be identical) for some special operations. - ** Returns : (gfxr_pic_t *) The appropriate pic resource with all maps as index (but not - ** neccessarily translated) data. - ** This function invalidates the cached pic pointed to by old_nr in the cache. While subsequent - ** addToPic() writes will still modify the 'invalidated' pic, gfxr_get_pic() operations will - ** cause it to be removed from the cache and to be replaced by a clean version. - */ - gfxr_pic_t *addToPic(int old_nr, int new_nr, int flags, int old_default_palette, int default_palette); - - /* Calculate a picture - ** Parameters: (gfxr_pic_t *) scaled_pic: The pic structure that is to be written to - ** (gfxr_pic_t *) unscaled_pic: The pic structure the unscaled pic is to be written to, - ** or NULL if it isn't needed. - ** (int) flags: Pic drawing flags (interpreter dependant) - ** (int) default_palette: The default palette to use for pic drawing (interpreter dependant) - ** (int) nr: pic resource number - ** Returns : (int) GFX_ERROR if the resource could not be found, GFX_OK otherwise - */ - int calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, int flags, int default_palette, int nr); - - /* Determines whether support for pointers with more than two colors is required - ** Returns : (bool) false if no support for multi-colored pointers is required, true - ** otherwise - */ + /** + * Retrieves a displayable (translated) pic resource. + * + * @param[in] num Number of the pic resource + * @param[in] maps The maps to translate (ORred GFX_MASK_*) + * @param[in] flags Interpreter-dependant pic flags + * @param[in] default_palette The default palette to use for drawing + * (if applicable) + * @param[in] scaled Whether to return the scaled maps, or + * the unscaled ones (which may be + * identical) for some special operations. + * @return The appropriate pic resource with all + * maps as index (but not neccessarily + * translated) data. + */ + gfxr_pic_t *getPic(int num, int maps, int flags, int default_palette, + bool scaled = false); + + + /** + * Retrieves a displayable (translated) pic resource written ontop of + * an existing pic. + * + * This function invalidates the cached pic pointed to by old_nr in the + * cache. While subsequent addToPic() writes will still modify the + * 'invalidated' pic, gfxr_get_pic() operations will cause it to be + * removed from the cache and to be replaced by a clean version. + * + * @param[in] old_nr Number of the pic resource to write on + * @param[in] new_nr Number of the pic resource that is to + * be added + * @param[in] flags Interpreter-dependant pic flags + * @param[in] old_default_palette The default palette of the pic before + * translation + * @param[in] default_palette The default palette to use for drawing + * (if applicable) + * @return The appropriate pic resource with all + * maps as index (but not neccessarily + * translated) data. + */ + gfxr_pic_t *addToPic(int old_nr, int new_nr, int flags, + int old_default_palette, int default_palette); + + /** + * Calculate a picture + * + * @param[in] scaled_pic The pic structure that is to be + * written to + * @param[in] unscaled_pic The pic structure the unscaled pic is + * to be written to, or NULL if it isn't + * needed. + * @param[in] flags Pic drawing flags (interpreter + * dependant) + * @param[in] default_palette The default palette to use for pic + * drawing (interpreter dependant) + * @param[in] nr pic resource number + * @return GFX_ERROR if the resource could not be + * found, GFX_OK otherwise + */ + int calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, + int flags, int default_palette, int nr); + + /** + * Determines whether support for pointers with more than two colors + * is required. + * + * @return false if no support for multi-colored pointers is required, + * true otherwise + */ bool multicoloredPointers() { return _version > SCI_VERSION_1; } - /* Frees all resources currently allocated - ** Parameter: (void) - ** Returns : (void) - ** This function is intended to be used primarily for debugging. - */ + /** + * Frees all resources currently allocated. + * + * This function is intended to be used primarily for debugging. + */ void freeAllResources(); - /* Frees all tagged resources. - ** Parameters: (void) - ** Returns : (void) - ** Resources are tagged by calling gfx_tag_resources(), and untagged by calling the - ** approprate dereferenciation function. - ** Note that this function currently only affects view resources, as pic resources are - ** treated differently, while font and cursor resources are relatively rare. - */ + /** + * Frees all tagged resources. + * + * Resources are tagged by calling gfx_tag_resources(), and untagged by + * calling the approprate dereferenciation function. + * Note that this function currently only affects view resources, as + * pic resources are treated differently, while font and cursor + * resources are relatively rare. + */ void freeTaggedResources(); - /* Frees a previously allocated resource manager, and all allocated resources. - ** Parameters: (void) - ** Return : (void) - */ + /** + * Frees a previously allocated resource manager, and all allocated + * resources. + */ void freeResManager(); - const PaletteEntry &getColor(int color) { return _staticPalette->getColor(color); } + /** + * Retrieves a color from the static palette + */ + const PaletteEntry &getColor(int color) + { + return _staticPalette->getColor(color); + } - // Set static palette and merge it into the global palette + /** + * Set static palette and merge it into the global palette + */ void setStaticPalette(Palette *newPalette); - /* - ** Sets the picture port bounds - */ + /** + * Sets the picture port bounds + */ void changePortBounds(int x1, int y1, int x2, int y2) { _portBounds = Common::Rect(x1, y1, x2, y2); } @@ -252,7 +306,15 @@ public: } #endif - int getColorCount() { return _staticPalette ? _staticPalette->size() : 0; } + /** + * Gets the number of colors in the static palette. + * + * @return Number of pallete entries + */ + int getColorCount() + { + return _staticPalette ? _staticPalette->size() : 0; + } private: int _version; @@ -260,11 +322,11 @@ private: gfx_options_t *_options; GfxDriver *_driver; Palette *_staticPalette; - int _lockCounter; /* Global lock counter; increased for each new resource allocated. - ** The newly allocated resource will then be assigned the new value - ** of the lock_counter, as will any resources referenced afterwards. - */ - int _tagLockCounter; /* lock counter value at tag time */ + int _lockCounter; /**< Global lock counter; increased for each new + * resource allocated. The newly allocated resource will + * then be assigned the new value of the lock_counter, + * as will any resources referenced afterwards. */ + int _tagLockCounter; /**< lock counter value at tag time */ Common::Rect _portBounds; IntResMap _resourceMaps[GFX_RESOURCE_TYPES_NR]; diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h index 8ce4a8ea83..780060bc4f 100644 --- a/engines/sci/gfx/gfx_resource.h +++ b/engines/sci/gfx/gfx_resource.h @@ -23,7 +23,9 @@ * */ -/* SCI Resource library */ +/** @file gfx_resource.h + * SCI Resource library. + */ #ifndef SCI_GFX_GFX_RESOURCE_H #define SCI_GFX_GFX_RESOURCE_H @@ -44,6 +46,7 @@ namespace Sci { #define GFXR_DITHER_MODE_D16 0 /* Sierra SCI style */ #define GFXR_DITHER_MODE_F256 1 /* Flat color interpolation */ #define GFXR_DITHER_MODE_D256 2 /* 256 color dithering */ + /* Dithering patterns */ #define GFXR_DITHER_PATTERN_SCALED 0 /* Dither per pixel on the 320x200 grid */ #define GFXR_DITHER_PATTERN_1 1 /* Dither per pixel on the target */ @@ -64,52 +67,53 @@ namespace Sci { extern int sci0_palette; -/* (gfx_pic_0.c) The 16 EGA base colors */ +/** The 16 EGA base colors */ extern Palette* gfx_sci0_image_pal[]; extern gfx_pixmap_color_t gfx_sci0_image_colors[][16]; -/* (gfx_pic_0.c) The 256 interpolated colors (initialized when -** gfxr_init_pic() is called for the first time, or when gfxr_init_static_palette() is called) -*/ +/** + * The 256 interpolated colors (initialized when gfxr_init_pic() is called + * for the first time, or when gfxr_init_static_palette() is called) + */ extern Palette* gfx_sci0_pic_colors; - struct gfxr_pic0_params_t { gfx_line_mode_t line_mode; /* one of GFX_LINE_MODE_* */ gfx_brush_mode_t brush_mode; }; +/** A SCI resource pic */ struct gfxr_pic_t { - int ID; /* pic number (NOT resource ID, just number) */ + int ID; /**< pic number (NOT resource ID, just number) */ gfx_mode_t *mode; - gfx_pixmap_t *visual_map; - gfx_pixmap_t *priority_map; - gfx_pixmap_t *control_map; - + gfx_pixmap_t *visual_map; /**< Visual part of pic */ + gfx_pixmap_t *priority_map; /**< Priority map for pic */ + gfx_pixmap_t *control_map; /**< Control map for pic */ + + /** + * Auxiliary map. + * Bit 0: Vis + * Bit 1: Pri + * Bit 2: Ctrl + * Bit 3-5: 'filled' (all three bits are set to 1) + */ byte aux_map[GFXR_AUX_MAP_SIZE]; - /* Auxiliary map details: - ** Bit 0: Vis - ** Bit 1: Pri - ** Bit 2: Ctrl - ** Bit 3-5: 'filled' (all three bits are set to 1) - */ - // rect_t bounds; // unused - void *undithered_buffer; /* copies visual_map->index_data before dithering */ + void *undithered_buffer; /**< copies visual_map->index_data before dithering */ int undithered_buffer_size; int *priorityTable; }; - +/** A animation loop */ struct gfxr_loop_t { - int cels_nr; - gfx_pixmap_t **cels; + int cels_nr; /**< Number of 'cels' or frames in the animation */ + gfx_pixmap_t **cels; /**< Pointer to the pixmaps for the cels */ }; - +/** A graphics view */ struct gfxr_view_t { int ID; @@ -122,172 +126,197 @@ struct gfxr_view_t { int translation[GFX_SCI0_IMAGE_COLORS_NR]; }; +/** + * Initializes the static 256 color palette. + */ void gfxr_init_static_palette(); -/* Initializes the static 256 color palette -** Parameters: (void) -** Returns : (void) -*/ - -gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, int sci1); -/* Initializes a gfxr_pic_t for a specific mode -** Parameters: (gfx_mode_t *) mode: The specific graphics mode -** (int) ID: The ID to assign to the resulting pixmaps -** Returns : (gfxr_pic_t *) The allocated pic resource, or NULL on error. -** This function allocates memory for use by resource drawer functions. -*/ -void gfxr_free_pic(gfxr_pic_t *pic); -/* Uninitializes a pic resource -** Parameters: (gfxr_pic_t *) pic: The pic to free -** Returns : (void) -*/ - -void gfxr_free_view(gfxr_view_t *view); -/* Frees all memory associated with a view -** Paremeters: (gfxr_view_t *) view: The view to free -** Returns : (void) -*/ +/** @name Resource picture management functions */ +/** @{ */ +/** + * Initializes a gfxr_pic_t for a specific mode. + * + * This function allocates memory for use by resource drawer functions. + * + * @param[in] mode The specific graphics mode + * @param[in] ID The ID to assign to the resulting pixmaps + * @param[in] sci1 true if a SCI1 pic, false otherwise + * @return The allocated pic resource, or NULL on error. + */ +gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, bool sci1); +/** + * Uninitializes a pic resource. + * + * @param[in] pic The pic to free + */ +void gfxr_free_pic(gfxr_pic_t *pic); +/** + * Frees all memory associated with a view. + * + * @param[in] view The view to free + */ +void gfxr_free_view(gfxr_view_t *view); +/** @} */ +/** @name SCI0 resource picture operations */ +/** @{ */ -/*********************/ -/* SCI0 operations */ -/*********************/ +/** + * Clears all pic buffers of one pic/ + * + * This function should be called before gfxr_draw_pic0, unless cumulative + * drawing is intended + * + * @param[in] pic The picture to clear + * @param[in] titlebar_size How much space to reserve for the title bar + */ +void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size); +/** + * Draws a pic resource (all formats prior to SCI1.1). + * + * The result is stored in gfxr_visual_map, gfxr_priority_map, and + * gfxr_control_map. The palette entry of gfxr_visual_map is never used. + * Note that the picture will not be drawn dithered; use gfxr_dither_pic0 + * for that. + * + * @param[in] pic The pic to draw to + * @param[in] fill_normally If 1, the pic is drawn normally; if 0, all + * fill operations will fill with black + * @param[in] default_palette The default palette to use for drawing + * @param[in] size Resource 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] 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, + Palette *static_pal, Common::Rect portBounds); -void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size); -/* Clears all pic buffers of one pic -** Parameters: (gfxr_pic_t) pic: The picture to clear -** (int) titlebar_size: How much space to reserve for the title bar -** Returns : (void) -** This function should be called before gfxr_draw_pic0, unless cumulative -** drawing is intended -*/ - - -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, - Palette *static_pal, Common::Rect portBounds); -/* Draws a pic resource (all formats prior to SCI1.1) -** Parameters: (gfxr_pic_t *) pic: The pic to draw to -** (int) fill_normally: If 1, the pic is drawn normally; if 0, all -** fill operations will fill with black -** (int) default_palette: The default palette to use for drawing -** (int) size: Resource size -** (byte *) resource: Pointer to the resource data -** (gfxr_pic0_params_t *) style: The drawing style -** (int) resid: The resource ID -** (int) sci1: Nonzero if SCI1 -** (Palette *) static_pal: The static palette -** (int) static_pal_nr: Number of entries in static palette -** Returns : (void) -** The result is stored in gfxr_visual_map, gfxr_priority_map, and gfxr_control_map. -** The palette entry of gfxr_visual_map is never used. -** Note that the picture will not be drawn dithered; use gfxr_dither_pic0 for that. -*/ - -void gfxr_draw_pic11(gfxr_pic_t *pic, int fill_normally, int default_palette, - int size, byte *resource, gfxr_pic0_params_t *style, int resid, - Palette *static_pal, Common::Rect portBounds); -/* Draws a pic resource (SCI1.1) -** Parameters: (gfxr_pic_t *) pic: The pic to draw to -** (int) fill_normally: If 1, the pic is drawn normally; if 0, all -** fill operations will fill with black -** (int) default_palette: The default palette to use for drawing -** (int) size: Resource size -** (byte *) resource: Pointer to the resource data -** (gfxr_pic0_params_t *) style: The drawing style -** (int) resid: The resource ID -** (Palette *) static_pal: The static palette -** (int) static_pal_nr: Number of entries in static palette -** Returns : (void) -** The result is stored in gfxr_visual_map, gfxr_priority_map, and gfxr_control_map. -** The palette entry of gfxr_visual_map is never used. -** Note that the picture will not be drawn dithered; use gfxr_dither_pic0 for that. -*/ +/** + * Draws a pic resource (SCI1.1). + * + * The result is stored in gfxr_visual_map, gfxr_priority_map, and + * gfxr_control_map. The palette entry of gfxr_visual_map is never used. + * Note that the picture will not be drawn dithered; use gfxr_dither_pic11 + * for that. + * + * @param[in] pic The pic to draw to + * @param[in] fill_normally If 1, the pic is drawn normally; if 0, all + * fill operations will fill with black + * @param[in] default_palette The default palette to use for drawing + * @param[in] size Resource size + * @param[in] resource Pointer to the resource data + * @param[in] style The drawing style + * @param[in] resid The resource ID + * @param[in] static_pal The static palette + * @param[in] portBounds Bounds of the port being drawn to + */ +void gfxr_draw_pic11(gfxr_pic_t *pic, int fill_normally, + int default_palette, int size, byte *resource, + gfxr_pic0_params_t *style, int resid, Palette *static_pal, + Common::Rect portBounds); +/** + * Removes artifacts from a scaled pic. + * + * Using information from the (correctly rendered) src pic, this function + * implements some heuristics to remove artifacts from dest. Must be used + * before dither_pic0 is called, because it operates on the index buffer. + * + * @param[in] dest The scaled pic + * @param[in] src An unscaled pic + */ void gfxr_remove_artifacts_pic0(gfxr_pic_t *dest, gfxr_pic_t *src); -/* Removes artifacts from a scaled pic -** Parameters: (gfxr_pic_t *) dest: The scaled pic -** (gfxr_pic_t *) src: An unscaled pic -** Returns : (void) -** Using information from the (correctly rendered) src pic, this function implements -** some heuristics to remove artifacts from dest. Must be used before dither_pic0 is -** called, because it operates on the index buffer. -*/ +/** + * Dithers a gfxr_visual_map. + * + * @param[in] pic The pic to dither + * @param[in] mode One of GFXR_DITHER_MODE + * @param[in] pattern One of GFXR_DITHER_PATTERN + */ void gfxr_dither_pic0(gfxr_pic_t *pic, int mode, int pattern); -/* Dithers a gfxr_visual_map -** Parameters: (gfxr_pic_t *) pic: The pic to dither -** (int) mode: One of GFXR_DITHER_MODE -** (int) pattern: One of GFXR_DITHER_PATTERN -** Returns : (void) -*/ +/** + * Calculates a SCI0 view. + * + * @param[in] id Resource ID of the view + * @param[in] resource Pointer to the resource to read + * @param[in] size Size of the resource + * @param[in] palette The palette to use + * @return The resulting view + */ gfxr_view_t *gfxr_draw_view0(int id, byte *resource, int size, int palette); -/* Calculates an SCI0 view -** Parameters: (int) id: Resource ID of the view -** (byte *) resource: Pointer to the resource to read -** (int) size: Size of the resource -** (int) palette: The palette to use -** Returns : (gfxr_view_t *) The resulting view -*/ - -gfx_pixmap_t *gfxr_draw_cursor(int id, byte *resource, int size, bool isSci01); -/* Calculates n SCI cursor -** Parameters: (int) id: The cursor's resource ID -** (byte *) resource: Pointer to the resource data -** (int) size: Resource size -** (bool) isSci01: Set to true to load a SCI1 cursor -** Returns : (gfx_pixmap_t *) A newly allocated pixmap containing an index -** color representation of the cursor -*/ - -/*********************/ -/* SCI1 operations */ -/*********************/ +/** + * Calculates a SCI cursor. + * + * @param[in] id The cursor's resource ID + * @param[in] resource Pointer to the resource data + * @param[in] size Resource size + * @param[in] isSci01 Set to true to load a SCI1 cursor + * @return A newly allocated pixmap containing an index color + * representation of the cursor + */ +gfx_pixmap_t *gfxr_draw_cursor(int id, byte *resource, int size, + bool isSci01); +/** @} */ + + +/** @name SCI1/1.1 resource picture operations */ +/** @{ */ + +/** + * Reads an SCI1 palette. + * + * @param[in] id Resource ID for the palette (or the view it was + * found in) + * @param[in] resource Source data + * @param[in] size Size of the memory block pointed to by resource + * @return Palette with the colors + */ Palette *gfxr_read_pal1(int id, byte *resource, int size); -/* Reads an SCI1 palette -** Parameters: (int) id: Resource ID for the palette (or the view it was found in) -** (int *) colors_nr: Pointer to the variable the number of colors -** will be stored in -** (byte *) resource: Source data -** (int) size: Size of the memory block pointed to by resource -** Returns : (Palette *) *colors_nr Palette with the colors -*/ +/** + * Reads an SCI1 palette. + * + * @param[in] file Palette file + * @return Palette with the colors + */ Palette *gfxr_read_pal1_amiga(Common::File &file); -/* Reads an SCI1 palette -** Parameters: (int *) colors_nr: Pointer to the variable the number of colors -** will be stored in -** (FILE *) f: Palette file -** Returns : (Palette *) Palette with the colors -*/ +/** + * Reads an SCI1.1 palette. + * + * @param[in] id Resource ID for the palette (or the view it was + * found in) + * @param[in] resource Source data + * @param[in] size Size of the memory block pointed to by resource + * @return Palette with the colors + */ Palette *gfxr_read_pal11(int id, byte *resource, int size); -/* Reads an SCI1.1 palette -** Parameters: (int) id: Resource ID for the palette (or the view it was found in) -** (int *) colors_nr: Pointer to the variable the number of colors -** will be stored in -** (byte *) resource: Source data -** (int) size: Size of the memory block pointed to by resource -** Returns : (Palette *) Palette with the colors -*/ +/** + * Calculates an SCI1 view. + * + * @param[in] id Resource ID of the view + * @param[in] resource Pointer to the resource to read + * @param[in] size Size of the resource + * @param[in] static_pal The static palette + * @param[in] isSci11 true if SCI1.1, false otherwise + * @return The resulting view + */ 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 -** (int) size: Size of the resource -** (Palette *) static_pal: The static palette -** (int) static_pal_nr: Number of entries in static palette -** Returns : (gfxr_view_t *) The resulting view -*/ 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); - +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_state_internal.h b/engines/sci/gfx/gfx_state_internal.h index d03c5e9519..3f00b5213c 100644 --- a/engines/sci/gfx/gfx_state_internal.h +++ b/engines/sci/gfx/gfx_state_internal.h @@ -34,14 +34,16 @@ namespace Sci { -#define GFXW_FLAG_VISIBLE (1<<0) -#define GFXW_FLAG_OPAQUE (1<<1) -#define GFXW_FLAG_CONTAINER (1<<2) -#define GFXW_FLAG_DIRTY (1<<3) -#define GFXW_FLAG_TAGGED (1<<4) -#define GFXW_FLAG_MULTI_ID (1<<5) /**< Means that the ID used herein may be used more than once, i.e. is not unique */ -#define GFXW_FLAG_IMMUNE_TO_SNAPSHOTS (1<<6) /**< Snapshot restoring doesn't kill this widget, and +5 bonus to saving throws vs. Death Magic */ -#define GFXW_FLAG_NO_IMPLICIT_SWITCH (1<<7) /**< Ports: Don't implicitly switch to this port when disposing windows */ +enum gfxw_flag_t { + GFXW_FLAG_VISIBLE = (1<<0), + GFXW_FLAG_OPAQUE = (1<<1), + GFXW_FLAG_CONTAINER = (1<<2), + GFXW_FLAG_DIRTY = (1<<3), + GFXW_FLAG_TAGGED = (1<<4), + GFXW_FLAG_MULTI_ID = (1<<5), /**< Means that the ID used herein may be used more than once, i.e. is not unique */ + GFXW_FLAG_IMMUNE_TO_SNAPSHOTS = (1<<6), /**< Snapshot restoring doesn't kill this widget, and +5 bonus to saving throws vs. Death Magic */ + GFXW_FLAG_NO_IMPLICIT_SWITCH = (1<<7) /**< Ports: Don't implicitly switch to this port when disposing windows */ +}; struct gfxw_snapshot_t { int serial; /**< The first serial number to kill */ @@ -82,6 +84,7 @@ struct GfxPort; typedef int gfxw_bin_op(GfxWidget *, GfxWidget *); +/** SCI graphics widget */ struct GfxWidget { public: int _magic; /**< Extra check after typecasting */ @@ -101,27 +104,28 @@ public: /** * The widget automatically removes itself from its owner, if it has one. - * Deleting a container will recursively free all of its - * contents. + * Deleting a container will recursively free all of its contents. */ virtual ~GfxWidget(); /** * Draws the widget. * - * The widget is drawn iff it is flagged as dirty. Invoking this operation on - * a container widget will recursively draw all of its contents. + * The widget is drawn iff it is flagged as dirty. Invoking this operation + * on a container widget will recursively draw all of its contents. * - * @param pos The position to draw to (added to the widget's internal position) + * @param[in] pos The position to draw to (added to the widget's + * internal position) */ virtual int draw(const Common::Point &pos) = 0; /** * Tags the specified widget. * - * If invoked on a container widget, this will also tag all of the container's - * contents (but not the contents' contents!) - * FIXME: Actually, the code in GfxContainer::tag contradicts the last claim! + * If invoked on a container widget, this will also tag all of the + * container's contents (but not the contents' contents!) + * FIXME: Actually, the code in GfxContainer::tag contradicts the last + * claim! */ virtual void tag() { _flags |= GFXW_FLAG_TAGGED; @@ -130,10 +134,10 @@ public: /** * Prints a string representation of the widget with sciprintf. * - * Will recursively print all of the widget's contents if the widget contains - * further sub-widgets + * Will recursively print all of the widget's contents if the widget + * contains further sub-widgets * - * @param indentation Number of double spaces to indent + * @param[in] indentation Number of double spaces to indent */ virtual void print(int indentation) const; @@ -143,55 +147,63 @@ public: * This comparison only applies to some widgets; compare_to(a,a)=0 is not * guaranteed. It may be used for sorting for all widgets. * - * @param other other widget - * @return <0, 0, or >0 if other is, respectively, less than, equal - * to, or greater than self + * @param other The other widget + * @return <0, 0, or >0 if other is, respectively, less than, equal + * to, or greater than self */ gfxw_bin_op *compare_to; /** * Compares two compareable widgets for equality. * - * This operation checks whether two widgets describe the same graphical data. - * It is used to determine whether a new widget should be discarded because it - * describes the same graphical data as an old widget that has already been - * drawn. For lists, it also checks whether all contents are in an identical - * order. + * This operation checks whether two widgets describe the same graphical + * data. It is used to determine whether a new widget should be discarded + * because it describes the same graphical data as an old widget that has + * already been drawn. For lists, it also checks whether all contents are + * in an identical order. * - * @param other other widget - * @return false if the widgets are not equal, true if they match + * @param[in] other The other widget + * @return false if the widgets are not equal, true if they match */ gfxw_bin_op *equals; /** - * Determine whether other should replace this even though they are equivalent. + * Determine whether other should replace this even though they are + * equivalent. * * When 'equals' returns true, this means that no new widget will be added. * However, in some cases newer widgets may contain information that should - * cause the older widget to be removed nonetheless; this is indicated by this - * function. + * cause the older widget to be removed nonetheless; this is indicated by + * this function. * - * @param other other widget - * @return false if this should be kept, true if this should be replaced by the 'other' + * @param[in] other The other widget + * @return false if this should be kept, true if this should be + * replaced by the 'other' */ gfxw_bin_op *should_replace; /** - * Tests whether drawing this after other would reduce all traces of other. + * Tests whether drawing this after other would reduce all traces of + * other. * - * /a superarea_of b <=> for each pixel of b there exists an opaque pixel in a at the same location + * /a superarea_of b <=> for each pixel of b there exists an opaque pixel + * in a at the same location * - * @param other the widget to compare for containment - * @return true if this is superarea_of other, false otherwise + * @param[in] other The widget to compare for containment + * @return true if this is superarea_of other, false otherwise */ gfxw_bin_op *superarea_of; /** * Sets the visual for the widget - * This function is called by container->add() and need not be invoked explicitly. - * It also makes sure that dirty rectangles are passed to parent containers. + * + * This function is called by container->add() and need not be invoked + * explicitly. It also makes sure that dirty rectangles are passed to + * parent containers. + * + * @param[in] visual GfxVisual to set for the widget */ - virtual int setVisual(GfxVisual *); + virtual int setVisual(GfxVisual *visual); //protected: void printIntern(int indentation) const; @@ -200,6 +212,7 @@ public: #define GFXW_IS_BOX(widget) ((widget)->_type == GFXW_BOX) +/** SCI box widget */ struct GfxBox : public GfxWidget { gfx_color_t _color1, _color2; gfx_box_shade_t _shadeType; @@ -213,6 +226,7 @@ public: #define GFXW_IS_PRIMITIVE(widget) ((widget)->_type == GFXW_RECT || (widget)->_type == GFXW_LINE) +/** SCI graphics primitive */ struct GfxPrimitive : public GfxWidget { gfx_color_t _color; gfx_line_mode_t _lineMode; @@ -227,6 +241,7 @@ public: #define GFXW_IS_VIEW(widget) ((widget)->_type == GFXW_VIEW || (widget)->_type == GFXW_STATIC_VIEW \ || (widget)->_type == GFXW_DYN_VIEW || (widget)->_type == GFXW_PIC_VIEW) +/** SCI graphics view */ struct GfxView : public GfxWidget { Common::Point _pos; /**< Implies the value of 'bounds' in GfxWidget */ gfx_color_t _color; @@ -242,6 +257,7 @@ public: }; #define GFXW_IS_DYN_VIEW(widget) ((widget)->_type == GFXW_DYN_VIEW || (widget)->_type == GFXW_PIC_VIEW) +/** SCI dynamic view */ struct GfxDynView : public GfxView { /* FIXME: This code is specific to SCI */ rect_t draw_bounds; /* The correct position to draw to */ @@ -265,6 +281,7 @@ public: #define GFXW_IS_TEXT(widget) ((widget)->_type == GFXW_TEXT) +/** SCI text widget */ struct GfxText : public GfxWidget { int _font; int lines_nr, lineheight, lastline_width; @@ -293,7 +310,7 @@ typedef int gfxw_unary_container_op(GfxContainer *); typedef int gfxw_container_op(GfxContainer *, GfxWidget *); typedef int gfxw_rect_op(GfxContainer *, rect_t, int); - +/** SCI container widget */ struct GfxContainer : public GfxWidget { rect_t zone; /**< The writeable zone (absolute) for contained objects */ DirtyRectList _dirtyRects; /**< List of dirty rectangles */ @@ -324,7 +341,7 @@ public: #define GFXW_IS_LIST(widget) ((widget)->_type == GFXW_LIST || (widget)->_type == GFXW_SORTED_LIST) #define GFXW_IS_SORTED_LIST(widget) ((widget)->_type == GFXW_SORTED_LIST) - +/** SCI graphics list */ struct GfxList : public GfxContainer { public: GfxList(rect_t area, bool sorted); @@ -334,6 +351,7 @@ public: }; #define GFXW_IS_VISUAL(widget) ((widget)->_type == GFXW_VISUAL) +/** SCI graphic visual */ struct GfxVisual : public GfxContainer { Common::Array<GfxPort *> _portRefs; /**< References to ports */ int _font; /**< Default font */ @@ -353,6 +371,7 @@ public: }; #define GFXW_IS_PORT(widget) ((widget)->_type == GFXW_PORT) +/** SCI graphics port */ struct GfxPort : public GfxContainer { GfxList *_decorations; /**< optional window decorations - drawn before the contents */ GfxWidget *port_bg; /**< Port background widget or NULL */ @@ -366,16 +385,20 @@ struct GfxPort : public GfxContainer { byte gray_text; /**< Whether text is 'grayed out' (dithered) */ public: - /* Creates a new port widget with the default settings - ** Paramaters: (GfxVisual *) visual: The visual the port is added to - ** (GfxPort *) predecessor: The port's predecessor - ** (rect_t) area: The screen area covered by the port (absolute position) - ** (gfx_color_t) fgcolor: Foreground drawing color - ** (gfx_color_t) bgcolor: Background color - ** A port differentiates itself from a list in that it contains additional information, - ** and an optional title (stored in a display list). - ** Ports are assigned implicit IDs identifying their position within the port stack. - */ + /** + * Creates a new port widget with the default settings + * + * A port differentiates itself from a list in that it contains additional + * information, and an optional title (stored in a display list). + * Ports are assigned implicit IDs identifying their position within the + * port stack. + * + * @param[in] visual The visual the port is added to + * @param[in] area The screen area covered by the port (absolute + * position) + * @param[in] fgcolor Foreground drawing color + * @param[in] bgcolor Background color + */ GfxPort(GfxVisual *visual, rect_t area, gfx_color_t fgcolor, gfx_color_t bgcolor); ~GfxPort(); diff --git a/engines/sci/gfx/gfx_system.h b/engines/sci/gfx/gfx_system.h index 3922b21db2..6b7724a6bd 100644 --- a/engines/sci/gfx/gfx_system.h +++ b/engines/sci/gfx/gfx_system.h @@ -36,7 +36,7 @@ namespace Sci { #define GFX_DEBUG /* General output macros */ -# define GFXERROR sciprintf("GFX Error: %s, L%d:", __FILE__, __LINE__); error +#define GFXERROR sciprintf("GFX Error: %s, L%d:", __FILE__, __LINE__); error /***********************/ /*** Data structures ***/ @@ -50,32 +50,35 @@ namespace Sci { ** enabled */ #define GFX_MODE_FLAG_REVERSE_ALPHA (1<<1) -/** Graphics mode description */ -struct gfx_mode_t { +/** Graphics mode description + * + * Color masks: + * Each of the mask/shift pairs describe where the corresponding color + * values are stored for the described mode. Internally, color + * calculations are done by using 32 bit values for r, g, b, a. After + * the internal values have been calculated, they are shifted RIGHT + * by the xxx_shift amount described above, then ANDed with the + * corresponding color mask; finally, all three results are ORred to- + * gether. The alpha values are used as appropriate; if alpha_mask is + * zero, then images use a special alpha map. + */ - int xfact, yfact; /* Horizontal and vertical scaling factors */ - int xsize, ysize; /* Horizontal and vertical size */ - int bytespp; /* Bytes per pixel */ +struct gfx_mode_t { - uint32 flags; /* GFX_MODE_FLAG_* Flags- see above */ + int xfact, yfact; /**< Horizontal and vertical scaling factors */ + int xsize, ysize; /**< Horizontal and vertical size */ + int bytespp; /**< Bytes per pixel */ + uint32 flags; /**< GFX_MODE_FLAG_* Flags- see above */ - Palette *palette; // Palette or NULL to indicate non-palette mode. - // Palette mode is only supported for bytespp = 1 + /** + * Palette or NULL to indicate non-palette mode. + * Palette mode is only supported for bytespp = 1 + */ + Palette *palette; - /* Color masks */ uint32 red_mask, green_mask, blue_mask, alpha_mask; short red_shift, green_shift, blue_shift, alpha_shift; - - /* Each of the mask/shift pairs describe where the corresponding color - ** values are stored for the described mode. Internally, color - ** calculations are done by using 32 bit values for r, g, b, a. After - ** the internal values have been calculated, they are shifted RIGHT - ** by the xxx_shift amount described above, then ANDed with the - ** corresponding color mask; finally, all three results are ORred to- - ** gether. The alpha values are used as appropriate; if alpha_mask is - ** zero, then images use a special alpha map. */ - }; @@ -84,16 +87,16 @@ struct gfx_mode_t { /** Pixmap-specific color entries */ struct gfx_pixmap_color_t{ - int global_index; /* Global index color or GFX_COLOR_INDEX_UNMAPPED. */ - uint8 r, g, b; /* Real color */ + int global_index; /**< Global index color or GFX_COLOR_INDEX_UNMAPPED. */ + uint8 r, g, b; /**< Real color */ }; /** Full color */ struct gfx_color_t { PaletteEntry visual; - uint8 alpha; /* transparency = (1-opacity) */ + uint8 alpha; /**< transparency = (1-opacity) */ int8 priority, control; - byte mask; /* see mask values below */ + byte mask; /**< see mask values below */ }; @@ -104,11 +107,15 @@ struct rect_t { int width, height; /* width, height: (x,y,width,height)=(5,5,1,1) occupies 1 pixel */ }; -/* Generates a rect_t from index data -** Parameters: (int x int) x,y: Upper left point of the rectangle -** (int x int) width, height: Horizontal and vertical extension of the rectangle -** Returns : (rect_t) A rectangle matching the supplied parameters -*/ +/** + * Generates a rect_t from index data + * + * @param[in] x Left side of the rectangle + * @param[in] y Top side of the rectangle + * @param[in] width Horizontal extent of the rectangle + * @param[in] height Verical extent of the rectangle + * @return A rectangle matching the supplied parameters + */ static inline rect_t gfx_rect(int x, int y, int width, int height) { rect_t rect; @@ -120,11 +127,16 @@ static inline rect_t gfx_rect(int x, int y, int width, int height) { return rect; } -// Temporary helper functions to ease the transition from rect_t to Common::Rect +/** + * Temporary helper function to ease the transition from rect_t to Common::Rect + */ static inline rect_t toSCIRect(Common::Rect in) { return gfx_rect(in.left, in.top, in.width(), in.height()); } +/** + * Temporary helper function to ease the transition from rect_t to Common::Rect + */ static inline Common::Rect toCommonRect(rect_t in) { return Common::Rect(in.x, in.y, in.x + in.width, in.y + in.height); } @@ -133,10 +145,13 @@ static inline Common::Rect toCommonRect(rect_t in) { #define OVERLAP(a, b, z, zl) (a.z >= b.z && a.z < (b.z + b.zl)) -/* Determines whether two rects overlap -** Parameters: (rect_t x rect_t) a,b: The two rect_ts to check for overlap -** Returns : (int) 1 if they overlap, 0 otherwise -*/ +/** + * Determines whether two rects overlap + * + * @param[in] a First rect to check for overlap + * @param[in] b Second rect to check for overlap + * @return 1 if they overlap, 0 otherwise + */ static inline int gfx_rects_overlap(rect_t a, rect_t b) { return (OVERLAP(a, b, x, width) || OVERLAP(b, a, x, width)) && (OVERLAP(a, b, y, height) || OVERLAP(b, a, y, height)); } @@ -150,86 +165,95 @@ extern rect_t gfx_rect_fullscreen; #define GFX_PIC_COLORS 256 -#define GFX_PIXMAP_FLAG_SCALED_INDEX (1<<0) /* Index data is scaled already */ -#define GFX_PIXMAP_FLAG_INSTALLED (1<<2) /* Pixmap has been registered */ -#define GFX_PIXMAP_FLAG_PALETTIZED (1<<6) /* Indicates a palettized view */ +#define GFX_PIXMAP_FLAG_SCALED_INDEX (1<<0) /* Index data is scaled already */ +#define GFX_PIXMAP_FLAG_INSTALLED (1<<2) /* Pixmap has been registered */ +#define GFX_PIXMAP_FLAG_PALETTIZED (1<<6) /* Indicates a palettized view */ #define GFX_PIXMAP_COLOR_KEY_NONE -1 /* No transpacency colour key */ #define GFX_CURSOR_TRANSPARENT 255 // Cursor colour key -struct gfx_pixmap_t { /* gfx_pixmap_t: Pixel map */ +/** Pixel map */ +struct gfx_pixmap_t { - /*** Meta information ***/ - int ID; /* Resource ID, or GFX_RESID_NONE for anonymous graphical data */ - short loop, cel; /* loop and cel number for views */ + /** @name Meta information + * @{*/ + int ID; /**< Resource ID, or GFX_RESID_NONE for anonymous graphical data */ + short loop; /**< loop number for view */ + short cel; /**< cel number for view */ + /** @}*/ - - /*** Color map ***/ + /** @name Color map + * @{*/ Palette *palette; - int colors_nr() const { return palette ? palette->size() : 0; } - /* color entries, or NULL if the - ** default palette is to be used. - ** A maximum of 255 colors is allowed; color - ** index 0xff is reserved for transparency. - ** As a special exception, 256 colors are - ** allowed for background pictures (which do - ** not use transparency) - */ - uint32 flags; - - /*** Hot spot ***/ - int xoffset, yoffset; /* x and y coordinates of the 'hot spot' (unscaled) */ - /*** Index data ***/ - int index_width, index_height; /* width and height of the indexed original image */ - byte *index_data; /* Color-index data, or NULL if read from an - ** external source - */ - - /*** Drawable data ***/ - int width, height; /* width and height of the actual image */ - int data_size; /* Amount of allocated memory */ - byte *data; /* Drawable data, or NULL if not converted. */ - - byte *alpha_map; /* Byte map with alpha values. It is used only if the - ** graphics mode's alpha_mask is zero. - */ + /** + * color entries, or NULL if the default palette is to be used. A maximum + * of 255 colors is allowed; color index 0xff is reserved for transparency. + * As a special exception, 256 colors are allowed for background pictures + * (which do not use transparency) + */ + int colors_nr() const { return palette ? palette->size() : 0; } - int color_key; - int palette_revision; // Revision of palette at the time data was generated + uint32 flags; + /* @} */ + + /** @name Hot spot + * x and y coordinates of the 'hot spot' (unscaled) + * @{*/ + int xoffset, yoffset; + /** @} */ + + /** @name Index data + * @{ + */ + int index_width; /**< width of the indexed original image */ + int index_height; /**< height of the indexed original image */ + byte *index_data; /**< Color-index data, or NULL if read from an external source */ + /** @} */ + + /** @name Drawable data + * @{ + */ + int width; /**< width of the actual image */ + int height; /**< height of the actual image */ + int data_size; /**< Amount of allocated memory */ + byte *data; /**< Drawable data, or NULL if not converted. */ + + byte *alpha_map; /**< Byte map with alpha values. It is used only if the graphics mode's alpha_mask is zero. */ + + int color_key; /**< The color to make transparent */ + int palette_revision; /**< Revision of palette at the time data was generated */ + /** @} */ }; -/***********************/ -/*** Constant values ***/ -/***********************/ -/* Return values */ +/** @name Constant values + * @{ */ + +/** Return values */ enum gfx_return_value_t { - GFX_OK = 0, /* Indicates "operation successful" */ - GFX_ERROR = -1, /* Indicates "operation failed" */ - GFX_FATAL = -2 - /* Fatal error: Used by graphics drivers to indicate that they were unable to - ** do anything useful - */ + GFX_OK = 0, /**< Indicates "operation successful" */ + GFX_ERROR = -1, /**< Indicates "operation failed" */ + GFX_FATAL = -2 /**< Fatal error: Used by graphics drivers to indicate + that they were unable to do anything useful */ }; - -enum gfx_map_mask_t {/* Map masks */ +/** Map masks */ +enum gfx_map_mask_t { GFX_MASK_NONE = 0, GFX_MASK_VISUAL = 1, GFX_MASK_PRIORITY = 2, GFX_MASK_CONTROL = 4 }; -/* 'no priority' mode */ +/** 'no priority' mode */ enum { GFX_NO_PRIORITY = -1 }; -/* Text alignment values */ - +/** Text alignment values */ enum gfx_alignment_t { ALIGN_RIGHT = -1, ALIGN_TOP = -1, @@ -240,16 +264,16 @@ enum gfx_alignment_t { enum gfx_line_mode_t { - GFX_LINE_MODE_CORRECT, /* Scaled separately */ - GFX_LINE_MODE_FAST, /* Scaled by (xfact+yfact)/2 */ - GFX_LINE_MODE_FINE /* Always drawn at width 1 */ + GFX_LINE_MODE_CORRECT, /**< Scaled separately */ + GFX_LINE_MODE_FAST, /**< Scaled by (xfact+yfact)/2 */ + GFX_LINE_MODE_FINE /**< Always drawn at width 1 */ }; enum gfx_brush_mode_t { - GFX_BRUSH_MODE_SCALED, /* Just scale the brush pixels */ - GFX_BRUSH_MODE_ELLIPSES, /* Replace pixels with ellipses */ - GFX_BRUSH_MODE_RANDOM_ELLIPSES, /* Replace pixels with ellipses moved and re-scaled randomly */ - GFX_BRUSH_MODE_MORERANDOM /* Distribute randomly */ + GFX_BRUSH_MODE_SCALED, /**< Just scale the brush pixels */ + GFX_BRUSH_MODE_ELLIPSES, /**< Replace pixels with ellipses */ + GFX_BRUSH_MODE_RANDOM_ELLIPSES, /**< Replace pixels with ellipses moved and re-scaled randomly */ + GFX_BRUSH_MODE_MORERANDOM /**< Distribute randomly */ }; @@ -260,18 +284,19 @@ enum gfx_line_style_t { enum gfx_rectangle_fill_t { - GFX_SHADE_FLAT, /* Don't shade */ - GFX_SHADE_VERTICALLY, /* Shade vertically */ - GFX_SHADE_HORIZONTALLY /* Shade horizontally */ + GFX_SHADE_FLAT, /**< Don't shade */ + GFX_SHADE_VERTICALLY, /**< Shade vertically */ + GFX_SHADE_HORIZONTALLY /**< Shade horizontally */ }; enum gfx_color_mode_t { - GFX_COLOR_MODE_AUTO = 0, /* Auto-detect- handled by the gfxop library */ - GFX_COLOR_MODE_INDEX = 1, /* Index mode */ - GFX_COLOR_MODE_HIGH = 2, /* High color mode (15bpp or 16 bpp) */ - GFX_COLOR_MODE_TRUE = 4 /* True color mode (24 bpp padded to 32 bpp) */ + GFX_COLOR_MODE_AUTO = 0, /**< Auto-detect- handled by the gfxop library */ + GFX_COLOR_MODE_INDEX = 1, /**< Index mode */ + GFX_COLOR_MODE_HIGH = 2, /**< High color mode (15bpp or 16 bpp) */ + GFX_COLOR_MODE_TRUE = 4 /**< True color mode (24 bpp padded to 32 bpp) */ }; +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/gfx_tools.h b/engines/sci/gfx/gfx_tools.h index 8582dfa565..9b4ce32e89 100644 --- a/engines/sci/gfx/gfx_tools.h +++ b/engines/sci/gfx/gfx_tools.h @@ -23,9 +23,6 @@ * */ -/* SCI graphics subsystem helper functions */ - - #ifndef SCI_GFX_GFX_TOOLS_H #define SCI_GFX_GFX_TOOLS_H @@ -36,162 +33,198 @@ namespace Sci { +/** @name SCI graphics subsystem helper functions */ +/** @{ */ + enum gfx_xlate_filter_t { GFX_XLATE_FILTER_NONE, GFX_XLATE_FILTER_LINEAR, GFX_XLATE_FILTER_TRILINEAR }; +/** + * Allocates a new gfx_mode_t structure with the specified parameters + * + * @param[in] xfact Horizontal scaling factors + * @param[in] yfact Vertical scaling factors + * @param[in] format Pixel format description + * @param[in] palette Number of palette colors, 0 if we're not in palette mode + * @param[in] flags GFX_MODE_FLAG_* values ORred together, or just 0 + * @return A newly allocated gfx_mode_t structure + */ gfx_mode_t *gfx_new_mode(int xfact, int yfact, const Graphics::PixelFormat &format, Palette *palette, int flags); -/* Allocates a new gfx_mode_t structure with the specified parameters -** Parameters: (int x int) xfact x yfact: Horizontal and vertical scaling factors -** (Graphics::PixelFormat) format: pixel format description -** (int) palette: Number of palette colors, 0 if we're not in palette mode -** (int) flags: GFX_MODE_FLAG_* values ORred together, or just 0 -** Returns : (gfx_mode_t *) A newly allocated gfx_mode_t structure -*/ - +/** + * Clips a rect_t + * + * @param[in] box Pointer to the box to clip + * @param[in] maxx Maximum allowed width + * @param[in] maxy Maximum allowed height + */ void gfx_clip_box_basic(rect_t *box, int maxx, int maxy); -/* Clips a rect_t -** Parameters: (rect_t *) box: Pointer to the box to clip -** (int x int) maxx, maxy: Maximum allowed width and height -** Returns : (void) -*/ - +/** + * Frees all memory allocated by a mode structure + * @param[in] mode The mode to free + */ void gfx_free_mode(gfx_mode_t *mode); -/* Frees all memory allocated by a mode structure -** Parameters: (gfx_mode_t *) mode: The mode to free -** Returns : (void) -*/ - +/** + * Creates a new pixmap structure + * + * The following fiels are initialized: + * ID, loop, cel, index_width, index_height, xl, yl, data <- NULL, + * alpha_map <- NULL, internal.handle <- 0, internal.info <- NULL, + * colors <- NULL, index_scaled <- 0 + * + * @param[in] xl Width (in SCI coordinates) of the pixmap + * @param[in] yl Height (in SCI coordinates) of the pixmap + * @param[in] resid The pixmap's resource ID, or GFX_RESID_NONE + * @param[in] loop For views: The pixmap's loop number + * @param[in] cel For cels: The pixmap's cel number + * @return The newly allocated pixmap + */ gfx_pixmap_t *gfx_new_pixmap(int xl, int yl, int resid, int loop, int cel); -/* Creates a new pixmap structure -** Parameters: (int x int) xl x yl: The dimensions (in SCI coordinates) of the pixmap -** (int) resid: The pixmap's resource ID, or GFX_RESID_NONE -** (int) loop: For views: The pixmap's loop number -** (int) cel: For cels: The pixmap's cel number -** Returns : (gfx_pixmap_t *) The newly allocated pixmap -** The following fiels are initialized: -** ID, loop, cel, index_width, index_height, xl, yl, data <- NULL, -** alpha_map <- NULL, internal.handle <- 0, internal.info <- NULL, colors <- NULL, -** index_scaled <- 0 -*/ +/** + * Clones a pixmap, minus its index data, palette and driver-specific + * handles + * + * @param[in] pixmap The pixmap to clone + * @param[in] mode The mode to be applied to the pixmap + * @return The clone + */ gfx_pixmap_t *gfx_clone_pixmap(gfx_pixmap_t *pixmap, gfx_mode_t *mode); -/* Clones a pixmap, minus its index data, palette and driver-specific handles -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to clone -** (gfx_mode_t *) mode: The mode to be applied to the pixmap -** Returns : (gfx_pixmap_t *) The clone -*/ - +/** + * Allocates the index_data field of a pixmap + * + * @param[in] pixmap The pixmap to allocate for + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap); -/* Allocates the index_data field of a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to allocate for -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Frees the index_data field of a pixmap + * + * @param[in] pixmap The pixmap to modify + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_free_index_data(gfx_pixmap_t *pixmap); -/* Frees the index_data field of a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to modify -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Allocates the data field of a pixmap + * + * @param[in] pixmap The pixmap to allocate for + * @param[in] mode The mode the memory is to be allocated for + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode); -/* Allocates the data field of a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to allocate for -** (gfx_mode_t *) mode: The mode the memory is to be allocated for -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Frees the memory allocated for a pixmap's data field + * + * @param[in] pixmap The pixmap to modify + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_free_data(gfx_pixmap_t *pixmap); -/* Frees the memory allocated for a pixmap's data field -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap to modify -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** + * Frees all memory associated with a pixmap + * + * @param[in] pxm The pixmap to free + */ void gfx_free_pixmap(gfx_pixmap_t *pxm); -/* Frees all memory associated with a pixmap -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to free -** Returns : (void) -*/ - -void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, Common::Point end, int color); -/* Draws a line to a pixmap's index data buffer -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw to -** (Common::Point) start: Starting point of the line to draw -** (Common::Point) end: End point of the line to draw -** (int) color: The byte value to write -** Returns : (void) -** Remember, this only draws to the /index/ buffer, not to the drawable buffer. -** The line is not clipped. Invalid x, y, x1, y1 values will result in memory corruption. -*/ +/** + * Draws a line to a pixmap's index data buffer + * + * Remember, this only draws to the /index/ buffer, not to the drawable buffer. + * The line is not clipped. Invalid x, y, x1, y1 values will result in memory + * corruption. + * + * @param[in] pxm The pixmap to draw to + * @param[in] start Starting point of the line to draw + * @param[in] end End point of the line to draw + * @param[in] color The byte value to write + */ +void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, + Common::Point end, int color); + +/** + * Draws a filled rectangular area to a pixmap's index buffer + * + * This function only draws to the index buffer. + * + * @param[in] pxm The pixmap to draw to + * @param[in] box The box to fill + * @param[in] color The color to use for drawing + */ void gfx_draw_box_pixmap_i(gfx_pixmap_t *pxm, rect_t box, int color); -/* Draws a filled rectangular area to a pixmap's index buffer -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to draw to -** (rect_t) box: The box to fill -** (int) color: The color to use for drawing -** Returns : (void) -** This function only draws to the index buffer. -*/ +/** + * Copies part of a pixmap to another pixmap, with clipping + * + * @param[in] dest The destination pixmap + * @param[in] src The source pixmap + * @param[in] box The area to copy + */ void gfx_copy_pixmap_box_i(gfx_pixmap_t *dest, gfx_pixmap_t *src, rect_t box); -/* Copies part of a pixmap to another pixmap, with clipping -** Parameters: (gfx_pixmap_t *) dest: The destination pixmap -** (gfx_pixmap_t *) src: The source pixmap -** (rect_t) box: The area to copy -** Returns : (void) -*/ +/** + * Translates a pixmap's index data to drawable graphics data + * + * @param[in] pxm The pixmap to translate + * @param[in] mode The mode according which to scale + * @param[in] filter How to filter the data + */ void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode, gfx_xlate_filter_t filter); -/* Translates a pixmap's index data to drawable graphics data -** Parameters: (gfx_pixmap_t *) pxm: The pixmap to translate -** (gfx_mode_t *) mode: The mode according which to scale -** (gfx_xlate_filter_t) filter: How to filter the data -** Returns : (void) -*/ -#define GFX_CROSSBLIT_FLAG_DATA_IS_HOMED (1<<0) -/* Means that the first byte in the visual data refers to the -** point corresponding to (dest.x, dest.y) */ +#define GFX_CROSSBLIT_FLAG_DATA_IS_HOMED (1<<0) /**< Means that the first byte in the visual data refers to the point corresponding to (dest.x, dest.y) */ +/** + * Transfers the non-transparent part of a pixmap to a linear pixel + * buffer. + * + * A 'linear buffer' in this context means a data buffer containing an entire + * screen (visual or priority), with fixed offsets between each data row, and + * linear access. + * + * @param[in] mode The graphics mode of the target buffer + * @param[in] pxm The pixmap to transfer + * @param[in] priority The pixmap's priority + * @param[in] src_coords The source coordinates within the pixmap + * @param[in] dest_coords The destination coordinates (no scaling) + * @param[in] dest Memory position of the upper left pixel of + * the linear pixel buffer + * @param[in] dest_line_width Byte offset of the very first pixel in the + * second line of the linear pixel buffer, + * relative to dest. + * @param[in] priority_dest Destination buffer for the pixmap's priority + * values + * @param[in] priority_line_width Byte offset of the first pixel in the second + * line of the priority buffer + * @param[in] priority_skip Amount of bytes allocated by each priority + * value + * @param[in] flags Any crossblit flags + * @return GFX_OK, or GFX_ERROR if the specified mode + * was invalid or unsupported + */ int gfx_crossblit_pixmap(gfx_mode_t *mode, gfx_pixmap_t *pxm, int priority, rect_t src_coords, rect_t dest_coords, byte *dest, int dest_line_width, byte *priority_dest, int priority_line_width, int priority_skip, int flags); -/* Transfers the non-transparent part of a pixmap to a linear pixel buffer -** Parameters: (gfx_mode_t *) mode: The graphics mode of the target buffer -** (gfx_pixmap_t *) pxm: The pixmap to transfer -** (int priority): The pixmap's priority -** (rect_t) src_coords: The source coordinates within the pixmap -** (rect_t) dest_coords: The destination coordinates (no scaling) -** (byte *) dest: Memory position of the upper left pixel of the -** linear pixel buffer -** (int) dest_line_width: Byte offset of the very first pixel in the -** second line of the linear pixel buffer, -** relative to dest. -** (byte *) priority_dest: Destination buffer for the pixmap's priority -** values -** (int) priority_line_width: Byte offset of the first pixel in the -** second line of the priority buffer -** (int) priority_skip: Amount of bytes allocated by each priority value -** (int) flags: Any crossblit flags -** Returns : (int) GFX_OK, or GFX_ERROR if the specified mode was invalid or unsupported -** A 'linear buffer' in this context means a data buffer containing an entire -** screen (visual or priority), with fixed offsets between each data row, and -** linear access. -*/ + +/** + * Scales the index data associated with a pixmap + * + * @param[in] pixmap The pixmap whose index data should be scaled + * @param[in] mode The mode to scale it to + * @return The pixmap + */ gfx_pixmap_t *gfx_pixmap_scale_index_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode); -/* Scales the index data associated with a pixmap -** Parameters: (gfx_pixmap_t *) pixmap: The pixmap whose index data should be scaled -** (gfx_mode_t *) mode: The mode to scale it to -** Returns : (gfx_pixmap_t *) pixmap -*/ +/** @} */ } // End of namespace Sci #endif // SCI_GFX_GFX_TOOLS_H diff --git a/engines/sci/gfx/gfx_widgets.h b/engines/sci/gfx/gfx_widgets.h index bd884ffbb4..80129152cb 100644 --- a/engines/sci/gfx/gfx_widgets.h +++ b/engines/sci/gfx/gfx_widgets.h @@ -23,7 +23,6 @@ * */ -/* Graphical state management */ #ifndef SCI_GFX_GFX_WIDGETS_H #define SCI_GFX_GFX_WIDGETS_H @@ -34,6 +33,8 @@ #include "sci/gfx/operations.h" namespace Sci { +/** @name Widget Graphical State Management */ +/** @{ */ struct GfxState; struct GfxBox; @@ -155,241 +156,324 @@ extern Common::Point gfxw_point_zero; /*-- Primitive types --*/ +/** + * Creates a new box + * + * The graphics state, if non-NULL, is used here for some optimizations. + * + * @param[in] state The (optional) state + * @param[in] area The box's dimensions, relative to its container + * widget + * @param[in] color1 The primary color + * @param[in] color2 The secondary color (ignored if shading is disabled) + * @param[in] shade_type The shade type for the box + * @return The resulting box widget + */ GfxBox *gfxw_new_box(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type); -/* Creates a new box -** Parameters: (GfxState *) state: The (optional) state -** (rect_t) area: The box's dimensions, relative to its container widget -** (gfx_color_t) color1: The primary color -** (gfx_color_t) color1: The secondary color (ignored if shading is disabled) -** (gfx_box_shade_t) shade_type: The shade type for the box -** Returns : (GfxBox *) The resulting box widget -** The graphics state- if non-NULL- is used here for some optimizations. -*/ -GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); -/* Creates a new rectangle -** Parameters: (rect_t) rect: The rectangle area -** (gfx_color_t) color: The rectangle's color -** (gfx_line_mode_t) line_mode: The line mode for the lines that make up the rectangle -** (gfx_line_style_t) line_style: The rectangle's lines' style -** Returns : (GfxPrimitive *) The newly allocated rectangle widget (a Primitive) -*/ +/** + * Creates a new rectangle + * + * @param[in] rect The rectangle area + * @param[in] color The rectangle's color + * @param[in] line_mode The line mode for the lines that make up the + * rectangle + * @param[in] line_style The rectangle's lines' style + * @return The newly allocated rectangle widget (a Primitive) + */ +GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color, + gfx_line_mode_t line_mode, gfx_line_style_t line_style); -GfxPrimitive *gfxw_new_line(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); -/* Creates a new line -** Parameters: (Common::Point * Common::Point) (start, line): The line origin and end point -** (gfx_color_t) color: The line's color -** (gfx_line_mode_t) line_mode: The line mode to use for drawing -** (gfx_line_style_t) line_style: The line style -** Returns : (GfxPrimitive *) The newly allocated line widget (a Primitive) -*/ +/** + * Creates a new line + * + * @param[in] start The line's origin + * @param[in] end The line's end point + * @param[in] color The line's color + * @param[in] line_mode The line mode to use for drawing + * @param[in] line_style The line style + * @return The newly allocated line widget (a Primitive) + */ +GfxPrimitive *gfxw_new_line(Common::Point start, Common::Point end, + gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); +/** View flags */ +enum { + GFXW_VIEW_FLAG_STATIC = (1 << 0), /**< Whether the view should be static */ + GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET = (1 << 1) /**< Whether the view should _not_ apply its x/y offset modifyers */ +}; -/* Whether the view should be static */ -#define GFXW_VIEW_FLAG_STATIC (1 << 0) - -/* Whether the view should _not_ apply its x/y offset modifyers */ -#define GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET (1 << 1) - -GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int flags); -/* Creates a new view (a cel, actually) -** Parameters: (GfxState *) state: The graphics state -** (Common::Point) pos: The position to place the view at -** (int x int x int) view, loop, cel: The global cel ID -** (int) priority: The priority to use for drawing, or -1 for none -** (int) control: The value to write to the control map, or -1 for none -** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and vertical -** cel alignment -** (int) flags: Any combination of GFXW_VIEW_FLAGs -** Returns : (gfxw_cel_t *) A newly allocated cel according to the specs -*/ +/** + * Creates a new view (a cel, actually) + * + * @param[in] state The graphics state + * @param[in] pos The position to place the view at + * @param[in] view The global cel ID + * @param[in] loop The global cel ID + * @param[in] cel The global cel ID + * @param[in] palette The palette to use + * @param[in] priority The priority to use for drawing, or -1 for none + * @param[in] control The value to write to the control map, or -1 for none + * @param[in] halign Horizontal cel alignment + * @param[in] valign Vertical cel alignment + * @param[in] flags Any combination of GFXW_VIEW_FLAGs + * @return A newly allocated cel according to the specs + */ +GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view, int loop, + int cel, int palette, int priority, int control, gfx_alignment_t halign, + gfx_alignment_t valign, int flags); -GfxDynView *gfxw_new_dyn_view(GfxState *state, Common::Point pos, int z, int view, int loop, int cel, int palette, - int priority, int control, gfx_alignment_t halign, gfx_alignment_t valign, int sequence); -/* Creates a new dyn view -** Parameters: (GfxState *) state: The graphics state -** (Common::Point) pos: The position to place the dynamic view at -** (int) z: The z coordinate -** (int x int x int) view, loop, cel: The global cel ID -** (int) priority: The priority to use for drawing, or -1 for none -** (int) control: The value to write to the control map, or -1 for none -** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and vertical -** cel alignment -** (int) sequence: Sequence number: When sorting dynviews, this number is -** considered last for sorting (ascending order) -** Returns : (gfxw_cel_t *) A newly allocated cel according to the specs -** Dynamic views are non-pic views with a unique global identifyer. This allows for drawing -** optimizations when they move or change shape. -*/ -GfxText *gfxw_new_text(GfxState *state, rect_t area, int font, const char *text, gfx_alignment_t halign, - gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, - gfx_color_t bgcolor, int flags); -/* Creates a new text widget -** Parameters: (GfxState *) state: The state the text is to be calculated from -** (rect_t) area: The area the text is to be confined to (the yl value is only -** relevant for text aligment, though) -** (int) font: The number of the font to use -** (gfx_alignment_t x gfx_alignment_t) halign, valign: Horizontal and -** vertical text alignment -** (gfx_color_t x gfx_color_t) color1, color2: Text foreground colors (if not equal, -** The foreground is dithered between them) -** (gfx_color_t) bgcolor: Text background color -** (int) flags: GFXR_FONT_FLAGs, orred together (see gfx_resource.h) -** Returns : (GfxText *) The resulting text widget -*/ +/** + * Creates a new dyn view + * + * Dynamic views are non-pic views with a unique global identifyer. This allows for drawing optimizations when they move or change shape. + * + * @param[in] state The graphics state + * @param[in] pos The position to place the dynamic view at + * @param[in] z The z coordinate + * @param[in] view The global cel ID + * @param[in] loop The global cel ID + * @param[in] cel The global cel ID + * @param[in] palette The palette to use + * @param[in] priority The priority to use for drawing, or -1 for none + * @param[in] control The value to write to the control map, or -1 for none + * @param[in] halign Horizontal cel alignment + * @param[in] valign Vertical cel alignment + * @param[in] sequence Sequence number: When sorting dynviews, this number is + * considered last for sorting (ascending order) + * @return A newly allocated cel according to the specs + */ +GfxDynView *gfxw_new_dyn_view(GfxState *state, Common::Point pos, int z, + int view, int loop, int cel, int palette, int priority, int control, + gfx_alignment_t halign, gfx_alignment_t valign, int sequence); +/** + * Creates a new text widget + * + * @param[in] state The state the text is to be calculated from + * @param[in] area The area the text is to be confined to (the yl value is + * only relevant for text aligment, though) + * @param[in] font The number of the font to use + * @param[in] text String to put in text widget + * @param[in] halign Horizontal text alignment + * @param[in] valign Vertical text alignment + * @param[in] color1 Text foreground colors (if not equal, the foreground is + * dithered between them) + * @param[in] color2 Text foreground colors (if not equal, the foreground is + * dithered between them) + * @param[in] bgcolor Text background color + * @param[in] flags GFXR_FONT_FLAGs, orred together (see gfx_resource.h) + * @return The resulting text widget + */ +GfxText *gfxw_new_text(GfxState *state, rect_t area, int font, const char *text, + gfx_alignment_t halign, gfx_alignment_t valign, gfx_color_t color1, + gfx_color_t color2, gfx_color_t bgcolor, int flags); + +/** + * Determines text widget meta-information + * + * @param[in] state The state to operate on + * @param[in] text The widget to query + * @param[out] lines_nr Number of lines used in the text + * @param[out] lineheight Pixel height (SCI scale) of each text line + * @param[out] offset Pixel offset (SCI scale) of the space after the last + * character in the last line + */ void gfxw_text_info(GfxState *state, GfxText *text, int *lines_nr, int *lineheight, int *offset); -/* Determines text widget meta-information -** Parameters: (GfxState *) state: The state to operate on -** (gfx_text_t *) text: The widget to query -** Returns : (int) lines_nr: Number of lines used in the text -** (int) lineheight: Pixel height (SCI scale) of each text line -** (int) offset: Pixel offset (SCI scale) of the space after the -** last character in the last line -*/ +/** + * Sets a widget's ID + * + * A widget ID is unique within the container it is stored in, if and only if it + * was added to that container with gfxw_add(). This function handles widget == + * NULL gracefully (by doing nothing and returning NULL). + * + * @param[in] widget The widget whose ID should be set + * @param[in] ID The ID to set + * @param[in] subID The ID to set + * @return The widget + */ GfxWidget *gfxw_set_id(GfxWidget *widget, int ID, int subID); -/* Sets a widget's ID -** Parmaeters: (GfxWidget *) widget: The widget whose ID should be set -** (int x int) ID, subID: The ID to set -** Returns : (GfxWidget *) widget -** A widget ID is unique within the container it is stored in, if and only if it was -** added to that container with gfxw_add(). -** This function handles widget = NULL gracefully (by doing nothing and returning NULL). -*/ +/** + * Finds a widget with a specific ID in a container and removes it from there + * + * Search is non-recursive; widgets with IDs hidden in subcontainers will not + * be found. + * + * @param[in] container The container to search in + * @param[in] ID The ID to look for + * @param[in] subID The subID to look for, or GFXW_NO_ID for any + * @return The resulting widget or NULL if no match was found + */ GfxWidget *gfxw_remove_id(GfxContainer *container, int ID, int subID); -/* Finds a widget with a specific ID in a container and removes it from there -** Parameters: (GfxContainer *) container: The container to search in -** (int) ID: The ID to look for -** (int) subID: The subID to look for, or GFXW_NO_ID for any -** Returns : (GfxWidget *) The resulting widget or NULL if no match was found -** Search is non-recursive; widgets with IDs hidden in subcontainers will not be found. -*/ +/** + * Initializes a dyn view's interpreter attributes + * + * @param[in] widget The widget affected + * @param[in] under_bits Interpreter-dependant data + * @param[in] under_bitsp Interpreter-dependant data + * @param[in] signal Interpreter-dependant data + * @param[in] signalp Interpreter-dependant data + * @return The widget + */ +GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, + const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp); -GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp); -/* Initializes a dyn view's interpreter attributes -** Parameters: (GfxDynView *) widget: The widget affected -** (int x void * x int x void *) under_bits, inder_bitsp, signal, signalp: Interpreter-dependant data -** Returns : (GfxDynView *) widget -*/ - +/** + * Makes a widget invisible without removing it from the list of widgets + * + * Has no effect on invisible widgets + * + * @param[in] widget The widget to invisibilize + * @return The widget + */ GfxWidget *gfxw_hide_widget(GfxWidget *widget); -/* Makes a widget invisible without removing it from the list of widgets -** Parameters: (GfxWidget *) widget: The widget to invisibilize -** Returns : (GfxWidget *) widget -** Has no effect on invisible widgets -*/ +/** + * Makes an invisible widget reappear + * + * Does not affect visible widgets + * + * @param[in] widget The widget to show again + * @return The widget + */ GfxWidget *gfxw_show_widget(GfxWidget *widget); -/* Makes an invisible widget reappear -** Parameters: (GfxWidget *) widget: The widget to show again -** Returns : (GfxWidget *) widget -** Does not affect visible widgets -*/ +/** + * Marks a widget as "abandoned" + * + * @param[in] widget The widget to abandon + * @return The widget + */ GfxWidget *gfxw_abandon_widget(GfxWidget *widget); -/* Marks a widget as "abandoned" -** Parameters: (GfxWidget *) widget: The widget to abandon -** Returns : (GfxWidget *) widget -*/ - -/*-- Container types --*/ -#define GFXW_LIST_UNSORTED 0 -#define GFXW_LIST_SORTED 1 +/** Container types */ +enum { + GFXW_LIST_UNSORTED = 0, + GFXW_LIST_SORTED = 1 +}; +/** + * Creates a new list widget + * + * List widgets are also referred to as Display Lists. + * + * @param[in] area The area covered by the list (absolute position) + * @param[in] sorted Whether the list should be a sorted list + * @return A newly allocated list widget + */ GfxList *gfxw_new_list(rect_t area, int sorted); -/* Creates a new list widget -** Parameters: (rect_t) area: The area covered by the list (absolute position) -** (int) sorted: Whether the list should be a sorted list -** Returns : (GfxList *) A newly allocated list widget -** List widgets are also referred to as Display Lists. -*/ +/** + * Retrieves the default port from a visual + * + * The 'default port' is the last port to be instantiated; usually the topmost + * or highest-ranking port. + * + * @param[in] visual The visual the port should be retrieved from + * @return The default port, or NULL if no port is present + */ GfxPort *gfxw_find_default_port(GfxVisual *visual); -/* Retrieves the default port from a visual -** Parameters: (GfxVisual *) visual: The visual the port should be retrieved from -** Returns : (GfxPort *) The default port, or NULL if no port is present -** The 'default port' is the last port to be instantiated; usually the topmost -** or highest-ranking port. -*/ +/** + * Sets rectangle to be restored upon port removal + * + * @param[in] visual The visual to operate on + * @param[in] window The affected window + * @param[in] auto_rect The area to restore + */ void gfxw_port_set_auto_restore(GfxVisual *visual, GfxPort *window, rect_t auto_rect); -/* Sets rectangle to be restored upon port removal -** Parameters: (state_t *) s: The state to operate on -** (GfxPort *) window: The affected window -** (rect_t) auto_rect: The area to restore -** Returns : (void) -*/ +/** + * Removes a port from a visual + * + * @param[in] visual The visual the port should be removed from + * @param[in] port The port to remove + * @return port's parent port, or NULL if it had none + */ GfxPort *gfxw_remove_port(GfxVisual *visual, GfxPort *port); -/* Removes a port from a visual -** Parameters: (GfxVisual *) visual: The visual the port should be removed from -** (GfxPort *) port: The port to remove -** Returns : (GfxPort *) port's parent port, or NULL if it had none -*/ +/** + * Removes the widget from the specified port + * + * @param[in] container The container it should be removed from + * @param[in] widget The widget to remove + */ void gfxw_remove_widget_from_container(GfxContainer *container, GfxWidget *widget); -/* Removes the widget from the specified port -** Parameters: (GfxContainer *) container: The container it should be removed from -** (GfxWidget *) widget: The widget to remove -** Returns : (void) -*/ +/** + * Makes a "snapshot" of a visual + * + * It's not really a full qualified snaphot, though. See gfxw_restore_snapshot + * for a full discussion. This operation also increases the global serial number + * counter by one. + * + * @param[in] visual The visual a snapshot is to be taken of + * @param[in] area The area a snapshot should be taken of + * @return The resulting, newly allocated snapshot + */ gfxw_snapshot_t *gfxw_make_snapshot(GfxVisual *visual, rect_t area); -/* Makes a "snapshot" of a visual -** Parameters: (GfxVisual *) visual: The visual a snapshot is to be taken of -** (rect_t) area: The area a snapshot should be taken of -** Returns : (gfxw_snapshot_t *) The resulting, newly allocated snapshot -** It's not really a full qualified snaphot, though. See gfxw_restore_snapshot -** for a full discussion. -** This operation also increases the global serial number counter by one. -*/ +/** + * Predicate to test whether a widget would be destroyed by applying a snapshot + * + * @param[in] snapshot The snapshot to test against + * @param[in] widget The widget to test + * @return An appropriate boolean value + */ int gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, GfxWidget *widget); -/* Predicate to test whether a widget would be destroyed by applying a snapshot -** Parameters: (gfxw_snapshot_t *) snapshot: The snapshot to test against -** (GfxWidget *) widget: The widget to test -** Retunrrs : (int) An appropriate boolean value -*/ +/** + * Restores a snapshot to a visual + * + * The snapshot is not really restored; only more recent widgets touching + * the snapshotted area are destroyed. + * + * @param[in] visual The visual to operate on + * @param[in] snapshot The snapshot to restore + * @return The snapshot (still needs to be freed) + */ gfxw_snapshot_t *gfxw_restore_snapshot(GfxVisual *visual, gfxw_snapshot_t *snapshot); -/* Restores a snapshot to a visual -** Parameters: (GfxVisual *) visual: The visual to operate on -** (gfxw_snapshot_t *) snapshot: The snapshot to restore -** Returns : (gfxw_snapshot_t *) snapshot (still needs to be freed) -** The snapshot is not really restored; only more recent widgets touching -** the snapshotted area are destroyed. -*/ +/** + * As widget->widfree(widget), but destroys all overlapping widgets + * + * This operation calls widget->widfree(widget), but it also destroys all + * widgets with a higher or equal priority drawn after this widget. + * + * @param[in] widget The widget to use + */ void gfxw_annihilate(GfxWidget *widget); -/* As widget->widfree(widget), but destroys all overlapping widgets -** Parameters: (GfxWidget *) widget: The widget to use -** Returns : (void) -** This operation calls widget->widfree(widget), but it also destroys -** all widgets with a higher or equal priority drawn after this widget. -*/ +/** + * Turns a dynview into a picview + * + * The only changes are in function and type variables, actually. + * + * @param[in] dynview The victim + * @return The victim, after his transformation + */ GfxDynView *gfxw_picviewize_dynview(GfxDynView *dynview); -/* Turns a dynview into a picview -** Parameters: (GfxDynView *) dynview: The victim -** Returns : (GfxDynView *) The victim, after his transformation -** The only changes are in function and type variables, actually. -*/ -void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window, rect_t auto_rect); -/* Tags a window widget as automatically restoring the visual background upon removal -** Parameters: (gfx_visual_t *) visual: The base visual -** (GfxPort *) window: The window to tag -** (rect_t) auto_rect: The background to remember -** Also records the specified background rectangle, for later recovery -*/ +/** + * Tags a window widget as automatically restoring the visual background + * upon removal. + * + * Also records the specified background rectangle, for later recovery. + * + * @param[in] visual The base visual + * @param[in] window The window to tag + * @param[in] auto_rect The background to remember + + */ +void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window, + rect_t auto_rect); +/** @} */ } // End of namespace Sci #endif // SCI_GFX_GFX_WIDGETS_H diff --git a/engines/sci/gfx/menubar.h b/engines/sci/gfx/menubar.h index 02d99332d9..44ecd8f1bb 100644 --- a/engines/sci/gfx/menubar.h +++ b/engines/sci/gfx/menubar.h @@ -50,9 +50,7 @@ struct EngineState; /* The number of pixels added to the left of the first menu */ #define MENU_BOX_CENTER_PADDING 10 -/* Number of pixels to leave in between the left and the right centered text content in boxes -** that use right centered content -*/ +/* Number of pixels to leave in between the left and the right centered text content in boxes that use right centered content */ #define MENU_BOX_LEFT_PADDING 0 /* Number of pixels to pad to the left */ @@ -88,16 +86,16 @@ enum MenuType { class MenuItem : public Common::Serializable { public: - MenuType _type; /* Normal or hbar */ - Common::String _keytext; /* right-centered part of the text (the key) */ + MenuType _type; /**< Normal or hbar */ + Common::String _keytext; /**< right-centered part of the text (the key) */ int _flags; - byte _said[MENU_SAID_SPEC_SIZE]; /* Said spec for this item */ + byte _said[MENU_SAID_SPEC_SIZE]; /**< Said spec for this item */ reg_t _saidPos; Common::String _text; reg_t _textPos; - int _modifiers; /* Hotkey for this item */ - int _key; /* Hotkey for this item */ + int _modifiers; /**< Hotkey for this item */ + int _key; /**< Hotkey for this item */ int _enabled; int _tag; @@ -108,9 +106,10 @@ public: /** * Determines whether a message/modifiers key pair matches a menu item's key parameters. - * @param message The message to match - * @param modifiers The modifier flags to match - * @return true on match, false otherwise + * + * @param[in] message The message to match + * @param[in] modifiers The modifier flags to match + * @return true on match, false otherwise */ bool matchKey(int message, int modifiers); }; @@ -156,59 +155,68 @@ public: /** * Adds a menu to the menubar. - * Parameters: (GfxState *) state: The state the fonts are stored in - * (char *) title: The menu title - * (char *) entries: A string of menu entries - * (int) font: The font which is to be used for drawing - * (reg_t) entries_base: Segmented VM address of the entries string - * Returns : (void) + * * The menu entries use the following special characters: * '`' : Right justify the following part * ':' : End of this entry * '#' : Function key (replaced by 'F') * '^' : Control key (replaced by \002, which looks like "CTRL") * '=' : Initial tag value - * and the special string "--!", which represents a horizontal bar in the menu. + * and the special string "--!", which represents a horizontal bar in the + * menu. + * + * @param[in] state The state the fonts are stored in + * @param[in] title The menu title + * @param[in] entries A string of menu entries + * @param[in] font The font which is to be used for drawing + * @param[in] entries_base Segmented VM address of the entries string */ void addMenu(GfxState *state, const char *title, const char *entries, int font, reg_t entries_base); /** - * Sets the (currently unidentified) foo and bar values. - * Parameters: (state_t *) s: The current state - * (int) menu: The menu number to edit - * (int) item: The menu item to change - * (int) attribute: The attribute to modify - * (int) value: The value the attribute should be set to - * Returns : (int) 0 on success, 1 if either menu or item were invalid + * Sets the attributes for a menu item. + * + * @param[in] s The current state + * @param[in] menu The menu number to edit + * @param[in] item The menu item to change + * @param[in] attribute The attribute to modify + * @param[in] value The value the attribute should be set to + * @return 0 on success, 1 if either menu or item were invalid */ int setAttribute(EngineState *s, int menu, int item, int attribute, reg_t value); /** - * Sets the (currently unidentified) foo and bar values. - * Parameters: (int) menu: The menu number - * (int) item: The menu item to read - * (int) attribute: The attribute to read from - * Returns : (int) The attribute value, or -1 on error + * Gets an attribute for a menuitem. + * + * @param[in] menu The menu number + * @param[in] item The menu item to read + * @param[in] attribute The attribute to read from + * @return The attribute value, or -1 on error */ reg_t getAttribute(int menu, int item, int attribute) const; /** * Determines whether the specified menu entry may be activated. - * @return true if the menu item may be selected, false otherwise + * + * @return true if the menu item may be selected, false otherwise */ bool itemValid(int menu, int item) const; /** * Maps the pointer position to a (menu,item) tuple. - * @param pointerPos the current pointer position - * @param menu_nr the current menu (updated by this function if necessary) - * @param item_nr the current menu item (updated by this function if necessary) - * @param port the port of the currently active menu (if any) - * @return true if the pointer is outside a valid port, false otherwise. + * + * @param[in] pointerPos the current pointer position + * @param[in] menu_nr the current menu (updated by this function if + * necessary) + * @param[in] item_nr the current menu item (updated by this function + * if necessary) + * @param[in] port the port of the currently active menu (if any) + * @return true if the pointer is outside a valid port, + * false otherwise. */ bool mapPointer(const Common::Point &pointerPos, int &menu_nr, int &item_nr, GfxPort *port) const; diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h index d559d3b6d2..491b485da0 100644 --- a/engines/sci/gfx/operations.h +++ b/engines/sci/gfx/operations.h @@ -93,10 +93,10 @@ typedef Common::List<rect_t> DirtyRectList; struct GfxState { gfx_options_t *options; - Common::Point pointer_pos; /* Mouse pointer coordinates */ + Common::Point pointer_pos; /**< Mouse pointer coordinates */ - rect_t clip_zone_unscaled; /* The current UNSCALED clipping zone */ - rect_t clip_zone; /* The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */ + rect_t clip_zone_unscaled; /**< The current UNSCALED clipping zone */ + rect_t clip_zone; /**< The current SCALED clipping zone; a cached scaled version of clip_zone_unscaled */ GfxDriver *driver; @@ -104,543 +104,640 @@ struct GfxState { GfxResManager *gfxResMan; - gfx_pixmap_t *priority_map; /* back buffer priority map (unscaled) */ - gfx_pixmap_t *static_priority_map; /* static buffer priority map (unscaled) */ - gfx_pixmap_t *control_map; /* back buffer control map (only exists unscaled in the first place) */ + gfx_pixmap_t *priority_map; /**< back buffer priority map (unscaled) */ + gfx_pixmap_t *static_priority_map; /**< static buffer priority map (unscaled) */ + gfx_pixmap_t *control_map; /**< back buffer control map (only exists unscaled in the first place) */ - int tag_mode; /* Set to 1 after a new pic is drawn and the resource manager - ** has tagged all resources. Reset after the next front buffer - ** update is done, when all resources that are still tagged are - ** flushed. */ + int tag_mode; /**< Set to 1 after a new pic is drawn and the resource manager has tagged all resources. Reset after the next front buffer update is done, when all resources that are still tagged are flushed. */ - int disable_dirty; /* Set to 1 to disable dirty rect accounting */ + int disable_dirty; /**< Set to 1 to disable dirty rect accounting */ - int pic_nr; /* Number of the current pic */ - int palette_nr; /* Palette number of the current pic */ + int pic_nr; /**< Number of the current pic */ + int palette_nr; /**< Palette number of the current pic */ Common::List<sci_event_t> _events; - gfx_pixmap_t *fullscreen_override; /* An optional override picture which must have unscaled - ** full-screen size, which overrides all other visibility, and - ** which is generally slow */ + gfx_pixmap_t *fullscreen_override; /**< An optional override picture which must have unscaled full-screen size, which overrides all other visibility, and which is generally slow */ - gfxr_pic_t *pic, *pic_unscaled; /* The background picture and its unscaled equivalent */ - rect_t pic_port_bounds; /* Picture port bounds */ + gfxr_pic_t *pic, *pic_unscaled; /**< The background picture and its unscaled equivalent */ + rect_t pic_port_bounds; /**< Picture port bounds */ - DirtyRectList _dirtyRects; /* Dirty rectangles */ + DirtyRectList _dirtyRects; /**< Dirty rectangles */ }; -/**************************/ -/* Fundamental operations */ -/**************************/ - -int gfxop_init(int version, bool isVGA, GfxState *state, gfx_options_t *options, ResourceManager *resManager, - int xfact = 1, int yfact = 1, gfx_color_mode_t bpp = GFX_COLOR_MODE_INDEX); -/* Initializes a graphics mode -** Parameters: (int) version: The interpreter version -** (GfxState *) state: The state to initialize -** (int x int) xfact, yfact: Horizontal and vertical scale factors -** (gfx_color_mode_t) bpp: Bytes per pixel to initialize with, or -** 0 (GFX_COLOR_MODE_AUTO) to auto-detect -** (gfx_options_t *) options: Rendering options -** (void *) misc_info: Additional information for the interpreter -** part of the resource loader -** Returns : (int) GFX_OK on success, GFX_ERROR if that particular mode is -** unavailable, or GFX_FATAL if the graphics driver is unable -** to provide any useful graphics support -*/ +/** @name Fundamental operations */ +/** @{ */ + +/** + * Initializes a graphics mode. + * + * @param[in] version The interpreter version + * @param[in] isVGA true if using VGA resolution + * @param[in] state The state to initialize + * @param[in] xfact Horizontal scale factor + * @param[in] yfact Vertical scale factors + * @param[in] bpp Bytes per pixel to initialize with, or 0 + * (GFX_COLOR_MODE_AUTO) to auto-detect + * @param[in] options Rendering options + * @param[in] resManager Resource manager to use + * @return GFX_OK on success, GFX_ERROR if that particular mode + * is unavailable, or GFX_FATAL if the graphics driver + * is unable to provide any useful graphics support + */ +int gfxop_init(int version, bool isVGA, GfxState *state, gfx_options_t *options, + ResourceManager *resManager, int xfact = 1, int yfact = 1, + gfx_color_mode_t bpp = GFX_COLOR_MODE_INDEX); + +/** + * Deinitializes a currently active driver. + * + * @param[in] state The state encapsulating the driver in question + * @return GFX_OK + */ int gfxop_exit(GfxState *state); -/* Deinitializes a currently active driver -** Parameters: (GfxState *) state: The state encapsulating the driver in question -** Returns : (int) GFX_OK -*/ +/** + * Calculates a bit mask calculated from some pixels on the specified + * map. + * + * @param[in] state The state containing the pixels to scan + * @param[in] area The area to check + * @param[in] map The GFX_MASKed map(s) to test + * @return An integer value where, for each 0 <= i <= 15, bit i is set + * iff there exists a map for which the corresponding bit was + * set in the 'map' parameter and for which there exists a + * pixel within the specified area so that the pixel's lower 4 + * bits, interpreted as an integer value, equal i. (Short + * version: This is an implementation of "on_control()"). + */ int gfxop_scan_bitmask(GfxState *state, rect_t area, gfx_map_mask_t map); -/* Calculates a bit mask calculated from some pixels on the specified map -** Parameters: (GfxState *) state: The state containing the pixels to scan -** (rect_t) area: The area to check -** (gfx_map_mask_t) map: The GFX_MASKed map(s) to test -** Returns : (int) An integer value where, for each 0<=i<=15, bit #i is set -** iff there exists a map for which the corresponding bit was set -** in the 'map' parameter and for which there exists a pixel within -** the specified area so that the pixel's lower 4 bits, interpreted -** as an integer value, equal i. -** (Short version: This is an implementation of "on_control()"). -*/ +/** + * Sets the currently visible map. + * + * 'visible_map' can be any of GFX_MASK_VISUAL, GFX_MASK_PRIORITY and + * GFX_MASK_CONTROL; the appropriate map (as far as its contents are known to + * the graphics subsystem) is then subsequently drawn to the screen at each + * update. If this is set to anything other than GFX_MASK_VISUAL, slow + * full-screen updates are performed. Mostly useful for debugging. The screen + * needs to be updated for the changes to take effect. + * + * @param[in] state The state to modify + * @param[in] map The GFX_MASK to set + * @return GFX_OK, or GFX_ERROR if map was invalid + */ int gfxop_set_visible_map(GfxState *state, gfx_map_mask_t map); -/* Sets the currently visible map -** Parameters: (GfxState *) state: The state to modify -** (gfx_map_mask_t) map: The GFX_MASK to set -** Returns : (int) GFX_OK, or GFX_ERROR if map was invalid -** 'visible_map' can be any of GFX_MASK_VISUAL, GFX_MASK_PRIORITY and GFX_MASK_CONTROL; the appropriate -** map (as far as its contents are known to the graphics subsystem) is then subsequently drawn to the -** screen at each update. If this is set to anything other than GFX_MASK_VISUAL, slow full-screen updates -** are performed. Mostly useful for debugging. -** The screen needs to be updated for the changes to take effect. -*/ +/** + * Sets a new clipping zone. + * + * @param[in] state The affected state + * @param[in] zone The new clipping zone + * @return GFX_OK + */ int gfxop_set_clip_zone(GfxState *state, rect_t zone); -/* Sets a new clipping zone -** Parameters: (GfxState *) state: The affected state -** (rect_t) zone: The new clipping zone -** Returns : (int) GFX_OK -*/ +/** @} */ + -/******************************/ -/* Generic drawing operations */ -/******************************/ +/** @name Generic drawing operations */ +/** @{ */ +/** + * Renders a clipped line to the back buffer. + * + * @param[in] state The state affected + * @param[in] start Starting point of the line + * @param[in] end End point of the line + * @param[in] color The color to use for drawing + * @param[in] line_mode Any valid line mode to use + * @param[in] line_style The line style to use + * @return GFX_OK or GFX_FATAL + */ int gfxop_draw_line(GfxState *state, Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); -/* Renders a clipped line to the back buffer -** Parameters: (GfxState *) state: The state affected -** (Common::Point) start: Starting point of the line -** (Common::Point) end: End point of the line -** (gfx_color_t) color: The color to use for drawing -** (gfx_line_mode_t) line_mode: Any valid line mode to use -** (gfx_line_style_t) line_style: The line style to use -** Returns : (int) GFX_OK or GFX_FATAL -*/ -int gfxop_draw_rectangle(GfxState *state, rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, - gfx_line_style_t line_style); -/* Draws a non-filled rectangular box to the back buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) rect: The rectangular area the box is drawn to -** (gfx_color_t) color: The color the box is to be drawn in -** (gfx_line_mode_t) line_mode: The line mode to use -** (gfx_line_style_t) line_style: The line style to use for the box -** Returns : (int) GFX_OK or GFX_FATAL -** Boxes drawn in thin lines will surround the minimal area described by rect. -*/ +/** + * Draws a non-filled rectangular box to the back buffer. + * + * Boxes drawn in thin lines will surround the minimal area described by rect. + * + * @param[in] state The affected state + * @param[in] rect The rectangular area the box is drawn to + * @param[in] color The color the box is to be drawn in + * @param[in] line_mode The line mode to use + * @param[in] line_style The line style to use for the box + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_rectangle(GfxState *state, rect_t rect, gfx_color_t color, + gfx_line_mode_t line_mode, gfx_line_style_t line_style); -int gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, gfx_color_t color2, - gfx_box_shade_t shade_type); -/* Draws a filled box to the back buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) box: The area to draw to -** (gfx_color_t) color1: The primary color to use for drawing -** (gfx_color_t) color2: The secondary color to draw in -** (gfx_box_shade_t) shade_type: The shading system to use -** (e.g. GFX_BOX_SHADE_FLAT) -** Returns : (int) GFX_OK or GFX_FATAL -** The draw mask, control, and priority values are derived from color1. -*/ +/** + * Draws a filled box to the back buffer. + * + * The draw mask, control, and priority values are derived from color1. + * + * @param[in] state The affected state + * @param[in] box The area to draw to + * @param[in] color1 The primary color to use for drawing + * @param[in] color2 The secondary color to draw in + * @param[in] shade_type The shading system to use (e.g. GFX_BOX_SHADE_FLAT) + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, + gfx_color_t color2, gfx_box_shade_t shade_type); +/** + * Fills a box in the back buffer with a specific color. + * + * This is a simple wrapper function for gfxop_draw_box + * + * @param[in] state The state to draw to + * @param[in] box The box to fill + * @param[in] color The color to use for filling + * @return GFX_OK or GFX_FATAL + */ int gfxop_fill_box(GfxState *state, rect_t box, gfx_color_t color); -/* Fills a box in the back buffer with a specific color -** Parameters: (GfxState *) state: The state to draw to -** (rect_t) box: The box to fill -** (gfx_color_t) color: The color to use for filling -** Returns : (int) GFX_OK or GFX_FATAL -** This is a simple wrapper function for gfxop_draw_box -*/ +/** + * Copies a box from the static buffer to the back buffer. + * + * @param[in] state The affected state + * @param[in] box The box to propagate from the static buffer + * @return GFX_OK or GFX_FATAL + */ int gfxop_clear_box(GfxState *state, rect_t box); -/* Copies a box from the static buffer to the back buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) box: The box to propagate from the static buffer -** Returns : (int) GFX_OK or GFX_FATAL -*/ +/** + * Updates all dirty rectangles. + * + * In order to track dirty rectangles, they must be enabled in the options. This + * function instructs the resource manager to free all tagged data on certain + * occasions (see gfxop_new_pic). + * + * @param[in] state The relevant state + * @return GFX_OK or GFX_FATAL if reported by the driver + */ int gfxop_update(GfxState *state); -/* Updates all dirty rectangles -** Parameters: (GfxState) *state: The relevant state -** Returns : (int) GFX_OK or GFX_FATAL if reported by the driver -** In order to track dirty rectangles, they must be enabled in the options. -** This function instructs the resource manager to free all tagged data -** on certain occasions (see gfxop_new_pic). -*/ +/** + * Propagates a box from the back buffer to the front (visible) buffer. + * + * This function instructs the resource manager to free all tagged data on + * certain occasions (see gfxop_new_pic). When called with dirty rectangle + * management enabled, it will automatically propagate all dirty rectangles as + * well, UNLESS dirty frame accounting has been disabled explicitly. + * + * @param[in] state The affected state + * @param[in] box The box to propagate to the front buffer + * @return GFX_OK or GFX_FATAL + */ int gfxop_update_box(GfxState *state, rect_t box); -/* Propagates a box from the back buffer to the front (visible) buffer -** Parameters: (GfxState *) state: The affected state -** (rect_t) box: The box to propagate to the front buffer -** Returns : (int) GFX_OK or GFX_FATAL -** This function instructs the resource manager to free all tagged data -** on certain occasions (see gfxop_new_pic). -** When called with dirty rectangle management enabled, it will automatically -** propagate all dirty rectangles as well, UNLESS dirty frame accounting has -** been disabled explicitly. -*/ +/** + * Enables dirty frame accounting. + * + * Dirty frame accounting is enabled by default. + * + * @param[in] state The state dirty frame accounting is to be enabled in + * @return GFX_OK or GFX_ERROR if state was invalid + */ int gfxop_enable_dirty_frames(GfxState *state); -/* Enables dirty frame accounting -** Parameters: (GfxState *) state: The state dirty frame accounting is to be enabled in -** Returns : (int) GFX_OK or GFX_ERROR if state was invalid -** Dirty frame accounting is enabled by default. -*/ +/** + * Disables dirty frame accounting. + * + * @param[in] state The state dirty frame accounting is to be disabled in + * @return GFX_OK or GFX_ERROR if state was invalid + */ int gfxop_disable_dirty_frames(GfxState *state); -/* Disables dirty frame accounting -** Parameters: (GfxState *) state: The state dirty frame accounting is to be disabled in -** Returns : (int) GFX_OK or GFX_ERROR if state was invalid -*/ +/** @} */ -/********************/ -/* Color operations */ -/********************/ - -int gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, int a, - int priority, int control); -/* Maps an r/g/b value to a color and sets a gfx_color_t structure -** Parameters: (GfxState *) state: The current state -** (gfx_color_t *) color: Pointer to the structure to write to -** (int x int x int) r,g,b: The red/green/blue color intensity values -** of the result color (0x00 (minimum) to 0xff (max)) -** If any of these values is less than zero, the -** resulting color will not affect the visual map when -** used for drawing -** (int) a: The alpha (transparency) value, with 0x00 meaning absolutely -** opaque and 0xff meaning fully transparent. Alpha blending support -** is optional for drivers, so these are the only two values that -** are guaranteed to work as intended. Any value in between them -** must guarantee the following opaqueness: -** opaqueness(x-1) >= opaqueness(x) >= opaqueness (x+1) -** (i.e. ([0,255], less-transparent-than) must define a partial order) -** (int) priority: The priority to use for drawing, or -1 for none -** (int) control: The control to use for drawing, or -1 to disable drawing to the -** control map -** Returns : (int) GFX_OK or GFX_ERROR if state is invalid -** In palette mode, this may allocate a new color. Use gfxop_free_color() described below to -** free that color. -*/ +/** @name Color operations */ +/** @{ */ + +/** + * Maps an r/g/b value to a color and sets a gfx_color_t structure. + * + * In palette mode, this may allocate a new color. Use gfxop_free_color() to + * free that color. If any of the r/g/b values are less than zero, the resulting + * color will not affect the visual map when used for drawing + * + * @param[in] state The current state + * @param[in] color Pointer to the structure to write to + * @param[in] r The red color intensity values of the result color + * @param[in] g The green color intensity values of the result color + * @param[in] b The blue color intensity values of the result color + * @param[in] a The alpha (transparency) value, with 0x00 meaning + * absolutely opaque and 0xff meaning fully transparent. + * Alpha blending support is optional for drivers, so these + * are the only two values that are guaranteed to work as + * intended. Any value in between them must guarantee the + * following opaqueness: opaqueness(x-1) >= opaqueness(x) + * >= opaqueness (x+1) (i.e. ([0,255], + * less-transparent-than) must define a partial order) + * @param[in] priority The priority to use for drawing, or -1 for none + * @param[in] control The control to use for drawing, or -1 to disable drawing + * to the control map + * @return GFX_OK or GFX_ERROR if state is invalid + */ +int gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, + int a, int priority, int control); +/** + * Designates a color as a 'system color'. + * + * system colors are permanent colors that cannot be deallocated. as such, they must be used with caution. + * + * @param[in] state The affected state + * @param[in] index The index for the new system color + * @param[in] color The color to designate as a system color + * @return GFX_OK or GFX_ERROR if state is invalid + */ int gfxop_set_system_color(GfxState *state, unsigned int index, gfx_color_t *color); -/* Designates a color as a 'system color' -** Parameters: (GfxState *) state: The affected state -** (unsigned int) index: The index for the new system color -** (gfx_color_t *) color: The color to designate as a system color -** Returns : (int) GFX_OK or GFX_ERROR if state is invalid -** System colors are permanent colors that cannot be deallocated. As such, they must be used -** with caution. -*/ +/** + * Frees a color allocated by gfxop_set_color(). + * + * This function is a no-op in non-index mode, or if color is a system color. + * + * @param[in] state The state affected + * @param[in] color The color to de-allocate + * @return GFX_OK or GFX_ERROR if state is invalid + */ int gfxop_free_color(GfxState *state, gfx_color_t *color); -/* Frees a color allocated by gfxop_set_color() -** Parmaeters: (GfxState *) state: The state affected -** (gfx_color_t *) color: The color to de-allocate -** Returns : (int) GFX_OK or GFX_ERROR if state is invalid -** This function is a no-op in non-index mode, or if color is a system color. -*/ - +/** @} */ -/**********************/ -/* Pointer and IO ops */ -/**********************/ +/** @name Pointer and IO ops */ +/** @{ */ +/** + * Suspends program execution for the specified amount of milliseconds. + * + * The mouse pointer will be redrawn continually, if applicable + * + * @param[in] state The state affected + * @param[in] msecs The amount of milliseconds to wait + * @return GFX_OK or GFX_ERROR + */ int gfxop_sleep(GfxState *state, uint32 msecs); -/* Suspends program execution for the specified amount of milliseconds -** Parameters: (GfxState *) state: The state affected -** (uint32) usecs: The amount of milliseconds to wait -** Returns : (int) GFX_OK or GFX_ERROR -** The mouse pointer will be redrawn continually, if applicable -*/ +/** + * Sets the mouse pointer to a cursor resource. + * + * @param[in] state The affected state + * @param[in] nr Number of the cursor resource to use + * @return GFX_OK, GFX_ERROR if the resource did not exist and was not + * GFXOP_NO_POINTER, or GFX_FATAL on fatal error conditions. + * Use nr = GFX_NO_POINTER to disable the mouse pointer + * (default). + */ int gfxop_set_pointer_cursor(GfxState *state, int nr); -/* Sets the mouse pointer to a cursor resource -** Parameters: (GfxState *) state: The affected state -** (int) nr: Number of the cursor resource to use -** Returns : (int) GFX_OK, GFX_ERROR if the resource did not -** exist and was not GFXOP_NO_POINTER, or GFX_FATAL on -** fatal error conditions. -** Use nr = GFX_NO_POINTER to disable the mouse pointer (default). -*/ +/** + * Sets the mouse pointer to a view resource. + * + * Use gfxop_set_pointer_cursor(state, GFXOP_NO_POINTER) to disable the pointer. + * + * @param[in] state The affected state + * @param[in] nr Number of the view resource to use + * @param[in] loop View loop to use + * @param[in] cel View cel to use + * @param[in] hotspot Manually set hotspot to use, or NULL for default. + * @return GFX_OK or GFX_FATAL + */ int gfxop_set_pointer_view(GfxState *state, int nr, int loop, int cel, Common::Point *hotspot); -/* Sets the mouse pointer to a view resource -** Parameters: (GfxState *) state: The affected state -** (int) nr: Number of the view resource to use -** (int) loop: View loop to use -** (int) cel: View cel to use -** (Common::Point *) hotspot: Manually set hotspot to use, or NULL for default. -** Returns : (int) GFX_OK or GFX_FATAL -** Use gfxop_set_pointer_cursor(state, GFXOP_NO_POINTER) to disable the -** pointer. -*/ +/** + * Teleports the mouse pointer to a specific position. + * + * Depending on the graphics driver, this operation may be without any effect + * + * @param[in] state The state the pointer is in + * @param[in] pos The position to teleport it to + * @return Any error code or GFX_OK + */ int gfxop_set_pointer_position(GfxState *state, Common::Point pos); -/* Teleports the mouse pointer to a specific position -** Parameters: (GfxState *) state: The state the pointer is in -** (Common::Point) pos: The position to teleport it to -** Returns : (int) Any error code or GFX_OK -** Depending on the graphics driver, this operation may be without -** any effect -*/ +/** + * Retrieves the next input event from the driver. + * + * @param[in] state The affected state + * @param[in] mask The event mask to poll from (see uinput.h) + * @return The next event in the driver's event queue, or a NONE event + * if no event matching the mask was found. + */ sci_event_t gfxop_get_event(GfxState *state, unsigned int mask); -/* Retrieves the next input event from the driver -** Parameters: (GfxState *) state: The affected state -** (int) mask: The event mask to poll from (see uinput.h) -** Returns : (sci_event_t) The next event in the driver's event queue, or -** a NONE event if no event matching the mask was found. -*/ +/** @} */ +/** @name View operations */ +/** @{ */ -/*******************/ -/* View operations */ -/*******************/ - +/** + * Determines the number of loops associated with a view. + * + * @param[in] state The state to use + * @param[in] nr Number of the view to investigate + * @return The number of loops, or GFX_ERROR if the view didn't exist + */ int gfxop_lookup_view_get_loops(GfxState *state, int nr); -/* Determines the number of loops associated with a view -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view to investigate -** Returns : (int) The number of loops, or GFX_ERROR if the view didn't exist -*/ +/** + * Determines the number of cels associated stored in a loop. + * + * @param[in] state The state to look up in + * @param[in] nr Number of the view to look up in + * @param[in] loop Number of the loop the number of cels of are to be + * investigated + * @return The number of cels in that loop, or GFX_ERROR if either the + * view or the loop didn't exist + */ int gfxop_lookup_view_get_cels(GfxState *state, int nr, int loop); -/* Determines the number of cels associated stored in a loop -** Parameters: (GfxState *) state: The state to look up in -** (int) nr: Number of the view to look up in -** (int) loop: Number of the loop the number of cels of -** are to be investigated -** Returns : (int) The number of cels in that loop, or GFX_ERROR if either -** the view or the loop didn't exist -*/ +/** + * Clips the view/loop/cel position of a cel. + * + * *loop is clipped first, then *cel. The resulting setup will be a valid view + * configuration. + * + * @param[in] state The state to use + * @param[in] nr Number of the view to use + * @param[in] loop Pointer to the variable storing the loop number to verify + * @param[in] cel Pointer to the variable storing the cel number to check + * @return GFX_OK or GFX_ERROR if the view didn't exist + */ int gfxop_check_cel(GfxState *state, int nr, int *loop, int *cel); -/* Clips the view/loop/cel position of a cel -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view to use -** (int *) loop: Pointer to the variable storing the loop -** number to verify -** (int *) cel: Pointer to the variable storing the cel -** number to check -** Returns : (int) GFX_OK or GFX_ERROR if the view didn't exist -** *loop is clipped first, then *cel. The resulting setup will be a valid -** view configuration. -*/ +/** + * Resets loop/cel values to zero if they have become invalid. + * + * @param[in] state The state to use + * @param[in] nr Number of the view to use + * @param[in] loop Pointer to the variable storing the loop number to verify + * @param[in] cel Pointer to the variable storing the cel number to check + * @return GFX_OK or GFX_ERROR if the view didn't exist *loop is + * clipped first, then *cel. The resulting setup will be a + * valid view configuration. + */ int gfxop_overflow_cel(GfxState *state, int nr, int *loop, int *cel); -/* Resets loop/cel values to zero if they have become invalid -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view to use -** (int *) loop: Pointer to the variable storing the loop -** number to verify -** (int *) cel: Pointer to the variable storing the cel -** number to check -** Returns : (int) GFX_OK or GFX_ERROR if the view didn't exist -** *loop is clipped first, then *cel. The resulting setup will be a valid -** view configuration. -*/ +/** + * Retrieves the width and height of a cel. + * + * @param[in] state The state to use + * @param[in] nr Number of the view + * @param[in] loop Loop number to examine + * @param[in] cel The cel (inside the loop) to look up + * @param[in] width The variable the width will be stored in + * @param[in] height The variable the height will be stored in + * @param[in] offset The variable the cel's x/y offset will be stored in + * @return GFX_OK if the lookup succeeded, GFX_ERROR if the + * nr/loop/cel combination was invalid + */ int gfxop_get_cel_parameters(GfxState *state, int nr, int loop, int cel, int *width, int *height, Common::Point *offset); -/* Retrieves the width and height of a cel -** Parameters: (GfxState *) state: The state to use -** (int) nr: Number of the view -** (int) loop: Loop number to examine -** (int) cel: The cel (inside the loop) to look up -** (int *) width: The variable the width will be stored in -** (int *) height: The variable the height will be stored in -** (Common::Point *) offset: The variable the cel's x/y offset will be stored in -** Returns : (int) GFX_OK if the lookup succeeded, GFX_ERROR if the nr/loop/cel -** combination was invalid -*/ -int gfxop_draw_cel(GfxState *state, int nr, int loop, int cel, Common::Point pos, - gfx_color_t color, int palette); -/* Draws (part of) a cel to the back buffer -** Parameters: (GfxState *) state: The state encapsulating the driver to draw with -** (int) nr: Number of the view to draw -** (int) loop: Loop of the cel to draw -** (int) cel: The cel number of the cel to draw -** (Common::Point) pos: The positino the cel is to be drawn to -** (gfx_color_t color): The priority and control values to use for drawing -** (int) palette: The palette to use -** Returns : (int) GFX_OK or GFX_FATAL -*/ +/** + * Draws (part of) a cel to the back buffer. + * + * @param[in] state The state encapsulating the driver to draw with + * @param[in] nr Number of the view to draw + * @param[in] loop Loop of the cel to draw + * @param[in] cel The cel number of the cel to draw + * @param[in] pos The positino the cel is to be drawn to + * @param[in] color The priority and control values to use for drawing + * @param[in] palette The palette to use + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_cel(GfxState *state, int nr, int loop, int cel, + Common::Point pos, gfx_color_t color, int palette); -int gfxop_draw_cel_static(GfxState *state, int nr, int loop, int cel, Common::Point pos, - gfx_color_t color, int palette); -/* Draws a cel to the static buffer; no clipping is performed -** Parameters: (GfxState *) state: The state encapsulating the driver to draw with -** (int) nr: Number of the view to draw -** (int) loop: Loop of the cel to draw -** (int) cel: The cel number of the cel to draw -** (Common::Point) pos: The positino the cel is to be drawn to -** (gfx_color_t color): The priority and control values to use for drawing -** (int) palette: The palette to use -** Returns : (int) GFX_OK or GFX_FATAL -** Let me repeat, no clipping (except for the display borders) is performed. -*/ +/** + * Draws a cel to the static buffer; no clipping is performed. + * + * No clipping (except for the display borders) is performed. + * + * @param[in] state The state encapsulating the driver to draw with + * @param[in] nr Number of the view to draw + * @param[in] loop Loop of the cel to draw + * @param[in] cel The cel number of the cel to draw + * @param[in] pos The positino the cel is to be drawn to + * @param[in] color The priority and control values to use for drawing + * @param[in] palette The palette to use + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_cel_static(GfxState *state, int nr, int loop, int cel, + Common::Point pos, gfx_color_t color, int palette); -int gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, Common::Point pos, - gfx_color_t color, int palette); -/* Draws (part of) a clipped cel to the static buffer -** Parameters: (GfxState *) state: The state encapsulating the driver to draw with -** (int) nr: Number of the view to draw -** (int) loop: Loop of the cel to draw -** (int) cel: The cel number of the cel to draw -** (Common::Point) pos: The positino the cel is to be drawn to -** (gfx_color_t color): The priority and control values to use for drawing -** (int) palette: The palette to use -** Returns : (int) GFX_OK or GFX_FATAL -** This function does clip. -*/ +/** + * Draws (part of) a clipped cel to the static buffer. + * + * This function does clip. + * + * @param[in] state The state encapsulating the driver to draw with + * @param[in] nr Number of the view to draw + * @param[in] loop Loop of the cel to draw + * @param[in] cel The cel number of the cel to draw + * @param[in] pos The positino the cel is to be drawn to + * @param[in] color The priority and control values to use for drawing + * @param[in] palette The palette to use + * @return GFX_OK or GFX_FATAL + */ +int gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, + Common::Point pos, gfx_color_t color, int palette); +/** @} */ -/******************/ -/* Pic operations */ -/******************/ -/* These operations are exempt from clipping */ +/** @name Pic operations + * These operations are exempt from clipping */ +/** @{ */ +/** + * Draws a pic and writes it over the static buffer. + * + * This function instructs the resource manager to tag all data as "unused". + * See the resource manager tag functions for a full description. + * + * @param[in] state The state affected + * @param[in] nr Number of the pic to draw + * @param[in] flags Interpreter-dependant flags to use for drawing + * @param[in] default_palette The default palette for drawing + * @return GFX_OK or GFX_FATAL + */ int gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette); -/* Draws a pic and writes it over the static buffer -** Parameters: (GfxState *) state: The state affected -** (int) nr: Number of the pic to draw -** (int) flags: Interpreter-dependant flags to use for drawing -** (int) default_palette: The default palette for drawing -** Returns : (int) GFX_OK or GFX_FATAL -** This function instructs the resource manager to tag all data as "unused". -** See the resource manager tag functions for a full description. -*/ +/** + * Retrieves all meta-information assigned to the current pic. + * + * @param[in] state The state affected + * @return NULL if the pic doesn't exist or has no meta-information, + * the meta-info otherwise. This meta-information is referred + * to as 'internal data' in the pic code + */ int *gfxop_get_pic_metainfo(GfxState *state); -/* Retrieves all meta-information assigned to the current pic -** Parameters: (GfxState *) state: The state affected -** Returns : (int *) NULL if the pic doesn't exist or has no meta-information, -** the meta-info otherwise -** This meta-information is referred to as 'internal data' in the pic code -*/ +/** + * Adds a pic to the static buffer. + * + * @param[in] state The state affected + * @param[in] nr Number of the pic to add + * @param[in] flags Interpreter-dependant flags to use for drawing + * @param[in] default_palette The default palette for drawing + * @return GFX_OK or GFX_FATAL + */ int gfxop_add_to_pic(GfxState *state, int nr, int flags, int default_palette); -/* Adds a pic to the static buffer -** Parameters: (GfxState *) state: The state affected -** (int) nr: Number of the pic to add -** (int) flags: Interpreter-dependant flags to use for drawing -** (int) default_palette: The default palette for drawing -** Returns : (int) GFX_OK or GFX_FATAL -*/ - +/** @} */ +/** @name Text operations */ +/** @{ */ -/*******************/ -/* Text operations */ -/*******************/ - - +/** + * Returns the fixed line height for one specified font. + * + * @param[in] state The state to work on + * @param[in] font_nr Number of the font to inspect + * @return GFX_ERROR, GFX_FATAL, or the font line height + */ int gfxop_get_font_height(GfxState *state, int font_nr); -/* Returns the fixed line height for one specified font -** Parameters: (GfxState *) state: The state to work on -** (int) font_nr: Number of the font to inspect -** Returns : (int) GFX_ERROR, GFX_FATAL, or the font line height -*/ +/** + * Calculates the width and height of a specified text in a specified + * font. + * + * @param[in] state The state to use + * @param[in] font_nr Font number to use for the calculation + * @param[in] text The text to examine + * @param[in] flags ORred GFXR_FONT_FLAGs + * @param[in] maxwidth The maximum pixel width to allow for the text + * @param[out] width The resulting width + * @param[out] height The resulting height + * @param[out] lines_nr Number of lines used in the text + * @param[out] lineheight Pixel height (SCI scale) of each text line + * @param[out] lastline_width Pixel offset (SCI scale) of the space after + * the last character in the last line + * @return GFX_OK or GFX_ERROR if the font didn't exist + */ int gfxop_get_text_params(GfxState *state, int font_nr, const char *text, int maxwidth, int *width, int *height, int flags, int *lines_nr, int *lineheight, int *lastline_width); -/* Calculates the width and height of a specified text in a specified font -** Parameters: (GfxState *) state: The state to use -** (int) font_nr: Font number to use for the calculation -** (const char *) text: The text to examine -** (int) flags: ORred GFXR_FONT_FLAGs -** (int) maxwidth: The maximum pixel width to allow for the text -** Returns : (int) GFX_OK or GFX_ERROR if the font didn't exist -** (int) *width: The resulting width -** (int) *height: The resulting height -** (int) *lines_nr: Number of lines used in the text -** (int) *lineheight: Pixel height (SCI scale) of each text line -** (int) *lastline_wdith: Pixel offset (SCI scale) of the space -** after the last character in the last line -*/ -TextHandle *gfxop_new_text(GfxState *state, int font_nr, const Common::String &text, int maxwidth, - gfx_alignment_t halign, gfx_alignment_t valign, gfx_color_t color1, - gfx_color_t color2, gfx_color_t bg_color, int flags); -/* Generates a new text handle that can be used to draw any text -** Parameters: (GfxState *) state: The state to use -** (int) font_nr: Font number to use for the calculation -** (const char *) text: The text to examine -** (int) maxwidth: The maximum pixel width to allow for the text -** (gfx_alignment_t) halign: The horizontal text alignment -** (gfx_alignment_t) valign: The vertical text alignment -** (gfx_color_t x gfx_color_t) color1, color2: The text's foreground colors -** (the function will dither between those two) -** (gfx_color_t) bg_color: The background color -** (int) flags: ORred GFXR_FONT_FLAGs -** Returns : (TextHandle *) A newly allocated TextHandle, or -** NULL if font_nr was invalid -** The control and priority values for the text will be extracted from color1. -** Note that the colors must have been allocated properly, or the text may display in -** incorrect colors. -*/ +/** + * Generates a new text handle that can be used to draw any text. + * + * The control and priority values for the text will be extracted from color1. + * Note that the colors must have been allocated properly, or the text may + * display in incorrect colors. + * + * @param[in] state The state to use + * @param[in] font_nr Font number to use for the calculation + * @param[in] text The text to examine + * @param[in] maxwidth: The maximum pixel width to allow for the text + * @param[in] halign The horizontal text alignment + * @param[in] valign The vertical text alignment + * @param[in] color1 The text's foreground colors (the function will dither + * between color1 and 2) + * @param[in] color2 The text's foreground colors (the function will dither + * between color1 and 2) + * @param[in] bg_color The background color + * @param[in] flags ORred GFXR_FONT_FLAGs + * @return A newly allocated TextHandle, or NULL if font_nr was + * invalid + */ +TextHandle *gfxop_new_text(GfxState *state, int font_nr, + const Common::String &text, int maxwidth, gfx_alignment_t halign, + gfx_alignment_t valign, gfx_color_t color1, gfx_color_t color2, + gfx_color_t bg_color, int flags); +/** + * Frees a previously allocated text handle and all related resources. + * + * @param[in] state The state to use + * @param[in] handle The handle to free + * @return GFX_OK + */ int gfxop_free_text(GfxState *state, TextHandle *handle); -/* Frees a previously allocated text handle and all related resources -** Parameters: (GfxState *) state: The state to use -** (TextHandle *) handle: The handle to free -** Returns : (int) GFX_OK -*/ +/** + * Draws text stored in a text handle. + * + * @param[in] state The target state + * @param[in] handle The text handle to use for drawing + * @param[in] zone The rectangular box to draw to. In combination with + * halign and valign, this defines where the text is drawn + * to. + * @return GFX_OK or GFX_FATAL + */ int gfxop_draw_text(GfxState *state, TextHandle *handle, rect_t zone); -/* Draws text stored in a text handle -** Parameters: (GfxState *) state: The target state -** (TextHandle *) handle: The text handle to use for drawing -** (rect_t) zone: The rectangular box to draw to. In combination with -** halign and valign, this defines where the text is -** drawn to. -** Returns : (int) GFX_OK or GFX_FATAL -*/ +/** @} */ -/****************************/ -/* Manual pixmap operations */ -/****************************/ +/** @name Manual pixmap operations */ +/** @{ */ +/** + * Grabs a screen section from the back buffer and stores it in a pixmap. + * + * Obviously, this only affects the visual map + * + * @param[in] state The affected state + * @param[in] area The area to grab + * Returns A result pixmap, or NULL on error + */ gfx_pixmap_t *gfxop_grab_pixmap(GfxState *state, rect_t area); -/* Grabs a screen section from the back buffer and stores it in a pixmap -** Parameters: (GfxState *) state: The affected state -** (rect_t) area: The area to grab -** Returns : (gfx_pixmap_t *) A result pixmap, or NULL on error -** Obviously, this only affects the visual map -*/ -int gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, Common::Point pos); -/* Draws part of a pixmap to the screen -** Parameters: (GfxState *) state: The affected state -** (gfx_pixmap_t *) pxm: The pixmap to draw -** (rect_t) zone: The segment of the pixmap to draw -** (Common::Point) pos: The position the pixmap should be drawn to -** Returns : (int) GFX_OK or any error code -*/ +/** + * Draws part of a pixmap to the screen. + * + * @param[in] state The affected state + * @param[in] pxm The pixmap to draw + * @param[in] zone The segment of the pixmap to draw + * @param[in] pos The position the pixmap should be drawn to + * @return GFX_OK or any error code + */ +int gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, + Common::Point pos); +/** + * Frees a pixmap returned by gfxop_grab_pixmap(). + * + * @param[in] state The affected state + * @param[in] pxm The pixmap to free + * @return GFX_OK, or GFX_ERROR if the state was invalid + */ int gfxop_free_pixmap(GfxState *state, gfx_pixmap_t *pxm); -/* Frees a pixmap returned by gfxop_grab_pixmap() -** Parameters: (GfxState *) state: The affected state -** (gfx_pixmap_t *) pxm: The pixmap to free -** Returns : (int) GFX_OK, or GFX_ERROR if the state was invalid -*/ +/** @} */ -/******************************/ -/* Dirty rectangle operations */ -/******************************/ + +/** @name Dirty rectangle operations */ +/** @{ */ /** * Adds a dirty rectangle to 'base' according to a strategy. - * @param list the list to add to - * @param box the dirty frame to addable - * @param strategy the dirty frame heuristic to use (see gfx_options.h) + * + * @param[in] list the list to add to + * @param[in] box the dirty frame to addable + * @param[in] strategy the dirty frame heuristic to use (see gfx_options.h) */ void gfxdr_add_dirty(DirtyRectList &list, rect_t box, int strategy); +/** + * Clips a rectangle against another one. + * + * @param[in] rect The rectangle to clip + * @param[in] clipzone The outer bounds rect must be in + * @return 1 if rect is empty now, 0 otherwise + */ int _gfxop_clip(rect_t *rect, rect_t clipzone); -/* Clips a rectangle against another one -** Parameters: (rect_t *) rect: The rectangle to clip -** (rect_t) clipzone: The outer bounds rect must be in -** Reuturns : (int) 1 if rect is empty now, 0 otherwise -*/ +/** @} */ } // End of namespace Sci diff --git a/engines/sci/gfx/palette.h b/engines/sci/gfx/palette.h index 127871bce4..65d1cac18e 100644 --- a/engines/sci/gfx/palette.h +++ b/engines/sci/gfx/palette.h @@ -42,15 +42,18 @@ struct PaletteEntry { : r(R), g(G), b(B), parent_index(-1), refcount(PALENTRY_FREE) { } - // Color data + /** @name Color data */ + /** @{ */ byte r, g, b; + /** @} */ - // Index in parent palette, or -1 + /** Index in parent palette, or -1 */ int parent_index; - // Number of references from child palettes. (This includes palettes - // of pixmaps.) - // Special values: PALENTRY_LOCKED, PALENTRY_FREE + /** + * Number of references from child palettes. (This includes palettes + * of pixmaps.) + * Special values: PALENTRY_LOCKED, PALENTRY_FREE */ int refcount; }; @@ -98,10 +101,9 @@ private: Palette *_parent; - bool _dirty; // Palette has changed - int _refcount; // Number of pixmaps (or other objects) using this palette - int _revision; // When this is incremented, all child references are - // invalidated + bool _dirty; /**< Palette has changed */ + int _refcount; /**< Number of pixmaps (or other objects) using this palette */ + int _revision; /**< When this is incremented, all child references are invalidated */ }; diff --git a/engines/sci/gfx/res_pic.cpp b/engines/sci/gfx/res_pic.cpp index 762cb7b55d..5ee2665b50 100644 --- a/engines/sci/gfx/res_pic.cpp +++ b/engines/sci/gfx/res_pic.cpp @@ -152,7 +152,7 @@ void gfxr_init_static_palette() { } -gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, int sci1) { +gfxr_pic_t *gfxr_init_pic(gfx_mode_t *mode, int ID, bool sci1) { gfxr_pic_t *pic = (gfxr_pic_t*)malloc(sizeof(gfxr_pic_t)); pic->mode = mode; diff --git a/engines/sci/gfx/res_view.cpp b/engines/sci/gfx/res_view.cpp index f282369e15..b30c57f38d 100644 --- a/engines/sci/gfx/res_view.cpp +++ b/engines/sci/gfx/res_view.cpp @@ -331,7 +331,7 @@ gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *reso 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) : (int8) cel_base[5]; + 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; gfx_pixmap_t *retval = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xl, yl, id, loop, cel)); diff --git a/engines/sci/gfx/seq_decoder.h b/engines/sci/gfx/seq_decoder.h index 16574007fe..b9feadb5f3 100644 --- a/engines/sci/gfx/seq_decoder.h +++ b/engines/sci/gfx/seq_decoder.h @@ -28,6 +28,9 @@ namespace Sci { +/** + * Decoder for image sequences + */ class SeqDecoder { public: SeqDecoder() : _fileStream(0), _palette(0) { } @@ -37,7 +40,9 @@ public: gfx_pixmap_t *getFrame(bool &hasNext); private: - bool decodeFrame(byte *runlength_data, int runlength_size, byte *literal_data, int literal_size, byte *dest, int xl, int yl, int color_key); + bool decodeFrame(byte *runlength_data, int runlength_size, + byte *literal_data, int literal_size, byte *dest, int xl, int yl, + int color_key); Common::SeekableReadStream *_fileStream; Palette *_palette; diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp index 5edf1b7145..3c377e8ef2 100644 --- a/engines/sci/resource.cpp +++ b/engines/sci/resource.cpp @@ -56,13 +56,6 @@ const char *sci_version_types[] = { const int sci_max_resource_nr[] = {65536, 1000, 2048, 2048, 2048, 65536, 65536, 65536}; -enum SolFlags { - kSolFlagCompressed = 1 << 0, - kSolFlagUnknown = 1 << 1, - kSolFlag16Bit = 1 << 2, - kSolFlagIsSigned = 1 << 3 -}; - static const char *sci_error_types[] = { "No error", "I/O error", @@ -217,7 +210,7 @@ bool ResourceManager::loadFromPatchFile(Resource *res) { return loadPatch(res, file); } -bool ResourceManager::loadFromAudioVolume(Resource *res, Common::File &file) { +bool ResourceManager::loadFromAudioVolumeSCI11(Resource *res, Common::File &file) { ResourceType type = (ResourceType)(file.readByte() & 0x7f); if (((res->id.type == kResourceTypeAudio || res->id.type == kResourceTypeAudio36) && (type != kResourceTypeAudio)) || ((res->id.type == kResourceTypeSync || res->id.type == kResourceTypeSync36) && (type != kResourceTypeSync))) { @@ -243,6 +236,21 @@ bool ResourceManager::loadFromAudioVolume(Resource *res, Common::File &file) { return loadPatch(res, file); } +bool ResourceManager::loadFromAudioVolumeSCI1(Resource *res, Common::File &file) { + res->data = new byte[res->size]; + + if (res->data == NULL) { + error("Can't allocate %d bytes needed for loading %s", res->size, res->id.toString().c_str()); + } + + unsigned int really_read = file.read(res->data, res->size); + if (really_read != res->size) + warning("Read %d bytes from %s but expected %d", really_read, res->id.toString().c_str(), res->size); + + res->status = kResStatusAllocated; + return true; +} + Common::File *ResourceManager::getVolumeFile(const char *filename) { Common::List<Common::File *>::iterator it = _volumeFiles.begin(); Common::File *file; @@ -292,7 +300,10 @@ void ResourceManager::loadResource(Resource *res) { file->seek(res->file_offset, SEEK_SET); if (res->source->source_type == kSourceAudioVolume) { - loadFromAudioVolume(res, *file); + if (_sciVersion < SCI_VERSION_1_1) + loadFromAudioVolumeSCI1(res, *file); + else + loadFromAudioVolumeSCI11(res, *file); } else { int error = decompress(res, file); if (error) { @@ -436,8 +447,11 @@ void ResourceManager::scanNewSources() { else readResourceMapSCI1(source); break; + case kSourceExtAudioMap: + readAudioMapSCI1(source); + break; case kSourceIntMap: - readMap(source); + readAudioMapSCI11(source); break; default: break; @@ -460,6 +474,7 @@ ResourceManager::ResourceManager(int version, int maxMemory) { _LRU.clear(); _resMap.clear(); _sciVersion = version; + _audioMapSCI1 = NULL; addAppropriateSources(); @@ -607,15 +622,10 @@ void ResourceManager::printLRU() { debug("Total: %d entries, %d bytes (mgr says %d)", entries, mem, _memoryLRU); } -void ResourceManager::freeOldResources(int last_invulnerable) { - while (_maxMemory < _memoryLRU && (!last_invulnerable || !_LRU.empty())) { +void ResourceManager::freeOldResources() { + while (_maxMemory < _memoryLRU) { + assert(!_LRU.empty()); Resource *goner = *_LRU.reverse_begin(); - if (!goner) { - debug("Internal error: mgr->lru_last is NULL!"); - debug("LRU-mem= %d", _memoryLRU); - debug("lru_first = %p", (void *)*_LRU.begin()); - printLRU(); - } removeFromLRU(goner); goner->unalloc(); #ifdef SCI_VERBOSE_RESMGR @@ -659,6 +669,8 @@ Resource *ResourceManager::findResource(ResourceId id, bool lock) { // Unless an error occured, the resource is now either // locked or allocated, but never queued or freed. + freeOldResources(); + if (lock) { if (retval->status == kResStatusAllocated) { retval->status = kResStatusLocked; @@ -671,8 +683,6 @@ Resource *ResourceManager::findResource(ResourceId id, bool lock) { addToLRU(retval); } - freeOldResources(retval->status == kResStatusAllocated); - if (retval->data) return retval; else { @@ -695,7 +705,7 @@ void ResourceManager::unlockResource(Resource *res) { addToLRU(res); } - freeOldResources(0); + freeOldResources(); } int ResourceManager::detectMapVersion() { @@ -871,15 +881,7 @@ void ResourceManager::processPatch(ResourceSource *source, ResourceType restype, } // Prepare destination, if neccessary if (_resMap.contains(resId) == false) { - // FIXME: code duplication - switch (restype) { - case kResourceTypeSync: - newrsc = new ResourceSync; - break; - default: - newrsc = new Resource; - break; - } + newrsc = new Resource; _resMap.setVal(resId, newrsc); } else newrsc = _resMap.getVal(resId); @@ -1042,15 +1044,7 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { resId = ResourceId((ResourceType)type, number); // adding new resource only if it does not exist if (_resMap.contains(resId) == false) { - switch (type) { - case kResourceTypeSync: - res = new ResourceSync; - break; - default: - res = new Resource; - break; - } - + res = new Resource; _resMap.setVal(resId, res); res->id = resId; res->source = getVolume(map, volume_nr); @@ -1064,11 +1058,7 @@ int ResourceManager::readResourceMapSCI1(ResourceSource *map) { void ResourceManager::addResource(ResourceId resId, ResourceSource *src, uint32 offset, uint32 size) { // Adding new resource only if it does not exist if (_resMap.contains(resId) == false) { - Resource *res; - if ((resId.type == kResourceTypeSync) || (resId.type == kResourceTypeSync36)) - res = new ResourceSync; - else - res = new Resource; + Resource *res = new Resource; _resMap.setVal(resId, res); res->id = resId; res->source = src; @@ -1077,6 +1067,22 @@ void ResourceManager::addResource(ResourceId resId, ResourceSource *src, uint32 } } +void ResourceManager::removeAudioResource(ResourceId resId) { + // Remove resource, unless it was loaded from a patch + if (_resMap.contains(resId)) { + Resource *res = _resMap.getVal(resId); + + if (res->source->source_type == kSourceAudioVolume) { + if (res->lockers == 0) { + _resMap.erase(resId); + delete res; + } else { + warning("Failed to remove resource %s (still in use)", resId.toString().c_str()); + } + } + } +} + // Early SCI1.1 65535.MAP structure (uses RESOURCE.AUD): // ========= // 6-byte entries: @@ -1112,7 +1118,7 @@ void ResourceManager::addResource(ResourceId resId, ResourceSource *src, uint32 // w syncSize (iff seq has bit 7 set) // w syncAscSize (iff seq has bit 6 set) -int ResourceManager::readMap(ResourceSource *map) { +int ResourceManager::readAudioMapSCI11(ResourceSource *map) { bool isEarly = true; uint32 offset = 0; Resource *mapRes = findResource(ResourceId(kResourceTypeMap, map->volume_number), false); @@ -1197,6 +1203,103 @@ int ResourceManager::readMap(ResourceSource *map) { return 0; } +// AUDIOnnn.MAP contains 10-byte entries: +// w nEntry +// dw offset+volume (as in resource.map) +// dw size +// ending with 10 0xFFs + +int ResourceManager::readAudioMapSCI1(ResourceSource *map, bool unload) { + Common::File file; + + if (!file.open(map->location_name)) + return SCI_ERROR_RESMAP_NOT_FOUND; + + while (1) { + uint16 n = file.readUint16LE(); + uint32 offset = file.readUint32LE(); + uint32 size = file.readUint32LE(); + + if (file.ioFailed()) { + warning("Error while reading %s", map->location_name.c_str()); + return SCI_ERROR_RESMAP_NOT_FOUND; + } + + if (n == 0xffff) + break; + + byte volume_nr = offset >> 28; // most significant 4 bits + offset &= 0x0fffffff; // least significant 28 bits + + ResourceSource *src = getVolume(map, volume_nr); + + if (src) { + if (unload) + removeAudioResource(ResourceId(kResourceTypeAudio, n)); + else + addResource(ResourceId(kResourceTypeAudio, n), src, offset, size); + } else { + warning("Failed to find audio volume %i", volume_nr); + } + } + + return 0; +} + +void ResourceManager::setAudioLanguage(int language) { + if (_audioMapSCI1) { + if (_audioMapSCI1->volume_number == language) { + // This language is already loaded + return; + } + + // We already have a map loaded, so we unload it first + readAudioMapSCI1(_audioMapSCI1, true); + + // Remove all volumes that use this map from the source list + Common::List<ResourceSource *>::iterator it = _sources.begin(); + while (it != _sources.end()) { + ResourceSource *src = *it; + if (src->associated_map == _audioMapSCI1) { + it = _sources.erase(it); + delete src; + } else { + ++it; + } + } + + // Remove the map itself from the source list + _sources.remove(_audioMapSCI1); + delete _audioMapSCI1; + + _audioMapSCI1 = NULL; + } + + char filename[9]; + snprintf(filename, 9, "AUDIO%03d", language); + + Common::String fullname = Common::String(filename) + ".MAP"; + if (!Common::File::exists(fullname)) { + warning("No audio map found for language %i", language); + return; + } + + _audioMapSCI1 = addSource(NULL, kSourceExtAudioMap, fullname.c_str(), language); + + // Search for audio volumes for this language and add them to the source list + Common::ArchiveMemberList files; + SearchMan.listMatchingMembers(files, Common::String(filename) + ".0??"); + for (Common::ArchiveMemberList::const_iterator x = files.begin(); x != files.end(); ++x) { + const Common::String name = (*x)->getName(); + const char *dot = strrchr(name.c_str(), '.'); + int number = atoi(dot + 1); + + addSource(_audioMapSCI1, kSourceAudioVolume, name.c_str(), number); + } + + scanNewSources(); +} + int ResourceManager::readResourceInfo(Resource *res, Common::File *file, uint32&szPacked, ResourceCompression &compression) { // SCI0 volume format: {wResId wPacked+4 wUnpacked wCompression} = 8 bytes @@ -1328,325 +1431,4 @@ int ResourceManager::decompress(Resource *res, Common::File *file) { return error; } -void ResourceSync::startSync(EngineState *s, reg_t obj) { - _syncTime = _syncCue = -1; - PUT_SEL32V(obj, syncCue, 0); - _ptr = (uint16 *)data; - //syncStarted = true; // not used -} - -void ResourceSync::nextSync(EngineState *s, reg_t obj) { - if (_ptr) { - _syncTime = (int16)READ_LE_UINT16(_ptr); - if (_syncTime == -1) { - stopSync(); - } else { - _syncCue = (int16)READ_LE_UINT16(_ptr + 1); - _ptr += 2; - } - PUT_SEL32V(obj, syncTime, _syncTime); - PUT_SEL32V(obj, syncCue, _syncCue); - } -} -//-------------------------------- -void ResourceSync::stopSync() { - _ptr = 0; - _syncCue = -1; - //syncStarted = false; // not used -} - - -AudioResource::AudioResource(ResourceManager *resMgr, int sciVersion) { - _resMgr = resMgr; - _sciVersion = sciVersion; - _audioRate = 11025; - _lang = 0; - _audioMapSCI1 = 0; - _audioMapSCI11 = 0; -} - -AudioResource::~AudioResource() { - if (_sciVersion < SCI_VERSION_1_1) { - if (_audioMapSCI1) { - delete[] _audioMapSCI1; - _audioMapSCI1 = 0; - } - } else { - if (_audioMapSCI11) - _resMgr->unlockResource(_audioMapSCI11); - } -} - -// Used in SCI1 games -void AudioResource::setAudioLang(int16 lang) { - if (lang != -1) { - _lang = lang; - - char filename[40]; - sprintf(filename, "AUDIO%03d.MAP", _lang); - - Common::File* audioMapFile = new Common::File(); - if (audioMapFile->open(filename)) { - // The audio map is freed in the destructor - _audioMapSCI1 = new byte[audioMapFile->size()]; - audioMapFile->read(_audioMapSCI1, audioMapFile->size()); - audioMapFile->close(); - delete audioMapFile; - } else { - _audioMapSCI1 = 0; - } - } -} - -int AudioResource::getAudioPosition() { - if (g_system->getMixer()->isSoundHandleActive(_audioHandle)) { - return g_system->getMixer()->getSoundElapsedTime(_audioHandle) * 6 / 100; // return elapsed time in ticks - } else { - return -1; // Sound finished - } -} - -bool AudioResource::findAudEntrySCI1(uint16 audioNumber, byte &volume, uint32 &offset, uint32 &size) { - // AUDIO00X.MAP contains 10-byte entries: - // w nEntry - // dw offset+volume (as in resource.map) - // dw size - // ending with 10 0xFFs - uint16 n; - uint32 off; - - if (_audioMapSCI1 == 0) - return false; - - byte *ptr = _audioMapSCI1; - while ((n = READ_LE_UINT16(ptr)) != 0xFFFF) { - if (n == audioNumber) { - off = READ_LE_UINT32(ptr + 2); - size = READ_LE_UINT32(ptr + 6); - volume = off >> 28; - offset = off & 0x0FFFFFFF; - return true; - } - ptr += 10; - } - - return false; -} - -// FIXME: Move this to sound/adpcm.cpp? -// Note that the 16-bit version is also used in coktelvideo.cpp -static const uint16 tableDPCM16[128] = { - 0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080, - 0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120, - 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0, - 0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230, - 0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280, - 0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0, - 0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, - 0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, - 0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0, - 0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480, - 0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700, - 0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, - 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 -}; - -static const byte tableDPCM8[8] = {0, 1, 2, 3, 6, 10, 15, 21}; - -static void deDPCM16(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { - int16 *out = (int16 *) soundBuf; - - int32 s = 0; - for (uint32 i = 0; i < n; i++) { - byte b = audioStream.readByte(); - if (b & 0x80) - s -= tableDPCM16[b & 0x7f]; - else - s += tableDPCM16[b]; - - s = CLIP<int32>(s, -32768, 32767); - *out++ = TO_BE_16(s); - } -} - -static void deDPCM8Nibble(byte *soundBuf, int32 &s, byte b) { - if (b & 8) - s -= tableDPCM8[7 - (b & 7)]; - else - s += tableDPCM8[b & 7]; - s = CLIP<int32>(s, 0, 255); - *soundBuf = s; -} - -static void deDPCM8(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { - int32 s = 0x80; - - for (uint i = 0; i < n; i++) { - byte b = audioStream.readByte(); - - deDPCM8Nibble(soundBuf++, s, b >> 4); - deDPCM8Nibble(soundBuf++, s, b & 0xf); - } -} - -// Sierra SOL audio file reader -// Check here for more info: http://wiki.multimedia.cx/index.php?title=Sierra_Audio -static bool readSOLHeader(Common::SeekableReadStream *audioStream, int headerSize, uint32 &size, uint16 &audioRate, byte &audioFlags) { - if (headerSize != 11 && headerSize != 12) { - warning("SOL audio header of size %i not supported", headerSize); - return false; - } - - audioStream->readUint32LE(); // skip "SOL" + 0 (4 bytes) - audioRate = audioStream->readUint16LE(); - audioFlags = audioStream->readByte(); - - size = audioStream->readUint32LE(); - return true; -} - -static byte* readSOLAudio(Common::SeekableReadStream *audioStream, uint32 &size, byte audioFlags, byte &flags) { - byte *buffer; - - // Convert the SOL stream flags to our own format - flags = 0; - if (audioFlags & kSolFlag16Bit) - flags |= Audio::Mixer::FLAG_16BITS; - if (!(audioFlags & kSolFlagIsSigned)) - flags |= Audio::Mixer::FLAG_UNSIGNED; - - if (audioFlags & kSolFlagCompressed) { - buffer = (byte *)malloc(size * 2); - - if (audioFlags & kSolFlag16Bit) - deDPCM16(buffer, *audioStream, size); - else - deDPCM8(buffer, *audioStream, size); - - size *= 2; - } else { - // We assume that the sound data is raw PCM - buffer = (byte *)malloc(size); - audioStream->read(buffer, size); - } - - return buffer; -} - -Audio::AudioStream* AudioResource::getAudioStream(uint32 audioNumber, uint32 volume, int *sampleLen) { - Audio::AudioStream *audioStream = 0; - uint32 offset; - uint32 size; - bool found = false; - byte *data = 0; - char filename[40]; - byte flags = 0; - Sci::Resource* audioRes = NULL; - - // Try to load from resource manager - if (volume == 65535) - audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio, audioNumber), false); - else - audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio36, volume, audioNumber), false); - - if (audioRes) { - if (_sciVersion < SCI_VERSION_1_1) { - size = audioRes->size; - data = audioRes->data; - } else { - byte audioFlags; - - Common::MemoryReadStream *headerStream = - new Common::MemoryReadStream(audioRes->header, audioRes->headerSize, false); - - if (readSOLHeader(headerStream, audioRes->headerSize, size, _audioRate, audioFlags)) { - Common::MemoryReadStream *dataStream = - new Common::MemoryReadStream(audioRes->data, audioRes->size, false); - data = readSOLAudio(dataStream, size, audioFlags, flags); - delete dataStream; - } - delete headerStream; - } - - if (data) { - audioStream = Audio::makeLinearInputStream(data, size, _audioRate, - flags | Audio::Mixer::FLAG_AUTOFREE, 0, 0); - } - } else { - // Load it from the audio file - if (_sciVersion < SCI_VERSION_1_1) { - byte sci1Volume; - found = findAudEntrySCI1(audioNumber, sci1Volume, offset, size); - sprintf(filename, "AUDIO%03d.%03d", _lang, sci1Volume); - flags |= Audio::Mixer::FLAG_UNSIGNED; - } - - if (found) { - #if 0 - // TODO: This tries to load directly from the KQ5CD audio file with MP3/OGG/FLAC - // compression. Once we got a tool to compress this file AND update the map file - // at the same time, we can use this code to play compressed audio. - if (_sciVersion < SCI_VERSION_1_1) { - uint32 start = offset * 1000 / _audioRate; - uint32 duration = size * 1000 / _audioRate; - - // Try to load compressed - audioStream = Audio::AudioStream::openStreamFile(filename, start, duration); - } - #endif - - if (!audioStream) { - // Compressed file load failed, try to load original raw data - Common::File* audioFile = new Common::File(); - if (audioFile->open(filename)) { - audioFile->seek(offset); - - if (_sciVersion < SCI_VERSION_1_1) { - data = (byte *)malloc(size); - audioFile->read(data, size); - } else { - byte type = audioFile->readByte() & 0x7f; - byte audioFlags; - - if (type != kResourceTypeAudio) { - warning("Resource type mismatch"); - delete audioFile; - return NULL; - } - - byte headerSize = audioFile->readByte(); - - if (readSOLHeader(audioFile, headerSize, size, _audioRate, audioFlags)) - data = readSOLAudio(audioFile, size, audioFlags, flags); - - if (!data) { - delete audioFile; - return NULL; - } - } - - audioFile->close(); - - if (data) { - audioStream = Audio::makeLinearInputStream(data, size, _audioRate, - flags | Audio::Mixer::FLAG_AUTOFREE, 0, 0); - } - } - - delete audioFile; - } - } else { - warning("Failed to find audio entry (%i, %i, %i, %i, %i)", volume, (audioNumber >> 24) & 0xff, - (audioNumber >> 16) & 0xff, (audioNumber >> 8) & 0xff, audioNumber & 0xff); - } - } - - if (audioStream) { - *sampleLen = (flags & Audio::Mixer::FLAG_16BITS ? size >> 1 : size) * 60 / _audioRate; - return audioStream; - } - - return NULL; -} - } // End of namespace Sci diff --git a/engines/sci/resource.h b/engines/sci/resource.h index fc3f37f25c..77c92840ee 100644 --- a/engines/sci/resource.h +++ b/engines/sci/resource.h @@ -72,19 +72,14 @@ enum { enum ResSourceType { kSourceDirectory = 0, - kSourcePatch = 1, - kSourceVolume = 2, - kSourceExtMap = 3, - kSourceIntMap = 4, - kSourceAudioVolume = 5, - kSourceMask = 127 + kSourcePatch, + kSourceVolume, + kSourceExtMap, + kSourceIntMap, + kSourceAudioVolume, + kSourceExtAudioMap }; -#define RESSOURCE_ADDRESSING_BASIC 0 -#define RESSOURCE_ADDRESSING_EXTENDED 128 -#define RESSOURCE_ADDRESSING_MASK 128 - -#define RESOURCE_HASH(type, number) (uint32)((type<<16) | number) #define SCI0_RESMAP_ENTRIES_SIZE 6 #define SCI1_RESMAP_ENTRIES_SIZE 6 #define SCI11_RESMAP_ENTRIES_SIZE 5 @@ -136,7 +131,6 @@ struct ResourceSource { Common::String location_name; // FIXME: Replace by FSNode ? int volume_number; ResourceSource *associated_map; - ResourceSource *next; }; class ResourceManager; @@ -270,6 +264,8 @@ public: */ Common::List<ResourceId> *listResources(ResourceType type, int mapNumber = -1); + void setAudioLanguage(int language); + protected: int _maxMemory; //!< Config option: Maximum total byte number allocated Common::List<ResourceSource *> _sources; @@ -278,6 +274,7 @@ protected: Common::List<Resource *> _LRU; //!< Last Resource Used list ResourceMap _resMap; Common::List<Common::File *> _volumeFiles; //!< list of opened volume files + ResourceSource *_audioMapSCI1; //!< Currently loaded audio map for SCI1 /** * Add a path to the resource manager's list of sources. @@ -325,11 +322,13 @@ protected: void loadResource(Resource *res); bool loadPatch(Resource *res, Common::File &file); bool loadFromPatchFile(Resource *res); - bool loadFromAudioVolume(Resource *res, Common::File &file); - void freeOldResources(int last_invulnerable); + bool loadFromAudioVolumeSCI1(Resource *res, Common::File &file); + bool loadFromAudioVolumeSCI11(Resource *res, Common::File &file); + void freeOldResources(); int decompress(Resource *res, Common::File *file); int readResourceInfo(Resource *res, Common::File *file, uint32&szPacked, ResourceCompression &compression); void addResource(ResourceId resId, ResourceSource *src, uint32 offset, uint32 size = 0); + void removeAudioResource(ResourceId resId); /**--- Resource map decoding functions ---*/ int detectMapVersion(); @@ -337,21 +336,32 @@ protected: /** * Reads the SCI0 resource.map file from a local directory. + * @param map The map * @return 0 on success, an SCI_ERROR_* code otherwise */ int readResourceMapSCI0(ResourceSource *map); /** * Reads the SCI1 resource.map file from a local directory. + * @param map The map * @return 0 on success, an SCI_ERROR_* code otherwise */ int readResourceMapSCI1(ResourceSource *map); /** - * Reads SCI1.1 MAP resources + * Reads SCI1.1 audio map resources + * @param map The map * @return 0 on success, an SCI_ERROR_* code otherwise */ - int readMap(ResourceSource *map); + int readAudioMapSCI11(ResourceSource *map); + + /** + * Reads SCI1 audio map files + * @param map The map + * @param unload Unload the map instead of loading it + * @return 0 on success, an SCI_ERROR_* code otherwise + */ + int readAudioMapSCI1(ResourceSource *map, bool unload = false); /**--- Patch management functions ---*/ @@ -368,60 +378,6 @@ protected: int guessSciVersion(); }; -/** - * Used for lip and animation syncing in CD talkie games - */ -class ResourceSync : public Resource { -public: - ResourceSync() {} - ~ResourceSync() {} - - void startSync(EngineState *s, reg_t obj); - void nextSync(EngineState *s, reg_t obj); - void stopSync(); - -protected: - uint16 *_ptr; - int16 _syncTime, _syncCue; - //bool _syncStarted; // not used -}; - -/** - * Used for speech playback and digital music playback - * in CD talkie games - */ -class AudioResource { -public: - AudioResource(ResourceManager *resMgr, int sciVersion); - ~AudioResource(); - - void setAudioRate(uint16 audioRate) { _audioRate = audioRate; } - void setAudioLang(int16 lang); - - Audio::SoundHandle* getAudioHandle() { return &_audioHandle; } - int getAudioPosition(); - - Audio::AudioStream* getAudioStream(uint32 audioNumber, uint32 volume, int *sampleLen); - - void stop() { g_system->getMixer()->stopHandle(_audioHandle); } - void pause() { g_system->getMixer()->pauseHandle(_audioHandle, true); } - void resume() { g_system->getMixer()->pauseHandle(_audioHandle, false); } - -private: - Audio::SoundHandle _audioHandle; - uint16 _audioRate; - int16 _lang; - byte *_audioMapSCI1; - Resource *_audioMapSCI11; - ResourceManager *_resMgr; - int _sciVersion; - - bool findAudEntrySCI1(uint16 audioNumber, byte &volume, uint32 &offset, uint32 &size); - bool findAudEntrySCI11(uint32 audioNumber, uint32 volume, uint32 &offset, bool getSync = false, uint32 *size = NULL); - bool findAudEntrySCI11Late(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size); - bool findAudEntrySCI11Early(uint32 audioNumber, uint32 &offset, bool getSync, uint32 *size); -}; - } // End of namespace Sci #endif // SCI_SCICORE_RESOURCE_H diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index f58d729bf6..9b277b058f 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -158,7 +158,8 @@ Common::Error SciEngine::run() { if (flags & GF_SCI0_OLD || flags & GF_SCI0_OLDGFXFUNCS || - flags & GF_SCI0_OLDGETTIME) { + flags & GF_SCI0_OLDGETTIME || + flags & GF_SCI0_SCI1VOCAB) { error("This game entry is erroneous. It's marked as SCI1, but it has SCI0 flags set"); } } else if (version == SCI_VERSION_1_1 || version == SCI_VERSION_32) { @@ -170,7 +171,8 @@ Common::Error SciEngine::run() { if (flags & GF_SCI0_OLD || flags & GF_SCI0_OLDGFXFUNCS || - flags & GF_SCI0_OLDGETTIME) { + flags & GF_SCI0_OLDGETTIME || + flags & GF_SCI0_SCI1VOCAB) { error("This game entry is erroneous. It's marked as SCI1.1/SCI32, but it has SCI0 flags set"); } diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 91f491fe71..18b1b93a92 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -108,6 +108,11 @@ enum SciGameFlags { ** Older SCI versions had simpler code for GetTime() */ GF_SCI0_OLDGETTIME = (1 << 2), + + /* Applies to any game that requires the SCI1 kernel vocab + ** Some games (such as the King's Quest I demo) require the default kernel vocab table. + */ + GF_SCI0_SCI1VOCAB = (1 << 3), // ---------------------------------------------------------------------------- @@ -118,18 +123,18 @@ enum SciGameFlags { /* ** Used to distinguish SCI1 EGA games */ - GF_SCI1_EGA = (1 << 3), + GF_SCI1_EGA = (1 << 4), /* Applies to all SCI1 versions after 1.000.200 ** In late SCI1 versions, the argument of lofs[as] instructions ** is absolute rather than relative. */ - GF_SCI1_LOFSABSOLUTE = (1 << 4), + GF_SCI1_LOFSABSOLUTE = (1 << 5), /* Applies to all versions from 1.000.510 onwards ** kDoSound() is different than in earlier SCI1 versions. */ - GF_SCI1_NEWDOSOUND = (1 << 5) + GF_SCI1_NEWDOSOUND = (1 << 6) }; class SciEngine : public Engine { diff --git a/engines/sci/sfx/core.cpp b/engines/sci/sfx/core.cpp index e37007bf8e..9bf7730fc9 100644 --- a/engines/sci/sfx/core.cpp +++ b/engines/sci/sfx/core.cpp @@ -348,11 +348,13 @@ SfxState::SfxState() { _flags = 0; _song = NULL; _suspended = 0; - _soundSync = 0; - _audioResource = 0; + _syncResource = NULL; + _audioRate = 11025; } SfxState::~SfxState() { + if (_syncResource) + _resMgr->unlockResource(_syncResource); } @@ -526,7 +528,7 @@ void SfxState::updateSingleSong() { debugMessage += " none\n"; } - debugC(2, kDebugLevelSound, debugMessage.c_str()); + debugC(2, kDebugLevelSound, "%s", debugMessage.c_str()); _song = newsong; thawTime(); /* Recover song delay time */ @@ -641,8 +643,8 @@ void SfxState::sfx_init(ResourceManager *resmgr, int flags) { _songlib._lib = 0; _song = NULL; _flags = flags; - _soundSync = NULL; - _audioResource = NULL; + _syncResource = NULL; + _syncOffset = 0; player = NULL; @@ -676,6 +678,8 @@ void SfxState::sfx_init(ResourceManager *resmgr, int flags) { delete player; player = NULL; } + + _resMgr = resmgr; } void SfxState::sfx_exit() { @@ -689,12 +693,6 @@ void SfxState::sfx_exit() { g_system->getMixer()->stopAll(); _songlib.freeSounds(); - - // Delete audio resources for CD talkie games - if (_audioResource) { - delete _audioResource; - _audioResource = 0; - } } void SfxState::sfx_suspend(bool suspend) { @@ -1004,4 +1002,187 @@ void SfxState::sfx_all_stop() { update(); } +int SfxState::startAudio(uint16 module, uint32 number) { + int sampleLen; + Audio::AudioStream *audioStream = getAudioStream(number, module, &sampleLen); + + if (audioStream) { + g_system->getMixer()->playInputStream(Audio::Mixer::kSpeechSoundType, &_audioHandle, audioStream); + return sampleLen; + } + + return 0; +} + +int SfxState::getAudioPosition() { + if (g_system->getMixer()->isSoundHandleActive(_audioHandle)) + return g_system->getMixer()->getSoundElapsedTime(_audioHandle) * 6 / 100; // return elapsed time in ticks + else + return -1; // Sound finished +} + +enum SolFlags { + kSolFlagCompressed = 1 << 0, + kSolFlagUnknown = 1 << 1, + kSolFlag16Bit = 1 << 2, + kSolFlagIsSigned = 1 << 3 +}; + +// FIXME: Move this to sound/adpcm.cpp? +// Note that the 16-bit version is also used in coktelvideo.cpp +static const uint16 tableDPCM16[128] = { + 0x0000, 0x0008, 0x0010, 0x0020, 0x0030, 0x0040, 0x0050, 0x0060, 0x0070, 0x0080, + 0x0090, 0x00A0, 0x00B0, 0x00C0, 0x00D0, 0x00E0, 0x00F0, 0x0100, 0x0110, 0x0120, + 0x0130, 0x0140, 0x0150, 0x0160, 0x0170, 0x0180, 0x0190, 0x01A0, 0x01B0, 0x01C0, + 0x01D0, 0x01E0, 0x01F0, 0x0200, 0x0208, 0x0210, 0x0218, 0x0220, 0x0228, 0x0230, + 0x0238, 0x0240, 0x0248, 0x0250, 0x0258, 0x0260, 0x0268, 0x0270, 0x0278, 0x0280, + 0x0288, 0x0290, 0x0298, 0x02A0, 0x02A8, 0x02B0, 0x02B8, 0x02C0, 0x02C8, 0x02D0, + 0x02D8, 0x02E0, 0x02E8, 0x02F0, 0x02F8, 0x0300, 0x0308, 0x0310, 0x0318, 0x0320, + 0x0328, 0x0330, 0x0338, 0x0340, 0x0348, 0x0350, 0x0358, 0x0360, 0x0368, 0x0370, + 0x0378, 0x0380, 0x0388, 0x0390, 0x0398, 0x03A0, 0x03A8, 0x03B0, 0x03B8, 0x03C0, + 0x03C8, 0x03D0, 0x03D8, 0x03E0, 0x03E8, 0x03F0, 0x03F8, 0x0400, 0x0440, 0x0480, + 0x04C0, 0x0500, 0x0540, 0x0580, 0x05C0, 0x0600, 0x0640, 0x0680, 0x06C0, 0x0700, + 0x0740, 0x0780, 0x07C0, 0x0800, 0x0900, 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, + 0x0F00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000 +}; + +static const byte tableDPCM8[8] = {0, 1, 2, 3, 6, 10, 15, 21}; + +static void deDPCM16(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { + int16 *out = (int16 *) soundBuf; + + int32 s = 0; + for (uint32 i = 0; i < n; i++) { + byte b = audioStream.readByte(); + if (b & 0x80) + s -= tableDPCM16[b & 0x7f]; + else + s += tableDPCM16[b]; + + s = CLIP<int32>(s, -32768, 32767); + *out++ = TO_BE_16(s); + } +} + +static void deDPCM8Nibble(byte *soundBuf, int32 &s, byte b) { + if (b & 8) + s -= tableDPCM8[7 - (b & 7)]; + else + s += tableDPCM8[b & 7]; + s = CLIP<int32>(s, 0, 255); + *soundBuf = s; +} + +static void deDPCM8(byte *soundBuf, Common::SeekableReadStream &audioStream, uint32 n) { + int32 s = 0x80; + + for (uint i = 0; i < n; i++) { + byte b = audioStream.readByte(); + + deDPCM8Nibble(soundBuf++, s, b >> 4); + deDPCM8Nibble(soundBuf++, s, b & 0xf); + } +} + +// Sierra SOL audio file reader +// Check here for more info: http://wiki.multimedia.cx/index.php?title=Sierra_Audio +static bool readSOLHeader(Common::SeekableReadStream *audioStream, int headerSize, uint32 &size, uint16 &audioRate, byte &audioFlags) { + if (headerSize != 11 && headerSize != 12) { + warning("SOL audio header of size %i not supported", headerSize); + return false; + } + + audioStream->readUint32LE(); // skip "SOL" + 0 (4 bytes) + audioRate = audioStream->readUint16LE(); + audioFlags = audioStream->readByte(); + + size = audioStream->readUint32LE(); + return true; +} + +static byte* readSOLAudio(Common::SeekableReadStream *audioStream, uint32 &size, byte audioFlags, byte &flags) { + byte *buffer; + + // Convert the SOL stream flags to our own format + flags = 0; + if (audioFlags & kSolFlag16Bit) + flags |= Audio::Mixer::FLAG_16BITS; + if (!(audioFlags & kSolFlagIsSigned)) + flags |= Audio::Mixer::FLAG_UNSIGNED; + + if (audioFlags & kSolFlagCompressed) { + buffer = (byte *)malloc(size * 2); + + if (audioFlags & kSolFlag16Bit) + deDPCM16(buffer, *audioStream, size); + else + deDPCM8(buffer, *audioStream, size); + + size *= 2; + } else { + // We assume that the sound data is raw PCM + buffer = (byte *)malloc(size); + audioStream->read(buffer, size); + } + + return buffer; +} + +Audio::AudioStream* SfxState::getAudioStream(uint32 number, uint32 volume, int *sampleLen) { + Audio::AudioStream *audioStream = 0; + uint32 size; + byte *data = 0; + byte flags = 0; + Sci::Resource* audioRes; + + if (volume == 65535) { + audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio, number), false); + if (!audioRes) { + warning("Failed to find audio entry %i", number); + return NULL; + } + } else { + audioRes = _resMgr->findResource(ResourceId(kResourceTypeAudio36, volume, number), false); + if (!audioRes) { + warning("Failed to find audio entry (%i, %i, %i, %i, %i)", volume, (number >> 24) & 0xff, + (number >> 16) & 0xff, (number >> 8) & 0xff, number & 0xff); + return NULL; + } + } + + byte audioFlags; + + if (audioRes->headerSize > 0) { + // SCI1.1 + Common::MemoryReadStream *headerStream = + new Common::MemoryReadStream(audioRes->header, audioRes->headerSize, false); + + if (readSOLHeader(headerStream, audioRes->headerSize, size, _audioRate, audioFlags)) { + Common::MemoryReadStream *dataStream = + new Common::MemoryReadStream(audioRes->data, audioRes->size, false); + data = readSOLAudio(dataStream, size, audioFlags, flags); + delete dataStream; + } + delete headerStream; + } else { + // SCI1 + size = audioRes->size; + data = (byte *)malloc(size); + assert(data); + memcpy(data, audioRes->data, size); + flags = Audio::Mixer::FLAG_UNSIGNED; + } + + if (data) { + audioStream = Audio::makeLinearInputStream(data, size, _audioRate, + flags | Audio::Mixer::FLAG_AUTOFREE, 0, 0); + if (audioStream) { + *sampleLen = (flags & Audio::Mixer::FLAG_16BITS ? size >> 1 : size) * 60 / _audioRate; + return audioStream; + } + } + + return NULL; +} + } // End of namespace Sci diff --git a/engines/sci/sfx/core.h b/engines/sci/sfx/core.h index 5db56bd864..e7eba85c99 100644 --- a/engines/sci/sfx/core.h +++ b/engines/sci/sfx/core.h @@ -50,8 +50,9 @@ public: // FIXME, make private SongLibrary _songlib; /**< Song library */ Song *_song; /**< Active song, or start of active song chain */ bool _suspended; /**< Whether we are suspended */ - ResourceSync *_soundSync; /**< Used by kDoSync for speech syncing in CD talkie games */ - AudioResource *_audioResource; /**< Used for audio resources in CD talkie games */ + Resource *_syncResource; /**< Used by kDoSync for speech syncing in CD talkie games */ + uint _syncOffset; + ResourceManager *_resMgr; public: SfxState(); @@ -164,6 +165,15 @@ public: Common::Error sfx_send_midi(SongHandle handle, int channel, int command, int arg1, int arg2); + // Functions for digital sound + void setAudioRate(uint16 rate) { _audioRate = rate; } + Audio::SoundHandle* getAudioHandle() { return &_audioHandle; } + int getAudioPosition(); + int startAudio(uint16 module, uint32 tuple); + void stopAudio() { g_system->getMixer()->stopHandle(_audioHandle); } + void pauseAudio() { g_system->getMixer()->pauseHandle(_audioHandle, true); } + void resumeAudio() { g_system->getMixer()->pauseHandle(_audioHandle, false); } + protected: void freezeTime(); void thawTime(); @@ -173,8 +183,12 @@ protected: void updateSingleSong(); void updateMultiSong(); void update(); -}; +private: + uint16 _audioRate; + Audio::SoundHandle _audioHandle; + Audio::AudioStream* getAudioStream(uint32 number, uint32 volume, int *sampleLen); +}; } // End of namespace Sci |