diff options
48 files changed, 1 insertions, 16409 deletions
diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 4b2313280f..75a1d08db2 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -35,11 +35,6 @@ #include "sci/engine/state.h" #include "sci/engine/gc.h" #include "sci/engine/kernel_types.h" // for determine_reg_type -#ifdef INCLUDE_OLDGFX -#include "sci/gfx/gfx_gui.h" // for sciw_set_status_bar -#include "sci/gfx/gfx_state_internal.h" -#include "sci/gfx/gfx_widgets.h" // for getPort -#endif #ifdef USE_OLD_MUSIC_FUNCTIONS #include "sci/sfx/iterator/songlib.h" // for SongLibrary #include "sci/sfx/iterator/iterator.h" // for SCI_SONG_ITERATOR_TYPE_SCI0 @@ -111,31 +106,11 @@ Console::Console(SciEngine *vm) : GUI::Debugger() { DCmd_Register("exit", WRAP_METHOD(Console, cmdExit)); DCmd_Register("list_saves", WRAP_METHOD(Console, cmdListSaves)); // Screen - DCmd_Register("sci0_palette", WRAP_METHOD(Console, cmdSci0Palette)); - DCmd_Register("clear_screen", WRAP_METHOD(Console, cmdClearScreen)); - DCmd_Register("redraw_screen", WRAP_METHOD(Console, cmdRedrawScreen)); - DCmd_Register("fill_screen", WRAP_METHOD(Console, cmdFillScreen)); DCmd_Register("show_map", WRAP_METHOD(Console, cmdShowMap)); - DCmd_Register("update_zone", WRAP_METHOD(Console, cmdUpdateZone)); - DCmd_Register("propagate_zone", WRAP_METHOD(Console, cmdPropagateZone)); - DCmd_Register("priority_bands", WRAP_METHOD(Console, cmdPriorityBands)); // Graphics DCmd_Register("draw_pic", WRAP_METHOD(Console, cmdDrawPic)); - DCmd_Register("draw_rect", WRAP_METHOD(Console, cmdDrawRect)); - DCmd_Register("draw_cel", WRAP_METHOD(Console, cmdDrawCel)); - DCmd_Register("view_info", WRAP_METHOD(Console, cmdViewInfo)); DCmd_Register("undither", WRAP_METHOD(Console, cmdUndither)); DCmd_Register("play_video", WRAP_METHOD(Console, cmdPlayVideo)); - // GUI - DCmd_Register("current_port", WRAP_METHOD(Console, cmdCurrentPort)); - DCmd_Register("print_port", WRAP_METHOD(Console, cmdPrintPort)); - DCmd_Register("visual_state", WRAP_METHOD(Console, cmdVisualState)); - DCmd_Register("flush_visual", WRAP_METHOD(Console, cmdFlushPorts)); - DCmd_Register("dynamic_views", WRAP_METHOD(Console, cmdDynamicViews)); - DCmd_Register("dropped_views", WRAP_METHOD(Console, cmdDroppedViews)); -#ifdef GFXW_DEBUG_WIDGETS - DCmd_Register("print_widget", WRAP_METHOD(Console, cmdPrintWidget)); -#endif // Segments DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable)); DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias @@ -330,34 +305,10 @@ bool Console::cmdHelp(int argc, const char **argv) { DebugPrintf(" room - Gets or sets the current room number\n"); DebugPrintf(" exit - Exits the game\n"); DebugPrintf("\n"); - DebugPrintf("Screen:\n"); - DebugPrintf(" sci0_palette - Sets the SCI0 palette to use (EGA, Amiga or grayscale)\n"); - DebugPrintf(" clear_screen - Clears the screen\n"); - DebugPrintf(" redraw_screen - Redraws the screen\n"); - DebugPrintf(" fill_screen - Fills the screen with one of the EGA colors\n"); - DebugPrintf(" show_map - Shows one of the screen maps (visual, priority or control)\n"); - DebugPrintf(" update_zone - Propagates a rectangular area from the back buffer to the front buffer\n"); - DebugPrintf(" propagate_zone - Propagates a rectangular area from a lower graphics buffer to a higher one\n"); - DebugPrintf(" priority_bands - Shows information about priority bands\n"); - DebugPrintf("\n"); DebugPrintf("Graphics:\n"); DebugPrintf(" draw_pic - Draws a pic resource\n"); - DebugPrintf(" draw_rect - Draws a rectangle to the screen with one of the EGA colors\n"); - DebugPrintf(" draw_cel - Draws a single view cel to the center of the screen\n"); - DebugPrintf(" view_info - Displays information for the specified view\n"); DebugPrintf(" undither - Enable/disable undithering\n"); DebugPrintf("\n"); - DebugPrintf("GUI:\n"); - DebugPrintf(" current_port - Shows the ID of the currently active port\n"); - DebugPrintf(" print_port - Prints information about a port\n"); - DebugPrintf(" visual_state - Shows the state of the current visual widget\n"); - DebugPrintf(" flush_visual - Flushes dynamically allocated ports (for memory profiling)\n"); - DebugPrintf(" dynamic_views - Lists active dynamic views\n"); - DebugPrintf(" dropped_views - Lists dropped dynamic views\n"); -#ifdef GFXW_DEBUG_WIDGETS - DebugPrintf(" print_widget - Shows active widgets (no params) or information on the specified widget indices\n"); -#endif - DebugPrintf("\n"); DebugPrintf("Segments:\n"); DebugPrintf(" segment_table / segtable - Lists all segments\n"); DebugPrintf(" segment_info / seginfo - Provides information on the specified segment\n"); @@ -699,22 +650,6 @@ bool Console::cmdResourceTypes(int argc, const char **argv) { return true; } -extern int sci0_palette; - -bool Console::cmdSci0Palette(int argc, const char **argv) { - if (argc != 2) { - DebugPrintf("Sets the SCI0 palette to use - 0: EGA, 1: AGI/Amiga, 2: Grayscale\n"); - return true; - } - -#ifdef INCLUDE_OLDGFX - sci0_palette = atoi(argv[1]); - cmdRedrawScreen(argc, argv); -#endif - - return false; -} - bool Console::cmdHexgrep(int argc, const char **argv) { if (argc < 4) { DebugPrintf("Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers.\n"); @@ -832,24 +767,6 @@ bool Console::cmdList(int argc, const char **argv) { return true; } -bool Console::cmdClearScreen(int argc, const char **argv) { -#ifdef INCLUDE_OLDGFX - gfxop_clear_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); - gfxop_update_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); -#endif - return false; -} - -bool Console::cmdRedrawScreen(int argc, const char **argv) { -#ifdef INCLUDE_OLDGFX - _vm->_gamestate->visual->draw(Common::Point(0, 0)); - gfxop_update_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); - gfxop_update(_vm->_gamestate->gfx_state); - kernel_sleep(_vm->_gamestate->_event, 0); -#endif - return false; -} - bool Console::cmdSaveGame(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Saves the current game state to the hard disk\n"); @@ -1055,123 +972,17 @@ bool Console::cmdParserNodes(int argc, const char **argv) { bool Console::cmdDrawPic(int argc, const char **argv) { if (argc < 2) { DebugPrintf("Draws a pic resource\n"); - DebugPrintf("Usage: %s <nr> [<pal>] [<fl>]\n", argv[0]); + DebugPrintf("Usage: %s <nr>\n", argv[0]); DebugPrintf("where <nr> is the number of the pic resource to draw\n"); - DebugPrintf("<pal> is the optional default palette for the pic (default: 0)\n"); - DebugPrintf("<fl> are any pic draw flags (default: 1)\n"); return true; } - int flags = 1, default_palette = 0; - - if (argc > 2) - default_palette = atoi(argv[2]); - - if (argc == 4) - flags = atoi(argv[3]); - -#ifdef INCLUDE_OLDGFX - gfxop_new_pic(_vm->_gamestate->gfx_state, atoi(argv[1]), flags, default_palette); - gfxop_clear_box(_vm->_gamestate->gfx_state, gfx_rect(0, 0, 320, 200)); - gfxop_update(_vm->_gamestate->gfx_state); - kernel_sleep(_vm->_gamestate->_event, 0); -#else _vm->_gamestate->_gui->drawPicture(atoi(argv[1]), 100, false, false, false, 0); _vm->_gamestate->_gui->animateShowPic(); -#endif - - return false; -} - -bool Console::cmdDrawRect(int argc, const char **argv) { - if (argc != 6) { - DebugPrintf("Draws a rectangle to the screen with one of the EGA colors\n"); - DebugPrintf("Usage: %s <x> <y> <width> <height> <color>\n", argv[0]); - DebugPrintf("where <color> is the EGA color to use (0-15)\n"); - return true; - } - -#ifdef INCLUDE_OLDGFX - int col = CLIP<int>(atoi(argv[5]), 0, 15); - - gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); - gfxop_fill_box(_vm->_gamestate->gfx_state, gfx_rect(atoi(argv[1]), atoi(argv[2]), - atoi(argv[3]), atoi(argv[4])), _vm->_gamestate->ega_colors[col]); - gfxop_update(_vm->_gamestate->gfx_state); -#endif return false; } -bool Console::cmdDrawCel(int argc, const char **argv) { - if (argc != 4) { - DebugPrintf("Draws a single view cel to the center of the screen\n"); - DebugPrintf("Usage: %s <view> <loop> <cel> <palette>\n", argv[0]); - return true; - } - -#ifdef INCLUDE_OLDGFX - int view = atoi(argv[1]); - int loop = atoi(argv[2]); - int cel = atoi(argv[3]); - int palette = atoi(argv[4]); - - gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); - gfxop_draw_cel(_vm->_gamestate->gfx_state, view, loop, cel, Common::Point(160, 100), _vm->_gamestate->ega_colors[0], palette); - gfxop_update(_vm->_gamestate->gfx_state); -#endif - - return false; -} - -bool Console::cmdViewInfo(int argc, const char **argv) { - if (argc != 2) { - DebugPrintf("Displays the number of loops and cels of each loop\n"); - DebugPrintf("for the specified view resource and palette."); - DebugPrintf("Usage: %s <view> <palette>\n", argv[0]); - return true; - } - -#ifdef INCLUDE_OLDGFX - int view = atoi(argv[1]); - int palette = atoi(argv[2]); - int loops, i; - gfxr_view_t *view_pixmaps = NULL; - gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 }; - - DebugPrintf("Resource view.%d ", view); - - loops = _vm->_gamestate->_gui->getLoopCount(view); - - if (loops < 0) - DebugPrintf("does not exist.\n"); - else { - DebugPrintf("has %d loops:\n", loops); - - for (i = 0; i < loops; i++) { - int j, cels = _vm->_gamestate->_gui->getCelCount(view, i); - - DebugPrintf("Loop %d: %d cels.\n", i, cels); - for (j = 0; j < cels; j++) { - int width; - int height; - Common::Point mod; - - // Show pixmap on screen - view_pixmaps = _vm->_gamestate->gfx_state->gfxResMan->getView(view, &i, &j, palette); - gfxop_draw_cel(_vm->_gamestate->gfx_state, view, i, j, Common::Point(0,0), transparent, palette); - - gfxop_get_cel_parameters(_vm->_gamestate->gfx_state, view, i, j, &width, &height, &mod); - - DebugPrintf(" cel %d: size %dx%d, adj+(%d,%d)\n", j, width, height, mod.x, mod.y); - } - } - } -#endif - - return true; -} - bool Console::cmdUndither(int argc, const char **argv) { if (argc != 2) { DebugPrintf("Enable/disable undithering.\n"); @@ -1206,117 +1017,6 @@ bool Console::cmdPlayVideo(int argc, const char **argv) { } } -bool Console::cmdUpdateZone(int argc, const char **argv) { - if (argc != 4) { - DebugPrintf("Propagates a rectangular area from the back buffer to the front buffer\n"); - DebugPrintf("Usage: %s <x> <y> <width> <height>\n", argv[0]); - return true; - } - -#ifdef INCLUDE_OLDGFX - int x = atoi(argv[1]); - int y = atoi(argv[2]); - int width = atoi(argv[3]); - int height = atoi(argv[4]); - - _vm->_gamestate->gfx_state->driver->update(gfx_rect(x, y, width, height), Common::Point(x, y), GFX_BUFFER_FRONT); -#endif - - return false; -} - -bool Console::cmdPropagateZone(int argc, const char **argv) { - if (argc != 5) { - DebugPrintf("Propagates a rectangular area from a lower graphics buffer to a higher one\n"); - DebugPrintf("Usage: %s <x> <y> <width> <height> <map>\n", argv[0]); - DebugPrintf("Where <map> can be 0 or 1\n"); - return true; - } - -#ifdef INCLUDE_OLDGFX - int x = atoi(argv[1]); - int y = atoi(argv[2]); - int width = atoi(argv[3]); - int height = atoi(argv[4]); - int map = CLIP<int>(atoi(argv[5]), 0, 1); - rect_t rect = gfx_rect(x, y, width, height); - - gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); - - if (map == 1) - gfxop_clear_box(_vm->_gamestate->gfx_state, rect); - else - gfxop_update_box(_vm->_gamestate->gfx_state, rect); - gfxop_update(_vm->_gamestate->gfx_state); - kernel_sleep(_vm->_gamestate->_event, 0); -#endif - - return false; -} - -bool Console::cmdFillScreen(int argc, const char **argv) { - if (argc != 2) { - DebugPrintf("Fills the screen with one of the EGA colors\n"); - DebugPrintf("Usage: %s <color>\n", argv[0]); - DebugPrintf("where <color> is the EGA color to use (0-15)\n"); - return true; - } - -#ifdef INCLUDE_OLDGFX - int col = CLIP<int>(atoi(argv[1]), 0, 15); - - gfxop_set_clip_zone(_vm->_gamestate->gfx_state, gfx_rect_fullscreen); - gfxop_fill_box(_vm->_gamestate->gfx_state, gfx_rect_fullscreen, _vm->_gamestate->ega_colors[col]); - gfxop_update(_vm->_gamestate->gfx_state); -#endif - - return false; -} - -bool Console::cmdCurrentPort(int argc, const char **argv) { -#ifdef INCLUDE_OLDGFX - if (!_vm->_gamestate->port) - DebugPrintf("There is no port active currently.\n"); - else - DebugPrintf("Current port ID: %d\n", _vm->_gamestate->port->_ID); -#endif - - return true; -} - -bool Console::cmdPrintPort(int argc, const char **argv) { - if (argc != 2) { - DebugPrintf("Prints information about a port\n"); - DebugPrintf("%s current - prints information about the current port\n", argv[0]); - DebugPrintf("%s <ID> - prints information about the port with the specified ID\n", argv[0]); - return true; - } - -#ifdef INCLUDE_OLDGFX - GfxPort *port; - - if (!scumm_stricmp(argv[1], "current")) { - port = _vm->_gamestate->port; - if (!port) - DebugPrintf("There is no active port currently\n"); - else - port->print(0); - } else { - if (!_vm->_gamestate->visual) { - DebugPrintf("Visual is uninitialized\n"); - } else { - port = _vm->_gamestate->visual->getPort(atoi(argv[1])); - if (!port) - DebugPrintf("No such port\n"); - else - port->print(0); - } - } -#endif - - return true; -} - bool Console::cmdParseGrammar(int argc, const char **argv) { DebugPrintf("Parse grammar, in strict GNF:\n"); @@ -1325,73 +1025,6 @@ bool Console::cmdParseGrammar(int argc, const char **argv) { return true; } -bool Console::cmdVisualState(int argc, const char **argv) { - DebugPrintf("State of the current visual widget:\n"); - -#ifdef INCLUDE_OLDGFX - if (_vm->_gamestate->visual) - _vm->_gamestate->visual->print(0); - else - DebugPrintf("The visual widget is uninitialized.\n"); -#endif - - return true; -} - -bool Console::cmdFlushPorts(int argc, const char **argv) { -#ifdef INCLUDE_OLDGFX - _vm->_gamestate->_gui->hideCursor(); - DebugPrintf("Flushing dynamically allocated ports (for memory profiling)...\n"); - delete _vm->_gamestate->visual; - _vm->_gamestate->gfx_state->gfxResMan->freeAllResources(); - _vm->_gamestate->visual = NULL; -#endif - - return true; -} - -bool Console::cmdDynamicViews(int argc, const char **argv) { -#ifdef INCLUDE_OLDGFX - DebugPrintf("List of active dynamic views:\n"); - - if (_vm->_gamestate->dyn_views) - _vm->_gamestate->dyn_views->print(0); - else - DebugPrintf("The list is empty.\n"); -#endif - - return true; -} - -bool Console::cmdDroppedViews(int argc, const char **argv) { -#ifdef INCLUDE_OLDGFX - DebugPrintf("List of dropped dynamic views:\n"); - - if (_vm->_gamestate->drop_views) - _vm->_gamestate->drop_views->print(0); - else - DebugPrintf("The list is empty.\n"); -#endif - - return true; -} - -bool Console::cmdPriorityBands(int argc, const char **argv) { -#ifdef INCLUDE_OLDGFX - if (argc != 2) { - DebugPrintf("Priority bands start at y=%d. They end at y=%d\n", _vm->_gamestate->priority_first, _vm->_gamestate->priority_last); - DebugPrintf("Use %s <priority band> to print the start of priority for the specified priority band (0 - 15)\n", argv[0]); - return true; - } - - int zone = CLIP<int>(atoi(argv[1]), 0, 15); - - DebugPrintf("Zone %x starts at y=%d\n", zone, _find_priority_band(_vm->_gamestate, zone)); -#endif - - return true; -} - bool Console::cmdPrintSegmentTable(int argc, const char **argv) { DebugPrintf("Segment table:\n"); @@ -3145,219 +2778,4 @@ int Console::printObject(reg_t pos) { return 0; } -#define GETRECT(ll, rr, tt, bb) \ - ll = GET_SELECTOR(pos, ll); \ - rr = GET_SELECTOR(pos, rr); \ - tt = GET_SELECTOR(pos, tt); \ - bb = GET_SELECTOR(pos, bb); - -#if 0 -// TODO Re-implement this -static void viewobjinfo(EngineState *s, HeapPtr pos) { - char *signals[16] = { - "stop_update", - "updated", - "no_update", - "hidden", - "fixed_priority", - "always_update", - "force_update", - "remove", - "frozen", - "is_extra", - "hit_obstacle", - "doesnt_turn", - "no_cycler", - "ignore_horizon", - "ignore_actor", - "dispose!" - }; - - int x, y, z, priority; - int cel, loop, view, signal; - int nsLeft, nsRight, nsBottom, nsTop; - int lsLeft, lsRight, lsBottom, lsTop; - int brLeft, brRight, brBottom, brTop; - int i; - int have_rects = 0; - Common::Rect nsrect, nsrect_clipped, brrect; - - if (lookup_selector(s->_segMan, pos, s->_kernel->_selectorCache.nsBottom, NULL) == kSelectorVariable) { - GETRECT(nsLeft, nsRight, nsBottom, nsTop); - GETRECT(lsLeft, lsRight, lsBottom, lsTop); - GETRECT(brLeft, brRight, brBottom, brTop); - have_rects = 1; - } - - GETRECT(view, loop, signal, cel); - - printf("\n-- View information:\ncel %d/%d/%d at ", view, loop, cel); - - x = GET_SELECTOR(pos, x); - y = GET_SELECTOR(pos, y); - priority = GET_SELECTOR(pos, priority); - if (s->_kernel->_selectorCache.z > 0) { - z = GET_SELECTOR(pos, z); - printf("(%d,%d,%d)\n", x, y, z); - } else - printf("(%d,%d)\n", x, y); - - if (priority == -1) - printf("No priority.\n\n"); - else - printf("Priority = %d (band starts at %d)\n\n", priority, PRIORITY_BAND_FIRST(priority)); - - if (have_rects) { - printf("nsRect: [%d..%d]x[%d..%d]\n", nsLeft, nsRight, nsTop, nsBottom); - printf("lsRect: [%d..%d]x[%d..%d]\n", lsLeft, lsRight, lsTop, lsBottom); - printf("brRect: [%d..%d]x[%d..%d]\n", brLeft, brRight, brTop, brBottom); - } - - nsrect = get_nsrect(s, pos, 0); - nsrect_clipped = get_nsrect(s, pos, 1); - //brrect = set_base(s, pos); - printf("new nsRect: [%d..%d]x[%d..%d]\n", nsrect.x, nsrect.xend, nsrect.y, nsrect.yend); - printf("new clipped nsRect: [%d..%d]x[%d..%d]\n", nsrect_clipped.x, nsrect_clipped.xend, nsrect_clipped.y, nsrect_clipped.yend); - printf("new brRect: [%d..%d]x[%d..%d]\n", brrect.x, brrect.xend, brrect.y, brrect.yend); - printf("\n signals = %04x:\n", signal); - - for (i = 0; i < 16; i++) - if (signal & (1 << i)) - printf(" %04x: %s\n", 1 << i, signals[i]); -} -#endif -#undef GETRECT - -#define GETRECT(ll, rr, tt, bb) \ - ll = GET_SELECTOR(pos, ll); \ - rr = GET_SELECTOR(pos, rr); \ - tt = GET_SELECTOR(pos, tt); \ - bb = GET_SELECTOR(pos, bb); - -#if 0 -// Draws the nsRect and brRect of a dynview object. nsRect is green, brRect is blue. -// TODO: Re-implement this -static int c_gfx_draw_viewobj(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - HeapPtr pos = (HeapPtr)(cmdParams[0].val); - int is_view; - int x, y, priority; - int nsLeft, nsRight, nsBottom, nsTop; - int brLeft, brRight, brBottom, brTop; - - if (!s) { - printf("Not in debug state!\n"); - return 1; - } - - if ((pos < 4) || (pos > 0xfff0)) { - printf("Invalid address.\n"); - return 1; - } - - if (((int16)READ_LE_UINT16(s->heap + pos + SCRIPT_OBJECT_MAGIC_OFFSET)) != SCRIPT_OBJECT_MAGIC_NUMBER) { - printf("Not an object.\n"); - return 0; - } - - - is_view = (lookup_selector(s->_segMan, pos, s->_kernel->_selectorCache.x, NULL) == kSelectorVariable) && - (lookup_selector(s->_segMan, pos, s->_kernel->_selectorCache.brLeft, NULL) == kSelectorVariable) && - (lookup_selector(s->_segMan, pos, s->_kernel->_selectorCache.signal, NULL) == kSelectorVariable) && - (lookup_selector(s->_segMan, pos, s->_kernel->_selectorCache.nsTop, NULL) == kSelectorVariable); - - if (!is_view) { - printf("Not a dynamic View object.\n"); - return 0; - } - - x = GET_SELECTOR(pos, x); - y = GET_SELECTOR(pos, y); - priority = GET_SELECTOR(pos, priority); - GETRECT(brLeft, brRight, brBottom, brTop); - GETRECT(nsLeft, nsRight, nsBottom, nsTop); - gfxop_set_clip_zone(s->gfx_state, gfx_rect_fullscreen); - - brTop += 10; - brBottom += 10; - nsTop += 10; - nsBottom += 10; - - gfxop_fill_box(s->gfx_state, gfx_rect(nsLeft, nsTop, nsRight - nsLeft + 1, nsBottom - nsTop + 1), s->ega_colors[2]); - gfxop_fill_box(s->gfx_state, gfx_rect(brLeft, brTop, brRight - brLeft + 1, brBottom - brTop + 1), s->ega_colors[1]); - gfxop_fill_box(s->gfx_state, gfx_rect(x - 1, y - 1, 3, 3), s->ega_colors[0]); - gfxop_fill_box(s->gfx_state, gfx_rect(x - 1, y, 3, 1), s->ega_colors[priority]); - gfxop_fill_box(s->gfx_state, gfx_rect(x, y - 1, 1, 3), s->ega_colors[priority]); - gfxop_update(s->gfx_state); - - return 0; -} -#endif -#undef GETRECT - -#if 0 -// Executes one operation skipping over sends -// TODO Re-implement this -int c_stepover(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { - int opcode, opnumber; - - opcode = s->_heap[*p_pc]; - opnumber = opcode >> 1; - if (opnumber == 0x22 /* callb */ || opnumber == 0x23 /* calle */ || - opnumber == 0x25 /* send */ || opnumber == 0x2a /* self */ || opnumber == 0x2b /* super */) { - g_debugState.seeking = kDebugSeekSO; - g_debugState.seekLevel = s->_executionStack.size()-1; - // Store in g_debugState.seekSpecial the offset of the next command after send - switch (opcode) { - case 0x46: // calle W - g_debugState.seekSpecial = *p_pc + 5; - break; - - case 0x44: // callb W - case 0x47: // calle B - case 0x56: // super W - g_debugState.seekSpecial = *p_pc + 4; - break; - - case 0x45: // callb B - case 0x57: // super B - case 0x4A: // send W - case 0x54: // self W - g_debugState.seekSpecial = *p_pc + 3; - break; - - default: - g_debugState.seekSpecial = *p_pc + 2; - } - } - - return 0; -} -#endif - -#ifdef GFXW_DEBUG_WIDGETS -extern GfxWidget *debug_widgets[]; -extern int debug_widget_pos; - -// If called with no parameters, it shows which widgets are active -// With parameters, it lists the widget corresponding to the numerical index specified (for each parameter). -bool Console::cmdPrintWidget(int argc, const char **argv) { - if (argc > 1) { - for (int i = 0; i < argc; i++) { - int widget_nr = atoi(argv[1]); - - DebugPrintf("===== Widget #%d:\n", widget_nr); - debug_widgets[widget_nr]->print(0); - } - } else if (debug_widget_pos > 1) { - DebugPrintf("Widgets 0-%d are active\n", debug_widget_pos - 1); - } else if (debug_widget_pos == 1) { - DebugPrintf("Widget 0 is active\n"); - } else { - DebugPrintf("No widgets are active\n"); - } - - return true; -} -#endif - } // End of namespace Sci diff --git a/engines/sci/console.h b/engines/sci/console.h index b6bc7523d6..a292e126ae 100644 --- a/engines/sci/console.h +++ b/engines/sci/console.h @@ -81,29 +81,11 @@ private: bool cmdExit(int argc, const char **argv); bool cmdListSaves(int argc, const char **argv); // Screen - bool cmdSci0Palette(int argc, const char **argv); - bool cmdClearScreen(int argc, const char **argv); - bool cmdRedrawScreen(int argc, const char **argv); - bool cmdFillScreen(int argc, const char **argv); bool cmdShowMap(int argc, const char **argv); - bool cmdUpdateZone(int argc, const char **argv); - bool cmdPropagateZone(int argc, const char **argv); - bool cmdPriorityBands(int argc, const char **argv); // Graphics bool cmdDrawPic(int argc, const char **argv); - bool cmdDrawRect(int argc, const char **argv); - bool cmdDrawCel(int argc, const char **argv); - bool cmdViewInfo(int argc, const char **argv); bool cmdUndither(int argc, const char **argv); bool cmdPlayVideo(int argc, const char **argv); - // GUI - bool cmdCurrentPort(int argc, const char **argv); - bool cmdPrintPort(int argc, const char **argv); - bool cmdVisualState(int argc, const char **argv); - bool cmdFlushPorts(int argc, const char **argv); - bool cmdDynamicViews(int argc, const char **argv); - bool cmdDroppedViews(int argc, const char **argv); - bool cmdPrintWidget(int argc, const char **argv); // Segments bool cmdPrintSegmentTable(int argc, const char **argv); bool cmdSegmentInfo(int argc, const char **argv); diff --git a/engines/sci/engine/game.cpp b/engines/sci/engine/game.cpp index 49652867a8..133abff3b9 100644 --- a/engines/sci/engine/game.cpp +++ b/engines/sci/engine/game.cpp @@ -35,10 +35,6 @@ #include "sci/engine/kernel_types.h" #include "sci/engine/message.h" #include "sci/gui/gui.h" -#ifdef INCLUDE_OLDGFX -#include "sci/gfx/gfx_state_internal.h" // required for GfxPort, GfxVisual -#include "sci/gfx/menubar.h" -#endif #include "sci/sfx/music.h" namespace Sci { @@ -179,133 +175,6 @@ const char *convertSierraGameId(const char *gameId, uint32 *gameFlags, ResourceM return strdup(sierraId.c_str()); } -#ifdef INCLUDE_OLDGFX -int _reset_graphics_input(EngineState *s) { - Resource *resource; - int font_nr; - gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 }; - debug(2, "Initializing graphics"); - - if (s->resMan->getViewType() == kViewEga) { - for (int i = 0; i < 16; i++) { - gfxop_set_color(s->gfx_state, &(s->ega_colors[i]), gfx_sci0_image_colors[sci0_palette][i].r, - gfx_sci0_image_colors[sci0_palette][i].g, gfx_sci0_image_colors[sci0_palette][i].b, 0, -1, -1); - s->gfx_state->driver->getMode()->palette->makeSystemColor(i, s->ega_colors[i].visual); - } - } else { - // Allocate SCI1 system colors - gfx_color_t black = { PaletteEntry(0, 0, 0), 0, 0, 0, GFX_MASK_VISUAL }; - s->gfx_state->driver->getMode()->palette->makeSystemColor(0, black.visual); - - // Check for Amiga palette file. - Common::File file; - if (file.open("spal")) { - s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal1_amiga(file)); - file.close(); - } else { - resource = s->resMan->findResource(ResourceId(kResourceTypePalette, 999), 1); - if (resource) { - if (s->resMan->getViewType() != kViewVga11) - s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal1(999, resource->data, resource->size)); - else - s->gfx_state->gfxResMan->setStaticPalette(gfxr_read_pal11(999, resource->data, resource->size)); - s->resMan->unlockResource(resource); - } else { - debug(2, "Couldn't find the default palette!"); - } - } - } - - gfxop_fill_box(s->gfx_state, gfx_rect(0, 0, 320, 200), s->ega_colors[0]); // Fill screen black - gfxop_update(s->gfx_state); - - s->pic_is_new = 0; - s->pic_visible_map = GFX_MASK_NONE; // Other values only make sense for debugging - s->dyn_views = NULL; // no DynViews - s->drop_views = NULL; // And, consequently, no list for dropped views - - font_nr = -1; - do { - resource = s->resMan->testResource(ResourceId(kResourceTypeFont, ++font_nr)); - } while ((!resource) && (font_nr < 65536)); - - if (!resource) { - debug(2, "No text font was found."); - return 1; - } - - s->visual = new GfxVisual(s->gfx_state, font_nr); - - s->wm_port = new GfxPort(s->visual, s->gfx_state->pic_port_bounds, s->ega_colors[0], transparent); - - s->iconbar_port = new GfxPort(s->visual, gfx_rect(0, 0, 320, 200), s->ega_colors[0], transparent); - s->iconbar_port->_flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH; - - if (s->resMan->isVGA()) { - // This bit sets the foreground and background colors in VGA SCI games - gfx_color_t fgcolor; - gfx_color_t bgcolor; - memset(&fgcolor, 0, sizeof(gfx_color_t)); - memset(&bgcolor, 0, sizeof(gfx_color_t)); - -#if 0 - fgcolor.visual = s->gfx_state->resstate->static_palette[0]; - fgcolor.mask = GFX_MASK_VISUAL; - bgcolor.visual = s->gfx_state->resstate->static_palette[255]; - bgcolor.mask = GFX_MASK_VISUAL; -#endif - s->titlebar_port = new GfxPort(s->visual, gfx_rect(0, 0, 320, 10), fgcolor, bgcolor); - } else { - s->titlebar_port = new GfxPort(s->visual, gfx_rect(0, 0, 320, 10), s->ega_colors[0], s->ega_colors[15]); - } - s->titlebar_port->_color.mask |= GFX_MASK_PRIORITY; - s->titlebar_port->_color.priority = 11; - s->titlebar_port->_bgcolor.mask |= GFX_MASK_PRIORITY; - s->titlebar_port->_bgcolor.priority = 11; - s->titlebar_port->_flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH; - - // but this is correct - s->picture_port = new GfxPort(s->visual, s->gfx_state->pic_port_bounds, s->ega_colors[0], transparent); - - s->visual->add((GfxContainer *)s->visual, s->wm_port); - s->visual->add((GfxContainer *)s->visual, s->titlebar_port); - s->visual->add((GfxContainer *)s->visual, s->picture_port); - s->visual->add((GfxContainer *)s->visual, s->iconbar_port); - // Add ports to visual - - s->port = s->picture_port; // Currently using the picture port - -#if 0 - s->titlebar_port->_bgcolor.mask |= GFX_MASK_PRIORITY; - s->titlebar_port->_bgcolor.priority = 11; // Standard priority for the titlebar port -#endif - - s->priority_first = 42; // Priority zone 0 ends here - - if (s->usesOldGfxFunctions()) - s->priority_last = 200; - else - s->priority_last = 190; - - return 0; -} - -int game_init_graphics(EngineState *s) { - return _reset_graphics_input(s); -} - -static void _free_graphics_input(EngineState *s) { - debug(2, "Freeing graphics"); - - delete s->visual; - - s->wm_port = s->titlebar_port = s->picture_port = NULL; - s->visual = NULL; - s->dyn_views = NULL; - s->port = NULL; -} -#endif - #ifdef USE_OLD_MUSIC_FUNCTIONS int game_init_sound(EngineState *s, int sound_flags, SciVersion soundVersion) { if (getSciVersion() > SCI_VERSION_0_LATE) @@ -358,10 +227,6 @@ int script_init_engine(EngineState *s) { debug(2, "Engine initialized"); -#ifdef INCLUDE_OLDGFX - s->pic_priority_table = NULL; -#endif - return 0; } @@ -401,10 +266,6 @@ int game_init(EngineState *s) { s->parserIsValid = false; // Invalidate parser s->parser_event = NULL_REG; // Invalidate parser event -#ifdef INCLUDE_OLDGFX - if (s->gfx_state && _reset_graphics_input(s)) - return 1; -#endif // Initialize menu TODO: Actually this should be another init() s->_gui->menuReset(); @@ -430,10 +291,6 @@ int game_init(EngineState *s) { debug(2, " \"%s\" at %04x:%04x", s->_gameId.c_str(), PRINT_REG(s->_gameObj)); -#ifdef INCLUDE_OLDGFX - s->_menubar = new Menubar(); // Create menu bar -#endif - #ifdef USE_OLD_MUSIC_FUNCTIONS if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND) game_init_sound(s, 0, s->detectDoSoundType()); @@ -472,12 +329,6 @@ int game_exit(EngineState *s) { // TODO Free scripts here -#ifdef INCLUDE_OLDGFX - delete s->_menubar; - - _free_graphics_input(s); -#endif - // Close all opened file handles s->_fileHandles.clear(); s->_fileHandles.resize(5); diff --git a/engines/sci/engine/kevent.cpp b/engines/sci/engine/kevent.cpp index 7c7bc7c084..4619f29f40 100644 --- a/engines/sci/engine/kevent.cpp +++ b/engines/sci/engine/kevent.cpp @@ -26,7 +26,6 @@ #include "sci/sci.h" #include "sci/engine/state.h" #include "sci/engine/kernel.h" -#include "sci/gfx/operations.h" #include "sci/console.h" #include "sci/debug.h" // for g_debug_simulated_key #include "sci/event.h" diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index f909ab5f13..ff3783db79 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -33,7 +33,6 @@ #include "sci/video/seq_decoder.h" #include "sci/engine/state.h" #include "sci/engine/kernel.h" -#include "sci/gfx/operations.h" #include "sci/gui/gui.h" #include "sci/gui/gui_animate.h" #include "sci/gui/gui_cursor.h" @@ -295,9 +294,6 @@ reg_t kGraph(EngineState *s, int argc, reg_t *argv) { warning("Unsupported kGraph() operation %04x", argv[0].toSint16()); } -#ifdef INCLUDE_OLDGFX - gfxop_update(s->gfx_state); -#endif return s->r_acc; } diff --git a/engines/sci/engine/kmenu.cpp b/engines/sci/engine/kmenu.cpp index 4074e81ba0..b3ed6d03e0 100644 --- a/engines/sci/engine/kmenu.cpp +++ b/engines/sci/engine/kmenu.cpp @@ -27,11 +27,6 @@ #include "sci/resource.h" #include "sci/engine/state.h" #include "sci/engine/kernel.h" -#ifdef INCLUDE_OLDGFX -#include "sci/gfx/gfx_gui.h" -#include "sci/gfx/gfx_state_internal.h" // required for GfxPort, GfxVisual -#include "sci/gfx/menubar.h" -#endif #include "sci/gui/gui.h" #include "sci/gui/gui_cursor.h" diff --git a/engines/sci/engine/kscripts.cpp b/engines/sci/engine/kscripts.cpp index 51fe7b887c..16ef002e66 100644 --- a/engines/sci/engine/kscripts.cpp +++ b/engines/sci/engine/kscripts.cpp @@ -168,10 +168,6 @@ reg_t kDisposeClone(EngineState *s, int argc, reg_t *argv) { victim_obj->markAsFreed(); -#ifdef INCLUDE_OLDGFX - _k_view_list_mark_free(s, victim_addr); // Free on view list, if neccessary -#endif - return s->r_acc; } diff --git a/engines/sci/engine/savegame.cpp b/engines/sci/engine/savegame.cpp index 9ec79dd2c0..cd8b738bde 100644 --- a/engines/sci/engine/savegame.cpp +++ b/engines/sci/engine/savegame.cpp @@ -31,10 +31,6 @@ #include "sci/sci.h" #include "sci/event.h" -#ifdef INCLUDE_OLDGFX -#include "sci/gfx/menubar.h" -#include "sci/gfx/gfx_state_internal.h" // required for GfxPort, GfxContainer -#endif #include "sci/engine/state.h" #include "sci/engine/message.h" @@ -217,39 +213,6 @@ void syncWithSerializer(Common::Serializer &s, reg_t &obj) { sync_reg_t(s, obj); } - -#ifdef INCLUDE_OLDGFX - -void MenuItem::saveLoadWithSerializer(Common::Serializer &s) { - s.syncAsSint32LE(_type); - s.syncString(_keytext); - s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be keytext_size - - s.syncAsSint32LE(_flags); - s.syncBytes(_said, MENU_SAID_SPEC_SIZE); - sync_reg_t(s, _saidPos); - s.syncString(_text); - sync_reg_t(s, _textPos); - s.syncAsSint32LE(_modifiers); - s.syncAsSint32LE(_key); - s.syncAsSint32LE(_enabled); - s.syncAsSint32LE(_tag); -} - -void Menu::saveLoadWithSerializer(Common::Serializer &s) { - s.syncString(_title); - s.syncAsSint32LE(_titleWidth); - s.syncAsSint32LE(_width); - - syncArray<MenuItem>(s, _items); -} - -void Menubar::saveLoadWithSerializer(Common::Serializer &s) { - syncArray<Menu>(s, _menus); -} - -#endif - void SegManager::saveLoadWithSerializer(Common::Serializer &s) { s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be reserved_id s.syncAsSint32LE(_exportsAreWide); @@ -360,16 +323,6 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { s.syncString(tmp); // OBSOLETE: Used to be game_version s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be version -#ifdef INCLUDE_OLDGFX - if (s.isLoading()) { - //free(menubar); - _menubar = new Menubar(); - } else - assert(_menubar); - _menubar->saveLoadWithSerializer(s); -#else - // FIXME: This code goes out of sync when loading. Find out why - // OBSOLETE: Saved menus. Skip all of the saved data if (s.getVersion() < 14) { int totalMenus = 0; @@ -398,7 +351,6 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { } } } -#endif s.skip(4, VER(12), VER(12)); // obsolete: used to be status_bar_foreground s.skip(4, VER(12), VER(12)); // obsolete: used to be status_bar_background @@ -416,11 +368,6 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) { s.syncAsSint16LE(picPortRect.right); s.syncAsSint16LE(picPortTop); s.syncAsSint16LE(picPortLeft); - - #ifndef USE_OLDGFX - if (s.isLoading()) - _gui->setPortPic(picPortRect, picPortTop, picPortLeft, true); - #endif } sync_SegManagerPtr(s, resMan, _segMan); @@ -825,9 +772,6 @@ void SegManager::reconstructScripts(EngineState *s) { } } } -#ifdef INCLUDE_OLDGFX -int _reset_graphics_input(EngineState *s); -#endif #ifdef USE_OLD_MUSIC_FUNCTIONS static void reconstruct_sounds(EngineState *s) { @@ -912,7 +856,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { retval->_event = new SciEvent(); // Copy some old data - retval->gfx_state = s->gfx_state; retval->_soundCmd = s->_soundCmd; retval->saveLoadWithSerializer(ser); // FIXME: Error handling? @@ -925,10 +868,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { retval->execution_stack_base = 0; // Now copy all current state information -#ifdef INCLUDE_OLDGFX - // Graphics and input state: - retval->old_screen = 0; -#endif #ifdef USE_OLD_MUSIC_FUNCTIONS temp = retval->_sound._songlib; @@ -947,9 +886,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { retval->gc_countdown = GC_INTERVAL - 1; retval->sys_strings_segment = retval->_segMan->findSegmentByType(SEG_TYPE_SYS_STRINGS); retval->sys_strings = (SystemStrings *)GET_SEGMENT(*retval->_segMan, retval->sys_strings_segment, SEG_TYPE_SYS_STRINGS); -#ifdef INCLUDE_OLDGFX - _reset_graphics_input(retval); -#endif // Time state: retval->last_wait_time = g_system->getMillis(); @@ -964,9 +900,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) { retval->bp_list = s->bp_list; retval->successor = NULL; -#ifdef INCLUDE_OLDGFX - retval->pic_priority_table = (int *)(retval->gfx_state->pic) ? retval->gfx_state->pic->priorityTable : NULL; -#endif retval->_gameId = s->_gameId; #ifdef USE_OLD_MUSIC_FUNCTIONS diff --git a/engines/sci/engine/state.cpp b/engines/sci/engine/state.cpp index 98ef8715ab..0cef76836f 100644 --- a/engines/sci/engine/state.cpp +++ b/engines/sci/engine/state.cpp @@ -35,37 +35,10 @@ namespace Sci { EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, SegManager *segMan, SciGui *gui, AudioPlayer *audio) : resMan(res), _kernel(kernel), _voc(voc), _segMan(segMan), _gui(gui), _audio(audio), _dirseeker(this) { - gfx_state = 0; - sfx_init_flags = 0; restarting_flags = 0; -#ifdef INCLUDE_OLDGFX - pic_priority_table = 0; - pic_not_valid = 0; - pic_is_new = 0; - old_screen = 0; - port = 0; - memset(ega_colors, 0, sizeof(ega_colors)); - visual = 0; - titlebar_port = 0; - wm_port = 0; - picture_port = 0; - iconbar_port = 0; - - pic_visible_map = GFX_MASK_NONE; - pic_animate = 0; - - dyn_views = 0; - drop_views = 0; - - priority_first = 0; - priority_last = 0; - - _menubar = 0; -#endif - last_wait_time = 0; _fileHandles.resize(5); diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h index ddfebddf19..61f3aa68f2 100644 --- a/engines/sci/engine/state.h +++ b/engines/sci/engine/state.h @@ -41,7 +41,6 @@ namespace Common { #include "sci/engine/kernel.h" // for kfunct_sig_pair_t #include "sci/engine/script.h" #include "sci/engine/seg_manager.h" -#include "sci/gfx/gfx_system.h" #include "sci/sfx/audio.h" #ifdef USE_OLD_MUSIC_FUNCTIONS #include "sci/sfx/iterator/core.h" @@ -148,8 +147,6 @@ public: SciEvent *_event; // Event handling - GfxState *gfx_state; /**< Graphics state and driver */ - AudioPlayer *_audio; #ifdef USE_OLD_MUSIC_FUNCTIONS SfxState _sound; /**< sound subsystem */ @@ -159,35 +156,6 @@ public: byte restarting_flags; /**< Flags used for restarting */ -#ifdef INCLUDE_OLDGFX - int *pic_priority_table; /**< 16 entries with priorities or NULL if not present */ - byte pic_not_valid; /**< Is 0 if the background picture is "valid" */ - byte pic_is_new; /**< New pic was loaded or port was opened */ - gfx_pixmap_t *old_screen; /**< Old screen content: Stored during kDrawPic() for kAnimate() */ - - GfxPort *port; /**< The currently active port */ - - gfx_color_t ega_colors[16]; /**< The 16 EGA colors- for SCI0(1) */ - - GfxVisual *visual; /**< A visual widget, containing all ports */ - - GfxPort *titlebar_port; /**< Title bar viewport (0,0,9,319) */ - GfxPort *wm_port; /**< window manager viewport and designated &heap[0] view (10,0,199,319) */ - GfxPort *picture_port; /**< The background picture viewport (10,0,199,319) */ - GfxPort *iconbar_port; /**< Full-screen port used for non-clipped icon bar draw in SCI1 */ - - gfx_map_mask_t pic_visible_map; /**< The number of the map to display in update commands */ - int pic_animate; /**< The animation used by Animate() to display the picture */ - - GfxList *dyn_views; /**< Pointers to pic and dynamic view lists */ - GfxList *drop_views; /**< A list Animate() can dump dropped dynviews into */ - - int priority_first; /**< The line where priority zone 0 ends */ - int priority_last; /**< The line where the highest priority zone starts */ - - Menubar *_menubar; /**< The menu bar */ -#endif - uint32 game_start_time; /**< The time at which the interpreter was started */ uint32 last_wait_time; /**< The last time the game invoked Wait() */ @@ -310,24 +278,6 @@ private: bool _usesCdTrack; }; -#ifdef INCLUDE_OLDGFX - -/** - * Retrieves the gfx_pixmap_color_t associated with a game color index. - * @param s game state - * @param color color to look up - * @return the requested color - */ -PaletteEntry get_pic_color(EngineState *s, int color); - -/* Functions used in gui32\gui32.cpp */ -reg_t graph_save_box(EngineState *s, rect_t area); -void graph_restore_box(EngineState *s, reg_t handle); -void assert_primary_widget_lists(EngineState *s); -void reparentize_primary_widget_lists(EngineState *s, GfxPort *newport); - -#endif - } // End of namespace Sci #endif // SCI_INCLUDE_ENGINE_H diff --git a/engines/sci/engine/vm.h b/engines/sci/engine/vm.h index a90528ac16..75b2508f20 100644 --- a/engines/sci/engine/vm.h +++ b/engines/sci/engine/vm.h @@ -480,17 +480,6 @@ const char *convertSierraGameId(const char *gameId, uint32 *gameFlags, ResourceM */ int game_init(EngineState *s); -#ifdef INCLUDE_OLDGFX -/** - * 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); -#endif - #ifdef USE_OLD_MUSIC_FUNCTIONS /** * Initializes the sound part of an SCI game diff --git a/engines/sci/gfx/gfx_driver.cpp b/engines/sci/gfx/gfx_driver.cpp deleted file mode 100644 index 41205a0ecc..0000000000 --- a/engines/sci/gfx/gfx_driver.cpp +++ /dev/null @@ -1,205 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "common/scummsys.h" -#include "common/system.h" -#include "graphics/cursorman.h" -#include "graphics/primitives.h" -#include "graphics/surface.h" - -#include "sci/gui/gui_screen.h" -#include "sci/gfx/gfx_driver.h" -#include "sci/gfx/gfx_tools.h" - -#include "sci/gui/gui_screen.h" - -namespace Sci { - - -GfxDriver::GfxDriver(SciGuiScreen *screen, int scaleFactor) : _screen(screen) { - _mode = gfx_new_mode(scaleFactor, new Palette(256)); - - if (_mode->palette) - _mode->palette->name = "global"; -} - -GfxDriver::~GfxDriver() { -} - - -// Drawing operations - -static void drawProc(int x, int y, int c, void *data) { - GfxDriver *drv = (GfxDriver *)data; - byte *p = drv->_screen->_displayScreen; - uint8 col = c; - memcpy(p + (y * drv->_screen->_width * drv->getMode()->scaleFactor + x), &col, 1); -} - -void GfxDriver::drawLine(Common::Point start, Common::Point end, gfx_color_t color, - gfx_line_mode_t line_mode, gfx_line_style_t line_style) { - uint32 scolor = color.visual.getParentIndex(); - int scaleFactor = (line_mode == GFX_LINE_MODE_FINE)? 1: _mode->scaleFactor; - int xsize = _mode->xsize; - int ysize = _mode->ysize; - - if (color.mask & GFX_MASK_VISUAL) { - Common::Point nstart, nend; - - for (int xc = 0; xc < scaleFactor; xc++) { - for (int yc = 0; yc < scaleFactor; yc++) { - - nstart.x = CLIP<int16>(start.x + xc, 0, xsize); - nstart.y = CLIP<int16>(start.y + yc, 0, ysize); - nend.x = CLIP<int16>(end.x + xc, 0, xsize - 1); - nend.y = CLIP<int16>(end.y + yc, 0, ysize - 1); - - Graphics::drawLine(nstart.x, nstart.y, nend.x, nend.y, scolor, drawProc, this); - - if (color.mask & GFX_MASK_PRIORITY) { - gfx_draw_line_buffer(_screen->_priorityScreen, 1, 1, nstart, nend, color.priority); - } - } - } - } -} - -void GfxDriver::drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode) { - if (color1.mask & GFX_MASK_VISUAL) { - for (int i = rect.y; i < rect.y + rect.height; i++) { - memset(_screen->_displayScreen + (i * _mode->xsize + rect.x), - color1.visual.getParentIndex(), rect.width); - } - } - - if (color1.mask & GFX_MASK_PRIORITY) { - gfx_clip_box_basic(&rect, _screen->_width - 1, _screen->_height - 1); - gfx_draw_box_buffer(_screen->_priorityScreen, _screen->_width, rect, color1.priority); - } -} - -// Pixmap operations - -void GfxDriver::drawPixmap(gfx_pixmap_t *pxm, int priority, rect_t src, rect_t dest, gfx_buffer_t buffer) { - byte *destBuffer = (buffer == GFX_BUFFER_STATIC) ? _screen->_visualScreen : _screen->_displayScreen; - byte *destPriority = (buffer == GFX_BUFFER_STATIC) ? _screen->_controlScreen : _screen->_priorityScreen; - if (dest.width != src.width || dest.height != src.height) { - warning("Attempt to scale pixmap (%dx%d)->(%dx%d): Not supported\n", src.width, src.height, dest.width, dest.height); - return; - } - - gfx_crossblit_pixmap(_mode, pxm, priority, src, dest, destBuffer, - _mode->xsize, - destPriority, - _screen->_width, 1); -} - -void GfxDriver::grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map) { - if (src.x < 0 || src.y < 0) - error("Attempt to grab pixmap from invalid coordinates (%d,%d)", src.x, src.y); - - if (!pxm->data) - error("Attempt to grab pixmap to unallocated memory"); - - switch (map) { - - case GFX_MASK_VISUAL: - pxm->width = src.width; - pxm->height = src.height; - for (int i = 0; i < src.height; i++) { - memcpy(pxm->data + i * src.width, - _screen->_displayScreen + ((i + src.y) * _mode->xsize + src.x), - src.width); - } - break; - - case GFX_MASK_PRIORITY: - warning("FIXME: priority map grab not implemented yet"); - break; - - default: - error("Attempt to grab pixmap from invalid map 0x%02x", map); - } -} - -// Buffer operations - -void GfxDriver::update(rect_t src, Common::Point dest, gfx_buffer_t buffer) { - switch (buffer) { - case GFX_BUFFER_BACK: - for (int i = 0; i < src.height; i++) { - memcpy(_screen->_displayScreen + ( (dest.y + i) * _mode->xsize + dest.x), - _screen->_visualScreen + ( (src.y + i) * _mode->xsize + src.x), src.width ); - } - - if ((src.x == dest.x) && (src.y == dest.y)) { - int offset = src.x + (src.y * _screen->_width); - - gfx_clip_box_basic(&src, _screen->_width, _screen->_height); - - while (src.height--) { - memcpy(_screen->_priorityScreen + offset, _screen->_controlScreen + offset, _screen->_width); - offset += _screen->_width; - } - } - break; - case GFX_BUFFER_FRONT: { - // TODO: we need to call SciGuiCursor::refreshPosition() before each screen update to limit the mouse cursor position - g_system->copyRectToScreen(_screen->_displayScreen + (src.x + src.y * _mode->xsize), _mode->xsize, dest.x, dest.y, src.width, src.height); - g_system->updateScreen(); - break; - } - default: - error("Invalid buffer %d in update", buffer); - } -} - -void GfxDriver::setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority) { - memcpy(_screen->_visualScreen, pic->data, _mode->xsize * _mode->ysize); - memcpy(_screen->_controlScreen, priority->index_data, _mode->xsize * _mode->ysize); -} - -void GfxDriver::animatePalette(int fromColor, int toColor, int stepCount) { - int i; - PaletteEntry firstColor = _mode->palette->getColor(fromColor); - PaletteEntry loopColor; - for (i = fromColor + 1; i <= toColor; i++) { - loopColor = _mode->palette->getColor(i); - loopColor.r = 0; - loopColor.g = 0; - loopColor.b = 0; - _mode->palette->makeSystemColor(i-1, loopColor); // loopColor.r, loopColor.g, loopColor.b); - } -// _mode->palette->setColor(toColor, firstColor.r, firstColor.g, firstColor.b); - _mode->palette->makeSystemColor(toColor, firstColor); -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_driver.h b/engines/sci/gfx/gfx_driver.h deleted file mode 100644 index e4f8bfd2f6..0000000000 --- a/engines/sci/gfx/gfx_driver.h +++ /dev/null @@ -1,228 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_DRIVER_H -#define SCI_GFX_GFX_DRIVER_H - -#include "sci/gfx/gfx_system.h" - -namespace Sci { - -enum gfx_buffer_t { - GFX_BUFFER_FRONT = 0, - GFX_BUFFER_BACK = 1, - GFX_BUFFER_STATIC = 2 -}; - -class SciGuiScreen; - - -/** - * 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: - /** @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 - * @return GFX_OK on success, GFX_ERROR if the mode could - * not be set, or GFX_FATAL if the graphics target - * is unuseable. - */ - GfxDriver(SciGuiScreen *screen, int scaleFactor); - - /** - * 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(); - /** @} */ - - /** @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 - */ - void 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 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_*. - */ - void drawFilledRect(rect_t rect, gfx_color_t color1, gfx_color_t color2, - gfx_rectangle_fill_t shade_mode); - /** @} */ - - /** @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 - */ - void drawPixmap(gfx_pixmap_t *pxm, int priority, - rect_t src, rect_t dest, gfx_buffer_t buffer); - - /** - * 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 - */ - void grabPixmap(rect_t src, gfx_pixmap_t *pxm, gfx_map_mask_t map); - /** @} */ - - /** @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 - */ - void update(rect_t src, Common::Point dest, gfx_buffer_t buffer); - - /** - * 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 - */ - void setStaticBuffer(gfx_pixmap_t *pic, gfx_pixmap_t *priority); - /** @} */ - - gfx_mode_t *getMode() { return _mode; } - - /** - * Animates palette - */ - void animatePalette(int fromColor, int toColor, int stepCount); - -public: // temporary hack - SciGuiScreen *_screen; -private: - gfx_mode_t *_mode; /**< Currently active mode, NULL if no mode is active */ -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_DRIVER_H - -#endif diff --git a/engines/sci/gfx/gfx_gui.cpp b/engines/sci/gfx/gfx_gui.cpp deleted file mode 100644 index 2cfe0f3a39..0000000000 --- a/engines/sci/gfx/gfx_gui.cpp +++ /dev/null @@ -1,666 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/engine/state.h" -#include "sci/gfx/operations.h" -#include "sci/gfx/gfx_widgets.h" -#include "sci/gfx/menubar.h" -#include "sci/gfx/gfx_gui.h" -#include "sci/gfx/gfx_state_internal.h" -#include "sci/gui32/font.h" -#include "sci/gui/gui_animate.h" - -#include "common/system.h" - -namespace Sci { - -#define SCI_SPECIAL_CHAR_ARROW_UP 0x18 -#define SCI_SPECIAL_CHAR_ARROW_DOWN 0x19 - -static void clear_titlebar(GfxPort *titlebar) { - if (titlebar->_contents) { - delete titlebar->_contents; - titlebar->_contents = NULL; - titlebar->_nextpp = &(titlebar->_contents); - } -} - -static GfxList *make_titlebar_list(EngineState *s, rect_t bounds, GfxPort *status_bar) { - gfx_color_t color = status_bar->_bgcolor; - GfxList *list; - GfxBox *bgbox; - - - list = gfxw_new_list(status_bar->_bounds, 0); - bgbox = gfxw_new_box(s->gfx_state, gfx_rect(0, 0, status_bar->_bounds.width, status_bar->_bounds.height - 1), - color, color, GFX_BOX_SHADE_FLAT); - - list->add((GfxContainer *) list, (GfxWidget *) bgbox); - - return list; -} - -static GfxList *finish_titlebar_list(EngineState *s, GfxList *list, GfxPort *status_bar) { - gfx_color_t black = s->ega_colors[0]; - GfxPrimitive *line; - - line = gfxw_new_line(Common::Point(0, status_bar->_bounds.height - 1), Common::Point(status_bar->_bounds.width, status_bar->_bounds.height - 1), - black, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL); - list->add((GfxContainer *)list, (GfxWidget *)line); - - return list; -} - -void sciw_set_status_bar(EngineState *s, GfxPort *status_bar, const Common::String &text, int fgcolor, int bgcolor) { - GfxState *state; - GfxList *list; - gfx_color_t bg = status_bar->_bgcolor; - gfx_color_t fg = status_bar->_color; - gfx_color_t black = s->ega_colors[0]; - - if (!status_bar->_visual) { - error("Attempt to change title bar without visual"); - return; - } - - state = status_bar->_visual->_gfxState; - - if (!state) { - error("Attempt to change title bar with stateless visual"); - return; - } - - clear_titlebar(status_bar); - - if (!text.empty()) { - GfxText *textw = gfxw_new_text(state, gfx_rect(0, 0, status_bar->_bounds.width, status_bar->_bounds.height), - status_bar->_font, text.c_str(), ALIGN_LEFT, ALIGN_CENTER, - fg, fg, bg, kFontNoNewlines); - - list = make_titlebar_list(s, status_bar->_bounds, status_bar); - - list->add((GfxContainer *)list, (GfxWidget *)textw); - - } else { - GfxBox *bgbox = gfxw_new_box(state, gfx_rect(0, 0, status_bar->_bounds.width, status_bar->_bounds.height - 1), - black, black, GFX_BOX_SHADE_FLAT); - - list = gfxw_new_list(status_bar->_bounds, 0); - - list->add((GfxContainer *)list, (GfxWidget *)bgbox); - } - - list->add((GfxContainer *)status_bar, list); - finish_titlebar_list(s, list, status_bar); - - status_bar->draw(gfxw_point_zero); - gfxop_update(state); -} - -static void sciw_make_window_fit(rect_t *rect, GfxPort *parent) { - // This window is meant to cover the whole screen, so we allow it to go through. - if (rect->width == 319 && rect->height == 189) - return; - - if (rect->x + rect->width > parent->_bounds.x + parent->_bounds.width) - rect->x -= (rect->x + rect->width) - (parent->_bounds.x + parent->_bounds.width) + 2; - - if (rect->y + rect->height > parent->_bounds.y + parent->_bounds.height) - rect->y -= (rect->y + rect->height) - (parent->_bounds.y + parent->_bounds.height) + 2; -} - -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_bgcolor, - const char *title, int flags) { - GfxVisual *visual = s->visual; - GfxState *state = s->gfx_state; - int shadow_offset = 2; - rect_t frame; - gfx_color_t black; - gfxop_set_color(state, &black, 0, 0, 0, 0, 0, 0); - GfxPort *win; - GfxList *decorations; -// int xextra = !(flags & kWindowNoFrame) ? 1 : 0; -// int yextra = !(flags & kWindowNoFrame) ? 2 : 0; - - if (area.width == 319 && area.height == 189) { - flags |= kWindowNoFrame; - // The below line makes the points bar in QfG2 work, but breaks - // the one in QfG1. Hm. - if ((byte)bgcolor.priority == 255) /* Yep, QfG2 */ - area.y += 3; - } - - /* - if (area.y + area.height > visual->_bounds.y + visual->_bounds.height) { - area.y -= (area.y + area.height) - (visual->_bounds.y + visual->_bounds.height) + yextra; - } - - if (area.x + area.width > visual->_bounds.x + visual->_bounds.width) { - area.x -= (area.x + area.width) - (visual->_bounds.x + visual->_bounds.width) + xextra; - } - */ - - if (flags & kWindowTitle) - area. y += 10; - - if (!(flags & (kWindowTitle | kWindowNoFrame))) - area.height -= 1; // Normal windows are drawn one pixel too small. - - sciw_make_window_fit(&area, s->wm_port); - win = new GfxPort(visual, area, color, bgcolor); - - win->_font = font; - win->_title_text = title ? title : ""; - win->port_flags = flags; - - win->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - - if (flags & kWindowDontDraw) - flags = kWindowTransparent | kWindowNoFrame; - - if (flags == (kWindowTransparent | kWindowNoFrame)) - return win; // Fully transparent window - - if (flags & kWindowTitle) - frame = gfx_rect(area.x - 1, area.y - 10, area.width + 2, area.height + 11); - else - frame = gfx_rect(area.x - 1, area.y - 1, area.width + 2, area.height + 2); - - // Set visible window boundaries - win->_bounds = gfx_rect(frame.x, frame.y, frame.width + shadow_offset, frame.height + shadow_offset); - - decorations = gfxw_new_list(gfx_rect(frame.x, frame.y, frame.width + 1 + shadow_offset, frame.height + 1 + shadow_offset), 0); - - if (!(flags & kWindowTransparent)) { - // Draw window background - win->port_bg = (GfxWidget *)gfxw_new_box(state, gfx_rect(1, (flags & kWindowTitle) ? 10 : 1, - area.width, area.height), bgcolor, bgcolor, GFX_BOX_SHADE_FLAT); - decorations->add((GfxContainer *)decorations, win->port_bg); - win->_flags |= GFXW_FLAG_OPAQUE; - } - - if (flags & kWindowTitle) { - // Add window title - rect_t title_rect = gfx_rect(1, 1, area.width, 8); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_box(state, title_rect, title_bgcolor, title_bgcolor, GFX_BOX_SHADE_FLAT)); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_text(state, title_rect, title_font, title, ALIGN_CENTER, ALIGN_CENTER, title_color, title_color, - title_bgcolor, kFontNoNewlines)); - } - - if (!(flags & kWindowNoFrame)) { - // Draw backdrop shadow - - if (!(flags & kWindowNoDropShadow)) { - gfxop_set_color(state, &black, 0, 0, 0, 0x80, bgcolor.priority, -1); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_box(state, gfx_rect(shadow_offset + 1, frame.height - 1, - frame.width - 4, shadow_offset), black, black, GFX_BOX_SHADE_FLAT)); - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_box(state, gfx_rect(frame.width - 1, shadow_offset + 1, - shadow_offset, frame.height - 2), black, black, GFX_BOX_SHADE_FLAT)); - } - - // Draw frame - - gfxop_set_color(state, &black, 0, 0, 0, 0, bgcolor.priority, -1); - - if (!(flags & kWindowNoDropShadow)) { - - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_rect(gfx_rect(0, 0, frame.width - 1, frame.height - 1), black, GFX_LINE_MODE_FINE, GFX_LINE_STYLE_NORMAL)); - - if (flags & kWindowTitle) - decorations->add((GfxContainer *)decorations, (GfxWidget *)gfxw_new_line(Common::Point(1, 9), - Common::Point(frame.width - 2, 9), black, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } else { - decorations->add((GfxContainer *)decorations, (GfxWidget *) - gfxw_new_rect(gfx_rect(0, 0, frame.width, frame.height), black, GFX_LINE_MODE_FINE, GFX_LINE_STYLE_NORMAL)); - } - } - - win->_decorations = decorations; - decorations->_parent = (GfxContainer *)win; - - return win; -} - -//*** Controls *** - -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, const char *text, - int font, gfx_alignment_t align, char framed, char inverse, int flags, char gray_text) { - gfx_color_t *color1, *color2, *bgcolor; - - if (inverse) { - color1 = color2 = &(port->_bgcolor); - bgcolor = &(port->_color); - } else if (gray_text) { - bgcolor = color1 = &(port->_bgcolor); - color2 = &(port->_color); - } else { - color1 = color2 = &(port->_color); - bgcolor = &(port->_bgcolor); - } - - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, zone, font, text, align, ALIGN_TOP, - *color1, *color2, *bgcolor, flags)); - - zone.width--; - zone.height -= 2; - - if (framed) { - list->add((GfxContainer *)list, gfxw_new_rect(zone, *color2, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_STIPPLED)); - } - - return list; -} - -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; - - zone.x--; - zone.y--; - zone.width++; - zone.height++; - - list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - - gfxw_set_id(list, ID.segment, ID.offset); - - zone.x = 0; - zone.y = 0; - - if (!inverse) { - list = _sciw_add_text_to_list(list, port, gfx_rect(zone.x + 1, zone.y + 2, zone.width - 1, zone.height), - text, font, ALIGN_CENTER, 0, inverse, kFontIgnoreLF, grayed_out); - - list->add((GfxContainer *)list, - gfxw_new_rect(zone, *frame_col, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } else { - list->add((GfxContainer *)list, gfxw_new_box(NULL, gfx_rect(zone.x, zone.y, zone.width + 1, zone.height + 1), - port->_color, port->_color, GFX_BOX_SHADE_FLAT)); - - list = _sciw_add_text_to_list(list, port, gfx_rect(zone.x + 1, zone.y + 2, zone.width - 1, zone.height), - text, font, ALIGN_CENTER, 0, inverse, kFontIgnoreLF, grayed_out); - } - - if (selected) - list->add((GfxContainer *)list, - gfxw_new_rect(gfx_rect(zone.x + 1, zone.y + 1, zone.width - 2, zone.height - 2), - *frame_col, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - - return list; -} - -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); - - gfxw_set_id(list, ID.segment, ID.offset); - - zone.x = 0; - zone.y = 0; - - 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, const char *text, int font, unsigned int cursor, - char inverse) { - GfxText *text_handle; - - GfxList *list; - int cursor_height = port->_visual->_gfxState->gfxResMan->getFont(font)->line_height; - - zone.x--; - zone.y--; - zone.width++; - zone.height++; - - list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - gfxw_set_id(list, ID.segment, ID.offset); - zone.x = 1; - zone.y = 1; - - if ((g_system->getMillis() % 1000) < 500) { - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, text, ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines); - - list->add((GfxContainer *)list, text_handle); - } else { - char *textdup = (char *)malloc(strlen(text) + 1); - - strncpy(textdup, text, cursor); - - if (cursor <= strlen(text)) - textdup[cursor] = 0; // terminate - - if (cursor > 0) { - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, textdup, ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines); - - list->add((GfxContainer *)list, text_handle); - zone.x += text_handle->width; - } - - if (cursor < strlen(text)) { - textdup[0] = text[cursor]; - textdup[1] = 0; - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, textdup, ALIGN_LEFT, ALIGN_TOP, - port->_bgcolor, port->_bgcolor, port->_color, kFontNoNewlines); - list->add((GfxContainer *)list, text_handle); - zone.x += text_handle->width; - }; - - if (cursor + 1 < strlen(text)) { - text_handle = gfxw_new_text(port->_visual->_gfxState, zone, font, text + cursor + 1, ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines); - list->add((GfxContainer *)list, text_handle); - zone.x += text_handle->width; - }; - - if (cursor == strlen(text)) - list->add((GfxContainer *)list, gfxw_new_line(Common::Point(zone.x, zone.y), Common::Point(zone.x, zone.y + cursor_height - 1), - port->_color, GFX_LINE_MODE_FAST, GFX_LINE_STYLE_NORMAL)); - free(textdup); - } - - zone.x = zone.y = 0; - - list->add((GfxContainer *)list, gfxw_new_rect(zone, port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - - return list; -} - -GfxList *sciw_new_icon_control(GfxPort *port, reg_t ID, rect_t zone, int view, int loop, int cel, - char frame, char inverse) { - GfxList *list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - GfxWidget *icon; - gfxw_set_id(list, ID.segment, ID.offset); - - if (!port->_visual) { - error("Attempting to create icon control for virtual port"); - return NULL; - } - - zone.x = 0; - zone.y = 0; - - icon = gfxw_new_view(port->_visual->_gfxState, Common::Point(zone.x, zone.y), view, loop, cel, 0, -1, -1, - ALIGN_LEFT, ALIGN_TOP, GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET); - - if (!icon) { - error("Attempt to create icon control with cel %d/%d/%d (invalid)", view, loop, cel); - return NULL; - } - - list->_flags |= GFXW_FLAG_MULTI_ID; - - list->add((GfxContainer *)list, icon); - - return 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; - - char arr_up[2], arr_down[2]; - int i; - - int font_height; - int columns; - - zone.x--; - zone.y--; - zone.width++; - zone.height++; - - list = gfxw_new_list(_move_and_extend_rect(zone, Common::Point(port->zone.x, port->zone.y), 1), 0); - - font_height = port->_visual->_gfxState->gfxResMan->getFont(font_nr)->line_height; - columns = (zone.height - 20); - - columns /= font_height; - - gfxw_set_id(list, ID.segment, ID.offset); - - arr_up[0] = SCI_SPECIAL_CHAR_ARROW_UP; - arr_down[0] = SCI_SPECIAL_CHAR_ARROW_DOWN; - arr_up[1] = arr_down[1] = 0; - - zone.x = 1; - zone.y = 11; - - // Draw text - - for (i = list_top; columns-- && i < entries_nr; i++) { - if (i != selection) - list->add((GfxContainer *)list, - gfxw_new_text(port->_visual->_gfxState, gfx_rect(zone.x, zone.y, zone.width - 2, font_height), - font_nr, entries_list[i], ALIGN_LEFT, ALIGN_TOP, - port->_color, port->_color, port->_bgcolor, kFontNoNewlines)); - else { - list->add((GfxContainer *)list, gfxw_new_box(port->_visual->_gfxState, gfx_rect(zone.x, zone.y, zone.width - 1, font_height), - port->_color, port->_color, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, gfx_rect(zone.x, zone.y, zone.width - 2, font_height), - font_nr, entries_list[i], ALIGN_LEFT, ALIGN_TOP, - port->_bgcolor, port->_bgcolor, port->_color, kFontNoNewlines)); - } - - zone.y += font_height; - } - - // Draw frames - - zone.x = 0; - zone.y = 0; - - // Add up arrow - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, gfx_rect(1, 0, zone.width - 2, 8), - port->_font, arr_up, ALIGN_CENTER, ALIGN_CENTER, - port->_color, port->_color, port->_bgcolor, 0)); - - // Add down arrow - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, gfx_rect(1, zone.height - 9, zone.width - 2, 8), - port->_font, arr_down, ALIGN_CENTER, ALIGN_CENTER, - port->_color, port->_color, port->_bgcolor, 0)); - - if (list_top & 1) { // Hack to work around aggressive caching - list->add((GfxContainer *)list, gfxw_new_rect(zone, port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - list->add((GfxContainer *)list, gfxw_new_rect(gfx_rect(zone.x, zone.y + 10, zone.width, zone.height - 20), - port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } else { - list->add((GfxContainer *)list, - gfxw_new_rect(gfx_rect(zone.x, zone.y, zone.width, zone.height - 10), - port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - list->add((GfxContainer *)list, - gfxw_new_rect(gfx_rect(zone.x, zone.y + 10, zone.width, zone.height - 10), - port->_color, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - } - - return list; -} - -void sciw_set_menubar(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection) { - GfxList *list = make_titlebar_list(s, status_bar->_bounds, status_bar); - int offset = MENU_LEFT_BORDER; - int i; - - clear_titlebar(status_bar); - - for (i = 0; i < (int)menubar->_menus.size(); i++) { - Menu *menu = &menubar->_menus[i]; - int width = menu->_titleWidth + (MENU_BORDER_SIZE * 2); - - if (i == selection) { - list->add((GfxContainer *)list, gfxw_new_box(status_bar->_visual->_gfxState, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT), - status_bar->_color, status_bar->_color, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_text(s->gfx_state, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT), - status_bar->_font, menu->_title.c_str(), ALIGN_CENTER, ALIGN_CENTER, - status_bar->_bgcolor, status_bar->_bgcolor, status_bar->_color, kFontNoNewlines)); - } else - list->add((GfxContainer *)list, gfxw_new_text(s->gfx_state, gfx_rect(offset, 0, width, MENU_BAR_HEIGHT), - status_bar->_font, menu->_title.c_str(), ALIGN_CENTER, ALIGN_CENTER, - status_bar->_color, status_bar->_color, status_bar->_bgcolor, kFontNoNewlines)); - offset += width; - } - - status_bar->add((GfxContainer *)status_bar, list); - finish_titlebar_list(s, list, status_bar); -} - -GfxPort *sciw_new_menu(EngineState *s, GfxPort *status_bar, Menubar *menubar, int selection) { - GfxPort *retval; - Menu *menu = &menubar->_menus[selection]; - rect_t area = gfx_rect(MENU_LEFT_BORDER, 10, 0, 0); - int i; - - if (selection < -1) - return NULL; - - if (selection >= (int)menubar->_menus.size()) { - error("Attempt to make menu #%d of %d", selection, menubar->_menus.size()); - return NULL; - } - - for (i = 0; i < selection; i++) - area.x += menubar->_menus[i]._titleWidth; - - area.width = menu->_width - 1; - area.height = menu->_items.size() * 10; - - retval = sciw_new_window(s, area, status_bar->_font, status_bar->_color, status_bar->_bgcolor, - 0, status_bar->_color, status_bar->_bgcolor, NULL, kWindowNoDropShadow | kWindowTransparent); - - retval->setVisual(s->visual); - - for (i = 0; i < (int)menu->_items.size(); i++) - sciw_toggle_item(retval, menu, i, false); - - return retval; -} - -#define MAGIC_ID_OFFSET 0x2000 - -static gfx_color_t un_prioritize(gfx_color_t col) { - col.priority = -1; - col.mask &= ~GFX_MASK_PRIORITY; - - return col; -} - -GfxWidget *_make_menu_entry(MenuItem *item, int offset, int width, GfxPort *port, gfx_color_t color, gfx_color_t bgcolor, int ID, int gray) { - rect_t area = gfx_rect(MENU_BOX_LEFT_PADDING, 0, width - MENU_BOX_LEFT_PADDING, 10); - rect_t list_area = gfx_rect(port->zone.x, area.y + offset + port->zone.y, width, area.height); - GfxList *list = (GfxList *) gfxw_set_id(gfxw_new_list(list_area, 0), ID, GFXW_NO_ID); - gfx_color_t xcolor = { PaletteEntry(), 0, 0, 0, 0}; - - color = un_prioritize(color); - bgcolor = un_prioritize(bgcolor); - - xcolor = gray ? color : bgcolor; - - list->add((GfxContainer *)list, gfxw_new_box(port->_visual->_gfxState, area, bgcolor, bgcolor, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, area, port->_font, item->_text.c_str(), ALIGN_LEFT, ALIGN_CENTER, - color, xcolor, bgcolor, kFontNoNewlines)); - - if (!item->_keytext.empty()) { - area.width -= MENU_BOX_RIGHT_PADDING; - list->add((GfxContainer *)list, gfxw_new_text(port->_visual->_gfxState, area, port->_font, item->_keytext.c_str(), ALIGN_RIGHT, ALIGN_CENTER, - color, xcolor, bgcolor, kFontNoNewlines)); - } - - return list; -} - -GfxWidget *_make_menu_hbar(int offset, int width, GfxPort *port, gfx_color_t color, gfx_color_t bgcolor, int ID) { - rect_t area = gfx_rect(0, 0, width, 10); - rect_t list_area = gfx_rect(area.x + port->zone.x, area.y + offset + port->zone.y, area.width, area.height); - GfxList *list = (GfxList *) gfxw_set_id(gfxw_new_list(list_area, 0), ID, GFXW_NO_ID); - - color = un_prioritize(color); - bgcolor = un_prioritize(bgcolor); - - list->add((GfxContainer *)list, gfxw_new_box(port->_visual->_gfxState, area, bgcolor, bgcolor, GFX_BOX_SHADE_FLAT)); - list->add((GfxContainer *)list, gfxw_new_line(Common::Point(0, 5), Common::Point(width, 5), color, - GFX_LINE_MODE_FAST, GFX_LINE_STYLE_STIPPLED)); - - return list; -} - -GfxPort *sciw_toggle_item(GfxPort *menu_port, Menu *menu, int selection, bool selected) { - if (selection < 0 || selection >= (int)menu->_items.size()) - return menu_port; - - gfx_color_t fgColor = !selected ? menu_port->_color : menu_port->_bgcolor; - gfx_color_t bgColor = !selected ? menu_port->_bgcolor : menu_port->_color; - - MenuItem *item = &menu->_items[selection]; - - if (item->_type == MENU_TYPE_NORMAL) - menu_port->add((GfxContainer *)menu_port, _make_menu_entry(item, selection * 10, menu_port->zone.width + 1, - menu_port, fgColor, bgColor, selection + MAGIC_ID_OFFSET, item->_enabled)); - else - menu_port->add((GfxContainer *)menu_port, _make_menu_hbar(selection * 10, menu_port->zone.width + 1, - menu_port, fgColor, bgColor, selection + MAGIC_ID_OFFSET)); - - return menu_port; -} - -void _k_view_list_mark_free(EngineState *s, reg_t off) { - if (s->dyn_views) { - - GfxDynView *w = (GfxDynView *)s->dyn_views->_contents; - - while (w) { - if (w->_ID == off.segment - && w->_subID == off.offset) { - w->under_bitsp.obj = NULL_REG; - } - - w = (GfxDynView *)w->_next; - } - } -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_gui.h b/engines/sci/gfx/gfx_gui.h deleted file mode 100644 index be724ae873..0000000000 --- a/engines/sci/gfx/gfx_gui.h +++ /dev/null @@ -1,225 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_INCLUDE_SCI_WIDGETS_H -#define SCI_INCLUDE_SCI_WIDGETS_H - -#include "sci/engine/state.h" - -namespace Sci { - -class Menu; - -/* SCI-specific widget handling */ - -/** - * Flags for windows in SCI0. - */ -enum windowFlags { - 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 -}; - -/** - * 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 - -#endif // SCI_INCLUDE_SCI_WIDGETS_H - -#endif diff --git a/engines/sci/gfx/gfx_pixmap_scale.cpp b/engines/sci/gfx/gfx_pixmap_scale.cpp deleted file mode 100644 index d542683cee..0000000000 --- a/engines/sci/gfx/gfx_pixmap_scale.cpp +++ /dev/null @@ -1,133 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -/* Required defines: -** FUNCNAME: Function name -** SIZETYPE: Type used for each pixel -*/ - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - - -// TODO: Replace this code with our common scalers (/graphics/scaler.h) - - -static void _gfx_xlate_pixmap_unfiltered(gfx_mode_t *mode, gfx_pixmap_t *pxm, int scale) { - byte result_colors[GFX_PIC_COLORS]; - int scaleFactor = (scale) ? mode->scaleFactor : 1; - int widthc, heightc; // Width duplication counter - int line_width = scaleFactor * pxm->index_width; - int x, y; - int i; - byte byte_transparent = 0; - byte byte_opaque = 255; - byte *src = pxm->index_data; - byte *dest = pxm->data; - byte *alpha_dest = pxm->alpha_map; - int using_alpha = pxm->color_key != GFX_PIXMAP_COLOR_KEY_NONE; - int separate_alpha_map = using_alpha; - - if (separate_alpha_map && !alpha_dest) - alpha_dest = pxm->alpha_map = (byte *)malloc(pxm->index_width * scaleFactor * pxm->index_height * scaleFactor); - - // Calculate all colors - for (i = 0; i < pxm->colors_nr(); i++) - result_colors[i] = pxm->palette->getColor(i).getParentIndex(); - - if (!separate_alpha_map && pxm->color_key != GFX_PIXMAP_COLOR_KEY_NONE) - result_colors[pxm->color_key] = 0; - - src = pxm->index_data; // Workaround for gcc 4.2.3 bug on EMT64 - for (y = 0; y < pxm->index_height; y++) { - byte *prev_dest = dest; - byte *prev_alpha_dest = alpha_dest; - - for (x = 0; x < pxm->index_width; x++) { - int isalpha; - byte col = result_colors[isalpha = *src++]; - isalpha = (isalpha == pxm->color_key) && using_alpha; - - // O(n) loops. There is an O(ln(n)) algorithm for this, but its slower for small n (which we're optimizing for here). - // And, anyway, most of the time is spent in memcpy() anyway. - - for (widthc = 0; widthc < scaleFactor; widthc++) { - memcpy(dest, &col, 1); - dest++; - } - - if (separate_alpha_map) { // Set separate alpha map - memset(alpha_dest, (isalpha) ? byte_transparent : byte_opaque, scaleFactor); - alpha_dest += scaleFactor; - } - } - - // Copies each line. O(n) iterations; again, this could be optimized to O(ln(n)) for very high resolutions, - // but that wouldn't really help that much, as the same amount of data still would have to be transferred. - for (heightc = 1; heightc < scaleFactor; heightc++) { - memcpy(dest, prev_dest, line_width); - dest += line_width; - if (separate_alpha_map) { - memcpy(alpha_dest, prev_alpha_dest, line_width); - alpha_dest += line_width; - } - } - } - - pxm->width = pxm->index_width; - pxm->height = pxm->index_height; -} - - -void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode) { - if (pxm->palette && pxm->palette != mode->palette) - pxm->palette->mergeInto(mode->palette); - - if (!pxm->data) { - pxm->data = (byte*)malloc(mode->scaleFactor * mode->scaleFactor * pxm->index_width * pxm->index_height + 1); - // +1: Eases coying on BE machines in 24 bpp packed mode - // Assume that memory, if allocated already, will be sufficient - - // Allocate alpha map - if (pxm->colors_nr() < GFX_PIC_COLORS) - pxm->alpha_map = (byte*)malloc(mode->scaleFactor * mode->scaleFactor * pxm->index_width * pxm->index_height + 1); - } - - _gfx_xlate_pixmap_unfiltered(mode, pxm, false); - - if (pxm->palette) - pxm->palette_revision = pxm->palette->getRevision(); -} - - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_resmgr.cpp b/engines/sci/gfx/gfx_resmgr.cpp deleted file mode 100644 index f78f5980e9..0000000000 --- a/engines/sci/gfx/gfx_resmgr.cpp +++ /dev/null @@ -1,532 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -// Resource manager core part - -// FIXME/TODO: The name "(Graphics) resource manager", and the associated -// filenames, are misleading. This should be renamed to "Graphics manager" -// or something like that. - -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gfx/gfx_resmgr.h" -#include "sci/gui/gui_palette.h" -#include "sci/gui/gui_screen.h" -#include "sci/gui/gui_view.h" -#include "sci/gfx/gfx_driver.h" -#include "sci/gfx/gfx_state_internal.h" -#include "sci/gui32/font.h" - -#include "common/system.h" - -namespace Sci { - -struct param_struct { - int args[4]; - GfxDriver *driver; -}; - -GfxResManager::GfxResManager(GfxDriver *driver, ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, Common::Rect portBounds) : - _driver(driver), _resMan(resMan), _screen(screen), _palette(palette), - _lockCounter(0), _tagLockCounter(0), _staticPalette(0) { - gfxr_init_static_palette(); - - _portBounds = portBounds; - - if (!_resMan->isVGA()) { - _staticPalette = gfx_sci0_pic_colors->getref(); - } else if (getSciVersion() == SCI_VERSION_1_1) { - debugC(2, kDebugLevelGraphics, "Palettes are not yet supported in this SCI version\n"); -#ifdef ENABLE_SCI32 - } else if (getSciVersion() >= SCI_VERSION_2) { - debugC(2, kDebugLevelGraphics, "Palettes are not yet supported in this SCI version\n"); -#endif - } else { - Resource *res = resMan->findResource(ResourceId(kResourceTypePalette, 999), 0); - if (res && res->data) - _staticPalette = gfxr_read_pal1(res->id.number, res->data, res->size); - } -} - -GfxResManager::~GfxResManager() { - _staticPalette->free(); - _staticPalette = 0; -} - -void GfxResManager::calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, int flags, int default_palette, int nr) { - Resource *res = _resMan->findResource(ResourceId(kResourceTypePic, nr), 0); - int need_unscaled = unscaled_pic != NULL; - gfxr_pic0_params_t style, basic_style; - - basic_style.line_mode = GFX_LINE_MODE_CORRECT; - basic_style.brush_mode = GFX_BRUSH_MODE_SCALED; - style.line_mode = GFX_LINE_MODE_CORRECT; - style.brush_mode = GFX_BRUSH_MODE_RANDOM_ELLIPSES; - - if (!res || !res->data) - error("calculatePic(): pic number %d not found", nr); - - if (need_unscaled) { - if (_resMan->getViewType() == kViewVga11) - gfxr_draw_pic11(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _staticPalette, _portBounds); - else - gfxr_draw_pic01(unscaled_pic, flags, default_palette, res->size, res->data, &basic_style, res->id.number, _resMan->getViewType(), _staticPalette, _portBounds); - } - - if (scaled_pic && scaled_pic->undithered_buffer) - memcpy(scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer, scaled_pic->undithered_buffer_size); - - if (_resMan->getViewType() == kViewVga11) - gfxr_draw_pic11(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _staticPalette, _portBounds); - else - gfxr_draw_pic01(scaled_pic, flags, default_palette, res->size, res->data, &style, res->id.number, _resMan->getViewType(), _staticPalette, _portBounds); - - if (getSciVersion() <= SCI_VERSION_1_EGA) { - if (need_unscaled) - gfxr_remove_artifacts_pic0(scaled_pic, unscaled_pic); - - if (!scaled_pic->undithered_buffer) - scaled_pic->undithered_buffer = malloc(scaled_pic->undithered_buffer_size); - - memcpy(scaled_pic->undithered_buffer, scaled_pic->visual_map->index_data, scaled_pic->undithered_buffer_size); - - gfxr_dither_pic0(scaled_pic, kDitherNone); - } - - // Mark default palettes - if (scaled_pic) - scaled_pic->visual_map->loop = default_palette; - - if (unscaled_pic) - unscaled_pic->visual_map->loop = default_palette; -} - -#define FREEALL(freecmd, type) \ - if (resource->scaled_data.type) \ - freecmd(resource->scaled_data.type); \ - resource->scaled_data.type = NULL; \ - if (resource->unscaled_data.type) \ - freecmd(resource->unscaled_data.type); \ - resource->unscaled_data.type = NULL; - -void gfxr_free_resource(gfx_resource_t *resource, int type) { - if (!resource) - return; - - switch (type) { - - case GFX_RESOURCE_TYPE_VIEW: - FREEALL(gfxr_free_view, view); - break; - - case GFX_RESOURCE_TYPE_PIC: - FREEALL(gfxr_free_pic, pic); - break; - - case GFX_RESOURCE_TYPE_FONT: - FREEALL(gfxr_free_font, font); - break; - - case GFX_RESOURCE_TYPE_CURSOR: - FREEALL(gfx_free_pixmap, pointer); - break; - - default: - warning("[GFX] Attempt to free invalid resource type %d", type); - } - - free(resource); -} - -void GfxResManager::freeAllResources() { - for (int type = 0; type < GFX_RESOURCE_TYPES_NR; ++type) { - for (IntResMap::iterator iter = _resourceMaps[type].begin(); iter != _resourceMaps[type].end(); ++iter) { - gfxr_free_resource(iter->_value, type); - iter->_value = 0; - } - } -} - -void GfxResManager::freeResManager() { - freeAllResources(); - _lockCounter = _tagLockCounter = 0; -} - -void GfxResManager::freeTaggedResources() { - // Current heuristics: free tagged views and old pics - - IntResMap::iterator iter; - int type; - const int tmp = _tagLockCounter; - - type = GFX_RESOURCE_TYPE_VIEW; - for (iter = _resourceMaps[type].begin(); iter != _resourceMaps[type].end(); ++iter) { - gfx_resource_t *resource = iter->_value; - - if (resource) { - if (resource->lock_sequence_nr < tmp) { - gfxr_free_resource(resource, type); - iter->_value = 0; - } else { - resource->lock_sequence_nr = 0; - } - } - } - - type = GFX_RESOURCE_TYPE_PIC; - for (iter = _resourceMaps[type].begin(); iter != _resourceMaps[type].end(); ++iter) { - gfx_resource_t *resource = iter->_value; - - if (resource) { - if (resource->lock_sequence_nr < 0) { - gfxr_free_resource(resource, type); - iter->_value = 0; - } else { - resource->lock_sequence_nr--; - } - } - } - - _tagLockCounter = 0; -} - - -void GfxResManager::setStaticPalette(Palette *newPalette) -{ - if (_staticPalette) - _staticPalette->free(); - - _staticPalette = newPalette; - _staticPalette->name = "static palette"; - - if (_driver->getMode()->palette) - _staticPalette->mergeInto(_driver->getMode()->palette); -} - -#if 0 -// FIXME: the options for GFX_MASK_VISUAL are actually unused -#define XLATE_AS_APPROPRIATE(key, entry) \ - if (maps & key) { \ - if (res->unscaled_data.pic&& (force || !res->unscaled_data.pic->entry->data)) { \ - if (key == GFX_MASK_VISUAL) \ - gfx_get_res_config(options->res_conf, res->unscaled_data.pic->entry); \ - gfx_xlate_pixmap(res->unscaled_data.pic->entry, mode, filter); \ - } if (scaled && res->scaled_data.pic && (force || !res->scaled_data.pic->entry->data)) { \ - if (key == GFX_MASK_VISUAL) \ - gfx_get_res_config(options->res_conf, res->scaled_data.pic->entry); \ - gfx_xlate_pixmap(res->scaled_data.pic->entry, mode, filter); \ - } \ - } -#endif - -#define XLATE_AS_APPROPRIATE(key, entry) \ - if (maps & key) { \ - if (res->unscaled_data.pic&& (force || !res->unscaled_data.pic->entry->data)) { \ - gfx_xlate_pixmap(res->unscaled_data.pic->entry, mode); \ - } if (scaled && res->scaled_data.pic && (force || !res->scaled_data.pic->entry->data)) { \ - gfx_xlate_pixmap(res->scaled_data.pic->entry, mode); \ - } \ - } - -static gfxr_pic_t *gfxr_pic_xlate_common(gfx_resource_t *res, int maps, int scaled, int force, gfx_mode_t *mode) { - - XLATE_AS_APPROPRIATE(GFX_MASK_VISUAL, visual_map); - XLATE_AS_APPROPRIATE(GFX_MASK_PRIORITY, priority_map); - XLATE_AS_APPROPRIATE(GFX_MASK_CONTROL, control_map); - - return scaled ? res->scaled_data.pic : res->unscaled_data.pic; -} -#undef XLATE_AS_APPROPRIATE - -/* unscaled color index mode: Used in addition to a scaled mode -** to render the pic resource twice. -*/ -// FIXME: this is an ugly hack. Perhaps we could do it some other way? -gfx_mode_t mode_1x1_color_index = { /* Fake 1x1 mode */ - /* scaleFactor */ 1, - /* xsize */ 1, /* ysize */ 1, - /* palette */ NULL -}; - -gfxr_pic_t *GfxResManager::getPic(int num, int maps, int flags, int default_palette, bool scaled) { - gfxr_pic_t *npic = NULL; - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_PIC]; - gfx_resource_t *res = NULL; - int need_unscaled = (_driver->getMode()->scaleFactor != 1); - - res = resMap.contains(num) ? resMap[num] : NULL; - - if (!res) { - gfxr_pic_t *pic = NULL; - gfxr_pic_t *unscaled_pic = NULL; - - need_unscaled = 0; - pic = gfxr_init_pic(_driver->getMode(), GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resMan->isVGA()); - - if (!pic) { - error("Failed to allocate scaled pic"); - return NULL; - } - - gfxr_clear_pic0(pic, SCI_TITLEBAR_SIZE); - - if (need_unscaled) { - unscaled_pic = gfxr_init_pic(&mode_1x1_color_index, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num), _resMan->isVGA()); - if (!unscaled_pic) { - error("Failed to allocate unscaled pic"); - return NULL; - } - gfxr_clear_pic0(pic, SCI_TITLEBAR_SIZE); - } - - calculatePic(pic, unscaled_pic, flags, default_palette, num); - - if (!res) { - res = (gfx_resource_t *)malloc(sizeof(gfx_resource_t)); - res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, num); - res->lock_sequence_nr = 0; - resMap[num] = res; - } else { - gfxr_free_pic(res->scaled_data.pic); - if (res->unscaled_data.pic) - gfxr_free_pic(res->unscaled_data.pic); - } - - res->scaled_data.pic = pic; - res->unscaled_data.pic = unscaled_pic; - } else { - res->lock_sequence_nr = 0; - } - - npic = gfxr_pic_xlate_common(res, maps, 1, 0, _driver->getMode()); - - return npic; -} - -static void set_pic_id(gfx_resource_t *res, int id) { - if (res->scaled_data.pic) { - gfxr_pic_t *pic = res->scaled_data.pic; - pic->control_map->ID = id; - pic->priority_map->ID = id; - pic->visual_map->ID = id; - } - - if (res->unscaled_data.pic) { - gfxr_pic_t *pic = res->unscaled_data.pic; - pic->control_map->ID = id; - pic->priority_map->ID = id; - pic->visual_map->ID = id; - } -} - -static int get_pic_id(gfx_resource_t *res) { - if (res->scaled_data.pic) - return res->scaled_data.pic->visual_map->ID; - else - return res->unscaled_data.pic->visual_map->ID; -} - -gfxr_pic_t *GfxResManager::addToPic(int old_nr, int new_nr, int flags, int old_default_palette, int default_palette) { - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_PIC]; - gfxr_pic_t *pic = NULL; - gfx_resource_t *res = NULL; - int need_unscaled = 1; - - res = resMap.contains(old_nr) ? resMap[old_nr] : NULL; - - if (!res) { - getPic(old_nr, 0, flags, old_default_palette, 1); - - res = resMap.contains(old_nr) ? resMap[old_nr] : NULL; - - if (!res) { - warning("[GFX] Attempt to add pic %d to non-existing pic %d", new_nr, old_nr); - return NULL; - } - } - - // The following two operations are needed when returning scaled maps (which is always the case here) - res->lock_sequence_nr = 0; - calculatePic(res->scaled_data.pic, need_unscaled ? res->unscaled_data.pic : NULL, - flags | DRAWPIC01_FLAG_OVERLAID_PIC, default_palette, new_nr); - - { - int old_ID = get_pic_id(res); - set_pic_id(res, GFXR_RES_ID(GFX_RESOURCE_TYPE_PIC, new_nr)); // To ensure that our graphical translation options work properly - pic = gfxr_pic_xlate_common(res, GFX_MASK_VISUAL, 1, 1, _driver->getMode()); - set_pic_id(res, old_ID); - } - - return pic; -} - -gfxr_view_t *GfxResManager::getView(int nr, int *loop, int *cel, int palette) { - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_VIEW]; - gfx_resource_t *res = resMap.contains(nr) ? resMap[nr] : NULL; - ViewType viewType = _resMan->getViewType(); - - gfxr_view_t *view = NULL; - gfxr_loop_t *loop_data = NULL; - gfx_pixmap_t *cel_data = NULL; - - if (!res) { - // Wrapper code for the new view decoder - view = (gfxr_view_t *)malloc(sizeof(gfxr_view_t)); - - view->ID = nr; - view->flags = 0; - - SciGuiView *guiView = new SciGuiView(_resMan, _screen, _palette, nr); - - // Translate view palette - view->palette = NULL; - - if (viewType == kViewVga || viewType == kViewVga11) { - GuiPalette *viewPalette = guiView->getPalette(); - if (viewPalette) { - view->palette = new Palette(256); - for (int c = 0; c < 256; c++) - view->palette->setColor(c, viewPalette->colors[c].r, viewPalette->colors[c].g, viewPalette->colors[c].b); - } - - // Assign missing colors from the view's palette to the global palette ones - for (unsigned i = 0; i < MIN(view->palette->size(), _staticPalette->size()); i++) { - const PaletteEntry& vc = view->palette->getColor(i); - if (vc.r == 0 && vc.g == 0 && vc.b == 0) { - const PaletteEntry& sc = _staticPalette->getColor(i); - view->palette->setColor(i, sc.r, sc.g, sc.b); - } - } - } else { - view->palette = _staticPalette->getref(); - } - - view->loops_nr = guiView->getLoopCount(); - view->loops = (gfxr_loop_t*)malloc(sizeof(gfxr_loop_t) * ((view->loops_nr) ? view->loops_nr : 1)); /* Alloc 1 if no loop */ - - for (int i = 0; i < view->loops_nr; i++) { - view->loops[i].cels_nr = guiView->getLoopInfo(i)->celCount; - view->loops[i].cels = (gfx_pixmap_t**)calloc(view->loops[i].cels_nr, sizeof(gfx_pixmap_t *)); - - for (int j = 0; j < view->loops[i].cels_nr; j++) { - sciViewCelInfo *celInfo = guiView->getCelInfo(i, j); - view->loops[i].cels[j] = gfx_pixmap_alloc_index_data(gfx_new_pixmap(celInfo->width, celInfo->height, nr, i, j)); - gfx_pixmap_t *curCel = view->loops[i].cels[j]; - curCel->color_key = celInfo->clearKey; - // old code uses malloc() here, so we do so as well, as the buffer will be freed with free() in gfx_free_pixmap - curCel->index_data = (byte *)malloc(celInfo->width * celInfo->height); - byte *tmpBuffer = guiView->getBitmap(i, j); - memcpy(curCel->index_data, tmpBuffer, celInfo->width * celInfo->height); - curCel->flags = 0; - curCel->width = celInfo->width; - curCel->height = celInfo->height; - curCel->index_width = celInfo->width; - curCel->index_height = celInfo->height; - curCel->palette_revision = -1; - curCel->xoffset = -celInfo->displaceX; - curCel->yoffset = -celInfo->displaceY; - curCel->palette = view->palette->getref(); - curCel->alpha_map = 0; // will be allocated by gfx_xlate_pixmap() - curCel->data = 0; // will be allocated by gfx_xlate_pixmap() - } - } - - delete guiView; - - if (!res) { - res = (gfx_resource_t *)malloc(sizeof(gfx_resource_t)); - res->scaled_data.view = NULL; - res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_VIEW, nr); - res->lock_sequence_nr = _tagLockCounter; - resMap[nr] = res; - } else { - gfxr_free_view(res->unscaled_data.view); - } - - res->unscaled_data.view = view; - - } else { - res->lock_sequence_nr = _tagLockCounter; // Update lock counter - view = res->unscaled_data.view; - } - - *loop = CLIP<int>(*loop, 0, view->loops_nr - 1); - loop_data = view->loops + (*loop); - *cel = CLIP<int>(*cel, 0, loop_data->cels_nr - 1); - cel_data = loop_data->cels[*cel]; - - if (!cel_data->data) { - gfx_xlate_pixmap(cel_data, _driver->getMode()); - } - - return view; -} - -gfx_bitmap_font_t *GfxResManager::getFont(int num, bool scaled) { - IntResMap &resMap = _resourceMaps[GFX_RESOURCE_TYPE_FONT]; - gfx_resource_t *res = NULL; - - // Workaround: lsl1sci mixes its own internal fonts with the global - // SCI ones, so we translate them here, by removing their extra bits - if (!resMap.contains(num) && !_resMan->testResource(ResourceId(kResourceTypeFont, num))) - num = num & 0x7ff; - - res = resMap.contains(num) ? resMap[num] : NULL; - - if (!res) { - Resource *fontRes = _resMan->findResource(ResourceId(kResourceTypeFont, num), 0); - if (!fontRes || !fontRes->data) - return NULL; - - gfx_bitmap_font_t *font = gfxr_read_font(fontRes->id.number, fontRes->data, fontRes->size); - - if (!res) { - res = (gfx_resource_t *)malloc(sizeof(gfx_resource_t)); - res->scaled_data.font = NULL; - res->ID = GFXR_RES_ID(GFX_RESOURCE_TYPE_FONT, num); - res->lock_sequence_nr = _tagLockCounter; - resMap[num] = res; - } else { - gfxr_free_font(res->unscaled_data.font); - } - - res->unscaled_data.font = font; - - return font; - } else { - res->lock_sequence_nr = _tagLockCounter; // Update lock counter - if (res->unscaled_data.pointer) - return res->unscaled_data.font; - else - return res->scaled_data.font; - } -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_resmgr.h b/engines/sci/gfx/gfx_resmgr.h deleted file mode 100644 index 5b3b728702..0000000000 --- a/engines/sci/gfx/gfx_resmgr.h +++ /dev/null @@ -1,289 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_RESMAN_H -#define SCI_GFX_GFX_RESMAN_H - -#include "common/hashmap.h" -#include "common/rect.h" - -// FIXME/TODO: The name "(Graphics) resource manager", and the associated -// filenames, are misleading. This should be renamed to "Graphics manager" -// or something like that. - -#include "sci/gfx/gfx_resource.h" - -#include "sci/resource.h" - -namespace Sci { - -struct gfx_bitmap_font_t; -class ResourceManager; -class SciGuiPalette; - -enum gfx_resource_type_t { - GFX_RESOURCE_TYPE_VIEW = 0, - GFX_RESOURCE_TYPE_PIC, - GFX_RESOURCE_TYPE_FONT, - GFX_RESOURCE_TYPE_CURSOR, - GFX_RESOURCE_TYPE_PALETTE, - /* FIXME: Add PAL resource */ - - GFX_RESOURCE_TYPES_NR /**< Number of resource types that are to be supported */ -}; - -#define GFX_RESOURCE_TYPE_0 GFX_RESOURCE_TYPE_VIEW - -#define GFXR_RES_ID(type, index) ((type) << 16 | (index)) -#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 */ - - /** Scaled pic */ - union { - gfx_pixmap_t *pointer; - gfxr_view_t *view; - gfx_bitmap_font_t *font; - gfxr_pic_t *pic; - } scaled_data; - - /** Original pic */ - union { - gfx_pixmap_t *pointer; - gfxr_view_t *view; - gfx_bitmap_font_t *font; - gfxr_pic_t *pic; - } unscaled_data; - -}; - - -struct gfx_options_t; - -typedef Common::HashMap<int, gfx_resource_t *> IntResMap; - -/** Graphics resource manager */ -class GfxResManager { -public: - GfxResManager(GfxDriver *driver, ResourceManager *resMan, SciGuiScreen *screen, SciGuiPalette *palette, Common::Rect portBounds); - ~GfxResManager(); - - - /** - * 'Tags' all resources for deletion. - * - * Tagged resources are untagged if they are referenced. - */ - void tagResources() { _tagLockCounter++; } - - - /** - * 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. - * - * @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. - * - * @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 - */ - void calculatePic(gfxr_pic_t *scaled_pic, gfxr_pic_t *unscaled_pic, - int flags, int default_palette, int nr); - - - /** - * Frees all resources currently allocated. - * - * This function is intended to be used primarily for debugging. - */ - void freeAllResources(); - - - /** - * 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. - */ - void freeResManager(); - - /** - * 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 - */ - void setStaticPalette(Palette *newPalette); - - /** - * Sets the picture port bounds - */ - void changePortBounds(int x1, int y1, int x2, int y2) { - _portBounds = Common::Rect(x1, y1, x2, y2); - } - -#if 0 - void setPaletteIntensity(int16 from, int16 to, int16 intensity) { - Palette *pal = _staticPalette->getref(); - - for (uint16 i = 0; i < _driver->getMode()->palette->size(); i++) { - byte r = pal->getColor(i).r * intensity / 100; - byte g = pal->getColor(i).g * intensity / 100; - byte b = pal->getColor(i).b * intensity / 100; - pal->makeSystemColor(i, PaletteEntry(r, g, b)); - } - pal->mergeInto(_driver->getMode()->palette); - _driver->install_palette(_driver, pal); - pal->unmerge(); - pal->free(); - } -#endif - - /** - * Gets the number of colors in the static palette. - * - * @return Number of pallete entries - */ - int getColorCount() { - return _staticPalette ? _staticPalette->size() : 0; - } - -private: - 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 */ - Common::Rect _portBounds; - - IntResMap _resourceMaps[GFX_RESOURCE_TYPES_NR]; - ResourceManager *_resMan; - SciGuiScreen *_screen; - SciGuiPalette *_palette; -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_RESMAN_H - -#endif diff --git a/engines/sci/gfx/gfx_resource.cpp b/engines/sci/gfx/gfx_resource.cpp deleted file mode 100644 index 4a39b0d385..0000000000 --- a/engines/sci/gfx/gfx_resource.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - -static void gfxr_free_loop(gfxr_loop_t *loop) { - int i; - - if (loop->cels) { - for (i = 0; i < loop->cels_nr; i++) - if (loop->cels[i]) - gfx_free_pixmap(loop->cels[i]); - - free(loop->cels); - } -} - -void gfxr_free_view(gfxr_view_t *view) { - int i; - - if (view->palette) - view->palette->free(); - - if (view->loops) { - for (i = 0; i < view->loops_nr; i++) - gfxr_free_loop(view->loops + i); - - free(view->loops); - } - free(view); -} - -void gfxr_free_pic(gfxr_pic_t *pic) { - gfx_free_pixmap(pic->visual_map); - gfx_free_pixmap(pic->priority_map); - gfx_free_pixmap(pic->control_map); - pic->visual_map = NULL; - pic->priority_map = NULL; - pic->control_map = NULL; - free(pic->priorityTable); - pic->priorityTable = NULL; - free(pic->undithered_buffer); - pic->undithered_buffer = 0; - free(pic); -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_resource.h b/engines/sci/gfx/gfx_resource.h deleted file mode 100644 index d3f1c727a5..0000000000 --- a/engines/sci/gfx/gfx_resource.h +++ /dev/null @@ -1,289 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -/** @file gfx_resource.h - * SCI Resource library. - */ - -#ifndef SCI_GFX_GFX_RESOURCE_H -#define SCI_GFX_GFX_RESOURCE_H - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_driver.h" -#include "sci/gui/gui_helpers.h" - -#include "common/rect.h" - -namespace Common { - class File; -} - -namespace Sci { - -/*** Styles for pic0 drawing ***/ -/* Dithering modes for SCI0 games */ -enum DitherMode { - kDitherNone = 0, // No dithering - kDither16Colors = 1, // Sierra SCI style - kDither256Colors = 2 // Enhanced style -}; - -#define SCI_TITLEBAR_SIZE 10 - -#define DRAWPIC01_FLAG_FILL_NORMALLY 1 -#define DRAWPIC01_FLAG_OVERLAID_PIC 2 -#define DRAWPIC1_FLAG_MIRRORED 4 - -#define GFXR_AUX_MAP_SIZE (320*200) - - -#define GFX_SCI0_IMAGE_COLORS_NR 16 -#define GFX_SCI0_PIC_COLORS_NR 256 - -#define GFX_SCI1_AMIGA_COLORS_NR 32 - -extern int sci0_palette; - -/** The 16 EGA base colors */ -extern Palette* gfx_sci0_image_pal[]; -extern PaletteEntry gfx_sci0_image_colors[][16]; - -/** - * 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) */ - gfx_mode_t *mode; - 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]; - - // rect_t bounds; // unused - - 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; /**< 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; - - int flags; - Palette *palette; - - int loops_nr; - gfxr_loop_t *loops; -}; - -/** - * Initializes the static 256 color palette. - */ -void gfxr_init_static_palette(); - -/** @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 */ -/** @{ */ - -/** - * 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] viewType The view type for embedded views - * @param[in] static_pal The static palette - * @param[in] portBounds The bounds of the port being drawn to - */ -void gfxr_draw_pic01(gfxr_pic_t *pic, int fill_normally, - int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, ViewType viewType, - Palette *static_pal, Common::Rect portBounds); - -/** - * 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); - -/** - * Dithers a gfxr_visual_map. - * - * @param[in] pic The pic to dither - * @param[DitherMode] mode The dithering mode to use - */ -void gfxr_dither_pic0(gfxr_pic_t *pic, DitherMode mode); - -/** @} */ - - -/** @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. - * - * @param[in] file Palette file - * @return Palette with the colors - */ -Palette *gfxr_read_pal1_amiga(Common::File &file); - -/** - * 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); - -gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, ViewType viewType); -/** @} */ - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_RESOURCE_H - -#endif diff --git a/engines/sci/gfx/gfx_state_internal.h b/engines/sci/gfx/gfx_state_internal.h deleted file mode 100644 index ec8219dc46..0000000000 --- a/engines/sci/gfx/gfx_state_internal.h +++ /dev/null @@ -1,417 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_STATE_INTERNAL_H -#define SCI_GFX_GFX_STATE_INTERNAL_H - -#include "sci/engine/vm.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gfx/operations.h" -#include "sci/gfx/gfx_resmgr.h" -#include "sci/gfx/gfx_system.h" - -namespace Sci { - -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 */ - rect_t area; -}; - -enum gfxw_widget_type_t { - GFXW_, /**< Base widget */ - - GFXW_BOX, - GFXW_RECT, - GFXW_LINE, /* For lines, the bounding rectangle's xl, yl determine the line's expansion: - ** (x2, y2) = (x+xl, y+yl) */ - GFXW_VIEW, - GFXW_STATIC_VIEW, - GFXW_DYN_VIEW, - GFXW_PIC_VIEW, - GFXW_TEXT, - - GFXW_CONTAINER, - - GFXW_LIST, - GFXW_SORTED_LIST, - GFXW_VISUAL, - GFXW_PORT -}; - - -#define GFXW_MAGIC_VALID 0xC001 -#define GFXW_MAGIC_INVALID 0xbad - -#define GFXW_NO_ID -1 - -struct GfxWidget; -struct GfxContainer; -struct GfxVisual; -struct GfxPort; - -typedef int gfxw_bin_op(GfxWidget *, GfxWidget *); - -/** SCI graphics widget */ -struct GfxWidget { -public: - int _magic; /**< Extra check after typecasting */ - int _serial; /**< Serial number */ - int _flags; /**< Widget flags */ - gfxw_widget_type_t _type; - rect_t _bounds; /**< Boundaries */ - GfxWidget *_next; /**< Next widget in widget list */ - int _ID; /**< Unique ID or GFXW_NO_ID */ - int _subID; /**< A 'sub-ID', or GFXW_NO_ID */ - GfxContainer *_parent; /**< The parent widget, or NULL if not owned */ - GfxVisual *_visual; /**< The owner visual */ - int _widgetPriority; /**< Drawing priority, or -1 */ - -public: - GfxWidget(gfxw_widget_type_t type); - - /** - * The widget automatically removes itself from its owner, if it has one. - * 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. - * - * @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! - */ - virtual void tag() { - _flags |= GFXW_FLAG_TAGGED; - } - - /** - * Prints a string representation of the widget with printf. - * - * Will recursively print all of the widget's contents if the widget - * contains further sub-widgets - * - * @param[in] indentation Number of double spaces to indent - */ - virtual void print(int indentation) const; - - /** - * Compares two comparable widgets by their screen position. - * - * 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 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. - * - * @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. - * - * 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. - * - * @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. - * - * /a superarea_of b <=> for each pixel of b there exists an opaque pixel - * in a at the same location - * - * @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. - * - * @param[in] visual GfxVisual to set for the widget - */ - virtual int setVisual(GfxVisual *visual); - -//protected: - void printIntern(int indentation) const; - -}; - - -#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; - -public: - GfxBox(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - - -#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; - gfx_line_style_t _lineStyle; - -public: - GfxPrimitive(rect_t area, gfx_color_t color, gfx_line_mode_t mode, - gfx_line_style_t style, gfxw_widget_type_t type); -}; - - - -#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; - int _view, _loop, _cel; - int _palette; - -public: - GfxView(GfxState *state, Common::Point pos, int view_nr, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int flags); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -#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 */ - ObjVarRef under_bitsp; - ObjVarRef signalp; - int under_bits, signal; - int _z; /**< The z coordinate: Added to y, but used for sorting */ - int sequence; /**< Sequence number: For sorting */ - int force_precedence; /**< Precedence enforcement variable for sorting- defaults to 0 */ - - bool _isDrawn; // FIXME: This is specific to GFXW_PIC_VIEW - -public: - GfxDynView(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); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - - - -#define GFXW_IS_TEXT(widget) ((widget)->_type == GFXW_TEXT) -/** SCI text widget */ -struct GfxText : public GfxWidget { - int _font; - int lines_nr, lineheight, lastline_width; - Common::String _text; - gfx_alignment_t halign, valign; - gfx_color_t _color1, _color2, _bgcolor; - int _textFlags; - int width; /**< Real text width */ - int height; /**< Real text height */ - TextHandle *_textHandle; - -public: - GfxText(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 text_flags); - - ~GfxText(); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - - -/* Container widgets */ - -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 */ - GfxWidget *_contents; - GfxWidget **_nextpp; /**< Pointer to the 'next' pointer in the last entry in contents */ - -public: - // TODO: Replace the following with virtual methods - gfxw_unary_container_op *free_tagged; /**< Free all tagged contained widgets */ - gfxw_unary_container_op *free_contents; /**< Free all contained widgets */ - gfxw_rect_op *add_dirty_abs; /**< Add an absolute dirty rectangle */ - gfxw_rect_op *add_dirty_rel; /**< Add a relative dirty rectangle */ - gfxw_container_op *add; /**< Append widget to an appropriate position (for view and control lists) */ - -public: - // FIXME: This should be a virtual base class, mark it so somehow? - GfxContainer(rect_t area, gfxw_widget_type_t type); - ~GfxContainer(); - - virtual void tag(); - virtual void print(int indentation) const; - virtual int setVisual(GfxVisual *); -}; - - -#define GFXW_IS_CONTAINER(widget) ((widget)->_type == GFXW_PORT || (widget)->_type == GFXW_VISUAL || \ - (widget)->_type == GFXW_SORTED_LIST || (widget)->_type == GFXW_LIST) - -#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); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -#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 */ - GfxState *_gfxState; - -public: - GfxVisual(GfxState *state, int font); - ~GfxVisual(); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; - virtual int setVisual(GfxVisual *); - - GfxPort *getPort(int portId) { - return (portId < 0 || portId >= (int)_portRefs.size()) ? NULL : _portRefs[portId]; - } -}; - -#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 */ - gfx_color_t _color, _bgcolor; - int _font; - Common::Point draw_pos; /**< Drawing position */ - gfxw_snapshot_t *restore_snap; /**< Snapshot to be restored automagically, - experimental feature used in the PQ3 interpreter */ - int port_flags; /**< interpreter-dependant flags */ - Common::String _title_text; - byte gray_text; /**< Whether text is 'grayed out' (dithered) */ - -public: - /** - * 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(); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; - virtual int setVisual(GfxVisual *); -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_STATE_INTERNAL_H - -#endif diff --git a/engines/sci/gfx/gfx_support.cpp b/engines/sci/gfx/gfx_support.cpp deleted file mode 100644 index 8efe59b855..0000000000 --- a/engines/sci/gfx/gfx_support.cpp +++ /dev/null @@ -1,281 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -/* Graphics support functions for drivers and replacements for driver functions -** for use with the graphical state manager -*/ - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_tools.h" - -#include "common/endian.h" -#include "graphics/primitives.h" - -namespace Sci { - -#define LINEMACRO(startx, starty, deltalinear, deltanonlinear, linearvar, nonlinearvar, \ - linearend, nonlinearstart, linearmod, nonlinearmod) \ - incrNE = ((deltalinear) > 0) ? (deltalinear) : -(deltalinear); \ - incrNE <<= 1; \ - deltanonlinear <<= 1; \ - incrE = ((deltanonlinear) > 0) ? -(deltanonlinear) : (deltanonlinear); \ - d = nonlinearstart - 1; \ - while (linearvar != (linearend)) { \ - memcpy(buffer + linewidth * (starty) + (startx), &color, pixelwidth); \ - linearvar += linearmod; \ - if ((d += incrE) < 0) { \ - d += incrNE; \ - nonlinearvar += nonlinearmod; \ - }; \ - }; \ - memcpy(buffer + linewidth * (starty) + (startx), &color, pixelwidth); - - -// Sierra's Bresenham line drawing -// WARNING: Do not just blindly replace this with Graphics::drawLine(), as it seems to create issues with flood fill -void gfx_draw_line_buffer(byte *buffer, int linewidth, int pixelwidth, Common::Point start, Common::Point end, unsigned int color) { - int incrE, incrNE, d; - int dx = ABS(end.x - start.x); - int dy = ABS(end.y - start.y); -#ifdef SCUMM_BIG_ENDIAN - color = SWAP_BYTES_32(color); -#endif - - if (dx > dy) { - int sign1 = (end.x < start.x) ? -1 : 1; - int sign2 = (end.y < start.y) ? -1 : 1; - LINEMACRO(start.x, start.y, dx, dy, start.x, start.y, end.x, dx, sign1 * pixelwidth, sign2); - } else { // dx <= dy - int sign1 = (end.y < start.y) ? -1 : 1; - int sign2 = (end.x < start.x) ? -1 : 1; - LINEMACRO(start.x, start.y, dy, dx, start.y, start.x, end.y, dy, sign1, sign2 * pixelwidth); - } - } - -#undef LINEMACRO - -void gfx_draw_line_pixmap_i(gfx_pixmap_t *pxm, Common::Point start, Common::Point end, int color) { - gfx_draw_line_buffer(pxm->index_data, pxm->index_width, 1, start, end, color); -} - -void gfx_draw_box_buffer(byte *buffer, int linewidth, rect_t zone, int color) { - byte *dest = buffer + zone.x + (linewidth * zone.y); - int i; - - if (zone.width <= 0 || zone.height <= 0) - return; - - for (i = 0; i < zone.height; i++) { - memset(dest, color, zone.width); - dest += linewidth; - } -} - -void gfx_draw_box_pixmap_i(gfx_pixmap_t *pxm, rect_t box, int color) { - gfx_clip_box_basic(&box, pxm->index_width - 1, pxm->index_height - 1); - - gfx_draw_box_buffer(pxm->index_data, pxm->index_width, box, color); -} - - -void _gfx_crossblit(byte *dest, byte *src, int bytes_per_dest_line, int bytes_per_src_line, - int xl, int yl, byte *alpha, int bytes_per_alpha_line, int bytes_per_alpha_pixel, - unsigned int alpha_test_mask, unsigned int alpha_min, - byte *priority_buffer, int bytes_per_priority_line, int bytes_per_priority_pixel, int priority, - bool usePriority) { - int x, y; - int alpha_end = xl * bytes_per_alpha_pixel; - - for (y = 0; y < yl; y++) { - int pixel_offset = 0; - int alpha_offset = 0; - int priority_offset = 0; - - for (x = 0; x < alpha_end; x += bytes_per_alpha_pixel) { - if (((alpha_test_mask & alpha[x]) < alpha_min) ^ 1) { - - if (usePriority) { - if (priority_buffer[priority_offset] <= priority) { - priority_buffer[priority_offset] = priority; - memcpy(dest + pixel_offset, src + pixel_offset, 1); - } - } else { - memcpy(dest + pixel_offset, src + pixel_offset, 1); - } - } - - pixel_offset++; - alpha_offset += bytes_per_alpha_pixel; - if (usePriority) - priority_offset += bytes_per_priority_pixel; - } - - dest += bytes_per_dest_line; - src += bytes_per_src_line; - alpha += bytes_per_alpha_line; - if (usePriority) - priority_buffer += bytes_per_priority_line; - } -} - -void _gfx_crossblit_simple(byte *dest, byte *src, int dest_line_width, int src_line_width, int xl, int yl) { - int line_width = xl; - int i; - - for (i = 0; i < yl; i++) { - memcpy(dest, src, line_width); - dest += dest_line_width; - src += src_line_width; - } -} - -void 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 maxx = 320 * mode->scaleFactor; - int maxy = 200 * mode->scaleFactor; - byte *src = pxm->data; - byte *alpha = pxm->alpha_map ? pxm->alpha_map : pxm->data; - byte *priority_pos = priority_dest; - unsigned int alpha_mask, alpha_min; - int xl = pxm->width, yl = pxm->height; - int xoffset = (dest_coords.x < 0) ? - dest_coords.x : 0; - int yoffset = (dest_coords.y < 0) ? - dest_coords.y : 0; - - if (src_coords.x + src_coords.width > xl) - src_coords.width = xl - src_coords.x; - - if (src_coords.y + src_coords.height > yl) - src_coords.height = yl - src_coords.y; - - // --???-- - if (src_coords.y > yl) - return; - if (src_coords.x > xl) - return; - // --???-- - - if (dest_coords.x + xl >= maxx) - xl = maxx - dest_coords.x; - if (dest_coords.y + yl >= maxy) - yl = maxy - dest_coords.y; - - xl -= xoffset; - yl -= yoffset; - - if (!pxm->data) - error("Attempted to crossblit an empty pixmap"); - - if (xl <= 0 || yl <= 0) - return; - - // Set destination offsets - - // Set x offsets - dest += dest_coords.x; - priority_pos += dest_coords.x * priority_skip; - - // Set y offsets - dest += dest_coords.y * dest_line_width; - priority_pos += dest_coords.y * priority_line_width; - - // Set source offsets - if (xoffset += src_coords.x) { - dest_coords.x = 0; - src += xoffset; - alpha += xoffset; - } - - - if (yoffset += src_coords.y) { - dest_coords.y = 0; - src += yoffset * pxm->width; - alpha += yoffset * pxm->width; - } - - // Adjust length for clip box - if (xl > src_coords.width) - xl = src_coords.width; - if (yl > src_coords.height) - yl = src_coords.height; - - // now calculate alpha - if (pxm->alpha_map) - alpha_mask = 0xff; - else { - int shift_nr = 0; - - alpha_mask = 0; - if (!alpha_mask && pxm->alpha_map) - error("Invalid alpha mode: both pxm->alpha_map and alpha_mask are white"); - - if (alpha_mask) { - while (!(alpha_mask & 0xff)) { - alpha_mask >>= 8; - shift_nr++; - } - alpha_mask &= 0xff; - } - -#ifdef SCUMM_BIG_ENDIAN - alpha += 1 - (shift_nr + 1); -#else - alpha += shift_nr; -#endif - } - - /** - * Crossblitting functions use this value as threshold for distinguishing - * between transparent and opaque wrt alpha values. - */ - int gfx_crossblit_alpha_threshold = 0x90; // was 128 - - if (alpha_mask & 0xff) - alpha_min = ((alpha_mask * gfx_crossblit_alpha_threshold) >> 8) & alpha_mask; - else - alpha_min = ((alpha_mask >> 8) * gfx_crossblit_alpha_threshold) & alpha_mask; - - alpha_min = 255 - alpha_min; // Since we use it for the reverse effect - - if (!alpha_mask) - _gfx_crossblit_simple(dest, src, dest_line_width, pxm->width, xl, yl); - else - - if (priority == GFX_NO_PRIORITY) { - _gfx_crossblit(dest, src, dest_line_width, pxm->width, - xl, yl, alpha, pxm->width, 1, alpha_mask, alpha_min, - 0, 0, 0, 0, false); - } else { // priority - _gfx_crossblit(dest, src, dest_line_width, pxm->width, - xl, yl, alpha, pxm->width, 1, alpha_mask, alpha_min, - priority_pos, priority_line_width, priority_skip, priority, true); - } -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_system.h b/engines/sci/gfx/gfx_system.h deleted file mode 100644 index d57c68552e..0000000000 --- a/engines/sci/gfx/gfx_system.h +++ /dev/null @@ -1,286 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_SYSTEM -#define SCI_GFX_GFX_SYSTEM - -#include "common/scummsys.h" -#include "common/rect.h" -#include "sci/gfx/palette.h" - -namespace Sci { - -#define GFX_DEBUG - -/***********************/ -/*** Data structures ***/ -/***********************/ - -#define GFX_MODE_IS_UNSCALED(mode) (((mode)->scaleFactor == 1) && ((mode)->scaleFactor == 1)) - -/** 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. - */ - -struct gfx_mode_t { - - int scaleFactor; /**< Horizontal and vertical scaling factor */ - int xsize, ysize; /**< Horizontal and vertical size */ - - /** - * Palette or NULL to indicate non-palette mode. - */ - Palette *palette; -}; - - -// TODO: Replace rect_t by Common::Rect -/** Rectangle description */ -struct rect_t { - int x, y; - int width, height; /* width, height: (x,y,width,height)=(5,5,1,1) occupies 1 pixel */ -}; - -/** - * 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; - - rect.x = x; - rect.y = y; - rect.width = width; - rect.height = height; - - return 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); -} - -#define GFX_PRINT_RECT(rect) (rect).x, (rect).y, (rect).width, (rect).height - -#define OVERLAP(a, b, z, zl) (a.z >= b.z && a.z < (b.z + b.zl)) - -/** - * 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)); -} - -#undef OVERLAP - -/* gfx_rect_fullscreen is declared in gfx/gfx_tools.c */ -extern rect_t gfx_rect_fullscreen; - -#define GFX_RESID_NONE -1 - -#define GFX_PIC_COLORS 256 - -#define GFX_PIXMAP_COLOR_KEY_NONE -1 /* No transpacency colour key */ -#define GFX_CURSOR_TRANSPARENT 255 // Cursor colour key - -/** Pixel map */ -struct gfx_pixmap_t { - - /** @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 */ - /** @}*/ - - /** @name Color map - * @{*/ - Palette *palette; - - /** - * 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 ? MIN<int>(palette->size(), 256) : 0; } - - 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 */ - /** @} */ -}; - - - - -/** @name Constant values - * @{ */ - -/** 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 */ -enum { - GFX_NO_PRIORITY = -1 -}; - -/** Text alignment values */ -enum gfx_alignment_t { - ALIGN_RIGHT = -1, - ALIGN_TOP = -1, - ALIGN_CENTER = 1, - ALIGN_LEFT = 0, - ALIGN_BOTTOM = 0 -}; - - -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 */ -}; - -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 */ -}; - - -enum gfx_line_style_t { - GFX_LINE_STYLE_NORMAL, - GFX_LINE_STYLE_STIPPLED -}; - - -enum gfx_rectangle_fill_t { - GFX_SHADE_FLAT, /**< Don't shade */ - GFX_SHADE_VERTICALLY, /**< Shade vertically */ - GFX_SHADE_HORIZONTALLY /**< Shade horizontally */ -}; - -/** @} */ - -/** Full color */ -struct gfx_color_t { - PaletteEntry visual; - uint8 alpha; /**< transparency = (1-opacity) */ - int8 priority, control; - byte mask; /**< see mask values below */ - - bool operator==(const gfx_color_t &c) const { - if (mask != c.mask) - return false; - - if (mask & GFX_MASK_VISUAL) { - if (visual.r != c.visual.r || visual.g != c.visual.g || visual.b != c.visual.b || alpha != c.alpha) - return false; - } - - if (mask & GFX_MASK_PRIORITY) - if (priority != c.priority) - return false; - - if (mask & GFX_MASK_CONTROL) - if (control != c.control) - return false; - - return true; - } - - bool operator!=(const gfx_color_t &c) const { - return !(*this == c); - } -}; - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_SYSTEM - -#endif diff --git a/engines/sci/gfx/gfx_tools.cpp b/engines/sci/gfx/gfx_tools.cpp deleted file mode 100644 index 0ea488fe1d..0000000000 --- a/engines/sci/gfx/gfx_tools.cpp +++ /dev/null @@ -1,163 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - -rect_t gfx_rect_fullscreen = {0, 0, 320, 200}; - -void gfx_clip_box_basic(rect_t *box, int maxx, int maxy) { - if (box->x < 0) - box->x = 0; - - if (box->y < 0) - box->y = 0; - - if (box->x + box->width > maxx) - box->width = maxx - box->x + 1; - - if (box->y + box->height > maxy) - box->height = maxy - box->y + 1; -} - -gfx_mode_t *gfx_new_mode(int scaleFactor, Palette *palette) { - gfx_mode_t *mode = (gfx_mode_t *)malloc(sizeof(gfx_mode_t)); - - mode->scaleFactor = scaleFactor; - mode->xsize = scaleFactor * 320; - mode->ysize = scaleFactor * 200; - mode->palette = palette; - - return mode; -} - -void gfx_free_mode(gfx_mode_t *mode) { - mode->palette->free(); - free(mode); - mode = NULL; -} - -void gfx_copy_pixmap_box_i(gfx_pixmap_t *dest, gfx_pixmap_t *src, rect_t box) { - int width, height; - int offset; - - if ((dest->index_width != src->index_width) || (dest->index_height != src->index_height)) - return; - - gfx_clip_box_basic(&box, dest->index_width, dest->index_height); - - if (box.width <= 0 || box.height <= 0) - return; - - height = box.height; - width = box.width; - - offset = box.x + (box.y * dest->index_width); - - while (height--) { - memcpy(dest->index_data + offset, src->index_data + offset, width); - offset += dest->index_width; - } -} - -gfx_pixmap_t *gfx_new_pixmap(int xl, int yl, int resid, int loop, int cel) { - gfx_pixmap_t *pxm = (gfx_pixmap_t *)malloc(sizeof(gfx_pixmap_t)); - - pxm->alpha_map = NULL; - pxm->data = NULL; - pxm->palette = NULL; - pxm->palette_revision = -1; - - pxm->index_width = xl; - pxm->index_height = yl; - - pxm->ID = resid; - pxm->loop = loop; - pxm->cel = cel; - - pxm->index_data = NULL; - - pxm->flags = 0; - - pxm->color_key = 0xff; - - return pxm; -} - -void gfx_free_pixmap(gfx_pixmap_t *pxm) { - if (pxm->palette) - pxm->palette->free(); - - free(pxm->index_data); - free(pxm->alpha_map); - free(pxm->data); - free(pxm); -} - -gfx_pixmap_t *gfx_pixmap_alloc_index_data(gfx_pixmap_t *pixmap) { - int size; - - if (pixmap->index_data) { - warning("[GFX] Attempt to allocate pixmap index data twice"); - return pixmap; - } - - size = pixmap->index_width * pixmap->index_height; - if (!size) - size = 1; - - pixmap->index_data = (byte*)malloc(size); - - memset(pixmap->index_data, 0, size); - - return pixmap; -} - -gfx_pixmap_t *gfx_pixmap_alloc_data(gfx_pixmap_t *pixmap, gfx_mode_t *mode) { - int size; - - if (pixmap->data) { - warning("[GFX] Attempt to allocate pixmap data twice"); - return pixmap; - } - - pixmap->width = pixmap->index_width; - pixmap->height = pixmap->index_height; - - size = pixmap->width * pixmap->height; - if (!size) - size = 1; - - pixmap->data = (byte*)malloc(pixmap->data_size = size); - return pixmap; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_tools.h b/engines/sci/gfx/gfx_tools.h deleted file mode 100644 index 06543532e8..0000000000 --- a/engines/sci/gfx/gfx_tools.h +++ /dev/null @@ -1,191 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_TOOLS_H -#define SCI_GFX_GFX_TOOLS_H - -#include "graphics/pixelformat.h" - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_driver.h" - -namespace Sci { - -/** @name SCI graphics subsystem helper functions */ -/** @{ */ - -/** - * 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] palette Number of palette colors, 0 if we're not in palette mode - * @return A newly allocated gfx_mode_t structure - */ -gfx_mode_t *gfx_new_mode(int scaleFactor, Palette *palette); - -/** - * 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); - -/** - * Frees all memory allocated by a mode structure - * @param[in] mode The mode to free - */ -void gfx_free_mode(gfx_mode_t *mode); - -/** - * 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); - -/** - * 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 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); - -/** - * Frees all memory associated with a pixmap - * - * @param[in] pxm The pixmap to free - */ -void gfx_free_pixmap(gfx_pixmap_t *pxm); - -/** - * 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); - -void gfx_draw_line_buffer(byte *buffer, int linewidth, int pixelwidth, - Common::Point start, Common::Point end, unsigned 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); - -void gfx_draw_box_buffer(byte *buffer, int linewidth, rect_t zone, int color); - -/** - * 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); - -/** - * 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 - */ -void gfx_xlate_pixmap(gfx_pixmap_t *pxm, gfx_mode_t *mode); - -/** - * 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 - */ -void 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); - - -/** @} */ -} // End of namespace Sci - -#endif // SCI_GFX_GFX_TOOLS_H - -#endif diff --git a/engines/sci/gfx/gfx_widgets.cpp b/engines/sci/gfx/gfx_widgets.cpp deleted file mode 100644 index d260e66cfc..0000000000 --- a/engines/sci/gfx/gfx_widgets.cpp +++ /dev/null @@ -1,1775 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/gfx_gui.h" // for kWindowAutoRestore -#include "sci/gfx/gfx_widgets.h" -#include "sci/gfx/gfx_state_internal.h" - -namespace Sci { - -#undef GFXW_DEBUG_DIRTY // Enable to debug dirty rectangle propagation (writes to stderr) - -#ifdef GFXW_DEBUG_DIRTY -# define DDIRTY fprintf(stderr, "%s:%5d| ", __FILE__, __LINE__); fprintf -#else -# define DDIRTY if (0) fprintf -#endif - -Common::Point gfxw_point_zero(0, 0); - -#define MAX_SERIAL_NUMBER 0x7fffffff -static int widget_serial_number_counter = 0x10000; // Avoid confusion with IDs - -#ifdef GFXW_DEBUG_WIDGETS - -GfxWidget *debug_widgets[GFXW_DEBUG_WIDGETS]; -int debug_widget_pos = 0; - -static void _gfxw_debug_add_widget(GfxWidget *widget) { - if (debug_widget_pos == GFXW_DEBUG_WIDGETS) - error("WIDGET DEBUG: Allocated the maximum number of %d widgets- Aborting!\n", GFXW_DEBUG_WIDGETS); - debug_widgets[debug_widget_pos++] = widget; -} - -static void _gfxw_debug_remove_widget(GfxWidget *widget) { - int i; - int found = 0; - for (i = 0; i < debug_widget_pos; i++) { - if (debug_widgets[i] == widget) { - memmove(debug_widgets + i, debug_widgets + i + 1, (sizeof(GfxWidget *)) * (debug_widget_pos - i - 1)); - debug_widgets[debug_widget_pos--] = NULL; - found++; - } - } - - if (found > 1) { - error("While removing widget: Found it %d times!\n", found); - } - - if (found == 0) { - error("Attempted removal of unregistered widget!\n"); - } -} -#else // !GFXW_DEBUG_WIDGETS -#define _gfxw_debug_add_widget(a) -#define _gfxw_debug_remove_widget(a) -#endif - - -static void indent(int indentation) { - for (int i = 0; i < indentation; i++) - printf(" "); -} - -void GfxWidget::printIntern(int indentation) const { - unsigned int i; - char flags_list[] = "VOCDTMI"; - - indent(indentation); - - if (_magic == GFXW_MAGIC_VALID) { - if (_visual) - printf("v "); - else - printf("NoVis "); - } else if (_magic == GFXW_MAGIC_INVALID) - printf("INVALID "); - - printf("S%08x", _serial); - - if (_ID != GFXW_NO_ID) { - printf("#%x", _ID); - - if (_subID != GFXW_NO_ID) - printf(":%x ", _subID); - else - printf(" "); - } - - printf("[(%d,%d)(%dx%d)]", _bounds.x, _bounds.y, _bounds.width, _bounds.height); - - for (i = 0; i < strlen(flags_list); i++) - if (_flags & (1 << i)) - printf("%c", flags_list[i]); - - printf(" "); -} - -void GfxWidget::print(int indentation) const { - printIntern(indentation); - printf("<untyped #%d>", _type); -} - -GfxWidget::GfxWidget(gfxw_widget_type_t type_) { - _magic = GFXW_MAGIC_VALID; - - _serial = widget_serial_number_counter++; - widget_serial_number_counter &= MAX_SERIAL_NUMBER; - - _flags = GFXW_FLAG_DIRTY; - _type = type_; - _bounds = gfx_rect(0, 0, 0, 0); - _next = NULL; - _ID = GFXW_NO_ID; - _subID = GFXW_NO_ID; - _parent = NULL; - _visual = NULL; - _widgetPriority = -1; - - compare_to = NULL; - equals = NULL; - should_replace = NULL; - superarea_of = NULL; - - _gfxw_debug_add_widget(this); -} - -static int verify_widget(GfxWidget *widget) { - if (!widget) { - warning("Attempt to use NULL widget"); - return 1; - } else if (widget->_magic != GFXW_MAGIC_VALID) { - if (widget->_magic == GFXW_MAGIC_INVALID) { - warning("Attempt to use invalidated widget"); - } else { - warning("Attempt to use non-widget"); - } - return 1; - } - return 0; -} - -#define VERIFY_WIDGET(w) \ - if (verify_widget((GfxWidget *)(w))) { error("Error occured while validating widget"); } - -//********** Widgets ************* - -// Base class operations and common stuff - -// Assertion for drawing -#define DRAW_ASSERT(widget, exp_type) \ - if (!(widget)) { \ - printf("L%d: NULL widget", __LINE__); \ - return 1; \ - } \ - if ((widget)->_type != (exp_type)) { \ - printf("L%d: Error in widget: Expected type " # exp_type "(%d) but got %d\n", __LINE__, exp_type, (widget)->_type); \ - printf("Erroneous widget: "); \ - widget->print(4); \ - printf("\n"); \ - return 1; \ - } \ - if (!(widget->_flags & GFXW_FLAG_VISIBLE)) \ - return 0; \ - if (!(widget->_type == GFXW_VISUAL || widget->_visual)) { \ - printf("L%d: Error while drawing widget: Widget has no visual\n", __LINE__); \ - printf("Erroneous widget: "); \ - widget->print(1); \ - printf("\n"); \ - return 1; \ - } - -int GfxWidget::setVisual(GfxVisual *visual) { - _visual = visual; - - if (_parent) { - DDIRTY(stderr, "GfxWidget::setVisual: DOWNWARDS rel(%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(_bounds)); - _parent->add_dirty_rel(_parent, _bounds, 1); - } - - return 0; -} - -static int _gfxwop_basic_should_replace(GfxWidget *widget, GfxWidget *other) { - return 0; -} - -static void _gfxw_set_ops(GfxWidget *widget, - gfxw_bin_op *compare_to, gfxw_bin_op *equals, gfxw_bin_op *superarea_of) { - widget->compare_to = compare_to; - widget->equals = equals; - widget->superarea_of = superarea_of; - - widget->should_replace = _gfxwop_basic_should_replace; -} - -void gfxw_remove_widget_from_container(GfxContainer *container, GfxWidget *widget) { - GfxWidget **seekerp; - - if (!container) { - error("Attempt to remove widget from NULL container!\n"); - } - - seekerp = &(container->_contents); - - if (GFXW_IS_LIST(widget) && GFXW_IS_PORT(container)) { - GfxPort *port = (GfxPort *) container; - if (port->_decorations == (GfxList *) widget) { - port->_decorations = NULL; - return; - } - } - - while (*seekerp && *seekerp != widget) - seekerp = &((*seekerp)->_next); - - if (!*seekerp) { - printf("Internal error: Attempt to remove widget from container it was not contained in!\n"); - printf("Widget:"); - widget->print(1); - printf("Container:"); - widget->print(1); - error("gfxw_remove_widget_from_container() failed. Breakpoint in %s, line %d", __FILE__, __LINE__); - return; - } - - if (container->_nextpp == &(widget->_next)) - container->_nextpp = seekerp; - - *seekerp = widget->_next; // Remove it - widget->_parent = NULL; - widget->_next = NULL; -} - -GfxWidget::~GfxWidget() { - DDIRTY(stderr, "BASIC-FREE: SomeAddDirty\n"); // FIXME: What is this? - - if (_parent) { - if (GFXW_IS_CONTAINER(this)) - _parent->add_dirty_abs(_parent, _bounds, 1); - else - _parent->add_dirty_rel(_parent, _bounds, 1); - - gfxw_remove_widget_from_container(_parent, this); - } - - _magic = GFXW_MAGIC_INVALID; - _gfxw_debug_remove_widget(this); -} - -static int _gfxwop_basic_compare_to(GfxWidget *widget, GfxWidget *other) { - return 1; -} - -static int _gfxwop_basic_equals(GfxWidget *widget, GfxWidget *other) { - return 0; -} - -static int _gfxwop_basic_superarea_of(GfxWidget *widget, GfxWidget *other) { - return (widget == other); -} - -//*** Boxes *** - -static rect_t _move_rect(rect_t rect, Common::Point point) { - return gfx_rect(rect.x + point.x, rect.y + point.y, rect.width, rect.height); -} - -static void _split_rect(rect_t rect, Common::Point *p1, Common::Point *p2) { - p1->x = rect.x; - p1->y = rect.y; - p2->x = rect.x + rect.width; - p2->y = rect.y + rect.height; -} - -static Common::Point _move_point(rect_t rect, Common::Point point) { - return Common::Point(rect.x + point.x, rect.y + point.y); -} - -int GfxBox::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_BOX); - gfxop_draw_box(_visual->_gfxState, _move_rect(_bounds, pos), _color1, _color2, _shadeType); - return 0; -} - -void GfxBox::print(int indentation) const { - printIntern(indentation); - printf("BOX"); -} - -static int _gfxwop_box_superarea_of(GfxWidget *widget, GfxWidget *other) { - GfxBox *box = (GfxBox *) widget; - - if (box->_color1.alpha) - return 0; - - if (box->_shadeType != GFX_BOX_SHADE_FLAT && box->_color2.alpha) - return 0; - - // Note: the check for box->_bounds and other->_bounds is NOT the same as contains() - // in Common::Rect (this one includes equality too) - if (!(box->_bounds.x <= other->_bounds.x && box->_bounds.y <= other->_bounds.y && - box->_bounds.x + box->_bounds.width >= other->_bounds.x + other->_bounds.width && - box->_bounds.y + box->_bounds.height >= other->_bounds.y + other->_bounds.height)) - return 0; - - return 1; -} - -static int _gfxwop_box_equals(GfxWidget *widget, GfxWidget *other) { - GfxBox *wbox = (GfxBox *)widget, *obox; - if (other->_type != GFXW_BOX) - return 0; - - obox = (GfxBox *) other; - - if (!toCommonRect(wbox->_bounds).equals(toCommonRect(obox->_bounds))) - return 0; - - if (wbox->_color1 != obox->_color1) - return 0; - - if (wbox->_shadeType != obox->_shadeType) - return 0; - - if (wbox->_shadeType != GFX_BOX_SHADE_FLAT - && wbox->_color2 == obox->_color2) - return 0; - - return 1; -} - -void _gfxw_set_ops_BOX(GfxWidget *widget) { - _gfxw_set_ops(widget, _gfxwop_basic_compare_to, _gfxwop_box_equals, _gfxwop_box_superarea_of); -} - -static int _gfxw_color_get_priority(gfx_color_t color) { - return (color.mask & GFX_MASK_PRIORITY) ? color.priority : -1; -} - -GfxBox *gfxw_new_box(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) { - return new GfxBox(state, area, color1, color2, shade_type); -} - -GfxBox::GfxBox(GfxState *state, rect_t area, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) - : GfxWidget(GFXW_BOX) { - - _widgetPriority = _gfxw_color_get_priority(color1); - _bounds = area; - _color1 = color1; - _color2 = color2; - _shadeType = shade_type; - - _flags |= GFXW_FLAG_VISIBLE; - - if ((_color1.mask & GFX_MASK_VISUAL) && ((state && (state->driver->getMode()->palette)) || (!_color1.alpha && !_color2.alpha))) - _flags |= GFXW_FLAG_OPAQUE; - - _gfxw_set_ops_BOX(this); -} - -GfxPrimitive::GfxPrimitive(rect_t area, gfx_color_t color_, gfx_line_mode_t mode, - gfx_line_style_t style, gfxw_widget_type_t type_) - : GfxWidget(type_) { - - _widgetPriority = _gfxw_color_get_priority(color_); - _bounds = area; - _color = color_; - _lineMode = mode; - _lineStyle = style; - - _flags |= GFXW_FLAG_VISIBLE; -} - -//*** Rectangles *** - -struct GfxRect : public GfxPrimitive { - GfxRect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -static int _gfxwop_primitive_equals(GfxWidget *widget, GfxWidget *other) { - GfxPrimitive *wprim = (GfxPrimitive *) widget, *oprim; - if (widget->_type != other->_type) - return 0; - - oprim = (GfxPrimitive *) other; - - // Check if the two primitives are equal (note: the primitives aren't always rectangles, so - // the "width" and the "height" here could be negative) - if (wprim->_bounds.x != oprim->_bounds.x || wprim->_bounds.y != oprim->_bounds.y || - wprim->_bounds.width != oprim->_bounds.width || wprim->_bounds.height != oprim->_bounds.height) - return 0; - - if (wprim->_color != oprim->_color) - return 0; - - if (wprim->_lineMode != oprim->_lineMode) - return 0; - - if (wprim->_lineStyle != oprim->_lineStyle) - return 0; - - return 1; -} - -int GfxRect::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_RECT); - - gfxop_draw_rectangle(_visual->_gfxState, gfx_rect(_bounds.x + pos.x, _bounds.y + pos.y, - _bounds.width - 1, _bounds.height - 1), _color, _lineMode, _lineStyle); - return 0; -} - -void GfxRect::print(int indentation) const { - printIntern(indentation); - printf("RECT"); -} - -void _gfxw_set_ops_RECT(GfxWidget *prim) { - _gfxw_set_ops(prim, - _gfxwop_basic_compare_to, _gfxwop_primitive_equals, _gfxwop_basic_superarea_of); -} - -GfxPrimitive *gfxw_new_rect(rect_t rect, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style) { - return new GfxRect(rect, color, line_mode, line_style); -} - -GfxRect::GfxRect(rect_t rect, gfx_color_t color_, gfx_line_mode_t line_mode_, gfx_line_style_t line_style_) - : GfxPrimitive(rect, color_, line_mode_, line_style_, GFXW_RECT) { - - _bounds.width++; - _bounds.height++; // Since it is actually one pixel bigger in each direction - - _gfxw_set_ops_RECT(this); -} - -//*** Lines *** - -struct GfxLine : public GfxPrimitive { - GfxLine(Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, gfx_line_style_t line_style); - - virtual int draw(const Common::Point &pos); - virtual void print(int indentation) const; -}; - -int GfxLine::draw(const Common::Point &pos) { - rect_t linepos = _bounds; - Common::Point p1, p2; - - linepos.width--; - linepos.height--; - - DRAW_ASSERT(this, GFXW_LINE); - - _split_rect(_move_rect(linepos, pos), &p1, &p2); - gfxop_draw_line(_visual->_gfxState, p1, p2, _color, _lineMode, _lineStyle); - return 0; -} - -void GfxLine::print(int indentation) const { - printIntern(indentation); -// printf("LINE"); -} - -void _gfxw_set_ops_LINE(GfxWidget *prim) { - _gfxw_set_ops(prim, - _gfxwop_basic_compare_to, _gfxwop_primitive_equals, _gfxwop_basic_superarea_of); -} - -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) { - return new GfxLine(start, end, color, line_mode, line_style); -} - -GfxLine::GfxLine(Common::Point start, Common::Point end, gfx_color_t color_, gfx_line_mode_t line_mode_, gfx_line_style_t line_style_) - : GfxPrimitive(gfx_rect(start.x, start.y, end.x - start.x + 1, end.y - start.y + 1), color_, line_mode_, line_style_, GFXW_LINE) { - _gfxw_set_ops_LINE(this); -} - -//*** Views and static views *** - - -GfxView::GfxView(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_) - : GfxWidget((flags_ & GFXW_VIEW_FLAG_STATIC) ? GFXW_STATIC_VIEW : GFXW_VIEW) { - - int width, height; - Common::Point offset; - - if (!state) { - error("Attempt to create view widget with NULL state"); - } - - gfxop_get_cel_parameters(state, view_, loop_, cel_, &width, &height, &offset); - - _pos = pos_; - _color.mask = ((priority < 0) ? 0 : GFX_MASK_PRIORITY) | ((control < 0) ? 0 : GFX_MASK_CONTROL); - _widgetPriority = priority; - _color.priority = priority; - _color.control = control; - _view = view_; - _loop = loop_; - _cel = cel_; - _palette = palette_; - - if (halign == ALIGN_CENTER) - _pos.x -= width >> 1; - else if (halign == ALIGN_RIGHT) - _pos.x -= width; - - if (valign == ALIGN_CENTER) - _pos.y -= height >> 1; - else if (valign == ALIGN_BOTTOM) - _pos.y -= height; - - _bounds = gfx_rect(_pos.x - offset.x, _pos.y - offset.y, width, height); - - _flags |= GFXW_FLAG_VISIBLE; -} - -int GfxView::draw(const Common::Point &pos) { - if (_type == GFXW_VIEW) { - DRAW_ASSERT(this, GFXW_VIEW); - gfxop_draw_cel(_visual->_gfxState, _view, _loop, _cel, - Common::Point(_pos.x + pos.x, _pos.y + pos.y), _color, _palette); - } else { - // FIXME: _gfxwop_static_view_draw checked for GFXW_VIEW here, instead of GFXW_STATIC_VIEW. - //DRAW_ASSERT(this, GFXW_VIEW); - DRAW_ASSERT(this, GFXW_STATIC_VIEW); - gfxop_draw_cel_static(_visual->_gfxState, _view, _loop, _cel, - _move_point(_bounds, pos), _color, _palette); - } - return 0; -} - -void GfxView::print(int indentation) const { - printIntern(indentation); - - if (_type == GFXW_STATIC_VIEW) - printf("STATICVIEW"); - else if (_type == GFXW_VIEW) - printf("VIEW"); - else - error("GfxView::print: Invalid type %d", _type); - - printf("(%d/%d/%d)@(%d,%d)[p:%d,c:%d]", _view, _loop, _cel, _pos.x, _pos.y, - (_color.mask & GFX_MASK_PRIORITY) ? _color.priority : -1, - (_color.mask & GFX_MASK_CONTROL) ? _color.control : -1); -} - -void _gfxw_set_ops_VIEW(GfxWidget *view, char stat) { - _gfxw_set_ops(view, _gfxwop_basic_compare_to, _gfxwop_basic_equals, _gfxwop_basic_superarea_of); -} - -GfxView *gfxw_new_view(GfxState *state, Common::Point pos, int view_nr, int loop, int cel, int palette, int priority, int control, - gfx_alignment_t halign, gfx_alignment_t valign, int flags) { - GfxView *view; - - if (flags & GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET) { - int foo; - Common::Point offset; - gfxop_get_cel_parameters(state, view_nr, loop, cel, &foo, &foo, &offset); - pos.x += offset.x; - pos.y += offset.y; - } - - view = new GfxView(state, pos, view_nr, loop, cel, palette, priority, control, halign, valign, - (flags & GFXW_VIEW_FLAG_STATIC) ? GFXW_STATIC_VIEW : GFXW_VIEW); - - _gfxw_set_ops_VIEW(view, (char)(flags & GFXW_VIEW_FLAG_STATIC)); - - return view; -} - -//*** Dynamic Views *** - -int GfxDynView::draw(const Common::Point &pos) { - if (_type == GFXW_DYN_VIEW) { - DRAW_ASSERT(this, GFXW_DYN_VIEW); - - gfxop_draw_cel(_visual->_gfxState, _view, _loop, _cel, - _move_point(draw_bounds, pos), _color, _palette); - - /* - gfx_color_t red; - red.visual.r = 0xff; - red.visual.g = red.visual.b = 0; - red.mask = GFX_MASK_VISUAL; - gfxop_draw_rectangle(view->visual->_gfxState, - gfx_rect(view->_bounds.x + pos.x, view->_bounds.y + pos.y, view->_bounds.width - 1, view->_bounds.height - 1), red, 0, 0); - */ - } else { - DRAW_ASSERT(this, GFXW_PIC_VIEW); - - if (_isDrawn) - return 0; - - gfxop_set_clip_zone(_visual->_gfxState, _parent->zone); - gfxop_draw_cel_static_clipped(_visual->_gfxState, _view, _loop, - _cel, _move_point(draw_bounds, pos), _color, _palette); - - // Draw again on the back buffer - gfxop_draw_cel(_visual->_gfxState, _view, _loop, _cel, - _move_point(draw_bounds, pos), _color, _palette); - - - _isDrawn = true; // No more drawing needs to be done - } - - return 0; -} - - void GfxDynView::print(int indentation) const { - printIntern(indentation); - - if (_type == GFXW_DYN_VIEW) - printf("DYNVIEW"); - else if (_type == GFXW_PIC_VIEW) - printf("PICVIEW"); - else - error("GfxDynView::print: Invalid type %d", _type); - - printf(" SORT=%d z=%d seq=%d (%d/%d/%d)@(%d,%d)[p:%d,c:%d]; sig[%04x@%04X:%04X[%d]]", force_precedence, _z, - sequence, _view, _loop, _cel, _pos.x, _pos.y, - (_color.mask & GFX_MASK_PRIORITY) ? _color.priority : -1, - (_color.mask & GFX_MASK_CONTROL) ? _color.control : -1, signal, signalp.obj.segment, signalp.obj.offset, signalp.varindex); -} - -static int _gfxwop_dyn_view_equals(GfxWidget *widget, GfxWidget *other) { - GfxDynView *wview = (GfxDynView *)widget, *oview; - if (!GFXW_IS_DYN_VIEW(other)) - return 0; - - oview = (GfxDynView *)other; - - if (wview->_pos.x != oview->_pos.x || wview->_pos.y != oview->_pos.y || wview->_z != oview->_z) - return 0; - - if (wview->_view != oview->_view || wview->_loop != oview->_loop || wview->_cel != oview->_cel) - return 0; - - if (wview->_color != oview->_color) - return 0; - - if (wview->_flags != oview->_flags) - return 0; - - return 1; -} - -static int _gfxwop_dyn_view_compare_to(GfxWidget *widget, GfxWidget *other) { - int retval; - GfxDynView *wview = (GfxDynView *) widget, *oview; - if (!GFXW_IS_DYN_VIEW(other)) - return 1; - - oview = (GfxDynView *) other; - - retval = wview->force_precedence - oview->force_precedence; - if (retval) - return retval; - - retval = wview->_pos.y - oview->_pos.y; - if (retval) - return retval; - - retval = (wview->_z - oview->_z); - if (retval) - return retval; - - return -(wview->sequence - oview->sequence); -} - -void _gfxw_set_ops_DYNVIEW(GfxWidget *widget) { - _gfxw_set_ops(widget, _gfxwop_dyn_view_compare_to, _gfxwop_dyn_view_equals, _gfxwop_basic_superarea_of); -} - -void _gfxw_set_ops_PICVIEW(GfxWidget *widget) { - _gfxw_set_ops_DYNVIEW(widget); -} - -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) { - - return new GfxDynView(state, pos, z, view, loop, cel, palette, priority, control, halign, valign, sequence); -} - -GfxDynView::GfxDynView(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_) - : GfxView(state, pos_, view_, loop_, cel_, palette_, priority, control, halign, valign, 0) { - int width, height; - int xalignmod, yalignmod; - Common::Point offset; - - _type = GFXW_DYN_VIEW; - - if (!state) - error("Attempt to create view widget with NULL state"); - - gfxop_get_cel_parameters(state, view_, loop_, cel_, &width, &height, &offset); - - _pos = pos_; - _color.mask = ((priority < 0) ? 0 : GFX_MASK_PRIORITY) | ((control < 0) ? 0 : GFX_MASK_CONTROL); - _widgetPriority = priority; - _color.priority = priority; - _color.control = control; - _view = view_; - _loop = loop_; - _cel = cel_; - _palette = palette_; - - _color.alpha = 0; - _color.visual = PaletteEntry(0,0,0); // FIXME: black! - - if (halign == ALIGN_CENTER) - xalignmod = width >> 1; - else if (halign == ALIGN_RIGHT) - xalignmod = width; - else - xalignmod = 0; - - if (valign == ALIGN_CENTER) - yalignmod = height >> 1; - else if (valign == ALIGN_BOTTOM) - yalignmod = height; - else - yalignmod = 0; - - draw_bounds = gfx_rect(_pos.x - xalignmod, _pos.y - yalignmod - z_, width, height); - _bounds = gfx_rect(_pos.x - offset.x - xalignmod, _pos.y - offset.y - yalignmod - z_, width, height); - - under_bitsp.obj = NULL_REG; - under_bits = 0; - signalp.obj = NULL_REG; - signal = 0; - _z = z_; - sequence = sequence_; - force_precedence = 0; - - _isDrawn = false; - - _flags |= GFXW_FLAG_VISIBLE; - - _gfxw_set_ops_DYNVIEW(this); -} - -//*** Text *** - -GfxText::~GfxText() { - if (_textHandle) { - GfxState *state = _visual ? _visual->_gfxState : NULL; - if (!state) { - error("Attempt to free text without supplying mode to free it from!\n"); - } else { - delete _textHandle; - _textHandle = NULL; - } - } -} - -int GfxText::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_TEXT); - - if (_textHandle == 0) { - _textHandle = gfxop_new_text(_visual->_gfxState, _font, _text, _bounds.width, - halign, valign, _color1, _color2, _bgcolor, _textFlags); - } - - gfxop_draw_text(_visual->_gfxState, _textHandle, _move_rect(_bounds, pos)); - return 0; -} - -void GfxText::print(int indentation) const { - printIntern(indentation); - printf("TEXT:'%s'", _text.c_str()); -} - -static int _gfxwop_text_equals(GfxWidget *widget, GfxWidget *other) { - GfxText *wtext = (GfxText *)widget, *otext; - if (other->_type != GFXW_TEXT) - return 0; - - otext = (GfxText *)other; - - if ((wtext->_bounds.x != otext->_bounds.x) || (wtext->_bounds.y != otext->_bounds.y)) - return 0; - - if (wtext->halign != otext->halign || wtext->valign != otext->valign) - return 0; - - if (wtext->_textFlags != otext->_textFlags) - return 0; - - if (wtext->_font != otext->_font) - return 0; - - /* if (!(wtext->_color1 == otext->_color1 && wtext->_color2 == otext->_color2 - && wtext->_bgcolor == otext->_bgcolor)) - return 0; */ - - return 1; -} - -static int _gfxwop_text_should_replace(GfxWidget *widget, GfxWidget *other) { - GfxText *wtext = (GfxText *)widget, *otext; - - if (other->_type != GFXW_TEXT) - return 0; - - otext = (GfxText *)other; - - return wtext->_text != otext->_text; -} - -static int _gfxwop_text_compare_to(GfxWidget *widget, GfxWidget *other) { - return 1; -} - -void _gfxw_set_ops_TEXT(GfxWidget *widget) { - _gfxw_set_ops(widget, - _gfxwop_text_compare_to, _gfxwop_text_equals, - _gfxwop_basic_superarea_of); - widget->should_replace = _gfxwop_text_should_replace; -} - -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 text_flags) { - return new GfxText(state, area, font, text, halign, valign, color1, color2, bgcolor, text_flags); -} - -GfxText::GfxText(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 text_flags_) - : GfxWidget(GFXW_TEXT) { - - _widgetPriority = _gfxw_color_get_priority(color1_); - _font = font; - _text = text; - halign = halign_; - valign = valign_; - _color1 = color1_; - _color2 = color2_; - _bgcolor = bgcolor_; - _textFlags = text_flags_; - _textHandle = NULL; - - gfxop_get_text_params(state, font, text, area.width, &width, &height, _textFlags, - &lines_nr, &lineheight, &lastline_width); - - /* FIXME: Window is too big - area.x += _calc_needmove(halign, area.width, width); - area.y += _calc_needmove(valign, area.height, height); - */ - - if (halign == ALIGN_LEFT) - area.width = width; - if (valign == ALIGN_TOP) - area.height = height; - - _bounds = area; - - _flags |= GFXW_FLAG_VISIBLE; - - _gfxw_set_ops_TEXT(this); -} - -void gfxw_text_info(GfxState *state, GfxText *text, int *lines, int *lineheight, int *offset) { - if (lines) - *lines = text->lines_nr; - if (lineheight) - *lineheight = text->lineheight; - if (offset) - *offset = text->lastline_width; -} - -//-- Container types -- - -static int _gfxwop_container_add_dirty_rel(GfxContainer *cont, rect_t rect, int propagate) { - DDIRTY(stderr, "->container_add_dirty_rel(%d,%d,%d,%d, %d)\n", GFX_PRINT_RECT(rect), propagate); - return cont->add_dirty_abs(cont, _move_rect(rect, Common::Point(cont->zone.x, cont->zone.y)), propagate); -} - -static void _gfxw_set_container_ops(GfxContainer *container, - gfxw_bin_op *compare_to, gfxw_bin_op *equals, - gfxw_bin_op *superarea_of, - gfxw_unary_container_op *free_tagged, gfxw_unary_container_op *free_contents, - gfxw_rect_op *add_dirty, gfxw_container_op *add) { - _gfxw_set_ops(container, compare_to, equals, superarea_of); - - container->free_tagged = free_tagged; - container->free_contents = free_contents; - container->add_dirty_abs = add_dirty; - container->add_dirty_rel = _gfxwop_container_add_dirty_rel; - container->add = add; -} - -static int _w_gfxwop_container_print_contents(const char *name, GfxWidget *widget, int indentation) { - GfxWidget *seeker = widget; - - indent(indentation); - - printf("--%s:\n", name); - - while (seeker) { - seeker->print(indentation + 1); - printf("\n"); - seeker = seeker->_next; - } - - return 0; -} - -void GfxContainer::print(int indentation) const { - printf(" viszone=((%d,%d),(%dx%d))\n", zone.x, zone.y, zone.width, zone.height); - - indent(indentation); - printf("--dirty:\n"); - - for (DirtyRectList::const_iterator dirty = _dirtyRects.begin(); dirty != _dirtyRects.end(); ++dirty) { - indent(indentation + 1); - printf("dirty(%d,%d, (%dx%d))\n", dirty->x, dirty->y, dirty->width, dirty->height); - } - - _w_gfxwop_container_print_contents("contents", _contents, indentation); -} - - -GfxContainer::GfxContainer(rect_t area, gfxw_widget_type_t type_) - : GfxWidget(type_) { - _bounds = zone = area; - _contents = NULL; - _nextpp = &_contents; - - free_tagged = NULL; - free_contents = NULL; - add_dirty_abs = NULL; - add_dirty_rel = NULL; - add = NULL; - - _flags |= GFXW_FLAG_VISIBLE | GFXW_FLAG_CONTAINER; -} - -static int _gfxw_dirty_rect_overlaps_normal_rect(rect_t port_zone, rect_t bounds, rect_t dirty) { - bounds.x += port_zone.x; - bounds.y += port_zone.y; - - return gfx_rects_overlap(bounds, dirty); -} - -static int _gfxwop_container_draw_contents(GfxWidget *widget, GfxWidget *contents) { - GfxContainer *container = (GfxContainer *)widget; - GfxState *gfx_state = (widget->_visual) ? widget->_visual->_gfxState : ((GfxVisual *) widget)->_gfxState; - int draw_ports; - rect_t nullzone = {0, 0, 0, 0}; - - if (!contents) - return 0; - - DirtyRectList::iterator dirty = container->_dirtyRects.begin(); - while (dirty != container->_dirtyRects.end()) { - GfxWidget *seeker = contents; - - while (seeker) { - if (_gfxw_dirty_rect_overlaps_normal_rect(GFXW_IS_CONTAINER(seeker) ? nullzone : container->zone, - // Containers have absolute coordinates, reflect this. - seeker->_bounds, *dirty)) { - - if (GFXW_IS_CONTAINER(seeker)) {// Propagate dirty rectangles /upwards/ - DDIRTY(stderr, "container_draw_contents: propagate upwards (%d,%d,%d,%d ,0)\n", GFX_PRINT_RECT(*dirty)); - ((GfxContainer *)seeker)->add_dirty_abs((GfxContainer *)seeker, *dirty, 0); - } - - seeker->_flags |= GFXW_FLAG_DIRTY; - } - - seeker = seeker->_next; - } - - ++dirty; - } - - // The draw loop is executed twice: Once for normal data, and once for ports. - for (draw_ports = 0; draw_ports < 2; draw_ports++) { - - dirty = container->_dirtyRects.begin(); - while (dirty != container->_dirtyRects.end()) { - GfxWidget *seeker = contents; - // FIXME: Ugly hack to check whether this is the last dirty rect or not - DirtyRectList::iterator next = dirty; - ++next; - const bool isLastDirtyRect = (next == container->_dirtyRects.end()); - - while (seeker && (draw_ports || !GFXW_IS_PORT(seeker))) { - rect_t small_rect = *dirty; - bool draw_noncontainers = !_gfxop_clip(&small_rect, container->_bounds); - - if (seeker->_flags & GFXW_FLAG_DIRTY) { - - if (!GFXW_IS_CONTAINER(seeker) && draw_noncontainers) { - gfxop_set_clip_zone(gfx_state, small_rect); - } - /* Clip zone must be reset after each element, because we might - ** descend into containers. - ** Doing this is relatively cheap, though. */ - if (draw_noncontainers || GFXW_IS_CONTAINER(seeker)) - seeker->draw(Common::Point(container->zone.x, container->zone.y)); - - if (isLastDirtyRect) - seeker->_flags &= ~GFXW_FLAG_DIRTY; - } - - seeker = seeker->_next; - } - ++dirty; - } - } - // Remember that the dirty rects should be freed afterwards! - - return 0; -} - -GfxContainer::~GfxContainer() { - GfxWidget *seeker = _contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - delete seeker; - seeker = next; - } - - _dirtyRects.clear(); -} - -void GfxContainer::tag() { - // FIXME: Should we also tag this object itself? - GfxWidget *seeker = _contents; - while (seeker) { - seeker->tag(); - seeker = seeker->_next; - } -} - -int GfxContainer::setVisual(GfxVisual *visual) { - _visual = visual; - if (_parent) { - if (!(GFXW_IS_LIST(this) && !_contents)) { - DDIRTY(stderr, "set_visual::DOWNWARDS abs(%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(_bounds)); - _parent->add_dirty_abs(_parent, _bounds, 1); - } - } - - GfxWidget *seeker = _contents; - while (seeker) { - seeker->setVisual(visual); - seeker = seeker->_next; - } - return 0; -} - -static int _gfxwop_container_free_tagged(GfxContainer *container) { - GfxWidget *seeker = container->_contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - if (seeker->_flags & GFXW_FLAG_TAGGED) - delete seeker; - seeker = next; - } - - return 0; -} - -static int _gfxwop_container_free_contents(GfxContainer *container) { - GfxWidget *seeker = container->_contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - delete seeker; - seeker = next; - } - return 0; -} - -static void _gfxw_dirtify_container(GfxContainer *container, GfxWidget *widget) { - if (GFXW_IS_CONTAINER(widget)) - container->add_dirty_abs(container, widget->_bounds, 1); - else - container->add_dirty_rel(container, widget->_bounds, 1); -} - -static int _parentize_widget(GfxContainer *container, GfxWidget *widget) { - if (widget->_parent) { - printf("_parentize_widget(): Attempt to give second parent node to widget!\nWidget:"); - widget->print(3); - printf("\nContainer:"); - container->print(3); - error("Error in _parentize_widget()"); - return 1; - } - - widget->_parent = container; - - if (GFXW_IS_VISUAL(container)) - widget->setVisual((GfxVisual *)container); - else if (container->_visual) - widget->setVisual(container->_visual); - - return 0; -} - -static int _gfxw_container_id_equals(GfxContainer *container, GfxWidget *widget) { - GfxWidget **seekerp = &(container->_contents); - - if (GFXW_IS_PORT(widget)) - return 0; - - if (widget->_ID == GFXW_NO_ID) - return 0; - - while (*seekerp && ((*seekerp)->_ID != widget->_ID || (*seekerp)->_subID != widget->_subID)) - seekerp = &((*seekerp)->_next); - - if (!*seekerp) - return 0; - - if ((*seekerp)->equals(*seekerp, widget) && !(*seekerp)->should_replace(*seekerp, widget)) { - delete widget; - (*seekerp)->_flags &= ~GFXW_FLAG_TAGGED; - return 1; - } else { - if (!(widget->_flags & GFXW_FLAG_MULTI_ID)) - delete *seekerp; - return 0; - } -} - -static int _gfxwop_container_add_dirty(GfxContainer *container, rect_t dirty, int propagate) { -#if 0 - // This code has been disabled because containers may contain sub-containers with - // bounds greater than their own. - if (_gfxop_clip(&dirty, container->_bounds)) - return 0; -#endif - - DDIRTY(stderr, "Effectively adding dirty %d,%d,%d,%d %d to ID %d\n", GFX_PRINT_RECT(dirty), propagate, container->_ID); - gfxdr_add_dirty(container->_dirtyRects, dirty); - return 0; -} - -static int _gfxwop_container_add(GfxContainer *container, GfxWidget *widget) { - if (_gfxw_container_id_equals(container, widget)) - return 0; - - if (_parentize_widget(container, widget)) - return 1; - - if (!(GFXW_IS_LIST(widget) && (!((GfxContainer *)widget)->_contents))) { // Don't dirtify self on empty lists - DDIRTY(stderr, "container_add: dirtify DOWNWARDS (%d,%d,%d,%d, 1)\n", GFX_PRINT_RECT(widget->_bounds)); - _gfxw_dirtify_container(container, widget); - } - - *(container->_nextpp) = widget; - container->_nextpp = &(widget->_next); - - return 0; -} - -//*** Lists and sorted lists *** - -int GfxList::draw(const Common::Point &pos) { - if (_type == GFXW_LIST) { - DRAW_ASSERT(this, GFXW_LIST); - - _gfxwop_container_draw_contents(this, _contents); - _flags &= ~GFXW_FLAG_DIRTY; - } else { - DRAW_ASSERT(this, GFXW_SORTED_LIST); - - _gfxwop_container_draw_contents(this, _contents); - } - _dirtyRects.clear(); - - return 0; -} - - -void GfxList::print(int indentation) const { - printIntern(indentation); - - if (_type == GFXW_LIST) - printf("LIST"); - else if (_type == GFXW_SORTED_LIST) - printf("SORTED_LIST"); - else - error("GfxList::print: Invalid type %d", _type); - - GfxContainer::print(indentation); -} - -static int _gfxwop_list_equals(GfxWidget *widget, GfxWidget *other) { - // Requires identical order of list elements. - GfxList *wlist, *olist; - - if (widget->_type != other->_type) - return 0; - - if (!GFXW_IS_LIST(widget)) { - warning("[GFX] _gfxwop_list_equals(): Method called on non-list"); - widget->print(0); - printf("\n"); - return 0; - } - - wlist = (GfxList *)widget; - olist = (GfxList *)other; - - if (memcmp(&(wlist->_bounds), &(olist->_bounds), sizeof(rect_t))) - return 0; - - widget = wlist->_contents; - other = olist->_contents; - - while (widget && other) { - if (!(widget->equals(widget, other) && !widget->should_replace(widget, other))) - return 0; - - widget = widget->_next; - other = other->_next; - } - - return (!widget && !other); // True if both are finished now -} - -static int _gfxwop_list_add_dirty(GfxContainer *container, rect_t dirty, int propagate) { - // Lists add dirty boxes to both themselves and their parenting port/visual - - container->_flags |= GFXW_FLAG_DIRTY; - - DDIRTY(stderr, "list_add_dirty %d,%d,%d,%d %d\n", GFX_PRINT_RECT(dirty), propagate); - if (propagate) - if (container->_parent) { - DDIRTY(stderr, "->PROPAGATING\n"); - container->_parent->add_dirty_abs(container->_parent, dirty, 1); - } - - return _gfxwop_container_add_dirty(container, dirty, propagate); -} - -int _gfxwop_ordered_add(GfxContainer *container, GfxWidget *widget, int compare_all) { - // O(n) - GfxWidget **seekerp = &(container->_contents); - - if (widget->_next) { - printf("_gfxwop_ordered_add(): Attempt to add widget to two lists!\nWidget:"); - widget->print(3); - printf("\nList:"); - container->print(3); - error("Error in _gfxwop_ordered_add()"); - } - - if (_gfxw_container_id_equals(container, widget)) - return 0; - - while (*seekerp && (compare_all || (widget->compare_to(widget, *seekerp) >= 0))) { - - if (widget->equals(widget, *seekerp)) { - if (compare_all) { - if ((*seekerp)->_visual) - delete *seekerp; // If it's a fresh widget - else - gfxw_annihilate(*seekerp); - - return _gfxwop_ordered_add(container, widget, compare_all); // We might have destroyed the container's contents - } else { - widget->_next = (*seekerp)->_next; - delete *seekerp; - *seekerp = widget; - return (_parentize_widget(container, widget)); - } - } - - if (*seekerp) - seekerp = &((*seekerp)->_next); - } - - widget->_next = *seekerp; - *seekerp = widget; - - return _parentize_widget(container, widget); -} - -static int _gfxwop_sorted_list_add(GfxContainer *container, GfxWidget *widget) { - // O(n) - return _gfxwop_ordered_add(container, widget, 0); -} - -void _gfxw_set_ops_LIST(GfxContainer *list, char sorted) { - _gfxw_set_container_ops((GfxContainer *)list, - _gfxwop_basic_compare_to, sorted ? _gfxwop_basic_equals : _gfxwop_list_equals, - _gfxwop_basic_superarea_of, - _gfxwop_container_free_tagged, _gfxwop_container_free_contents, - _gfxwop_list_add_dirty, sorted ? _gfxwop_sorted_list_add : _gfxwop_container_add); -} - -GfxList *gfxw_new_list(rect_t area, int sorted) { - return new GfxList(area, sorted); -} - -GfxList::GfxList(rect_t area, bool sorted) - : GfxContainer(area, sorted ? GFXW_SORTED_LIST : GFXW_LIST) { - - _gfxw_set_ops_LIST(this, sorted); -} - - - -//*** Visuals *** - -int GfxVisual::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_VISUAL); - - for (DirtyRectList::iterator dirty = _dirtyRects.begin(); dirty != _dirtyRects.end(); ++dirty) { - gfxop_clear_box(_gfxState, *dirty); - } - - _gfxwop_container_draw_contents(this, _contents); - - _dirtyRects.clear(); - _flags &= ~GFXW_FLAG_DIRTY; - - return 0; -} - -void GfxVisual::print(int indentation) const { - printIntern(indentation); - printf("VISUAL; ports={"); - for (uint i = 0; i < _portRefs.size(); i++) { - if (_portRefs[i]) { - if (i != 0) - printf(","); - printf("%d", i); - } - } - printf("}\n"); - - GfxContainer::print(indentation); -} - -int GfxVisual::setVisual(GfxVisual *visual) { - if (this != visual) { - warning("Attempt to set a visual's parent visual to something else"); - } else { - warning("Attempt to set a visual's parent visual to itself"); - } - - return 1; -} - -void _gfxw_set_ops_VISUAL(GfxContainer *visual) { - _gfxw_set_container_ops((GfxContainer *)visual, - _gfxwop_basic_compare_to, - _gfxwop_basic_equals, _gfxwop_basic_superarea_of, - _gfxwop_container_free_tagged, _gfxwop_container_free_contents, - _gfxwop_container_add_dirty, _gfxwop_container_add); -} - -GfxVisual::GfxVisual(GfxState *state, int font) - : GfxContainer(gfx_rect(0, 0, 320, 200), GFXW_VISUAL) { - - _font = font; - _gfxState = state; - - _gfxw_set_ops_VISUAL(this); -} - -GfxVisual::~GfxVisual() { - // HACK: We must dispose all content *here* already, because our child widgets - // still may have references to this object, and will try to invoke methods - // of this object which try to access the already cleared _portRefs array - // when they are destroyed. - GfxWidget *seeker = _contents; - - while (seeker) { - GfxWidget *next = seeker->_next; - delete seeker; - seeker = next; - } - _contents = 0; -} - -static int _visual_find_free_ID(GfxVisual *visual) { - uint id = 0; - - while (id < visual->_portRefs.size() && visual->_portRefs[id]) - id++; - - if (id == visual->_portRefs.size()) { // Out of ports? - visual->_portRefs.push_back(0); - } - - return id; -} - -//*** Ports *** - -int GfxPort::draw(const Common::Point &pos) { - DRAW_ASSERT(this, GFXW_PORT); - - if (_decorations) { - DDIRTY(stderr, "Getting/applying deco dirty (multi)\n"); - - DDIRTY(stderr, "Adding multiple dirty to #%d\n", _decorations->_ID); - for (DirtyRectList::iterator dirty = _dirtyRects.begin(); dirty != _dirtyRects.end(); ++dirty) { - gfxdr_add_dirty(_decorations->_dirtyRects, *dirty); - } - - if (_decorations->draw(gfxw_point_zero)) { - _decorations->_dirtyRects.clear(); - return 1; // error - } - _decorations->_dirtyRects.clear(); - } - - _gfxwop_container_draw_contents(this, _contents); - - _dirtyRects.clear(); - _flags &= ~GFXW_FLAG_DIRTY; - - return 0; -} - -GfxPort::~GfxPort() { - if (_visual) { - if (_ID < 0 || _ID >= (int)_visual->_portRefs.size()) { - error("Attempt to free port #%d; allowed: [0..%d]", _ID, _visual->_portRefs.size()); - } - - if (_visual->_portRefs[_ID] != this) { - warning("[GFX] While freeing port %d: Port is at %p, but port list indicates %p", _ID, (void *)this, (void *)_visual->_portRefs[_ID]); - } else - _visual->_portRefs[_ID] = NULL; - - } - - delete _decorations; -} - -void GfxPort::print(int indentation) const { - printIntern(indentation); - printf("PORT"); - printf(" font=%d drawpos=(%d,%d)", _font, draw_pos.x, draw_pos.y); - if (gray_text) - printf(" (gray)"); - - GfxContainer::print(indentation); - _w_gfxwop_container_print_contents("decorations", _decorations, indentation); -} - -static int _gfxwop_port_superarea_of(GfxWidget *self, GfxWidget *other) { - GfxPort *port = (GfxPort *) self; - - if (!port->port_bg) - return _gfxwop_basic_superarea_of(self, other); - - return port->port_bg->superarea_of(port->port_bg, other); -} - -int GfxPort::setVisual(GfxVisual *visual) { - _visual = visual; - - if (_decorations) - if (_decorations->setVisual(visual)) { - warning("[GFX] Setting the visual for decorations failed for port "); - this->print(1); - return 1; - } - - return GfxContainer::setVisual(visual); -} - -static int _gfxwop_port_add_dirty(GfxContainer *widget, rect_t dirty, int propagate) { - GfxPort *self = (GfxPort *) widget; - - self->_flags |= GFXW_FLAG_DIRTY; - - _gfxwop_container_add_dirty(widget, dirty, propagate); - - DDIRTY(stderr, "Added dirty to ID %d\n", widget->_ID); - DDIRTY(stderr, "dirty= (%d,%d,%d,%d) bounds (%d,%d,%d,%d)\n", dirty.x, dirty.x, dirty.width, dirty.height, - widget->_bounds.x, widget->_bounds.y, widget->_bounds.width, widget->_bounds.height); -#if 0 - // FIXME: This is a worthwhile optimization - if (self->port_bg) { - GfxWidget foo; - - foo.bounds = dirty; // Yeah, sub-elegant, I know - foo.bounds.x -= self->zone.x; - foo.bounds.y -= self->zone.y; - if (self->port_bg->superarea_of(self->port_bg, &foo)) { - GfxContainer *parent = self->_parent; - while (parent) { - fprintf(stderr, "Dirtifying parent id %d\n", parent->_ID); - parent->_flags |= GFXW_FLAG_DIRTY; - parent = parent->_parent; - } - return 0; - } - } // else propagate to the parent, since we're not 'catching' the dirty rect -#endif - - if (propagate) - if (self->_parent) { - DDIRTY(stderr, "PROPAGATE\n"); - return self->_parent->add_dirty_abs(self->_parent, dirty, 1); - } - - return 0; -} - -static int _gfxwop_port_add(GfxContainer *container, GfxWidget *widget) { - // O(n) - return _gfxwop_ordered_add(container, widget, 1); -} - -void _gfxw_set_ops_PORT(GfxContainer *widget) { - _gfxw_set_container_ops((GfxContainer *)widget, - _gfxwop_basic_compare_to, _gfxwop_basic_equals, _gfxwop_port_superarea_of, - _gfxwop_container_free_tagged, _gfxwop_container_free_contents, - _gfxwop_port_add_dirty, _gfxwop_port_add); -} - -GfxPort::GfxPort(GfxVisual *visual_, rect_t area, gfx_color_t fgcolor, gfx_color_t bgcolor_) - : GfxContainer(area, GFXW_PORT) { - VERIFY_WIDGET(visual_); - - port_bg = NULL; - _parent = NULL; - _decorations = NULL; - draw_pos = Common::Point(0, 0); - gray_text = 0; - _color = fgcolor; - _bgcolor = bgcolor_; - _font = visual_->_font; - _ID = _visual_find_free_ID(visual_); - visual_->_portRefs[_ID] = this; - - _gfxw_set_ops_PORT(this); -} - -void gfxw_port_auto_restore_background(GfxVisual *visual, GfxPort *window, rect_t auto_rect) { - window->port_flags |= kWindowAutoRestore; - window->restore_snap = gfxw_make_snapshot(visual, auto_rect); -} - -GfxPort *gfxw_remove_port(GfxVisual *visual, GfxPort *port) { - GfxPort *parent; - VERIFY_WIDGET(visual); - VERIFY_WIDGET(port); - - if (!visual->_contents) { - warning("[GFX] Attempt to remove port from empty visual"); - return NULL; - } - - parent = (GfxPort *)port->_parent; - if (port->port_flags & kWindowAutoRestore) - gfxw_restore_snapshot(visual, port->restore_snap); - - delete port; - - while (parent && !GFXW_IS_PORT(parent)) - parent = (GfxPort *)parent->_parent; // Ascend through ancestors - - return parent; -} - -GfxPort *gfxw_find_default_port(GfxVisual *visual) { - int id = visual->_portRefs.size(); - - while (id--) { - GfxPort *port = visual->_portRefs[id]; - - if (port) - return port; - } - - return NULL; -} - -// - other functions - - -GfxWidget *gfxw_set_id(GfxWidget *widget, int ID, int subID) { - if (widget) { - widget->_ID = ID; - widget->_subID = subID; - } - - return widget; -} - -GfxDynView *gfxw_dyn_view_set_params(GfxDynView *widget, int under_bits, const ObjVarRef& under_bitsp, int signal, const ObjVarRef& signalp) { - if (!widget) - return NULL; - - widget->under_bits = under_bits; - widget->under_bitsp = under_bitsp; - widget->signal = signal; - widget->signalp = signalp; - - return widget; -} - -GfxWidget *gfxw_remove_id(GfxContainer *container, int ID, int subID) { - GfxWidget **wp = &(container->_contents); - - while (*wp) { - if ((*wp)->_ID == ID && (subID == GFXW_NO_ID || (*wp)->_subID == subID)) { - GfxWidget *widget = *wp; - - *wp = (*wp)->_next; - widget->_next = NULL; - widget->_parent = NULL; - widget->_visual = NULL; - - return widget; - } - - wp = &((*wp)->_next); - } - - return NULL; -} - -GfxWidget *gfxw_hide_widget(GfxWidget *widget) { - if (widget->_flags & GFXW_FLAG_VISIBLE) { - widget->_flags &= ~GFXW_FLAG_VISIBLE; - - if (widget->_parent) - widget->_parent->add_dirty_rel(widget->_parent, widget->_bounds, 1); - } - - return widget; -} - -GfxWidget *gfxw_show_widget(GfxWidget *widget) { - if (!(widget->_flags & GFXW_FLAG_VISIBLE)) { - widget->_flags |= GFXW_FLAG_VISIBLE; - - if (widget->_parent) - widget->_parent->add_dirty_rel(widget->_parent, widget->_bounds, 1); - } - - return widget; -} - -gfxw_snapshot_t *gfxw_make_snapshot(GfxVisual *visual, rect_t area) { - gfxw_snapshot_t *retval = (gfxw_snapshot_t*)malloc(sizeof(gfxw_snapshot_t)); - - retval->serial = widget_serial_number_counter++; - - retval->area = area; - - // Work around subset semantics in gfx_rect_subset. - // This fixes the help icon in LSL5. */ - if (retval->area.width == 320) - retval->area.width = 321; - - return retval; -} - -int gfxw_widget_matches_snapshot(gfxw_snapshot_t *snapshot, GfxWidget *widget) { - int free_below = (snapshot->serial < widget_serial_number_counter) ? 0 : widget_serial_number_counter; - int free_above_eq = snapshot->serial; - rect_t bounds = widget->_bounds; - - if (!GFXW_IS_CONTAINER(widget) && widget->_parent) { - bounds.x += widget->_parent->_bounds.x; - bounds.y += widget->_parent->_bounds.y; - } - - // Note: the check for snapshot->area and bounds is NOT the same as contains() in Common::Rect - // (this one includes equality too) - return ((widget->_serial >= free_above_eq || widget->_serial < free_below) && - (snapshot->area.x <= bounds.x && snapshot->area.y <= bounds.y && - snapshot->area.x + snapshot->area.width >= bounds.x + bounds.width && - snapshot->area.y + snapshot->area.height >= bounds.y + bounds.height)); -} - -#define MAGIC_FREE_NUMBER -42 - -void _gfxw_free_contents_appropriately(GfxContainer *container, gfxw_snapshot_t *snapshot, int priority) { - GfxWidget *widget = container->_contents; - - while (widget) { - GfxWidget *next = widget->_next; - - if (gfxw_widget_matches_snapshot(snapshot, widget) && !(widget->_flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS) - && (priority == MAGIC_FREE_NUMBER || priority <= widget->_widgetPriority || widget->_widgetPriority == -1)) { - delete widget; - } else { - if (GFXW_IS_CONTAINER(widget)) - _gfxw_free_contents_appropriately((GfxContainer *)widget, snapshot, priority); - } - - widget = next; - } -} - -gfxw_snapshot_t *gfxw_restore_snapshot(GfxVisual *visual, gfxw_snapshot_t *snapshot) { - _gfxw_free_contents_appropriately((GfxContainer *)visual, snapshot, MAGIC_FREE_NUMBER); - - return snapshot; -} - -void gfxw_annihilate(GfxWidget *widget) { - GfxVisual *visual = widget->_visual; - int widget_priority = 0; - int free_overdrawn = 0; - - gfxw_snapshot_t snapshot; - if (!GFXW_IS_CONTAINER(widget) && widget->_parent && visual && (widget->_flags & GFXW_FLAG_VISIBLE)) { - snapshot.serial = 0; - snapshot.area = widget->_bounds; - snapshot.area.x += widget->_parent->zone.x; - snapshot.area.y += widget->_parent->zone.y; - free_overdrawn = 1; - widget_priority = widget->_widgetPriority; - } - - delete widget; - - if (free_overdrawn) - _gfxw_free_contents_appropriately((GfxContainer *)visual, &snapshot, widget_priority); -} - -GfxDynView *gfxw_picviewize_dynview(GfxDynView *dynview) { - dynview->_type = GFXW_PIC_VIEW; - dynview->_flags |= GFXW_FLAG_DIRTY; - - _gfxw_set_ops_PICVIEW(dynview); - - if (dynview->_parent) - _gfxw_dirtify_container(dynview->_parent, dynview); - - return dynview; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/gfx_widgets.h b/engines/sci/gfx/gfx_widgets.h deleted file mode 100644 index d30af8ce4e..0000000000 --- a/engines/sci/gfx/gfx_widgets.h +++ /dev/null @@ -1,477 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_GFX_WIDGETS_H -#define SCI_GFX_GFX_WIDGETS_H - -#include "common/rect.h" - -#include "sci/engine/vm.h" -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/operations.h" - -namespace Sci { -/** @name Widget Graphical State Management */ -/** @{ */ - -struct GfxState; -struct GfxBox; -struct GfxDynView; -struct GfxContainer; -struct GfxList; -struct GfxPort; -struct GfxPrimitive; -struct gfxw_snapshot_t; -struct GfxText; -struct GfxView; -struct GfxVisual; -struct GfxWidget; - - -/* Enable the next line to keep a list of pointers to all widgets, with up to the specified amount -** of members (/SLOW/) */ -//#define GFXW_DEBUG_WIDGETS 2048 - -/* Terminology -** -** Two special terms are used in here: /equivalent/ and /clear/. Their meanings -** in this context are as follows: -** -** /clear/: Clearing a widget means overwriting the space it occupies in the back -** buffer with data from the static buffer. This affects both the visual and the -** priority buffer, the static buffer (and any effect the widget may have had on -** it) is not touched. -** -** /equivalent/: Two Widgets A and B are equivalent if and only if either of the -** following conditions is met: -** a) Both A and B are text widgets, and they occupy the same bounding rectangle. -** b) Both A and B are dynview widgets, and they have the same unique ID -** Note that /equivalent/ is not really an equivalence relation- while it is ob- -** viously transitive and symmetrical, it is not reflexive (e.g. a box widget -** is not /equivalent/ to itself), although this might be a nice addition for the -** future. -*/ - - -/*********************************/ -/* Fundamental widget operations */ -/*********************************/ - - -/* gfxw_point_zero is declared in gfx/widgets.cpp */ -extern Common::Point gfxw_point_zero; - -/*********************/ -/* Widget operations */ -/*********************/ - -/* These are for documentation purposes only. The actual declarations are in -** gfx_state_internal.h. -** -** -** ************************** -** ** Container operations ** -** ************************** -** -** -** -- free_tagged(GfxContainer *self) -** Frees all tagged resources in the container -** Parameters: (GfxContainer *) self: self reference -** Returns : (int) 0 -** The container itself is never freed in this way. -** -** -** -- free_contents(GfxContainer *self) -** Frees all resources contained in the container -** Parameters: (GfxContainer *) self: self reference -** Returns : (int) 0 -** -** -** -- add_dirty_abs(GfxContainer *self, rect_t dirty, int propagate) -** Adds a dirty rectangle to the container's list of dirty rects -** Parameters: (GfxContainer *) self: self reference -** (rect_t) dirty: The rectangular screen area that is to be flagged -** as dirty, absolute to the screen -** (int) propagate: Whether the dirty rect should be propagated to the -** widget's parents -** Returns : (int) 0 -** Transparent containers will usually pass this value to their next ancestor, -** because areas below them might have to be redrawn. -** -** -** -- add_dirty_rel(GfxContainer *self, rect_t dirty, int propagate) -** Adds a dirty rectangle to the container's list of dirty rects -** Parameters: (GfxContainer *) self: self reference -** (rect_t) dirty: The rectangular screen area that is to be flagged -** as dirty, relative to the widget -** (int) propagate: Whether the dirty rect should be propagated to the -** widget's parents -** Returns : (int) 0 -** Transparent containers will usually pass this value to their next ancestor, -** because areas below them might have to be redrawn. -** -** -** -- add(GfxContainer *self, GfxWidget *widget) -** Adds a widget to the list of contained widgets -** Parameters: (GfxContainer *) self: self reference -** (GfxWidget *) widget: The widget to add -** Returns : (int) 0 -** Sorted lists sort their content into the list rather than adding it to the -** end. -*/ - - -/***************************/ -/* Basic widget generation */ -/***************************/ - -/*-- 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 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); - -/** - * 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 */ -}; - -/** - * 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); - - -/** - * 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); - -/** - * 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); - -/** - * 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); - -/** - * 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); - -/** - * 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 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); - -/** - * Marks a widget as "abandoned" - * - * @param[in] widget The widget to abandon - * @return The widget - */ -GfxWidget *gfxw_abandon_widget(GfxWidget *widget); - -/** 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); - -/** - * 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); - -/** - * 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); - -/** - * 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 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); - -/** - * 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); - -/** - * 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); - -/** - * 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); - -/** - * 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); - -/** - * 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); - -/** - * 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 - -#endif diff --git a/engines/sci/gfx/menubar.cpp b/engines/sci/gfx/menubar.cpp deleted file mode 100644 index 8dcefdcd34..0000000000 --- a/engines/sci/gfx/menubar.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -/* Management and drawing operations for the SCI0 menu bar */ -/* I currently assume that the hotkey information used in the menu bar is NOT -** used for any actual actions on behalf of the interpreter. -*/ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/event.h" -#include "sci/engine/state.h" -#include "sci/gfx/menubar.h" -#include "sci/gui/gui.h" -#include "sci/engine/kernel.h" - -namespace Sci { - - -/* Copies a string into a newly allocated memory part, up to a certain length. -** Parameters: (char *) src: The source string -** (int) length: The maximum length of the string (not counting -** a trailing \0). -** Returns : (char *) The resulting copy, allocated with malloc(). -** To free this string, use the free() command. -** See _SCI_MALLOC() for more information if call fails. -*/ -char *sci_strndup(const char *src, size_t length) { - assert(src); - - size_t rlen = (int)MIN(strlen(src), length) + 1; - char *strres = (char *)malloc(rlen); - assert(strres); - - strncpy(strres, src, rlen); - strres[rlen - 1] = 0; - - return strres; -} - - -#define SIZE_INF 32767 - -Menu::Menu() { - _titleWidth = 0; - _width = 0; -} - -MenuItem::MenuItem() { - _type = MENU_TYPE_NORMAL; - _flags = 0; - memset(_said, 0, sizeof(_said)); - _saidPos = NULL_REG; - _textPos = NULL_REG; - _modifiers = 0; - _key = 0; - _enabled = 0; - _tag = 0; -} - -int Menu::addMenuItem(GfxState *state, MenuType type, const char *left, const char *right, - int font, int key, int modifiers, int tag, reg_t text_pos) { -// Returns the total text size, plus MENU_BOX_CENTER_PADDING if (right != NULL) - MenuItem newItem; - MenuItem *item; - int total_left_size = 0; - int16 width = 10, height = 10; - EngineState *s = ((SciEngine *)g_engine)->getEngineState(); // HACK - - item = &newItem; - item->_type = type; - - if (type == MENU_TYPE_HBAR) { - _items.push_back(newItem); - return 0; - } - - // else assume MENU_TYPE_NORMAL - item->_text = left; - if (right) { - item->_keytext = right; - item->_keytext.trim(); // Remove trailing whitespace - item->_flags = MENU_ATTRIBUTE_FLAGS_KEY; - item->_key = key; - item->_modifiers = modifiers; - } else { - item->_flags = 0; - } - - if (right) { - s->_gui->textSize(item->_keytext.c_str(), font, -1, &width, &height); - total_left_size = MENU_BOX_CENTER_PADDING + width; - } - - item->_enabled = 1; - item->_tag = tag; - item->_textPos = text_pos; - s->_gui->textSize(left, font, -1, &width, &height); - - _items.push_back(newItem); - - return total_left_size + width; -} - -void Menubar::addMenu(GfxState *state, const Common::String &title, const Common::String &entries, int font, reg_t entries_base) { - char tracker; - char *left = NULL; - reg_t left_origin = entries_base; - int string_len = 0; - int tag = 0, c_width, max_width = 0; - int16 height = 10; - EngineState *s = ((SciEngine *)g_engine)->getEngineState(); // HACK - - Menu menu; - - menu._title = title; - menu._titleWidth = 10; - - s->_gui->textSize(title.c_str(), font, -1, &(menu._titleWidth), &height); - - const char *entries_p = entries.c_str(); - - do { - tracker = *entries_p++; - entries_base.offset++; - - if (!left) { // Left string not finished? - if (tracker == '=') { // Hit early-SCI tag assignment? - left = sci_strndup(entries_p - string_len - 1, string_len); - tag = atoi(entries_p++); - tracker = *entries_p++; - } - if ((tracker == 0 && string_len > 0) || (tracker == '=') || (tracker == ':')) { // End of entry - MenuType entrytype = MENU_TYPE_NORMAL; - char *inleft; - reg_t beginning; - - if (!left) - left = sci_strndup(entries_p - string_len - 1, string_len); - - inleft = left; - while (isspace((unsigned char)*inleft)) - inleft++; // Seek beginning of actual string - - if (!strncmp(inleft, MENU_HBAR_STRING_1, strlen(MENU_HBAR_STRING_1)) - || !strncmp(inleft, MENU_HBAR_STRING_2, strlen(MENU_HBAR_STRING_2)) - || !strncmp(inleft, MENU_HBAR_STRING_3, strlen(MENU_HBAR_STRING_3))) { - entrytype = MENU_TYPE_HBAR; // Horizontal bar - free(left); - left = NULL; - } - - beginning = entries_base; - beginning.offset -= string_len + 1; -#ifdef INCLUDE_OLDGFX - c_width = menu.addMenuItem(state, entrytype, left, NULL, font, 0, 0, tag, beginning); -#endif - if (c_width > max_width) - max_width = c_width; - - string_len = 0; - free(left); - left = NULL; // Start over - } else if (tracker == '`') { // Start of right string - if (!left) { - left_origin = entries_base; - left_origin.offset -= string_len + 1; - left = sci_strndup(entries_p - string_len - 1, string_len); - } - string_len = 0; // Continue with the right string - } else - string_len++; // Nothing special - - } else { // Left string finished => working on right string - if ((tracker == ':') || (tracker == 0)) { // End of entry - int key, modifiers = 0; - - char *right = sci_strndup(entries_p - string_len - 1, string_len); - - if (right[0] == '#') { - right[0] = SCI_SPECIAL_CHAR_FUNCTION; // Function key - - key = SCI_KEY_F1 + ((right[1] - '1') << 8); - - if (right[1] == '0') - key = SCI_KEY_F10; // F10 - - if (right[2] == '=') { - tag = atoi(right + 3); - right[2] = 0; - }; - } else if (right[0] == '@') { // Alt key - right[0] = SCI_SPECIAL_CHAR_ALT; // ALT - key = right[1]; - modifiers = SCI_KEYMOD_ALT; - - if ((key >= 'a') && (key <= 'z')) - right[1] = key - 'a' + 'A'; - - if (right[2] == '=') { - tag = atoi(right + 3); - right[2] = 0; - } - } else { - if (right[0] == '^') { - right[0] = SCI_SPECIAL_CHAR_CTRL; // Control key - there must be a replacement... - key = right[1]; - modifiers = SCI_KEYMOD_CTRL; - - if ((key >= 'a') && (key <= 'z')) - right[1] = key - 'a' + 'A'; - - if (right[2] == '=') { - tag = atoi(right + 3); - right[2] = 0; - } - } else { - key = right[0]; - if ((key >= 'a') && (key <= 'z')) - right[0] = key - 'a' + 'A'; - - if (right[1] == '=') { - tag = atoi(right + 2); - right[1] = 0; - } - } - if ((key >= 'A') && (key <= 'Z')) - key = key - 'A' + 'a'; // Lowercase the key - } - - int i = strlen(right); - - while (i > 0 && right[--i] == ' ') - right[i] = 0; // Cut off chars to the right - - c_width = menu.addMenuItem(state, MENU_TYPE_NORMAL, left, right, font, key, - modifiers, tag, left_origin); - tag = 0; - if (c_width > max_width) - max_width = c_width; - - string_len = 0; - free(right); - free(left); - left = NULL; // Start over - - } else - string_len++; // continuing entry - } // right string finished - } while (tracker); - - menu._width = max_width; - - _menus.push_back(menu); -} - -bool MenuItem::matchKey(int message, int modifiers) { - if ((_key == message) && ((modifiers & (SCI_KEYMOD_CTRL | SCI_KEYMOD_ALT)) == _modifiers)) - return true; - - if (message == '\t' && _key == 'i' && ((modifiers & (SCI_KEYMOD_CTRL | SCI_KEYMOD_ALT)) == 0) && _modifiers == SCI_KEYMOD_CTRL) - return true; // Match TAB to ^I - - return 0; -} - -int Menubar::setAttribute(EngineState *s, int menu_nr, int item_nr, int attribute, reg_t value) { - MenuItem *item; - - if ((menu_nr < 0) || (item_nr < 0)) - return 1; - - if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size())) - return 1; - - item = &_menus[menu_nr]._items[item_nr]; - - switch (attribute) { - - case MENU_ATTRIBUTE_SAID: - if (value.segment) { - item->_saidPos = value; - s->_segMan->memcpy(item->_said, value, MENU_SAID_SPEC_SIZE); // Copy Said spec - item->_flags |= MENU_ATTRIBUTE_FLAGS_SAID; - - } else - item->_flags &= ~MENU_ATTRIBUTE_FLAGS_SAID; - - break; - - case MENU_ATTRIBUTE_TEXT: - assert(value.segment); - item->_text = s->_segMan->getString(value); - item->_textPos = value; - break; - - case MENU_ATTRIBUTE_KEY: - item->_keytext.clear(); - - if (value.segment) { - - // FIXME: What happens here if <value> is an extended key? Potential bug. LS - item->_key = value.offset; - item->_modifiers = 0; - item->_keytext = value.offset; - item->_flags |= MENU_ATTRIBUTE_FLAGS_KEY; - if ((item->_key >= 'A') && (item->_key <= 'Z')) - item->_key = item->_key - 'A' + 'a'; // Lowercase the key - } else { - item->_flags &= ~MENU_ATTRIBUTE_FLAGS_KEY; - } - break; - - case MENU_ATTRIBUTE_ENABLED: - item->_enabled = value.offset; - break; - - case MENU_ATTRIBUTE_TAG: - item->_tag = value.offset; - break; - - default: - error("Attempt to set invalid attribute of menu %d, item %d: 0x%04x", menu_nr, item_nr, attribute); - return 1; - } - - return 0; -} - -reg_t Menubar::getAttribute(int menu_nr, int item_nr, int attribute) const { - if ((menu_nr < 0) || (item_nr < 0)) - return SIGNAL_REG; - - if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size())) - return SIGNAL_REG; - - const MenuItem &item = _menus[menu_nr]._items[item_nr]; - - switch (attribute) { - case MENU_ATTRIBUTE_SAID: - return item._saidPos; - - case MENU_ATTRIBUTE_TEXT: - return item._textPos; - - case MENU_ATTRIBUTE_KEY: - return make_reg(0, item._key); - - case MENU_ATTRIBUTE_ENABLED: - return make_reg(0, item._enabled); - - case MENU_ATTRIBUTE_TAG: - return make_reg(0, item._tag); - - default: - warning("Attempt to read invalid attribute from menu %d, item %d: 0x%04x", menu_nr, item_nr, attribute); - return SIGNAL_REG; - } -} - -bool Menubar::itemValid(int menu_nr, int item_nr) const { - if ((menu_nr < 0) || (item_nr < 0)) - return false; - - if ((menu_nr >= (int)_menus.size()) || (item_nr >= (int)_menus[menu_nr]._items.size())) - return false; - - const MenuItem &item = _menus[menu_nr]._items[item_nr]; - - if ((item._type == MENU_TYPE_NORMAL) && item._enabled) - return true; - - return false; // May not be selected -} - -bool Menubar::mapPointer(const Common::Point &pointerPos, int &menu_nr, int &item_nr, Common::Rect portBounds) const { - - if (pointerPos.y <= 10) { // Re-evaulate menu - int x = MENU_LEFT_BORDER; - - for (uint i = 0; i < _menus.size(); i++) { - int newx = x + MENU_BORDER_SIZE * 2 + _menus[i]._titleWidth; - - if (pointerPos.x < x) - return false; - - if (pointerPos.x < newx) { - menu_nr = i; - item_nr = -1; - } - - x = newx; - } - } else { - int row = (pointerPos.y / 10) - 1; - - if ((menu_nr < 0) || (menu_nr >= (int)_menus.size())) - return true; // No menu - - const Menu &menu = _menus[menu_nr]; // Menu is valid, assume that it's popped up - - if ((int)menu._items.size() <= row) - return true; - - if ((pointerPos.x < portBounds.left) || (pointerPos.x > portBounds.right)) - return true; - - if (itemValid(menu_nr, row)) - item_nr = row; // Only modify if we'll be hitting a valid element - - } - - return false; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/menubar.h b/engines/sci/gfx/menubar.h deleted file mode 100644 index 6208c16e02..0000000000 --- a/engines/sci/gfx/menubar.h +++ /dev/null @@ -1,232 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -/* Header for SCI0 menu bar management */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_SCI_MENUBAR_H -#define SCI_GFX_SCI_MENUBAR_H - -#include "sci/engine/vm_types.h" -#include "sci/gfx/operations.h" - -#include "common/array.h" -#include "common/rect.h" - -namespace Sci { - -struct EngineState; - -#define MENU_HBAR_STRING_1 "--!" -#define MENU_HBAR_STRING_2 "-!" -#define MENU_HBAR_STRING_3 "!--" -/* These strings are used in SCI to determine an empty menu line */ - -#define MENU_BORDER_SIZE 0 -/* The number of pixels added to the left and right to the text of a menu on the menu bar */ - -#define MENU_LEFT_BORDER 5 -/* 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 */ - -#define MENU_BOX_LEFT_PADDING 0 -/* Number of pixels to pad to the left */ -#define MENU_BOX_RIGHT_PADDING 2 -/* Number of pixels to pad to the right */ - -#define MENU_BAR_HEIGHT 10 - - -/* Special characters used while building the menu bar */ -#define SCI_SPECIAL_CHAR_FUNCTION 'F' -#define SCI_SPECIAL_CHAR_CTRL 3 -#define SCI_SPECIAL_CHAR_ALT 2 - -/* Maximum number of bytes per SAID spec */ -#define MENU_SAID_SPEC_SIZE 64 - -#define MENU_ATTRIBUTE_SAID 0x6d -#define MENU_ATTRIBUTE_TEXT 0x6e -#define MENU_ATTRIBUTE_KEY 0x6f -#define MENU_ATTRIBUTE_ENABLED 0x70 -#define MENU_ATTRIBUTE_TAG 0x71 - -/* Those flags determine whether the corresponding MenuItem entries are valid */ -#define MENU_ATTRIBUTE_FLAGS_KEY 0x01 -#define MENU_ATTRIBUTE_FLAGS_SAID 0x02 - - -enum MenuType { - MENU_TYPE_NORMAL = 0, - MENU_TYPE_HBAR = 1 /* Horizontal bar */ -}; - -class MenuItem : public Common::Serializable { -public: - 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 */ - reg_t _saidPos; - Common::String _text; - reg_t _textPos; - int _modifiers; /**< Hotkey for this item */ - int _key; /**< Hotkey for this item */ - int _enabled; - int _tag; - -public: - MenuItem(); - - virtual void saveLoadWithSerializer(Common::Serializer &ser); - - /** - * Determines whether a message/modifiers key pair matches a menu item's key parameters. - * - * @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); -}; - - -class Menu : public Common::Serializable { -public: - Common::String _title; - - /** Width of the title in pixels */ - int16 _titleWidth; - - /** Pixel width of the menu window */ - int16 _width; - - /** - * Actual entries into the menu. - * Window height equals to number of items times 10. - */ - Common::Array<MenuItem> _items; - -public: - Menu(); - - virtual void saveLoadWithSerializer(Common::Serializer &ser); - -//protected: - // FIXME: This should be (partially) turned into a MenuItem constructor - int addMenuItem(GfxState *state, MenuType type, const char *left, const char *right, - int font, int key, int modifiers, int tag, reg_t text_pos); -}; - - - - -class Menubar : public Common::Serializable { -public: - /** The actual menus. */ - Common::Array<Menu> _menus; - -public: - virtual void saveLoadWithSerializer(Common::Serializer &ser); - - /** - * Adds a menu to the menubar. - * - * 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. - * - * @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 Common::String &title, const Common::String &entries, int font, reg_t entries_base); - - /** - * 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); - - - /** - * 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 - */ - bool itemValid(int menu, int item) const; - - - /** - * Maps the pointer position to a (menu,item) tuple. - * - * @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] portBounds the port bounds 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, Common::Rect portBounds) const; - -}; - -} // End of namespace Sci - -#endif // SCI_GFX_SCI_MENUBAR_H - -#endif - diff --git a/engines/sci/gfx/operations.cpp b/engines/sci/gfx/operations.cpp deleted file mode 100644 index a2791794fd..0000000000 --- a/engines/sci/gfx/operations.cpp +++ /dev/null @@ -1,1212 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -// Graphical operations, called from the widget state manager - -#include "sci/sci.h" -#include "sci/gfx/operations.h" -#ifdef INCLUDE_OLDGFX -#include "sci/gui32/font.h" -#endif -#include "sci/console.h" -#include "sci/event.h" - -#include "common/system.h" -#include "common/events.h" - -namespace Sci { - -#ifdef INCLUDE_OLDGFX - -#define PRECISE_PRIORITY_MAP // Duplicate all operations on the local priority map as appropriate - -#undef GFXW_DEBUG_DIRTY -// Enable to debug stuff relevant for dirty rectsin widget management - -#ifdef GFXW_DEBUG_DIRTY -# define DDIRTY fprintf(stderr, "%s:%5d| ", __FILE__, __LINE__); fprintf -#else -# define DDIRTY if (0) fprintf -#endif - -// Default color maps -#define DEFAULT_COLORS_NR 16 - -PaletteEntry default_colors[DEFAULT_COLORS_NR] = { - PaletteEntry(0x00, 0x00, 0x00), PaletteEntry(0x00, 0x00, 0xaa), - PaletteEntry(0x00, 0xaa, 0x00), PaletteEntry(0x00, 0xaa, 0xaa), - PaletteEntry(0xaa, 0x00, 0x00), PaletteEntry(0xaa, 0x00, 0xaa), - PaletteEntry(0xaa, 0x55, 0x00), PaletteEntry(0xaa, 0xaa, 0xaa), - PaletteEntry(0x55, 0x55, 0x55), PaletteEntry(0x55, 0x55, 0xff), - PaletteEntry(0x55, 0xff, 0x55), PaletteEntry(0x55, 0xff, 0xff), - PaletteEntry(0xff, 0x55, 0x55), PaletteEntry(0xff, 0x55, 0xff), - PaletteEntry(0xff, 0xff, 0x55), PaletteEntry(0xff, 0xff, 0xff) -}; // "Normal" EGA - -#define POINTER_VISIBLE_BUT_CLIPPED 2 - -// How to determine whether colors have to be allocated -#define SCREEN_PALETTE state->driver->getMode()->palette - -//#define GFXOP_DEBUG_DIRTY - -// Internal operations - -static void _gfxop_scale_rect(rect_t *rect, gfx_mode_t *mode) { - rect->x *= mode->scaleFactor; - rect->y *= mode->scaleFactor; - rect->width *= mode->scaleFactor; - rect->height *= mode->scaleFactor; -} - -static void _gfxop_scale_point(Common::Point *point, gfx_mode_t *mode) { - point->x *= mode->scaleFactor; - point->y *= mode->scaleFactor; -} - -int _gfxop_clip(rect_t *rect, rect_t clipzone) { -// Returns 1 if nothing is left */ -#if 0 - printf("Clipping (%d, %d) size (%d, %d) by (%d,%d)(%d,%d)\n", rect->x, rect->y, rect->width, rect->height, - clipzone.x, clipzone.y, clipzone.width, clipzone.height); -#endif - - if (rect->x < clipzone.x) { - rect->width -= (clipzone.x - rect->x); - rect->x = clipzone.x; - } - - if (rect->y < clipzone.y) { - rect->height -= (clipzone.y - rect->y); - rect->y = clipzone.y; - } - - if (rect->x + rect->width > clipzone.x + clipzone.width) - rect->width = (clipzone.x + clipzone.width) - rect->x; - - if (rect->y + rect->height > clipzone.y + clipzone.height) - rect->height = (clipzone.y + clipzone.height) - rect->y; - - if (rect->width < 0) - rect->width = 0; - if (rect->height < 0) - rect->height = 0; - -#if 0 - printf(" => (%d, %d) size (%d, %d)\n", rect->x, rect->y, rect->width, rect->height); -#endif - return (rect->width <= 0 || rect->height <= 0); -} - -static void _gfxop_grab_pixmap(GfxState *state, gfx_pixmap_t **pxmp, int x, int y, - int xl, int yl, int priority, rect_t *zone) { - // Returns 1 if the resulting data size was zero, GFX_OK or an error code otherwise */ - int xfact = state->driver->getMode()->scaleFactor; - int yfact = state->driver->getMode()->scaleFactor; - int unscaled_xl = (xl + xfact - 1) / xfact; - int unscaled_yl = (yl + yfact - 1) / yfact; - *zone = gfx_rect(x, y, xl, yl); - - if (_gfxop_clip(zone, gfx_rect(0, 0, 320 * state->driver->getMode()->scaleFactor, 200 * state->driver->getMode()->scaleFactor))) - error("_gfxop_grab_pixmap: zone was empty"); - - if (!*pxmp) - *pxmp = gfx_new_pixmap(unscaled_xl, unscaled_yl, GFX_RESID_NONE, 0, 0); - else - if (xl * yl > (*pxmp)->width * (*pxmp)->height) { - free((*pxmp)->data); - (*pxmp)->data = NULL; - } - - if (!(*pxmp)->data) { - (*pxmp)->index_width = unscaled_xl + 1; - (*pxmp)->index_height = unscaled_yl + 1; - gfx_pixmap_alloc_data(*pxmp, state->driver->getMode()); - } - state->driver->grabPixmap(*zone, *pxmp, priority ? GFX_MASK_PRIORITY : GFX_MASK_VISUAL); -} - -#define DRAW_LOOP(condition) \ -{ \ - rect_t drawrect = gfx_rect(pos.x, pos.y, pxm->index_width, pxm->index_height); \ - int offset, base_offset; \ - int read_offset, base_read_offset; \ - int x,y; \ - \ - if (!pxm->index_data) { \ - error("Attempt to draw control color %d on pixmap %d/%d/%d without index data", color, pxm->ID, pxm->loop, pxm->cel); \ - return; \ - } \ - \ - if (_gfxop_clip(&drawrect, gfx_rect(0, 0, 320, 200))) \ - return; \ - \ - offset = base_offset = drawrect.x + drawrect.y * 320; \ - read_offset = base_read_offset = (drawrect.x - pos.x) + ((drawrect.y - pos.y) * pxm->index_width); \ - \ - for (y = 0; y < drawrect.height; y++) { \ - for (x = 0; x < drawrect.width; x++) \ - if (pxm->index_data[read_offset++] != pxm->color_key) { \ - if (condition) \ - map->index_data[offset++] = color; \ - else \ - ++offset; \ - } else \ - ++offset; \ - \ - offset = base_offset += 320; \ - read_offset = base_read_offset += pxm->index_width; \ - } \ -} - -static void _gfxop_draw_control(gfx_pixmap_t *map, gfx_pixmap_t *pxm, int color, Common::Point pos) -DRAW_LOOP(1) // Always draw - -#ifdef PRECISE_PRIORITY_MAP -static void _gfxop_draw_priority(gfx_pixmap_t *map, gfx_pixmap_t *pxm, int color, Common::Point pos) -DRAW_LOOP(map->index_data[offset] < color) // Draw only lower priority -#endif - -#undef DRAW_LOOP - -static void _gfxop_install_pixmap(GfxDriver *driver, gfx_pixmap_t *pxm) { - if (!driver->getMode()->palette) - return; - if (!pxm->palette) - return; - - pxm->palette->mergeInto(driver->getMode()->palette); - assert(pxm->palette->getParent() == driver->getMode()->palette); - - if (pxm->palette_revision != pxm->palette->getRevision()) - gfx_xlate_pixmap(pxm, driver->getMode()); - - if (!driver->getMode()->palette->isDirty()) - return; - - // TODO: We probably want to only update the colours used by this pixmap - // here. This will require updating the 'dirty' system. - byte paletteData[4*256]; - const uint paletteSize = driver->getMode()->palette->size(); - for (uint i = 0; i < paletteSize; ++i) { - const PaletteEntry& c = (*driver->getMode()->palette)[i]; - paletteData[4*i+0] = c.r; - paletteData[4*i+1] = c.g; - paletteData[4*i+2] = c.b; - paletteData[4*i+3] = 255; - } - - g_system->setPalette(paletteData, 0, paletteSize); - driver->getMode()->palette->markClean(); -} - -static void _gfxop_draw_pixmap(GfxDriver *driver, gfx_pixmap_t *pxm, int priority, int control, - rect_t src, rect_t dest, rect_t clip, int static_buf, gfx_pixmap_t *control_map, gfx_pixmap_t *priority_map) { - rect_t clipped_dest = gfx_rect(dest.x, dest.y, dest.width, dest.height); - - if (control >= 0 || priority >= 0) { - Common::Point original_pos = Common::Point(dest.x / driver->getMode()->scaleFactor, dest.y / driver->getMode()->scaleFactor); - - if (control >= 0) - _gfxop_draw_control(control_map, pxm, control, original_pos); - -#ifdef PRECISE_PRIORITY_MAP - if (priority >= 0) - _gfxop_draw_priority(priority_map, pxm, priority, original_pos); -#endif - } - - if (_gfxop_clip(&clipped_dest, clip)) - return; - - src.x += clipped_dest.x - dest.x; - src.y += clipped_dest.y - dest.y; - src.width = clipped_dest.width; - src.height = clipped_dest.height; - - _gfxop_install_pixmap(driver, pxm); - - DDIRTY(stderr, "\\-> Drawing to actual %d %d %d %d\n", clipped_dest.x / driver->getMode()->scaleFactor, - clipped_dest.y / driver->getMode()->scaleFactor, clipped_dest.width / driver->getMode()->scaleFactor, clipped_dest.height / driver->getMode()->scaleFactor); - - driver->drawPixmap(pxm, priority, src, clipped_dest, static_buf ? GFX_BUFFER_STATIC : GFX_BUFFER_BACK); -} - -static void _gfxop_buffer_propagate_box(GfxState *state, rect_t box, gfx_buffer_t buffer) { - if (_gfxop_clip(&box, gfx_rect(0, 0, 320 * state->driver->getMode()->scaleFactor, 200 * state->driver->getMode()->scaleFactor))) - return; - - state->driver->update(box, Common::Point(box.x, box.y), buffer); -} - -//** Dirty rectangle operations ** - -static void _gfxop_update_box(GfxState *state, rect_t box) { - _gfxop_scale_rect(&box, state->driver->getMode()); - _gfxop_buffer_propagate_box(state, box, GFX_BUFFER_FRONT); -} - -void gfxdr_add_dirty(DirtyRectList &list, rect_t box) { - if (box.width < 0) { - box.x += box.width; - box.width = - box.width; - } - - if (box.height < 0) { - box.y += box.height; - box.height = - box.height; - } -#ifdef GFXOP_DEBUG_DIRTY - fprintf(stderr, "Adding new dirty (%d %d %d %d)\n", - GFX_PRINT_RECT(box)); -#endif - if (_gfxop_clip(&box, gfx_rect(0, 0, 320, 200))) - return; - - DirtyRectList::iterator dirty = list.begin(); - while (dirty != list.end()) { - if (gfx_rects_overlap(*dirty, box)) { - Common::Rect tmp = toCommonRect(box); - tmp.extend(toCommonRect(*dirty)); - box = toSCIRect(tmp); - - dirty = list.erase(dirty); - } else - ++dirty; - } - list.push_back(box); -} - -static void _gfxop_add_dirty(GfxState *state, rect_t box) { - if (state->disable_dirty) - return; - - gfxdr_add_dirty(state->_dirtyRects, box); -} - -static void _gfxop_add_dirty_x(GfxState *state, rect_t box) { - // Extends the box size by one before adding (used for lines) - if (box.width < 0) - box.width--; - else - box.width++; - - if (box.height < 0) - box.height--; - else - box.height++; - - _gfxop_add_dirty(state, box); -} - -static void _gfxop_clear_dirty_rec(GfxState *state, DirtyRectList &dirtyRects) { - DirtyRectList::iterator dirty = dirtyRects.begin(); - while (dirty != dirtyRects.end()) { - - #ifdef GFXOP_DEBUG_DIRTY - fprintf(stderr, "\tClearing dirty (%d %d %d %d)\n", GFX_PRINT_RECT(*dirty)); - #endif - _gfxop_update_box(state, *dirty); - ++dirty; - } - dirtyRects.clear(); -} - -//** Exported operations ** - -static void init_aux_pixmap(gfx_pixmap_t **pixmap) { - *pixmap = gfx_pixmap_alloc_index_data(gfx_new_pixmap(320, 200, GFX_RESID_NONE, 0, 0)); - // FIXME: don't duplicate this palette for every aux_pixmap - (*pixmap)->palette = new Palette(default_colors, DEFAULT_COLORS_NR); -} - -void gfxop_init(GfxState *state, ResourceManager *resMan, - SciGuiScreen *screen, SciGuiPalette *palette, int scaleFactor) { - state->visible_map = GFX_MASK_VISUAL; - state->disable_dirty = 0; - state->pic = state->pic_unscaled = NULL; - state->pic_nr = -1; // Set background pic number to an invalid value - state->tag_mode = 0; - state->_dirtyRects.clear(); - - // Jones in the Fast Lane uses up the whole window - if (!scumm_stricmp(((SciEngine *)g_engine)->getGameID(), "jones")) - state->pic_port_bounds = gfx_rect(0, 0, 320, 200); - else - state->pic_port_bounds = gfx_rect(0, 10, 320, 190); - - state->driver = new GfxDriver(screen, scaleFactor); - - state->gfxResMan = new GfxResManager(state->driver, resMan, screen, palette, toCommonRect(state->pic_port_bounds)); - - gfxop_set_clip_zone(state, gfx_rect(0, 0, 320, 200)); - - init_aux_pixmap(&(state->control_map)); - init_aux_pixmap(&(state->priority_map)); - init_aux_pixmap(&(state->static_priority_map)); -} - -void gfxop_exit(GfxState *state) { - state->gfxResMan->freeResManager(); - - if (state->control_map) { - gfx_free_pixmap(state->control_map); - state->control_map = NULL; - } - - if (state->priority_map) { - gfx_free_pixmap(state->priority_map); - state->priority_map = NULL; - } - - if (state->static_priority_map) { - gfx_free_pixmap(state->static_priority_map); - state->static_priority_map = NULL; - } - - delete state->driver; -} - -static int _gfxop_scan_one_bitmask(gfx_pixmap_t *pixmap, rect_t zone) { - int retval = 0; - int pixmap_xscale = pixmap->index_width / 320; - int pixmap_yscale = pixmap->index_height / 200; - int line_width = pixmap_yscale * pixmap->index_width; - int startindex = (line_width * zone.y) + (zone.x * pixmap_xscale); - - startindex += pixmap_xscale >> 1; // Center on X - startindex += (pixmap_yscale >> 1) * pixmap->index_width; // Center on Y - - if (_gfxop_clip(&zone, gfx_rect(0, 0, pixmap->index_width, pixmap->index_height))) - return 0; - - while (zone.height--) { - int i; - for (i = 0; i < (zone.width * pixmap_xscale); i += pixmap_xscale) - retval |= (1 << ((pixmap->index_data[startindex + i]) & 0xf)); - - startindex += line_width; - } - - return retval; -} - -int gfxop_scan_bitmask(GfxState *state, rect_t area, gfx_map_mask_t map) { - gfxr_pic_t *pic = (state->pic_unscaled) ? state->pic_unscaled : state->pic; - int retval = 0; - - _gfxop_clip(&area, gfx_rect(0, 10, 320, 200)); - - if (area.width <= 0 - || area.height <= 0) - return 0; - - if (map & GFX_MASK_VISUAL) - retval |= _gfxop_scan_one_bitmask(pic->visual_map, area); - - if (map & GFX_MASK_PRIORITY) - retval |= _gfxop_scan_one_bitmask(state->priority_map, area); - if (map & GFX_MASK_CONTROL) - retval |= _gfxop_scan_one_bitmask(state->control_map, area); - - return retval; -} - -#define MIN_X 0 -#define MIN_Y 0 -#define MAX_X 319 -#define MAX_Y 199 - -void gfxop_set_clip_zone(GfxState *state, rect_t zone) { - int xfact, yfact; - - DDIRTY(stderr, "-- Setting clip zone %d %d %d %d\n", GFX_PRINT_RECT(zone)); - - xfact = state->driver->getMode()->scaleFactor; - yfact = state->driver->getMode()->scaleFactor; - - if (zone.x < MIN_X) { - zone.width -= (zone.x - MIN_X); - zone.x = MIN_X; - } - - if (zone.y < MIN_Y) { - zone.height -= (zone.y - MIN_Y); - zone.y = MIN_Y; - } - - if (zone.x + zone.width > MAX_X) - zone.width = MAX_X + 1 - zone.x; - - if (zone.y + zone.height > MAX_Y) - zone.height = MAX_Y + 1 - zone.y; - - memcpy(&(state->clip_zone_unscaled), &zone, sizeof(rect_t)); - - state->clip_zone.x = state->clip_zone_unscaled.x * xfact; - state->clip_zone.y = state->clip_zone_unscaled.y * yfact; - state->clip_zone.width = state->clip_zone_unscaled.width * xfact; - state->clip_zone.height = state->clip_zone_unscaled.height * yfact; -} - -void gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, int a, int priority, int control) { - int mask = ((r >= 0 && g >= 0 && b >= 0) ? GFX_MASK_VISUAL : 0) | ((priority >= 0) ? GFX_MASK_PRIORITY : 0) - | ((control >= 0) ? GFX_MASK_CONTROL : 0); - - if (a >= GFXOP_ALPHA_THRESHOLD) - mask &= ~GFX_MASK_VISUAL; - - color->mask = mask; - - color->priority = priority; - color->control = control; - - if (mask & GFX_MASK_VISUAL) { - color->visual.r = r; - color->visual.g = g; - color->visual.b = b; - color->alpha = a; - color->visual._parentIndex = SCREEN_PALETTE->findNearbyColor(r,g,b,true); - } -} - -// Wrapper for gfxop_set_color -void gfxop_set_color(GfxState *state, gfx_color_t *colorOut, gfx_color_t &colorIn) { - gfxop_set_color(state, colorOut, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.visual.r : -1, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.visual.g : -1, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.visual.b : -1, - (colorIn.mask & GFX_MASK_VISUAL) ? colorIn.alpha : -1, - (colorIn.mask & GFX_MASK_PRIORITY) ? colorIn.priority : -1, - (colorIn.mask & GFX_MASK_CONTROL) ? colorIn.control : -1); -} - -// Generic drawing operations - -static int line_check_bar(int *start, int *length, int clipstart, int cliplength) { - int overlength; - - if (*start < clipstart) { - *length -= (clipstart - *start); - *start = clipstart; - } - - overlength = 1 + (*start + *length) - (clipstart + cliplength); - - if (overlength > 0) - *length -= overlength; - - return (*length < 0); -} - -static void clip_line_partial(float *start, float *end, float delta_val, float pos_val, float start_val, float end_val) { - float my_start = (start_val - pos_val) * delta_val; - float my_end = (end_val - pos_val) * delta_val; - - if (my_end < *end) - *end = my_end; - if (my_start > *start) - *start = my_start; -} - -static int line_clip(rect_t *line, rect_t clip, int xfact, int yfact) { - // returns 1 if nothing is left, or 0 if part of the line is in the clip window - // Compensate for line thickness (should match precisely) - clip.width -= xfact; - clip.height -= yfact; - - if (!line->width) { // vbar - if (line->x < clip.x || line->x >= (clip.x + clip.width)) - return 1; - - return line_check_bar(&(line->y), &(line->height), clip.y, clip.height); - - } else { - if (!line->height) {// hbar - if (line->y < clip.y || line->y >= (clip.y + clip.height)) - return 1; - - return line_check_bar(&(line->x), &(line->width), clip.x, clip.width); - - } else { // "normal" line - float start = 0.0f, end = 1.0f; - float xv = (float)line->width; - float yv = (float)line->height; - - if (line->width < 0) - clip_line_partial(&start, &end, (float)(1.0 / xv), (float)line->x, (float)(clip.x + clip.width), (float)clip.x); - else - clip_line_partial(&start, &end, (float)(1.0 / xv), (float)line->x, (float)clip.x, (float)(clip.x + clip.width)); - - if (line->height < 0) - clip_line_partial(&start, &end, (float)(1.0 / yv), (float)line->y, (float)(clip.y + clip.height), (float)clip.y); - else - clip_line_partial(&start, &end, (float)(1.0 / yv), (float)line->y, (float)clip.y, (float)(clip.y + clip.height)); - - line->x += (int)(xv * start); - line->y += (int)(yv * start); - - line->width = (int)(xv * (end - start)); - line->height = (int)(yv * (end - start)); - - return (start > 1.0f || end < 0.0f); - } - } - - return 0; -} - -static int point_clip(Common::Point *start, Common::Point *end, rect_t clip, int xfact, int yfact) { - rect_t line = gfx_rect(start->x, start->y, end->x - start->x, end->y - start->y); - int retval = line_clip(&line, clip, xfact, yfact); - - start->x = line.x; - start->y = line.y; - - end->x = line.x + line.width; - end->y = line.y + line.height; - - return retval; -} - -static void draw_line_to_control_map(GfxState *state, Common::Point start, Common::Point end, gfx_color_t color) { - if (color.mask & GFX_MASK_CONTROL) - if (!point_clip(&start, &end, state->clip_zone_unscaled, 0, 0)) - gfx_draw_line_pixmap_i(state->control_map, start, end, color.control); -} - -static void simulate_stippled_line_draw(GfxDriver *driver, int skipone, Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode) { - // Draws a stippled line if this isn't supported by the driver (skipone is ignored ATM) - int xl = end.x - start.x; - int yl = end.y - start.y; - int stepwidth = (xl) ? driver->getMode()->scaleFactor : driver->getMode()->scaleFactor; - int dbl_stepwidth = 2 * stepwidth; - int linelength = (line_mode == GFX_LINE_MODE_FINE) ? stepwidth - 1 : 0; - int16 *posvar; - int length; - int delta; - int length_left; - - if (!xl) { // xl = 0, so we move along yl - posvar = &start.y; - length = yl; - delta = (yl < 0) ? -dbl_stepwidth : dbl_stepwidth; - } else { - assert(!yl); // We don't do diagonals; that's not needed ATM. - posvar = &start.x; - length = xl; - delta = (xl < 0) ? -dbl_stepwidth : dbl_stepwidth; - } - - length_left = length; - - if (skipone) { - length_left -= stepwidth; - *posvar += stepwidth; - } - - length /= delta; - - length_left -= length * dbl_stepwidth; - - if (xl) - xl = linelength; - else - yl = linelength; - - while (length--) { - Common::Point nextpos = Common::Point(start.x + xl, start.y + yl); - driver->drawLine(start, nextpos, color, line_mode, GFX_LINE_STYLE_NORMAL); - *posvar += delta; - } - - if (length_left) { - Common::Point nextpos; - - if (length_left > stepwidth) - length_left = stepwidth; - - if (xl) - xl = length_left; - else - if (yl) - yl = length_left; - - nextpos = Common::Point(start.x + xl, start.y + yl); - - driver->drawLine(start, nextpos, color, line_mode, GFX_LINE_STYLE_NORMAL); - } -} - -static void _gfxop_draw_line_clipped(GfxState *state, Common::Point start, Common::Point end, gfx_color_t color, gfx_line_mode_t line_mode, - gfx_line_style_t line_style) { - int skipone = (start.x ^ end.y) & 1; // Used for simulated line stippling - - // First, make sure that the line is normalized - if (start.y > end.y) { - Common::Point swap = start; - start = end; - end = swap; - } - - if (start.x < state->clip_zone.x - || start.y < state->clip_zone.y - || end.x >= (state->clip_zone.x + state->clip_zone.width) - || end.y >= (state->clip_zone.y + state->clip_zone.height)) - if (point_clip(&start, &end, state->clip_zone, state->driver->getMode()->scaleFactor - 1, state->driver->getMode()->scaleFactor - 1)) - return; // Clipped off - - if (line_style == GFX_LINE_STYLE_STIPPLED) { - if (start.x != end.x && start.y != end.y) - error("[GFX] Attempt to draw stippled line which is neither an hbar nor a vbar: (%d,%d) -- (%d,%d)", start.x, start.y, end.x, end.y); - simulate_stippled_line_draw(state->driver, skipone, start, end, color, line_mode); - } - - state->driver->drawLine(start, end, color, line_mode, line_style); -} - -void 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) { - int xfact, yfact; - - _gfxop_add_dirty_x(state, gfx_rect(start.x, start.y, end.x - start.x, end.y - start.y)); - - xfact = state->driver->getMode()->scaleFactor; - yfact = state->driver->getMode()->scaleFactor; - - draw_line_to_control_map(state, start, end, color); - - _gfxop_scale_point(&start, state->driver->getMode()); - _gfxop_scale_point(&end, state->driver->getMode()); - - if (line_mode == GFX_LINE_MODE_FINE) { - start.x += xfact >> 1; - start.y += yfact >> 1; - - end.x += xfact >> 1; - end.y += yfact >> 1; - } - - if (color.visual.getParentIndex() == -1) - gfxop_set_color(state, &color, color); - _gfxop_draw_line_clipped(state, start, end, color, line_mode, line_style); -} - -void 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 xfact, yfact; - int x, y, xl, yl; - Common::Point upper_left_u, upper_right_u, lower_left_u, lower_right_u; - Common::Point upper_left, upper_right, lower_left, lower_right; - - xfact = state->driver->getMode()->scaleFactor; - yfact = state->driver->getMode()->scaleFactor; - - int offset = line_mode == GFX_LINE_MODE_FINE ? 1 : 0; - x = rect.x * xfact + (xfact - 1) * offset; - y = rect.y * yfact + (yfact - 1) * offset; - xl = offset + (rect.width - offset) * xfact; - yl = offset + (rect.height - offset) * yfact; - - upper_left_u = Common::Point(rect.x, rect.y); - upper_right_u = Common::Point(rect.x + rect.width, rect.y); - lower_left_u = Common::Point(rect.x, rect.y + rect.height); - lower_right_u = Common::Point(rect.x + rect.width, rect.y + rect.height); - - upper_left = Common::Point(x, y); - upper_right = Common::Point(x + xl, y); - lower_left = Common::Point(x, y + yl); - lower_right = Common::Point(x + xl, y + yl); - -#define PARTIAL_LINE(pt1, pt2) \ - _gfxop_draw_line_clipped(state, pt1, pt2, color, line_mode, line_style); \ - draw_line_to_control_map(state, pt1##_u, pt2##_u, color); \ - _gfxop_add_dirty_x(state, gfx_rect(pt1##_u.x, pt1##_u.y, pt2##_u.x - pt1##_u.x, pt2##_u.y - pt1##_u.y)) - - PARTIAL_LINE(upper_left, upper_right); - PARTIAL_LINE(upper_right, lower_right); - PARTIAL_LINE(lower_right, lower_left); - PARTIAL_LINE(lower_left, upper_left); - -#undef PARTIAL_LINE -} - - -void gfxop_draw_box(GfxState *state, rect_t box, gfx_color_t color1, gfx_color_t color2, gfx_box_shade_t shade_type) { - GfxDriver *drv = state->driver; - int reverse = 0; // switch color1 and color2 - float mod_offset = 0.0f, mod_breadth = 1.0f; // 0.0 to 1.0: Color adjustment - gfx_rectangle_fill_t driver_shade_type; - rect_t new_box; - - shade_type = GFX_BOX_SHADE_FLAT; - - _gfxop_add_dirty(state, box); - - if (color1.mask & GFX_MASK_CONTROL) { - // Write control block, clipped by 320x200 - memcpy(&new_box, &box, sizeof(rect_t)); - _gfxop_clip(&new_box, gfx_rect(0, 0, 320, 200)); - - gfx_draw_box_pixmap_i(state->control_map, new_box, color1.control); - } - - _gfxop_scale_rect(&box, state->driver->getMode()); - - if (!(color1.mask & (GFX_MASK_VISUAL | GFX_MASK_PRIORITY))) - return; - - if (box.width <= 1 || box.height <= 1) { - debugC(2, kDebugLevelGraphics, "Attempt to draw box with size %dx%d", box.width, box.height); - return; - } - - memcpy(&new_box, &box, sizeof(rect_t)); - if (_gfxop_clip(&new_box, state->clip_zone)) - return; - - switch (shade_type) { - - case GFX_BOX_SHADE_FLAT: - driver_shade_type = GFX_SHADE_FLAT; - break; - - case GFX_BOX_SHADE_LEFT: - reverse = 1; - case GFX_BOX_SHADE_RIGHT: - driver_shade_type = GFX_SHADE_HORIZONTALLY; - mod_offset = (float)(((new_box.x - box.x) * 1.0) / (box.width * 1.0)); - mod_breadth = (float)((new_box.width * 1.0) / (box.width * 1.0)); - break; - - case GFX_BOX_SHADE_UP: - reverse = 1; - case GFX_BOX_SHADE_DOWN: - driver_shade_type = GFX_SHADE_VERTICALLY; - mod_offset = (float)(((new_box.y - box.y) * 1.0) / (box.height * 1.0)); - mod_breadth = (float)((new_box.height * 1.0) / (box.height * 1.0)); - break; - - default: - error("Invalid shade type: %d", shade_type); - } - - - if (reverse) - mod_offset = (float)(1.0 - (mod_offset + mod_breadth)); - // Reverse offset if we have to interpret colors inversely - - if (shade_type == GFX_BOX_SHADE_FLAT) { - color1.priority = 0; - color1.control = 0; - if (color1.visual.getParentIndex() == -1) - gfxop_set_color(state, &color1, color1); - drv->drawFilledRect(new_box, color1, color1, GFX_SHADE_FLAT); - return; - } -} - -void gfxop_fill_box(GfxState *state, rect_t box, gfx_color_t color) { - gfxop_draw_box(state, box, color, color, GFX_BOX_SHADE_FLAT); -} - -extern int sci0_palette; - -void gfxop_clear_box(GfxState *state, rect_t box) { - _gfxop_add_dirty(state, box); - DDIRTY(stderr, "[] clearing box %d %d %d %d\n", GFX_PRINT_RECT(box)); - - _gfxop_clip(&box, gfx_rect(0, 0, 320, 200)); -#ifdef PRECISE_PRIORITY_MAP - if (state->pic_unscaled) - gfx_copy_pixmap_box_i(state->priority_map, state->static_priority_map, box); -#endif - - _gfxop_scale_rect(&box, state->driver->getMode()); - - _gfxop_buffer_propagate_box(state, box, GFX_BUFFER_BACK); -} - -void gfxop_update(GfxState *state) { - _gfxop_clear_dirty_rec(state, state->_dirtyRects); - - if (state->tag_mode) { - // This usually happens after a pic and all resources have been drawn - state->gfxResMan->freeTaggedResources(); - state->tag_mode = 0; - } -} - -void gfxop_update_box(GfxState *state, rect_t box) { - if (state->disable_dirty) - _gfxop_update_box(state, box); - else - _gfxop_add_dirty(state, box); - - gfxop_update(state); -} - -void gfxop_enable_dirty_frames(GfxState *state) { - state->disable_dirty = 0; -} - -void gfxop_disable_dirty_frames(GfxState *state) { - state->disable_dirty = 1; -} - -// View operations - -void gfxop_get_cel_parameters(GfxState *state, int nr, int loop, int cel, int *width, int *height, Common::Point *offset) { - gfxr_view_t *view = NULL; - gfx_pixmap_t *pxm = NULL; - - view = state->gfxResMan->getView(nr, &loop, &cel, 0); - - if (!view) - error("[GFX] Attempt to get cel parameters for invalid view %d", nr); - - pxm = view->loops[loop].cels[cel]; - *width = pxm->index_width; - *height = pxm->index_height; - offset->x = pxm->xoffset; - offset->y = pxm->yoffset; -} - -static void _gfxop_draw_cel_buffer(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int static_buf, int palette) { - int priority = (color.mask & GFX_MASK_PRIORITY) ? color.priority : -1; - int control = (color.mask & GFX_MASK_CONTROL) ? color.control : -1; - gfxr_view_t *view = NULL; - gfx_pixmap_t *pxm = NULL; - int old_x, old_y; - - view = state->gfxResMan->getView(nr, &loop, &cel, palette); - - if (!view) { - warning("[GFX] Attempt to draw loop/cel %d/%d in invalid view %d\n", loop, cel, nr); - return; - } - pxm = view->loops[loop].cels[cel]; - - old_x = pos.x -= pxm->xoffset; - old_y = pos.y -= pxm->yoffset; - - pos.x *= state->driver->getMode()->scaleFactor; - pos.y *= state->driver->getMode()->scaleFactor; - - if (!static_buf) - _gfxop_add_dirty(state, gfx_rect(old_x, old_y, pxm->index_width, pxm->index_height)); - - _gfxop_draw_pixmap(state->driver, pxm, priority, control, gfx_rect(0, 0, pxm->width, pxm->height), - gfx_rect(pos.x, pos.y, pxm->width, pxm->height), state->clip_zone, static_buf , state->control_map, - static_buf ? state->static_priority_map : state->priority_map); -} - -void gfxop_draw_cel(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int palette) { - _gfxop_draw_cel_buffer(state, nr, loop, cel, pos, color, 0, palette); -} - -void gfxop_draw_cel_static(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int palette) { - rect_t oldclip = state->clip_zone; - - state->clip_zone = gfx_rect_fullscreen; - _gfxop_scale_rect(&(state->clip_zone), state->driver->getMode()); - gfxop_draw_cel_static_clipped(state, nr, loop, cel, pos, color, palette); - // Except that the area it's clipped against is... unusual ;-) - state->clip_zone = oldclip; -} - -void gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, Common::Point pos, gfx_color_t color, int palette) { - _gfxop_draw_cel_buffer(state, nr, loop, cel, pos, color, 1, palette); -} - -// Pic operations - -static void _gfxop_set_pic(GfxState *state) { - gfx_copy_pixmap_box_i(state->control_map, state->pic->control_map, gfx_rect(0, 0, 320, 200)); - gfx_copy_pixmap_box_i(state->priority_map, state->pic_unscaled->priority_map, gfx_rect(0, 0, 320, 200)); - gfx_copy_pixmap_box_i(state->static_priority_map, state->pic_unscaled->priority_map, gfx_rect(0, 0, 320, 200)); - - // Reset global palette to this PIC's palette - // FIXME: The _gfxop_install_pixmap call below updates the OSystem palette. - // This is too soon, since it causes brief palette corruption until the - // screen is updated too. (Possibly related: EngineState::pic_not_valid .) - if (state->pic->visual_map->palette) { - state->pic->visual_map->palette->forceInto(SCREEN_PALETTE); - _gfxop_install_pixmap(state->driver, state->pic->visual_map); - } - - state->driver->setStaticBuffer(state->pic->visual_map, state->pic->priority_map); -} - -void gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette) { - state->gfxResMan->tagResources(); - state->tag_mode = 1; - state->palette_nr = default_palette; - state->pic = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, true); - - if (state->driver->getMode()->scaleFactor == 1 && state->driver->getMode()->scaleFactor == 1) { - state->pic_unscaled = state->pic; - } else { - state->pic_unscaled = state->gfxResMan->getPic(nr, GFX_MASK_VISUAL, flags, default_palette, false); - } - - if (!state->pic || !state->pic_unscaled) { - warning("Could not retrieve background pic %d", nr); - if (state->pic) { - warning(" -- Inconsistency: scaled pic _was_ retrieved!"); - } - - if (state->pic_unscaled) { - warning(" -- Inconsistency: unscaled pic _was_ retrieved!"); - } - - error("Error occured in gfxop_new_pic()"); - state->pic = state->pic_unscaled = NULL; - } - - state->pic_nr = nr; - - _gfxop_set_pic(state); -} - -void gfxop_add_to_pic(GfxState *state, int nr, int flags, int default_palette) { - if (!state->pic) - error("Attempt to add to pic with no pic active"); - - state->pic = state->gfxResMan->addToPic(state->pic_nr, nr, flags, state->palette_nr, default_palette); - - if (!state->pic) - error("Could not add pic #%d to pic #%d", state->pic_nr, nr); - - state->pic_unscaled = state->gfxResMan->addToPic(state->pic_nr, nr, flags, state->palette_nr, default_palette); - - _gfxop_set_pic(state); -} - -// Text operations - -void gfxop_get_text_params(GfxState *state, int font_nr, const char *text, int maxwidth, int *width, int *height, int text_flags, - int *lines_nr, int *lineheight, int *lastline_width) { - Common::Array<TextFragment> fragments; - bool textsplits; - gfx_bitmap_font_t *font; - - font = state->gfxResMan->getFont(font_nr); - - if (!font) - error("Attempt to calculate text size with invalid font #%d", font_nr); - - textsplits = gfxr_font_calculate_size(fragments, font, maxwidth, text, width, height, lineheight, lastline_width, text_flags); - - if (!textsplits) - error("Could not calculate text size"); - - if (lines_nr) - *lines_nr = fragments.size(); -} - -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) { - TextHandle *handle; - gfx_bitmap_font_t *font; - - // mapping text colors to palette - gfxop_set_color(state, &color1, color1); - gfxop_set_color(state, &color2, color2); - gfxop_set_color(state, &bg_color, bg_color); - - font = state->gfxResMan->getFont(font_nr); - - if (!font) { - error("Attempt to draw text with invalid font #%d", font_nr); - return NULL; - } - - handle = new TextHandle(); - - handle->_text = text; - handle->halign = halign; - handle->valign = valign; - handle->line_height = font->line_height; - - bool result = gfxr_font_calculate_size(handle->lines, font, maxwidth, handle->_text.c_str(), &(handle->width), &(handle->height), - NULL, NULL, flags); - - if (!result) { - error("Could not calculate text parameters in font #%d", font_nr); - delete handle; - return NULL; - } - - if (flags & kFontNoNewlines) { - handle->lines.resize(1); - handle->lines[0].length = text.size(); - } - - handle->text_pixmaps.resize(handle->lines.size()); - - for (uint i = 0; i < handle->lines.size(); i++) { - int chars_nr = handle->lines[i].length; - - handle->text_pixmaps[i] = gfxr_draw_font(font, handle->lines[i].offset, chars_nr, - (color1.mask & GFX_MASK_VISUAL) ? &color1.visual : NULL, - (color2.mask & GFX_MASK_VISUAL) ? &color2.visual : NULL, - (bg_color.mask & GFX_MASK_VISUAL) ? &bg_color.visual : NULL); - - if (!handle->text_pixmaps[i]) { - error("Failed to draw text pixmap for line %d/%d", i, handle->lines.size()); - delete handle; - return NULL; - } - } - - handle->font = font; - - handle->priority = (color1.mask & GFX_MASK_PRIORITY) ? color1.priority : -1; - handle->control = (color1.mask & GFX_MASK_CONTROL) ? color1.control : -1; - - return handle; -} - -TextHandle::TextHandle() { - line_height = 0; - font = 0; - - width = height = 0; - - priority = control = 0; - halign = valign = ALIGN_BOTTOM; -} - -TextHandle::~TextHandle() { - for (uint j = 0; j < text_pixmaps.size(); j++) - if (text_pixmaps[j]) - gfx_free_pixmap(text_pixmaps[j]); -} - -void gfxop_draw_text(GfxState *state, TextHandle *handle, rect_t zone) { - int line_height; - rect_t pos; - - if (!handle) - error("Attempt to draw text with NULL handle"); - - if (handle->lines.empty()) { - debugC(2, kDebugLevelGraphics, "Skipping draw_text operation because number of lines is zero\n"); - return; - } - - _gfxop_scale_rect(&zone, state->driver->getMode()); - - line_height = handle->line_height * state->driver->getMode()->scaleFactor; - - pos.y = zone.y; - - switch (handle->valign) { - - case ALIGN_TOP: - break; - - case ALIGN_CENTER: - pos.y += (zone.height - (line_height * handle->lines.size())) >> 1; - break; - - case ALIGN_BOTTOM: - pos.y += (zone.height - (line_height * handle->lines.size())); - break; - - default: - error("Invalid vertical alignment %d", handle->valign); - } - - for (uint i = 0; i < handle->lines.size(); i++) { - - gfx_pixmap_t *pxm = handle->text_pixmaps[i]; - - if (!pxm->data) { - gfx_xlate_pixmap(pxm, state->driver->getMode()); - } - if (!pxm) - error("Could not find text pixmap %d/%d", i, handle->lines.size()); - - pos.x = zone.x; - - switch (handle->halign) { - - case ALIGN_LEFT: - break; - - case ALIGN_CENTER: - pos.x += (zone.width - pxm->width) >> 1; - break; - - case ALIGN_RIGHT: - pos.x += (zone.width - pxm->width); - break; - - default: - error("Invalid vertical alignment %d", handle->valign); - } - - pos.width = pxm->width; - pos.height = pxm->height; - - _gfxop_add_dirty(state, pos); - _gfxop_draw_pixmap(state->driver, pxm, handle->priority, handle->control, - gfx_rect(0, 0, pxm->width, pxm->height), pos, state->clip_zone, 0, state->control_map, state->priority_map); - - pos.y += line_height; - } -} - -gfx_pixmap_t *gfxop_grab_pixmap(GfxState *state, rect_t area) { - gfx_pixmap_t *pixmap = NULL; - rect_t resultzone; // Ignored for this application - - _gfxop_scale_rect(&area, state->driver->getMode()); - _gfxop_grab_pixmap(state, &pixmap, area.x, area.y, area.width, area.height, 0, &resultzone); - - return pixmap; -} - -void gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, Common::Point pos) { - rect_t target = gfx_rect(pos.x, pos.y, zone.width, zone.height); - - if (!pxm) - error("Attempt to draw NULL pixmap"); - - _gfxop_add_dirty(state, target); - - _gfxop_scale_rect(&zone, state->driver->getMode()); - _gfxop_scale_rect(&target, state->driver->getMode()); - - return _gfxop_draw_pixmap(state->driver, pxm, -1, -1, zone, target, gfx_rect(0, 0, 320*state->driver->getMode()->scaleFactor, - 200*state->driver->getMode()->scaleFactor), 0, NULL, NULL); -} - - - -#endif // INCLUDE_OLDGFX - -} // End of namespace Sci diff --git a/engines/sci/gfx/operations.h b/engines/sci/gfx/operations.h deleted file mode 100644 index bc8b27b846..0000000000 --- a/engines/sci/gfx/operations.h +++ /dev/null @@ -1,530 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -/* Graphical operations, called from the widget state manager */ - -#ifndef SCI_GFX_GFX_OPERATIONS_H -#define SCI_GFX_GFX_OPERATIONS_H - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX -#include "sci/gfx/gfx_resmgr.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gfx/gfx_system.h" -#endif - -#include "common/list.h" - -namespace Sci { - -#ifdef INCLUDE_OLDGFX - -struct TextFragment; - -/* Threshold in color index mode to differentiate between visible and non-visible stuff. -** GFXOP_ALPHA_THRESHOLD itself should be treated as non-visible. -*/ -#define GFXOP_ALPHA_THRESHOLD 0xff - -struct TextHandle { - Common::String _text; /**< Copy of the actual text */ - - int line_height; - Common::Array<TextFragment> lines; /**< Text offsets */ - gfx_bitmap_font_t *font; - Common::Array<gfx_pixmap_t *> text_pixmaps; - - int width, height; - - int priority, control; - gfx_alignment_t halign, valign; - - TextHandle(); - ~TextHandle(); -}; - -/* Unless individually stated otherwise, the following applies: -** All operations herein apply to the standard 320x200 coordinate system. -** All operations perform clipping relative to state->clip_zone. -*/ - -enum gfx_box_shade_t { - GFX_BOX_SHADE_FLAT, - GFX_BOX_SHADE_RIGHT, - GFX_BOX_SHADE_LEFT, - GFX_BOX_SHADE_DOWN, - GFX_BOX_SHADE_UP -#if 0 - /* possible with alphaing, but there is no way to check for - ** alpha capability of gfx_driver->draw_filled_rect() yet - */ - , GFX_BOX_SHADE_RIGHT_DOWN, - GFX_BOX_SHADE_LEFT_DOWN, - GFX_BOX_SHADE_RIGHT_UP, - GFX_BOX_SHADE_LEFT_UP -#endif -}; - - -typedef Common::List<rect_t> DirtyRectList; - -#endif // INCLUDE_OLDGFX - -struct GfxState { -#ifdef INCLUDE_OLDGFX - 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; - - int visible_map; - - 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) */ - - - 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 pic_nr; /**< Number of the current pic */ - int palette_nr; /**< Palette number of the current pic */ - - 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 */ -#endif -}; - - -#ifdef INCLUDE_OLDGFX - - -/** @name Fundamental operations */ -/** @{ */ - -/** - * Initializes a graphics mode. - * - * @param[in] state The state to initialize - * @param[in] scaleFactor Scale factor - * @param[in] mode Graphics mode to use - * @param[in] resMan Resource manager to use - */ -void gfxop_init(GfxState *state, ResourceManager *resMan, - SciGuiScreen *screen, SciGuiPalette *palette, int scaleFactor = 1); - -/** - * Deinitializes a currently active driver. - * - * @param[in] state The state encapsulating the driver in question - */ -void gfxop_exit(GfxState *state); - -/** - * 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); - -/** - * Sets a new clipping zone. - * - * @param[in] state The affected state - * @param[in] zone The new clipping zone - */ -void gfxop_set_clip_zone(GfxState *state, rect_t zone); -/** @} */ - - -/** @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 - */ -void 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); - -/** - * 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 - */ -void 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 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) - */ -void 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 - */ -void gfxop_fill_box(GfxState *state, rect_t box, gfx_color_t color); - -/** - * 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 - */ -void gfxop_clear_box(GfxState *state, rect_t box); - - -/** - * 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 - */ -void gfxop_update(GfxState *state); - - -/** - * 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 - */ -void gfxop_update_box(GfxState *state, rect_t box); - -/** - * Enables dirty frame accounting. - * - * Dirty frame accounting is enabled by default. - * - * @param[in] state The state dirty frame accounting is to be enabled in - */ -void gfxop_enable_dirty_frames(GfxState *state); - -/** - * Disables dirty frame accounting. - * - * @param[in] state The state dirty frame accounting is to be disabled in - */ -void gfxop_disable_dirty_frames(GfxState *state); -/** @} */ - - -/** @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. 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 - */ -void gfxop_set_color(GfxState *state, gfx_color_t *color, int r, int g, int b, - int a, int priority, int control); - -/** @} */ - -/** @name View operations */ -/** @{ */ - -/** - * 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 - */ -void gfxop_get_cel_parameters(GfxState *state, int nr, int loop, int cel, - int *width, int *height, Common::Point *offset); - -/** - * 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 - */ -void gfxop_draw_cel(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. - * - * 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 - */ -void gfxop_draw_cel_static(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. - * - * 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 - */ -void gfxop_draw_cel_static_clipped(GfxState *state, int nr, int loop, int cel, - Common::Point pos, gfx_color_t color, int palette); -/** @} */ - - -/** @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 - */ -void gfxop_new_pic(GfxState *state, int nr, int flags, int default_palette); - -/** - * 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 - */ -void gfxop_add_to_pic(GfxState *state, int nr, int flags, int default_palette); -/** @} */ - - -/** @name Text operations */ - -/** - * 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 - */ -void 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); - -/** - * 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); - -/** - * 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. - */ -void gfxop_draw_text(GfxState *state, TextHandle *handle, rect_t zone); -/** @} */ - - -/** @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); - -/** - * 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 - */ -void gfxop_draw_pixmap(GfxState *state, gfx_pixmap_t *pxm, rect_t zone, - Common::Point pos); - -/** @} */ - - -/** @name Dirty rectangle operations */ -/** @{ */ - -/** - * Adds a dirty rectangle to 'base' according to a strategy. - * - * @param[in] list the list to add to - * @param[in] box the dirty frame to addable - */ -void gfxdr_add_dirty(DirtyRectList &list, rect_t box); - -/** - * 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); -/** @} */ - -#endif // INCLUDE_OLDGFX - -/** @name Pointer and IO ops */ -/** @{ */ - -} // End of namespace Sci - -#endif // SCI_GFX_GFX_OPERATIONS_H diff --git a/engines/sci/gfx/palette.cpp b/engines/sci/gfx/palette.cpp deleted file mode 100644 index 62e70e2a6d..0000000000 --- a/engines/sci/gfx/palette.cpp +++ /dev/null @@ -1,330 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/palette.h" -#include "sci/gfx/gfx_system.h" - -// #define DEBUG_MERGE - -namespace Sci { - -Palette::Palette(uint s) { - _size = s; - _colors = new PaletteEntry[s]; - _parent = 0; - _dirty = true; - _refcount = 1; - _revision = 0; -} - -Palette::Palette(const PaletteEntry *colors, uint s) { - _size = s; - _colors = new PaletteEntry[s]; - _parent = 0; - _dirty = true; - _refcount = 1; - _revision = 0; - - for (uint i = 0; i < _size; ++i) { - _colors[i].r = colors[i].r; - _colors[i].g = colors[i].g; - _colors[i].b = colors[i].b; - _colors[i].refcount = 0; - _colors[i]._parentIndex = -1; - } -} - -Palette::~Palette() { - if (_parent) - unmerge(); - - delete[] _colors; - _colors = 0; -} - -Palette *Palette::getref() { - _refcount++; - return this; -} - -void Palette::free() { - assert(_refcount > 0); - _refcount--; - - if (_refcount == 0) - delete this; -} - -void Palette::resize(uint s) { - if (s == _size) - return; - - assert(!_parent); - assert(_refcount == 1); - assert(s >= _size); - - PaletteEntry *n = new PaletteEntry[s]; - for (uint i = 0; i < _size; ++i) - n[i] = _colors[i]; - - delete[] _colors; - _colors = n; - _size = s; -} - -void Palette::unmerge() { - assert(_parent); -#ifdef DEBUG_MERGE - fprintf(stderr, "Unmerge %s from %s (%d colors)\n", name.c_str(), _parent->name.c_str(), _size); -#endif - if (_parent->_revision != _revision) { -#ifdef DEBUG_MERGE - fprintf(stderr, "NOP (revision mismatch)\n"); -#endif - return; - } - - int count = 0; - for (uint i = 0; i < _size; ++i) { - if (_colors[i].refcount == PaletteEntry::FREE) { - assert(_colors[i]._parentIndex == 0); - } - - int pi = _colors[i]._parentIndex; - assert(pi >= 0); - assert(pi < (int)_parent->_size); - assert(_parent->_colors[pi].refcount != 0); - assert(_parent->_colors[pi].refcount != PaletteEntry::FREE); - if (_parent->_colors[pi].refcount != PaletteEntry::LOCKED) - _parent->_colors[pi].refcount--; - if (_parent->_colors[pi].refcount == 0) { - _parent->_colors[pi].refcount = PaletteEntry::FREE; - count++; - } - _colors[i]._parentIndex = -1; - } -#ifdef DEBUG_MERGE - fprintf(stderr, "Unmerge free %d colors\n", count); -#endif - - _parent = 0; -} - -void Palette::setColor(uint index, byte r, byte g, byte b, int parentIndex) { - assert(index < _size); - assert(!_parent); - -// FIXME: We may want to have this assert. This will require changing the -// way loops sharing a single view's palette works. -// assert(_refcount == 1); - - PaletteEntry& entry = _colors[index]; - - assert(entry.refcount == PaletteEntry::FREE || entry.refcount == 0); - entry.refcount = 0; - entry.r = r; - entry.g = g; - entry.b = b; - entry._parentIndex = parentIndex; - - _dirty = true; -} - -void Palette::makeSystemColor(uint index, const PaletteEntry &color) { - assert(index < _size); - PaletteEntry& entry = _colors[index]; - entry.r = color.r; - entry.g = color.g; - entry.b = color.b; - entry.refcount = PaletteEntry::LOCKED; -} - -uint Palette::findNearbyColor(byte r, byte g, byte b, bool lock) { - int bestdelta = 1 + ((0x100 * 0x100) * 3); - int bestcolor = -1; - int firstfree = -1; - - assert(_size != 0); - - for (uint i = 0; i < _size; ++i) { - PaletteEntry& entry = _colors[i]; - - if (entry.refcount != PaletteEntry::FREE) { - int dr = abs(entry.r - r); - int dg = abs(entry.g - g); - int db = abs(entry.b - b); - - if (dr == 0 && dg == 0 && db == 0) { - // Exact match - //exact = true; - if (lock && entry.refcount != PaletteEntry::LOCKED) - entry.refcount++; - return i; - } - - int delta = (dr * dr) + (dg * dg) + (db * db); - if (delta < bestdelta) { - bestdelta = delta; - bestcolor = i; - } - } else { - if (firstfree == -1) - firstfree = i; - } - } - - if (firstfree != -1) { - // TODO: mark palette as dirty - setColor(firstfree, r, g, b); - //exact = true; - if (lock) - _colors[firstfree].refcount++; - return firstfree; - } - - //exact = false; - if (lock && _colors[bestcolor].refcount != PaletteEntry::LOCKED) { -#if 0 - _colors[bestcolor].r = r; - _colors[bestcolor].g = g; - _colors[bestcolor].b = b; - _dirty = true; -#endif - _colors[bestcolor].refcount++; - } - return bestcolor; -} - -bool Palette::mergeInto(Palette *parent) { - assert(!_parent || _parent == parent); - assert(parent != this); -#ifdef DEBUG_MERGE - fprintf(stderr, "Merge: %s into %s (%d colors)\n", name.c_str(), parent->name.c_str(), _size); -#endif - - if (_parent == parent && parent->_revision == _revision) { -#ifdef DEBUG_MERGE - fprintf(stderr, "NOP\n"); -#endif - return false; - } - _parent = parent; - _revision = parent->_revision; - -#ifdef DEBUG_MERGE - bool *used = new bool[_parent->size()]; - for (uint i = 0; i < _parent->size(); ++i) - used[i] = false; - int count = 0; - uint used_min = 1000; - uint used_max = 0; -#endif - - for (uint i = 0; i < _size; ++i) { - PaletteEntry& entry = _colors[i]; - if (entry.refcount == PaletteEntry::FREE) { - // Force all unused colours to index 0 - entry._parentIndex = 0; - if (_parent->_colors[0].refcount != PaletteEntry::LOCKED) - _parent->_colors[0].refcount++; - if (_colors[i].r || _colors[i].g || _colors[i].b) - warning("Non-black unused colour in pic: index %d, %02X %02X %02X", i, _colors[i].r, _colors[i].g, _colors[i].b); - continue; - } - - uint pi = _parent->findNearbyColor(entry.r, entry.g, entry.b); -#ifdef DEBUG_MERGE - if (!used[pi]) count++; - used[pi] = true; - if (pi > used_max) used_max = pi; - if (pi < used_min) used_min = pi; -#endif - entry._parentIndex = pi; - if (_parent->_colors[pi].refcount != PaletteEntry::LOCKED) - _parent->_colors[pi].refcount++; - } -#ifdef DEBUG_MERGE - fprintf(stderr, "Merge used %d colours in [%d..%d]\n", count, used_min, used_max); - delete[] used; -#endif - return true; -} - -void Palette::forceInto(Palette *parent) { - assert(!_parent || _parent == parent); - assert(parent != this); -#ifdef DEBUG_MERGE - fprintf(stderr, "Merge: force %s into %s (%d colors)\n", name.c_str(), parent->name.c_str(), _size); -#endif - - _parent = parent; - parent->_revision++; - _revision = parent->_revision; - - for (unsigned int i = 0; i < _size; ++i) { - // FIXME: PaletteEntry::LOCKED doesn't work well with forceInto... - if (_colors[i].refcount != PaletteEntry::FREE) { - _parent->_colors[i] = _colors[i]; - _parent->_colors[i]._parentIndex = -1; - _colors[i]._parentIndex = i; - if (_parent->_colors[i].refcount != PaletteEntry::LOCKED) - _parent->_colors[i].refcount = 1; - } else { - _parent->_colors[i].refcount = 0; - // Force all unused colours to index 0 - _colors[i]._parentIndex = 0; - if (_parent->_colors[0].refcount != PaletteEntry::LOCKED) { - if (i == 0) - _parent->_colors[0].refcount = 1; - else - _parent->_colors[0].refcount++; - } - if (_colors[i].r || _colors[i].g || _colors[i].b) - warning("Non-black unused colour in pic: index %d, %02X %02X %02X", i, _colors[i].r, _colors[i].g, _colors[i].b); - } - } - _parent->_dirty = true; -} - -Palette *Palette::copy() { - assert(!_parent); - Palette* p = new Palette(_size); - p->name = "copy of " + name; - - for (uint i = 0; i < _size; ++i) { - p->_colors[i] = _colors[i]; - if (p->_colors[i].refcount >= 0) - p->_colors[i].refcount = 0; - } - return p; -} - - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gfx/palette.h b/engines/sci/gfx/palette.h deleted file mode 100644 index b74eebd72e..0000000000 --- a/engines/sci/gfx/palette.h +++ /dev/null @@ -1,129 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GFX_PALETTE_H -#define SCI_GFX_PALETTE_H - -#include "common/scummsys.h" -#include "common/str.h" - -namespace Sci { - -class PaletteEntry { - - friend class Palette; - - enum { - LOCKED = -42, - FREE = -41 - }; - -public: - PaletteEntry() - : r(0), g(0), b(0), _parentIndex(-1), refcount(FREE) - { } - PaletteEntry(byte R, byte G, byte B) - : r(R), g(G), b(B), _parentIndex(-1), refcount(FREE) - { } - - /** @name Color data */ - /** @{ */ - byte r, g, b; - /** @} */ - - inline int getParentIndex() const { return _parentIndex; } - - /** Index in parent palette, or -1 */ - int _parentIndex; - -protected: - /** - * Number of references from child palettes. (This includes palettes - * of pixmaps.) - * Special values: PALENTRY_LOCKED, PALENTRY_FREE */ - int refcount; -}; - -class Palette { -public: - explicit Palette(uint size); - Palette(const PaletteEntry *colors, uint size); - ~Palette(); - - Palette *getref(); - void free(); - Palette *copy(); - - void resize(uint size); - void setColor(uint index, byte r, byte g, byte b, int parentIndex = -1); - void makeSystemColor(uint index, const PaletteEntry &color); - const PaletteEntry &getColor(uint index) const { - assert(index < _size); - return _colors[index]; - } - const PaletteEntry &operator[](uint index) const { - return getColor(index); - } - uint size() const { return _size; } - bool isDirty() const { return _dirty; } - bool isShared() const { return _refcount > 1; } - Palette *getParent() { return _parent; } - int getRevision() const { return _revision; } - - void markClean() { _dirty = false; } - - uint findNearbyColor(byte r, byte g, byte b, bool lock=false); - - bool mergeInto(Palette *parent); // returns false if already merged - void forceInto(Palette *parent); - - void unmerge(); - - Common::String name; // strictly for debugging purposes -private: - PaletteEntry *_colors; - uint _size; - - Palette *_parent; - - /** Palette has changed */ - bool _dirty; - - /** Number of pixmaps (or other objects) using this palette */ - int _refcount; - - /** When this is incremented, all child references are invalidated */ - int _revision; -}; - - -} // End of namespace Sci - -#endif // SCI_GFX_PALETTE_H - -#endif diff --git a/engines/sci/gui/gui.cpp b/engines/sci/gui/gui.cpp index 5f03cec1f9..8189aea4d6 100644 --- a/engines/sci/gui/gui.cpp +++ b/engines/sci/gui/gui.cpp @@ -43,8 +43,6 @@ #include "sci/gui/gui_transitions.h" #include "sci/gui/gui_view.h" -#include "sci/gfx/operations.h" - namespace Sci { // for debug purposes @@ -90,7 +88,6 @@ void SciGui::init(bool usesOldGfxFunctions) { _gfx->init(_text); _windowMgr->init(_s->_gameId); - _menu->init(_s->gfx_state); initPriorityBands(); } @@ -329,7 +326,6 @@ void SciGui::drawMenuBar(bool clear) { void SciGui::menuReset() { delete _menu; _menu = new SciGuiMenu(_s->_event, _s->_segMan, _gfx, _text, _screen, _cursor); - _menu->init(_s->gfx_state); } void SciGui::menuAdd(Common::String title, Common::String content, reg_t contentVmPtr) { diff --git a/engines/sci/gui/gui_menu.cpp b/engines/sci/gui/gui_menu.cpp index 316d0bbf01..e9795edc5c 100644 --- a/engines/sci/gui/gui_menu.cpp +++ b/engines/sci/gui/gui_menu.cpp @@ -30,8 +30,6 @@ #include "sci/sci.h" #include "sci/event.h" #include "sci/engine/state.h" -#include "sci/gfx/operations.h" -#include "sci/gfx/gfx_state_internal.h" #include "sci/gui/gui_helpers.h" #include "sci/gui/gui_gfx.h" #include "sci/gui/gui_cursor.h" @@ -60,10 +58,6 @@ SciGuiMenu::~SciGuiMenu() { // TODO: deallocate _list and _itemList } -void SciGuiMenu::init(GfxState *gfxstate) { - _gfxstate = gfxstate; -} - void SciGuiMenu::add(Common::String title, Common::String content, reg_t contentVmPtr) { GuiMenuEntry *menuEntry; uint16 itemCount = 0; diff --git a/engines/sci/gui/gui_menu.h b/engines/sci/gui/gui_menu.h index 66cb19a71a..a396378dc0 100644 --- a/engines/sci/gui/gui_menu.h +++ b/engines/sci/gui/gui_menu.h @@ -81,7 +81,6 @@ public: SciGuiMenu(SciEvent *event, SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor); ~SciGuiMenu(); - void init(GfxState *gfxstate); void reset(); void add(Common::String title, Common::String content, reg_t contentVmPtr); void setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value); @@ -100,7 +99,6 @@ private: GuiMenuItemEntry *interactiveGetItem(uint16 menuId, uint16 itemId, bool menuChanged); SciEvent *_event; - GfxState *_gfxstate; SegManager *_segMan; SciGuiGfx *_gfx; SciGuiText *_text; diff --git a/engines/sci/gui32/font.cpp b/engines/sci/gui32/font.cpp deleted file mode 100644 index aa5370bce7..0000000000 --- a/engines/sci/gui32/font.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gui32/font.h" - -namespace Sci { - -int font_counter = 0; - -void gfxr_free_font(gfx_bitmap_font_t *font) { - free(font->widths); - free(font->data); - - --font_counter; - - free(font); -} - -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_p, int *last_offset_p, int flags) { - - int maxheight = font->line_height; - int last_breakpoint = 0; - int last_break_width = 0; - int maxwidth = 0, localmaxwidth = 0; - const char *breakpoint_ptr = NULL; - unsigned char curChar; - - if (line_height_p) - *line_height_p = font->line_height; - - - fragments.push_back(TextFragment(text)); - - while ((curChar = *text++)) { - if (curChar >= font->chars_nr) { - error("Invalid char 0x%02x (max. 0x%02x) encountered in text string '%s', font %04x", - curChar, font->chars_nr, text, font->ID); - if (font->chars_nr > ' ') - curChar = ' '; - else { - return false; - } - } - - if (((curChar == '\n') || (curChar == 0x0d)) && !(flags & kFontNoNewlines)) { - fragments.back().length = text - 1 - fragments.back().offset; - - if (*text) - maxheight += font->line_height; - - if (curChar == 0x0d && *text == '\n') - text++; // Interpret DOS-style CR LF as single NL - - fragments.push_back(TextFragment(text)); - - if (localmaxwidth > maxwidth) - maxwidth = localmaxwidth; - - localmaxwidth = 0; - - } else { // curChar != '\n' - localmaxwidth += font->widths[curChar]; - - if (localmaxwidth > max_width) { - int blank_break = 1; // break is at a blank char, i.e. not within a word - - maxheight += font->line_height; - - if (last_breakpoint == 0) { // Text block too long and without whitespace? - last_breakpoint = localmaxwidth - font->widths[curChar]; - last_break_width = 0; - --text; - blank_break = 0; // non-blank break - } else { - text = breakpoint_ptr + 1; - assert(breakpoint_ptr); - } - - if (last_breakpoint == 0) { - warning("[GFX] maxsize %d too small for '%s'", max_width, text); - } - - if (last_breakpoint > maxwidth) - maxwidth = last_breakpoint; - - fragments.back().length = text - blank_break - fragments.back().offset; - fragments.push_back(TextFragment(text)); - - localmaxwidth = localmaxwidth - last_breakpoint; - localmaxwidth -= last_break_width; - last_breakpoint = localmaxwidth = 0; - - } else if (*text == ' ') { - last_breakpoint = localmaxwidth; - last_break_width = font->widths[curChar]; - breakpoint_ptr = text; - } - - } - } - - if (localmaxwidth > maxwidth) - *width = localmaxwidth; - else - *width = maxwidth; - - if (last_offset_p) - *last_offset_p = localmaxwidth; - - if (height) - *height = maxheight; - - fragments.back().length = text - fragments.back().offset - 1; - - return true; -} - -static void render_char(byte *dest, byte *src, int width, int line_width, int lines, int bytes_per_src_line, int fg0, int fg1, int bg) { - int x, y; - - for (y = 0; y < lines; y++) { - int dat = 0; - byte *vdest = dest; - byte *vsrc = src; - int xc = 0; - - for (x = 0; x < width; x++) { - if (!xc) { - dat = *vsrc++; - xc = 8; - } - xc--; - - if (dat & 0x80) - *vdest++ = ((xc ^ y) & 1) ? fg0 : fg1; /* dither */ - else - *vdest++ = bg; - - dat <<= 1; - } - src += bytes_per_src_line; - dest += line_width; - } -} - -gfx_pixmap_t *gfxr_draw_font(gfx_bitmap_font_t *font, const char *stext, int characters, PaletteEntry *fg0, PaletteEntry *fg1, PaletteEntry *bg) { - const byte *text = (const byte *)stext; - int height = font->height; - int width = 0; - gfx_pixmap_t *pxm; - int fore_0, fore_1, back; - int i; - int hack = 0; - PaletteEntry dummy(0,0,0); // black - byte *offset; - - for (i = 0; i < characters; i++) { - int ch = (int) text[i]; - - if (ch >= font->chars_nr) { - error("Invalid character 0x%02x encountered", text[i]); - return NULL; - } - - width += font->widths[ch]; - } - - pxm = gfx_pixmap_alloc_index_data(gfx_new_pixmap(width, height, GFX_RESID_NONE, 0, 0)); - - int colors_nr = !!fg0 + !!fg1 + !!bg; - if (colors_nr == 0) { - warning("[GFX] Pixmap would have zero colors, resetting"); - colors_nr = 3; - hack = 1; - fg0 = fg1 = bg = &dummy; - } - pxm->palette = new Palette(colors_nr); - pxm->palette->name = "font"; - - i = 0; - - if (fg0 || hack) { - pxm->palette->setColor(i, fg0->r, fg0->g, fg0->b); - fore_0 = i++; - } else - fore_0 = pxm->color_key; - - if (fg1 || hack) { - pxm->palette->setColor(i, fg1->r, fg1->g, fg1->b); - fore_1 = i++; - } else - fore_1 = pxm->color_key; - - if (bg || hack) { - pxm->palette->setColor(i, bg->r, bg->g, bg->b); - back = i++; - } else - back = pxm->color_key; - - offset = pxm->index_data; - - memset(pxm->index_data, back, pxm->index_width * pxm->index_height); - for (i = 0; i < characters; i++) { - unsigned char ch = text[i]; - width = font->widths[ch]; - - render_char(offset, font->data + (ch * font->char_size), width, - pxm->index_width, pxm->index_height, font->row_size, fore_0, fore_1, back); - - offset += width; - } - - return pxm; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui32/font.h b/engines/sci/gui32/font.h deleted file mode 100644 index d7b92db029..0000000000 --- a/engines/sci/gui32/font.h +++ /dev/null @@ -1,150 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#ifndef SCI_GFX_FONT_H -#define SCI_GFX_FONT_H - -#include "common/scummsys.h" - - -namespace Sci { -/** @name Font operations and stuctures */ -/** @{ */ - -struct TextFragment { - const char *offset; - int length; - - TextFragment() : offset(0), length(0) {} - TextFragment(const char *o) : offset(o), length(0) {} -}; - -/** - * 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 handling flags. - * - * SCI0, SCI01 and SCI1 all use the same font format. - */ -enum fontFlags { - kFontNoNewlines = 1 << 0, ///< Don't treat newline characters - kFontIgnoreLF = 1 << 1 ///< 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); - -/** - * Frees a previously allocated font structure. - * - * @param font The font to free - */ -void gfxr_free_font(gfx_bitmap_font_t *font); - -/** - * 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); - -/** - * 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 - -#endif // SCI_GFX_FONT_H diff --git a/engines/sci/gui32/gui32.cpp b/engines/sci/gui32/gui32.cpp deleted file mode 100644 index bcda0e3611..0000000000 --- a/engines/sci/gui32/gui32.cpp +++ /dev/null @@ -1,3055 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX and USE_OLD_MUSIC_FUNCTIONS -#ifdef INCLUDE_OLDGFX - -#include "graphics/cursorman.h" -#include "common/util.h" - -#include "sci/engine/state.h" -#include "sci/debug.h" // for g_debug_sleeptime_factor -#include "sci/event.h" -#include "sci/resource.h" -#include "sci/engine/state.h" -#include "sci/engine/kernel.h" -#include "sci/gfx/gfx_gui.h" -#include "sci/gfx/gfx_widgets.h" -#include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual -#include "sci/gfx/menubar.h" -#include "sci/gui32/gui32.h" -#include "sci/gui/gui_animate.h" -#include "sci/gui/gui_cursor.h" -#include "sci/gui/gui_gfx.h" - -// This is the real width of a text with a specified width of 0 -#define MAX_TEXT_WIDTH_MAGIC_VALUE 192 - -#define K_DRAWPIC_FLAG_MIRRORED (1 << 14) - -namespace Sci { - -#undef DEBUG_LSRECT - -// This is the real width of a text with a specified width of 0 -#define MAX_TEXT_WIDTH_MAGIC_VALUE 192 - -#define ADD_TO_CURRENT_PORT(widget) \ - {if (_s->port) \ - _s->port->add((GfxContainer *)_s->port, widget); \ - else \ - _s->picture_port->add((GfxContainer *)_s->visual, widget);} - -#define ADD_TO_CURRENT_PICTURE_PORT(widget) \ - {if (_s->port) \ - _s->port->add((GfxContainer *)_s->port, widget); \ - else \ - _s->picture_port->add((GfxContainer *)_s->picture_port, widget);} - -#define ADD_TO_WINDOW_PORT(widget) \ - _s->wm_port->add((GfxContainer *)_s->wm_port, widget); - -#define FULL_REDRAW()\ - if (_s->visual) \ - _s->visual->draw(gfxw_point_zero); \ - gfxop_update(_s->gfx_state); - -#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)))) - -#define SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr) ((((nr) == 0)? 0 : \ - ((s->priority_first) + (((nr)-1) * (s->priority_last - s->priority_first)) / 14))) - -#define SCI0_VIEW_PRIORITY(y) (((y) < s->priority_first)? 0 : (((y) >= s->priority_last)? 14 : 1\ - + ((((y) - s->priority_first) * 15) / (s->priority_last - s->priority_first)))) - -#define SCI0_PRIORITY_BAND_FIRST(nr) ((((nr) == 0)? 0 : \ - ((s->priority_first) + (((nr)-1) * (s->priority_last - s->priority_first)) / 15))) - -#if 0 -// Used for debugging -#define FULL_INSPECTION()\ - if (_s->visual) \ - _s->visual->print(_s->visual, 0); -#endif - -// was static -void assert_primary_widget_lists(EngineState *s) { - EngineState *_s = s; - if (!s->dyn_views) { - rect_t bounds = _s->picture_port->_bounds; - - s->dyn_views = gfxw_new_list(bounds, GFXW_LIST_SORTED); - s->dyn_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - ADD_TO_CURRENT_PICTURE_PORT(_s->dyn_views); - } - - if (!s->drop_views) { - rect_t bounds = _s->picture_port->_bounds; - - s->drop_views = gfxw_new_list(bounds, GFXW_LIST_SORTED); - s->drop_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - ADD_TO_CURRENT_PICTURE_PORT(_s->drop_views); - } -} - -// static -void reparentize_primary_widget_lists(EngineState *s, GfxPort *newport) { - if (!newport) - newport = s->picture_port; - - if (s->dyn_views) { - gfxw_remove_widget_from_container(s->dyn_views->_parent, s->dyn_views); - - newport->add((GfxContainer *)newport, s->dyn_views); - } -} - -int _find_view_priority(EngineState *s, int y) { - /*if (_s->version <= SCI_VERSION_LTU_PRIORITY_OB1) - ++y; */ - - if (s->pic_priority_table) { // SCI01 priority table set? - int j; - for (j = 0; j < 15; j++) - if (y < s->pic_priority_table[j+1]) - return j; - return 14; // Maximum - } else { - if (!s->usesOldGfxFunctions()) - return SCI0_VIEW_PRIORITY_14_ZONES(y); - else - return SCI0_VIEW_PRIORITY(y) == 15 ? 14 : SCI0_VIEW_PRIORITY(y); - } -} - -int _find_priority_band(EngineState *s, int nr) { - if (!s->usesOldGfxFunctions() && (nr < 0 || nr > 14)) { - if (nr == 15) - return 0xffff; - else { - warning("Attempt to get priority band %d", nr); - } - return 0; - } - - if (s->usesOldGfxFunctions() && (nr < 0 || nr > 15)) { - warning("Attempt to get priority band %d", nr); - return 0; - } - - if (s->pic_priority_table) // SCI01 priority table set? - return s->pic_priority_table[nr]; - else { - int retval; - - if (!s->usesOldGfxFunctions()) - retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr); - else - retval = SCI0_PRIORITY_BAND_FIRST(nr); - -/* if (_s->version <= SCI_VERSION_LTU_PRIORITY_OB1) - --retval; */ - return retval; - } -} - -reg_t graph_save_box(EngineState *s, rect_t area) { - reg_t handle = kalloc(s->_segMan, "graph_save_box()", sizeof(gfxw_snapshot_t *)); - gfxw_snapshot_t **ptr = (gfxw_snapshot_t **)kmem(s->_segMan, handle); - - // FIXME: gfxw_make_snapshot returns a pointer. Now why do we store a - // pointer to real memory inside the SCI heap? - // If we save and the load again, this cannot work in general. - // This seems like bad design. Either the snapshot data itself should be - // stored in the heap, or a unique persistent id. - *ptr = gfxw_make_snapshot(s->visual, area); - - return handle; -} - -void graph_restore_box(EngineState *s, reg_t handle) { - gfxw_snapshot_t **ptr; - int port_nr = s->port->_ID; - - if (!handle.segment) { - warning("Attempt to restore box with zero handle"); - return; - } - - ptr = (gfxw_snapshot_t **)kmem(s->_segMan, handle); - - if (!ptr) { - warning("Attempt to restore invalid handle %04x:%04x", PRINT_REG(handle)); - return; - } - - while (port_nr > 2 && !(s->port->_flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS) && (gfxw_widget_matches_snapshot(*ptr, s->port))) { - // This shouldn't ever happen, actually, since windows (ports w/ ID > 2) should all be immune - GfxPort *newport = s->visual->getPort(port_nr); - error("Port %d is not immune against snapshots", s->port->_ID); - port_nr--; - if (newport) - s->port = newport; - } - - if (s->dyn_views && gfxw_widget_matches_snapshot(*ptr, s->dyn_views->_parent)) { - GfxContainer *parent = s->dyn_views->_parent; - - do { - parent = parent->_parent; - } while (parent && (gfxw_widget_matches_snapshot(*ptr, parent))); - - if (!parent) { - error("Attempted widget mass destruction by a snapshot"); - } - - reparentize_primary_widget_lists(s, (GfxPort *) parent); - } - - - if (!ptr) { - error("Attempt to restore invalid snaphot with handle %04x:%04x", PRINT_REG(handle)); - return; - } - - gfxw_restore_snapshot(s->visual, *ptr); - free(*ptr); - *ptr = NULL; - - kfree(s->_segMan, handle); -} - -PaletteEntry get_pic_color(EngineState *s, int color) { - if (!s->resMan->isVGA()) - return s->ega_colors[color].visual; - - if (color == -1 || color == 255) // -1 occurs in Eco Quest 1. Not sure if this is the best approach, but it seems to work - return PaletteEntry(255,255,255); - else if (color < s->gfx_state->gfxResMan->getColorCount()) - return s->gfx_state->gfxResMan->getColor(color); - else { - // Happens in the beginning of EcoQuest 2, when the dialog box of the customs officer shows up - warning("Color index %d out of bounds for pic %d (%d max)", color, s->gfx_state->pic_nr, s->gfx_state->gfxResMan->getColorCount()); - return PaletteEntry(0,0,0); - } -} - -static Common::Rect nsrect_clip(EngineState *s, int y, Common::Rect retval, int priority) { - int pri_top; - - if (priority == -1) - priority = _find_view_priority(s, y); - - pri_top = _find_priority_band(s, priority) + 1; - // +1: Don't know why, but this seems to be happening - - if (retval.top < pri_top) - retval.top = pri_top; - - if (retval.bottom < retval.top) - retval.top = retval.bottom - 1; - - return retval; -} - -static Common::Rect calculate_nsrect(EngineState *s, int x, int y, int view, int loop, int cel) { - int xbase, ybase, xend, yend, xsize, ysize; - int xmod = 0, ymod = 0; - Common::Rect retval(0, 0, 0, 0); - - Common::Point offset = Common::Point(0, 0); - - gfxop_get_cel_parameters(s->gfx_state, view, loop, cel, &xsize, &ysize, &offset); - - xmod = offset.x; - ymod = offset.y; - - xbase = x - xmod - (xsize >> 1); - xend = xbase + xsize; - yend = y - ymod + 1; // +1: magic modifier - ybase = yend - ysize; - - retval.left = xbase; - retval.top = ybase; - retval.right = xend; - retval.bottom = yend; - - return retval; -} - -Common::Rect get_nsrect(EngineState *s, reg_t object, byte clip) { - int x, y, z; - int view, loop, cel; - Common::Rect retval; - - x = (int16)GET_SEL32V(s->_segMan, object, x); - y = (int16)GET_SEL32V(s->_segMan, object, y); - - if (s->_kernel->_selectorCache.z > -1) - z = (int16)GET_SEL32V(s->_segMan, object, z); - else - z = 0; - - y -= z; // Subtract z offset - - view = (int16)GET_SEL32V(s->_segMan, object, view); - int l = (int16)GET_SEL32V(s->_segMan, object, loop); - loop = (l & 0x80) ? l - 256 : l; - int c = (int16)GET_SEL32V(s->_segMan, object, cel); - cel = (c & 0x80) ? c - 256 : c; - - retval = calculate_nsrect(s, x, y, view, loop, cel); - - if (clip) { - int priority = (int16)GET_SEL32V(s->_segMan, object, priority); - return nsrect_clip(s, y, retval, priority); - } - - return retval; -} - -Common::Rect get_nsrect32(EngineState *s, reg_t object, byte clip) { - int x, y, z; - int view, loop, cel; - Common::Rect retval; - - x = (int16)GET_SEL32V(s->_segMan, object, x); - y = (int16)GET_SEL32V(s->_segMan, object, y); - - if (s->_kernel->_selectorCache.z > -1) - z = (int16)GET_SEL32V(s->_segMan, object, z); - else - z = 0; - - y -= z; // Subtract z offset - - view = (int16)GET_SEL32V(s->_segMan, object, view); - int l = (int16)GET_SEL32V(s->_segMan, object, loop); - loop = (l & 0x80) ? l - 256 : l; - int c = (int16)GET_SEL32V(s->_segMan, object, cel); - cel = (c & 0x80) ? c - 256 : c; - - retval = calculate_nsrect(s, x, y, view, loop, cel); - - if (clip) { - int priority = (int16)GET_SEL32V(s->_segMan, object, priority); - return nsrect_clip(s, y, retval, priority); - } - - return retval; -} - -// ====================================================================================================== - -SciGui32::SciGui32( EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor) { - _s = state; - _screen = screen; - _palette = palette; - _cursor = cursor; - _gfx = new SciGuiGfx(_s->resMan, _s->_segMan, _s->_kernel, _screen, _palette); -} - -SciGui32::~SciGui32() { -} - -void SciGui32::init(bool oldGfxFunctions) { - _usesOldGfxFunctions = oldGfxFunctions; - _k_animate_ran = false; - activated_icon_bar = false; - port_origin_x = 0; - port_origin_y = 0; -} - -void SciGui32::resetEngineState(EngineState *s) { - _s = s; -} - -void SciGui32::wait(int16 ticks) { - uint32 time; - - time = g_system->getMillis(); - _s->r_acc = make_reg(0, ((long)time - (long)_s->last_wait_time) * 60 / 1000); - _s->last_wait_time = time; - - ticks *= g_debug_sleeptime_factor; - kernel_sleep(_s->_event, ticks * 1000 / 60); -} - -void SciGui32::setPort(uint16 portPtr) { - GfxPort *new_port; - - /* We depart from official semantics here, sorry! - Reasoning: Sierra SCI does not clip ports while we do. - Therefore a draw to the titlebar port (which is the - official semantics) would cut off the lower part of the - icons in an SCI1 icon bar. Instead we have an - iconbar_port that does not exist in SSCI. */ - if (portPtr == 65535) portPtr = _s->iconbar_port->_ID; - - new_port = _s->visual->getPort(portPtr); - - if (!new_port) { - warning("Invalid port %04x requested", portPtr); - return; - } - - _s->port->draw(gfxw_point_zero); // Update the port we're leaving - _s->port = new_port; -} - -Common::Rect SciGui32::getPortPic(int16 &picTop, int16 &picLeft) { - // Don't want to fiddle around with oldgui, so we just return defaults when saving games - Common::Rect defaultRect(0, 0, 320, 200); - picTop = 10; - picLeft = 0; - return defaultRect; -} - -void SciGui32::setPortPic(Common::Rect rect, int16 picTop, int16 picLeft, bool initPriorityBandsFlag) { - if (activated_icon_bar) { - port_origin_x = port_origin_y = 0; - activated_icon_bar = false; - return; - } - port_origin_y = rect.top; - port_origin_x = rect.left; - - if (rect.top == -10) { - _s->port->draw(gfxw_point_zero); // Update the port we're leaving - _s->port = _s->iconbar_port; - activated_icon_bar = true; - return; - } - - // Notify the graphics resource manager that the pic port bounds changed - _s->gfx_state->gfxResMan->changePortBounds(picLeft, picTop, rect.right + picLeft, rect.bottom + picTop); - - // LSL6 calls kSetPort to extend the screen to draw the Gui. If we free all resources - // here, the background picture is freed too, and this makes everything a big mess. - // FIXME/TODO: This code really needs to be rewritten to conform to the original behavior - if (_s->_gameId != "lsl6") { - _s->gfx_state->pic_port_bounds = gfx_rect(picLeft, picTop, rect.right, rect.bottom); - - // FIXME: Should really only invalidate all loaded pic resources here; - // this is overkill - _s->gfx_state->gfxResMan->freeAllResources(); - } else { - // WORKAROUND for LSL6 - warning("SetPort case 6 called in LSL6."); - } -} - -reg_t SciGui32::getPort() { - return make_reg(0, _s->port->_ID); -} - -void SciGui32::globalToLocal(int16 *x, int16 *y) { - *x = *x - _s->port->zone.x; - *y = *y - _s->port->zone.y; -} - -void SciGui32::localToGlobal(int16 *x, int16 *y) { - *x = *x + _s->port->zone.x; - *y = *y + _s->port->zone.y; -} - -int16 SciGui32::coordinateToPriority(int16 y) { - return _find_view_priority(_s, y); -} - -int16 SciGui32::priorityToCoordinate(int16 priority) { - return _find_priority_band(_s, priority); -} - -reg_t SciGui32::newWindow(Common::Rect dims, Common::Rect restoreRect, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title) { - GfxPort *window; - int x, y, xl, yl; - gfx_color_t bgcolor; - gfx_color_t fgcolor; - gfx_color_t black; - gfx_color_t lWhite; - - y = dims.top; - x = dims.left; - yl = dims.height(); - xl = dims.width(); - - y += _s->wm_port->_bounds.y; - - if (x + xl > 319) - x -= ((x + xl) - 319); - - bgcolor.mask = 0; - - if (colorBack >= 0) { - if (!_s->resMan->isVGA()) - bgcolor.visual = get_pic_color(_s, MIN<int>(colorBack, 15)); - else - bgcolor.visual = get_pic_color(_s, colorBack); - bgcolor.mask = GFX_MASK_VISUAL; - } else { - bgcolor.visual = PaletteEntry(0,0,0); - } - - bgcolor.priority = priority; - bgcolor.mask |= priority >= 0 ? GFX_MASK_PRIORITY : 0; - bgcolor.alpha = 0; - bgcolor.control = -1; - debugC(2, kDebugLevelGraphics, "New window with params %d, %d, %d, %d\n", dims.top, dims.left, dims.height(), dims.width()); - - fgcolor.visual = get_pic_color(_s, colorPen); - fgcolor.mask = GFX_MASK_VISUAL; - fgcolor.control = -1; - fgcolor.priority = -1; - fgcolor.alpha = 0; - black.visual = get_pic_color(_s, 0); - black.mask = GFX_MASK_VISUAL; - black.alpha = 0; - black.control = -1; - black.priority = -1; - lWhite.visual = get_pic_color(_s, !_s->resMan->isVGA() ? 15 : 255); - lWhite.mask = GFX_MASK_VISUAL; - lWhite.alpha = 0; - lWhite.priority = -1; - lWhite.control = -1; - - window = sciw_new_window(_s, gfx_rect(x, y, xl, yl), _s->titlebar_port->_font, fgcolor, bgcolor, - _s->titlebar_port->_font, lWhite, black, title ? _s->strSplit(title, NULL).c_str() : NULL, style); - - // PQ3 and SCI1.1 games have the interpreter store underBits implicitly - if (restoreRect.top != 0 && restoreRect.left != 0 && restoreRect.height() != 0 && restoreRect.width() != 0) - gfxw_port_auto_restore_background(_s->visual, window, gfx_rect(restoreRect.left, restoreRect.top + _s->wm_port->_bounds.y, - restoreRect.width(), restoreRect.height())); - - ADD_TO_WINDOW_PORT(window); - FULL_REDRAW(); - - window->draw(gfxw_point_zero); - gfxop_update(_s->gfx_state); - - _s->port = window; // Set active port - - return make_reg(0, window->_ID); -} - -void SciGui32::disposeWindow(uint16 windowPtr, bool reanimate) { - GfxPort *goner; - GfxPort *pred; - - goner = _s->visual->getPort(windowPtr); - if ((windowPtr < 3) || (goner == NULL)) { - error("Removal of invalid window %04x requested", windowPtr); - return; - } - - if (_s->dyn_views && (GfxContainer *)_s->dyn_views->_parent == (GfxContainer *)goner) { - reparentize_primary_widget_lists(_s, (GfxPort *) goner->_parent); - } - - if (_s->drop_views && (GfxContainer *)_s->drop_views->_parent == (GfxContainer *)goner) - _s->drop_views = NULL; // Kill it - - pred = gfxw_remove_port(_s->visual, goner); - - if (goner == _s->port) // Did we kill the active port? - _s->port = pred; - - // Find the last port that exists and that isn't marked no-switch - int id = _s->visual->_portRefs.size() - 1; - while (id > 0 && (!_s->visual->_portRefs[id] || (_s->visual->_portRefs[id]->_flags & GFXW_FLAG_NO_IMPLICIT_SWITCH))) - id--; - - debugC(2, kDebugLevelGraphics, "Activating port %d after disposing window %d\n", id, windowPtr); - _s->port = (id >= 0) ? _s->visual->_portRefs[id] : 0; - - if (!_s->port) - _s->port = gfxw_find_default_port(_s->visual); - - gfxop_update(_s->gfx_state); -} - -#define K_DISPLAY_SET_COORDS 100 -#define K_DISPLAY_SET_ALIGNMENT 101 -#define K_DISPLAY_SET_COLOR 102 -#define K_DISPLAY_SET_BGCOLOR 103 -#define K_DISPLAY_SET_GRAYTEXT 104 -#define K_DISPLAY_SET_FONT 105 -#define K_DISPLAY_WIDTH 106 -#define K_DISPLAY_SAVE_UNDER 107 -#define K_DISPLAY_RESTORE_UNDER 108 -#define K_DONT_UPDATE_IMMEDIATELY 121 - -void SciGui32::display(const char *text, int argc, reg_t *argv) { - int argpt = 0; - int temp; - bool save_under = false; - gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 }; - GfxPort *port = (_s->port) ? _s->port : _s->picture_port; - bool update_immediately = true; - - gfx_color_t color0, *color1, bg_color; - gfx_alignment_t halign = ALIGN_LEFT; - rect_t area = gfx_rect(port->draw_pos.x, port->draw_pos.y, 320 - port->draw_pos.x, 200 - port->draw_pos.y); - int gray = port->gray_text; - int font_nr = port->_font; - GfxText *text_handle; - - color0 = port->_color; - bg_color = port->_bgcolor; - // TODO: in SCI1VGA the default colors for text and background are #0 (black) - // SCI0 case should be checked - if (_s->resMan->isVGA()) { - // This priority check fixes the colors in the menus in KQ5 - // TODO/FIXME: Is this correct? - if (color0.priority >= 0) - color0.visual = get_pic_color(_s, 0); - if (bg_color.priority >= 0) - bg_color.visual = get_pic_color(_s, 0); - } - - while (argpt < argc) { - switch (argv[argpt++].toUint16()) { - - case K_DISPLAY_SET_COORDS: - - area.x = argv[argpt++].toUint16(); - area.y = argv[argpt++].toUint16(); - debugC(2, kDebugLevelGraphics, "Display: set_coords(%d, %d)\n", area.x, area.y); - break; - - case K_DISPLAY_SET_ALIGNMENT: - - halign = (gfx_alignment_t)argv[argpt++].toSint16(); - debugC(2, kDebugLevelGraphics, "Display: set_align(%d)\n", halign); - break; - - case K_DISPLAY_SET_COLOR: - - temp = argv[argpt++].toSint16(); - debugC(2, kDebugLevelGraphics, "Display: set_color(%d)\n", temp); - if (!_s->resMan->isVGA() && temp >= 0 && temp <= 15) - color0 = (_s->ega_colors[temp]); - else - if (_s->resMan->isVGA() && temp >= 0 && temp < 256) { - color0.visual = get_pic_color(_s, temp); - color0.mask = GFX_MASK_VISUAL; - } else - if (temp == -1) - color0 = transparent; - else - warning("Display: Attempt to set invalid fg color %d", temp); - break; - - case K_DISPLAY_SET_BGCOLOR: - - temp = argv[argpt++].toSint16(); - debugC(2, kDebugLevelGraphics, "Display: set_bg_color(%d)\n", temp); - if (!_s->resMan->isVGA() && temp >= 0 && temp <= 15) - bg_color = _s->ega_colors[temp]; - else - if (_s->resMan->isVGA() && temp >= 0 && temp <= 256) { - bg_color.visual = get_pic_color(_s, temp); - bg_color.mask = GFX_MASK_VISUAL; - } else - if (temp == -1) - bg_color = transparent; - else - warning("Display: Attempt to set invalid fg color %d", temp); - break; - - case K_DISPLAY_SET_GRAYTEXT: - - gray = argv[argpt++].toSint16(); - debugC(2, kDebugLevelGraphics, "Display: set_graytext(%d)\n", gray); - break; - - case K_DISPLAY_SET_FONT: - - font_nr = argv[argpt++].toUint16(); - - debugC(2, kDebugLevelGraphics, "Display: set_font(\"font.%03d\")\n", font_nr); - break; - - case K_DISPLAY_WIDTH: - - area.width = argv[argpt++].toUint16(); - if (area.width == 0) - area.width = MAX_TEXT_WIDTH_MAGIC_VALUE; - - debugC(2, kDebugLevelGraphics, "Display: set_width(%d)\n", area.width); - break; - - case K_DISPLAY_SAVE_UNDER: - - save_under = true; - debugC(2, kDebugLevelGraphics, "Display: set_save_under()\n"); - break; - - case K_DISPLAY_RESTORE_UNDER: - - debugC(2, kDebugLevelGraphics, "Display: restore_under(%04x)\n", argv[argpt].toUint16()); - graph_restore_box(_s, argv[argpt++]); - update_immediately = true; - argpt++; - return; - - case K_DONT_UPDATE_IMMEDIATELY: - - update_immediately = false; - debugC(2, kDebugLevelGraphics, "Display: set_dont_update()\n"); - argpt++; - break; - - default: - debugC(2, kDebugLevelGraphics, "Unknown Display() command %x\n", argv[argpt - 1].toUint16()); - return; - } - } - - if (halign == ALIGN_LEFT) { - // If the text does not fit on the screen, move it to the left and upwards until it does - gfxop_get_text_params(_s->gfx_state, font_nr, text, area.width, &area.width, &area.height, 0, NULL, NULL, NULL); - - // Make the text fit on the screen - if (area.x + area.width > 320) - area.x += 320 - area.x - area.width; // Plus negative number = subtraction - - if (area.y + area.height > 200) - area.y += 200 - area.y - area.height; // Plus negative number = subtraction - } else { - // If the text does not fit on the screen, clip it till it does - if (area.x + area.width > _s->gfx_state->pic_port_bounds.width) - area.width = _s->gfx_state->pic_port_bounds.width - area.x; - - if (area.y + area.height > _s->gfx_state->pic_port_bounds.height) - area.height = _s->gfx_state->pic_port_bounds.height - area.y; - } - - if (gray) - color1 = &bg_color; - else - color1 = &color0; - - assert_primary_widget_lists(_s); - - 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"); - return; - } - - if (save_under) { // Backup - rect_t save_area = text_handle->_bounds; - save_area.x += port->_bounds.x; - save_area.y += port->_bounds.y; - - _s->r_acc = graph_save_box(_s, save_area); - text_handle->_serial++; // This is evil! - - debugC(2, kDebugLevelGraphics, "Saving (%d, %d) size (%d, %d) as %04x:%04x\n", save_area.x, save_area.y, save_area.width, save_area.height, PRINT_REG(_s->r_acc)); - } - - debugC(2, kDebugLevelGraphics, "Display: Commiting text '%s'\n", text); - - //ADD_TO_CURRENT_PICTURE_PORT(text_handle); - - ADD_TO_CURRENT_PICTURE_PORT(text_handle); - if ((!_s->pic_not_valid) && update_immediately) { // Refresh if drawn to valid picture - FULL_REDRAW(); - debugC(2, kDebugLevelGraphics, "Refreshing display...\n"); - } -} - -void SciGui32::textSize(const char *text, int16 fontId, int16 maxWidth, int16 *textWidth, int16 *textHeight) { - int width, height; - if (maxWidth < 0) - maxWidth = 0; - gfxop_get_text_params(_s->gfx_state, fontId, text, maxWidth ? maxWidth : MAX_TEXT_WIDTH_MAGIC_VALUE, - &width, &height, 0, NULL, NULL, NULL); - *textWidth = width; *textHeight = height; -} - -void SciGui32::textFonts(int argc, reg_t *argv) { - // stub -} - -void SciGui32::textColors(int argc, reg_t *argv) { - // stub -} - -void SciGui32::drawStatus(const char *text, int16 colorPen, int16 colorBack) { - _s->titlebar_port->_color.visual = get_pic_color(_s, colorPen); - _s->titlebar_port->_color.mask = GFX_MASK_VISUAL; - _s->titlebar_port->_bgcolor.visual = get_pic_color(_s, colorBack); - _s->titlebar_port->_bgcolor.mask = GFX_MASK_VISUAL; - - sciw_set_status_bar(_s, _s->titlebar_port, text, colorPen, colorBack); - - gfxop_update(_s->gfx_state); -} - -void SciGui32::drawMenuBar(bool clear) { - if (!clear) { - sciw_set_menubar(_s, _s->titlebar_port, _s->_menubar, -1); - } else { - sciw_set_status_bar(_s, _s->titlebar_port, "", 0, 0); - } - _s->titlebar_port->draw(Common::Point(0, 0)); - gfxop_update(_s->gfx_state); -} - -void SciGui32::menuReset() { -} - -void SciGui32::menuAdd(Common::String title, Common::String content, reg_t entriesBase) { - int titlebarFont = _s->titlebar_port->_font; - - _s->_menubar->addMenu(_s->gfx_state, title, content, titlebarFont, entriesBase); -} - -void SciGui32::menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value) { - _s->_menubar->setAttribute(_s, menuId - 1, itemId - 1, attributeId, value); -} - -reg_t SciGui32::menuGet(uint16 menuId, uint16 itemId, uint16 attributeId) { - return _s->_menubar->getAttribute(menuId - 1, itemId - 1, attributeId); -} - -int _menu_go_down(Menubar *menubar, int menu_nr, int item_nr) { - int seeker; - const int max = menubar->_menus[menu_nr]._items.size(); - seeker = item_nr + 1; - - while ((seeker < max) && !menubar->itemValid(menu_nr, seeker)) - ++seeker; - - if (seeker != max) - return seeker; - else - return item_nr; -} - -#define MENU_FULL_REDRAW \ - _s->visual->draw(Common::Point(0, 0)); \ - gfxop_update(_s->gfx_state); - -reg_t SciGui32::menuSelect(reg_t eventObject) { - /*int pause_sound = (argc > 1) ? argv[1].toUint16() : 1;*/ /* FIXME: Do this eventually */ - bool claimed = false; - int type = GET_SEL32V(_s->_segMan, eventObject, type); - int message = GET_SEL32V(_s->_segMan, eventObject, message); - int modifiers = GET_SEL32V(_s->_segMan, eventObject, modifiers); - int menu_nr = -1, item_nr = 0; - MenuItem *item; - int menu_mode = 0; /* Menu is active */ - int mouse_down = 0; - -#ifdef DEBUG_PARSER - const int debug_parser = 1; -#else - const int debug_parser = 0; -#endif - -#ifdef INCLUDE_OLDGFX - gfxop_set_clip_zone(_s->gfx_state, gfx_rect_fullscreen); -#endif - - /* Check whether we can claim the event directly as a keyboard or said event */ - if (type & (SCI_EVENT_KEYBOARD | SCI_EVENT_SAID)) { - int menuc, itemc; - - if ((type == SCI_EVENT_KEYBOARD) - && (message == SCI_KEY_ESC)) - menu_mode = 1; - - else if ((type == SCI_EVENT_SAID) || message) { /* Don't claim 0 keyboard event */ - debugC(2, kDebugLevelMenu, "Menu: Got %s event: %04x/%04x\n", - ((type == SCI_EVENT_SAID) ? "SAID" : "KBD"), message, modifiers); - - for (menuc = 0; menuc < (int)_s->_menubar->_menus.size(); menuc++) - for (itemc = 0; itemc < (int)_s->_menubar->_menus[menuc]._items.size(); itemc++) { - item = &_s->_menubar->_menus[menuc]._items[itemc]; - - debugC(2, kDebugLevelMenu, "Menu: Checking against %s: %04x/%04x (type %d, %s)\n", - !item->_text.empty() ? item->_text.c_str() : "--bar--", item->_key, item->_modifiers, - item->_type, item->_enabled ? "enabled" : "disabled"); - - if ((item->_type == MENU_TYPE_NORMAL && item->_enabled) - && ((type == SCI_EVENT_KEYBOARD - && item->matchKey(message, modifiers) - ) - || - (type == SCI_EVENT_SAID - && (item->_flags & MENU_ATTRIBUTE_FLAGS_SAID) - && said(_s, item->_said, debug_parser) != SAID_NO_MATCH - ) - ) - ) { - /* Claim the event */ - debugC(2, kDebugLevelMenu, "Menu: Event CLAIMED for %d/%d\n", menuc, itemc); - claimed = true; - menu_nr = menuc; - item_nr = itemc; - } - } - } - } - - Common::Point cursorPos = _cursor->getPosition(); - - if ((type == SCI_EVENT_MOUSE_PRESS) && (cursorPos.y < 10)) { - menu_mode = 1; - mouse_down = 1; - } - - if (menu_mode) { - int old_item; - int old_menu; - Common::Rect portBounds = Common::Rect(4, 9, 200, 50); - -#ifdef INCLUDE_OLDGFX - GfxPort *port = sciw_new_menu(_s, _s->titlebar_port, _s->_menubar, 0); - portBounds = toCommonRect(port->_bounds); -#endif - - item_nr = -1; - - /* Default to menu 0, unless the mouse was used to generate this effect */ - if (mouse_down) - _s->_menubar->mapPointer(cursorPos, menu_nr, item_nr, portBounds); - else - menu_nr = 0; - -#ifdef INCLUDE_OLDGFX - sciw_set_menubar(_s, _s->titlebar_port, _s->_menubar, menu_nr); -#endif - - MENU_FULL_REDRAW; - - old_item = -1; - old_menu = -1; - - while (menu_mode) { - sciEvent ev = _s->_event->get(SCI_EVENT_ANY); - - claimed = false; - - switch (ev.type) { - case SCI_EVENT_QUIT: - quit_vm(); - return NULL_REG; - - case SCI_EVENT_KEYBOARD: - switch (ev.data) { - - case SCI_KEY_ESC: - menu_mode = 0; - break; - - case SCI_KEY_ENTER: - menu_mode = 0; - if ((item_nr >= 0) && (menu_nr >= 0)) - claimed = true; - break; - - case SCI_KEY_LEFT: - if (menu_nr > 0) - --menu_nr; - else - menu_nr = _s->_menubar->_menus.size() - 1; - - item_nr = _menu_go_down(_s->_menubar, menu_nr, -1); - break; - - case SCI_KEY_RIGHT: - if (menu_nr < ((int)_s->_menubar->_menus.size() - 1)) - ++menu_nr; - else - menu_nr = 0; - - item_nr = _menu_go_down(_s->_menubar, menu_nr, -1); - break; - - case SCI_KEY_UP: - if (item_nr > -1) { - - do { --item_nr; } - while ((item_nr > -1) && !_s->_menubar->itemValid(menu_nr, item_nr)); - } - break; - - case SCI_KEY_DOWN: { - item_nr = _menu_go_down(_s->_menubar, menu_nr, item_nr); - } - break; - - } - break; - - case SCI_EVENT_MOUSE_RELEASE: - { - Common::Point curMousePos = _cursor->getPosition(); - menu_mode = (curMousePos.y < 10); - claimed = !menu_mode && !_s->_menubar->mapPointer(curMousePos, menu_nr, item_nr, portBounds); - mouse_down = 0; - } - break; - - case SCI_EVENT_MOUSE_PRESS: - mouse_down = 1; - break; - - case SCI_EVENT_NONE: - kernel_sleep(_s->_event, 2500 / 1000); - break; - } - - if (mouse_down) - _s->_menubar->mapPointer(_cursor->getPosition(), menu_nr, item_nr, portBounds); - - if ((item_nr > -1 && old_item == -1) || (menu_nr != old_menu)) { /* Update menu */ - -#ifdef INCLUDE_OLDGFX - sciw_set_menubar(_s, _s->titlebar_port, _s->_menubar, menu_nr); - - delete port; - - port = sciw_new_menu(_s, _s->titlebar_port, _s->_menubar, menu_nr); - _s->wm_port->add((GfxContainer *)_s->wm_port, port); -#endif - - if (item_nr > -1) - old_item = -42; /* Enforce redraw in next step */ - else { - MENU_FULL_REDRAW; - } - } /* ...if the menu changed. */ - - /* Remove the active menu item, if neccessary */ - if (item_nr != old_item) { -#ifdef INCLUDE_OLDGFX - port = sciw_toggle_item(port, &(_s->_menubar->_menus[menu_nr]), old_item, false); - port = sciw_toggle_item(port, &(_s->_menubar->_menus[menu_nr]), item_nr, true); -#endif - MENU_FULL_REDRAW; - } - - old_item = item_nr; - old_menu = menu_nr; - - } /* while (menu_mode) */ - - // Clear the menu -#ifdef INCLUDE_OLDGFX - if (port) { - delete port; - port = NULL; - } -#endif - - _s->_gui->drawMenuBar(true); - - MENU_FULL_REDRAW; - } - - if (claimed) { - PUT_SEL32(_s->_segMan, eventObject, claimed, make_reg(0, 1)); - - if (menu_nr > -1) { - _s->r_acc = make_reg(0, ((menu_nr + 1) << 8) | (item_nr + 1)); - } else - _s->r_acc = NULL_REG; - - debugC(2, kDebugLevelMenu, "Menu: Claim -> %04x\n", _s->r_acc.offset); - } else - _s->r_acc = NULL_REG; /* Not claimed */ - - return _s->r_acc; -} - -void SciGui32::drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo) { - gfx_color_t transparent = _s->wm_port->_bgcolor; - int picFlags = DRAWPIC01_FLAG_FILL_NORMALLY; - int palNo = (EGApaletteNo != -1) ? EGApaletteNo : 0; - - if (mirroredFlag) - picFlags |= DRAWPIC1_FLAG_MIRRORED; - - gfxop_disable_dirty_frames(_s->gfx_state); - - if (NULL != _s->old_screen) { - gfx_free_pixmap(_s->old_screen); - } - - _s->old_screen = gfxop_grab_pixmap(_s->gfx_state, gfx_rect(0, 10, 320, 190)); - - debugC(2, kDebugLevelGraphics, "Drawing pic.%03d\n", pictureId); - if (addToFlag) { - gfxop_add_to_pic(_s->gfx_state, pictureId, picFlags, palNo); - } else { - gfxop_new_pic(_s->gfx_state, pictureId, picFlags, palNo); - } - - delete _s->wm_port; - delete _s->picture_port; - delete _s->iconbar_port; - - _s->wm_port = new GfxPort(_s->visual, _s->gfx_state->pic_port_bounds, _s->ega_colors[0], transparent); - _s->picture_port = new GfxPort(_s->visual, _s->gfx_state->pic_port_bounds, _s->ega_colors[0], transparent); - - _s->iconbar_port = new GfxPort(_s->visual, gfx_rect(0, 0, 320, 200), _s->ega_colors[0], transparent); - _s->iconbar_port->_flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH; - - _s->visual->add((GfxContainer *)_s->visual, _s->picture_port); - _s->visual->add((GfxContainer *)_s->visual, _s->wm_port); - _s->visual->add((GfxContainer *)_s->visual, _s->iconbar_port); - - _s->port = _s->picture_port; - - _s->pic_priority_table = (_s->gfx_state->pic) ? _s->gfx_state->pic->priorityTable : NULL; - - _s->pic_animate = animationNr; // The animation used during kAnimate() later on - - _s->dyn_views = NULL; - _s->drop_views = NULL; - - _s->priority_first = 42; - - if (_usesOldGfxFunctions) - _s->priority_last = 200; - else - _s->priority_last = 190; - - _s->pic_not_valid = 1; - _s->pic_is_new = 1; -} - -void SciGui32::drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, int16 origHeight) { - int loop = loopNo; - int cel = celNo; - GfxView *new_view; - - _s->gfx_state->gfxResMan->getView(viewId, &loop, &cel, 0); - debugC(2, kDebugLevelGraphics, "DrawCel((%d,%d), (view.%d, %d, %d), p=%d)\n", leftPos, topPos, viewId, loop, cel, priority); - - new_view = gfxw_new_view(_s->gfx_state, Common::Point(leftPos, topPos), viewId, loop, cel, 0, priority, -1, - ALIGN_LEFT, ALIGN_TOP, GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET); - - ADD_TO_CURRENT_PICTURE_PORT(new_view); - FULL_REDRAW(); -} - -void SciGui32::drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite) { - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(_s->port, obj, area, text, fontId, - (int8)(style & kControlStateFramed), (int8)hilite, (int8)(style & kControlStateDisabled))); - if (!_s->pic_not_valid) FULL_REDRAW(); -} - -void SciGui32::drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 alignment, int16 style, bool hilite) { - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(_s->port, obj, area, text, fontId, (gfx_alignment_t) alignment, - (int8)(!!(style & kControlStateDitherFramed)), (int8)hilite)); - if (!_s->pic_not_valid) FULL_REDRAW(); -} - -void SciGui32::drawControlTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite) { - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - int16 textLength = strlen(text); - - if (cursorPos > textLength) - cursorPos = textLength; - -// update_cursor_limits(&s->save_dir_edit_offset, &cursor, max); FIXME: get rid of this? - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_edit_control(_s->port, obj, area, text, fontId, (unsigned)cursorPos, (int8)hilite)); - if (!_s->pic_not_valid) FULL_REDRAW(); -} - - -void SciGui32::drawControlIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo cellNo, int16 style, bool hilite) { - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_icon_control(_s->port, obj, area, viewId, loopNo, cellNo, - (int8)(style & kControlStateFramed), (int8)hilite)); - if (!_s->pic_not_valid) FULL_REDRAW(); -} - -void SciGui32::drawControlList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite) { - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - - ADD_TO_CURRENT_PICTURE_PORT(sciw_new_list_control(_s->port, obj, area, fontId, entries, count, upperPos, cursorPos, (int8)hilite)); - if (!_s->pic_not_valid) FULL_REDRAW(); -} - - -// Control types and flags -enum { - K_CONTROL_BUTTON = 1, - K_CONTROL_TEXT = 2, - K_CONTROL_EDIT = 3, - K_CONTROL_ICON = 4, - K_CONTROL_CONTROL = 6, - K_CONTROL_CONTROL_ALIAS = 7, - K_CONTROL_BOX = 10 -}; - -#define _K_EDIT_DELETE \ - if (cursor < textlen) { \ - text.deleteChar(cursor); \ - } - -#define _K_EDIT_BACKSPACE \ - if (cursor) { \ - --cursor; \ - text.deleteChar(cursor); \ - --textlen; \ - } - -void update_cursor_limits(int *display_offset, int *cursor, int max_displayed) { - if (*cursor < *display_offset + 4) { - if (*cursor < 8) - *display_offset = 0; - else - *display_offset = *cursor - 8; - } else if (*cursor - *display_offset > max_displayed - 8) - *display_offset = 12 + *cursor - max_displayed; -} - -void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite); - -static inline int sign_extend_byte(int value) { - if (value & 0x80) - return value - 256; - else - return value; -} - -void SciGui32::editControl(reg_t controlObject, reg_t eventObject) { - uint16 ct_type = GET_SEL32V(_s->_segMan, controlObject, type); - - switch (ct_type) { - - case 0: - break; // NOP - - case K_CONTROL_EDIT: - if (eventObject.segment && ((GET_SEL32V(_s->_segMan, eventObject, type)) == SCI_EVENT_KEYBOARD)) { - int max_displayed = GET_SEL32V(_s->_segMan, controlObject, max); - int max = max_displayed; - int cursor = GET_SEL32V(_s->_segMan, controlObject, cursor); - int modifiers = GET_SEL32V(_s->_segMan, eventObject, modifiers); - int key = GET_SEL32V(_s->_segMan, eventObject, message); - reg_t text_pos = GET_SEL32(_s->_segMan, controlObject, text); - int display_offset = 0; - - Common::String text = _s->_segMan->getString(text_pos); - int textlen; - -#if 0 - if (!text) { - warning("Could not draw control: %04x:%04x does not reference text", PRINT_REG(text_pos)); - return _s->r_acc; - } -#endif - - textlen = text.size(); - - cursor += display_offset; - - if (cursor > textlen) - cursor = textlen; - - if (modifiers & SCI_KEYMOD_CTRL) { - - switch (tolower((char)key)) { - case 'a': - cursor = 0; - break; - case 'e': - cursor = textlen; - break; - case 'f': - if (cursor < textlen) ++cursor; - break; - case 'b': - if (cursor > 0) --cursor; - break; - case 'k': - text = Common::String(text.c_str(), cursor); - break; // Terminate string - case 'h': - _K_EDIT_BACKSPACE; - break; - case 'd': - _K_EDIT_DELETE; - break; - } - PUT_SEL32V(_s->_segMan, eventObject, claimed, 1); - - } else if (modifiers & SCI_KEYMOD_ALT) { // Ctrl has precedence over Alt - switch (key) { - case 0x2100 /* A-f */: - while ((cursor < textlen) && (text[cursor++] != ' ')) - ; - break; - case 0x3000 /* A-b */: - while ((cursor > 0) && (text[--cursor - 1] != ' ')) - ; - break; - case 0x2000 /* A-d */: { - while ((cursor < textlen) && (text[cursor] == ' ')) { - _K_EDIT_DELETE; - textlen--; - } - while ((cursor < textlen) && (text[cursor] != ' ')) { - _K_EDIT_DELETE; - textlen--; - } - break; - } - } - PUT_SEL32V(_s->_segMan, eventObject, claimed, 1); - } else if (key < 31) { - PUT_SEL32V(_s->_segMan, eventObject, claimed, 1); - switch (key) { - case SCI_KEY_BACKSPACE: - _K_EDIT_BACKSPACE; - break; - default: - PUT_SEL32V(_s->_segMan, eventObject, claimed, 0); - } - } else if (key & 0xff00) { - switch (key) { - case SCI_KEY_HOME: - cursor = 0; - break; - case SCI_KEY_END: - cursor = textlen; - break; - case SCI_KEY_RIGHT: - if (cursor + 1 <= textlen) - ++cursor; - break; - case SCI_KEY_LEFT: - if (cursor > 0) - --cursor; - break; - case SCI_KEY_DELETE: - _K_EDIT_DELETE; - break; - } - PUT_SEL32V(_s->_segMan, eventObject, claimed, 1); - } else if ((key > 31) && (key < 128)) { - int inserting = (modifiers & SCI_KEYMOD_INSERT); - - modifiers &= ~(SCI_KEYMOD_RSHIFT | SCI_KEYMOD_LSHIFT | SCI_KEYMOD_CAPSLOCK); - - if (cursor == textlen) { - if (textlen < max) { - text += key; - cursor++; - } - } else if (inserting) { - if (textlen < max) { - int i; - - for (i = textlen + 2; i >= cursor; i--) - text.setChar(text[i - 1], i); - text.setChar(key, cursor++); - - } - } else { // Overwriting - text.setChar(key, cursor++); - } - - if (max_displayed < max) - update_cursor_limits(&display_offset, &cursor, max_displayed); - - cursor -= display_offset; - - PUT_SEL32V(_s->_segMan, eventObject, claimed, 1); - } - - PUT_SEL32V(_s->_segMan, controlObject, cursor, cursor); // Write back cursor position - _s->_segMan->strcpy(text_pos, text.c_str()); // Write back string - } - if (eventObject.segment) PUT_SEL32V(_s->_segMan, eventObject, claimed, 1); - _k_GenericDrawControl(_s, controlObject, false); - return; - - case K_CONTROL_ICON: - case K_CONTROL_BOX: - case K_CONTROL_BUTTON: - return; - - case K_CONTROL_TEXT: { - int state = GET_SEL32V(_s->_segMan, controlObject, state); - PUT_SEL32V(_s->_segMan, controlObject, state, state | kControlStateDitherFramed); - _k_GenericDrawControl(_s, controlObject, false); - PUT_SEL32V(_s->_segMan, controlObject, state, state); - } - break; - - default: - warning("Attempt to edit control type %d", ct_type); - } -} - -static gfx_color_t graph_map_color(EngineState *s, int color, int priority, int control) { - gfx_color_t retval; - - if (!s->resMan->isVGA()) { - retval = s->ega_colors[(color >=0 && color < 16)? color : 0]; - gfxop_set_color(s->gfx_state, &retval, (color < 0) ? -1 : retval.visual.r, retval.visual.g, retval.visual.b, - (color == -1) ? 255 : 0, priority, control); - } else { - retval.visual = get_pic_color(s, color); - retval.alpha = 0; - retval.priority = priority; - retval.control = control; - retval.mask = GFX_MASK_VISUAL | ((priority >= 0) ? GFX_MASK_PRIORITY : 0) | ((control >= 0) ? GFX_MASK_CONTROL : 0); - }; - - return retval; -} - -void _k_graph_rebuild_port_with_color(EngineState *s, gfx_color_t newbgcolor) { - GfxPort *port = s->port; - GfxPort *newport; - - newport = sciw_new_window(s, port->zone, port->_font, port->_color, newbgcolor, - s->titlebar_port->_font, s->ega_colors[15], s->ega_colors[8], - port->_title_text.c_str(), port->port_flags & ~kWindowTransparent); - - if (s->dyn_views) { - int found = 0; - GfxContainer *parent = s->dyn_views->_parent; - - while (parent && !(found |= (parent == port))) - parent = parent->_parent; - - s->dyn_views = NULL; - } - - port->_parent->add((GfxContainer *)port->_parent, newport); - delete port; -} - -void SciGui32::graphFillBoxForeground(Common::Rect rect) { - _k_graph_rebuild_port_with_color(_s, _s->port->_color); - //port = _s->port; - - FULL_REDRAW(); -} - -void SciGui32::graphFillBoxBackground(Common::Rect rect) { - _k_graph_rebuild_port_with_color(_s, _s->port->_bgcolor); - //port = _s->port; - - FULL_REDRAW(); -} - -void SciGui32::graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control) { - gfx_color_t fillColor = graph_map_color(_s, color, priority, control); - fillColor.mask = (byte)colorMask; - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - - //debugC(2, kDebugLevelGraphics, "fill_box_any((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n", - // argv[2].toSint16(), argv[1].toSint16(), argv[4].toSint16(), argv[3].toSint16(), argv[6].toSint16(), priority, control, argv[5].toUint16()); - - // FIXME/TODO: this is not right, as some of the dialogs are drawn *behind* some widgets. But at least it works for now - //ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(_s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT)); // old code - - // FillBox seems to be meant again _s->port instead of _s->picture_port, at least in QfG3 -// warning("Fillbox"); -// ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(_s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT)); - _s->picture_port->add((GfxContainer *)_s->picture_port, gfxw_new_box(_s->gfx_state, area, fillColor, fillColor, GFX_BOX_SHADE_FLAT)); -} - -void SciGui32::graphDrawLine(Common::Point startPoint, Common::Point endPoint, int16 color, int16 priority, int16 control) { - gfx_color_t gfxcolor = graph_map_color(_s, color, priority, control); - - debugC(2, kDebugLevelGraphics, "draw_line((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n", - startPoint.x, startPoint.y, endPoint.x, endPoint.y, color, priority, control, gfxcolor.mask); - - ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_line(startPoint, endPoint, - gfxcolor, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL)); - FULL_REDRAW(); -} - -reg_t SciGui32::graphSaveBox(Common::Rect rect, uint16 screenMask) { - rect_t area; - area.x = rect.left + _s->port->zone.x + port_origin_x; - area.y = rect.top + _s->port->zone.y + port_origin_y; - area.width = rect.width() - port_origin_x; - area.height = rect.height() - port_origin_y; - - return graph_save_box(_s, area); -} - -reg_t SciGui32::graphSaveUpscaledHiresBox(Common::Rect rect) { - // STUB - return NULL_REG; -} - -void SciGui32::graphRestoreBox(reg_t handle) { - graph_restore_box(_s, handle); -} - -void SciGui32::graphUpdateBox(Common::Rect rect) { - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - - area.x += _s->port->zone.x; - area.y += _s->port->zone.y; - - gfxop_update_box(_s->gfx_state, area); -} - -void SciGui32::graphRedrawBox(Common::Rect rect) { - rect_t area = gfx_rect(rect.left, rect.top, rect.width(), rect.height()); - - area.x += _s->port->zone.x; - area.y += _s->port->zone.y; - - if (_s->dyn_views && _s->dyn_views->_parent == (GfxContainer *)_s->port) - _s->dyn_views->draw(Common::Point(0, 0)); - - gfxop_update_box(_s->gfx_state, area); -} - -int16 SciGui32::picNotValid(int16 newPicNotValid) { - int16 oldPicNotValid = _s->pic_not_valid; - - if (newPicNotValid != -1) - _s->pic_not_valid = newPicNotValid; - - return oldPicNotValid; -} - -void SciGui32::paletteSet(GuiResourceId resourceNo, uint16 flags) { - //warning("STUB"); -} - -void SciGui32::paletteSetFlag(uint16 fromColor, uint16 toColor, uint16 flag) { -} - -void SciGui32::paletteUnsetFlag(uint16 fromColor, uint16 toColor, uint16 flag) { -} - -int16 SciGui32::paletteFind(uint16 r, uint16 g, uint16 b) { - int i, delta, bestindex = -1, bestdelta = 200000; - - for (i = 0; i < _s->gfx_state->gfxResMan->getColorCount(); i++) { - int dr = abs(_s->gfx_state->gfxResMan->getColor(i).r - r); - int dg = abs(_s->gfx_state->gfxResMan->getColor(i).g - g); - int db = abs(_s->gfx_state->gfxResMan->getColor(i).b - b); - - delta = dr * dr + dg * dg + db * db; - - if (delta < bestdelta) { - bestdelta = delta; - bestindex = i; - } - } - // Don't warn about inexact mappings -- it's actually the - // rule rather than the exception - return bestindex; -} - -void SciGui32::paletteSetIntensity(uint16 fromColor, uint16 toColor, uint16 intensity) { -#if 0 - _s->gfx_state->gfxResMan->setPaletteIntensity(fromColor, toColor, intensity); -#endif -} - -bool SciGui32::paletteAnimate(uint16 fromColor, uint16 toColor, uint16 speed) { - //warning("STUB"); - return false; -} - -void SciGui32::paletteAnimateSet() { -} - -#define SHAKE_DOWN 1 -#define SHAKE_RIGHT 2 - -void SciGui32::shakeScreen(uint16 shakeCount, uint16 directions) { - gfx_pixmap_t *screen = gfxop_grab_pixmap(_s->gfx_state, gfx_rect(0, 0, 320, 200)); - int i; - - if (directions & ~3) - debugC(2, kDebugLevelGraphics, "ShakeScreen(): Direction bits are %x (unknown)\n", directions); - - gfxop_set_clip_zone(_s->gfx_state, gfx_rect_fullscreen); - - for (i = 0; i < shakeCount; i++) { - int shake_down = (directions & SHAKE_DOWN) ? 10 : 0; - int shake_right = (directions & SHAKE_RIGHT) ? 10 : 0; - - if (directions & SHAKE_DOWN) - gfxop_draw_box(_s->gfx_state, gfx_rect(0, 0, 320, 10), _s->ega_colors[0], _s->ega_colors[0], GFX_BOX_SHADE_FLAT); - - if (directions & SHAKE_RIGHT) - gfxop_draw_box(_s->gfx_state, gfx_rect(0, 0, 10, 200), _s->ega_colors[0], _s->ega_colors[0], GFX_BOX_SHADE_FLAT); - - gfxop_draw_pixmap(_s->gfx_state, screen, gfx_rect(0, 0, 320 - shake_right, 200 - shake_down), - Common::Point(shake_right, shake_down)); - - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, 50); - - gfxop_draw_pixmap(_s->gfx_state, screen, gfx_rect(0, 0, 320, 200), Common::Point(0, 0)); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, 50); - } - - gfx_free_pixmap(screen); - gfxop_update(_s->gfx_state); -} - -uint16 SciGui32::onControl(byte screenMask, Common::Rect rect) { - gfx_map_mask_t map = (gfx_map_mask_t)screenMask; - rect_t gfxrect = gfx_rect(rect.left, rect.top + 10, rect.width(), rect.height()); - - return gfxop_scan_bitmask(_s->gfx_state, gfxrect, map); -// old code, just for reference -// int xstart, ystart; -// int xlen = 1, ylen = 1; -// -// if (argc == 2 || argc == 4) -// map = GFX_MASK_CONTROL; -// else { -// arg = 1; -// map = (gfx_map_mask_t) argv[0].toSint16(); -// } -// -// ystart = argv[arg + 1].toSint16(); -// xstart = argv[arg].toSint16(); -// -// if (argc > 3) { -// ylen = argv[arg + 3].toSint16() - ystart; -// xlen = argv[arg + 2].toSint16() - xstart; -// } -// -// return make_reg(0, gfxop_scan_bitmask(_s->gfx_state, gfx_rect(xstart, ystart + 10, xlen, ylen), map)); -} - -enum { - _K_MAKE_VIEW_LIST_CYCLE = 1, - _K_MAKE_VIEW_LIST_CALC_PRIORITY = 2, - _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP = 4 -}; - -GfxDynView *SciGui32::_k_make_dynview_obj(reg_t obj, int options, int nr, int argc, reg_t *argv) { - short oldloop, oldcel; - int cel, loop, view_nr = (int16)GET_SEL32V(_s->_segMan, obj, view); - int palette; - int signal; - reg_t under_bits; - Common::Point pos; - int z; - GfxDynView *widget; - - debugC(2, kDebugLevelGraphics, " - Adding %04x:%04x\n", PRINT_REG(obj)); - - obj = obj; - - pos.x = (int16)GET_SEL32V(_s->_segMan, obj, x); - pos.y = (int16)GET_SEL32V(_s->_segMan, obj, y); - - pos.y++; // magic: Sierra appears to do something like this - - z = (int16)GET_SEL32V(_s->_segMan, obj, z); - - // !-- nsRect used to be checked here! - loop = oldloop = sign_extend_byte(GET_SEL32V(_s->_segMan, obj, loop)); - cel = oldcel = sign_extend_byte(GET_SEL32V(_s->_segMan, obj, cel)); - - if (_s->_kernel->_selectorCache.palette) - palette = GET_SEL32V(_s->_segMan, obj, palette); - else - palette = 0; - - // Clip loop and cel, write back if neccessary - _s->gfx_state->gfxResMan->getView(view_nr, &loop, &cel, 0); - - if (loop != oldloop) - loop = 0; - if (cel != oldcel) - cel = 0; - - if (oldloop != loop) - PUT_SEL32V(_s->_segMan, obj, loop, loop); - - if (oldcel != cel) { - PUT_SEL32V(_s->_segMan, obj, cel, cel); - } - - ObjVarRef under_bitsp; - if (lookup_selector(_s->_segMan, obj, _s->_kernel->_selectorCache.underBits, &(under_bitsp), NULL) != kSelectorVariable) { - under_bitsp.obj = NULL_REG; - under_bits = NULL_REG; - debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no underBits\n", PRINT_REG(obj)); - } else - under_bits = *under_bitsp.getPointer(_s->_segMan); - - ObjVarRef signalp; - if (lookup_selector(_s->_segMan, obj, _s->_kernel->_selectorCache.signal, &(signalp), NULL) != kSelectorVariable) { - signalp.obj = NULL_REG; - signal = 0; - debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no signal selector\n", PRINT_REG(obj)); - } else { - signal = signalp.getPointer(_s->_segMan)->offset; - debugC(2, kDebugLevelGraphics, " with signal = %04x\n", signal); - } - - widget = gfxw_new_dyn_view(_s->gfx_state, pos, z, view_nr, loop, cel, palette, -1, -1, ALIGN_CENTER, ALIGN_BOTTOM, nr); - - if (widget) { - widget = (GfxDynView *) gfxw_set_id(widget, obj.segment, obj.offset); - widget = gfxw_dyn_view_set_params(widget, under_bits.segment, under_bitsp, signal, signalp); - widget->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; // Only works the first time 'round' - - return widget; - } else { - warning("Could not generate dynview widget for %d/%d/%d", view_nr, loop, cel); - return NULL; - } -} - -void SciGui32::_k_make_view_list(GfxList **widget_list, List *list, int options, int argc, reg_t *argv) { -/* Creates a view_list from a node list in heap space. Returns the list, stores the -** number of list entries in *list_nr. Calls doit for each entry if cycle is set. -** argc, argv should be the same as in the calling kernel function. -*/ - EngineState *s = _s; - Node *node; - int sequence_nr = 0; - GfxDynView *widget; - - if (!*widget_list) { - error("make_view_list with widget_list == ()"); - }; - - assert_primary_widget_lists(_s); - // In case one of the views' doit() does a DrawPic... - // Yes, this _does_ happen! - - if (!list) { // list sanity check - error("Attempt to make list from non-list"); - } - - reg_t next_node = list->first; - node = _s->_segMan->lookupNode(next_node); - while (node) { - reg_t obj = node->value; // The object we're using - GfxDynView *tempWidget; - - if (options & _K_MAKE_VIEW_LIST_CYCLE) { - unsigned int signal = GET_SEL32V(_s->_segMan, obj, signal); - - if (!(signal & kSignalFrozen)) { - - debugC(2, kDebugLevelGraphics, " invoking %04x:%04x::doit()\n", PRINT_REG(obj)); - invoke_selector(INV_SEL(obj, doit, kContinueOnInvalidSelector), 0); // Call obj::doit() if neccessary - - - // Lookup node again, since the NodeTable it was in may - // have been re-allocated. - node = _s->_segMan->lookupNode(next_node); - } - } - - next_node = node->succ; // In case the cast list was changed - - if (list->first.segment == 0 && list->first.offset == 0) // The cast list was completely emptied! - break; - - tempWidget = _k_make_dynview_obj(obj, options, sequence_nr--, argc, argv); - if (tempWidget) - (*widget_list)->add((GfxContainer *)(*widget_list), tempWidget); - - node = _s->_segMan->lookupNode(next_node); // Next node - } - - widget = (GfxDynView *)(*widget_list)->_contents; - - while (widget) { // Read back widget values - reg_t *sp = widget->signalp.getPointer(_s->_segMan); - if (sp) - widget->signal = sp->offset; - - widget = (GfxDynView *)widget->_next; - } -} - -void SciGui32::draw_rect_to_control_map(Common::Rect abs_zone) { - GfxBox *box; - gfx_color_t color; - - gfxop_set_color(_s->gfx_state, &color, -1, -1, -1, -1, -1, 0xf); - - debugC(2, kDebugLevelGraphics, " adding control block (%d,%d)to(%d,%d)\n", abs_zone.left, abs_zone.top, abs_zone.right, abs_zone.bottom); - - box = gfxw_new_box(_s->gfx_state, gfx_rect(abs_zone.left, abs_zone.top, abs_zone.width(), - abs_zone.height()), color, color, GFX_BOX_SHADE_FLAT); - - assert_primary_widget_lists(_s); - - ADD_TO_CURRENT_PICTURE_PORT(box); -} - -void SciGui32::draw_obj_to_control_map(GfxDynView *view) { - reg_t obj = make_reg(view->_ID, view->_subID); - - if (!_s->_segMan->isObject(obj)) - warning("View %d does not contain valid object reference %04x:%04x", view->_ID, PRINT_REG(obj)); - - reg_t* sp = view->signalp.getPointer(_s->_segMan); - if (!(sp && (sp->offset & kSignalIgnoreActor))) { - Common::Rect abs_zone = get_nsrect32(_s, make_reg(view->_ID, view->_subID), 1); - draw_rect_to_control_map(abs_zone); - } -} - -int SciGui32::_k_view_list_dispose_loop(List *list, GfxDynView *widget, int argc, reg_t *argv) { -// disposes all list members flagged for disposal -// returns non-zero IFF views were dropped - int signal; - int dropped = 0; - EngineState *s = _s; - - _k_animate_ran = false; - - if (widget) { - int retval; - // Recurse: - retval = _k_view_list_dispose_loop(list, (GfxDynView *)widget->_next, argc, argv); - - if (retval == -1) // Bail out on annihilation, rely on re-start from Animate() - return -1; - - if (GFXW_IS_DYN_VIEW(widget) && (widget->_ID != GFXW_NO_ID)) { - signal = widget->signalp.getPointer(_s->_segMan)->offset; - if (signal & kSignalDisposeMe) { - reg_t obj = make_reg(widget->_ID, widget->_subID); - reg_t under_bits = NULL_REG; - - if (!_s->_segMan->isObject(obj)) { - error("Non-object %04x:%04x present in view list during delete time", PRINT_REG(obj)); - obj = NULL_REG; - } else { - reg_t *ubp = widget->under_bitsp.getPointer(_s->_segMan); - if (ubp) { // Is there a bg picture left to clean? - reg_t mem_handle = *ubp; - - if (mem_handle.segment) { - if (!kfree(_s->_segMan, mem_handle)) { - *ubp = make_reg(0, widget->under_bits = 0); - } else { - warning("Treating viewobj %04x:%04x as no longer present", PRINT_REG(obj)); - obj = NULL_REG; - } - } - } - } - if (_s->_segMan->isObject(obj)) { - if (invoke_selector(INV_SEL(obj, delete_, kContinueOnInvalidSelector), 0)) - warning("Object at %04x:%04x requested deletion, but does not have a delete funcselector", PRINT_REG(obj)); - if (_k_animate_ran) { - warning("Object at %04x:%04x invoked kAnimate() during deletion", PRINT_REG(obj)); - return dropped; - } - - reg_t *ubp = widget->under_bitsp.getPointer(_s->_segMan); - if (ubp) - under_bits = *ubp; - - if (under_bits.segment) { - *ubp = make_reg(0, 0); - graph_restore_box(_s, under_bits); - } - - debugC(2, kDebugLevelGraphics, "Freeing %04x:%04x with signal=%04x\n", PRINT_REG(obj), signal); - - if (!(signal & kSignalHidden)) { - debugC(2, kDebugLevelGraphics, "Adding view at %04x:%04x to background\n", PRINT_REG(obj)); - if (!(gfxw_remove_id(widget->_parent, widget->_ID, widget->_subID) == widget)) { - error("Attempt to remove view with ID %x:%x from list failed", widget->_ID, widget->_subID); - } - - s->drop_views->add((GfxContainer *)s->drop_views, gfxw_picviewize_dynview(widget)); - - draw_obj_to_control_map(widget); - widget->draw_bounds.y += s->dyn_views->_bounds.y - widget->_parent->_bounds.y; - widget->draw_bounds.x += s->dyn_views->_bounds.x - widget->_parent->_bounds.x; - dropped = 1; - } else { - debugC(2, kDebugLevelGraphics, "Deleting view at %04x:%04x\n", PRINT_REG(obj)); - widget->_flags |= GFXW_FLAG_VISIBLE; - gfxw_annihilate(widget); - return -1; // restart: Done in Animate() - } - } - } - } - - } - - return dropped; -} - -void SciGui32::_k_set_now_seen(reg_t object) { - Common::Rect absrect = get_nsrect32(_s, object, 0); - - if (lookup_selector(_s->_segMan, object, _s->_kernel->_selectorCache.nsTop, NULL, NULL) != kSelectorVariable) { - return; - } // This isn't fatal - - PUT_SEL32V(_s->_segMan, object, nsLeft, absrect.left); - PUT_SEL32V(_s->_segMan, object, nsRight, absrect.right); - PUT_SEL32V(_s->_segMan, object, nsTop, absrect.top); - PUT_SEL32V(_s->_segMan, object, nsBottom, absrect.bottom); -} - -void SciGui32::_k_prepare_view_list(GfxList *list, int options) { - GfxDynView *view = (GfxDynView *) list->_contents; - while (view) { - reg_t obj = make_reg(view->_ID, view->_subID); - int priority, _priority; - int has_nsrect = (view->_ID <= 0) ? 0 : lookup_selector(_s->_segMan, obj, _s->_kernel->_selectorCache.nsBottom, NULL, NULL) == kSelectorVariable; - int oldsignal = view->signal; - - _k_set_now_seen(obj); - _priority = /*GET_SELECTOR(obj, y); */((view->_pos.y)); - _priority = _find_view_priority(_s, _priority - 1); - - if (options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP) { // Picview - priority = (int16)GET_SEL32V(_s->_segMan, obj, priority); - if (priority < 0) - priority = _priority; // Always for picviews - } else { // Dynview - if (has_nsrect && !(view->signal & kSignalFixedPriority)) { // Calculate priority - if (options & _K_MAKE_VIEW_LIST_CALC_PRIORITY) - PUT_SEL32V(_s->_segMan, obj, priority, _priority); - - priority = _priority; - - } else // DON'T calculate the priority - priority = (int16)GET_SEL32V(_s->_segMan, obj, priority); - } - - view->_color.priority = priority; - - if (priority > -1) - view->_color.mask |= GFX_MASK_PRIORITY; - else - view->_color.mask &= ~GFX_MASK_PRIORITY; - - // CR (from :Bob Heitman:) stopupdated views (like pic views) have - // their clipped nsRect drawn to the control map - if (view->signal & kSignalStopUpdate) { - view->signal |= kSignalStopUpdHack; - debugC(2, kDebugLevelGraphics, "Setting magic STOP_UPD for %04x:%04x\n", PRINT_REG(obj)); - } - - if ((options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP)) - draw_obj_to_control_map(view); - - // Extreme Pattern Matching ugliness ahead... - if (view->signal & kSignalNoUpdate) { - if (((view->signal & (kSignalViewUpdated | kSignalForceUpdate))) // 9.1.1.1 - || ((view->signal & (kSignalHidden | kSignalRemoveView)) == kSignalHidden) - || ((view->signal & (kSignalHidden | kSignalRemoveView)) == kSignalRemoveView) // 9.1.1.2 - || ((view->signal & (kSignalHidden | kSignalRemoveView | kSignalAlwaysUpdate)) == kSignalAlwaysUpdate) // 9.1.1.3 - || ((view->signal & (kSignalHidden | kSignalAlwaysUpdate)) == (kSignalHidden | kSignalAlwaysUpdate))) { // 9.1.1.4 - _s->pic_not_valid++; - view->signal &= ~kSignalStopUpdate; - } - - else if (((view->signal & (kSignalHidden | kSignalRemoveView | kSignalAlwaysUpdate)) == 0) - || ((view->signal & (kSignalHidden | kSignalRemoveView | kSignalAlwaysUpdate)) == (kSignalHidden | kSignalRemoveView)) - || ((view->signal & (kSignalHidden | kSignalAlwaysUpdate)) == (kSignalHidden | kSignalAlwaysUpdate)) - || ((view->signal & (kSignalHidden | kSignalAlwaysUpdate)) == kSignalHidden)) { - view->signal &= ~kSignalStopUpdate; - } - } else { - if (view->signal & kSignalStopUpdate) { - _s->pic_not_valid++; - view->signal &= ~kSignalForceUpdate; - } else { // if not STOP_UPDATE - if (view->signal & kSignalAlwaysUpdate) - _s->pic_not_valid++; - view->signal &= ~kSignalForceUpdate; - } - } - - debugC(2, kDebugLevelGraphics, " dv[%04x:%04x]: signal %04x -> %04x\n", PRINT_REG(obj), oldsignal, view->signal); - - // Never happens -/* if (view->signal & 0) { - view->signal &= ~kSignalStopUpdHack; - fprintf(_stderr, "Unsetting magic StopUpd for view %04x:%04x\n", PRINT_REG(obj)); - } */ - - view = (GfxDynView *)view->_next; - } -} - -void SciGui32::_k_update_signals_in_view_list(GfxList *old_list, GfxList *new_list) { - // O(n^2)... a bit painful, but much faster than the redraws it helps prevent - GfxDynView *old_widget = (GfxDynView *)old_list->_contents; - - /* Traverses all old widgets, updates them with signals from the new widgets. - ** This is done to avoid evil hacks in widget.c; widgets with unique IDs are - ** replaced there iff they are NOT equal_to a new widget with the same ID. - ** If they were replaced every time, we'd be doing far too many redraws. - */ - - while (old_widget) { - GfxDynView *new_widget = (GfxDynView *) new_list->_contents; - - while (new_widget - && (new_widget->_ID != old_widget->_ID - || new_widget->_subID != old_widget->_subID)) - new_widget = (GfxDynView *)new_widget->_next; - - if (new_widget) { - int carry = old_widget->signal & kSignalStopUpdHack; - // Transfer 'stopupd' flag - - if ((new_widget->_pos.x != old_widget->_pos.x) - || (new_widget->_pos.y != old_widget->_pos.y) - // No idea why this is supposed to be bad -/* || (new_widget->z != old_widget->z) - || (new_widget->view != old_widget->view) - || (new_widget->loop != old_widget->loop) - || (new_widget->cel != old_widget->cel) - */) - carry = 0; - - old_widget->signal = new_widget->signal |= carry; - } - - old_widget = (GfxDynView *)old_widget->_next; - } -} - -void SciGui32::_k_view_list_kryptonize(GfxWidget *v) { - if (v) { - v->_flags &= ~GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - _k_view_list_kryptonize(v->_next); - } -} - -void SciGui32::_k_raise_topmost_in_view_list(GfxList *list, GfxDynView *view) { - if (view) { - GfxDynView *next = (GfxDynView *)view->_next; - - // step 11 - if ((view->signal & (kSignalNoUpdate | kSignalHidden | kSignalAlwaysUpdate)) == 0) { - debugC(2, kDebugLevelGraphics, "Forcing precedence 2 at [%04x:%04x] with %04x\n", PRINT_REG(make_reg(view->_ID, view->_subID)), view->signal); - view->force_precedence = 2; - - if ((view->signal & (kSignalRemoveView | kSignalHidden)) == kSignalRemoveView) { - view->signal &= ~kSignalRemoveView; - } - } - - gfxw_remove_widget_from_container(view->_parent, view); - - if (view->signal & kSignalHidden) - gfxw_hide_widget(view); - else - gfxw_show_widget(view); - - list->add((GfxContainer *)list, view); - - _k_raise_topmost_in_view_list(list, next); - } -} - -void SciGui32::_k_redraw_view_list(GfxList *list) { - GfxDynView *view = (GfxDynView *) list->_contents; - while (view) { - - debugC(2, kDebugLevelGraphics, " dv[%04x:%04x]: signal %04x\n", PRINT_REG(make_reg(view->_ID, view->_subID)), view->signal); - - // step 1 of subalgorithm - if (view->signal & kSignalNoUpdate) { - if (view->signal & kSignalForceUpdate) - view->signal &= ~kSignalForceUpdate; - - if (view->signal & kSignalViewUpdated) - view->signal &= ~(kSignalViewUpdated | kSignalNoUpdate); - } else { // NO_UPD is not set - if (view->signal & kSignalStopUpdate) { - view->signal &= ~kSignalStopUpdate; - view->signal |= kSignalNoUpdate; - } - } - - debugC(2, kDebugLevelGraphics, " at substep 6: signal %04x\n", view->signal); - - if (view->signal & kSignalAlwaysUpdate) - view->signal &= ~(kSignalStopUpdate | kSignalViewUpdated | kSignalNoUpdate | kSignalForceUpdate); - - debugC(2, kDebugLevelGraphics, " at substep 11/14: signal %04x\n", view->signal); - - if (view->signal & kSignalNoUpdate) { - if (view->signal & kSignalHidden) - view->signal |= kSignalRemoveView; - else - view->signal &= ~kSignalRemoveView; - } else if (!(view->signal & kSignalHidden)) - view->force_precedence = 1; - - debugC(2, kDebugLevelGraphics, " -> signal %04x\n", view->signal); - - view = (GfxDynView *)view->_next; - } -} - -// Flags for _k_draw_view_list -// Whether some magic with the base object's "signal" selector should be done: -#define _K_DRAW_VIEW_LIST_USE_SIGNAL 1 -// This flag draws all views with the "DISPOSE_ME" flag set: -#define _K_DRAW_VIEW_LIST_DISPOSEABLE 2 -// Use this one to draw all views with "DISPOSE_ME" NOT set: -#define _K_DRAW_VIEW_LIST_NONDISPOSEABLE 4 -// Draw as picviews -#define _K_DRAW_VIEW_LIST_PICVIEW 8 - -void SciGui32::_k_draw_view_list(GfxList *list, int flags) { - // Draws list_nr members of list to s->pic. - GfxDynView *widget = (GfxDynView *) list->_contents; - - if ((GfxContainer *)_s->port != (GfxContainer *)_s->dyn_views->_parent) - return; // Return if the pictures are meant for a different port - - while (widget) { - if (flags & _K_DRAW_VIEW_LIST_PICVIEW) - widget = gfxw_picviewize_dynview(widget); - - if (GFXW_IS_DYN_VIEW(widget) && widget->_ID) { - uint16 signal = (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) ? widget->signalp.getPointer(_s->_segMan)->offset : 0; - - if (signal & kSignalHidden) - gfxw_hide_widget(widget); - else - gfxw_show_widget(widget); - - if (!(flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) - || ((flags & _K_DRAW_VIEW_LIST_DISPOSEABLE) && (signal & kSignalDisposeMe)) - || ((flags & _K_DRAW_VIEW_LIST_NONDISPOSEABLE) && !(signal & kSignalDisposeMe))) { - - if (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) { - signal &= ~(kSignalStopUpdate | kSignalViewUpdated | kSignalNoUpdate | kSignalForceUpdate); - // Clear all of those flags - - if (signal & kSignalHidden) - gfxw_hide_widget(widget); - else - gfxw_show_widget(widget); - - *widget->signalp.getPointer(_s->_segMan) = make_reg(0, signal); // Write the changes back - }; - - } // ...if we're drawing disposeables and this one is disposeable, or if we're drawing non- - // disposeables and this one isn't disposeable - } - - widget = (GfxDynView *)widget->_next; - } // while (widget) -} - -void SciGui32::_k_view_list_do_postdraw(GfxList *list) { - GfxDynView *widget = (GfxDynView *) list->_contents; - - while (widget) { - reg_t obj = make_reg(widget->_ID, widget->_subID); - - /* - * this fixes a few problems, but doesn't match SSCI's logic. - * The semantics of the private flag need to be verified before this can be uncommented. - * Fixes bug #326 (CB1, ego falls down stairs) - * if ((widget->signal & (_K_VIEW_SIG_FLAG_PRIVATE | kSignalRemoveView | kSignalNoUpdate)) == _K_VIEW_SIG_FLAG_PRIVATE) { - */ - if ((widget->signal & (kSignalRemoveView | kSignalNoUpdate)) == 0) { - int has_nsrect = lookup_selector(_s->_segMan, obj, _s->_kernel->_selectorCache.nsBottom, NULL, NULL) == kSelectorVariable; - - if (has_nsrect) { - int temp; - - temp = GET_SEL32V(_s->_segMan, obj, nsLeft); - PUT_SEL32V(_s->_segMan, obj, lsLeft, temp); - - temp = GET_SEL32V(_s->_segMan, obj, nsRight); - PUT_SEL32V(_s->_segMan, obj, lsRight, temp); - - temp = GET_SEL32V(_s->_segMan, obj, nsTop); - PUT_SEL32V(_s->_segMan, obj, lsTop, temp); - - temp = GET_SEL32V(_s->_segMan, obj, nsBottom); - PUT_SEL32V(_s->_segMan, obj, lsBottom, temp); -#ifdef DEBUG_LSRECT - fprintf(_stderr, "lsRected %04x:%04x\n", PRINT_REG(obj)); -#endif - } -#ifdef DEBUG_LSRECT - else - fprintf(_stderr, "Not lsRecting %04x:%04x because %d\n", PRINT_REG(obj), lookup_selector(_s->_segMan, obj, _s->_kernel->_selectorCache.nsBottom, NULL, NULL)); -#endif - - if (widget->signal & kSignalHidden) - widget->signal |= kSignalRemoveView; - } -#ifdef DEBUG_LSRECT - fprintf(_stderr, "obj %04x:%04x has pflags %x\n", PRINT_REG(obj), (widget->signal & (kSignalRemoveView | kSignalNoUpdate))); -#endif - - reg_t* sp = widget->signalp.getPointer(_s->_segMan); - if (sp) { - *sp = make_reg(0, widget->signal & 0xffff); /* Write back signal */ - } - - widget = (GfxDynView *)widget->_next; - } -} - -#define K_ANIMATE_CENTER_OPEN_H 0 // horizontally open from center -#define K_ANIMATE_CENTER_OPEN_V 1 // vertically open from center -#define K_ANIMATE_RIGHT_OPEN 2 // open from right -#define K_ANIMATE_LEFT_OPEN 3 // open from left -#define K_ANIMATE_BOTTOM_OPEN 4 // open from bottom -#define K_ANIMATE_TOP_OPEN 5 // open from top -#define K_ANIMATE_BORDER_OPEN_F 6 // open from edges to center -#define K_ANIMATE_CENTER_OPEN_F 7 // open from center to edges -#define K_ANIMATE_OPEN_CHECKERS 8 // open random checkboard -#define K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H 9 // horizontally close to center,reopen from center -#define K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V 10 // vertically close to center, reopen from center -#define K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN 11 // close to right, reopen from right -#define K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN 12 // close to left, reopen from left -#define K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN 13 // close to bottom, reopen from bottom -#define K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN 14 // close to top, reopen from top -#define K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F 15 // close from center to edges, -// reopen from edges to center -#define K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F 16 // close from edges to center, reopen from -// center to edges */ -#define K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS 17 // close random checkboard, reopen -#define K_ANIMATE_PALETTE_FADEOUT_FADEIN 0x1e -#define K_ANIMATE_SCROLL_LEFT 0x28 -#define K_ANIMATE_SCROLL_RIGHT 0x29 -#define K_ANIMATE_SCROLL_DOWN 0x2a -#define K_ANIMATE_SCROLL_UP 0x2b - -#define GRAPH_BLANK_BOX(_s, x, y, xl, yl, color) gfxop_fill_box(_s->gfx_state, \ - gfx_rect(x, (((y) < 10)? 10 : (y)), xl, (((y) < 10)? ((y) - 10) : 0) + (yl)), _s->ega_colors[color]); - -#define GRAPH_UPDATE_BOX(_s, x, y, xl, yl) gfxop_draw_pixmap(_s->gfx_state, newscreen, \ - gfx_rect(x, (((y) < 10)? 10 : (y)) - 10, xl, (((y) < 10)? ((y) - 10) : 0) + (yl)), Common::Point(x, ((y) < 10)? 10 : (y) )); - -void SciGui32::animate_do_animation(int argc, reg_t *argv) { - long animation_delay = 5; - int i, remaining_checkers; - int update_counter; - // Number of animation steps to perform betwen updates for transition animations - int animation_granularity = 4; - int granularity0 = animation_granularity << 1; - int granularity1 = animation_granularity; - int granularity2 = animation_granularity >> 2; - int granularity3 = animation_granularity >> 4; - char checkers[32 * 19]; - gfx_pixmap_t *newscreen = gfxop_grab_pixmap(_s->gfx_state, gfx_rect(0, 10, 320, 190)); - - if (!granularity2) - granularity2 = 1; - if (!granularity3) - granularity3 = 1; - - gfxop_set_clip_zone(_s->gfx_state, gfx_rect_fullscreen); - - if (!newscreen) { - error("Failed to allocate 'newscreen'"); - return; - } - - gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(0, 0, 320, 190), Common::Point(0, 10)); - gfxop_update_box(_s->gfx_state, gfx_rect(0, 0, 320, 200)); - - //debugC(2, kDebugLevelGraphics, "Animating pic opening type %x\n", _s->pic_animate); - - gfxop_enable_dirty_frames(_s->gfx_state); - - switch (_s->pic_animate) { - case K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H : - for (i = 0; i < 159 + granularity1; i += granularity1) { - GRAPH_BLANK_BOX(_s, i, 10, granularity1, 190, 0); - gfxop_update(_s->gfx_state); - GRAPH_BLANK_BOX(_s, 319 - i, 10, granularity1, 190, 0); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0); - - case K_ANIMATE_CENTER_OPEN_H : - - for (i = 159; i >= 1 - granularity1; i -= granularity1) { - GRAPH_UPDATE_BOX(_s, i, 10, granularity1, 190); - gfxop_update(_s->gfx_state); - GRAPH_UPDATE_BOX(_s, 319 - i, 10, granularity1, 190); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - - case K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V : - - for (i = 0; i < 94 + granularity2; i += granularity2) { - GRAPH_BLANK_BOX(_s, 0, i + 10, 320, granularity2, 0); - gfxop_update(_s->gfx_state); - GRAPH_BLANK_BOX(_s, 0, 199 - i, 320, granularity2, 0); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, 2 * animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0); - - case K_ANIMATE_CENTER_OPEN_V : - - for (i = 94; i >= 1 - granularity2; i -= granularity2) { - GRAPH_UPDATE_BOX(_s, 0, i + 10, 320, granularity2); - gfxop_update(_s->gfx_state); - GRAPH_UPDATE_BOX(_s, 0, 199 - i, 320, granularity2); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, 2 * animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - - case K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN : - - for (i = 0; i < 319 + granularity0; i += granularity0) { - GRAPH_BLANK_BOX(_s, i, 10, granularity0, 190, 0); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 2 / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0); - - case K_ANIMATE_RIGHT_OPEN : - for (i = 319; i >= 1 - granularity0; i -= granularity0) { - GRAPH_UPDATE_BOX(_s, i, 10, granularity0, 190); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 2 / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - - case K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN : - - for (i = 319; i >= 1 - granularity0; i -= granularity0) { - GRAPH_BLANK_BOX(_s, i, 10, granularity0, 190, 0); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 2 / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0); - - case K_ANIMATE_LEFT_OPEN : - - for (i = 0; i < 319 + granularity0; i += granularity0) { - GRAPH_UPDATE_BOX(_s, i, 10, granularity0, 190); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 2 / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - - case K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN : - - for (i = 10; i < 199 + granularity1; i += granularity1) { - GRAPH_BLANK_BOX(_s, 0, i, 320, granularity1, 0); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0); - - case K_ANIMATE_BOTTOM_OPEN : - - for (i = 199; i >= 11 - granularity1; i -= granularity1) { - GRAPH_UPDATE_BOX(_s, 0, i, 320, granularity1); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - - case K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN : - - for (i = 199; i >= 11 - granularity1; i -= granularity1) { - GRAPH_BLANK_BOX(_s, 0, i, 320, granularity1, 0); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - GRAPH_BLANK_BOX(_s, 0, 10, 320, 190, 0); - - case K_ANIMATE_TOP_OPEN : - - for (i = 10; i < 199 + granularity1; i += granularity1) { - GRAPH_UPDATE_BOX(_s, 0, i, 320, granularity1); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - - case K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F : - - for (i = 31; i >= 1 - granularity3; i -= granularity3) { - int real_i = (i < 0) ? 0 : i; - int height_l = 3 * (granularity3 - real_i + i); - int width_l = 5 * (granularity3 - real_i + i); - int height = real_i * 3; - int width = real_i * 5; - - GRAPH_BLANK_BOX(_s, width, 10 + height, width_l, 190 - 2 * height, 0); - gfxop_update(_s->gfx_state); - GRAPH_BLANK_BOX(_s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height, 0); - gfxop_update(_s->gfx_state); - - GRAPH_BLANK_BOX(_s, width, 10 + height, 320 - 2 * width, height_l, 0); - gfxop_update(_s->gfx_state); - GRAPH_BLANK_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0); - gfxop_update(_s->gfx_state); - - kernel_sleep(_s->_event, 4 * animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - - case K_ANIMATE_BORDER_OPEN_F : - - for (i = 0; i < 31 + granularity3; i += granularity3) { - int real_i = (i < 0) ? 0 : i; - int height_l = 3 * (granularity3 - real_i + i); - int width_l = 5 * (granularity3 - real_i + i); - int height = real_i * 3; - int width = real_i * 5; - - GRAPH_UPDATE_BOX(_s, width, 10 + height, width_l, 190 - 2 * height); - gfxop_update(_s->gfx_state); - GRAPH_UPDATE_BOX(_s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height); - gfxop_update(_s->gfx_state); - - GRAPH_UPDATE_BOX(_s, width, 10 + height, 320 - 2 * width, height_l); - gfxop_update(_s->gfx_state); - GRAPH_UPDATE_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l); - gfxop_update(_s->gfx_state); - - kernel_sleep(_s->_event, 4 * animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - - break; - - case K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F : - - for (i = 0; i < 31 + granularity3; i += granularity3) { - int real_i = (i < 0) ? 0 : i; - int height_l = 3 * (granularity3 - real_i + i); - int width_l = 5 * (granularity3 - real_i + i); - int height = real_i * 3; - int width = real_i * 5; - - GRAPH_BLANK_BOX(_s, width, 10 + height, width_l, 190 - 2 * height, 0); - gfxop_update(_s->gfx_state); - GRAPH_BLANK_BOX(_s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height, 0); - gfxop_update(_s->gfx_state); - - GRAPH_BLANK_BOX(_s, width, 10 + height, 320 - 2 * width, height_l, 0); - gfxop_update(_s->gfx_state); - GRAPH_BLANK_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0); - gfxop_update(_s->gfx_state); - - kernel_sleep(_s->_event, 7 * animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - - case K_ANIMATE_CENTER_OPEN_F : - - for (i = 31; i >= 1 - granularity3; i -= granularity3) { - int real_i = (i < 0) ? 0 : i; - int height_l = 3 * (granularity3 - real_i + i); - int width_l = 5 * (granularity3 - real_i + i); - int height = real_i * 3; - int width = real_i * 5; - - GRAPH_UPDATE_BOX(_s, width, 10 + height, width_l, 190 - 2 * height); - gfxop_update(_s->gfx_state); - GRAPH_UPDATE_BOX(_s, 320 - width_l - width, 10 + height, width_l, 190 - 2*height); - gfxop_update(_s->gfx_state); - - GRAPH_UPDATE_BOX(_s, width, 10 + height, 320 - 2 * width, height_l); - gfxop_update(_s->gfx_state); - GRAPH_UPDATE_BOX(_s, width, 200 - height_l - height, 320 - 2 * width, height_l); - gfxop_update(_s->gfx_state); - - kernel_sleep(_s->_event, 7 * animation_delay / 1000); -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - case K_ANIMATE_PALETTE_FADEOUT_FADEIN: - warning("TODO: Palette fadeout/fadein"); - GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190); - break; - - case K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS : - - memset(checkers, 0, sizeof(checkers)); - remaining_checkers = 19 * 32; - update_counter = granularity1; - - while (remaining_checkers) { - int x, y, checker = 1 + (int)(1.0 * remaining_checkers * rand() / (RAND_MAX + 1.0)); - i = -1; - - while (checker) - if (checkers[++i] == 0) - --checker; - checkers[i] = 1; // Mark checker as used - - x = i % 32; - y = i / 32; - - GRAPH_BLANK_BOX(_s, x * 10, 10 + y * 10, 10, 10, 0); - if (!(update_counter--) || (remaining_checkers == 1)) { - gfxop_update(_s->gfx_state); - update_counter = granularity1; - } - - if (remaining_checkers & 1) { - kernel_sleep(_s->_event, animation_delay / 4 / 1000); - } - - --remaining_checkers; -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - - case K_ANIMATE_OPEN_CHECKERS : - - memset(checkers, 0, sizeof(checkers)); - remaining_checkers = 19 * 32; - update_counter = granularity1; - - while (remaining_checkers) { - int x, y, checker = 1 + (int)(1.0 * remaining_checkers * rand() / (RAND_MAX + 1.0)); - i = -1; - - while (checker) - if (checkers[++i] == 0) --checker; - checkers[i] = 1; // Mark checker as used - - x = i % 32; - y = i / 32; - - GRAPH_UPDATE_BOX(_s, x * 10, 10 + y * 10, 10, 10); - - if (!(update_counter--) || (remaining_checkers == 1)) { - gfxop_update(_s->gfx_state); - update_counter = granularity1; - } - - if (remaining_checkers & 1) { - kernel_sleep(_s->_event, animation_delay / 4 / 1000); - } - - --remaining_checkers; -#ifdef USE_OLD_MUSIC_FUNCTIONS - process_sound_events(_s); -#endif - } - break; - - - case K_ANIMATE_SCROLL_LEFT : - - for (i = 0; i < 319; i += granularity0) { - gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(320 - i, 0, i, 190), Common::Point(0, 10)); - gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(0, 0, 320 - i, 190), Common::Point(i, 10)); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, (animation_delay >> 3) / 1000); - } - GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190); - break; - - case K_ANIMATE_SCROLL_RIGHT : - - for (i = 0; i < 319; i += granularity0) { - gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(0, 0, i, 190), Common::Point(319 - i, 10)); - gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(i, 0, 320 - i, 190), Common::Point(0, 10)); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, (animation_delay >> 3) / 1000); - } - GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190); - break; - - case K_ANIMATE_SCROLL_UP : - - for (i = 0; i < 189; i += granularity0) { - gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(0, 190 - i, 320, i), Common::Point(0, 10)); - gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(0, 0, 320, 190 - i), Common::Point(0, 10 + i)); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, (animation_delay >> 3) / 1000); - } - GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190); - break; - - case K_ANIMATE_SCROLL_DOWN : - - for (i = 0; i < 189; i += granularity0) { - gfxop_draw_pixmap(_s->gfx_state, newscreen, gfx_rect(0, 0, 320, i), Common::Point(0, 200 - i)); - gfxop_draw_pixmap(_s->gfx_state, _s->old_screen, gfx_rect(0, i, 320, 190 - i), Common::Point(0, 10)); - gfxop_update(_s->gfx_state); - kernel_sleep(_s->_event, (animation_delay >> 3) / 1000); - } - GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190); - break; - - default: - warning("Unknown opening animation 0x%02x", _s->pic_animate); - GRAPH_UPDATE_BOX(_s, 0, 10, 320, 190); - - } - - gfx_free_pixmap(_s->old_screen); - gfx_free_pixmap(newscreen); - _s->old_screen = NULL; -} - -void SciGui32::animate(reg_t listReference, bool cycle, int argc, reg_t *argv) { - // Animations are supposed to take a maximum of animation_delay milliseconds. - List *cast_list = NULL; - int open_animation = 0; - - _k_animate_ran = true; // Used by some of the invoked functions to check for recursion, which may, - // after all, damage the cast list - - if (listReference.segment) { - cast_list = _s->_segMan->lookupList(listReference); - if (!cast_list) - return; - } - - open_animation = (_s->pic_is_new) && (_s->pic_not_valid); - _s->pic_is_new = 0; - - assert_primary_widget_lists(_s); - - if (!_s->dyn_views->_contents // Only reparentize empty dynview list - && (((GfxContainer *)_s->port != (GfxContainer *)_s->dyn_views->_parent) // If dynviews are on other port... - || (_s->dyn_views->_next))) // ... or not on top of the view list - reparentize_primary_widget_lists(_s, _s->port); - - if (cast_list) { - GfxList *templist = gfxw_new_list(_s->dyn_views->_bounds, 0); - - _k_make_view_list(&(templist), cast_list, (cycle ? _K_MAKE_VIEW_LIST_CYCLE : 0) - | _K_MAKE_VIEW_LIST_CALC_PRIORITY, argc, (reg_t *)argv); - - // Make sure that none of the doits() did something evil - assert_primary_widget_lists(_s); - - if (!_s->dyn_views->_contents // Only reparentize empty dynview list - && (((GfxContainer *)_s->port != (GfxContainer *)_s->dyn_views->_parent) // If dynviews are on other port... - || (_s->dyn_views->_next))) // ... or not on top of the view list - reparentize_primary_widget_lists(_s, _s->port); - // End of doit() recovery code - - if (_s->pic_is_new) { // Happens if DrawPic() is executed by a dynview (yes, that happens) - animate(listReference, cycle, argc, argv); /* Tail-recurse */ - return; - } - - debugC(2, kDebugLevelGraphics, "Handling Dynviews (..step 9 inclusive):\n"); - _k_prepare_view_list(templist, _K_MAKE_VIEW_LIST_CALC_PRIORITY); - - if (_s->pic_not_valid) { - debugC(2, kDebugLevelGraphics, "PicNotValid=%d -> Subalgorithm:\n", _s->pic_not_valid); - _k_redraw_view_list(templist); - } - - _k_update_signals_in_view_list(_s->dyn_views, templist); - _s->dyn_views->tag(); - - _k_raise_topmost_in_view_list(_s->dyn_views, (GfxDynView *)templist->_contents); - - delete templist; - _s->dyn_views->free_tagged((GfxContainer *)_s->dyn_views); // Free obsolete dynviews - } // if (cast_list) - - if (open_animation) { - gfxop_clear_box(_s->gfx_state, gfx_rect(0, 10, 320, 190)); // Propagate pic - _s->visual->add_dirty_abs((GfxContainer *)_s->visual, gfx_rect_fullscreen, 0); - // Mark screen as dirty so picviews will be drawn correctly - FULL_REDRAW(); - - animate_do_animation(argc, (reg_t*)argv); - } // if (open_animation) - - if (cast_list) { - int retval; - int reparentize = 0; - - _s->pic_not_valid = 0; - - _k_view_list_do_postdraw(_s->dyn_views); - - // _k_view_list_dispose_loop() returns -1 if it requested a re-start, so we do just that. - while ((retval = _k_view_list_dispose_loop(cast_list, (GfxDynView *) _s->dyn_views->_contents, argc, (reg_t *)argv) < 0)) - reparentize = 1; - - if (_s->drop_views->_contents) { - _s->drop_views = gfxw_new_list(_s->dyn_views->_bounds, GFXW_LIST_SORTED); - _s->drop_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - ADD_TO_CURRENT_PICTURE_PORT(_s->drop_views); - } else { - assert(_s->drop_views); - gfxw_remove_widget_from_container(_s->drop_views->_parent, _s->drop_views); - ADD_TO_CURRENT_PICTURE_PORT(_s->drop_views); - } - - if ((reparentize | retval) - && ((GfxContainer *)_s->port == (GfxContainer *)_s->dyn_views->_parent) // If dynviews are on the same port... - && (_s->dyn_views->_next)) // ... and not on top of the view list... - reparentize_primary_widget_lists(_s, _s->port); // ...then reparentize. - - _k_view_list_kryptonize(_s->dyn_views->_contents); - } - - FULL_REDRAW(); -} - -void SciGui32::addToPicList(reg_t listReference, int argc, reg_t *argv) { - List *list; - GfxList *pic_views; - - assert_primary_widget_lists(_s); - - if (!listReference.segment) { - warning("Attempt to AddToPic single non-list: %04x:%04x", PRINT_REG(listReference)); - return; - } - - list = _s->_segMan->lookupList(listReference); - - pic_views = gfxw_new_list(_s->picture_port->_bounds, 1); - - debugC(2, kDebugLevelGraphics, "Preparing picview list...\n"); - _k_make_view_list(&pic_views, list, 0, argc, argv); - _k_prepare_view_list(pic_views, _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP); - // Store pic views for later re-use - - debugC(2, kDebugLevelGraphics, "Drawing picview list...\n"); - ADD_TO_CURRENT_PICTURE_PORT(pic_views); - _k_draw_view_list(pic_views, _K_DRAW_VIEW_LIST_NONDISPOSEABLE | _K_DRAW_VIEW_LIST_DISPOSEABLE | _K_DRAW_VIEW_LIST_PICVIEW); - // Draw relative to the bottom center - debugC(2, kDebugLevelGraphics, "Returning.\n"); - - reparentize_primary_widget_lists(_s, _s->port); -} - -void SciGui32::addToPicView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control) { - assert_primary_widget_lists(_s); - - GfxWidget *widget; - - topPos++; // magic +1 - - widget = gfxw_new_dyn_view(_s->gfx_state, Common::Point(leftPos, topPos), 0, viewId, loopNo, celNo, 0, priority, -1 /* No priority */ , ALIGN_CENTER, ALIGN_BOTTOM, 0); - - if (!widget) { - error("Attempt to single-add invalid picview (%d/%d/%d)", viewId, loopNo, celNo); - } else { - widget->_ID = -1; - if (control >= 0) { - Common::Rect abs_zone = nsrect_clip(_s, topPos, calculate_nsrect(_s, leftPos, topPos, viewId, loopNo, celNo), priority); - draw_rect_to_control_map(abs_zone); - } - ADD_TO_CURRENT_PICTURE_PORT(gfxw_picviewize_dynview((GfxDynView *) widget)); - } - return; -} - -void SciGui32::setNowSeen(reg_t objectReference) { - _k_set_now_seen(objectReference); -} - -static int collides_with(EngineState *s, Common::Rect area, reg_t other_obj, int use_nsrect, int view_mask) { - int other_signal = GET_SEL32V(s->_segMan, other_obj, signal); - int other_priority = GET_SEL32V(s->_segMan, other_obj, priority); - int y = (int16)GET_SEL32V(s->_segMan, other_obj, y); - Common::Rect other_area; - - if (use_nsrect) { - other_area = get_nsrect(s, other_obj, 0); - other_area = nsrect_clip(s, y, other_area, other_priority); - } else { - other_area.left = GET_SEL32V(s->_segMan, other_obj, brLeft); - other_area.right = GET_SEL32V(s->_segMan, other_obj, brRight); - other_area.top = GET_SEL32V(s->_segMan, other_obj, brTop); - other_area.bottom = GET_SEL32V(s->_segMan, other_obj, brBottom); - } - - if (other_area.right < 0 || other_area.bottom < 0 || area.right < 0 || area.bottom < 0) - return 0; // Out of scope - - if (other_area.left >= 320 || other_area.top >= 190 || area.right >= 320 || area.bottom >= 190) - return 0; // Out of scope - - debugC(2, kDebugLevelBresen, "OtherSignal=%04x, z=%04x obj=%04x:%04x\n", other_signal, (other_signal & view_mask), PRINT_REG(other_obj)); - - if ((other_signal & (view_mask)) == 0) { - // check whether the other object ignores actors - - debugC(2, kDebugLevelBresen, " against (%d,%d) to (%d,%d)\n", other_area.left, other_area.top, other_area.right, other_area.bottom); - - if (area.intersects(other_area)) - return 1; - /* CR (from :Bob Heitman:) Collision rects have Mac semantics, ((0,0),(1,1)) only - ** covers the coordinate (0,0) */ - } - - debugC(2, kDebugLevelBresen, " (no)\n"); - return 0; -} - -#define GASEOUS_VIEW_MASK_ACTIVE (kSignalRemoveView | kSignalIgnoreActor) -#define GASEOUS_VIEW_MASK_PASSIVE (kSignalNoUpdate | kSignalRemoveView | kSignalIgnoreActor) - -bool SciGui32::canBeHere(reg_t curObject, reg_t listReference) { - List *cliplist = NULL; - GfxPort *port = _s->picture_port; - uint16 signal; - bool retval; - - Common::Rect abs_zone; - rect_t zone; - uint16 edgehit; - uint16 illegal_bits; - - abs_zone.left = (int16)GET_SEL32V(_s->_segMan, curObject, brLeft); - abs_zone.right = (int16)GET_SEL32V(_s->_segMan, curObject, brRight); - abs_zone.top = (int16)GET_SEL32V(_s->_segMan, curObject, brTop); - abs_zone.bottom = (int16)GET_SEL32V(_s->_segMan, curObject, brBottom); - - zone = gfx_rect(abs_zone.left + port->zone.x, abs_zone.top + port->zone.y, abs_zone.width(), abs_zone.height()); - - signal = GET_SEL32V(_s->_segMan, curObject, signal); - debugC(2, kDebugLevelBresen, "Checking collision: (%d,%d) to (%d,%d) ([%d..%d]x[%d..%d]), obj=%04x:%04x, sig=%04x, cliplist=%04x:%04x\n", - GFX_PRINT_RECT(zone), abs_zone.left, abs_zone.right, abs_zone.top, abs_zone.bottom, - PRINT_REG(curObject), signal, PRINT_REG(listReference)); - - illegal_bits = GET_SEL32V(_s->_segMan, curObject, illegalBits); - - retval = !(illegal_bits & (edgehit = gfxop_scan_bitmask(_s->gfx_state, zone, GFX_MASK_CONTROL))); - - debugC(2, kDebugLevelBresen, "edgehit = %04x (illegalBits %04x)\n", edgehit, illegal_bits); - if (!retval) { - debugC(2, kDebugLevelBresen, " -> %04x\n", retval); - return false; // Can't BeHere - } - - retval = false; - - if ((illegal_bits & 0x8000) // If we are vulnerable to those views at all... - && _s->dyn_views) { // ...check against all stop-updated dynviews - GfxDynView *widget = (GfxDynView *)_s->dyn_views->_contents; - - debugC(2, kDebugLevelBresen, "Checking vs dynviews:\n"); - - while (widget) { - if (widget->_ID && (widget->signal & kSignalStopUpdHack) - && ((widget->_ID != curObject.segment) || (widget->_subID != curObject.offset)) - && _s->_segMan->isObject(make_reg(widget->_ID, widget->_subID))) - if (collides_with(_s, abs_zone, make_reg(widget->_ID, widget->_subID), 1, GASEOUS_VIEW_MASK_ACTIVE)) - return false; - - widget = (GfxDynView *)widget->_next; - } - } - - if (signal & GASEOUS_VIEW_MASK_ACTIVE) { - retval = (signal & GASEOUS_VIEW_MASK_ACTIVE) ? true : false; // CanBeHere- it's either being disposed, or it ignores actors anyway - debugC(2, kDebugLevelBresen, " -> %04x\n", retval); - return retval; // CanBeHere - } - - if (listReference.segment) - cliplist = _s->_segMan->lookupList(listReference); - - if (cliplist) { - Node *node = _s->_segMan->lookupNode(cliplist->first); - - retval = false; // Assume that we Can'tBeHere... - - while (node) { // Check each object in the list against our bounding rectangle - reg_t other_obj = node->value; - debugC(2, kDebugLevelBresen, " comparing against %04x:%04x\n", PRINT_REG(other_obj)); - - if (!_s->_segMan->isObject(other_obj)) { - warning("CanBeHere() cliplist contains non-object %04x:%04x", PRINT_REG(other_obj)); - } else if (other_obj != curObject) { // Clipping against yourself is not recommended - - if (collides_with(_s, abs_zone, other_obj, 0, GASEOUS_VIEW_MASK_PASSIVE)) { - debugC(2, kDebugLevelBresen, " -> %04x\n", retval); - return false; - } - - } // if (other_obj != obj) - node = _s->_segMan->lookupNode(node->succ); // move on - } - } - - if (!retval) - retval = true; - debugC(2, kDebugLevelBresen, " -> %04x\n", retval); - return retval; -} - -void SciGui32::setCursorPos(Common::Point pos) { - pos.y += _s->port->_bounds.y; - pos.x += _s->port->_bounds.x; - moveCursor(pos); -} - -void SciGui32::moveCursor(Common::Point pos) { - pos.y += _s->port->zone.y; - pos.x += _s->port->zone.x; - - if (pos.x > _s->port->zone.x + _s->port->zone.width) - pos.x = _s->port->zone.x + _s->port->zone.width; - if (pos.y > _s->port->zone.y + _s->port->zone.height) - pos.y = _s->port->zone.y + _s->port->zone.height; - - if (pos.x < 0) pos.x = 0; - if (pos.y < 0) pos.y = 0; - - if (pos.x > 320 || pos.y > 200) { - debug("[GFX] Attempt to place pointer at invalid coordinates (%d, %d)\n", pos.x, pos.y); - return; // Not fatal - } - - g_system->warpMouse(pos.x, pos.y); - - // Trigger event reading to make sure the mouse coordinates will - // actually have changed the next time we read them. - _s->_event->get(SCI_EVENT_PEEK); -} - -void SciGui32::graphAdjustPriority(int top, int bottom) { - _s->priority_first = top; - _s->priority_last = bottom; -} - -bool SciGui32::debugUndither(bool flag) { - return true; -} - -bool SciGui32::debugShowMap(int mapNo) { - gfxop_set_clip_zone(_s->gfx_state, gfx_rect_fullscreen); - - switch (mapNo) { - case 0: - _s->visual->add_dirty_abs((GfxContainer *)_s->visual, gfx_rect(0, 0, 320, 200), 0); - _s->visual->draw(Common::Point(0, 0)); - break; - - case 1: - gfx_xlate_pixmap(_s->gfx_state->pic->priority_map, _s->gfx_state->driver->getMode()); - gfxop_draw_pixmap(_s->gfx_state, _s->gfx_state->pic->priority_map, gfx_rect(0, 0, 320, 200), Common::Point(0, 0)); - break; - - case 2: - gfx_xlate_pixmap(_s->gfx_state->control_map, _s->gfx_state->driver->getMode()); - gfxop_draw_pixmap(_s->gfx_state, _s->gfx_state->control_map, gfx_rect(0, 0, 320, 200), Common::Point(0, 0)); - break; - } - - gfxop_update(_s->gfx_state); - return false; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui32/gui32.h b/engines/sci/gui32/gui32.h deleted file mode 100644 index 3221242dd0..0000000000 --- a/engines/sci/gui32/gui32.h +++ /dev/null @@ -1,150 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#ifndef SCI_GUI32_GUI32_H -#define SCI_GUI32_GUI32_H - -#include "sci/gui/gui.h" - -namespace Sci { - -class SciGui32 : public SciGui { -public: - SciGui32(EngineState *s, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor); - ~SciGui32(); - - void init(bool oldGfxFunctions); - - void wait(int16 ticks); - void setPort(uint16 portPtr); - Common::Rect getPortPic(int16 &picTop, int16 &picLeft); - void setPortPic(Common::Rect rect, int16 picTop, int16 picLeft, bool initPriorityBandsFlag); - reg_t getPort(); - void globalToLocal(int16 *x, int16 *y); - void localToGlobal(int16 *x, int16 *y); - int16 coordinateToPriority(int16 y); - int16 priorityToCoordinate(int16 priority); - - reg_t newWindow(Common::Rect dims, Common::Rect restoreRect, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title); - void disposeWindow(uint16 windowPtr, bool reanimate); - - void display(const char *text, int argc, reg_t *argv); - - void textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight); - void textFonts(int argc, reg_t *argv); - void textColors(int argc, reg_t *argv); - - void drawStatus(const char *text, int16 colorPen, int16 colorBack); - void drawMenuBar(bool clear); - void menuReset(); - void menuAdd(Common::String title, Common::String content, reg_t entriesBase); - void menuSet(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value); - reg_t menuGet(uint16 menuId, uint16 itemId, uint16 attributeId); - reg_t menuSelect(reg_t eventObject); - - void drawPicture(GuiResourceId pictureId, int16 animationNr, bool animationBlackoutFlag, bool mirroredFlag, bool addToFlag, int16 EGApaletteNo); - void drawCel(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo, int16 origHeight = -1); - void drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool hilite); - void drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 alignment, int16 style, bool hilite); - void drawControlTextEdit(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, int16 cursorPos, int16 maxChars, bool hilite); - void drawControlIcon(Common::Rect rect, reg_t obj, GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo, int16 style, bool hilite); - void drawControlList(Common::Rect rect, reg_t obj, int16 maxChars, int16 count, const char **entries, GuiResourceId fontId, int16 style, int16 upperPos, int16 cursorPos, bool isAlias, bool hilite); - void editControl(reg_t controlObject, reg_t eventObject); - - void graphFillBoxForeground(Common::Rect rect); - void graphFillBoxBackground(Common::Rect rect); - void graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control); - void graphDrawLine(Common::Point startPoint, Common::Point endPoint, int16 color, int16 priority, int16 control); - reg_t graphSaveBox(Common::Rect rect, uint16 screenMask); - reg_t graphSaveUpscaledHiresBox(Common::Rect rect); - void graphRestoreBox(reg_t handle); - void graphUpdateBox(Common::Rect); - void graphRedrawBox(Common::Rect); - void graphAdjustPriority(int top, int bottom); - - int16 picNotValid(int16 newPicNotValid); - - void paletteSet(GuiResourceId resourceNo, uint16 flags); - void paletteSetFlag(uint16 fromColor, uint16 toColor, uint16 flag); - void paletteUnsetFlag(uint16 fromColor, uint16 toColor, uint16 flag); - int16 paletteFind(uint16 r, uint16 g, uint16 b); - void paletteSetIntensity(uint16 fromColor, uint16 toColor, uint16 intensity); - bool paletteAnimate(uint16 fromColor, uint16 toColor, uint16 speed); - void paletteAnimateSet(); - - void shakeScreen(uint16 shakeCount, uint16 directions); - - uint16 onControl(byte screenMask, Common::Rect rect); - void animate(reg_t castListReference, bool cycle, int argc, reg_t *argv); - void addToPicList(reg_t listReference, int argc, reg_t *argv); - void addToPicView(GuiResourceId viewId, GuiViewLoopNo loopNo, GuiViewCelNo celNo, int16 leftPos, int16 topPos, int16 priority, int16 control); - void setNowSeen(reg_t objectReference); - bool canBeHere(reg_t curObject, reg_t listReference); - - void setCursorPos(Common::Point pos); - void moveCursor(Common::Point pos); - - uint16 getScreenWidth() { return 320; } - uint16 getScreenHeight() { return 200; } - - bool debugUndither(bool flag); - bool debugShowMap(int mapNo); - - // FIXME: Don't store EngineState - virtual void resetEngineState(EngineState *newState); - -private: - bool _usesOldGfxFunctions; - - GfxDynView *_k_make_dynview_obj(reg_t obj, int options, int nr, int argc, reg_t *argv); - void _k_make_view_list(GfxList **widget_list, List *list, int options, int argc, reg_t *argv); - void draw_obj_to_control_map(GfxDynView *view); - void draw_rect_to_control_map(Common::Rect abs_zone); - int _k_view_list_dispose_loop(List *list, GfxDynView *widget, int argc, reg_t *argv); - void _k_set_now_seen(reg_t object); - void _k_prepare_view_list(GfxList *list, int options); - void _k_update_signals_in_view_list(GfxList *old_list, GfxList *new_list); - void _k_view_list_kryptonize(GfxWidget *v); - void _k_raise_topmost_in_view_list(GfxList *list, GfxDynView *view); - void _k_redraw_view_list(GfxList *list); - void _k_draw_view_list(GfxList *list, int flags); - void _k_view_list_do_postdraw(GfxList *list); - void animate_do_animation(int argc, reg_t *argv); - - bool _k_animate_ran; // FIXME: Avoid non-const global vars - - bool activated_icon_bar; // FIXME: Avoid non-const global vars - int port_origin_x; // FIXME: Avoid non-const global vars - int port_origin_y; // FIXME: Avoid non-const global vars -}; - -} // End of namespace Sci - -#endif - -#endif diff --git a/engines/sci/gui32/picfill.cpp b/engines/sci/gui32/picfill.cpp deleted file mode 100644 index f48f7e938d..0000000000 --- a/engines/sci/gui32/picfill.cpp +++ /dev/null @@ -1,588 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/gfx/gfx_resource.h" - -/* Generic pic filling code, to be included by sci_pic_0.c - * - * - * To use, define the following: - * AUXBUF_FILL: Name of the exported floodfill function - * AUXBUF_FILL_HELPER: Name of the helper function - * FILL_FUNCTION: Name of the exported floodfill function - * FILL_FUNCTION_RECURSIVE: Name of the helper function - * - * Define DRAW_SCALED to support scaled drawing, or leave it out for faster - * processing. - * - */ - -namespace Sci { - -#define CLIPMASK_HARD_BOUND 0x80 /* ensures that we don't re-fill filled stuff */ - -static void AUXBUF_FILL_HELPER(gfxr_pic_t *pic, int old_xl, int old_xr, int y, int dy, - int clipmask, int control, int sci_titlebar_size) { - int xl, xr; - int oldytotal = y * 320; -#ifdef DRAW_SCALED - unsigned const char fillmask = CLIPMASK_HARD_BOUND | 0x78; -#else - unsigned const char fillmask = CLIPMASK_HARD_BOUND | 0x84; -#endif - - do { - int ytotal = oldytotal + (320 * dy); - int xcont; - int state; - - y += dy; - - if (y < sci_titlebar_size || y > 199) - return; - - xl = old_xl; - if (!(pic->aux_map[ytotal + xl] & clipmask)) { // go left - while (xl && !(pic->aux_map[ytotal + xl - 1] & clipmask)) - --xl; - } else // go right and look for the first valid spot - while ((xl <= old_xr) && (pic->aux_map[ytotal + xl] & clipmask)) - ++xl; - - if (xl > old_xr) // No fillable strip above the last one - return; - - assert((ytotal + xl) >= 0); - - xr = xl; - while (xr < 320 && !(pic->aux_map[ytotal + xr] & clipmask)) { - pic->aux_map[ytotal + xr] |= fillmask; - ++xr; - } - - assert((ytotal + xr) <= 64000); - - --xr; - - if (xr < xl) - return; - - // Check whether we need to recurse on branches in the same direction - if ((y > sci_titlebar_size && dy < 0) || (y < 199 && dy > 0)) { - state = 0; - xcont = xr + 1; - while (xcont <= old_xr) { - if (pic->aux_map[ytotal + xcont] & clipmask) - state = 0; - else if (!state) { // recurse - state = 1; - AUXBUF_FILL_HELPER(pic, xcont, old_xr, y - dy, dy, clipmask, control, sci_titlebar_size); - } - ++xcont; - } - } - - // Check whether we need to recurse on backward branches: - // left - if (xl < old_xl - 1) { - state = 0; - for (xcont = old_xl - 1; xcont >= xl; xcont--) { - if (pic->aux_map[oldytotal + xcont] & clipmask) - state = xcont; - else if (state) { // recurse - AUXBUF_FILL_HELPER(pic, xcont, state, y, -dy, clipmask, control, sci_titlebar_size); - state = 0; - } - } - } - - // right - if (xr > old_xr + 1) { - state = 0; - for (xcont = old_xr + 1; xcont <= xr; xcont++) { - if (pic->aux_map[oldytotal + xcont] & clipmask) - state = xcont; - else if (state) { // recurse - AUXBUF_FILL_HELPER(pic, state, xcont, y, -dy, clipmask, control, sci_titlebar_size); - state = 0; - } - } - } - - assert((ytotal + xl) >= 0); - assert((ytotal + xr + 1) <= 64000); - - if (control) - memset(pic->control_map->index_data + ytotal + xl, control, xr - xl + 1); - - oldytotal = ytotal; - old_xr = xr; - old_xl = xl; - - } while (1); -} - - -static void AUXBUF_FILL(gfxr_pic_t *pic, int x, int y, int clipmask, int control, int sci_titlebar_size) { - // Fills the aux buffer and the control map (if control != 0) - int xl, xr; - int ytotal = y * 320; -#ifdef DRAW_SCALED - unsigned const char fillmask = 0x78; -#else - unsigned const char fillmask = 0x4; -#endif - -#ifndef DRAW_SCALED - if (!control || !(clipmask & 4)) - return; // Without pic scaling, we only do this to fill the control map -#endif - - if (clipmask & 1) - clipmask = 1; // vis - else if (clipmask & 2) - clipmask = 2; // pri - else if (clipmask & 4) - clipmask = 4; // ctl - else return; - -#ifdef DRAW_SCALED - clipmask |= fillmask; // Bits 3-5 -#endif - - if (pic->aux_map[ytotal + x] & clipmask) - return; - - pic->aux_map[ytotal + x] |= fillmask; - - xl = x; - while (xl && !(pic->aux_map[ytotal + xl - 1] & clipmask)) { - --xl; - pic->aux_map[ytotal + xl] |= fillmask; - } - - xr = x; - while ((xr < 319) && !(pic->aux_map[ytotal + xr + 1] & clipmask)) { - ++xr; - pic->aux_map[ytotal + xr] |= fillmask; - } - - clipmask |= CLIPMASK_HARD_BOUND; // Guarantee clipping - - if (control) // Draw the same strip on the control map - memset(pic->control_map->index_data + ytotal + xl, control, xr - xl + 1); - - if (y > sci_titlebar_size) - AUXBUF_FILL_HELPER(pic, xl, xr, y, -1, clipmask, control, sci_titlebar_size); - - if (y < 199) - AUXBUF_FILL_HELPER(pic, xl, xr, y, + 1, clipmask, control, sci_titlebar_size); -} - - -#undef CLIPMASK_HARD_BOUND - - -#ifdef FILL_RECURSIVE_DEBUG -# define PRINT_DEBUG0(s) if (!fillmagc) fprintf(stderr, s) -# define PRINT_DEBUG1(s,p1) if (!fillmagc) fprintf(stderr, s, p1) -# define PRINT_DEBUG4(s,p1,p2,p3,p4) if (!fillmagc) fprintf(stderr, s, p1) -#else -# define PRINT_DEBUG0(s) -# define PRINT_DEBUG1(s,p1) -# define PRINT_DEBUG4(s,p1,p2,p3,p4) -#endif - -#ifdef DRAW_SCALED -# define SCALED_CHECK(x) (x) -# define IS_BOUNDARY(x, y, index) (((index) & legalmask) != legalcolor) -#else -# define SCALED_CHECK(x) 1 -# define IS_BOUNDARY(x, y, index) ( \ - (((x)+(y)) & 1)? /* figure out which part of the mask to use, to simulate dithering */ \ - ((((index)) & ((legalmask) )) != ((legalcolor) & ((legalmask)))) /* odd coordinate */ \ - : ((((index)) & ((legalmask) >> 8)) != ((legalcolor) & ((legalmask) >> 8))) /* even coordinate */ \ - ) -#endif - -static void FILL_FUNCTION_RECURSIVE(gfxr_pic_t *pic, int old_xl, int old_xr, int y, int dy, byte *bounds, - int legalcolor, int legalmask, int color, int priority, int drawenable, int sci_titlebar_size) { - int linewidth = pic->mode->scaleFactor * 320; - int miny = pic->mode->scaleFactor * sci_titlebar_size; - int maxy = pic->mode->scaleFactor * 200; - int xl, xr; - int oldytotal = y * linewidth; -#ifdef DRAW_SCALED - int old_proj_y = -42; - int proj_y; - int proj_ytotal; - int proj_x; - int proj_xl_bound = 0; - int proj_xr_bound = 0; -#endif - - do { - int ytotal = oldytotal + (linewidth * dy); - int xcont; - int state; - - y += dy; - -#ifdef FILL_RECURSIVE_DEBUG - if (!fillc) - return; - else if (!fillmagc) { - --fillc; - } -#endif - - if (y < miny || y >= maxy) { - PRINT_DEBUG0("ABRT on failed initial assertion!\n"); - return; - } -#ifdef DRAW_SCALED - proj_y = y / pic->mode->yfact; - - if (proj_y != old_proj_y) { - // First, find the projected coordinates, unless known already: - proj_ytotal = proj_y * 320; - proj_x = old_xl / pic->mode->xfact; - - proj_xl_bound = proj_x; - if (SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) { - while (proj_xl_bound && pic->aux_map[proj_ytotal + proj_xl_bound - 1] & FRESH_PAINT) - --proj_xl_bound; - } else { - while (proj_xl_bound < 319 && !(pic->aux_map[proj_ytotal + proj_xl_bound + 1] & FRESH_PAINT)) - ++proj_xl_bound; - - if (proj_xl_bound < 319) - ++proj_xl_bound; - } - - if (proj_xl_bound == 319 - && !(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) { - PRINT_DEBUG0("ABRT because proj_xl_bound couldn't be found\n"); - return; - } - - proj_xr_bound = (proj_xl_bound > proj_x) ? proj_xl_bound : proj_x; - while ((proj_xr_bound < 319) - && pic->aux_map[proj_ytotal + proj_xr_bound + 1] & FRESH_PAINT) - ++proj_xr_bound; - -#ifdef FILL_RECURSIVE_DEBUG - if (!fillmagc) { - fprintf(stderr, "l%d: {%d,%d} | ", proj_y, proj_xl_bound, proj_xr_bound); - pic->aux_map[proj_y*320 + proj_xl_bound] |= 0x2; - pic->aux_map[proj_y*320 + proj_xr_bound] |= 0x2; - } -#endif - - proj_xl_bound *= pic->mode->xfact; - if (proj_xl_bound) - proj_xl_bound -= pic->mode->xfact - 1; - - if (proj_xr_bound < 319) - ++proj_xr_bound; - proj_xr_bound *= pic->mode->xfact; - proj_xr_bound += pic->mode->xfact - 1; - - old_proj_y = proj_y; - } -#else -# define proj_xl_bound 0 -# define proj_xr_bound 319 -#endif - - // Now we have the projected limits, get the real ones: - - xl = (old_xl > proj_xl_bound) ? old_xl : proj_xl_bound; - if (!IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl])) { // go left as far as possible - while (xl > proj_xl_bound && (!IS_BOUNDARY(xl - 1, y + 1, bounds[ytotal + xl - 1]))) - --xl; - } else // go right until the fillable area starts - while (xl < proj_xr_bound && (IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl]))) - ++xl; - - - PRINT_DEBUG1("<%d,", xl); - - if ((xl > proj_xr_bound) - || (xl > old_xr)) { - PRINT_DEBUG0("ABRT because xl > xr_bound\n"); - return; - } - - xr = (xl > old_xl) ? xl : old_xl; - while (xr < proj_xr_bound && (!IS_BOUNDARY(xr + 1, y + 1, bounds[ytotal + xr + 1]))) - ++xr; - - PRINT_DEBUG1("%d> -> ", xr); - - if (IS_BOUNDARY(xl, y + 1, bounds[ytotal + xl])) { - PRINT_DEBUG0("ABRT because xl illegal\n"); - return; - } - -#ifdef DRAW_SCALED - PRINT_DEBUG4("[%d[%d,%d]%d]\n", proj_xl_bound, xl, xr, proj_xr_bound); - - if (xl < proj_xl_bound && xr - 3*pic->mode->xfact < proj_xl_bound) { - PRINT_DEBUG0("ABRT interval left of zone\n"); - return; - } - - if (xr > proj_xr_bound && xl + 3*pic->mode->xfact > proj_xr_bound) { - PRINT_DEBUG0("ABRT because interval right of zone\n"); - return; - } -#endif - - if (drawenable & GFX_MASK_VISUAL) - memset(pic->visual_map->index_data + ytotal + xl, color, xr - xl + 1); - - if (drawenable & GFX_MASK_PRIORITY) - memset(pic->priority_map->index_data + ytotal + xl, priority, xr - xl + 1); - - - // Check whether we need to recurse on branches in the same direction - state = 0; - xcont = xr + 1; - while (xcont <= old_xr) { - if (IS_BOUNDARY(xcont, y + 1, bounds[ytotal + xcont])) - state = xcont; - else if (state) { // recurse - PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr); - PRINT_DEBUG4("rec BRANCH %d [%d,%d] l%d\n", dy, state, xcont, y - dy); - - FILL_FUNCTION_RECURSIVE(pic, state, xcont, y - dy, dy, bounds, legalcolor, - legalmask, color, priority, drawenable, sci_titlebar_size); - state = 0; - } - ++xcont; - } - - // Check whether we need to recurse on backward branches: - // left - if (xl < old_xl - 1) { - state = 0; - for (xcont = old_xl - 1; xcont >= xl; xcont--) { - if (IS_BOUNDARY(xcont, y, bounds[oldytotal + xcont])) - state = xcont; - else if (state) { // recurse - PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr); - PRINT_DEBUG4("rec BACK-LEFT %d [%d,%d] l%d\n", -dy, state, xcont, y); - - FILL_FUNCTION_RECURSIVE(pic, xcont, state, y, -dy, bounds, - legalcolor, legalmask, color, priority, drawenable, - sci_titlebar_size); - state = 0; - } - } - } - - // right - if (xr > old_xr + 1) { - state = 0; - for (xcont = old_xr + 1; xcont <= xr; xcont++) { - if (IS_BOUNDARY(xcont, y, bounds[oldytotal + xcont])) - state = xcont; - else if (state) { // recurse - PRINT_DEBUG4("[%d[%d,%d],%d]: ", old_xl, xl, xr, old_xr); - PRINT_DEBUG4("rec BACK-RIGHT %d [%d,%d] l%d\n", -dy, state, xcont, y); - - FILL_FUNCTION_RECURSIVE(pic, state, xcont, y, -dy, bounds, - legalcolor, legalmask, color, priority, drawenable, - sci_titlebar_size); - state = 0; - } - } - } - - oldytotal = ytotal; - old_xl = xl; - old_xr = xr; - - } while (1); -} - - -static void FILL_FUNCTION(gfxr_pic_t *pic, int x_320, int y_200, int color, int priority, int control, int drawenable, - int sci_titlebar_size) { - int linewidth = pic->mode->scaleFactor * 320; - int x, y; - int xl, xr; - int ytotal; - int bitmask; - byte *bounds = NULL; - int legalcolor, legalmask; -#ifdef DRAW_SCALED - int min_x, min_y, max_x, max_y; -#endif - int original_drawenable = drawenable; // Backup, since we need the unmodified value - // for filling the aux and control map - - // Restrict drawenable not to restrict itself to zero - if (pic->control_map->index_data[y_200 * 320 + x_320] != 0) - drawenable &= ~GFX_MASK_CONTROL; - - if (color == 0xff) - drawenable &= ~GFX_MASK_VISUAL; - - if (priority == 0) { - drawenable &= ~GFX_MASK_PRIORITY; - original_drawenable &= ~GFX_MASK_PRIORITY; - } - - AUXBUF_FILL(pic, x_320, y_200, original_drawenable, (drawenable & GFX_MASK_CONTROL) ? control : 0, - sci_titlebar_size); - -#ifdef DRAW_SCALED - _gfxr_auxbuf_spread(pic, &min_x, &min_y, &max_x, &max_y); - - if (_gfxr_find_fill_point(pic, min_x, min_y, max_x, max_y, x_320, y_200, color, drawenable, &x, &y)) { - //GFXWARN("Could not find scaled fill point, but unscaled fill point was available!\n"); - drawenable &= GFX_MASK_PRIORITY; - if (!drawenable) - _gfxr_auxbuf_propagate_changes(pic, 0); - } -#else - x = x_320; - y = y_200; -#endif - - ytotal = y * linewidth; - - if (!drawenable) - return; - - if (drawenable & GFX_MASK_VISUAL) { - bounds = pic->visual_map->index_data; -#if 0 - // Code disabled, as removing it fixes qg1 pic.095 (unscaled). However, - // it MAY be of relevance to scaled pic drawing... - - if ((color & 0xf) == 0xf // When dithering with white, do more - // conservative checks - || (color & 0xf0) == 0xf0) - legalcolor = 0xff; - else - legalcolor = 0xf0; // Only check the second color -#endif -#ifdef DRAW_SCALED - legalcolor = 0xff; - legalmask = legalcolor; -#else - legalmask = 0x0ff0; - legalcolor = 0xff; -#endif - } else if (drawenable & GFX_MASK_PRIORITY) { - bounds = pic->priority_map->index_data; - legalcolor = 0; - legalmask = 0x0f0f; - } else { - legalcolor = 0; - legalmask = 0x0f0f; - } - - if (!bounds || IS_BOUNDARY(x, y, bounds[ytotal + x])) - return; - - if (bounds) { -#ifdef DRAW_SCALED - int proj_y = y_200; - int proj_ytotal = proj_y * 320; - int proj_x = x_320; - int proj_xl_bound; - int proj_xr_bound; - int proj_xl, proj_xr; - - ytotal = y * linewidth; - - proj_xl_bound = proj_x; - if (SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound] & FRESH_PAINT)) { - while (proj_xl_bound && SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xl_bound - 1] & FRESH_PAINT)) - --proj_xl_bound; - } else - while (proj_xl_bound < 319 && SCALED_CHECK(!(pic->aux_map[proj_ytotal + proj_xl_bound + 1] & FRESH_PAINT))) - ++proj_xl_bound; - - proj_xr_bound = (proj_xl_bound > proj_x) ? proj_xl_bound : proj_x; - while ((proj_xr_bound < 319) && SCALED_CHECK(pic->aux_map[proj_ytotal + proj_xr_bound + 1] & FRESH_PAINT)) - ++proj_xr_bound; - - proj_xl = proj_xl_bound; - proj_xr = proj_xr_bound; - - proj_xl_bound *= pic->mode->xfact; - if (proj_xl_bound) - proj_xl_bound -= pic->mode->xfact - 1; - - if (proj_xr_bound < 319) - ++proj_xr_bound; - proj_xr_bound *= pic->mode->xfact; - proj_xr_bound += pic->mode->xfact - 1; -#endif - xl = x; - while (xl > proj_xl_bound && (!IS_BOUNDARY(xl - 1, y, bounds[ytotal + xl -1]))) - --xl; - - while (x < proj_xr_bound && (!IS_BOUNDARY(x + 1, y, bounds[ytotal + x + 1]))) - ++x; - xr = x; - - if (drawenable & GFX_MASK_VISUAL) - memset(pic->visual_map->index_data + ytotal + xl, color, xr - xl + 1); - - if (drawenable & GFX_MASK_PRIORITY) - memset(pic->priority_map->index_data + ytotal + xl, priority, xr - xl + 1); - - FILL_FUNCTION_RECURSIVE(pic, xl, xr, y, -1, bounds, legalcolor, legalmask, color, priority, drawenable, - sci_titlebar_size); - FILL_FUNCTION_RECURSIVE(pic, xl, xr, y, + 1, bounds, legalcolor, legalmask, color, priority, drawenable, - sci_titlebar_size); - } - - // Now finish the aux buffer - bitmask = drawenable & (((color != 0xff) ? 1 : 0) | ((priority) ? 2 : 0) | ((control) ? 4 : 0)); - -#ifdef DRAW_SCALED -# ifdef FILL_RECURSIVE_DEBUG - if (fillmagc) -# endif - _gfxr_auxbuf_propagate_changes(pic, bitmask); -#endif -} - -#undef SCALED_CHECK -#undef IS_BOUNDARY - -#ifndef DRAW_SCALED -# undef proj_xl_bound -# undef proj_xr_bound -#endif - -} // End of namespace Sci diff --git a/engines/sci/gui32/res_font.cpp b/engines/sci/gui32/res_font.cpp deleted file mode 100644 index 7c82b6581b..0000000000 --- a/engines/sci/gui32/res_font.cpp +++ /dev/null @@ -1,140 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include "common/endian.h" -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" -#include "sci/gui32/font.h" - -namespace Sci { - -extern int font_counter; - -#define FONT_HEIGHT_OFFSET 4 -#define FONT_MAXCHAR_OFFSET 2 - -static void calc_char(byte *dest, int total_width, int total_height, byte *src, int size) { - int width = src[0]; - int height = src[1]; - int byte_width = (width + 7) >> 3; - int y; - - src += 2; - - if ((width >> 3) > total_width || height > total_height) { - error("Weird character: width=%d/%d, height=%d/%d", width, total_width, height, total_height); - } - - if (byte_width * height + 2 > size) { - error("Character extends to %d of %d allowed bytes", byte_width * height + 2, size); - } - - for (y = 0; y < height; y++) { - memcpy(dest, src, byte_width); - src += byte_width; - dest += total_width; - } -} - -gfx_bitmap_font_t *gfxr_read_font(int id, byte *resource, int size) { - gfx_bitmap_font_t *font = (gfx_bitmap_font_t*)calloc(sizeof(gfx_bitmap_font_t), 1); - int chars_nr; - int max_width = 0, max_height; - int i; - - ++font_counter; - - if (size < 6) { - error("Font %04x size is %d", id, size); - gfxr_free_font(font); - return NULL; - } - - font->chars_nr = chars_nr = READ_LE_UINT16(resource + FONT_MAXCHAR_OFFSET); - font->line_height = max_height = READ_LE_UINT16(resource + FONT_HEIGHT_OFFSET); - - if (chars_nr < 0 || chars_nr > 256 || max_height < 0) { - if (chars_nr < 0 || chars_nr > 256) - error("Font %04x: Invalid number of characters: %d", id, chars_nr); - if (max_height < 0) - error("Font %04x: Invalid font height: %d", id, max_height); - gfxr_free_font(font); - return NULL; - } - - if (size < 6 + chars_nr * 2) { - error("Font %04x: Insufficient space for %d characters in font", id, chars_nr); - gfxr_free_font(font); - return NULL; - } - - font->ID = id; - font->widths = (int*)malloc(sizeof(int) * chars_nr); - - for (i = 0; i < chars_nr; i++) { - int offset = READ_LE_UINT16(resource + (i << 1) + 6); - - if (offset >= size) { - error("Font %04x: Error: Character 0x%02x is at offset 0x%04x (beyond 0x%04x)", id, i, offset, size); - gfxr_free_font(font); - return NULL; - } - - if ((resource[offset]) > max_width) - max_width = resource[offset]; - if ((resource[offset + 1]) > max_height) - max_height = resource[offset + 1]; - - font->widths[i] = resource[offset]; - } - - font->height = max_height; - font->row_size = (max_width + 7) >> 3; - - if (font->row_size == 3) - font->row_size = 4; - - if (font->row_size > 4) - font->row_size = (font->row_size + 3) & ~3; - - font->char_size = font->row_size * max_height; - font->data = (byte *)calloc(font->char_size, chars_nr); - - for (i = 0; i < chars_nr; i++) { - int offset = READ_LE_UINT16(resource + (i << 1) + 6); - - calc_char(font->data + (font->char_size * i), font->row_size, max_height, resource + offset, size - offset); - } - - return font; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui32/res_pal.cpp b/engines/sci/gui32/res_pal.cpp deleted file mode 100644 index 38a0eb5b60..0000000000 --- a/engines/sci/gui32/res_pal.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -/* SCI1 palette resource defrobnicator */ - -#include "common/file.h" -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" - -namespace Sci { - -#define MAX_COLORS 256 -#define PALETTE_START 260 -#define COLOR_OK 0x01 - -#define SCI_PAL_FORMAT_VARIABLE_FLAGS 0 -#define SCI_PAL_FORMAT_CONSTANT_FLAGS 1 - -Palette *gfxr_read_pal11(int id, byte *resource, int size) { - int start_color = resource[25]; - int format = resource[32]; - int entry_size = (format == SCI_PAL_FORMAT_VARIABLE_FLAGS) ? 4 : 3; - byte *pal_data = resource + 37; - int _colors_nr = READ_LE_UINT16(resource + 29); - - // Happens at the beginning of Pepper - if (_colors_nr > 256) - return NULL; - - Palette *retval = new Palette(_colors_nr + start_color); - int i; - - char buf[100]; - sprintf(buf, "read_pal11 (id %d)", id); - retval->name = buf; - - for (i = 0; i < start_color; i ++) { - retval->setColor(i, 0, 0, 0); - } - for (i = start_color; i < start_color + _colors_nr; i ++) { - switch (format) { - case SCI_PAL_FORMAT_CONSTANT_FLAGS: - retval->setColor(i, pal_data[0], pal_data[1], pal_data[2]); - break; - case SCI_PAL_FORMAT_VARIABLE_FLAGS: - if (pal_data[0] & 1) - retval->setColor(i, pal_data[1], pal_data[2], pal_data[3]); - break; - } - pal_data += entry_size; - } - - return retval; -} - -Palette *gfxr_read_pal1(int id, byte *resource, int size) { - int counter = 0; - int pos; - unsigned int colors[MAX_COLORS] = {0}; - - if (size < PALETTE_START + 4) { - error("Palette resource too small in %04x", id); - return NULL; - } - - pos = PALETTE_START; - - while (pos < size/* && resource[pos] == COLOR_OK && counter < MAX_COLORS*/) { - colors[counter++] = resource[pos] | (resource[pos + 1] << 8) | (resource[pos + 2] << 16) | (resource[pos + 3] << 24); - pos += 4; - } - - if (counter < MAX_COLORS) { - error("SCI1 palette %04x ends prematurely", id); - return NULL; - } - - Palette *retval = new Palette(counter); - char buf[100]; - sprintf(buf, "read_pal1 (id %d)", id); - retval->name = buf; - - for (pos = 0; pos < counter; pos++) { - unsigned int color = colors[pos]; - if (color & 1) - retval->setColor(pos, (color >> 8) & 0xff, (color >> 16) & 0xff, (color >> 24) & 0xff); - } - - return retval; -} - -Palette *gfxr_read_pal1_amiga(Common::File &file) { - int i; - Palette *retval = new Palette(32); - - for (i = 0; i < 32; i++) { - int b1, b2; - - b1 = file.readByte(); - b2 = file.readByte(); - - if (b1 == EOF || b2 == EOF) { - delete retval; - error("Amiga palette file ends prematurely"); - return NULL; - } - - retval->setColor(i, (b1 & 0xf) * 0x11, ((b2 & 0xf0) >> 4) * 0x11, (b2 & 0xf) * 0x11); - } - - return retval; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui32/res_pic.cpp b/engines/sci/gui32/res_pic.cpp deleted file mode 100644 index 10f26c213f..0000000000 --- a/engines/sci/gui32/res_pic.cpp +++ /dev/null @@ -1,1539 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -#include <time.h> // for time() to seed rand() via srand() - -#include "common/endian.h" - -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - -#define GFXR_PIC0_PALETTE_SIZE 40 -#define GFXR_PIC0_NUM_PALETTES 4 - -#define INTERCOL(a, b) ((int) sqrt((((3.3 * (a))*(a)) + ((1.7 * (b))*(b))) / 5.0)) -// Macro for color interpolation - -#define SCI0_MAX_PALETTE 2 - -int sci0_palette = 0; - -// Copied from include/kernel.h -#define SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr) ((((nr) == 0)? 0 : \ - ((first) + (((nr)-1) * (last - first)) / 14))) - -// Default color maps -PaletteEntry gfx_sci0_image_colors[SCI0_MAX_PALETTE+1][GFX_SCI0_IMAGE_COLORS_NR] = { - {PaletteEntry(0x00, 0x00, 0x00), PaletteEntry(0x00, 0x00, 0xaa), - PaletteEntry(0x00, 0xaa, 0x00), PaletteEntry(0x00, 0xaa, 0xaa), - PaletteEntry(0xaa, 0x00, 0x00), PaletteEntry(0xaa, 0x00, 0xaa), - PaletteEntry(0xaa, 0x55, 0x00), PaletteEntry(0xaa, 0xaa, 0xaa), - PaletteEntry(0x55, 0x55, 0x55), PaletteEntry(0x55, 0x55, 0xff), - PaletteEntry(0x55, 0xff, 0x55), PaletteEntry(0x55, 0xff, 0xff), - PaletteEntry(0xff, 0x55, 0x55), PaletteEntry(0xff, 0x55, 0xff), - PaletteEntry(0xff, 0xff, 0x55), PaletteEntry(0xff, 0xff, 0xff)}, // "Normal" EGA - - - {PaletteEntry(0x00, 0x00, 0x00), PaletteEntry(0x00, 0x00, 0xff), - PaletteEntry(0x00, 0xaa, 0x00), PaletteEntry(0x00, 0xaa, 0xaa), - PaletteEntry(0xce, 0x00, 0x00), PaletteEntry(0xbe, 0x71, 0xde), - PaletteEntry(0x8d, 0x50, 0x00), PaletteEntry(0xbe, 0xbe, 0xbe), - PaletteEntry(0x55, 0x55, 0x55), PaletteEntry(0x00, 0xbe, 0xff), - PaletteEntry(0x00, 0xce, 0x55), PaletteEntry(0x55, 0xff, 0xff), - PaletteEntry(0xff, 0x9d, 0x8d), PaletteEntry(0xff, 0x55, 0xff), - PaletteEntry(0xff, 0xff, 0x00), PaletteEntry(0xff, 0xff, 0xff)}, // AGI Amiga-ish - -// RGB and I intensities (former taken from the GIMP) -#define GR 30 -#define GG 59 -#define GB 11 -#define GI 15 - -#define FULL (GR+GG+GB+GI) - -#define CC(x) (((x)*255)/FULL),(((x)*255)/FULL),(((x)*255)/FULL) // Combines color intensities - - {PaletteEntry(CC(0) ), PaletteEntry(CC(GB) ), - PaletteEntry(CC(GG) ), PaletteEntry(CC(GB + GG) ), - PaletteEntry(CC(GR) ), PaletteEntry(CC(GB + GR) ), - PaletteEntry(CC(GG + GR) ), PaletteEntry(CC(GB + GG + GR) ), - PaletteEntry(CC(GI) ), PaletteEntry(CC(GB + GI) ), - PaletteEntry(CC(GG + GI) ), PaletteEntry(CC(GB + GG + GI) ), - PaletteEntry(CC(GR + GI) ), PaletteEntry(CC(GB + GR + GI) ), - PaletteEntry(CC(GG + GR + GI) ), PaletteEntry(CC(GB + GG + GR + GI) )} -}; // Grayscale - -#undef GR -#undef GG -#undef GB -#undef GI - -#undef FULL - -#undef C2 -#undef C3 -#undef C4 - -Palette* gfx_sci0_pic_colors = 0; // Initialized during initialization -Palette* gfx_sci0_image_pal[SCI0_MAX_PALETTE+1]; -Palette* embedded_view_pal = 0; - -#define SCI1_PALETTE_SIZE 1284 - -void gfxr_init_static_palette() { - int i; - - if (!gfx_sci0_pic_colors) { - gfx_sci0_pic_colors = new Palette(256); - gfx_sci0_pic_colors->name = "gfx_sci0_pic_colors"; - - // This 256 colour palette is used for the kDitherNone and kDither256Colors - // modes. We set index 0xXY to a blend of EGA colors X^Y and Y. We permute them - // in this somewhat strange way to ensure the regular EGA colours are at - // indices 0-15. - for (i = 0; i < 256; i++) { - byte r = INTERCOL(gfx_sci0_image_colors[sci0_palette][i & 0xf].r, - gfx_sci0_image_colors[sci0_palette][(i >> 4) ^ (i & 0xf)].r); - byte g = INTERCOL(gfx_sci0_image_colors[sci0_palette][i & 0xf].g, - gfx_sci0_image_colors[sci0_palette][(i >> 4) ^ (i & 0xf)].g); - byte b = INTERCOL(gfx_sci0_image_colors[sci0_palette][i & 0xf].b, - gfx_sci0_image_colors[sci0_palette][(i >> 4) ^ (i & 0xf)].b); - gfx_sci0_pic_colors->setColor(i,r,g,b); - } - //warning("Uncomment me after fixing sci0_palette changes to reset me"); - //_gfxr_pic0_colors_initialized = 1; - - for (i = 0; i <= SCI0_MAX_PALETTE; ++i) { - gfx_sci0_image_pal[i] = new Palette(gfx_sci0_image_colors[i], GFX_SCI0_IMAGE_COLORS_NR); - gfx_sci0_image_pal[i]->name = "gfx_sci0_image_pal[i]"; - } - - embedded_view_pal = new Palette(16); - for (i = 0; i < 16; i++) - embedded_view_pal->setColor(i, 0, 0, i * 0x11); - embedded_view_pal->name = "embedded_view_pal"; - } -} - - -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; - - pic->control_map = gfx_pixmap_alloc_index_data(gfx_new_pixmap(320, 200, ID, 2, 0)); - - pic->priority_map = gfx_pixmap_alloc_index_data(gfx_new_pixmap(mode->scaleFactor * 320, mode->scaleFactor * 200, - ID, 1, 0)); - - - pic->visual_map = gfx_pixmap_alloc_index_data(gfx_new_pixmap(320 * mode->scaleFactor, - 200 * mode->scaleFactor, ID, 0, 0)); - - // Initialize colors - if (!sci1) { - pic->ID = ID; - gfxr_init_static_palette(); - } - - pic->visual_map->palette = gfx_sci0_pic_colors->getref(); - pic->visual_map->color_key = GFX_PIXMAP_COLOR_KEY_NONE; - - pic->visual_map->flags = 0; - pic->priority_map->flags = 0; - pic->control_map->flags = 0; - pic->priority_map->palette = gfx_sci0_image_pal[sci0_palette]->getref(); - pic->control_map->palette = gfx_sci0_image_pal[sci0_palette]->getref(); - - pic->undithered_buffer_size = pic->visual_map->index_width * pic->visual_map->index_height; - pic->undithered_buffer = NULL; - pic->priorityTable = NULL; - - return pic; -} - -// Pic rendering operations - -void gfxr_clear_pic0(gfxr_pic_t *pic, int titlebar_size) { - memset(pic->visual_map->index_data, 0x00, (320 * pic->mode->scaleFactor * titlebar_size * pic->mode->scaleFactor)); - memset(pic->visual_map->index_data + (320 * pic->mode->scaleFactor * titlebar_size * pic->mode->scaleFactor), - 0xff, pic->mode->scaleFactor * 320 * pic->mode->scaleFactor * (200 - titlebar_size)); // white - memset(pic->priority_map->index_data + (320 * pic->mode->scaleFactor * titlebar_size * pic->mode->scaleFactor), - 0x0, pic->mode->scaleFactor * 320 * pic->mode->scaleFactor * (200 - titlebar_size)); - memset(pic->priority_map->index_data, 0x0a, titlebar_size * (pic->mode->scaleFactor * 320 * pic->mode->scaleFactor)); - memset(pic->control_map->index_data, 0, GFXR_AUX_MAP_SIZE); - memset(pic->aux_map, 0, GFXR_AUX_MAP_SIZE); -} - - -//** Basic operations on the auxiliary buffer ** - -#define FRESH_PAINT 0x40 -// freshly filled or near to something that is - -#define LINEMACRO(startx, starty, deltalinear, deltanonlinear, linearvar, nonlinearvar, \ - linearend, nonlinearstart, linearmod, nonlinearmod, operation) \ - x = (startx); y = (starty); \ - incrNE = ((deltalinear) > 0)? (deltalinear) : -(deltalinear); \ - incrNE <<= 1; \ - deltanonlinear <<= 1; \ - incrE = ((deltanonlinear) > 0) ? -(deltanonlinear) : (deltanonlinear); \ - d = nonlinearstart-1; \ - while (linearvar != (linearend)) { \ - buffer[linewidth * y + x] operation color; \ -/* color ^= color2; color2 ^= color; color ^= color2; */ /* Swap colors */ \ - linearvar += linearmod; \ - if ((d+=incrE) < 0) { \ - d += incrNE; \ - nonlinearvar += nonlinearmod; \ - }; \ - }; \ - buffer[linewidth * y + x] operation color; - -static void _gfxr_auxbuf_line_draw(gfxr_pic_t *pic, rect_t line, int color, int color2, int titlebar_size) { - int dx, dy, incrE, incrNE, d, finalx, finaly; - int x = line.x; - int y = line.y + titlebar_size; - unsigned char *buffer = pic->aux_map; - int linewidth = 320; - - dx = line.width; - dy = line.height; - finalx = x + dx; - finaly = y + dy; - - dx = abs(dx); - dy = abs(dy); - - if (dx > dy) { - if (finalx < x) { - if (finaly < y) { // llu == left-left-up - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, -1, -1, |=); - } else { // lld - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, -1, 1, |=); - } - } else { // x1 >= x - if (finaly < y) { // rru - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, 1, -1, |=); - } else { // rrd - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, 1, 1, |=); - } - } - } else { // dx <= dy - if (finaly < y) { - if (finalx < x) { // luu - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, -1, -1, |=); - } else { // ruu - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, -1, 1, |=); - } - } else { // y1 >= y - if (finalx < x) { // ldd - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, 1, -1, |=); - } else { // rdd - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, 1, 1, |=); - } - } - } -} - -static void _gfxr_auxbuf_line_clear(gfxr_pic_t *pic, rect_t line, int color, int titlebar_size) { - int dx, dy, incrE, incrNE, d, finalx, finaly; - int x = line.x; - int y = line.y + titlebar_size; - unsigned char *buffer = pic->aux_map; - int linewidth = 320; - - dx = line.width; - dy = line.height; - finalx = x + dx; - finaly = y + dy; - - dx = abs(dx); - dy = abs(dy); - - if (dx > dy) { - if (finalx < x) { - if (finaly < y) { // llu == left-left-up - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, -1, -1, &=); - } else { // lld - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, -1, 1, &=); - } - } else { // x1 >= x - if (finaly < y) { // rru - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, 1, -1, &=); - } else { // rrd - LINEMACRO(x, y, dx, dy, x, y, finalx, dx, 1, 1, &=); - } - } - } else { // dx <= dy - if (finaly < y) { - if (finalx < x) { // luu - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, -1, -1, &=); - } else { // ruu - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, -1, 1, &=); - } - } else { // y1 >= y - if (finalx < x) { // ldd - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, 1, -1, &=); - } else { // rdd - LINEMACRO(x, y, dy, dx, y, x, finaly, dy, 1, 1, &=); - } - } - } -} - -#undef LINEMACRO - -/*** Regular drawing operations ***/ - -#define PATTERN_FLAG_RECTANGLE 0x10 -#define PATTERN_FLAG_USE_PATTERN 0x20 - -#define PIC_OP_FIRST 0xf0 - -enum { - PIC_OP_SET_COLOR = 0xf0, - PIC_OP_DISABLE_VISUAL = 0xf1, - PIC_OP_SET_PRIORITY = 0xf2, - PIC_OP_DISABLE_PRIORITY = 0xf3, - PIC_OP_SHORT_PATTERNS = 0xf4, - PIC_OP_MEDIUM_LINES = 0xf5, - PIC_OP_LONG_LINES = 0xf6, - PIC_OP_SHORT_LINES = 0xf7, - PIC_OP_FILL = 0xf8, - PIC_OP_SET_PATTERN = 0xf9, - PIC_OP_ABSOLUTE_PATTERN = 0xfa, - PIC_OP_SET_CONTROL = 0xfb, - PIC_OP_DISABLE_CONTROL = 0xfc, - PIC_OP_MEDIUM_PATTERNS = 0xfd, - PIC_OP_OPX = 0xfe, - PIC_OP_TERMINATE = 0xff -}; - -enum { - PIC_SCI0_OPX_SET_PALETTE_ENTRIES = 0, - PIC_SCI0_OPX_SET_PALETTE = 1, - PIC_SCI0_OPX_MONO0 = 2, - PIC_SCI0_OPX_MONO1 = 3, - PIC_SCI0_OPX_MONO2 = 4, - PIC_SCI0_OPX_MONO3 = 5, - PIC_SCI0_OPX_MONO4 = 6, - PIC_SCI0_OPX_EMBEDDED_VIEW, - PIC_SCI0_OPX_SET_PRIORITY_TABLE -}; - -// We use this so we can keep OPX handling in one switch. -// We simply add this constant to the op number if we're running an SCI1 game, -// and offset the OPX constants below correspondingly. -#define SCI1_OP_OFFSET 42 - -enum { - PIC_SCI1_OPX_SET_PALETTE_ENTRIES = 0 + SCI1_OP_OFFSET, - PIC_SCI1_OPX_EMBEDDED_VIEW = 1 + SCI1_OP_OFFSET, - PIC_SCI1_OPX_SET_PALETTE = 2 + SCI1_OP_OFFSET, - PIC_SCI1_OPX_PRIORITY_TABLE_EQDIST = 3 + SCI1_OP_OFFSET, - PIC_SCI1_OPX_PRIORITY_TABLE_EXPLICIT = 4 + SCI1_OP_OFFSET -}; - - -enum { - ELLIPSE_SOLID, // Normal filled ellipse - ELLIPSE_OR // color ORred to the buffer -}; - -static void _gfxr_fill_ellipse(gfxr_pic_t *pic, byte *buffer, int linewidth, int x, int y, - int rad_x, int rad_y, int color, int fillstyle) { - int xx = 0, yy = rad_y; - int i, x_i, y_i; - int xr = 2 * rad_x * rad_x; - int yr = 2 * rad_y * rad_y; - - x_i = 1; - y_i = xr * rad_y - 1; - i = y_i >> 1; - - while (yy >= 0) { - int oldxx = xx; - int oldyy = yy; - - if (i >= 0) { - x_i += yr; - i -= x_i + 1; - ++xx; - } - - if (i < 0) { - y_i -= xr; - i += y_i - 1; - --yy; - } - - if (oldyy != yy) { - int j; - int offset0 = (y - oldyy) * linewidth; - int offset1 = (y + oldyy) * linewidth; - - offset0 += x - oldxx; - offset1 += x - oldxx; - - if (oldyy == 0) - offset1 = 0; // We never have to draw ellipses in the menu bar - - oldyy = yy; - - switch (fillstyle) { - - case ELLIPSE_SOLID: - memset(buffer + offset0, color, (oldxx << 1) + 1); - if (offset1) - memset(buffer + offset1, color, (oldxx << 1) + 1); - break; - - case ELLIPSE_OR: - for (j = 0; j < (oldxx << 1) + 1; j++) { - buffer[offset0 + j] |= color; - if (offset1) - buffer[offset1 + j] |= color; - } - break; - - default: - warning(" to %s,%d", __FILE__, __LINE__); - return; - - } - } - } -} - -static void _gfxr_auxplot_brush(gfxr_pic_t *pic, byte *buffer, int yoffset, int offset, int plot, - int color, gfx_brush_mode_t brush_mode, int randseed) { - // yoffset 63680, offset 320, plot 1, color 34, brush_mode 0, randseed 432)*/ - // Auxplot: Used by plot_aux_pattern to plot to visual and priority - int xc, yc; - int line_width = 320 * pic->mode->scaleFactor; - int full_offset = (yoffset * pic->mode->scaleFactor + offset) * pic->mode->scaleFactor; - - if (yoffset + offset >= 64000) { - error("_gfxr_auxplot_brush() failed. Breakpoint in %s, line %d", __FILE__, __LINE__); - } - - switch (brush_mode) { - case GFX_BRUSH_MODE_SCALED: - if (plot) - for (yc = 0; yc < pic->mode->scaleFactor; yc++) { - memset(buffer + full_offset, color, pic->mode->scaleFactor); - full_offset += line_width; - } - break; - - case GFX_BRUSH_MODE_ELLIPSES: - if (plot) { - int x = offset * pic->mode->scaleFactor + ((pic->mode->scaleFactor - 1) >> 1); - int y = (yoffset / 320) * pic->mode->scaleFactor + ((pic->mode->scaleFactor - 1) >> 1); - - _gfxr_fill_ellipse(pic, buffer, line_width, x, y, pic->mode->scaleFactor >> 1, pic->mode->scaleFactor >> 1, color, ELLIPSE_SOLID); - } - break; - - case GFX_BRUSH_MODE_RANDOM_ELLIPSES: - if (plot) { - int x = offset * pic->mode->scaleFactor + ((pic->mode->scaleFactor - 1) >> 1); - int y = (yoffset / 320) * pic->mode->scaleFactor + ((pic->mode->scaleFactor - 1) >> 1); - int sizex = pic->mode->scaleFactor >> 1; - int sizey = pic->mode->scaleFactor >> 1; - - srand(randseed); - - x -= (int)((sizex * rand() * 1.0) / (RAND_MAX + 1.0)); - x += (int)((sizex * rand() * 1.0) / (RAND_MAX + 1.0)); - y -= (int)((sizey * rand() * 1.0) / (RAND_MAX + 1.0)); - y += (int)((sizey * rand() * 1.0) / (RAND_MAX + 1.0)); - sizex = (int)((sizex * rand() * 1.0) / (RAND_MAX + 1.0)); - sizey = (int)((sizey * rand() * 1.0) / (RAND_MAX + 1.0)); - - _gfxr_fill_ellipse(pic, buffer, line_width, x, y, pic->mode->scaleFactor >> 1, pic->mode->scaleFactor >> 1, - color, ELLIPSE_SOLID); - srand(time(NULL)); // Make sure we don't accidently forget to re-init the random number generator - } - break; - - case GFX_BRUSH_MODE_MORERANDOM: { - int mask = plot ? 7 : 1; - srand(randseed); - for (yc = 0; yc < pic->mode->scaleFactor; yc++) { - for (xc = 0; xc < pic->mode->scaleFactor; xc++) - if ((rand() & 7) < mask) - buffer[full_offset + xc] = color; - full_offset += line_width; - } - srand(time(NULL)); // Make sure we don't accidently forget to re-init the random number generator - } - break; - } -} - -#define PLOT_AUX_PATTERN_NO_RANDOM -1 - -static void _gfxr_plot_aux_pattern(gfxr_pic_t *pic, int x, int y, int size, int circle, int random, - int mask, int color, int priority, int control, gfx_brush_mode_t brush_mode, int map_nr) { - // Plots an appropriate pattern to the aux buffer and the control buffer, - // if mask & GFX_MASK_CONTROL - // random should be set to the random index, or -1 to disable - - // These circle offsets uniquely identify the circles used by Sierra: - const int circle_data[][8] = { - {0}, - {1, 0}, - {2, 2, 1}, - {3, 3, 2, 1}, - {4, 4, 4, 3, 1}, - {5, 5, 4, 4, 3, 1}, - {6, 6, 6, 5, 5, 4, 2}, - {7, 7, 7, 6, 6, 5, 4, 2} - }; - - // 'Random' fill patterns, provided by Carl Muckenhoupt: - const byte random_data[32] = { - 0x20, 0x94, 0x02, 0x24, 0x90, 0x82, 0xa4, 0xa2, 0x82, 0x09, 0x0a, 0x22, - 0x12, 0x10, 0x42, 0x14, 0x91, 0x4a, 0x91, 0x11, 0x08, 0x12, 0x25, 0x10, - 0x22, 0xa8, 0x14, 0x24, 0x00, 0x50, 0x24, 0x04 - }; - - // 'Random' fill offsets, provided by Carl Muckenhoupt: - const byte random_offset[128] = { - 0x00, 0x18, 0x30, 0xc4, 0xdc, 0x65, 0xeb, 0x48, - 0x60, 0xbd, 0x89, 0x05, 0x0a, 0xf4, 0x7d, 0x7d, - 0x85, 0xb0, 0x8e, 0x95, 0x1f, 0x22, 0x0d, 0xdf, - 0x2a, 0x78, 0xd5, 0x73, 0x1c, 0xb4, 0x40, 0xa1, - 0xb9, 0x3c, 0xca, 0x58, 0x92, 0x34, 0xcc, 0xce, - 0xd7, 0x42, 0x90, 0x0f, 0x8b, 0x7f, 0x32, 0xed, - 0x5c, 0x9d, 0xc8, 0x99, 0xad, 0x4e, 0x56, 0xa6, - 0xf7, 0x68, 0xb7, 0x25, 0x82, 0x37, 0x3a, 0x51, - 0x69, 0x26, 0x38, 0x52, 0x9e, 0x9a, 0x4f, 0xa7, - 0x43, 0x10, 0x80, 0xee, 0x3d, 0x59, 0x35, 0xcf, - 0x79, 0x74, 0xb5, 0xa2, 0xb1, 0x96, 0x23, 0xe0, - 0xbe, 0x05, 0xf5, 0x6e, 0x19, 0xc5, 0x66, 0x49, - 0xf0, 0xd1, 0x54, 0xa9, 0x70, 0x4b, 0xa4, 0xe2, - 0xe6, 0xe5, 0xab, 0xe4, 0xd2, 0xaa, 0x4c, 0xe3, - 0x06, 0x6f, 0xc6, 0x4a, 0xa4, 0x75, 0x97, 0xe1 - }; - - int offset = 0, width = 0; - int yoffset = (y - size) * 320; - int i; - int random_index = 0; - gfx_pixmap_t *map = NULL; - - switch (map_nr) { - case GFX_MASK_VISUAL: - map = pic->visual_map; - break; - case GFX_MASK_PRIORITY: - map = pic->priority_map; - break; - default: - map = pic->control_map; - break; - } - - if (random >= 0) - random_index = random_offset[random]; - - if (!circle) { - offset = -size; - width = (size << 1) + 2; - } - - for (i = -size; i <= size; i++) { - int j; - int height; - - if (circle) { - offset = circle_data[size][abs(i)]; - height = width = (offset << 1) + 1; - offset = -offset; - } else - height = width - 1; - - if (random == PLOT_AUX_PATTERN_NO_RANDOM) { - - if (mask & map_nr) - memset(map->index_data + yoffset + offset + x, control, width); - - if (map_nr == GFX_MASK_CONTROL) - for (j = x; j < x + width; j++) - pic->aux_map[yoffset + offset + j] |= mask; - - } else { // Semi-Random! - for (j = 0; j < height; j++) { - if (random_data[random_index >> 3] & (0x80 >> (random_index & 7))) { - // The 'seemingly' random decision - if (mask & GFX_MASK_CONTROL) - pic->control_map->index_data[yoffset + x + offset + j] = control; - - pic->aux_map[yoffset + x + offset + j] |= mask; - - if (mask & GFX_MASK_VISUAL) - _gfxr_auxplot_brush(pic, pic->visual_map->index_data, yoffset, x + offset + j, - 1, color, brush_mode, random_index + x); - - if (mask & GFX_MASK_PRIORITY) - _gfxr_auxplot_brush(pic, pic->priority_map->index_data, yoffset, x + offset + j, - 1, priority, brush_mode, random_index + x); - - } else { - if (mask & GFX_MASK_VISUAL) - _gfxr_auxplot_brush(pic, pic->visual_map->index_data, yoffset, x + offset + j, - 0, color, brush_mode, random_index + x); - - if (mask & GFX_MASK_PRIORITY) - _gfxr_auxplot_brush(pic, pic->priority_map->index_data, yoffset, x + offset + j, - 0, priority, brush_mode, random_index + x); - } - random_index = (random_index + 1) & 0xff; - } - } - yoffset += 320; - } -} - -static void _gfxr_draw_pattern(gfxr_pic_t *pic, int x, int y, int color, int priority, int control, int drawenable, - int pattern_code, int pattern_size, int pattern_nr, gfx_brush_mode_t brush_mode, int titlebar_size) { - int xsize = (pattern_size + 1) * pic->mode->scaleFactor - 1; - int ysize = (pattern_size + 1) * pic->mode->scaleFactor - 1; - int scaled_x, scaled_y; - rect_t boundaries; - int max_x = (pattern_code & PATTERN_FLAG_RECTANGLE) ? 318 : 319; // Rectangles' width is size+1 - - debugC(2, kDebugLevelSci0Pic, "Pattern at (%d,%d) size %d, rand=%d, code=%02x\n", x, y, pattern_size, pattern_nr, pattern_code); - - y += titlebar_size; - - if (x - pattern_size < 0) - x = pattern_size; - - if (y - pattern_size < titlebar_size) - y = titlebar_size + pattern_size; - - if (x + pattern_size > max_x) - x = max_x - pattern_size; - - if (y + pattern_size > 199) - y = 199 - pattern_size; - - scaled_x = x * pic->mode->scaleFactor + ((pic->mode->scaleFactor - 1) >> 1); - scaled_y = y * pic->mode->scaleFactor + ((pic->mode->scaleFactor - 1) >> 1); - - if (scaled_x < xsize) - scaled_x = xsize; - - if (scaled_y < ysize + titlebar_size * pic->mode->scaleFactor) - scaled_y = ysize + titlebar_size * pic->mode->scaleFactor; - - if (scaled_x > (320 * pic->mode->scaleFactor) - 1 - xsize) - scaled_x = (320 * pic->mode->scaleFactor) - 1 - xsize; - - if (scaled_y > (200 * pic->mode->scaleFactor) - 1 - ysize) - scaled_y = (200 * pic->mode->scaleFactor) - 1 - ysize; - - if (pattern_code & PATTERN_FLAG_RECTANGLE) { - // Rectangle - boundaries.x = scaled_x - xsize; - boundaries.y = scaled_y - ysize; - boundaries.width = ((xsize + 1) << 1) + 1; - boundaries.height = (ysize << 1) + 1; - - if (pattern_code & PATTERN_FLAG_USE_PATTERN) { - _gfxr_plot_aux_pattern(pic, x, y, pattern_size, 0, pattern_nr, drawenable, color, priority, - control, brush_mode, GFX_MASK_CONTROL); - } else { - _gfxr_plot_aux_pattern(pic, x, y, pattern_size, 0, PLOT_AUX_PATTERN_NO_RANDOM, drawenable, 0, 0, control, - GFX_BRUSH_MODE_SCALED, GFX_MASK_CONTROL); - - if (drawenable & GFX_MASK_VISUAL) - gfx_draw_box_pixmap_i(pic->visual_map, boundaries, color); - - if (drawenable & GFX_MASK_PRIORITY) - gfx_draw_box_pixmap_i(pic->priority_map, boundaries, priority); - } - - } else { - // Circle - - if (pattern_code & PATTERN_FLAG_USE_PATTERN) { - - _gfxr_plot_aux_pattern(pic, x, y, pattern_size, 1, pattern_nr, drawenable, color, priority, - control, brush_mode, GFX_MASK_CONTROL); - } else { - _gfxr_plot_aux_pattern(pic, x, y, pattern_size, 1, PLOT_AUX_PATTERN_NO_RANDOM, - drawenable, 0, 0, control, GFX_BRUSH_MODE_SCALED, GFX_MASK_CONTROL); - - if (pic->mode->scaleFactor == 1 && pic->mode->scaleFactor == 1) { - if (drawenable & GFX_MASK_VISUAL) - _gfxr_plot_aux_pattern(pic, x, y, pattern_size, 1, PLOT_AUX_PATTERN_NO_RANDOM, - drawenable, 0, 0, color, GFX_BRUSH_MODE_SCALED, GFX_MASK_VISUAL); - - if (drawenable & GFX_MASK_PRIORITY) - _gfxr_plot_aux_pattern(pic, x, y, pattern_size, 1, PLOT_AUX_PATTERN_NO_RANDOM, - drawenable, 0, 0, priority, GFX_BRUSH_MODE_SCALED, GFX_MASK_PRIORITY); - } else { - if (drawenable & GFX_MASK_VISUAL) - _gfxr_fill_ellipse(pic, pic->visual_map->index_data, 320 * pic->mode->scaleFactor, - scaled_x, scaled_y, xsize, ysize, color, ELLIPSE_SOLID); - - if (drawenable & GFX_MASK_PRIORITY) - _gfxr_fill_ellipse(pic, pic->priority_map->index_data, 320 * pic->mode->scaleFactor, - scaled_x, scaled_y, xsize, ysize, priority, ELLIPSE_SOLID); - } - } - } -} - -static void _gfxr_draw_subline(gfxr_pic_t *pic, int x, int y, int ex, int ey, int color, int priority, int drawenable) { - Common::Point start; - Common::Point end; - - start.x = x; - start.y = y; - end.x = ex; - end.y = ey; - - if (ex >= pic->visual_map->index_width || ey >= pic->visual_map->index_height || x < 0 || y < 0) { - warning("While drawing pic0: INVALID LINE %d,%d,%d,%d", - start.x, start.y, end.x, end.y); - return; - } - - if (drawenable & GFX_MASK_VISUAL) - gfx_draw_line_pixmap_i(pic->visual_map, start, end, color); - - if (drawenable & GFX_MASK_PRIORITY) - gfx_draw_line_pixmap_i(pic->priority_map, start, end, priority); - -} - -static void _gfxr_draw_line(gfxr_pic_t *pic, int x, int y, int ex, int ey, int color, - int priority, int control, int drawenable, int line_mode, int cmd, int titlebar_size) { - int scale_x = pic->mode->scaleFactor; - int scale_y = pic->mode->scaleFactor; - int xc, yc; - rect_t line; - int mask; - int partially_white = (drawenable & GFX_MASK_VISUAL) && (((color & 0xf0) == 0xf0) || ((color & 0x0f) == 0x0f)); - - line.x = x; - line.y = y; - line.width = ex - x; - line.height = ey - y; - - if (x > 319 || y > 199 || x < 0 || y < 0 || ex > 319 || ey > 199 || ex < 0 || ey < 0) { - warning("[GFX] While building pic: Attempt to draw line (%d,%d) to (%d,%d): cmd was %d", x, y, ex, ey, cmd); - return; - } - - y += titlebar_size; - ey += titlebar_size; - - if (drawenable & GFX_MASK_CONTROL) { - debugC(2, kDebugLevelSci0Pic, " ctl:%x", control); - gfx_draw_line_pixmap_i(pic->control_map, Common::Point(x, y), Common::Point(x + line.width, y + line.height), control); - } - - // Calculate everything that is changed to SOLID - mask = drawenable & (((color != 0xff) ? 1 : 0) | ((priority) ? 2 : 0) | ((control) ? 4 : 0)); - - if (mask) { - int mask2 = mask; - if (partially_white) - mask2 = mask &= ~GFX_MASK_VISUAL; - _gfxr_auxbuf_line_draw(pic, line, mask, mask2, titlebar_size); - } - - // Calculate everything that is changed to TRANSPARENT - mask = drawenable & (((color == 0xff) ? 1 : 0) | ((!priority) ? 2 : 0) | ((!control) ? 4 : 0)); - - if (mask) - _gfxr_auxbuf_line_clear(pic, line, ~mask, titlebar_size); - - x *= scale_x; - y *= scale_y; - ex *= scale_x; - ey *= scale_y; - - if (drawenable & GFX_MASK_VISUAL) - debugC(2, kDebugLevelSci0Pic, " col:%02x", color); - - if (drawenable & GFX_MASK_PRIORITY) - debugC(2, kDebugLevelSci0Pic, " pri:%x", priority); - - if (line_mode == GFX_LINE_MODE_FINE) { // Adjust lines to extend over the full visual - x = (x * ((320 + 1) * scale_x - 1)) / (320 * scale_x); - y = (y * ((200 + 1) * scale_y - 1)) / (200 * scale_y); - ex = (ex * ((320 + 1) * scale_x - 1)) / (320 * scale_x); - ey = (ey * ((200 + 1) * scale_y - 1)) / (200 * scale_y); - - _gfxr_draw_subline(pic, x, y, ex, ey, color, priority, drawenable); - } else { - if (x == ex && y == ey) { // Just one single point? - rect_t drawrect; - drawrect.x = x; - drawrect.y = y; - drawrect.width = scale_x; - drawrect.height = scale_y; - - if (drawenable & GFX_MASK_VISUAL) - gfx_draw_box_pixmap_i(pic->visual_map, drawrect, color); - - if (drawenable & GFX_MASK_PRIORITY) - gfx_draw_box_pixmap_i(pic->priority_map, drawrect, priority); - - } else { - int width = scale_x; - int height = scale_y; - int x_offset = 0; - int y_offset = 0; - - if (line_mode == GFX_LINE_MODE_FAST) { - width = (width + 1) >> 1; - height = (height + 1) >> 1; - x_offset = (width >> 1); - y_offset = (height >> 1); - } - - for (xc = 0; xc < width; xc++) - _gfxr_draw_subline(pic, x + xc + x_offset, y + y_offset, ex + xc + x_offset, ey + y_offset, - color, priority, drawenable); - - if (height > 0) - for (xc = 0; xc < width; xc++) - _gfxr_draw_subline(pic, x + xc + x_offset, y + height - 1 + y_offset, - ex + xc + x_offset, ey + height - 1 + y_offset, color, priority, drawenable); - - if (height > 1) { - for (yc = 1; yc < height - 1; yc++) - _gfxr_draw_subline(pic, x + x_offset, y + yc + y_offset, ex + x_offset, ey + yc + y_offset, - color, priority, drawenable); - if (width > 0) - for (yc = 1; yc < height - 1; yc++) - _gfxr_draw_subline(pic, x + width - 1 + x_offset, y + yc + y_offset, - ex + width - 1 + x_offset, ey + yc + y_offset, color, priority, drawenable); - } - } - } - - debugC(2, kDebugLevelSci0Pic, "\n"); -} - - -} // End of namespace Sci - -// Include again, but this time without support for scaling -#define FILL_FUNCTION _gfxr_fill_1 -#define FILL_FUNCTION_RECURSIVE _gfxr_fill_1_recursive -#define AUXBUF_FILL_HELPER _gfxr_auxbuf_fill_1_recursive -#define AUXBUF_FILL _gfxr_auxbuf_fill_1 -# include "picfill.cpp" -#undef AUXBUF_FILL -#undef AUXBUF_FILL_HELPER -#undef FILL_FUNCTION_RECURSIVE -#undef FILL_FUNCTION - -namespace Sci { - -#define GET_ABS_COORDS(x, y) \ - temp = *(resource + pos++); \ - x = *(resource + pos++); \ - y = *(resource + pos++); \ - x |= (temp & 0xf0) << 4; \ - y |= (temp & 0x0f) << 8; \ - if (flags & DRAWPIC1_FLAG_MIRRORED) \ - x = 319 - x; - -#define GET_REL_COORDS(x, y) \ - temp = *(resource + pos++); \ - if (temp & 0x80) \ - x -= ((temp >> 4) & 0x7) * (flags & DRAWPIC1_FLAG_MIRRORED ? -1 : 1); \ - else \ - x += (temp >> 4) * (flags & DRAWPIC1_FLAG_MIRRORED ? -1 : 1); \ - \ - if (temp & 0x08) \ - y -= (temp & 0x7); \ - else \ - y += (temp & 0x7); - -#define GET_MEDREL_COORDS(oldx, oldy) \ - temp = *(resource + pos++); \ - if (temp & 0x80) \ - y = oldy - (temp & 0x7f); \ - else \ - y = oldy + temp; \ - x = oldx + *((signed char *) resource + pos++) * (flags & DRAWPIC1_FLAG_MIRRORED ? -1 : 1); - - -static void check_and_remove_artifact(byte *dest, byte* srcp, int legalcolor, byte l, byte r, byte u, byte d) { - if (*dest == legalcolor) { - if (*srcp == legalcolor) - return; - if (l) { - if (srcp[-1] == legalcolor) - return; - if (u && srcp[-320 - 1] == legalcolor) - return; - if (d && srcp[320 - 1] == legalcolor) - return; - } - if (r) { - if (srcp[1] == legalcolor) - return; - if (u && srcp[-320 + 1] == legalcolor) - return; - if (d && srcp[320 + 1] == legalcolor) - return; - } - - if (u && srcp[-320] == legalcolor) - return; - - if (d && srcp[-320] == legalcolor) - return; - - *dest = *srcp; - } -} - -void gfxr_remove_artifacts_pic0(gfxr_pic_t *dest, gfxr_pic_t *src) { - int x_320, y_200; - int scaled_line_size = dest->mode->scaleFactor * 320; - int read_offset = 0; - - assert(src->mode->scaleFactor == 1); - - if (dest->mode->scaleFactor == 1) { - warning("[GFX] attempt to remove artifacts from unscaled pic"); - return; - } - - for (y_200 = 0; y_200 < 200; y_200++) { - for (x_320 = 0; x_320 < 320; x_320++) { - int write_offset = (y_200 * dest->mode->scaleFactor * scaled_line_size) + (x_320 * dest->mode->scaleFactor); - int sub_x, sub_y; - byte *src_visualp = &(src->visual_map->index_data[read_offset]); - byte *src_priorityp = &(src->priority_map->index_data[read_offset]); - - for (sub_y = 0; sub_y < dest->mode->scaleFactor; sub_y++) { - for (sub_x = 0; sub_x < dest->mode->scaleFactor; sub_x++) { - check_and_remove_artifact(dest->visual_map->index_data + write_offset, src_visualp, (int)0xff, - (byte)x_320, (byte)(x_320 < 319), (byte)(y_200 > 10), (byte)(y_200 < 199)); - check_and_remove_artifact(dest->priority_map->index_data + write_offset, src_priorityp, 0, - (byte)x_320, (byte)(x_320 < 319), (byte)(y_200 > 10), (byte)(y_200 < 199)); - ++write_offset; - } - write_offset += scaled_line_size - dest->mode->scaleFactor; - } - ++read_offset; - } - } - -} - -static void view_transparentize(gfx_pixmap_t *view, gfx_pixmap_t *background, int posx, int posy, int width, int height) { - int i, j; - byte *pic_index_data = background->index_data; - - // FIXME: this assumes view and background have the same palette... - // We may want to do a reverse mapping or similar to make it general, - // but this (hopefully...) suffices for the current uses of this function. - - for (i = 0;i < width;i++) - for (j = 0;j < height;j++) { - if (view->index_data[j*width+i] == view->color_key) { - view->index_data[j*width+i] = pic_index_data[(j+posy)*width+i+posx]; - } - } -} - -extern gfx_pixmap_t *gfxr_draw_cel0(int id, int loop, int cel, byte *resource, int size, gfxr_view_t *view, int mirrored); -extern void _gfx_crossblit_simple(byte *dest, byte *src, int dest_line_width, int src_line_width, int xl, int yl); - -void gfxr_draw_pic01(gfxr_pic_t *pic, int flags, int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, ViewType viewType, Palette *static_pal, Common::Rect portBounds) { - const int default_palette_table[GFXR_PIC0_PALETTE_SIZE] = { - 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, - 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0x88, - 0x88, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x88, - 0x88, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff, - 0x08, 0x91, 0x2a, 0x3b, 0x4c, 0x5d, 0x6e, 0x88 - }; - - const int default_priority_table[GFXR_PIC0_PALETTE_SIZE] = { - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 - }; - int palette[GFXR_PIC0_NUM_PALETTES][GFXR_PIC0_PALETTE_SIZE]; - int priority_table[GFXR_PIC0_PALETTE_SIZE]; - int drawenable = GFX_MASK_VISUAL | GFX_MASK_PRIORITY; - int priority = 0; - int color = 0; - int pattern_nr = 0; - int pattern_code = 0; - int pattern_size = 0; - int control = 0; - int pos = 0; - int x, y; - int oldx, oldy; - int pal = 0, index = 0; - int temp; - int line_mode = style->line_mode; - int titlebar_size = portBounds.top; - byte op, opx; - - // Initialize palette - for (int i = 0; i < GFXR_PIC0_NUM_PALETTES; i++) - memcpy(palette[i], default_palette_table, sizeof(int) * GFXR_PIC0_PALETTE_SIZE); - - memcpy(priority_table, default_priority_table, sizeof(int) * GFXR_PIC0_PALETTE_SIZE); - - // Main loop - while (pos < size) { - op = *(resource + pos++); - - switch (op) { - - case PIC_OP_SET_COLOR: - debugC(2, kDebugLevelSci0Pic, "Set color @%d\n", pos); - - if (viewType == kViewEga) { - pal = *(resource + pos++); - index = pal % GFXR_PIC0_PALETTE_SIZE; - pal /= GFXR_PIC0_PALETTE_SIZE; - - pal += default_palette; - - if (pal >= GFXR_PIC0_NUM_PALETTES) { - error("Attempt to access invalid palette %d", pal); - return; - } - - color = palette[pal][index]; - } else - color = *(resource + pos++); - debugC(2, kDebugLevelSci0Pic, " color <- %02x [%d/%d]\n", color, pal, index); - drawenable |= GFX_MASK_VISUAL; - goto end_op_loop; - - case PIC_OP_DISABLE_VISUAL: - debugC(2, kDebugLevelSci0Pic, "Disable visual @%d\n", pos); - drawenable &= ~GFX_MASK_VISUAL; - goto end_op_loop; - - case PIC_OP_SET_PRIORITY: - debugC(2, kDebugLevelSci0Pic, "Set priority @%d\n", pos); - - if (viewType == kViewEga) { - pal = *(resource + pos++); - index = pal % GFXR_PIC0_PALETTE_SIZE; - pal /= GFXR_PIC0_PALETTE_SIZE; // Ignore pal - - priority = priority_table[index]; - } else priority = *(resource + pos++); - - debugC(2, kDebugLevelSci0Pic, " priority <- %d [%d/%d]\n", priority, pal, index); - drawenable |= GFX_MASK_PRIORITY; - goto end_op_loop; - - case PIC_OP_DISABLE_PRIORITY: - debugC(2, kDebugLevelSci0Pic, "Disable priority @%d\n", pos); - drawenable &= ~GFX_MASK_PRIORITY; - goto end_op_loop; - - case PIC_OP_SHORT_PATTERNS: - debugC(2, kDebugLevelSci0Pic, "Short patterns @%d\n", pos); - if (pattern_code & PATTERN_FLAG_USE_PATTERN) { - pattern_nr = ((*(resource + pos++)) >> 1) & 0x7f; - debugC(2, kDebugLevelSci0Pic, " pattern_nr <- %d\n", pattern_nr); - } - - GET_ABS_COORDS(x, y); - - _gfxr_draw_pattern(pic, x, y, color, priority, control, drawenable, pattern_code, - pattern_size, pattern_nr, style->brush_mode, titlebar_size); - - while (*(resource + pos) < PIC_OP_FIRST) { - if (pattern_code & PATTERN_FLAG_USE_PATTERN) { - pattern_nr = ((*(resource + pos++)) >> 1) & 0x7f; - debugC(2, kDebugLevelSci0Pic, " pattern_nr <- %d\n", pattern_nr); - } - - GET_REL_COORDS(x, y); - - _gfxr_draw_pattern(pic, x, y, color, priority, control, drawenable, pattern_code, - pattern_size, pattern_nr, style->brush_mode, titlebar_size); - } - goto end_op_loop; - - case PIC_OP_MEDIUM_LINES: - debugC(2, kDebugLevelSci0Pic, "Medium lines @%d\n", pos); - GET_ABS_COORDS(oldx, oldy); - while (*(resource + pos) < PIC_OP_FIRST) { -#if 0 - fprintf(stderr, "Medium-line: [%04x] from %d,%d, data %02x %02x (dx=%d)", pos, oldx, oldy, - 0xff & resource[pos], 0xff & resource[pos+1], *((signed char *) resource + pos + 1)); -#endif - GET_MEDREL_COORDS(oldx, oldy); -#if 0 - fprintf(stderr, " to %d,%d\n", x, y); -#endif - _gfxr_draw_line(pic, oldx, oldy, x, y, color, priority, control, drawenable, line_mode, - PIC_OP_MEDIUM_LINES, titlebar_size); - oldx = x; - oldy = y; - } - goto end_op_loop; - - case PIC_OP_LONG_LINES: - debugC(2, kDebugLevelSci0Pic, "Long lines @%d\n", pos); - GET_ABS_COORDS(oldx, oldy); - while (*(resource + pos) < PIC_OP_FIRST) { - GET_ABS_COORDS(x, y); - _gfxr_draw_line(pic, oldx, oldy, x, y, color, priority, control, drawenable, line_mode, - PIC_OP_LONG_LINES, titlebar_size); - oldx = x; - oldy = y; - } - goto end_op_loop; - - case PIC_OP_SHORT_LINES: - debugC(2, kDebugLevelSci0Pic, "Short lines @%d\n", pos); - GET_ABS_COORDS(oldx, oldy); - x = oldx; - y = oldy; - while (*(resource + pos) < PIC_OP_FIRST) { - GET_REL_COORDS(x, y); - _gfxr_draw_line(pic, oldx, oldy, x, y, color, priority, control, drawenable, line_mode, - PIC_OP_SHORT_LINES, titlebar_size); - oldx = x; - oldy = y; - } - goto end_op_loop; - - case PIC_OP_FILL: - debugC(2, kDebugLevelSci0Pic, "Fill @%d\n", pos); - while (*(resource + pos) < PIC_OP_FIRST) { - GET_ABS_COORDS(x, y); - debugC(2, kDebugLevelSci0Pic, "Abs coords %d,%d\n", x, y); - _gfxr_fill_1(pic, x, y + titlebar_size, (flags & DRAWPIC01_FLAG_FILL_NORMALLY) ? - color : 0, priority, control, drawenable, titlebar_size); - } - goto end_op_loop; - - case PIC_OP_SET_PATTERN: - debugC(2, kDebugLevelSci0Pic, "Set pattern @%d\n", pos); - pattern_code = (*(resource + pos++)); - pattern_size = pattern_code & 0x07; - goto end_op_loop; - - case PIC_OP_ABSOLUTE_PATTERN: - debugC(2, kDebugLevelSci0Pic, "Absolute pattern @%d\n", pos); - while (*(resource + pos) < PIC_OP_FIRST) { - if (pattern_code & PATTERN_FLAG_USE_PATTERN) { - pattern_nr = ((*(resource + pos++)) >> 1) & 0x7f; - debugC(2, kDebugLevelSci0Pic, " pattern_nr <- %d\n", pattern_nr); - } - - GET_ABS_COORDS(x, y); - - _gfxr_draw_pattern(pic, x, y, color, priority, control, drawenable, pattern_code, - pattern_size, pattern_nr, style->brush_mode, titlebar_size); - } - goto end_op_loop; - - case PIC_OP_SET_CONTROL: - debugC(2, kDebugLevelSci0Pic, "Set control @%d\n", pos); - control = (*(resource + pos++)) & 0xf; - drawenable |= GFX_MASK_CONTROL; - goto end_op_loop; - - - case PIC_OP_DISABLE_CONTROL: - debugC(2, kDebugLevelSci0Pic, "Disable control @%d\n", pos); - drawenable &= ~GFX_MASK_CONTROL; - goto end_op_loop; - - - case PIC_OP_MEDIUM_PATTERNS: - debugC(2, kDebugLevelSci0Pic, "Medium patterns @%d\n", pos); - if (pattern_code & PATTERN_FLAG_USE_PATTERN) { - pattern_nr = ((*(resource + pos++)) >> 1) & 0x7f; - debugC(2, kDebugLevelSci0Pic, " pattern_nr <- %d\n", pattern_nr); - } - - GET_ABS_COORDS(oldx, oldy); - - _gfxr_draw_pattern(pic, oldx, oldy, color, priority, control, drawenable, pattern_code, - pattern_size, pattern_nr, style->brush_mode, titlebar_size); - - x = oldx; - y = oldy; - while (*(resource + pos) < PIC_OP_FIRST) { - if (pattern_code & PATTERN_FLAG_USE_PATTERN) { - pattern_nr = ((*(resource + pos++)) >> 1) & 0x7f; - debugC(2, kDebugLevelSci0Pic, " pattern_nr <- %d\n", pattern_nr); - } - - GET_MEDREL_COORDS(x, y); - - _gfxr_draw_pattern(pic, x, y, color, priority, control, drawenable, pattern_code, - pattern_size, pattern_nr, style->brush_mode, titlebar_size); - } - goto end_op_loop; - - case PIC_OP_OPX: - opx = *(resource + pos++); - debugC(2, kDebugLevelSci0Pic, "OPX: "); - - if (viewType != kViewEga) - opx += SCI1_OP_OFFSET; // See comment at the definition of SCI1_OP_OFFSET. - - switch (opx) { - - case PIC_SCI1_OPX_SET_PALETTE_ENTRIES: - warning("[GFX] SCI1 Set palette entried not implemented"); - goto end_op_loop; - - case PIC_SCI0_OPX_SET_PALETTE_ENTRIES: - debugC(2, kDebugLevelSci0Pic, "Set palette entry @%d\n", pos); - while (*(resource + pos) < PIC_OP_FIRST) { - index = *(resource + pos++); - pal = index / GFXR_PIC0_PALETTE_SIZE; - index %= GFXR_PIC0_PALETTE_SIZE; - - if (pal >= GFXR_PIC0_NUM_PALETTES) { - error("Attempt to write to invalid palette %d", pal); - return; - } - palette[pal][index] = *(resource + pos++); - } - goto end_op_loop; - - case PIC_SCI0_OPX_SET_PALETTE: - debugC(2, kDebugLevelSci0Pic, "Set palette @%d\n", pos); - pal = *(resource + pos++); - if (pal >= GFXR_PIC0_NUM_PALETTES) { - error("Attempt to write to invalid palette %d", pal); - return; - } - - debugC(2, kDebugLevelSci0Pic, " palette[%d] <- (", pal); - for (index = 0; index < GFXR_PIC0_PALETTE_SIZE; index++) { - palette[pal][index] = *(resource + pos++); - if (index > 0) - debugC(2, kDebugLevelSci0Pic, ","); - if (!(index & 0x7)) - debugC(2, kDebugLevelSci0Pic, "[%d]=", index); - debugC(2, kDebugLevelSci0Pic, "%02x", palette[pal][index]); - } - debugC(2, kDebugLevelSci0Pic, ")\n"); - goto end_op_loop; - - case PIC_SCI1_OPX_SET_PALETTE: - debugC(2, kDebugLevelSci0Pic, "Set palette @%d\n", pos); - if (pic->visual_map->palette) - pic->visual_map->palette->free(); - pic->visual_map->palette = gfxr_read_pal1(resid, - resource + pos, SCI1_PALETTE_SIZE); - pos += SCI1_PALETTE_SIZE; - goto end_op_loop; - - case PIC_SCI0_OPX_MONO0: - debugC(2, kDebugLevelSci0Pic, "Monochrome opx 0 @%d\n", pos); - pos += 41; - goto end_op_loop; - - case PIC_SCI0_OPX_MONO1: - case PIC_SCI0_OPX_MONO3: - ++pos; - debugC(2, kDebugLevelSci0Pic, "Monochrome opx %d @%d\n", opx, pos); - goto end_op_loop; - - case PIC_SCI0_OPX_MONO2: - case PIC_SCI0_OPX_MONO4: // Monochrome ops: Ignored by us - debugC(2, kDebugLevelSci0Pic, "Monochrome opx %d @%d\n", opx, pos); - goto end_op_loop; - - case PIC_SCI0_OPX_EMBEDDED_VIEW: - case PIC_SCI1_OPX_EMBEDDED_VIEW: { - int posx, posy; - int bytesize; - //byte *vismap = pic->visual_map->index_data; - int nodraw = 0; - - gfx_pixmap_t *view; - - debugC(2, kDebugLevelSci0Pic, "Embedded view @%d\n", pos); - - GET_ABS_COORDS(posx, posy); - bytesize = (*(resource + pos)) + (*(resource + pos + 1) << 8); - debugC(2, kDebugLevelSci0Pic, "(%d, %d)\n", posx, posy); - pos += 2; - if (!nodraw) { - if (viewType == kViewEga) - view = gfxr_draw_cel0(-1, -1, -1, resource + pos, bytesize, NULL, flags & DRAWPIC1_FLAG_MIRRORED); - else - view = gfxr_draw_cel1(-1, -1, -1, flags & DRAWPIC1_FLAG_MIRRORED, resource + pos, resource + pos, - bytesize, NULL, viewType); - } - pos += bytesize; - if (nodraw) - continue; - - if (flags & DRAWPIC1_FLAG_MIRRORED) - posx -= view->index_width - 1; - - debugC(2, kDebugLevelSci0Pic, "(%d, %d)-(%d, %d)\n", posx, posy, posx + view->index_width, posy + view->index_height); - - // we can only safely replace the palette if it's static - // *if it's not for some reason, we should die - - if (view->palette && view->palette->isShared() && (viewType == kViewEga)) { - warning("gfx_draw_pic0(): can't set a non-static palette for an embedded view"); - } - - // For SCI0, use special color mapping to copy the low - // nibble of the color index to the high nibble. - - if (viewType != kViewEga) { - if (view->palette) - view->palette->free(); - - if (viewType == kViewAmiga) { - pic->visual_map->palette = static_pal->getref(); - } else { - view->palette = pic->visual_map->palette->copy(); - } - } else - view->palette = embedded_view_pal->getref(); - - // Clip the view's height to fit within the screen buffer - // It can go off screen at some cases, e.g. in KQ6's intro - view->index_height = CLIP<int>(view->index_height, 0, portBounds.height()); - - // Set up mode structure for resizing the view - gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, view->palette); - - gfx_xlate_pixmap(view, mode); - gfx_free_mode(mode); - // When the mode is freed, the associated view - // palette is freed too, so set it to NULL - view->palette = NULL; - - if (flags & DRAWPIC01_FLAG_OVERLAID_PIC) - view_transparentize(view, pic->visual_map, posx, titlebar_size + posy, - view->index_width, view->index_height); - - _gfx_crossblit_simple(pic->visual_map->index_data + (titlebar_size * 320) + posy * 320 + posx, - view->index_data, pic->visual_map->index_width, view->index_width, - view->index_width, view->index_height); - - gfx_free_pixmap(view); - view = NULL; - } - goto end_op_loop; - - case PIC_SCI0_OPX_SET_PRIORITY_TABLE: - case PIC_SCI1_OPX_PRIORITY_TABLE_EXPLICIT: { - int *pri_table; - - debugC(2, kDebugLevelSci0Pic, "Explicit priority table @%d\n", pos); - if (!pic->priorityTable) { - pic->priorityTable = (int*)malloc(16 * sizeof(int)); - } else { - // This occurs in the title screen of Longbow, perhaps with the animated Robin sprite - warning("[GFX] pic->priorityTable is not NULL (%p); this only occurs with overlaid pics, otherwise it's a bug", (void *)pic->priorityTable); - } - - pri_table = pic->priorityTable; - - pri_table[0] = 0; - pri_table[15] = 190; - - for (int i = 1; i < 15; i++) - pri_table[i] = resource[pos++]; - } - goto end_op_loop; - - case PIC_SCI1_OPX_PRIORITY_TABLE_EQDIST: { - int first = (int16)READ_LE_UINT16(resource + pos); - int last = (int16)READ_LE_UINT16(resource + pos + 2); - int nr; - int *pri_table; - - if (!pic->priorityTable) { - pic->priorityTable = (int*)malloc(16 * sizeof(int)); - } else { - error("pic->priorityTable is not NULL (%p); possible memory corruption", (void *)pic->priorityTable); - } - - pri_table = pic->priorityTable; - - for (nr = 0; nr < 16; nr ++) - pri_table[nr] = SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr); - pos += 4; - goto end_op_loop; - } - - default: - warning("gfxr_draw_pic01(): Unknown opx %02x", opx); - return; - } - goto end_op_loop; - - case PIC_OP_TERMINATE: - debugC(2, kDebugLevelSci0Pic, "Terminator\n"); - //warning( "ARTIFACT REMOVAL CODE is commented out") - //_gfxr_vismap_remove_artifacts(); - return; - - default: - warning("[GFX] Unknown op %02x", op); - return; - } -end_op_loop: {} - } - - warning("[GFX] Reached end of pic resource %04x", resid); -} - -void gfxr_draw_pic11(gfxr_pic_t *pic, int flags, int default_palette, int size, byte *resource, - gfxr_pic0_params_t *style, int resid, Palette *static_pal, Common::Rect portBounds) { - int has_bitmap = READ_LE_UINT16(resource + 4); - int vector_data_ptr = READ_LE_UINT16(resource + 16); - int palette_data_ptr = READ_LE_UINT16(resource + 28); - int bitmap_data_ptr = READ_LE_UINT16(resource + 32); - gfx_pixmap_t *view = NULL; - int titlebar_size = portBounds.top; - - if (pic->visual_map->palette) pic->visual_map->palette->free(); - pic->visual_map->palette = gfxr_read_pal11(-1, resource + palette_data_ptr, 1284); - - if (has_bitmap) - view = gfxr_draw_cel1(-1, 0, 0, flags & DRAWPIC1_FLAG_MIRRORED, resource, resource + bitmap_data_ptr, size - bitmap_data_ptr, NULL, kViewVga11); - - if (view) { - view->palette = pic->visual_map->palette->getref(); - - // Set up mode structure for resizing the view - gfx_mode_t *mode = gfx_new_mode(pic->visual_map->index_width / 320, view->palette); - - gfx_xlate_pixmap(view, mode); - gfx_free_mode(mode); - - if (flags & DRAWPIC01_FLAG_OVERLAID_PIC) - view_transparentize(view, pic->visual_map, 0, 0, view->index_width, view->index_height); - - // Clip the view's height to fit within the screen buffer - // It can go off screen at some cases, e.g. in KQ6's intro - view->index_height = CLIP<int>(view->index_height, 0, portBounds.height()); - - _gfx_crossblit_simple(pic->visual_map->index_data + titlebar_size*view->index_width, - view->index_data, - pic->visual_map->index_width, view->index_width, - view->index_width, - view->index_height); - } else { - warning("[GFX] No view was contained in SCI1.1 pic resource"); - } - - gfxr_draw_pic01(pic, flags, default_palette, size - vector_data_ptr, resource + vector_data_ptr, style, resid, kViewVga11, static_pal, portBounds); -} - -void gfxr_dither_pic0(gfxr_pic_t *pic, DitherMode dmode) { - int xl = pic->visual_map->index_width; - int yl = pic->visual_map->index_height; - int xfrobc = 0, yfrobc = 0; - int selection = 0; - int x, y; - byte *data = pic->visual_map->index_data; - - if (dmode == kDither16Colors) - pic->visual_map->palette = gfx_sci0_image_pal[sci0_palette]->getref(); - - for (y = 0; y < yl; y++) { - for (x = 0; x < xl; x++) { - - switch (dmode) { - case kDither16Colors: - if (selection) - *data = (*data & 0xf0) >> 4; - else - *data = (*data & 0xf); - break; - - case kDither256Colors: - if (selection) - *data = ((*data & 0xf) << 4) | ((*data & 0xf0) >> 4); - break; - - case kDitherNone: - break; - - default: - error("Invalid dither mode %d", dmode); - return; - } - - if (dmode != kDither16Colors) { - // We permuted the 256 palette indices this way - // to make sure the first 16 colours in the palette - // are the regular EGA colours. - *data ^= *data << 4; - } - - ++data; - - if (++xfrobc == pic->mode->scaleFactor) { - selection = !selection; - xfrobc = 0; - } - } - - if (++yfrobc == pic->mode->scaleFactor) { - selection = !selection; - yfrobc = 0; - } - } -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/gui32/res_view.cpp b/engines/sci/gui32/res_view.cpp deleted file mode 100644 index ac50a71927..0000000000 --- a/engines/sci/gui32/res_view.cpp +++ /dev/null @@ -1,308 +0,0 @@ -/* ScummVM - Graphic Adventure Engine - * - * ScummVM is the legal property of its developers, whose names - * are too numerous to list here. Please refer to the COPYRIGHT - * file distributed with this source distribution. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * $URL$ - * $Id$ - * - */ - -#include "sci/sci.h" // for INCLUDE_OLDGFX -#ifdef INCLUDE_OLDGFX - -// SCI 1 view resource defrobnicator - -#include "common/endian.h" - -#include "sci/gfx/gfx_system.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" - -namespace Sci { - -#define V0_LOOPS_NR_OFFSET 0 -#define V0_FIRST_LOOP_OFFSET 8 -#define V0_MIRROR_LIST_OFFSET 2 - -#define V1_LOOPS_NR_OFFSET 0 -#define V1_MIRROR_MASK 2 -#define V1_PALETTE_OFFSET 6 -#define V1_FIRST_LOOP_OFFSET 8 - -#define V1_RLE 0x80 // run-length encode? -#define V1_RLE_BG 0x40 // background fill - -#define V2_HEADER_SIZE 0 -#define V2_BYTES_PER_LOOP 12 -#define V2_BYTES_PER_CEL 13 - -#define V2_COPY_OF_LOOP 2 -#define V2_CELS_NUM 4 -#define V2_LOOP_OFFSET 14 - -gfx_pixmap_t *gfxr_draw_cel0(int id, int loop, int cel, byte *resource, int size, gfxr_view_t *view, int mirrored) { - int xl = READ_LE_UINT16(resource); - int yl = READ_LE_UINT16(resource + 2); - int pixmap_size = xl * yl; - int xdisplace = ((signed char *)resource)[4]; - int ydisplace = ((signed char *)resource)[5]; - int color_key = resource[6]; - int pos = 7; - int writepos = mirrored ? xl : 0; - int line_base = 0; - gfx_pixmap_t *retval = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xl, yl, id, loop, cel)); - byte *dest = retval->index_data; - - retval->color_key = 255; // Pick something larger than 15 - - retval->xoffset = mirrored ? xdisplace : -xdisplace; - retval->yoffset = -ydisplace; - - retval->palette = (view && view->palette) ? view->palette->getref() : - gfx_sci0_image_pal[sci0_palette]->getref(); - - if (xl <= 0 || yl <= 0) { - gfx_free_pixmap(retval); - error("View %02x:(%d/%d) has invalid xl=%d or yl=%d", id, loop, cel, xl, yl); - return NULL; - } - - if (mirrored) { - while (yl && pos < size) { - int op = resource[pos++]; - int count = op >> 4; - int color = op & 0xf; - - if (color == color_key) - color = retval->color_key; - - while (count) { - int pixels = writepos - line_base; - - if (pixels > count) - pixels = count; - - writepos -= pixels; - memset(dest + writepos, color, pixels); - count -= pixels; - - if (writepos == line_base) { - yl--; - writepos += (xl << 1); - line_base += xl; - } - } - } - } else { - - while (writepos < pixmap_size && pos < size) { - int op = resource[pos++]; - int count = op >> 4; - int color = op & 0xf; - - if (color == color_key) - color = retval->color_key; - - if (writepos + count > pixmap_size) { - error("View %02x:(%d/%d) writes RLE data over its designated end at rel. offset 0x%04x", id, loop, cel, pos); - return NULL; - } - - memset(dest + writepos, color, count); - writepos += count; - } - } - - return retval; -} - -#define NEXT_LITERAL_BYTE(n) \ - if (literal_pos == runlength_pos) \ - runlength_pos += n; \ - literal_pos += n; - -static int decompress_sci_view(int id, int loop, int cel, byte *resource, byte *dest, int mirrored, int pixmap_size, int size, - int runlength_pos, int literal_pos, int xl, int yl, int color_key) { - int writepos = mirrored ? xl : 0; - int linebase = 0; - - // For some cels the RLE data ends at the last non-transparent pixel, - // so we initialize the whole pixmap to transparency first - memset(dest, color_key, pixmap_size); - - while ((mirrored ? linebase < pixmap_size : writepos < pixmap_size) && literal_pos < size && runlength_pos < size) { - int op = resource[runlength_pos]; - int bytes; - int readbytes = 0; - int color = 0; - - if (literal_pos == runlength_pos) - literal_pos += 1; - - runlength_pos += 1; - - if (op & V1_RLE) { - bytes = op & 0x3f; - op &= (V1_RLE | V1_RLE_BG); - readbytes = (op & V1_RLE_BG) ? 0 : 1; - } else { - readbytes = bytes = op & 0x3f; - op = 0; - } - - assert(runlength_pos + readbytes <= size); - - /* - if (writepos - bytes < 0) { - warning("[GFX] View %02x:(%d/%d) describes more bytes than needed: %d/%d bytes at rel. offset 0x%04x", - id, loop, cel, writepos - bytes, pixmap_size, pos - 1); - bytes = pixmap_size - writepos; - } - */ - - if (mirrored && op == V1_RLE) { - color = resource[literal_pos]; - NEXT_LITERAL_BYTE(1); - } - - assert(op || literal_pos + bytes <= size); - - if (!mirrored && (writepos + bytes > pixmap_size)) { - warning("[GFX] Writing out of bounds: %d bytes at %d > size %d", bytes, writepos, pixmap_size); - } - - if (mirrored) { - while (bytes--) { - writepos--; - if (op) { - *(dest + writepos) = (op & V1_RLE_BG) ? color_key : color; - } else { - *(dest + writepos) = *(resource + literal_pos); - NEXT_LITERAL_BYTE(1); - } - if (writepos == linebase) { - writepos += 2 * xl; - linebase += xl; - } - } - } else { - if (op) { - if (op & V1_RLE_BG) - memset(dest + writepos, color_key, bytes); - else { - color = resource[literal_pos]; - - NEXT_LITERAL_BYTE(1); - memset(dest + writepos, color, bytes); - } - } else { - memcpy(dest + writepos, resource + literal_pos, bytes); - NEXT_LITERAL_BYTE(bytes); - } - writepos += bytes; - } - } - - return 0; -} - -static int decompress_sci_view_amiga(int id, int loop, int cel, byte *resource, byte *dest, int mirrored, int pixmap_size, int size, - int pos, int xl, int yl, int color_key) { - int writepos = mirrored ? xl - 1 : 0; - - while (writepos < pixmap_size && pos < size) { - int op = resource[pos++]; - int bytes = (op & 0x07) ? op & 0x07 : op >> 3; - int color = (op & 0x07) ? op >> 3 : color_key; - - if (mirrored) { - while (bytes--) { - dest[writepos--] = color; - // If we've just written the first pixel of a line... - if (!((writepos + 1) % xl)) { - // Then move to the end of next line - writepos += 2 * xl; - - if (writepos >= pixmap_size && bytes) { - warning("[GFX] View %02x:(%d/%d) writing out of bounds", id, loop, cel); - break; - } - } - } - } else { - if (writepos + bytes > pixmap_size) { - warning("[GFX] View %02x:(%d/%d) describes more bytes than needed: %d/%d bytes at rel. offset 0x%04x", - id, loop, cel, writepos - bytes, pixmap_size, pos - 1); - bytes = pixmap_size - writepos; - } - memset(dest + writepos, color, bytes); - writepos += bytes; - } - } - - if (writepos < pixmap_size) { - warning("[GFX] View %02x:(%d/%d) not enough pixel data in view", id, loop, cel); - return 1; - } - - return 0; -} - -gfx_pixmap_t *gfxr_draw_cel1(int id, int loop, int cel, int mirrored, byte *resource, byte *cel_base, int size, gfxr_view_t *view, ViewType viewType) { - int xl = READ_LE_UINT16(cel_base); - int yl = READ_LE_UINT16(cel_base + 2); - int pixmap_size = xl * yl; - int xdisplace = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 4) : (int8) cel_base[4]; - int ydisplace = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 6) : cel_base[5]; - int runlength_offset = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 24) : 8; - int literal_offset = (viewType == kViewVga11) ? READ_LE_UINT16(cel_base + 28) : 8; - gfx_pixmap_t *retval = gfx_pixmap_alloc_index_data(gfx_new_pixmap(xl, yl, id, loop, cel)); - byte *dest = retval->index_data; - int decompress_failed; - - retval->color_key = cel_base[(viewType == kViewVga11) ? 8 : 6]; - retval->xoffset = mirrored ? xdisplace : -xdisplace; - retval->yoffset = -ydisplace; - // FIXME: In LSL5, it seems that the inventory has views without palettes (or we don't load palettes properly) - retval->palette = (view && view->palette) ? view->palette->getref() : NULL; - - if (xl <= 0 || yl <= 0) { - gfx_free_pixmap(retval); - error("View %02x:(%d/%d) has invalid xl=%d or yl=%d", id, loop, cel, xl, yl); - return NULL; - } - - if (viewType == kViewAmiga) - decompress_failed = decompress_sci_view_amiga(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, - xl, yl, retval->color_key); - else - decompress_failed = decompress_sci_view(id, loop, cel, resource, dest, mirrored, pixmap_size, size, runlength_offset, - literal_offset, xl, yl, retval->color_key); - - if (decompress_failed) { - gfx_free_pixmap(retval); - return NULL; - } - - return retval; -} - -} // End of namespace Sci - -#endif diff --git a/engines/sci/module.mk b/engines/sci/module.mk index 13d815e366..f0cbe16476 100644 --- a/engines/sci/module.mk +++ b/engines/sci/module.mk @@ -35,17 +35,6 @@ MODULE_OBJS := \ engine/static_selectors.o \ engine/state.o \ engine/vm.o \ - gfx/gfx_driver.o \ - gfx/gfx_gui.o \ - gfx/gfx_pixmap_scale.o \ - gfx/gfx_resmgr.o \ - gfx/gfx_resource.o \ - gfx/gfx_support.o \ - gfx/gfx_tools.o \ - gfx/gfx_widgets.o \ - gfx/menubar.o \ - gfx/operations.o \ - gfx/palette.o \ gui/gui.o \ gui/gui_animate.o \ gui/gui_controls.o \ @@ -61,12 +50,6 @@ MODULE_OBJS := \ gui/gui_transitions.o \ gui/gui_view.o \ gui/gui_windowmgr.o \ - gui32/gui32.o \ - gui32/font.o \ - gui32/res_font.o \ - gui32/res_pal.o \ - gui32/res_pic.o \ - gui32/res_view.o \ sfx/audio.o \ sfx/midiparser.o \ sfx/music.o \ diff --git a/engines/sci/sci.cpp b/engines/sci/sci.cpp index 6cb5c87640..a75fd27fb3 100644 --- a/engines/sci/sci.cpp +++ b/engines/sci/sci.cpp @@ -36,11 +36,6 @@ #include "sci/engine/state.h" #include "sci/engine/kernel.h" -#include "sci/gfx/operations.h" // fog GfxState -#ifdef INCLUDE_OLDGFX -#include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual -#include "sci/gui32/gui32.h" -#endif #include "sci/sfx/audio.h" #include "sci/sfx/soundcmd.h" #include "sci/gui/gui.h" @@ -48,9 +43,6 @@ #include "sci/gui/gui_cursor.h" #include "sci/gui/gui_screen.h" -#include "sci/gfx/gfx_resource.h" -#include "sci/gfx/gfx_tools.h" - namespace Sci { class GfxDriver; @@ -146,15 +138,7 @@ Common::Error SciEngine::run() { if (script_init_engine(_gamestate)) return Common::kUnknownError; -#ifdef INCLUDE_OLDGFX - #ifndef USE_OLDGFX - _gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor); // new - #else - _gamestate->_gui = new SciGui32(_gamestate, screen, palette, cursor); // old - #endif -#else _gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor); -#endif if (game_init(_gamestate)) { /* Initialize */ warning("Game initialization failed: Aborting..."); @@ -172,22 +156,10 @@ Common::Error SciEngine::run() { _gamestate->_soundCmd = new SoundCommandParser(_resMan, segMan, _audio, soundVersion); - GfxState gfx_state; - _gamestate->gfx_state = &gfx_state; - // Assign default values to the config manager, in case settings are missing ConfMan.registerDefault("undither", "true"); screen->unditherSetState(ConfMan.getBool("undither")); -#ifdef INCLUDE_OLDGFX - gfxop_init(&gfx_state, _resMan, screen, palette, 1); - - if (game_init_graphics(_gamestate)) { // Init interpreter graphics - warning("Game initialization failed: Error in GFX subsystem. Aborting..."); - return Common::kUnknownError; - } -#endif - #ifdef USE_OLD_MUSIC_FUNCTIONS if (game_init_sound(_gamestate, 0, soundVersion)) { warning("Game initialization failed: Error in sound subsystem. Aborting..."); @@ -213,10 +185,6 @@ Common::Error SciEngine::run() { delete screen; delete _gamestate; -#ifdef INCLUDE_OLDGFX - gfxop_exit(&gfx_state); -#endif - return Common::kNoError; } diff --git a/engines/sci/sci.h b/engines/sci/sci.h index 7bf4c69160..fd56d860c3 100644 --- a/engines/sci/sci.h +++ b/engines/sci/sci.h @@ -43,8 +43,6 @@ namespace Sci { // Uncomment this to include old graphics code //#define INCLUDE_OLDGFX -// Uncomment this if you want to use the old graphics code. INCLUDE_OLDGFX must be defined -//#define USE_OLDGFX // Uncomment this to use old music functions //#define USE_OLD_MUSIC_FUNCTIONS // Uncomment this to use old pathfinding code |