SCI: Removed the old graphics code

svn-id: r47005
This commit is contained in:
Filippos Karapetis 2010-01-05 00:54:53 +00:00
parent 86cad51d07
commit f66d5a7f53
48 changed files with 1 additions and 16409 deletions

View file

@ -35,11 +35,6 @@
#include "sci/engine/state.h" #include "sci/engine/state.h"
#include "sci/engine/gc.h" #include "sci/engine/gc.h"
#include "sci/engine/kernel_types.h" // for determine_reg_type #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 #ifdef USE_OLD_MUSIC_FUNCTIONS
#include "sci/sfx/iterator/songlib.h" // for SongLibrary #include "sci/sfx/iterator/songlib.h" // for SongLibrary
#include "sci/sfx/iterator/iterator.h" // for SCI_SONG_ITERATOR_TYPE_SCI0 #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("exit", WRAP_METHOD(Console, cmdExit));
DCmd_Register("list_saves", WRAP_METHOD(Console, cmdListSaves)); DCmd_Register("list_saves", WRAP_METHOD(Console, cmdListSaves));
// Screen // 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("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 // Graphics
DCmd_Register("draw_pic", WRAP_METHOD(Console, cmdDrawPic)); 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("undither", WRAP_METHOD(Console, cmdUndither));
DCmd_Register("play_video", WRAP_METHOD(Console, cmdPlayVideo)); 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 // Segments
DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable)); DCmd_Register("segment_table", WRAP_METHOD(Console, cmdPrintSegmentTable));
DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias DCmd_Register("segtable", WRAP_METHOD(Console, cmdPrintSegmentTable)); // alias
@ -330,33 +305,9 @@ bool Console::cmdHelp(int argc, const char **argv) {
DebugPrintf(" room - Gets or sets the current room number\n"); DebugPrintf(" room - Gets or sets the current room number\n");
DebugPrintf(" exit - Exits the game\n"); DebugPrintf(" exit - Exits the game\n");
DebugPrintf("\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("Graphics:\n");
DebugPrintf(" draw_pic - Draws a pic resource\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(" 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("\n");
DebugPrintf("Segments:\n"); DebugPrintf("Segments:\n");
DebugPrintf(" segment_table / segtable - Lists all segments\n"); DebugPrintf(" segment_table / segtable - Lists all segments\n");
@ -699,22 +650,6 @@ bool Console::cmdResourceTypes(int argc, const char **argv) {
return true; 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) { bool Console::cmdHexgrep(int argc, const char **argv) {
if (argc < 4) { if (argc < 4) {
DebugPrintf("Searches some resources for a particular sequence of bytes, represented as hexadecimal numbers.\n"); 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; 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) { bool Console::cmdSaveGame(int argc, const char **argv) {
if (argc != 2) { if (argc != 2) {
DebugPrintf("Saves the current game state to the hard disk\n"); 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) { bool Console::cmdDrawPic(int argc, const char **argv) {
if (argc < 2) { if (argc < 2) {
DebugPrintf("Draws a pic resource\n"); 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("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; 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->drawPicture(atoi(argv[1]), 100, false, false, false, 0);
_vm->_gamestate->_gui->animateShowPic(); _vm->_gamestate->_gui->animateShowPic();
#endif
return false; 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) { bool Console::cmdUndither(int argc, const char **argv) {
if (argc != 2) { if (argc != 2) {
DebugPrintf("Enable/disable undithering.\n"); 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) { bool Console::cmdParseGrammar(int argc, const char **argv) {
DebugPrintf("Parse grammar, in strict GNF:\n"); DebugPrintf("Parse grammar, in strict GNF:\n");
@ -1325,73 +1025,6 @@ bool Console::cmdParseGrammar(int argc, const char **argv) {
return true; 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) { bool Console::cmdPrintSegmentTable(int argc, const char **argv) {
DebugPrintf("Segment table:\n"); DebugPrintf("Segment table:\n");
@ -3145,219 +2778,4 @@ int Console::printObject(reg_t pos) {
return 0; 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 } // End of namespace Sci

View file

@ -81,29 +81,11 @@ private:
bool cmdExit(int argc, const char **argv); bool cmdExit(int argc, const char **argv);
bool cmdListSaves(int argc, const char **argv); bool cmdListSaves(int argc, const char **argv);
// Screen // 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 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 // Graphics
bool cmdDrawPic(int argc, const char **argv); 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 cmdUndither(int argc, const char **argv);
bool cmdPlayVideo(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 // Segments
bool cmdPrintSegmentTable(int argc, const char **argv); bool cmdPrintSegmentTable(int argc, const char **argv);
bool cmdSegmentInfo(int argc, const char **argv); bool cmdSegmentInfo(int argc, const char **argv);

View file

@ -35,10 +35,6 @@
#include "sci/engine/kernel_types.h" #include "sci/engine/kernel_types.h"
#include "sci/engine/message.h" #include "sci/engine/message.h"
#include "sci/gui/gui.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" #include "sci/sfx/music.h"
namespace Sci { namespace Sci {
@ -179,133 +175,6 @@ const char *convertSierraGameId(const char *gameId, uint32 *gameFlags, ResourceM
return strdup(sierraId.c_str()); 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 #ifdef USE_OLD_MUSIC_FUNCTIONS
int game_init_sound(EngineState *s, int sound_flags, SciVersion soundVersion) { int game_init_sound(EngineState *s, int sound_flags, SciVersion soundVersion) {
if (getSciVersion() > SCI_VERSION_0_LATE) if (getSciVersion() > SCI_VERSION_0_LATE)
@ -358,10 +227,6 @@ int script_init_engine(EngineState *s) {
debug(2, "Engine initialized"); debug(2, "Engine initialized");
#ifdef INCLUDE_OLDGFX
s->pic_priority_table = NULL;
#endif
return 0; return 0;
} }
@ -401,10 +266,6 @@ int game_init(EngineState *s) {
s->parserIsValid = false; // Invalidate parser s->parserIsValid = false; // Invalidate parser
s->parser_event = NULL_REG; // Invalidate parser event 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() // Initialize menu TODO: Actually this should be another init()
s->_gui->menuReset(); 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)); 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 #ifdef USE_OLD_MUSIC_FUNCTIONS
if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND) if (s->sfx_init_flags & SFX_STATE_FLAG_NOSOUND)
game_init_sound(s, 0, s->detectDoSoundType()); game_init_sound(s, 0, s->detectDoSoundType());
@ -472,12 +329,6 @@ int game_exit(EngineState *s) {
// TODO Free scripts here // TODO Free scripts here
#ifdef INCLUDE_OLDGFX
delete s->_menubar;
_free_graphics_input(s);
#endif
// Close all opened file handles // Close all opened file handles
s->_fileHandles.clear(); s->_fileHandles.clear();
s->_fileHandles.resize(5); s->_fileHandles.resize(5);

View file

@ -26,7 +26,6 @@
#include "sci/sci.h" #include "sci/sci.h"
#include "sci/engine/state.h" #include "sci/engine/state.h"
#include "sci/engine/kernel.h" #include "sci/engine/kernel.h"
#include "sci/gfx/operations.h"
#include "sci/console.h" #include "sci/console.h"
#include "sci/debug.h" // for g_debug_simulated_key #include "sci/debug.h" // for g_debug_simulated_key
#include "sci/event.h" #include "sci/event.h"

View file

@ -33,7 +33,6 @@
#include "sci/video/seq_decoder.h" #include "sci/video/seq_decoder.h"
#include "sci/engine/state.h" #include "sci/engine/state.h"
#include "sci/engine/kernel.h" #include "sci/engine/kernel.h"
#include "sci/gfx/operations.h"
#include "sci/gui/gui.h" #include "sci/gui/gui.h"
#include "sci/gui/gui_animate.h" #include "sci/gui/gui_animate.h"
#include "sci/gui/gui_cursor.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()); warning("Unsupported kGraph() operation %04x", argv[0].toSint16());
} }
#ifdef INCLUDE_OLDGFX
gfxop_update(s->gfx_state);
#endif
return s->r_acc; return s->r_acc;
} }

View file

@ -27,11 +27,6 @@
#include "sci/resource.h" #include "sci/resource.h"
#include "sci/engine/state.h" #include "sci/engine/state.h"
#include "sci/engine/kernel.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.h"
#include "sci/gui/gui_cursor.h" #include "sci/gui/gui_cursor.h"

View file

@ -168,10 +168,6 @@ reg_t kDisposeClone(EngineState *s, int argc, reg_t *argv) {
victim_obj->markAsFreed(); 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; return s->r_acc;
} }

View file

@ -31,10 +31,6 @@
#include "sci/sci.h" #include "sci/sci.h"
#include "sci/event.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/state.h"
#include "sci/engine/message.h" #include "sci/engine/message.h"
@ -217,39 +213,6 @@ void syncWithSerializer(Common::Serializer &s, reg_t &obj) {
sync_reg_t(s, 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) { void SegManager::saveLoadWithSerializer(Common::Serializer &s) {
s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be reserved_id s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be reserved_id
s.syncAsSint32LE(_exportsAreWide); s.syncAsSint32LE(_exportsAreWide);
@ -360,16 +323,6 @@ void EngineState::saveLoadWithSerializer(Common::Serializer &s) {
s.syncString(tmp); // OBSOLETE: Used to be game_version s.syncString(tmp); // OBSOLETE: Used to be game_version
s.skip(4, VER(9), VER(9)); // OBSOLETE: Used to be 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 // OBSOLETE: Saved menus. Skip all of the saved data
if (s.getVersion() < 14) { if (s.getVersion() < 14) {
int totalMenus = 0; 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_foreground
s.skip(4, VER(12), VER(12)); // obsolete: used to be status_bar_background 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(picPortRect.right);
s.syncAsSint16LE(picPortTop); s.syncAsSint16LE(picPortTop);
s.syncAsSint16LE(picPortLeft); s.syncAsSint16LE(picPortLeft);
#ifndef USE_OLDGFX
if (s.isLoading())
_gui->setPortPic(picPortRect, picPortTop, picPortLeft, true);
#endif
} }
sync_SegManagerPtr(s, resMan, _segMan); 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 #ifdef USE_OLD_MUSIC_FUNCTIONS
static void reconstruct_sounds(EngineState *s) { static void reconstruct_sounds(EngineState *s) {
@ -912,7 +856,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
retval->_event = new SciEvent(); retval->_event = new SciEvent();
// Copy some old data // Copy some old data
retval->gfx_state = s->gfx_state;
retval->_soundCmd = s->_soundCmd; retval->_soundCmd = s->_soundCmd;
retval->saveLoadWithSerializer(ser); // FIXME: Error handling? retval->saveLoadWithSerializer(ser); // FIXME: Error handling?
@ -925,10 +868,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
retval->execution_stack_base = 0; retval->execution_stack_base = 0;
// Now copy all current state information // Now copy all current state information
#ifdef INCLUDE_OLDGFX
// Graphics and input state:
retval->old_screen = 0;
#endif
#ifdef USE_OLD_MUSIC_FUNCTIONS #ifdef USE_OLD_MUSIC_FUNCTIONS
temp = retval->_sound._songlib; temp = retval->_sound._songlib;
@ -947,9 +886,6 @@ EngineState *gamestate_restore(EngineState *s, Common::SeekableReadStream *fh) {
retval->gc_countdown = GC_INTERVAL - 1; retval->gc_countdown = GC_INTERVAL - 1;
retval->sys_strings_segment = retval->_segMan->findSegmentByType(SEG_TYPE_SYS_STRINGS); 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); 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: // Time state:
retval->last_wait_time = g_system->getMillis(); 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->bp_list = s->bp_list;
retval->successor = NULL; 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; retval->_gameId = s->_gameId;
#ifdef USE_OLD_MUSIC_FUNCTIONS #ifdef USE_OLD_MUSIC_FUNCTIONS

View file

@ -35,37 +35,10 @@ namespace Sci {
EngineState::EngineState(ResourceManager *res, Kernel *kernel, Vocabulary *voc, SegManager *segMan, SciGui *gui, AudioPlayer *audio) 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) { : resMan(res), _kernel(kernel), _voc(voc), _segMan(segMan), _gui(gui), _audio(audio), _dirseeker(this) {
gfx_state = 0;
sfx_init_flags = 0; sfx_init_flags = 0;
restarting_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; last_wait_time = 0;
_fileHandles.resize(5); _fileHandles.resize(5);

View file

@ -41,7 +41,6 @@ namespace Common {
#include "sci/engine/kernel.h" // for kfunct_sig_pair_t #include "sci/engine/kernel.h" // for kfunct_sig_pair_t
#include "sci/engine/script.h" #include "sci/engine/script.h"
#include "sci/engine/seg_manager.h" #include "sci/engine/seg_manager.h"
#include "sci/gfx/gfx_system.h"
#include "sci/sfx/audio.h" #include "sci/sfx/audio.h"
#ifdef USE_OLD_MUSIC_FUNCTIONS #ifdef USE_OLD_MUSIC_FUNCTIONS
#include "sci/sfx/iterator/core.h" #include "sci/sfx/iterator/core.h"
@ -148,8 +147,6 @@ public:
SciEvent *_event; // Event handling SciEvent *_event; // Event handling
GfxState *gfx_state; /**< Graphics state and driver */
AudioPlayer *_audio; AudioPlayer *_audio;
#ifdef USE_OLD_MUSIC_FUNCTIONS #ifdef USE_OLD_MUSIC_FUNCTIONS
SfxState _sound; /**< sound subsystem */ SfxState _sound; /**< sound subsystem */
@ -159,35 +156,6 @@ public:
byte restarting_flags; /**< Flags used for restarting */ 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 game_start_time; /**< The time at which the interpreter was started */
uint32 last_wait_time; /**< The last time the game invoked Wait() */ uint32 last_wait_time; /**< The last time the game invoked Wait() */
@ -310,24 +278,6 @@ private:
bool _usesCdTrack; 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 } // End of namespace Sci
#endif // SCI_INCLUDE_ENGINE_H #endif // SCI_INCLUDE_ENGINE_H

View file

@ -480,17 +480,6 @@ const char *convertSierraGameId(const char *gameId, uint32 *gameFlags, ResourceM
*/ */
int game_init(EngineState *s); 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 #ifdef USE_OLD_MUSIC_FUNCTIONS
/** /**
* Initializes the sound part of an SCI game * Initializes the sound part of an SCI game

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -43,8 +43,6 @@
#include "sci/gui/gui_transitions.h" #include "sci/gui/gui_transitions.h"
#include "sci/gui/gui_view.h" #include "sci/gui/gui_view.h"
#include "sci/gfx/operations.h"
namespace Sci { namespace Sci {
// for debug purposes // for debug purposes
@ -90,7 +88,6 @@ void SciGui::init(bool usesOldGfxFunctions) {
_gfx->init(_text); _gfx->init(_text);
_windowMgr->init(_s->_gameId); _windowMgr->init(_s->_gameId);
_menu->init(_s->gfx_state);
initPriorityBands(); initPriorityBands();
} }
@ -329,7 +326,6 @@ void SciGui::drawMenuBar(bool clear) {
void SciGui::menuReset() { void SciGui::menuReset() {
delete _menu; delete _menu;
_menu = new SciGuiMenu(_s->_event, _s->_segMan, _gfx, _text, _screen, _cursor); _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) { void SciGui::menuAdd(Common::String title, Common::String content, reg_t contentVmPtr) {

View file

@ -30,8 +30,6 @@
#include "sci/sci.h" #include "sci/sci.h"
#include "sci/event.h" #include "sci/event.h"
#include "sci/engine/state.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_helpers.h"
#include "sci/gui/gui_gfx.h" #include "sci/gui/gui_gfx.h"
#include "sci/gui/gui_cursor.h" #include "sci/gui/gui_cursor.h"
@ -60,10 +58,6 @@ SciGuiMenu::~SciGuiMenu() {
// TODO: deallocate _list and _itemList // TODO: deallocate _list and _itemList
} }
void SciGuiMenu::init(GfxState *gfxstate) {
_gfxstate = gfxstate;
}
void SciGuiMenu::add(Common::String title, Common::String content, reg_t contentVmPtr) { void SciGuiMenu::add(Common::String title, Common::String content, reg_t contentVmPtr) {
GuiMenuEntry *menuEntry; GuiMenuEntry *menuEntry;
uint16 itemCount = 0; uint16 itemCount = 0;

View file

@ -81,7 +81,6 @@ public:
SciGuiMenu(SciEvent *event, SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor); SciGuiMenu(SciEvent *event, SegManager *segMan, SciGuiGfx *gfx, SciGuiText *text, SciGuiScreen *screen, SciGuiCursor *cursor);
~SciGuiMenu(); ~SciGuiMenu();
void init(GfxState *gfxstate);
void reset(); void reset();
void add(Common::String title, Common::String content, reg_t contentVmPtr); void add(Common::String title, Common::String content, reg_t contentVmPtr);
void setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value); void setAttribute(uint16 menuId, uint16 itemId, uint16 attributeId, reg_t value);
@ -100,7 +99,6 @@ private:
GuiMenuItemEntry *interactiveGetItem(uint16 menuId, uint16 itemId, bool menuChanged); GuiMenuItemEntry *interactiveGetItem(uint16 menuId, uint16 itemId, bool menuChanged);
SciEvent *_event; SciEvent *_event;
GfxState *_gfxstate;
SegManager *_segMan; SegManager *_segMan;
SciGuiGfx *_gfx; SciGuiGfx *_gfx;
SciGuiText *_text; SciGuiText *_text;

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

File diff suppressed because it is too large Load diff

View file

@ -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

View file

@ -35,17 +35,6 @@ MODULE_OBJS := \
engine/static_selectors.o \ engine/static_selectors.o \
engine/state.o \ engine/state.o \
engine/vm.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.o \
gui/gui_animate.o \ gui/gui_animate.o \
gui/gui_controls.o \ gui/gui_controls.o \
@ -61,12 +50,6 @@ MODULE_OBJS := \
gui/gui_transitions.o \ gui/gui_transitions.o \
gui/gui_view.o \ gui/gui_view.o \
gui/gui_windowmgr.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/audio.o \
sfx/midiparser.o \ sfx/midiparser.o \
sfx/music.o \ sfx/music.o \

View file

@ -36,11 +36,6 @@
#include "sci/engine/state.h" #include "sci/engine/state.h"
#include "sci/engine/kernel.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/audio.h"
#include "sci/sfx/soundcmd.h" #include "sci/sfx/soundcmd.h"
#include "sci/gui/gui.h" #include "sci/gui/gui.h"
@ -48,9 +43,6 @@
#include "sci/gui/gui_cursor.h" #include "sci/gui/gui_cursor.h"
#include "sci/gui/gui_screen.h" #include "sci/gui/gui_screen.h"
#include "sci/gfx/gfx_resource.h"
#include "sci/gfx/gfx_tools.h"
namespace Sci { namespace Sci {
class GfxDriver; class GfxDriver;
@ -146,15 +138,7 @@ Common::Error SciEngine::run() {
if (script_init_engine(_gamestate)) if (script_init_engine(_gamestate))
return Common::kUnknownError; 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); _gamestate->_gui = new SciGui(_gamestate, screen, palette, cursor);
#endif
if (game_init(_gamestate)) { /* Initialize */ if (game_init(_gamestate)) { /* Initialize */
warning("Game initialization failed: Aborting..."); warning("Game initialization failed: Aborting...");
@ -172,22 +156,10 @@ Common::Error SciEngine::run() {
_gamestate->_soundCmd = new SoundCommandParser(_resMan, segMan, _audio, soundVersion); _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 // Assign default values to the config manager, in case settings are missing
ConfMan.registerDefault("undither", "true"); ConfMan.registerDefault("undither", "true");
screen->unditherSetState(ConfMan.getBool("undither")); 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 #ifdef USE_OLD_MUSIC_FUNCTIONS
if (game_init_sound(_gamestate, 0, soundVersion)) { if (game_init_sound(_gamestate, 0, soundVersion)) {
warning("Game initialization failed: Error in sound subsystem. Aborting..."); warning("Game initialization failed: Error in sound subsystem. Aborting...");
@ -213,10 +185,6 @@ Common::Error SciEngine::run() {
delete screen; delete screen;
delete _gamestate; delete _gamestate;
#ifdef INCLUDE_OLDGFX
gfxop_exit(&gfx_state);
#endif
return Common::kNoError; return Common::kNoError;
} }

View file

@ -43,8 +43,6 @@ namespace Sci {
// Uncomment this to include old graphics code // Uncomment this to include old graphics code
//#define INCLUDE_OLDGFX //#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 // Uncomment this to use old music functions
//#define USE_OLD_MUSIC_FUNCTIONS //#define USE_OLD_MUSIC_FUNCTIONS
// Uncomment this to use old pathfinding code // Uncomment this to use old pathfinding code