[Scummvm-cvs-logs] SF.net SVN: scummvm:[44565] scummvm/trunk
wjpalenstijn at users.sourceforge.net
wjpalenstijn at users.sourceforge.net
Sat Oct 3 22:49:26 CEST 2009
Revision: 44565
http://scummvm.svn.sourceforge.net/scummvm/?rev=44565&view=rev
Author: wjpalenstijn
Date: 2009-10-03 20:49:18 +0000 (Sat, 03 Oct 2009)
Log Message:
-----------
SCI: Merge new GUI code written by m_kiewitz.
This is a major rewrite of the graphics code. A slightly adapted
version of the old code is still available and currently the default.
The new code is selectable in sci.cpp, but is not yet finished.
Modified Paths:
--------------
scummvm/trunk/dists/msvc8/sci.vcproj
scummvm/trunk/dists/msvc9/sci.vcproj
scummvm/trunk/engines/sci/engine/kernel.cpp
scummvm/trunk/engines/sci/engine/kernel.h
scummvm/trunk/engines/sci/engine/kevent.cpp
scummvm/trunk/engines/sci/engine/kgraphics.cpp
scummvm/trunk/engines/sci/engine/kmisc.cpp
scummvm/trunk/engines/sci/engine/state.h
scummvm/trunk/engines/sci/gfx/gfx_driver.cpp
scummvm/trunk/engines/sci/gfx/gfx_driver.h
scummvm/trunk/engines/sci/gfx/res_view.cpp
scummvm/trunk/engines/sci/module.mk
scummvm/trunk/engines/sci/sci.cpp
scummvm/trunk/engines/sci/sci.h
Added Paths:
-----------
scummvm/trunk/engines/sci/gui/
scummvm/trunk/engines/sci/gui/gui.cpp
scummvm/trunk/engines/sci/gui/gui.h
scummvm/trunk/engines/sci/gui/gui_dbllist.cpp
scummvm/trunk/engines/sci/gui/gui_dbllist.h
scummvm/trunk/engines/sci/gui/gui_font.cpp
scummvm/trunk/engines/sci/gui/gui_font.h
scummvm/trunk/engines/sci/gui/gui_gfx.cpp
scummvm/trunk/engines/sci/gui/gui_gfx.h
scummvm/trunk/engines/sci/gui/gui_helpers.h
scummvm/trunk/engines/sci/gui/gui_memmgr.cpp
scummvm/trunk/engines/sci/gui/gui_memmgr.h
scummvm/trunk/engines/sci/gui/gui_picture.cpp
scummvm/trunk/engines/sci/gui/gui_picture.h
scummvm/trunk/engines/sci/gui/gui_screen.cpp
scummvm/trunk/engines/sci/gui/gui_screen.h
scummvm/trunk/engines/sci/gui/gui_view.cpp
scummvm/trunk/engines/sci/gui/gui_view.h
scummvm/trunk/engines/sci/gui/gui_windowmgr.cpp
scummvm/trunk/engines/sci/gui/gui_windowmgr.h
scummvm/trunk/engines/sci/gui32/
scummvm/trunk/engines/sci/gui32/gui32.cpp
scummvm/trunk/engines/sci/gui32/gui32.h
Modified: scummvm/trunk/dists/msvc8/sci.vcproj
===================================================================
--- scummvm/trunk/dists/msvc8/sci.vcproj 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/dists/msvc8/sci.vcproj 2009-10-03 20:49:18 UTC (rev 44565)
@@ -92,6 +92,29 @@
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.cpp" />
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.h" />
</Filter>
+ <Filter Name="gui">
+ <File RelativePath="..\..\engines\sci\gui\gui.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_dbllist.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_dbllist.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_font.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_font.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_gfx.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_helpers.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_memmgr.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_memmgr.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_picture.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_screen.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_screen.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_view.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_view.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_windowmgr.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_windowmgr.h" />
+ <File RelativePath="..\..\engines\sci\gui32\gui32.h" />
+ <File RelativePath="..\..\engines\sci\gui32\gui32.cpp" />
+ </Filter>
<Filter Name="sfx">
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
<File RelativePath="..\..\engines\sci\sfx\core.h" />
Modified: scummvm/trunk/dists/msvc9/sci.vcproj
===================================================================
--- scummvm/trunk/dists/msvc9/sci.vcproj 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/dists/msvc9/sci.vcproj 2009-10-03 20:49:18 UTC (rev 44565)
@@ -93,6 +93,29 @@
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.cpp" />
<File RelativePath="..\..\engines\sci\gfx\seq_decoder.h" />
</Filter>
+ <Filter Name="gui">
+ <File RelativePath="..\..\engines\sci\gui\gui.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_dbllist.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_dbllist.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_font.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_font.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_gfx.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_gfx.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_helpers.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_memmgr.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_memmgr.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_picture.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_picture.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_screen.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_screen.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_view.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_view.h" />
+ <File RelativePath="..\..\engines\sci\gui\gui_windowmgr.cpp" />
+ <File RelativePath="..\..\engines\sci\gui\gui_windowmgr.h" />
+ <File RelativePath="..\..\engines\sci\gui32\gui32.h" />
+ <File RelativePath="..\..\engines\sci\gui32\gui32.cpp" />
+ </Filter>
<Filter Name="sfx">
<File RelativePath="..\..\engines\sci\sfx\core.cpp" />
<File RelativePath="..\..\engines\sci\sfx\core.h" />
Modified: scummvm/trunk/engines/sci/engine/kernel.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.cpp 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/engine/kernel.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -332,18 +332,18 @@
DEFUN("ShowMovie", kShowMovie, "..*"),
DEFUN("SetVideoMode", kSetVideoMode, "i"),
DEFUN("Platform", kPlatform, "i*"),
- DEFUN("PalVary", kPalVary, "ii*"),
+ DEFUN("TextColors", kTextColors, ".*"),
+ DEFUN("TextFonts", kTextFonts, ".*"),
#if 0
// Stub functions
+ DEFUN("PalVary", kPalVary, "ii*"),
DEFUN("ShiftScreen", kShiftScreen, ".*"),
DEFUN("MemorySegment", kMemorySegment, ".*"),
DEFUN("ListOps", kListOps, ".*"),
DEFUN("ATan", kATan, ".*"),
DEFUN("MergePoly", kMergePoly, ".*"),
DEFUN("AssertPalette", kAssertPalette, ".*"),
- DEFUN("TextColors", kTextColors, ".*"),
- DEFUN("TextFonts", kTextFonts, ".*"),
DEFUN("Record", kRecord, ".*"),
DEFUN("PlayBack", kPlayBack, ".*"),
DEFUN("DbugStr", kDbugStr, ".*"),
Modified: scummvm/trunk/engines/sci/engine/kernel.h
===================================================================
--- scummvm/trunk/engines/sci/engine/kernel.h 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/engine/kernel.h 2009-10-03 20:49:18 UTC (rev 44565)
@@ -454,7 +454,8 @@
reg_t kSetVideoMode(EngineState *s, int argc, reg_t *argv);
reg_t kStrSplit(EngineState *s, int argc, reg_t *argv);
reg_t kPlatform(EngineState *s, int argc, reg_t *argv);
-reg_t kPalVary(EngineState *s, int argc, reg_t *argv);
+reg_t kTextColors(EngineState *s, int argc, reg_t *argv);
+reg_t kTextFonts(EngineState *s, int argc, reg_t *argv);
} // End of namespace Sci
Modified: scummvm/trunk/engines/sci/engine/kevent.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kevent.cpp 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/engine/kevent.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -206,11 +206,13 @@
SegManager *segMan = s->segMan;
if (obj.segment) {
- int x = GET_SEL32V(obj, x);
- int y = GET_SEL32V(obj, y);
+ int16 x = GET_SEL32V(obj, x);
+ int16 y = GET_SEL32V(obj, y);
- PUT_SEL32V(obj, x, x - s->port->zone.x);
- PUT_SEL32V(obj, y, y - s->port->zone.y);
+ s->gui->globalToLocal(&x, &y);
+
+ PUT_SEL32V(obj, x, x);
+ PUT_SEL32V(obj, y, y);
}
return s->r_acc;
@@ -222,11 +224,13 @@
SegManager *segMan = s->segMan;
if (obj.segment) {
- int x = GET_SEL32V(obj, x);
- int y = GET_SEL32V(obj, y);
+ int16 x = GET_SEL32V(obj, x);
+ int16 y = GET_SEL32V(obj, y);
- PUT_SEL32V(obj, x, x + s->port->zone.x);
- PUT_SEL32V(obj, y, y + s->port->zone.y);
+ s->gui->localToGlobal(&x, &y);
+
+ PUT_SEL32V(obj, x, x);
+ PUT_SEL32V(obj, y, y);
}
return s->r_acc;
Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -105,7 +105,8 @@
return value;
}
-static void assert_primary_widget_lists(EngineState *s) {
+// was static
+void assert_primary_widget_lists(EngineState *s) {
if (!s->dyn_views) {
rect_t bounds = s->picture_port->_bounds;
@@ -123,7 +124,8 @@
}
}
-static void reparentize_primary_widget_lists(EngineState *s, GfxPort *newport) {
+// static
+void reparentize_primary_widget_lists(EngineState *s, GfxPort *newport) {
if (!newport)
newport = s->picture_port;
@@ -264,24 +266,6 @@
}
}
-static gfx_color_t graph_map_color(EngineState *s, int color, int priority, int control) {
- gfx_color_t retval;
-
- if (!s->resMan->isVGA()) {
- retval = s->ega_colors[(color >=0 && color < 16)? color : 0];
- gfxop_set_color(s->gfx_state, &retval, (color < 0) ? -1 : retval.visual.r, retval.visual.g, retval.visual.b,
- (color == -1) ? 255 : 0, priority, control);
- } else {
- retval.visual = get_pic_color(s, color);
- retval.alpha = 0;
- retval.priority = priority;
- retval.control = control;
- retval.mask = GFX_MASK_VISUAL | ((priority >= 0) ? GFX_MASK_PRIORITY : 0) | ((control >= 0) ? GFX_MASK_CONTROL : 0);
- };
-
- return retval;
-}
-
static reg_t kSetCursorSci0(EngineState *s, int argc, reg_t *argv) {
int16 cursor = argv[0].toSint16();
@@ -353,27 +337,8 @@
}
reg_t kMoveCursor(EngineState *s, int argc, reg_t *argv) {
- Common::Point newPos;
-
- newPos = s->gfx_state->pointer_pos;
-
- if (argc == 1) {
- // Case ignored on IBM PC
- } else {
- newPos.x = argv[0].toSint16() + s->port->zone.x;
- newPos.y = argv[1].toSint16() + s->port->zone.y;
-
- if (newPos.x > s->port->zone.x + s->port->zone.width)
- newPos.x = s->port->zone.x + s->port->zone.width;
- if (newPos.y > s->port->zone.y + s->port->zone.height)
- newPos.y = s->port->zone.y + s->port->zone.height;
-
- if (newPos.x < 0) newPos.x = 0;
- if (newPos.y < 0) newPos.y = 0;
- }
-
- gfxop_set_pointer_position(s->gfx_state, newPos);
-
+ if (argc == 2)
+ s->gui->moveCursor(argv[0].toSint16(), argv[1].toSint16());
return s->r_acc;
}
@@ -439,117 +404,74 @@
#endif
}
-void _k_graph_rebuild_port_with_color(EngineState *s, gfx_color_t newbgcolor) {
- GfxPort *port = s->port;
- GfxPort *newport;
+reg_t kGraph(EngineState *s, int argc, reg_t *argv) {
+ int rectLeft = 0, rectTop = 0, rectRight = 0, rectBottom = 0;
+ uint16 flags;
+ int16 priority, control, color, colorMask;
- newport = sciw_new_window(s, port->zone, port->_font, port->_color, newbgcolor,
- s->titlebar_port->_font, s->ega_colors[15], s->ega_colors[8],
- port->_title_text.c_str(), port->port_flags & ~kWindowTransparent);
-
- if (s->dyn_views) {
- int found = 0;
- GfxContainer *parent = s->dyn_views->_parent;
-
- while (parent && !(found |= (parent == port)))
- parent = parent->_parent;
-
- s->dyn_views = NULL;
+ Common::Rect rect;
+ if (argc>=5) {
+ rectLeft = argv[2].toSint16(); rectTop = argv[1].toSint16();
+ rectRight = argv[4].toSint16(); rectBottom = argv[3].toSint16();
+ // Fixup data, so that a valid rectangle is formed
+ if (rectLeft > rectRight) {
+ rectRight = rectLeft; rectLeft = argv[4].toSint16();
+ }
+ if (rectTop > rectBottom) {
+ rectBottom = rectTop; rectTop = argv[3].toSint16();
+ }
+ rect = Common::Rect (rectLeft, rectTop, rectRight, rectBottom);
}
- port->_parent->add((GfxContainer *)port->_parent, newport);
- delete port;
-}
-
-static bool activated_icon_bar = false; // FIXME: Avoid non-const global vars
-static int port_origin_x = 0; // FIXME: Avoid non-const global vars
-static int port_origin_y = 0; // FIXME: Avoid non-const global vars
-
-reg_t kGraph(EngineState *s, int argc, reg_t *argv) {
- rect_t area;
+ // old code, may be removed later after class migration
GfxPort *port = s->port;
int redraw_port = 0;
-
+ rect_t area;
area = gfx_rect(argv[2].toSint16(), argv[1].toSint16() , argv[4].toSint16(), argv[3].toSint16());
-
area.width = area.width - area.x; // Since the actual coordinates are absolute
area.height = area.height - area.y;
switch (argv[0].toSint16()) {
case K_GRAPH_GET_COLORS_NR:
-
return make_reg(0, !s->resMan->isVGA() ? 0x10 : 0x100);
break;
- case K_GRAPH_DRAW_LINE: {
- int16 priority = (argc > 6) ? argv[6].toSint16() : -1;
- int16 control = (argc > 7) ? argv[7].toSint16() : -1;
- gfx_color_t gfxcolor = graph_map_color(s, argv[5].toSint16(), priority, control);
+ case K_GRAPH_DRAW_LINE:
+ priority = (argc > 6) ? argv[6].toSint16() : -1;
+ control = (argc > 7) ? argv[7].toSint16() : -1;
+ color = argv[5].toSint16();
- debugC(2, kDebugLevelGraphics, "draw_line((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n",
- argv[2].toSint16(), argv[1].toSint16(), argv[4].toSint16(), argv[3].toSint16(), argv[5].toSint16(), priority, control, gfxcolor.mask);
+ // FIXME: rect must be changed to 2 Common::Point
+ s->gui->graphDrawLine(rect, color, priority, control);
+ break;
- redraw_port = 1;
-
- // Note: it's quite possible that the coordinates of the line will *not* form a valid rectangle (e.g. it might
- // have negative width/height). The actual dirty rectangle is constructed in gfxdr_add_dirty().
- // FIXME/TODO: We need to change the semantics of this call, so that no fake rectangles are used. As it is, it's
- // not possible change rect_t to Common::Rect, as we assume that Common::Rect forms a *valid* rectangle.
- ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_line(Common::Point(argv[2].toSint16(), argv[1].toSint16()), Common::Point(argv[4].toSint16(), argv[3].toSint16()),
- gfxcolor, GFX_LINE_MODE_CORRECT, GFX_LINE_STYLE_NORMAL));
-
- }
- break;
-
case K_GRAPH_SAVE_BOX:
-
- area.x += s->port->zone.x + port_origin_x;
- area.y += s->port->zone.y + port_origin_y;
- area.width += -port_origin_x;
- area.height += -port_origin_y;
-
- return(graph_save_box(s, area));
+ flags = (argc > 5) ? argv[5].toUint16() : 0;
+ return s->gui->graphSaveBox(rect, flags);
break;
case K_GRAPH_RESTORE_BOX:
-
- graph_restore_box(s, argv[1]);
+ s->gui->graphRestoreBox(argv[1]);
break;
case K_GRAPH_FILL_BOX_BACKGROUND:
-
- _k_graph_rebuild_port_with_color(s, port->_bgcolor);
- port = s->port;
-
- redraw_port = 1;
+ s->gui->graphFillBoxBackground(rect);
break;
case K_GRAPH_FILL_BOX_FOREGROUND:
+ s->gui->graphFillBoxForeground(rect);
+ break;
- _k_graph_rebuild_port_with_color(s, port->_color);
- port = s->port;
+ case K_GRAPH_FILL_BOX_ANY:
+ priority = (argc > 7) ? argv[7].toSint16() : -1;
+ control = (argc > 8) ? argv[8].toSint16() : -1;
+ color = argv[6].toSint16();
+ colorMask = argv[5].toUint16();
- redraw_port = 1;
+ s->gui->graphFillBox(rect, colorMask, color, priority, control);
break;
- case K_GRAPH_FILL_BOX_ANY: {
- int16 priority = (argc > 7) ? argv[7].toSint16() : -1;
- int16 control = (argc > 8) ? argv[8].toSint16() : -1;
- gfx_color_t color = graph_map_color(s, argv[6].toSint16(), priority, control);
-
- color.mask = (byte)argv[5].toUint16();
-
- debugC(2, kDebugLevelGraphics, "fill_box_any((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n",
- argv[2].toSint16(), argv[1].toSint16(), argv[4].toSint16(), argv[3].toSint16(), argv[6].toSint16(), priority, control, argv[5].toUint16());
-
- // FIXME/TODO: this is not right, as some of the dialogs are drawn *behind* some widgets. But at least it works for now
- //ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT)); // old code
- s->picture_port->add((GfxContainer *)s->picture_port, gfxw_new_box(s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT));
-
- }
- break;
-
case K_GRAPH_UPDATE_BOX: {
debugC(2, kDebugLevelGraphics, "update_box(%d, %d, %d, %d)\n", argv[1].toSint16(), argv[2].toSint16(), argv[3].toSint16(), argv[4].toSint16());
@@ -557,14 +479,12 @@
area.x += s->port->zone.x;
area.y += s->port->zone.y;
- gfxop_update_box(s->gfx_state, area);
-
+ // FIXME: Change to class calling
+ //gfxop_update_box(s->gfx_state, area);
}
break;
case K_GRAPH_REDRAW_BOX: {
-
-
debugC(2, kDebugLevelGraphics, "redraw_box(%d, %d, %d, %d)\n", argv[1].toSint16(), argv[2].toSint16(), argv[3].toSint16(), argv[4].toSint16());
area.x += s->port->zone.x;
@@ -573,10 +493,9 @@
if (s->dyn_views && s->dyn_views->_parent == (GfxContainer *)s->port)
s->dyn_views->draw(Common::Point(0, 0));
- gfxop_update_box(s->gfx_state, area);
-
+ // FIXME: Change to class calling
+ //gfxop_update_box(s->gfx_state, area);
}
-
break;
case K_GRAPH_ADJUST_PRIORITY:
@@ -601,22 +520,19 @@
}
reg_t kTextSize(EngineState *s, int argc, reg_t *argv) {
- int width, height;
+ int16 textWidth, textHeight;
Common::String text = s->segMan->getString(argv[1]);
reg_t *dest = s->segMan->derefRegPtr(argv[0], 4);
int maxwidth = (argc > 3) ? argv[3].toUint16() : 0;
int font_nr = argv[2].toUint16();
Common::String sep_str;
- const char *sep = NULL;
+ const char *sep = NULL;
if ((argc > 4) && (argv[4].segment)) {
sep_str = s->segMan->getString(argv[4]);
sep = sep_str.c_str();
}
- if (maxwidth < 0)
- maxwidth = 0;
-
dest[0] = dest[1] = NULL_REG;
if (text.empty() || !dest) { // Empty text
@@ -625,20 +541,19 @@
return s->r_acc;
}
- gfxop_get_text_params(s->gfx_state, font_nr, s->strSplit(text.c_str(), sep).c_str(), maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE,
- &width, &height, 0, NULL, NULL, NULL);
- debugC(2, kDebugLevelStrings, "GetTextSize '%s' -> %dx%d\n", text.c_str(), width, height);
+ textWidth = dest[3].toUint16(); textHeight = dest[2].toUint16();
+ s->gui->textSize(s->strSplit(text.c_str(), sep).c_str(), font_nr, maxwidth, &textWidth, &textHeight);
+ debugC(2, kDebugLevelStrings, "GetTextSize '%s' -> %dx%d\n", text.c_str(), textWidth, textHeight);
- dest[2] = make_reg(0, height);
-// dest[3] = make_reg(0, maxwidth? maxwidth : width);
- dest[3] = make_reg(0, width);
-
+ dest[2] = make_reg(0, textHeight);
+ dest[3] = make_reg(0, textWidth);
return s->r_acc;
}
reg_t kWait(EngineState *s, int argc, reg_t *argv) {
- uint32 time;
int sleep_time = argv[0].toUint16();
+#if 0
+ uint32 time;
time = g_system->getMillis();
s->r_acc = make_reg(0, ((long)time - (long)s->last_wait_time) * 60 / 1000);
@@ -650,7 +565,12 @@
// Reset speed throttler: Game is playing along nicely anyway
if (sleep_time > 0)
s->speedThrottler->reset();
+#endif
+ // FIXME: we should not be asking from the GUI to wait. The kernel sounds
+ // like a better place
+ s->gui->wait(sleep_time);
+
return s->r_acc;
}
@@ -977,72 +897,25 @@
#define K_DRAWPIC_FLAG_MIRRORED (1 << 14)
reg_t kDrawPic(EngineState *s, int argc, reg_t *argv) {
- drawn_pic_t dp;
- bool add_to_pic = (argc > 2) ? !argv[2].toSint16() : false;
- gfx_color_t transparent = s->wm_port->_bgcolor;
- int picFlags = DRAWPIC01_FLAG_FILL_NORMALLY;
+ sciResourceId pictureId = argv[0].toUint16();
+ uint16 flags = 0;
+ uint16 style = 1;
+ int16 EGApaletteNo = -1;
- if (s->_kernel->usesOldGfxFunctions())
- add_to_pic = (argc > 2) ? argv[2].toSint16() : false;
-
- dp.nr = argv[0].toSint16();
- dp.palette = (argc > 3) ? argv[3].toSint16() : 0;
-
- if ((argc > 1) && (argv[1].toUint16() & K_DRAWPIC_FLAG_MIRRORED))
- picFlags |= DRAWPIC1_FLAG_MIRRORED;
-
- gfxop_disable_dirty_frames(s->gfx_state);
-
- if (NULL != s->old_screen) {
- gfxop_free_pixmap(s->gfx_state, s->old_screen);
+ if (argc >= 2)
+ style = argv[1].toUint16();
+ if (argc >= 3) {
+ if (!s->_kernel->usesOldGfxFunctions())
+ flags = !argv[2].toUint16();
+ else
+ flags = argv[2].toUint16();
}
+ if (argc >= 4)
+ EGApaletteNo = argv[3].toUint16();
- s->old_screen = gfxop_grab_pixmap(s->gfx_state, gfx_rect(0, 10, 320, 190));
+ s->gui->drawPicture(pictureId, style, flags, EGApaletteNo);
- debugC(2, kDebugLevelGraphics, "Drawing pic.%03d\n", argv[0].toSint16());
-
- if (add_to_pic) {
- gfxop_add_to_pic(s->gfx_state, dp.nr, picFlags, dp.palette);
- } else {
- gfxop_new_pic(s->gfx_state, dp.nr, picFlags, dp.palette);
- }
-
- delete s->wm_port;
- delete s->picture_port;
- delete s->iconbar_port;
-
- s->wm_port = new GfxPort(s->visual, s->gfx_state->pic_port_bounds, s->ega_colors[0], transparent);
- s->picture_port = new GfxPort(s->visual, s->gfx_state->pic_port_bounds, s->ega_colors[0], transparent);
-
- s->iconbar_port = new GfxPort(s->visual, gfx_rect(0, 0, 320, 200), s->ega_colors[0], transparent);
- s->iconbar_port->_flags |= GFXW_FLAG_NO_IMPLICIT_SWITCH;
-
- s->visual->add((GfxContainer *)s->visual, s->picture_port);
- s->visual->add((GfxContainer *)s->visual, s->wm_port);
- s->visual->add((GfxContainer *)s->visual, s->iconbar_port);
-
- s->port = s->picture_port;
-
- s->pic_priority_table = gfxop_get_pic_metainfo(s->gfx_state);
-
- if (argc > 1)
- s->pic_animate = argv[1].toSint16() & 0xff; // The animation used during kAnimate() later on
-
- s->dyn_views = NULL;
- s->drop_views = NULL;
-
- s->priority_first = 42;
-
- if (s->_kernel->usesOldGfxFunctions())
- s->priority_last = 200;
- else
- s->priority_last = 190;
-
- s->pic_not_valid = 1;
- s->pic_is_new = 1;
-
return s->r_acc;
-
}
Common::Rect set_base(EngineState *s, reg_t object) {
@@ -1230,9 +1103,14 @@
}
reg_t kPalette(EngineState *s, int argc, reg_t *argv) {
+// warning("kPalette %d", argv[0].toUint16());
switch (argv[0].toUint16()) {
case 1:
- debug(5, "STUB: kPalette() effect 1, direct palette set");
+ if (argc==3) {
+ int resourceNo = argv[1].toUint16();
+ int flags = argv[2].toUint16();
+ s->gui->paletteSet(resourceNo, flags);
+ }
break;
case 2:
debug(5, "STUB: kPalette() effect 2, set flag to colors");
@@ -1263,26 +1141,15 @@
int g = argv[2].toUint16();
int b = argv[3].toUint16();
- int i, delta, bestindex = -1, bestdelta = 200000;
-
- for (i = 0; i < s->gfx_state->gfxResMan->getColorCount(); i++) {
- int dr = abs(s->gfx_state->gfxResMan->getColor(i).r - r);
- int dg = abs(s->gfx_state->gfxResMan->getColor(i).g - g);
- int db = abs(s->gfx_state->gfxResMan->getColor(i).b - b);
-
- delta = dr * dr + dg * dg + db * db;
-
- if (delta < bestdelta) {
- bestdelta = delta;
- bestindex = i;
- }
- }
- // Don't warn about inexact mappings -- it's actually the
- // rule rather than the exception
- return make_reg(0, bestindex);
+ return make_reg(0, s->gui->paletteFind(r, g, b));
}
case 6:
- debug(5, "STUB: kPalette() effect 6, animate palette");
+ if (argc==4) {
+ int fromColor = argv[1].toUint16();
+ int toColor = argv[2].toUint16();
+ int speed = argv[3].toSint16();
+ s->gui->paletteAnimate(fromColor, toColor, speed);
+ }
break;
case 7:
debug(5, "STUB: kPalette() effect 7, save palette to heap");
@@ -1297,13 +1164,8 @@
return s->r_acc;
}
-reg_t kPalVary(EngineState *s, int argc, reg_t *argv) {
- warning("STUB: kPalVary()");
- return NULL_REG;
-}
+static void _k_draw_control(EngineState *s, reg_t obj, bool inverse);
-static void _k_draw_control(EngineState *s, reg_t obj, int inverse);
-
static void disableCertainButtons(SegManager *segMan, Common::String gameName, reg_t obj) {
reg_t text_pos = GET_SEL32(obj, text);
Common::String text;
@@ -1349,15 +1211,15 @@
reg_t obj = argv[0];
disableCertainButtons(s->segMan, s->_gameName, obj);
- _k_draw_control(s, obj, 0);
- FULL_REDRAW();
+ _k_draw_control(s, obj, false);
+// FULL_REDRAW();
return NULL_REG;
}
reg_t kHiliteControl(EngineState *s, int argc, reg_t *argv) {
reg_t obj = argv[0];
- _k_draw_control(s, obj, 1);
+ _k_draw_control(s, obj, true);
return s->r_acc;
}
@@ -1541,15 +1403,17 @@
case K_CONTROL_ICON:
case K_CONTROL_BOX:
case K_CONTROL_BUTTON:
- if (event.segment) PUT_SEL32V(event, claimed, 1);
- _k_draw_control(s, obj, 0);
+ // Control shall not be redrawn here, Original Sierra interpreter doesn't do it and it will mangle up
+ // menus in at least SQ5
+ //if (event.segment) PUT_SEL32V(event, claimed, 1);
+ //_k_draw_control(s, obj, false);
return NULL_REG;
break;
case K_CONTROL_TEXT: {
int state = GET_SEL32V(obj, state);
PUT_SEL32V(obj, state, state | kControlStateDitherFramed);
- _k_draw_control(s, obj, 0);
+ _k_draw_control(s, obj, false);
PUT_SEL32V(obj, state, state);
}
break;
@@ -1562,7 +1426,7 @@
return s->r_acc;
}
-static void _k_draw_control(EngineState *s, reg_t obj, int inverse) {
+static void _k_draw_control(EngineState *s, reg_t obj, bool inverse) {
SegManager *segMan = s->segMan;
int x = (int16)GET_SEL32V(obj, nsLeft);
int y = (int16)GET_SEL32V(obj, nsTop);
@@ -1570,6 +1434,9 @@
int yl = (int16)GET_SEL32V(obj, nsBottom) - y;
rect_t area = gfx_rect(x, y, xl, yl);
+ Common::Rect rect;
+ rect = Common::Rect (x, y, (int16)GET_SEL32V(obj, nsRight), (int16)GET_SEL32V(obj, nsBottom));
+
int font_nr = GET_SEL32V(obj, font);
reg_t text_pos = GET_SEL32(obj, text);
Common::String text;
@@ -1578,7 +1445,7 @@
int view = GET_SEL32V(obj, view);
int cel = sign_extend_byte(GET_SEL32V(obj, cel));
int loop = sign_extend_byte(GET_SEL32V(obj, loop));
- gfx_alignment_t mode;
+ int mode;
int type = GET_SEL32V(obj, type);
int state = GET_SEL32V(obj, state);
@@ -1588,19 +1455,15 @@
switch (type) {
case K_CONTROL_BUTTON:
debugC(2, kDebugLevelGraphics, "drawing button %04x:%04x to %d,%d\n", PRINT_REG(obj), x, y);
- ADD_TO_CURRENT_PICTURE_PORT(sciw_new_button_control(s->port, obj, area, s->strSplit(text.c_str(), NULL).c_str(), font_nr,
- (int8)(state & kControlStateFramed), (int8)inverse, (int8)(state & kControlStateDisabled)));
- break;
+ s->gui->drawControlButton(rect, obj, s->strSplit(text.c_str(), NULL).c_str(), font_nr, state, inverse);
+ return;
case K_CONTROL_TEXT:
mode = (gfx_alignment_t) GET_SEL32V(obj, mode);
-
debugC(2, kDebugLevelGraphics, "drawing text %04x:%04x to %d,%d, mode=%d\n", PRINT_REG(obj), x, y, mode);
+ s->gui->drawControlText(rect, obj, s->strSplit(text.c_str(), NULL).c_str(), font_nr, mode, state, inverse);
+ return;
- ADD_TO_CURRENT_PICTURE_PORT(sciw_new_text_control(s->port, obj, area, s->strSplit(text.c_str()).c_str(), font_nr, mode,
- (int8)(!!(state & kControlStateDitherFramed)), (int8)inverse));
- break;
-
case K_CONTROL_EDIT:
debugC(2, kDebugLevelGraphics, "drawing edit control %04x:%04x to %d,%d\n", PRINT_REG(obj), x, y);
@@ -1676,9 +1539,9 @@
selection = i + 1;
}
}
+
ADD_TO_CURRENT_PICTURE_PORT(sciw_new_list_control(s->port, obj, area, font_nr, entries_list, entries_nr,
list_top, selection, (int8)inverse));
-
free(entries_list);
delete[] strings;
}
@@ -2350,75 +2213,34 @@
}
reg_t kGetPort(EngineState *s, int argc, reg_t *argv) {
- return make_reg(0, s->port->_ID);
+ return s->gui->getPort();
}
reg_t kSetPort(EngineState *s, int argc, reg_t *argv) {
- if (activated_icon_bar && argc == 6) {
- port_origin_x = port_origin_y = 0;
- activated_icon_bar = false;
- return s->r_acc;
- }
-
+ uint16 portPtr;
+ Common::Rect picRect;
+ int16 picTop, picLeft;
+
switch (argc) {
- case 1 : {
- unsigned int port_nr = argv[0].toSint16();
- GfxPort *new_port;
+ case 1:
+ portPtr = argv[0].toSint16();
+ s->gui->setPort(portPtr);
+ break;
- /* We depart from official semantics here, sorry!
- Reasoning: Sierra SCI does not clip ports while we do.
- Therefore a draw to the titlebar port (which is the
- official semantics) would cut off the lower part of the
- icons in an SCI1 icon bar. Instead we have an
- iconbar_port that does not exist in SSCI. */
- if (port_nr == (unsigned int) - 1) port_nr = s->iconbar_port->_ID;
-
- new_port = s->visual->getPort(port_nr);
-
- if (!new_port) {
- warning("Invalid port %04x requested", port_nr);
- return NULL_REG;
- }
-
- s->port->draw(gfxw_point_zero); // Update the port we're leaving
- s->port = new_port;
- return s->r_acc;
- }
- case 6 : {
- port_origin_y = argv[0].toSint16();
- port_origin_x = argv[1].toSint16();
-
- if (argv[0].toSint16() == -10) {
- s->port->draw(gfxw_point_zero); // Update the port we're leaving
- s->port = s->iconbar_port;
- activated_icon_bar = true;
- return s->r_acc;
- }
-
- // Notify the graphics resource manager that the pic port bounds changed
- s->gfx_state->gfxResMan->changePortBounds(argv[5].toUint16(), argv[4].toUint16(), argv[3].toUint16() + argv[5].toUint16(), argv[2].toUint16() + argv[4].toUint16());
-
- // LSL6 calls kSetPort to extend the screen to draw the GUI. If we free all resources
- // here, the background picture is freed too, and this makes everything a big mess.
- // FIXME/TODO: This code really needs to be rewritten to conform to the original behavior
- if (s->_gameName != "lsl6") {
- s->gfx_state->pic_port_bounds = gfx_rect(argv[5].toUint16(), argv[4].toUint16(), argv[3].toUint16(), argv[2].toUint16());
-
- // FIXME: Should really only invalidate all loaded pic resources here;
- // this is overkill
- s->gfx_state->gfxResMan->freeAllResources();
- } else {
- // WORKAROUND for LSL6
- printf("SetPort case 6 called in LSL6. Origin: %d, %d - Clip rect: %d, %d, %d, %d\n", argv[1].toSint16(), argv[0].toSint16(), argv[5].toUint16(), argv[4].toUint16(), argv[3].toUint16(), argv[2].toUint16());
- }
-
+ case 6:
+ picRect.top = argv[0].toSint16();
+ picRect.left = argv[1].toSint16();
+ picRect.bottom = argv[2].toSint16();
+ picRect.right = argv[3].toSint16();
+ picTop = argv[4].toSint16();
+ picLeft = argv[5].toSint16();
+ s->gui->setPortPic(picRect, picTop, picLeft);
break;
- }
- default :
+
+ default:
error("SetPort was called with %d parameters", argc);
break;
}
-
return NULL_REG;
}
@@ -2428,142 +2250,43 @@
int cel = argv[2].toSint16();
int x = argv[3].toSint16();
int y = argv[4].toSint16();
- int priority = (argc > 5) ? argv[5].toSint16() : -1;
- GfxView *new_view;
+ int priority = (argc > 5) ? argv[5].toUint16() : -1;
+ int paletteNo = (argc > 6) ? argv[6].toSint16() : 0;
- gfxop_check_cel(s->gfx_state, view, &loop, &cel);
+ s->gui->drawCell(view, loop, cel, x, y, priority, paletteNo);
- debugC(2, kDebugLevelGraphics, "DrawCel((%d,%d), (view.%d, %d, %d), p=%d)\n", x, y, view, loop, cel, priority);
-
- new_view = gfxw_new_view(s->gfx_state, Common::Point(x, y), view, loop, cel, 0, priority, -1,
- ALIGN_LEFT, ALIGN_TOP, GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET);
-
- ADD_TO_CURRENT_PICTURE_PORT(new_view);
- FULL_REDRAW();
-
return s->r_acc;
}
reg_t kDisposeWindow(EngineState *s, int argc, reg_t *argv) {
- unsigned int goner_nr = argv[0].toSint16();
- GfxPort *goner;
- GfxPort *pred;
+ int goner_nr = argv[0].toSint16();
+ int arg2 = (argc != 2 || argv[2].toUint16() == 0 ? 0 : 1);
- goner = s->visual->getPort(goner_nr);
- if ((goner_nr < 3) || (goner == NULL)) {
- error("Removal of invalid window %04x requested", goner_nr);
- return s->r_acc;
- }
-
- if (s->dyn_views && (GfxContainer *)s->dyn_views->_parent == (GfxContainer *)goner) {
- reparentize_primary_widget_lists(s, (GfxPort *) goner->_parent);
- }
-
- if (s->drop_views && (GfxContainer *)s->drop_views->_parent == (GfxContainer *)goner)
- s->drop_views = NULL; // Kill it
-
- pred = gfxw_remove_port(s->visual, goner);
-
- if (goner == s->port) // Did we kill the active port?
- s->port = pred;
-
- // Find the last port that exists and that isn't marked no-switch
- int id = s->visual->_portRefs.size() - 1;
- while (id > 0 && (!s->visual->_portRefs[id] || (s->visual->_portRefs[id]->_flags & GFXW_FLAG_NO_IMPLICIT_SWITCH)))
- id--;
-
- debugC(2, kDebugLevelGraphics, "Activating port %d after disposing window %d\n", id, goner_nr);
- s->port = (id >= 0) ? s->visual->_portRefs[id] : 0;
-
- if (!s->port)
- s->port = gfxw_find_default_port(s->visual);
-
- gfxop_update(s->gfx_state);
-
+ s->gui->disposeWindow(goner_nr, arg2);
return s->r_acc;
}
reg_t kNewWindow(EngineState *s, int argc, reg_t *argv) {
- GfxPort *window;
- int x, y, xl, yl, flags;
- gfx_color_t bgcolor;
- gfx_color_t fgcolor;
- gfx_color_t black;
- gfx_color_t lWhite;
- int priority;
+ Common::Rect rect1 (argv[1].toSint16(), argv[0].toSint16(), argv[3].toSint16(), argv[2].toSint16());
+ Common::Rect rect2;
int argextra = argc == 13 ? 4 : 0; // Triggers in PQ3 and SCI1.1 games
+ int style = argv[5 + argextra].toSint16();
+ int priority = (argc > 6 + argextra) ? argv[6 + argextra].toSint16() : -1;
+ int colorPen = (argc > 7 + argextra) ? argv[7 + argextra].toSint16() : 0;
+ int colorBack = (argc > 8 + argextra) ? argv[8 + argextra].toSint16() : 255;
- y = argv[0].toSint16();
- x = argv[1].toSint16();
- yl = argv[2].toSint16() - y;
- xl = argv[3].toSint16() - x;
-
- y += s->wm_port->_bounds.y;
-
- if (x + xl > 319)
- x -= ((x + xl) - 319);
-
- flags = argv[5 + argextra].toSint16();
-
- priority = (argc > 6 + argextra) ? argv[6 + argextra].toSint16() : -1;
- bgcolor.mask = 0;
-
- int16 bgColor = (argc > 8 + argextra) ? argv[8 + argextra].toSint16() : 255;
-
- if (bgColor >= 0) {
- if (!s->resMan->isVGA())
- bgcolor.visual = get_pic_color(s, MIN<int>(bgColor, 15));
- else
- bgcolor.visual = get_pic_color(s, bgColor);
- bgcolor.mask = GFX_MASK_VISUAL;
- } else {
- bgcolor.visual = PaletteEntry(0,0,0);
+ // const char *title = argv[4 + argextra].segment ? kernel_dereference_char_pointer(s, argv[4 + argextra], 0) : NULL;
+ if (argc==13) {
+ rect2 = Common::Rect (argv[5].toSint16(), argv[4].toSint16(), argv[7].toSint16(), argv[6].toSint16());
}
- bgcolor.priority = priority;
- bgcolor.mask |= priority >= 0 ? GFX_MASK_PRIORITY : 0;
- bgcolor.alpha = 0;
- bgcolor.control = -1;
- debugC(2, kDebugLevelGraphics, "New window with params %d, %d, %d, %d\n", argv[0].toSint16(), argv[1].toSint16(), argv[2].toSint16(), argv[3].toSint16());
-
- int16 visualColor = (argc > 7 + argextra) ? argv[7 + argextra].toSint16() : 0;
- fgcolor.visual = get_pic_color(s, visualColor);
- fgcolor.mask = GFX_MASK_VISUAL;
- fgcolor.control = -1;
- fgcolor.priority = -1;
- fgcolor.alpha = 0;
- black.visual = get_pic_color(s, 0);
- black.mask = GFX_MASK_VISUAL;
- black.alpha = 0;
- black.control = -1;
- black.priority = -1;
- lWhite.visual = get_pic_color(s, !s->resMan->isVGA() ? 15 : 255);
- lWhite.mask = GFX_MASK_VISUAL;
- lWhite.alpha = 0;
- lWhite.priority = -1;
- lWhite.control = -1;
Common::String title;
if (argv[4 + argextra].segment) {
title = s->segMan->getString(argv[4 + argextra]);
title = s->strSplit(title.c_str(), NULL);
}
- window = sciw_new_window(s, gfx_rect(x, y, xl, yl), s->titlebar_port->_font, fgcolor, bgcolor,
- s->titlebar_port->_font, lWhite, black, title.c_str(), flags);
-
- // PQ3 and SCI1.1 games have the interpreter store underBits implicitly
- if (argextra)
- gfxw_port_auto_restore_background(s->visual, window, gfx_rect(argv[5].toSint16(), argv[4].toSint16() + s->wm_port->_bounds.y, argv[7].toSint16() - argv[5].toSint16(), argv[6].toSint16() - argv[4].toSint16()));
-
- ADD_TO_WINDOW_PORT(window);
- FULL_REDRAW();
-
- window->draw(gfxw_point_zero);
- gfxop_update(s->gfx_state);
-
- s->port = window; // Set active port
-
- return make_reg(0, window->_ID);
+ return s->gui->newWindow(rect1, rect2, style, priority, colorPen, colorBack, title.c_str());
}
#define K_ANIMATE_CENTER_OPEN_H 0 // horizontally open from center
@@ -3130,208 +2853,21 @@
return s->r_acc;
}
-#define K_DISPLAY_SET_COORDS 100
-#define K_DISPLAY_SET_ALIGNMENT 101
-#define K_DISPLAY_SET_COLOR 102
-#define K_DISPLAY_SET_BGCOLOR 103
-#define K_DISPLAY_SET_GRAYTEXT 104
-#define K_DISPLAY_SET_FONT 105
-#define K_DISPLAY_WIDTH 106
-#define K_DISPLAY_SAVE_UNDER 107
-#define K_DISPLAY_RESTORE_UNDER 108
-#define K_DONT_UPDATE_IMMEDIATELY 121
-
reg_t kDisplay(EngineState *s, int argc, reg_t *argv) {
- int argpt;
reg_t textp = argv[0];
int index = (argc > 1) ? argv[1].toUint16() : 0;
- int temp;
- bool save_under = false;
- gfx_color_t transparent = { PaletteEntry(), 0, -1, -1, 0 };
+
Common::String text;
- GfxPort *port = (s->port) ? s->port : s->picture_port;
- bool update_immediately = true;
- gfx_color_t color0, *color1, bg_color;
- gfx_alignment_t halign = ALIGN_LEFT;
- rect_t area = gfx_rect(port->draw_pos.x, port->draw_pos.y, 320 - port->draw_pos.x, 200 - port->draw_pos.y);
- int gray = port->gray_text;
- int font_nr = port->_font;
- GfxText *text_handle;
-
- color0 = port->_color;
- bg_color = port->_bgcolor;
- // TODO: in SCI1VGA the default colors for text and background are #0 (black)
- // SCI0 case should be checked
-
if (textp.segment) {
- argpt = 1;
+ argc--; argv++;
text = s->segMan->getString(textp);
} else {
- argpt = 2;
+ argc--; argc--; argv++; argv++;
text = kernel_lookup_text(s, textp, index);
}
-#if 0
- if (!text) {
- error("Display with invalid reference %04x:%04x", PRINT_REG(textp));
- return NULL_REG;
- }
-#endif
-
- while (argpt < argc) {
- switch (argv[argpt++].toUint16()) {
-
- case K_DISPLAY_SET_COORDS:
-
- area.x = argv[argpt++].toUint16();
- area.y = argv[argpt++].toUint16();
- debugC(2, kDebugLevelGraphics, "Display: set_coords(%d, %d)\n", area.x, area.y);
- break;
-
- case K_DISPLAY_SET_ALIGNMENT:
-
- halign = (gfx_alignment_t)argv[argpt++].toSint16();
- debugC(2, kDebugLevelGraphics, "Display: set_align(%d)\n", halign);
- break;
-
- case K_DISPLAY_SET_COLOR:
-
- temp = argv[argpt++].toSint16();
- debugC(2, kDebugLevelGraphics, "Display: set_color(%d)\n", temp);
- if (!s->resMan->isVGA() && temp >= 0 && temp <= 15)
- color0 = (s->ega_colors[temp]);
- else
- if (s->resMan->isVGA() && temp >= 0 && temp < 256) {
- color0.visual = get_pic_color(s, temp);
- color0.mask = GFX_MASK_VISUAL;
- } else
- if (temp == -1)
- color0 = transparent;
- else
- warning("Display: Attempt to set invalid fg color %d", temp);
- break;
-
- case K_DISPLAY_SET_BGCOLOR:
-
- temp = argv[argpt++].toSint16();
- debugC(2, kDebugLevelGraphics, "Display: set_bg_color(%d)\n", temp);
- if (!s->resMan->isVGA() && temp >= 0 && temp <= 15)
- bg_color = s->ega_colors[temp];
- else
- if (s->resMan->isVGA() && temp >= 0 && temp <= 256) {
- bg_color.visual = get_pic_color(s, temp);
- bg_color.mask = GFX_MASK_VISUAL;
- } else
- if (temp == -1)
- bg_color = transparent;
- else
- warning("Display: Attempt to set invalid fg color %d", temp);
- break;
-
- case K_DISPLAY_SET_GRAYTEXT:
-
- gray = argv[argpt++].toSint16();
- debugC(2, kDebugLevelGraphics, "Display: set_graytext(%d)\n", gray);
- break;
-
- case K_DISPLAY_SET_FONT:
-
- font_nr = argv[argpt++].toUint16();
-
- debugC(2, kDebugLevelGraphics, "Display: set_font(\"font.%03d\")\n", font_nr);
- break;
-
- case K_DISPLAY_WIDTH:
-
- area.width = argv[argpt++].toUint16();
- if (area.width == 0)
- area.width = MAX_TEXT_WIDTH_MAGIC_VALUE;
-
- debugC(2, kDebugLevelGraphics, "Display: set_width(%d)\n", area.width);
- break;
-
- case K_DISPLAY_SAVE_UNDER:
-
- save_under = true;
- debugC(2, kDebugLevelGraphics, "Display: set_save_under()\n");
- break;
-
- case K_DISPLAY_RESTORE_UNDER:
-
- debugC(2, kDebugLevelGraphics, "Display: restore_under(%04x)\n", argv[argpt].toUint16());
- graph_restore_box(s, argv[argpt++]);
- update_immediately = true;
- argpt++;
- return s->r_acc;
-
- case K_DONT_UPDATE_IMMEDIATELY:
-
- update_immediately = false;
- debugC(2, kDebugLevelGraphics, "Display: set_dont_update()\n");
- argpt++;
- break;
-
- default:
- debugC(2, kDebugLevelGraphics, "Unknown Display() command %x\n", argv[argpt - 1].toUint16());
- return NULL_REG;
- }
- }
-
- if (halign == ALIGN_LEFT) {
- // If the text does not fit on the screen, move it to the left and upwards until it does
- gfxop_get_text_params(s->gfx_state, font_nr, text.c_str(), area.width, &area.width, &area.height, 0, NULL, NULL, NULL);
-
- // Make the text fit on the screen
- if (area.x + area.width > 320)
- area.x += 320 - area.x - area.width; // Plus negative number = subtraction
-
- if (area.y + area.height > 200)
- area.y += 200 - area.y - area.height; // Plus negative number = subtraction
- } else {
- // If the text does not fit on the screen, clip it till it does
- if (area.x + area.width > s->gfx_state->pic_port_bounds.width)
- area.width = s->gfx_state->pic_port_bounds.width - area.x;
-
- if (area.y + area.height > s->gfx_state->pic_port_bounds.height)
- area.height = s->gfx_state->pic_port_bounds.height - area.y;
- }
-
- if (gray)
- color1 = &bg_color;
- else
- color1 = &color0;
-
- assert_primary_widget_lists(s);
-
- text_handle = gfxw_new_text(s->gfx_state, area, font_nr, s->strSplit(text.c_str()).c_str(), halign, ALIGN_TOP, color0, *color1, bg_color, 0);
-
- if (!text_handle) {
- error("Display: Failed to create text widget");
- return NULL_REG;
- }
-
- if (save_under) { // Backup
- rect_t save_area = text_handle->_bounds;
- save_area.x += port->_bounds.x;
- save_area.y += port->_bounds.y;
-
- s->r_acc = graph_save_box(s, save_area);
- text_handle->_serial++; // This is evil!
-
- debugC(2, kDebugLevelGraphics, "Saving (%d, %d) size (%d, %d) as %04x:%04x\n", save_area.x, save_area.y, save_area.width, save_area.height, PRINT_REG(s->r_acc));
- }
-
- debugC(2, kDebugLevelGraphics, "Display: Commiting text '%s'\n", text.c_str());
-
- //ADD_TO_CURRENT_PICTURE_PORT(text_handle);
-
- ADD_TO_CURRENT_PICTURE_PORT(text_handle);
- if ((!s->pic_not_valid) && update_immediately) { // Refresh if drawn to valid picture
- FULL_REDRAW();
- debugC(2, kDebugLevelGraphics, "Refreshing display...\n");
- }
-
+ s->gui->display(s->strSplit(text.c_str()).c_str(), argc, argv);
return s->r_acc;
}
@@ -3488,4 +3024,16 @@
return s->r_acc;
}
+// New calls for SCI11. Using those is only needed when using text-codes so that one is able to change
+// font and/or color multiple times during kDisplay and kDrawControl
+reg_t kTextFonts(EngineState *s, int argc, reg_t *argv) {
+ s->gui->textFonts(argc, argv);
+ return s->r_acc;
+}
+
+reg_t kTextColors(EngineState *s, int argc, reg_t *argv) {
+ s->gui->textColors(argc, argv);
+ return s->r_acc;
+}
+
} // End of namespace Sci
Modified: scummvm/trunk/engines/sci/engine/kmisc.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kmisc.cpp 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/engine/kmisc.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -131,7 +131,8 @@
switch (mode) {
case K_NEW_GETTIME_TICKS :
- retval = start_time * 60 / 1000;
+ retval = s->gui->getTimeTicks(); // FIXME
+ //retval = start_time * 60 / 1000;
debugC(2, kDebugLevelTime, "GetTime(elapsed) returns %d", retval);
break;
case K_NEW_GETTIME_TIME_12HOUR :
Modified: scummvm/trunk/engines/sci/engine/state.h
===================================================================
--- scummvm/trunk/engines/sci/engine/state.h 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/engine/state.h 2009-10-03 20:49:18 UTC (rev 44565)
@@ -44,6 +44,7 @@
#include "sci/engine/seg_manager.h"
#include "sci/gfx/gfx_system.h"
#include "sci/sfx/core.h"
+#include "sci/gui/gui.h"
namespace Sci {
@@ -175,6 +176,8 @@
/* Non-VM information */
+ SciGUI *gui; /* Currently active GUI */
+
GfxState *gfx_state; /**< Graphics state and driver */
gfx_pixmap_t *old_screen; /**< Old screen content: Stored during kDrawPic() for kAnimate() */
@@ -319,6 +322,12 @@
*/
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);
+
} // End of namespace Sci
#endif // SCI_INCLUDE_ENGINE_H
Modified: scummvm/trunk/engines/sci/gfx/gfx_driver.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_driver.cpp 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/gfx/gfx_driver.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -248,4 +248,19 @@
cursorData = 0;
}
+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
Modified: scummvm/trunk/engines/sci/gfx/gfx_driver.h
===================================================================
--- scummvm/trunk/engines/sci/gfx/gfx_driver.h 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/gfx/gfx_driver.h 2009-10-03 20:49:18 UTC (rev 44565)
@@ -228,6 +228,11 @@
gfx_mode_t *getMode() { return _mode; }
byte *getVisual0() { return _visual[0]; }
+ /**
+ * Animates palette
+ */
+ void animatePalette(int fromColor, int toColor, int stepCount);
+
private:
gfx_pixmap_t *_priority[2];
byte *_visual[2];
Modified: scummvm/trunk/engines/sci/gfx/res_view.cpp
===================================================================
--- scummvm/trunk/engines/sci/gfx/res_view.cpp 2009-10-03 20:42:26 UTC (rev 44564)
+++ scummvm/trunk/engines/sci/gfx/res_view.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -365,6 +365,12 @@
return retval;
}
+// SCI1:
+// [LoopCount:WORD] [MirrorMask:WORD] [??:WORD] [PaletteOffset:WORD] [LoopOffset0:WORD] [LoopOffset1:WORD]...
+// Loop-data:
+// [CellCount:WORD] [Unknown:WORD] [CellOffset0:WORD] [CellOffset1:WORD]...
+// SCI11:
+// [HeaderSize:WORD] [LoopCount:BYTE] [Unknown:BYTE] [??:WORD] [??:WORD] [PaletteOffset:WORD]
gfxr_view_t *getVGAView(int id, byte *resource, int size, ViewType viewType) {
uint16 palOffset = READ_LE_UINT16(resource + V1_PALETTE_OFFSET + ((viewType == kViewVga11) ? 2 : 0));
uint16 headerSize = (viewType == kViewVga11) ? READ_LE_UINT16(resource + V2_HEADER_SIZE) : 0;
Added: scummvm/trunk/engines/sci/gui/gui.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui.cpp (rev 0)
+++ scummvm/trunk/engines/sci/gui/gui.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -0,0 +1,330 @@
+/* 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 "common/util.h"
+
+#include "sci/sci.h"
+#include "sci/engine/state.h"
+#include "sci/tools.h"
+#include "sci/gui/gui_screen.h"
+#include "sci/gui/gui_gfx.h"
+#include "sci/gui/gui_windowmgr.h"
+#include "sci/gui/gui_memmgr.h"
+#include "sci/gui/gui_view.h"
+
+#include "sci/gfx/operations.h"
+
+namespace Sci {
+
+SciGUI::SciGUI(OSystem *system, EngineState *state)
+ : _system(system), _s(state) {
+ _screen = new SciGUIscreen(_system, _s);
+ _gfx = new SciGUIgfx(_system, _s, _screen);
+ _windowMgr = new SciGUIwindowMgr(_s, _gfx);
+}
+
+SciGUI::SciGUI() {
+}
+
+SciGUI::~SciGUI() {
+}
+
+void SciGUI::init(bool oldGfxFunctions) {
+ _usesOldGfxFunctions = oldGfxFunctions;
+
+ /* Set default SCI0 palette */
+}
+
+int16 SciGUI::getTimeTicks() {
+ return _gfx->_sysTicks;
+}
+
+void SciGUI::wait(int16 ticks) {
+ uint32 waitto = _gfx->_sysTicks + ticks;
+ do {
+ //eventMgr->pollEvents();
+ _system->delayMillis(_gfx->_sysSpeed >> 11);
+ } while (_gfx->_sysTicks < waitto);
+}
+
+void SciGUI::setPort(uint16 portPtr) {
+ switch (portPtr) {
+ case 0: _gfx->SetPort(_windowMgr->_wmgrPort); break;
+ case 0xFFFF: _gfx->SetPort(_gfx->_menuPort); break;
+ default:
+ _gfx->SetPort((sciPort *)heap2Ptr(portPtr));
+ };
+}
+
+void SciGUI::setPortPic(Common::Rect rect, int16 picTop, int16 picLeft) {
+ _windowMgr->_picWind->rect = rect;
+ _windowMgr->_picWind->top = picTop;
+ _windowMgr->_picWind->left = picLeft;
+ //if (argc >= 7)
+ //InitPri(42,190);
+}
+
+reg_t SciGUI::getPort() {
+ return make_reg(0, ptr2heap((byte *)_gfx->GetPort()));
+}
+
+void SciGUI::globalToLocal(int16 *x, int16 *y) {
+ sciPort *curPort = _gfx->GetPort();
+ *x = *x - curPort->left;
+ *y = *y - curPort->top;
+}
+
+void SciGUI::localToGlobal(int16 *x, int16 *y) {
+ sciPort *curPort = _gfx->GetPort();
+ *x = *x + curPort->left;
+ *y = *y + curPort->top;
+}
+
+reg_t SciGUI::newWindow(Common::Rect rect1, Common::Rect rect2, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title) {
+ sciWnd *wnd = NULL;
+
+ if (rect2.top != 0 && rect2.left != 0 && rect2.height() != 0 && rect2.width() != 0)
+ wnd = _windowMgr->NewWindow(&rect1, &rect2, "", style, priority, 0);
+ else
+ wnd = _windowMgr->NewWindow(&rect1, NULL, "", style, priority, 0);
+ wnd->penClr = colorPen;
+ wnd->backClr = colorBack;
+ _windowMgr->DrawWindow(wnd);
+ return make_reg(0, ptr2heap((byte *)wnd));
+}
+
+void SciGUI::disposeWindow(uint16 windowPtr, int16 arg2) {
+ sciWnd *wnd = (sciWnd *)heap2Ptr(windowPtr);
+ _windowMgr->DisposeWindow(wnd, arg2);
+}
+
+void SciGUI::display(const char *text, int argc, reg_t *argv) {
+ int displayArg;
+ sciPort oldPort;
+ int16 align = 0;
+ int16 bgcolor = -1, width = 0xFFFF, bRedraw = 1;
+ byte bSaveUnder = false;
+ Common::Rect rect, *orect = &((sciWnd *)_gfx->GetPort())->rect0;
+
+ memcpy(&oldPort, _gfx->GetPort(), sizeof(sciPort));
+ // setting defaults
+ _gfx->PenMode(0);
+ _gfx->PenColor(0);
+ _gfx->TextFace(0);
+ // processing codes in argv
+ while (argc > 0) {
+ displayArg = argv[0].toUint16();
+ argc--; argv++;
+ switch (displayArg - 100) {
+ case 0:
+ _gfx->MoveTo(argv[0].toUint16(), argv[1].toUint16());
+ argc -= 2; argv += 2;
+ break;// move pen
+ case 1:
+ align = argv[0].toUint16();
+ argc--; argv++;
+ break;// set alignment
+ case 2:
+ _gfx->PenColor(argv[0].toUint16());
+ argc--; argv++;
+ break;// set pen color
+ case 3:
+ bgcolor = argv[0].toUint16();
+ argc--; argv++;
+ break;
+ case 4:
+ _gfx->TextFace(argv[0].toUint16());
+ argc--; argv++;
+ break;// set text grayout flag
+ case 5:
+ _gfx->SetFont(argv[0].toUint16());
+ argc--; argv++;
+ break;// set font
+ case 6:
+ width = argv[0].toUint16();
+ argc--; argv++;
+ break;
+ case 7:
+ bSaveUnder = 1;
+ break;
+ case 8: // restore under
+// if (hunk2Ptr(*pArgs)) {
+// memcpy(&rect, hunk2Ptr(*pArgs), sizeof(Common::Rect));
+// // rect is now absolute. Have to move it to be port-relative
+// rect.translate(-_gfx->RGetPort()->left, -_gfx->RGetPort()->top);
+// _gfx->RestoreBits(*pArgs);
+// ReAnimate(&rect);
+// }
+ // finishing loop
+ argc = 0;
+ break;
+ case 0x15:
+ bRedraw = 0;
+ break;
+ default:
+ warning("Unknown kDisplay argument %X", displayArg);
+ break;
+ }
+ }
+ // now drawing the text
+ _gfx->TextSize(rect, text, -1, width);
+ _gfx->Move((orect->left <= 320 ? 0 : 320 - orect->left), (orect->top <= 200 ? 0 : 200 - orect->top)); // move port to (0,0)
+ rect.moveTo(_gfx->GetPort()->curLeft, _gfx->GetPort()->curTop);
+// if (bSaveUnder)
+// _acc = _gfx->SaveBits(rect, 1);
+ if (bgcolor != -1)
+ _gfx->FillRect(rect, 1, bgcolor, 0, 0);
+ _gfx->TextBox(text, 0, rect, align, 0xFFFF);
+// if (_picNotValid == 0 && bRedraw)
+// _gfx->ShowBits(rect, 1);
+ // restoring port and cursor pos
+ sciPort *currport = _gfx->GetPort();
+ uint16 tTop = currport->curTop;
+ uint16 tLeft = currport->curLeft;
+ memcpy(currport, &oldPort, sizeof(sciPort));
+ currport->curTop = tTop;
+ currport->curLeft = tLeft;
+
+ _screen->UpdateWhole();
+}
+
+void SciGUI::textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight) {
+ Common::Rect rect(0, 0, *textWidth, *textHeight);
+ _gfx->TextSize(rect, text, font, maxWidth);
+ *textWidth = rect.width(); *textHeight = rect.height();
+}
+
+// Used SCI1+ for text codes
+void SciGUI::textFonts(int argc, reg_t *argv) {
+}
+
+// Used SCI1+ for text codes
+void SciGUI::textColors(int argc, reg_t *argv) {
+}
+
+void SciGUI::drawPicture(sciResourceId pictureId, uint16 style, uint16 flags, int16 EGApaletteNo) {
+ bool addToFlag = flags ? true : false;
+
+ sciPort *oldPort = _gfx->SetPort((sciPort *)_windowMgr->_picWind);
+
+ if (_windowMgr->isFrontWindow(_windowMgr->_picWind)) {
+ _gfx->drawPicture(pictureId, style, addToFlag, EGApaletteNo);
+ } else {
+ _windowMgr->BeginUpdate(_windowMgr->_picWind);
+ _gfx->drawPicture(pictureId, style, addToFlag, EGApaletteNo);
+ _windowMgr->EndUpdate(_windowMgr->_picWind);
+ }
+ _screen->UpdateWhole();
+
+ _gfx->SetPort(oldPort);
+ _s->pic_not_valid = 1;
+}
+
+void SciGUI::drawCell(sciResourceId viewId, uint16 loopNo, uint16 cellNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo) {
+ _gfx->drawCell(viewId, loopNo, cellNo, leftPos, topPos, priority, paletteNo);
+ _gfx->SetCLUT(&_gfx->_sysPalette);
+ _screen->UpdateWhole();
+}
+
+void SciGUI::drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool inverse) {
+ rect.grow(1);
+ _gfx->EraseRect(rect);
+ _gfx->FrameRect(rect);
+ rect.grow(-2);
+ _gfx->TextFace(style & 1 ? 0 : 1);
+ _gfx->TextBox(text, 0, rect, 1, fontId);
+ _gfx->TextFace(0);
+ if (style & 8) { // selected
+ rect.grow(1);
+ _gfx->FrameRect(rect);
+ }
+ _screen->UpdateWhole();
+}
+
+void SciGUI::drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, bool inverse) {
+ rect.grow(1);
+ _gfx->EraseRect(rect);
+ rect.grow(-1);
+ _gfx->TextBox(text, 0, rect, mode, fontId);
+ if (style & 8) { // selected
+ _gfx->FrameRect(rect);
+ }
+ _screen->UpdateWhole();
+}
+
+void SciGUI::graphFillBoxForeground(Common::Rect rect) {
+ _gfx->PaintRect(rect);
+ _screen->UpdateWhole();
+}
+
+void SciGUI::graphFillBoxBackground(Common::Rect rect) {
+ _gfx->EraseRect(rect);
+ _screen->UpdateWhole();
+}
+
+void SciGUI::graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control) {
+ _gfx->FillRect(rect, colorMask, color, priority, control);
+ _screen->UpdateWhole();
+}
+
+void SciGUI::graphDrawLine(Common::Rect rect, int16 color, int16 priority, int16 control) {
+ _gfx->Draw_Line(rect.left, rect.top, rect.right, rect.bottom, color, priority, control);
+ _screen->UpdateWhole();
+}
+
+reg_t SciGUI::graphSaveBox(Common::Rect rect, uint16 flags) {
+ return _gfx->SaveBits(rect, flags);
+}
+
+void SciGUI::graphRestoreBox(reg_t handle) {
+ _gfx->RestoreBits(handle);
+ _screen->UpdateWhole();
+}
+
+void SciGUI::paletteSet(int resourceNo, int flags) {
+ _gfx->SetResPalette(resourceNo, flags);
+}
+
+int16 SciGUI::paletteFind(int r, int g, int b) {
+ return _gfx->MatchColor(&_gfx->_sysPalette, r, g, b) & 0xFF;
+}
+
+void SciGUI::paletteAnimate(int fromColor, int toColor, int speed) {
+ _gfx->animatePalette(fromColor, toColor, speed);
+}
+
+void SciGUI::moveCursor(int16 x, int16 y) {
+ Common::Point newPos;
+ sciPort *curPort = _gfx->GetPort();
+
+ x += _windowMgr->_picWind->rect.left;
+ y += _windowMgr->_picWind->rect.top;
+ newPos.x = CLIP<int16> (x, _windowMgr->_picWind->rect.left, _windowMgr->_picWind->rect.right - 1);
+ newPos.y = CLIP<int16> (y, _windowMgr->_picWind->rect.top, _windowMgr->_picWind->rect.bottom - 1);
+
+ gfxop_set_pointer_position(_s->gfx_state, newPos);
+}
+
+} // End of namespace Sci
Property changes on: scummvm/trunk/engines/sci/gui/gui.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/sci/gui/gui.h
===================================================================
--- scummvm/trunk/engines/sci/gui/gui.h (rev 0)
+++ scummvm/trunk/engines/sci/gui/gui.h 2009-10-03 20:49:18 UTC (rev 44565)
@@ -0,0 +1,86 @@
+/* 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/gui/gui_helpers.h"
+
+namespace Sci {
+
+class SciGUIscreen;
+class SciGUIgfx;
+class SciGUIresources;
+class SciGUIwindowMgr;
+class SciGUI {
+public:
+ SciGUI(OSystem *system, EngineState *s);
+ SciGUI();
+ ~SciGUI();
+
+ virtual void init(bool oldGfxFunctions);
+
+ virtual int16 getTimeTicks();
+ virtual void wait(int16 ticks);
+ virtual void setPort(uint16 portPtr);
+ virtual void setPortPic(Common::Rect rect, int16 picTop, int16 picLeft);
+ virtual reg_t getPort();
+ virtual void globalToLocal(int16 *x, int16 *y);
+ virtual void localToGlobal(int16 *x, int16 *y);
+ virtual reg_t newWindow(Common::Rect rect1, Common::Rect rect2, uint16 style, int16 priority, int16 colorPen, int16 colorBack, const char *title);
+ virtual void disposeWindow(uint16 windowPtr, int16 arg2);
+
+ virtual void display(const char *text, int argc, reg_t *argv);
+
+ virtual void textSize(const char *text, int16 font, int16 maxWidth, int16 *textWidth, int16 *textHeight);
+ virtual void textFonts(int argc, reg_t *argv);
+ virtual void textColors(int argc, reg_t *argv);
+
+ virtual void drawPicture(sciResourceId pictureId, uint16 showStyle, uint16 flags, int16 EGApaletteNo);
+ virtual void drawCell(sciResourceId viewId, uint16 loopNo, uint16 cellNo, uint16 leftPos, uint16 topPos, int16 priority, uint16 paletteNo);
+ virtual void drawControlButton(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 style, bool inverse);
+ virtual void drawControlText(Common::Rect rect, reg_t obj, const char *text, int16 fontId, int16 mode, int16 style, bool inverse);
+
+ virtual void graphFillBoxForeground(Common::Rect rect);
+ virtual void graphFillBoxBackground(Common::Rect rect);
+ virtual void graphFillBox(Common::Rect rect, uint16 colorMask, int16 color, int16 priority, int16 control);
+ virtual void graphDrawLine(Common::Rect rect, int16 color, int16 priority, int16 control);
+ virtual reg_t graphSaveBox(Common::Rect rect, uint16 flags);
+ virtual void graphRestoreBox(reg_t handle);
+
+ virtual void paletteSet(int resourceNo, int flags);
+ virtual int16 paletteFind(int r, int g, int b);
+ virtual void paletteAnimate(int fromColor, int toColor, int speed);
+
+ virtual void moveCursor(int16 x, int16 y);
+
+private:
+ OSystem *_system;
+ EngineState *_s;
+ SciGUIscreen *_screen;
+ SciGUIgfx *_gfx;
+ SciGUIresources *_resources;
+ SciGUIwindowMgr *_windowMgr;
+ bool _usesOldGfxFunctions;
+};
+
+} // End of namespace Sci
Property changes on: scummvm/trunk/engines/sci/gui/gui.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/sci/gui/gui_dbllist.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_dbllist.cpp (rev 0)
+++ scummvm/trunk/engines/sci/gui/gui_dbllist.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -0,0 +1,257 @@
+/* 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 "common/util.h"
+
+#include "sci/sci.h"
+#include "sci/gui/gui_helpers.h"
+#include "sci/gui/gui_memmgr.h"
+#include "sci/gui/gui_dbllist.h"
+
+namespace Sci {
+
+DblList::DblList() {
+ _hFirst = 0;
+ _hLast = 0;
+}
+
+DblList::DblList(HEAPHANDLE heap) {
+ byte *ptr = heap2Ptr(heap);
+ _hFirst = READ_UINT16(ptr);
+ _hLast = READ_UINT16(ptr + 2);
+}
+
+DblList::~DblList(void) {
+}
+//--------------------------------------
+// Prints all list contents
+void DblList::Dump(char*caption) {
+ debug("DumpList %s:", caption);
+ debug(" First: %04X Last: %04X", _hFirst, _hLast);
+ HEAPHANDLE node = _hFirst;
+ while (node) {
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ debug(" %04X key=%04X prev=%04X next=%04X add.data=%db", node,
+ pNode->key, pNode->prev, pNode->next, heapGetDataSize(node) - 6);
+ node = pNode->next;
+ }
+ debug("End of list");
+}
+//--------------------------------------
+// Add a new node to front of the list
+HEAPHANDLE DblList::AddToFront(HEAPHANDLE node, uint16 key) {
+ if (!node) {
+ warning("Bad node handler (%04X) passed to DblList::AddToFront !",
+ node);
+ return node;
+ }
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ pNode->key = key;
+ if (_hFirst) { // we already have a 1st node
+ sciNode *pnext = (sciNode *)heap2Ptr(_hFirst);
+ pnext->prev = node;
+ pNode->next = _hFirst;
+ } else { // list is empty, to passed node becames 1st one
+ _hLast = node;
+ pNode->next = 0;
+ }
+ _hFirst = node;
+ pNode->prev = 0;
+ return node;
+}
+
+//-------------------------------------
+//
+HEAPHANDLE DblList::AddToEnd(HEAPHANDLE node, uint16 key) {
+ if (!node) {
+ warning("Bad node handler (%04X) passed to DblList::AddToEnd !", node);
+ return node;
+ }
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ if (_hFirst) { // list is not empty
+ sciNode *plast = (sciNode *)heap2Ptr(_hLast);
+ plast->next = node;
+ pNode->prev = _hLast;
+ } else { // list is empty, so the node becames 1st one
+ _hFirst = node;
+ pNode->prev = 0;
+ }
+ _hLast = node;
+ pNode->next = 0;
+ pNode->key = key;
+
+ return node;
+}
+
+//------------------------------------------------
+// returns node that contains the key
+HEAPHANDLE DblList::FindKey(uint16 key) {
+ HEAPHANDLE node = _hFirst;
+ while (node) {
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ if (pNode->key == key)
+ break;
+ node = pNode->next;
+ }
+ return node;
+}
+//------------------------------------------------
+// detaches node with specified key and returning the node
+HEAPHANDLE DblList::DeleteKey(uint16 key) {
+ HEAPHANDLE node = FindKey(key);
+ if (node)
+ DeleteNode(node);
+ return node;
+}
+//------------------------------------------------
+// detaches specified node from list
+byte DblList::DeleteNode(HEAPHANDLE node) {
+ if (!node) {
+ warning("Bad node handler (%04X) passed to DblList::AddToEnd !", node);
+ return node;
+ }
+ // updating the links
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ if (pNode->prev) {
+ sciNode *pprev = (sciNode *)heap2Ptr(pNode->prev);
+ pprev->next = pNode->next;
+ }
+ if (pNode->next) {
+ sciNode *pnext = (sciNode *)heap2Ptr(pNode->next);
+ pnext->prev = pNode->prev;
+ }
+ // updating list head if needed
+ if (_hFirst == node)
+ _hFirst = pNode->next;
+ if (_hLast == node)
+ _hLast = pNode->prev;
+ pNode->prev = 0;
+ pNode->next = 0;
+ return 1;
+}
+//------------------------------------------------
+// Moves node to the end of the list
+HEAPHANDLE DblList::MoveToEnd(HEAPHANDLE node) {
+ if (!node) {
+ warning("Bad node handler (%04X) passed to DblList::MoveToEnd !", node);
+ return node;
+ }
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ if (pNode->next) { // node is not the last one in list
+ DeleteNode(node);
+ AddToEnd(node, pNode->key);
+ }
+ return node;
+}
+//------------------------------------------------
+// Moves node to the front of the list
+HEAPHANDLE DblList::MoveToFront(HEAPHANDLE node) {
+ if (!node) {
+ warning("Bad node handler (%04X) passed to DblList::MoveToFront !",
+ node);
+ return node;
+ }
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ if (pNode->prev) { // node is not 1st one in list
+ DeleteNode(node);
+ AddToFront(node, pNode->key);
+ }
+ return node;
+}
+//------------------------------------------------
+HEAPHANDLE DblList::AddAfter(HEAPHANDLE ref, HEAPHANDLE node, uint16 key) {
+ if (!node) {
+ warning("Bad node handler (%04X) passed to DblList::AddAfter !", node);
+ return node;
+ }
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ sciNode *pref = (sciNode *)heap2Ptr(ref);
+ pNode->key = key;
+ if (pref->next == 0) { // ref node is the last one
+ pNode->next = 0;
+ _hLast = node;
+ } else {
+ sciNode *pnext = (sciNode *)heap2Ptr(pref->next);
+ pNode->next = pref->next;
+ pnext->prev = node;
+ }
+ pref->next = node;
+ pNode->prev = ref;
+ return node;
+}
+//------------------------------------------------
+//
+HEAPHANDLE DblList::AddBefore(HEAPHANDLE ref, HEAPHANDLE node, uint16 key) {
+ if (!node) {
+ warning("Bad node handler (%04X) passed to DblList::AddBefore !", node);
+ return node;
+ }
+ sciNode *pNode = (sciNode *)heap2Ptr(node);
+ sciNode *pref = (sciNode *)heap2Ptr(ref);
+ pNode->key = key;
+ if (pref->prev == 0) { // ref node is the 1st one
+ pNode->prev = 0;
+ _hFirst = node;
+ } else {
+ sciNode*pprev = (sciNode *)heap2Ptr(pref->prev);
+ pNode->prev = pref->prev;
+ pprev->next = node;
+ }
+ pref->prev = node;
+ pNode->next = ref;
+ return node;
+}
+//------------------------------------------------
+void DblList::toHeap(HEAPHANDLE heap) {
+ byte *ptr = heap2Ptr(heap);
+ WRITE_UINT16(ptr, _hFirst);
+ WRITE_UINT16(ptr + 2, _hLast);
+}
+//------------------------------------------------
+void DblList::DeleteList() {
+ HEAPHANDLE node = getFirst(), next;
+ sciNode *pNode;
+ while (node) {
+ pNode = (sciNode *)heap2Ptr(node);
+ next = pNode->next;
+ heapDisposePtr(node);
+ node = next;
+ }
+ _hFirst = _hLast = 0;
+}
+//------------------------------------------------
+uint16 DblList::getSize() {
+ uint16 cnt = 0;
+ HEAPHANDLE node = getFirst();
+ sciNode *pNode;
+ while (node) {
+ pNode = (sciNode *)heap2Ptr(node);
+ node = pNode->next;
+ cnt++;
+ }
+ return cnt;
+}
+//------------------------------------------------
+} // end of namespace
Property changes on: scummvm/trunk/engines/sci/gui/gui_dbllist.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/sci/gui/gui_dbllist.h
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_dbllist.h (rev 0)
+++ scummvm/trunk/engines/sci/gui/gui_dbllist.h 2009-10-03 20:49:18 UTC (rev 44565)
@@ -0,0 +1,74 @@
+/* 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$
+ *
+ */
+
+/*
+ Each node contains handles to next and previous node and an optional key for searching
+ Head node contains handles to first and last node
+ */
+
+namespace Sci {
+
+typedef uint16 HEAPHANDLE;
+
+class DblList {
+public:
+ DblList();
+ DblList(HEAPHANDLE heap);
+ ~DblList(void);
+protected:
+ HEAPHANDLE _hFirst, _hLast;
+public:
+ // Add a new node to front of the list
+ HEAPHANDLE AddToFront(HEAPHANDLE node, uint16 key = 0);
+ HEAPHANDLE AddToEnd(HEAPHANDLE node, uint16 key = 0);
+ HEAPHANDLE MoveToEnd(HEAPHANDLE node);
+ HEAPHANDLE MoveToFront(HEAPHANDLE node);
+ HEAPHANDLE AddAfter(HEAPHANDLE ref, HEAPHANDLE node, uint16 key = 0);
+ HEAPHANDLE AddBefore(HEAPHANDLE ref, HEAPHANDLE node, uint16 key = 0);
+
+ HEAPHANDLE FindKey(uint16 key);
+ HEAPHANDLE DeleteKey(uint16 key);
+ byte DeleteNode(HEAPHANDLE node);
+ void DeleteList();
+ void Dump(char*caption = ""); // for debug
+ HEAPHANDLE getFirst() {
+ return _hFirst;
+ }
+ HEAPHANDLE getLast() {
+ return _hLast;
+ }
+ void toHeap(HEAPHANDLE heap);
+ bool isEmpty() {
+ return (_hFirst == 0 && _hLast == 0);
+ }
+ uint16 getSize();
+ void set(HEAPHANDLE first, HEAPHANDLE last){
+ _hFirst = first;
+ _hLast = last;
+ }
+
+};
+
+} // end of namespace
Property changes on: scummvm/trunk/engines/sci/gui/gui_dbllist.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/sci/gui/gui_font.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_font.cpp (rev 0)
+++ scummvm/trunk/engines/sci/gui/gui_font.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -0,0 +1,100 @@
+/* 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"
+#include "sci/engine/state.h"
+#include "sci/tools.h"
+#include "sci/gui/gui_screen.h"
+#include "sci/gui/gui_font.h"
+
+namespace Sci {
+
+SciGUIfont::SciGUIfont(OSystem *system, EngineState *state, SciGUIscreen *screen, sciResourceId resourceId)
+ : _system(system), _s(state), _screen(screen), _resourceId(resourceId) {
+ assert(resourceId != -1);
+ initData(resourceId);
+}
+
+SciGUIfont::~SciGUIfont() {
+}
+
+void SciGUIfont::initData(sciResourceId resourceId) {
+ Resource *fontResource = _s->resMan->findResource(ResourceId(kResourceTypeFont, resourceId), false);
+ if (!fontResource) {
+ error("font resource %d not found", resourceId);
+ }
+ _resourceData = fontResource->data;
+
+ mCharMax = READ_LE_UINT16(_resourceData + 2);
+ mFontH = READ_LE_UINT16(_resourceData + 4);
+ mChars = new charinfo[mCharMax];
+ // filling info for every char
+ for (int16 i = 0; i < mCharMax; i++) {
+ mChars[i].offset = READ_LE_UINT16(_resourceData + 6 + i * 2);
+ mChars[i].w = _resourceData[mChars[i].offset];
+ mChars[i].h = _resourceData[mChars[i].offset + 1];
+ }
+}
+
+sciResourceId SciGUIfont::getResourceId() {
+ return _resourceId;
+}
+
+byte SciGUIfont::getHeight() {
+ return mFontH;
+}
+byte SciGUIfont::getCharWidth(byte chr) {
+ return chr < mCharMax ? mChars[chr].w : 0;
+}
+byte SciGUIfont::getCharHeight(byte chr) {
+ return chr < mCharMax ? mChars[chr].h : 0;
+}
+byte *SciGUIfont::getCharData(byte chr) {
+ return chr < mCharMax ? _resourceData + mChars[chr].offset + 2 : 0;
+}
+
+void SciGUIfont::draw(int16 chr, int16 top, int16 left, byte color, byte textface) {
+ int charWidth = MIN<int>(getCharWidth(chr), _screen->_width - left);
+ int charHeight = MIN<int>(getCharHeight(chr), 200 - top);
+ byte b = 0, mask = 0xFF;
+ int pitch = _screen->_width;
+ int y = top;
+
+ byte *pIn = getCharData(chr);
+ for (int i = 0; i < charHeight; i++, y++) {
+ if (textface & 1) // "grayed" output
+ mask = top++ % 2 ? 0xAA : 0x55;
+ for (int done = 0; done < charWidth; done++) {
+ if ((done & 7) == 0) // fetching next data byte
+ b = *(pIn++) & mask;
+ if (b & 0x80) // if MSB is set - paint it
+ _screen->Put_Pixel(left + done, y, 1, color, 0, 0);
+ b = b << 1;
+ }
+ }
+
+}
+
+} // end of namespace Sci
Property changes on: scummvm/trunk/engines/sci/gui/gui_font.cpp
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/sci/gui/gui_font.h
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_font.h (rev 0)
+++ scummvm/trunk/engines/sci/gui/gui_font.h 2009-10-03 20:49:18 UTC (rev 44565)
@@ -0,0 +1,59 @@
+/* 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$
+ *
+ */
+
+namespace Sci {
+
+class SciGUIfont {
+public:
+ SciGUIfont(OSystem *system, EngineState *state, SciGUIscreen *screen, sciResourceId resourceId);
+ ~SciGUIfont();
+
+ sciResourceId getResourceId();
+ byte getHeight();
+ byte getCharWidth(byte chr);
+ byte getCharHeight(byte chr);
+ byte *getCharData(byte chr);
+ void draw(int16 chr, int16 top, int16 left, byte color, byte textface);
+
+private:
+ void initData(sciResourceId resourceId);
+
+ OSystem *_system;
+ EngineState *_s;
+ SciGUIscreen *_screen;
+
+ sciResourceId _resourceId;
+ byte *_resourceData;
+
+ struct charinfo {
+ byte w, h;
+ int16 offset;
+ };
+ byte mFontH;
+ uint16 mCharMax;
+ charinfo* mChars;
+};
+
+} // end of namespace Sci
Property changes on: scummvm/trunk/engines/sci/gui/gui_font.h
___________________________________________________________________
Added: svn:mime-type
+ text/plain
Added: svn:eol-style
+ native
Added: scummvm/trunk/engines/sci/gui/gui_gfx.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_gfx.cpp (rev 0)
+++ scummvm/trunk/engines/sci/gui/gui_gfx.cpp 2009-10-03 20:49:18 UTC (rev 44565)
@@ -0,0 +1,1194 @@
+/* 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 "common/timer.h"
+#include "common/util.h"
+
+#include "sci/sci.h"
+#include "sci/engine/state.h"
+#include "sci/tools.h"
+#include "sci/gui/gui_font.h"
+#include "sci/gui/gui_picture.h"
+#include "sci/gui/gui_view.h"
+#include "sci/gui/gui_screen.h"
+#include "sci/gui/gui_gfx.h"
+
+namespace Sci {
+
+static uint32 _sysTicks;
+
+SciGUIgfx::SciGUIgfx(OSystem *system, EngineState *state, SciGUIscreen *screen)
+ : _system(system), _s(state), _screen(screen) {
+ init();
+ initPalette();
+ initTimer();
+}
+
+SciGUIgfx::~SciGUIgfx() {
+ _system->getTimerManager()->removeTimerProc(&timerHandler);
+}
+
+void SciGUIgfx::init() {
+ uint16 a = 0;
+
+ _font = NULL;
+
+ _mainPort = mallocPort();
+ SetPort(_mainPort);
+ OpenPort(_mainPort);
+
+ _menuPort = mallocPort();
+ OpenPort(_menuPort);
+ SetFont(0);
+ _menuPort->rect = Common::Rect(0, 0, _screen->_width, _screen->_height);
+
+// HEAPHANDLE theMenuBarH = heapNewPtr(34, kDataPort, "MenuBar");
+// heapClearPtr(theMenuBarH);
+// _theMenuBar = (Common::Rect *)heap2Ptr(theMenuBarH);
+// *_theMenuBar = Common::Rect(_gfx->RGetPort()->rect.right, 10);
+
+ _sysTicks = 0;
+}
+
+void SciGUIgfx::initPalette() {
+ int16 i;
+ for (i = 0; i < 256; i++) {
+ _sysPalette.colors[i].used = 0;
+ _sysPalette.colors[i].r = 0;
+ _sysPalette.colors[i].g = 0;
+ _sysPalette.colors[i].b = 0;
+ _sysPalette.intencity[i] = 100;
+ _sysPalette.mapping[i] = i;
+ }
+ _sysPalette.colors[0].used = 1;
+ _sysPalette.colors[255].used = 1;
+ _sysPalette.colors[255].r = 255;
+ _sysPalette.colors[255].g = 255;
+ _sysPalette.colors[255].b = 255;
+ //if (g_sci->getPlatform() == Common::kPlatformAmiga)
+ // setAmigaPalette();
+ //else
+
+ // Load default palette from resource 999
+ if (!SetResPalette(999, 2)) {
+ // if not found, we set EGA palette
+ SetEGApalette();
+ };
+
+ // Init _clrPowers used in MatchColor
+ for(int16 i = 0; i < 256; i++)
+ _clrPowers[i] = i*i;
+}
+
+void SciGUIgfx::initTimer() {
+ _sysSpeed = 1000000 / 60;
+ Common::TimerManager *tm = _system->getTimerManager();
+ tm->removeTimerProc(&timerHandler);
+ tm->installTimerProc(&timerHandler, _sysSpeed, this);
+}
+
+void SciGUIgfx::timerHandler(void *ref) {
+ ((SciGUIgfx *)ref)->_sysTicks++;
+}
+
+sciPort *SciGUIgfx::mallocPort () {
+ sciPort *newPort = (sciPort *)malloc(sizeof(sciPort));
+ assert(newPort);
+ memset(newPort, 0, sizeof(sciPort));
+ return newPort;
+}
+
+#define SCI_PAL_FORMAT_CONSTANT 1
+#define SCI_PAL_FORMAT_VARIABLE 0
+
+void SciGUIgfx::SetEGApalette() {
+ int i;
+ _sysPalette.colors[1].r = 0x000; _sysPalette.colors[1].g = 0x000; _sysPalette.colors[1].b = 0x0AA;
+ _sysPalette.colors[2].r = 0x000; _sysPalette.colors[2].g = 0x0AA; _sysPalette.colors[2].b = 0x000;
+ _sysPalette.colors[3].r = 0x000; _sysPalette.colors[3].g = 0x0AA; _sysPalette.colors[3].b = 0x0AA;
+ _sysPalette.colors[4].r = 0x0AA; _sysPalette.colors[4].g = 0x000; _sysPalette.colors[4].b = 0x000;
+ _sysPalette.colors[5].r = 0x0AA; _sysPalette.colors[5].g = 0x000; _sysPalette.colors[5].b = 0x0AA;
+ _sysPalette.colors[6].r = 0x0AA; _sysPalette.colors[6].g = 0x055; _sysPalette.colors[6].b = 0x000;
+ _sysPalette.colors[7].r = 0x0AA; _sysPalette.colors[7].g = 0x0AA; _sysPalette.colors[7].b = 0x0AA;
+ _sysPalette.colors[8].r = 0x055; _sysPalette.colors[8].g = 0x055; _sysPalette.colors[8].b = 0x055;
+ _sysPalette.colors[9].r = 0x055; _sysPalette.colors[9].g = 0x055; _sysPalette.colors[9].b = 0x0FF;
+ _sysPalette.colors[10].r = 0x055; _sysPalette.colors[10].g = 0x0FF; _sysPalette.colors[10].b = 0x055;
+ _sysPalette.colors[11].r = 0x055; _sysPalette.colors[11].g = 0x0FF; _sysPalette.colors[11].b = 0x0FF;
+ _sysPalette.colors[12].r = 0x0FF; _sysPalette.colors[12].g = 0x055; _sysPalette.colors[12].b = 0x055;
+ _sysPalette.colors[13].r = 0x0FF; _sysPalette.colors[13].g = 0x055; _sysPalette.colors[13].b = 0x0FF;
+ _sysPalette.colors[14].r = 0x0FF; _sysPalette.colors[14].g = 0x0FF; _sysPalette.colors[14].b = 0x055;
+ _sysPalette.colors[15].r = 0x0FF; _sysPalette.colors[15].g = 0x0FF; _sysPalette.colors[15].b = 0x0FF;
+ for (i = 0; i <= 15; i++) {
+ _sysPalette.colors[i].used = 1;
+ }
+ for (i = 16; i <= 254; i++) {
+ _sysPalette.colors[i].r = 200;
+ _sysPalette.colors[i].used = 1;
+ }
+ SetCLUT(&_sysPalette);
+}
+
+void SciGUIgfx::CreatePaletteFromData(byte *data, sciPalette *paletteOut) {
+ int palFormat = 0;
+ int palOffset = 0;
+ int palColorStart = 0;
+ int palColorCount = 0;
+ int colorNo = 0;
+
+ memset(paletteOut, 0, sizeof(sciPalette));
+ if (data[0] == 0 && data[1] == 1) {
+ // SCI0/SCI1 palette
+ palFormat = SCI_PAL_FORMAT_VARIABLE; // CONSTANT;
+ palOffset = 260;
+ palColorStart = 0; palColorCount = 256;
+ } else {
+ // SCI1.1 palette
+ palFormat = data[32];
+ palOffset = 37;
+ palColorStart = READ_LE_UINT16(data + 25); palColorCount = READ_LE_UINT16(data + 29);
+ }
+ switch (palFormat) {
+ case SCI_PAL_FORMAT_CONSTANT:
+ for (colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) {
+ paletteOut->colors[colorNo].used = 1;
+ paletteOut->colors[colorNo].r = data[palOffset++];
+ paletteOut->colors[colorNo].g = data[palOffset++];
+ paletteOut->colors[colorNo].b = data[palOffset++];
+ }
+ break;
+ case SCI_PAL_FORMAT_VARIABLE:
+ for (colorNo = palColorStart; colorNo < palColorStart + palColorCount; colorNo++) {
+ paletteOut->colors[colorNo].used = data[palOffset++];
+ paletteOut->colors[colorNo].r = data[palOffset++];
+ paletteOut->colors[colorNo].g = data[palOffset++];
+ paletteOut->colors[colorNo].b = data[palOffset++];
+ }
+ break;
+ }
+}
+
+bool SciGUIgfx::SetResPalette(int16 resourceNo, int16 flag) {
+ Resource *palResource = _s->resMan->findResource(ResourceId(kResourceTypePalette, resourceNo), 0);
+ int palFormat = 0;
+ int palOffset = 0;
+ int palColorStart = 0;
+ int palColorCount = 0;
+ int colorNo = 0;
+ sciPalette palette = {0};
+
+ if (palResource) {
+ CreatePaletteFromData(palResource->data, &palette);
+ SetPalette(&palette, 2);
+ return true;
+ }
+ return false;
+}
+
+void SciGUIgfx::SetPalette(sciPalette *sciPal, int16 flag) {
+ uint32 systime = _sysPalette.timestamp;
+ if (flag == 2 || sciPal->timestamp != systime) {
+ MergePalettes(sciPal, &_sysPalette, flag);
+ sciPal->timestamp = _sysPalette.timestamp;
+ if (_s->pic_not_valid == 0 && systime != _sysPalette.timestamp)
+ SetCLUT(&_sysPalette);
+ }
+}
+
+void SciGUIgfx::MergePalettes(sciPalette *pFrom, sciPalette *pTo, uint16 flag) {
+ uint16 res;
+ int i,j;
+ // colors 0 (black) and 255 (white) are not affected by merging
+ for (i = 1 ; i < 255; i++) {
+ if (!pFrom->colors[i].used)// color is not used - so skip it
+ continue;
+ // forced palette merging or dest color is not used yet
+ if (flag == 2 || (!pTo->colors[i].used)) {
+ pTo->colors[i].used = pFrom->colors[i].used;
+ pTo->colors[i].r = pFrom->colors[i].r;
+ pTo->colors[i].g = pFrom->colors[i].g;
+ pTo->colors[i].b = pFrom->colors[i].b;
+ pFrom->mapping[i] = i;
+ continue;
+ }
+ // check if exact color could be matched
+ res = MatchColor(pTo, pFrom->colors[i].r, pFrom->colors[i].g, pFrom->colors[i].b);
+ if (res & 0x8000) { // exact match was found
+ pFrom->mapping[i] = res & 0xFF;
+ continue;
+ }
+ // no exact match - see if there is an unused color
+ for (j = 1; j < 256; j++)
+ if (!pTo->colors[j].used) {
+ pTo->colors[j].used = pFrom->colors[i].used;
+ pTo->colors[j].r = pFrom->colors[i].r;
+ pTo->colors[j].g = pFrom->colors[i].g;
+ pTo->colors[j].b = pFrom->colors[i].b;
+ pFrom->mapping[i] = j;
+ break;
+ }
+ // if still no luck - set an approximate color
+ if (j == 256) {
+ pFrom->mapping[i] = res & 0xFF;
+ pTo->colors[res & 0xFF].used |= 0x10;
+ }
+ }
+ pTo->timestamp = _sysTicks;
+}
+
+uint16 SciGUIgfx::MatchColor(sciPalette*pPal, byte r, byte g, byte b) {
+ byte found = 0xFF;
+ int diff = 0x2FFFF, cdiff;
+ int16 dr,dg,db;
+
+ for (int i = 0; i < 256; i++) {
+ if ((!pPal->colors[i].used))
+ continue;
+ dr = pPal->colors[i].r - r;
+ dg = pPal->colors[i].g - g;
+ db = pPal->colors[i].b - b;
+// minimum squares match
+ cdiff = _clrPowers[ABS(dr)] + _clrPowers[ABS(dg)] + _clrPowers[ABS(db)];
+// minimum sum match (Sierra's)
+// cdiff = ABS(dr) + ABS(dg) + ABS(db);
+ if (cdiff < diff) {
+ if (cdiff == 0)
+ return i | 0x8000; // setting this flag to indicate exact match
+ found = i;
+ diff = cdiff;
+ }
+ }
+ return found;
+}
+
+void SciGUIgfx::SetCLUT(sciPalette*pal) {
+ if (pal != &_sysPalette)
+ memcpy(&_sysPalette,pal,sizeof(sciPalette));
+ // just copy palette to system
+ byte bpal[4 * 256];
+ // Get current palette, update it and put back
+ _system->grabPalette(bpal, 0, 256);
+ for (int16 i = 0; i < 256; i++) {
+ if (!pal->colors[i].used)
+ continue;
+ bpal[i * 4] = pal->colors[i].r * pal->intencity[i] / 100;
+ bpal[i * 4 + 1] = pal->colors[i].g * pal->intencity[i] / 100;
+ bpal[i * 4 + 2] = pal->colors[i].b * pal->intencity[i] / 100;
+ bpal[i * 4 + 3] = 100;
+ }
+ _system->setPalette(bpal, 0, 256);
+ _system->updateScreen();
+}
+
+void SciGUIgfx::GetCLUT(sciPalette*pal) {
+ if (pal != &_sysPalette)
+ memcpy(pal,&_sysPalette,sizeof(sciPalette));
+}
+
+sciPort *SciGUIgfx::SetPort(sciPort *newPort) {
+ sciPort *oldPort = _curPort;
+ _curPort = newPort;
+ return oldPort;
+}
+
+sciPort *SciGUIgfx::GetPort(void) {
+ return _curPort;
+}
+
+void SciGUIgfx::SetOrigin(int16 left, int16 top) {
+ _curPort->left = left;
+ _curPort->top = top;
+}
+
+void SciGUIgfx::MoveTo(int16 left, int16 top) {
+ _curPort->curTop = top;
+ _curPort->curLeft = left;
+}
+
+void SciGUIgfx::Move(int16 left, int16 top) {
+ _curPort->curTop += top;
+ _curPort->curLeft += left;
+}
+
+int16 SciGUIgfx::GetFontId() {
+ return _curPort->fontId;
+}
+
+SciGUIfont *SciGUIgfx::GetFont() {
+ if ((_font == NULL) || (_font->getResourceId() != _curPort->fontId)) {
+ _font = new SciGUIfont(_system, _s, _screen, _curPort->fontId);
+ }
+ return _font;
+}
+
+void SciGUIgfx::SetFont(int16 fontId) {
+ if ((_font == NULL) || (_font->getResourceId() != fontId)) {
+ _font = new SciGUIfont(_system, _s, _screen, fontId);
+ }
+ _curPort->fontId = fontId;
+ _curPort->fontH = _font->getHeight();
+}
+
+void SciGUIgfx::OpenPort(sciPort *port) {
+ port->fontId = 0;
+ port->fontH = 8;
+
+ sciPort *tmp = _curPort;
+ _curPort = port;
+ SetFont(port->fontId);
+ _curPort = tmp;
+
+ port->top = 0;
+ port->left = 0;
+ port->textFace = 0;
+ port->penClr = 0;
+ port->backClr = 0xFF;
+ port->penMode = 0;
+ memcpy(&port->rect, &_bounds, sizeof(_bounds));
+}
+
+void SciGUIgfx::PenColor(int16 color) {
+ _curPort->penClr = color;
+}
+
+void SciGUIgfx::PenMode(int16 mode) {
+ _curPort->penMode = mode;
+}
+
+void SciGUIgfx::TextFace(int16 textFace) {
+ _curPort->textFace = textFace;
+}
+
+int16 SciGUIgfx::GetPointSize(void) {
+ return _curPort->fontH;
+}
+
+void SciGUIgfx::ClearScreen(byte color) {
+ FillRect(_curPort->rect, SCI_SCREEN_MASK_ALL, color, 0, 0);
+}
+
+void SciGUIgfx::InvertRect(const Common::Rect &rect) {
+ int16 oldpenmode = _curPort->penMode;
+ _curPort->penMode = 2;
+ FillRect(rect, 1, _curPort->penClr, _curPort->backClr);
+ _curPort->penMode = oldpenmode;
+}
+//-----------------------------
+void SciGUIgfx::EraseRect(const Common::Rect &rect) {
+ FillRect(rect, 1, _curPort->backClr);
+}
+//-----------------------------
+void SciGUIgfx::PaintRect(const Common::Rect &rect) {
+ FillRect(rect, 1, _curPort->penClr);
+}
+
+void SciGUIgfx::FillRect(const Common::Rect &rect, int16 drawFlags, byte clrPen, byte clrBack, byte bControl) {
+ Common::Rect r(rect.left, rect.top, rect.right, rect.bottom);
+ r.clip(_curPort->rect);
+ if (r.isEmpty()) // nothing to fill
+ return;
+
+ int16 oldPenMode = _curPort->penMode;
+ OffsetRect(r);
+ int16 w = r.width();
+ int16 h = r.height();
+ int16 x, y;
+ byte curVisual;
+
+ // Doing visual first
+ if (drawFlags & SCI_SCREEN_MASK_VISUAL) {
+ if (oldPenMode == 2) { // invert mode
+ for (y = r.top; y < r.bottom; y++) {
+ for (x = r.left; x < r.right; x++) {
+ curVisual = _screen->Get_Visual(x, y);
+ if (curVisual == clrPen) {
+ _screen->Put_Pixel(x, y, 1, clrBack, 0, 0);
+ } else if (curVisual == clrBack) {
+ _screen->Put_Pixel(x, y, 1, clrPen, 0, 0);
+ }
+ }
+ }
+ } else { // just fill rect with ClrPen
+ for (y = r.top; y < r.bottom; y++) {
+ for (x = r.left; x < r.right; x++) {
+ _screen->Put_Pixel(x, y, 1, clrPen, 0, 0);
+ }
+ }
+ }
+ }
+
+ if (drawFlags < 2)
+ return;
+ drawFlags &= SCI_SCREEN_MASK_PRIORITY|SCI_SCREEN_MASK_CONTROL;
+
+ if (oldPenMode != 2) {
+ for (y = r.top; y < r.bottom; y++) {
+ for (x = r.left; x < r.right; x++) {
+ _screen->Put_Pixel(x, y, drawFlags, 0, clrBack, bControl);
+ }
+ }
+ } else {
+ for (y = r.top; y < r.bottom; y++) {
+ for (x = r.left; x < r.right; x++) {
+ _screen->Put_Pixel(x, y, drawFlags, 0, !_screen->Get_Priority(x, y), !_screen->Get_Control(x, y));
+ }
+ }
+ }
+}
+
+void SciGUIgfx::FrameRect(const Common::Rect &rect) {
+ Common::Rect r;
+ // left
+ r = rect;
+ r.right = rect.left + 1;
+ PaintRect(r);
+ // right
+ r.right = rect.right;
+ r.left = rect.right - 1;
+ PaintRect(r);
+ //top
+ r.left = rect.left;
+ r.bottom = rect.top + 1;
+ PaintRect(r);
+ //bottom
+ r.bottom = rect.bottom;
+ r.top = rect.bottom - 1;
+ PaintRect(r);
+}
+
+void SciGUIgfx::OffsetRect(Common::Rect &r) {
+ r.top += _curPort->top;
+ r.bottom += _curPort->top;
+ r.left += _curPort->left;
+ r.right += _curPort->left;
+}
+
+byte SciGUIgfx::CharHeight(int16 ch) {
+#if 0
+ CResFont *res = getResFont();
+ return res ? res->getCharH(ch) : 0;
+#endif
+ return 0;
+}
+//-----------------------------
+byte SciGUIgfx::CharWidth(int16 ch) {
+ SciGUIfont *font = GetFont();
+ return font ? font->getCharWidth(ch) : 0;
+}
+//-----------------------------
+int16 SciGUIgfx::TextWidth(const char *text, int16 from, int16 len) {
+ SciGUIfont *font = GetFont();
+ if (font) {
+ int16 width = 0;
+ for (int i = from; i < len; i++)
+ width += _font->getCharWidth(text[i]);
+ return width;
+ }
+ return 0;
+}
+//-----------------------------
+void SciGUIgfx::ClearChar(int16 chr) {
+ if (_curPort->penMode != 1)
+ return;
+ Common::Rect rect;
+ rect.top = _curPort->curTop;
+ rect.bottom = rect.top + _curPort->fontH;
+ rect.left = _curPort->curLeft;
+ rect.right = rect.left + CharWidth(chr);
+ EraseRect(rect);
+}
+//-----------------------------
+void SciGUIgfx::DrawChar(int16 chr) {
+ chr = chr & 0xFF;
+ ClearChar(chr);
+ StdChar(chr);
+ _curPort->curLeft += CharWidth(chr);
+}
+//-----------------------------
+void SciGUIgfx::StdChar(int16 chr) {
+#if 0
+ CResFont*res = getResFont();
+ if (res)
+ res->Draw(chr, _curPort->top + _curPort->curTop, _curPort->left
+ + _curPort->curLeft, _vSeg, 320, _curPort->penClr,
+ _curPort->textFace);
+#endif
+}
+
+SCILanguage SciGUIgfx::getSCILanguage() {
+ return kLangEnglish;
+}
+
+char *SciGUIgfx::StrSplit(char *buff, const char *msg, const char *fmt) {
+ SCILanguage gameLang = getSCILanguage();
+ SCILanguage subtitleLang = kLangNone;
+ char *retval;
+// if (_theGame.getHandle())
+ //subtitleLang = (SCILanguage)_theGame.getProperty(0x58); // subtitleLang property
+
+ if (buff == msg) {
+ char str[2000];
+ getIntlString(str, msg, fmt, gameLang, subtitleLang);
+ retval = strcpy(buff, str);
+ } else
+ retval = getIntlString(buff, msg, fmt, gameLang, subtitleLang);
+ return retval;
+}
+//--------------------------------
+// In multilanguage game the msg has format ___english_text__#I___italian_text___
+// The function should place in buff a translated part of msg or the 1st one if a translation
+// does not exist
+char *SciGUIgfx::getIntlString(char *buff, const char *msg, const char *fmt, SCILanguage gameLang, SCILanguage subtitleLang) {
+
+ // prefer subtitleLang if set
+ SCILanguage lang = subtitleLang != kLangNone ? subtitleLang : gameLang;
+ const char *ptr = msg, *szFrom;
+ char ch;
+ int nLen = 0;
+ // searching for language code in msg
+ while (*ptr) {
+ ch = *(ptr + 1);
+ if(*ptr == '#' && (ch == 'I' || ch == 'F' || ch == 'G' || ch == 'S')) {
+ ptr +=2;
+ break;
+ }
+ ptr++;
+ }
+ // if a language code was found...
+ if (*ptr) {
+ if ((lang == kLangItalian && ch == 'I') || (lang == kLangFrench && ch == 'F') ||
+ (lang == kLangGerman && ch == 'G') || (lang == kLangSpanish && ch == 'S')) {
+ nLen = (int)strlen(ptr);
+ szFrom = ptr;
+ } else {
+ nLen = ptr - msg - 2;
+ szFrom = msg;
+ }
+ } else {
+ nLen = ptr - msg;
+ szFrom = msg;
+ }
+ if (fmt && subtitleLang != kLangNone) {
+ strcpy(buff, fmt);
+ strncat(buff, szFrom, nLen);
+ buff[nLen + strlen(fmt)] = 0;
+ } else {
+ strncpy(buff, szFrom, nLen);
+ buff[nLen] = 0;
+ }
+ return buff;
+}
+
+// TODO: implement codes
+int16 SciGUIgfx::TextSize(Common::Rect &rect, const char *str, int16 fontId, int16 maxwidth) {
+ char buff[1000] = { 0 };
+ int16 oldfont = GetFontId();
+ if (fontId != -1)
+ SetFont(fontId);
+ rect.top = rect.left = 0;
+
+ if (maxwidth < 0) { // force output as single line
+ rect.bottom = GetPointSize();
+ rect.right = StringWidth(str);
+ } else {
+ // rect.right=found widest line with RTextWidth and GetLongest
+ // rect.bottom=num. lines * GetPointSize
+ rect.right = (maxwidth ? maxwidth : 192);
+ int16 height = 0, maxWidth = 0, width, nc;
+ const char*p = str;
+ while (*p) {
+ if (*p == 0xD || *p == 0xA) {
+ p++;
+ continue;
+ }
+ nc = GetLongest(p, rect.right);
+ if (nc == 0)
+ break;
+ width = TextWidth(p, 0, nc);
+ maxWidth = MAX(width, maxWidth);
+ p += nc;
+ height++;
+ }
+ rect.bottom = height * GetPointSize();
+ rect.right = maxwidth ? maxwidth : MIN(rect.right, maxWidth);
+ }
+ SetFont(oldfont);
+ return rect.right;
+}
+
+// TODO: implement codes
+// return max # of chars to fit maxwidth with full words
+int16 SciGUIgfx::GetLongest(const char *str, int16 maxWidth) {
+ SciGUIfont *font = GetFont();
+ if (!font)
+ return 0;
+
+ int16 chars = 0, to = 0;
+ uint16 width = 0;
+ while (width <= maxWidth) {
+ switch (str[to]) {
+ case ' ':
+ chars = to + 1;
+ break;
+ case 0:
+ case 0xD:
+ case 0xA:
+ return to;
+ }
+ width += font->getCharWidth(str[to]);
+ to++;
+ }
+ return chars;
+}
+
+// TODO: implement codes
+void SciGUIgfx::DrawText(const char *text, int16 from, int16 len) {
+ int16 chr, width;
+ SciGUIfont *font = GetFont();
+ Common::Rect rect;
+
+ if (!font)
+ return;
+
+ text += from;
+ rect.top = _curPort->curTop;
+ rect.bottom = rect.top + _curPort->fontH;
+ while (len--) {
+ chr = (*text++) & 0xFF;
+ width = font->getCharWidth(chr);
+ // clear char
+ if (_curPort->penMode == 1) {
+ rect.left = _curPort->curLeft;
+ rect.right = rect.left + width;
+ EraseRect(rect);
+ }
+ // CharStd
+ font->draw(chr, _curPort->top + _curPort->curTop, _curPort->left + _curPort->curLeft, _curPort->penClr, _curPort->textFace);
+ _curPort->curLeft += width;
+ }
+}
+
+void SciGUIgfx::ShowText(const char *text, int16 from, int16 len) {
+ Common::Rect rect;
+
+ rect.top = _curPort->curTop;
+ rect.bottom = rect.top + GetPointSize();
+ rect.left = _curPort->curLeft;
+ DrawText(text, from, len);
+ rect.right = _curPort->curLeft;
+ ShowBits(rect, 1);
+}
+
+// Draws a text in rect.
+// align : -1-right , 0-left, 1-center
+void SciGUIgfx::TextBox(const char *text, int16 bshow, const Common::Rect &rect, int16 align, int16 fontId) {
+ int16 w, nc, offset;
+ int16 hline = 0;
+ int16 oldfont = GetFontId();
+ int16 rectWidth = rect.width();
+
+ if (fontId != -1)
+ SetFont(fontId);
+
+ while (*text) {
+ if (*text == 0xD || *text == 0xA) {
+ text++;
+ continue;
+ }
+ nc = GetLongest(text, rect.width());
+ if (nc == 0)
+ break;
+ w = TextWidth(text, 0, nc);
+ switch (align) {
+ case -1:
+ offset = rect.width() - w;
+ break;
+ case 1:
+ offset = (rect.width() - w) / 2;
+ break;
+ default:
+ offset = 0;
+ }
+ MoveTo(rect.left + offset, rect.top + hline);
+
+ if (bshow)
+ ShowText(text, 0, nc);
+ else
+ DrawText(text, 0, nc);
+ hline += GetPointSize();
+ text += nc;
+ }
+ SetFont(oldfont);
+}
+
+// Update (part of) screen
+void SciGUIgfx::ShowBits(const Common::Rect &r, uint16 flags) {
+ Common::Rect rect(r.left, r.top, r.right, r.bottom);
+ rect.clip(_curPort->rect);
+ if (rect.isEmpty()) // nothing to show
+ return;
+
+ OffsetRect(rect);
+ uint16 w = rect.width();
+ uint16 h = rect.height();
+ assert((flags&0x8000) == 0);
+ _screen->UpdateWhole();
+// _system->copyRectToScreen(GetSegment(flags) + _baseTable[rect.top] + rect.left, 320, rect.left, rect.top, w, h);
+// _system->updateScreen();
+}
+
+sciMemoryHandle SciGUIgfx::SaveBits(const Common::Rect &rect, byte screenMask) {
+ sciMemoryHandle memoryId;
+ byte *memoryPtr;
+ int size;
+
+ Common::Rect r(rect.left, rect.top, rect.right, rect.bottom);
+ r.clip(_curPort->rect);
+ if (r.isEmpty()) // nothing to save
+ return NULL_REG;
+
+ OffsetRect(r); //local port coords to screen coords
+
+ // now actually ask _screen how much space it will need for saving
+ size = _screen->BitsGetDataSize(r, screenMask);
+
+ memoryId = kalloc(_s->segMan, "SaveBits()", size);
+ memoryPtr = kmem(_s->segMan, memoryId);
+ _screen->BitsSave(r, screenMask, memoryPtr);
+ return memoryId;
+}
+
+void SciGUIgfx::RestoreBits(sciMemoryHandle memoryHandle) {
+ byte *memoryPtr = kmem(_s->segMan, memoryHandle);;
+
+ if (memoryPtr) {
+ _screen->BitsRestore(memoryPtr);
+ kfree(_s->segMan, memoryHandle);
+ }
+}
+
+void SciGUIgfx::Draw_Line(int16 left, int16 top, int16 right, int16 bottom, byte color, byte prio, byte control) {
+ //set_drawing_flag
+ byte flag = _screen->GetDrawingMask(color, prio, control);
+ prio &= 0xF0;
+ control &= 0x0F;
+
+ // offseting the line
+ left += _curPort->left;
+ right += _curPort->left;
+ top += _curPort->top;
+ bottom += _curPort->top;
+ // horizontal line
+ if (top == bottom) {
+ Draw_Horiz(left, right, top, flag, color, prio, control);
+ return;
+ }
+ // vertical line
+ if (left == right) {
+ Draw_Vert(top, bottom, left, flag, color, prio, control);
+ return;
+ }
+ // sloped line - draw with Bresenham algorithm
+ int dy = bottom - top;
+ int dx = right - left;
+ int stepy = dy < 0 ? -1 : 1;
+ int stepx = dx < 0 ? -1 : 1;
+ dy = ABS(dy) << 1;
+ dx = ABS(dx) << 1;
+
+ // setting the 1st and last pixel
+ _screen->Put_Pixel(left, top, flag, color, prio, control);
+ _screen->Put_Pixel(right, bottom, flag, color, prio, control);
+ // drawing the line
+ if (dx > dy) // going horizontal
+ {
+ int fraction = dy - (dx >> 1);
+ while (left != right) {
+ if (fraction >= 0) {
+ top += stepy;
+ fraction -= dx;
+ }
+ left += stepx;
+ fraction += dy;
+ _screen->Put_Pixel(left, top, flag, color, prio, control);
+ }
+ } else // going vertical
+ {
+ int fraction = dx - (dy >> 1);
+ while (top != bottom) {
+ if (fraction >= 0) {
+ left += stepx;
+ fraction -= dy;
+ }
+ top += stepy;
+ fraction += dx;
+ _screen->Put_Pixel(left, top, flag, color, prio, control);
+ }
+ }
+ //g_sci->eventMgr->waitUntil(5);
+ //ShowBits(&_rThePort->rect,6);
+}
+
+void SciGUIgfx::Draw_Horiz(int16 left, int16 right, int16 top, byte flag, byte color, byte prio, byte control) {
+ if (right < left)
+ SWAP(right, left);
+ for (int i = left; i <= right; i++)
+ _screen->Put_Pixel(i, top, flag, color, prio, control);
+}
+
+//--------------------------------
+void SciGUIgfx::Draw_Vert(int16 top, int16 bottom, int16 left, byte flag, byte color, byte prio, byte control) {
+ if (top > bottom)
+ SWAP(top, bottom);
+ for (int i = top; i <= bottom; i++)
+ _screen->Put_Pixel(left, i, flag, color, prio, control);
+}
+
+// Bitmap for drawing sierra circles
+const byte pattern_Circles[8][15] = {
+ { 0x01 },
+ { 0x03, 0x03, 0x03 },
+ { 0x02, 0x07, 0x07, 0x07, 0x02 },
+ { 0x06, 0x06, 0x0F, 0x0F, 0x0F, 0x06, 0x06 },
+ { 0x04, 0x0E, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x04 },
+ { 0x0C, 0x1E, 0x1E, 0x1E, 0x3F, 0x3F, 0x3F, 0x1E, 0x1E, 0x1E, 0x0C },
+ { 0x1C, 0x3E, 0x3E, 0x3E, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x3E, 0x3E, 0x3E, 0x1C },
+ { 0x18, 0x3C, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x3C, 0x18 }
+};
+
+const bool pattern_Textures[32 * 8 * 2] = {
+ false, false, false, false, false, true, false, false, // 0x20
+ false, false, true, false, true, false, false, true, // 0x94
+ false, true, false, false, false, false, false, false, // 0x02
+ false, false, true, false, false, true, false, false, // 0x24
+ false, false, false, false, true, false, false, true, // 0x90
+ false, true, false, false, false, false, false, true, // 0x82
+ false, false, true, false, false, true, false, true, // 0xA4
+ false, true, false, false, false, true, false, true, // 0xA2
+ false, true, false, false, false, false, false, true, // 0x82
+ true, false, false, true, false, false, false, false, // 0x09
+ false, true, false, true, false, false, false, false, // 0x0A
+ false, true, false, false, false, true, false, false, // 0x22
+ false, true, false, false, true, false, false, false, // 0x12
+ false, false, false, false, true, false, false, false, // 0x10
+ false, true, false, false, false, false, true, false, // 0x42
+ false, false, true, false, true, false, false, false, // 0x14
+ true, false, false, false, true, false, false, true, // 0x91
+ false, true, false, true, false, false, true, false, // 0x4A
+ true, false, false, false, true, false, false, true, // 0x91
+ true, false, false, false, true, false, false, false, // 0x11
+ false, false, false, true, false, false, false, false, // 0x08
+ false, true, false, false, true, false, false, false, // 0x12
+ true, false, true, false, false, true, false, false, // 0x25
+ false, false, false, false, true, false, false, false, // 0x10
+ false, true, false, false, false, true, false, false, // 0x22
@@ Diff output truncated at 100000 characters. @@
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list