diff options
Diffstat (limited to 'engines/sci')
-rw-r--r-- | engines/sci/engine/kgraphics.cpp | 366 | ||||
-rw-r--r-- | engines/sci/gui32/gui32.cpp | 460 |
2 files changed, 393 insertions, 433 deletions
diff --git a/engines/sci/engine/kgraphics.cpp b/engines/sci/engine/kgraphics.cpp index aedaee39cf..3d49511aa8 100644 --- a/engines/sci/engine/kgraphics.cpp +++ b/engines/sci/engine/kgraphics.cpp @@ -43,11 +43,6 @@ namespace Sci { -#undef DEBUG_LSRECT - -// This is the real width of a text with a specified width of 0 -#define MAX_TEXT_WIDTH_MAGIC_VALUE 192 - // Graph subfunctions enum { K_GRAPH_GET_COLORS_NR = 2, @@ -65,225 +60,6 @@ enum { K_GRAPH_ADJUST_PRIORITY = 14 }; -#define ADD_TO_CURRENT_PORT(widget) \ - {if (s->port) \ - s->port->add((GfxContainer *)s->port, widget); \ - else \ - s->picture_port->add((GfxContainer *)s->visual, widget);} - -#define ADD_TO_CURRENT_PICTURE_PORT(widget) \ - {if (s->port) \ - s->port->add((GfxContainer *)s->port, widget); \ - else \ - s->picture_port->add((GfxContainer *)s->picture_port, widget);} - -#define ADD_TO_WINDOW_PORT(widget) \ - s->wm_port->add((GfxContainer *)s->wm_port, widget); - -#define FULL_REDRAW()\ - if (s->visual) \ - s->visual->draw(gfxw_point_zero); \ - gfxop_update(s->gfx_state); - -#if 0 -// Used for debugging -#define FULL_INSPECTION()\ - if (s->visual) \ - s->visual->print(s->visual, 0); -#endif - -static inline int sign_extend_byte(int value) { - if (value & 0x80) - return value - 256; - else - return value; -} - -// was static -void assert_primary_widget_lists(EngineState *s) { - if (!s->dyn_views) { - rect_t bounds = s->picture_port->_bounds; - - s->dyn_views = gfxw_new_list(bounds, GFXW_LIST_SORTED); - s->dyn_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - ADD_TO_CURRENT_PICTURE_PORT(s->dyn_views); - } - - if (!s->drop_views) { - rect_t bounds = s->picture_port->_bounds; - - s->drop_views = gfxw_new_list(bounds, GFXW_LIST_SORTED); - s->drop_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; - ADD_TO_CURRENT_PICTURE_PORT(s->drop_views); - } -} - -// static -void reparentize_primary_widget_lists(EngineState *s, GfxPort *newport) { - if (!newport) - newport = s->picture_port; - - if (s->dyn_views) { - gfxw_remove_widget_from_container(s->dyn_views->_parent, s->dyn_views); - - newport->add((GfxContainer *)newport, s->dyn_views); - } -} - -int _find_view_priority(EngineState *s, int y) { - /*if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1) - ++y; */ - - if (s->pic_priority_table) { // SCI01 priority table set? - int j; - for (j = 0; j < 15; j++) - if (y < s->pic_priority_table[j+1]) - return j; - return 14; // Maximum - } else { - if (!s->usesOldGfxFunctions()) - return SCI0_VIEW_PRIORITY_14_ZONES(y); - else - return SCI0_VIEW_PRIORITY(y) == 15 ? 14 : SCI0_VIEW_PRIORITY(y); - } -} - -int _find_priority_band(EngineState *s, int nr) { - if (!s->usesOldGfxFunctions() && (nr < 0 || nr > 14)) { - if (nr == 15) - return 0xffff; - else { - warning("Attempt to get priority band %d", nr); - } - return 0; - } - - if (s->usesOldGfxFunctions() && (nr < 0 || nr > 15)) { - warning("Attempt to get priority band %d", nr); - return 0; - } - - if (s->pic_priority_table) // SCI01 priority table set? - return s->pic_priority_table[nr]; - else { - int retval; - - if (!s->usesOldGfxFunctions()) - retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr); - else - retval = SCI0_PRIORITY_BAND_FIRST(nr); - -/* if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1) - --retval; */ - return retval; - } -} - -reg_t graph_save_box(EngineState *s, rect_t area) { - reg_t handle = kalloc(s->_segMan, "graph_save_box()", sizeof(gfxw_snapshot_t *)); - gfxw_snapshot_t **ptr = (gfxw_snapshot_t **)kmem(s->_segMan, handle); - - // FIXME: gfxw_make_snapshot returns a pointer. Now why do we store a - // pointer to real memory inside the SCI heap? - // If we save and the load again, this cannot work in general. - // This seems like bad design. Either the snapshot data itself should be - // stored in the heap, or a unique persistent id. - *ptr = gfxw_make_snapshot(s->visual, area); - - return handle; -} - -void graph_restore_box(EngineState *s, reg_t handle) { - gfxw_snapshot_t **ptr; - int port_nr = s->port->_ID; - - if (!handle.segment) { - warning("Attempt to restore box with zero handle"); - return; - } - - ptr = (gfxw_snapshot_t **)kmem(s->_segMan, handle); - - if (!ptr) { - warning("Attempt to restore invalid handle %04x:%04x", PRINT_REG(handle)); - return; - } - - while (port_nr > 2 && !(s->port->_flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS) && (gfxw_widget_matches_snapshot(*ptr, s->port))) { - // This shouldn't ever happen, actually, since windows (ports w/ ID > 2) should all be immune - GfxPort *newport = s->visual->getPort(port_nr); - error("Port %d is not immune against snapshots", s->port->_ID); - port_nr--; - if (newport) - s->port = newport; - } - - if (s->dyn_views && gfxw_widget_matches_snapshot(*ptr, s->dyn_views->_parent)) { - GfxContainer *parent = s->dyn_views->_parent; - - do { - parent = parent->_parent; - } while (parent && (gfxw_widget_matches_snapshot(*ptr, parent))); - - if (!parent) { - error("Attempted widget mass destruction by a snapshot"); - } - - reparentize_primary_widget_lists(s, (GfxPort *) parent); - } - - - if (!ptr) { - error("Attempt to restore invalid snaphot with handle %04x:%04x", PRINT_REG(handle)); - return; - } - - gfxw_restore_snapshot(s->visual, *ptr); - free(*ptr); - *ptr = NULL; - - kfree(s->_segMan, handle); -} - -PaletteEntry get_pic_color(EngineState *s, int color) { - if (!s->resMan->isVGA()) - return s->ega_colors[color].visual; - - if (color == -1 || color == 255) // -1 occurs in Eco Quest 1. Not sure if this is the best approach, but it seems to work - return PaletteEntry(255,255,255); - else if (color < s->gfx_state->gfxResMan->getColorCount()) - return s->gfx_state->gfxResMan->getColor(color); - else { - // Happens in the beginning of EcoQuest 2, when the dialog box of the customs officer shows up - warning("Color index %d out of bounds for pic %d (%d max)", color, s->gfx_state->pic_nr, s->gfx_state->gfxResMan->getColorCount()); - return PaletteEntry(0,0,0); - } -} - -void _k_redraw_box(EngineState *s, int x1, int y1, int x2, int y2) { - warning("_k_redraw_box(): Unimplemented"); -#if 0 - int i; - ViewObject *list = s->dyn_views; - - printf("Reanimating views\n", s->dyn_views_nr); - - for (i = 0;i < s->dyn_views_nr;i++) { - *(list[i].underBitsp) = graph_save_box(s, list[i].nsLeft, list[i].nsTop, list[i].nsRight - list[i].nsLeft, - list[i].nsBottom - list[i].nsTop, SCI_MAP_VISUAL | SCI_MAP_PRIORITY); - draw_view0(s->pic, s->ports[0], list[i].nsLeft, list[i].nsTop, list[i].priority, list[i].loop, - list[i].cel, 0, list[i].view); - } - - graph_update_box(s, x1, y1, x2 - x1, y2 - y1); - - for (i = 0;i < s->dyn_views_nr;i++) { - graph_restore_box(s, *(list[i].underBitsp)); - list[i].underBits = 0; - } -#endif -} - void _k_dirloop(reg_t obj, uint16 angle, EngineState *s, int argc, reg_t *argv) { SegManager *segMan = s->_segMan; int view = GET_SEL32V(obj, view); @@ -328,140 +104,6 @@ void _k_dirloop(reg_t obj, uint16 angle, EngineState *s, int argc, reg_t *argv) PUT_SEL32V(obj, loop, loop); } -Common::Rect set_base(EngineState *s, reg_t object) { - SegManager *segMan = s->_segMan; - int x, y, original_y, z, ystep, xsize, ysize; - int xbase, ybase, xend, yend; - int view, loop, cel; - int oldloop, oldcel; - int xmod = 0, ymod = 0; - Common::Rect retval; - - x = (int16)GET_SEL32V(object, x); - original_y = y = (int16)GET_SEL32V(object, y); - - if (s->_kernel->_selectorCache.z > -1) - z = (int16)GET_SEL32V(object, z); - else - z = 0; - - y -= z; // Subtract z offset - - ystep = (int16)GET_SEL32V(object, yStep); - - view = (int16)GET_SEL32V(object, view); - oldloop = loop = sign_extend_byte(GET_SEL32V(object, loop)); - oldcel = cel = sign_extend_byte(GET_SEL32V(object, cel)); - - Common::Point offset = Common::Point(0, 0); - - if (loop != oldloop) { - loop = 0; - PUT_SEL32V(object, loop, 0); - debugC(2, kDebugLevelGraphics, "Resetting loop for %04x:%04x!\n", PRINT_REG(object)); - } - - if (cel != oldcel) { - cel = 0; - PUT_SEL32V(object, cel, 0); - } - - gfxop_get_cel_parameters(s->gfx_state, view, loop, cel, &xsize, &ysize, &offset); - - xmod = offset.x; - ymod = offset.y; - - xbase = x - xmod - (xsize >> 1); - xend = xbase + xsize; - yend = y /* - ymod */ + 1; - ybase = yend - ystep; - - debugC(2, kDebugLevelBaseSetter, "(%d,%d)+/-(%d,%d), (%d x %d) -> (%d, %d) to (%d, %d)\n", - x, y, xmod, ymod, xsize, ysize, xbase, ybase, xend, yend); - - retval.left = xbase; - retval.top = ybase; - retval.right = xend; - retval.bottom = yend; - - return retval; -} - -static Common::Rect nsrect_clip(EngineState *s, int y, Common::Rect retval, int priority) { - int pri_top; - - if (priority == -1) - priority = _find_view_priority(s, y); - - pri_top = _find_priority_band(s, priority) + 1; - // +1: Don't know why, but this seems to be happening - - if (retval.top < pri_top) - retval.top = pri_top; - - if (retval.bottom < retval.top) - retval.top = retval.bottom - 1; - - return retval; -} - -static Common::Rect calculate_nsrect(EngineState *s, int x, int y, int view, int loop, int cel) { - int xbase, ybase, xend, yend, xsize, ysize; - int xmod = 0, ymod = 0; - Common::Rect retval(0, 0, 0, 0); - - Common::Point offset = Common::Point(0, 0); - - gfxop_get_cel_parameters(s->gfx_state, view, loop, cel, &xsize, &ysize, &offset); - - xmod = offset.x; - ymod = offset.y; - - xbase = x - xmod - (xsize >> 1); - xend = xbase + xsize; - yend = y - ymod + 1; // +1: magic modifier - ybase = yend - ysize; - - retval.left = xbase; - retval.top = ybase; - retval.right = xend; - retval.bottom = yend; - - return retval; -} - -Common::Rect get_nsrect(EngineState *s, reg_t object, byte clip) { - SegManager *segMan = s->_segMan; - int x, y, z; - int view, loop, cel; - Common::Rect retval; - - x = (int16)GET_SEL32V(object, x); - y = (int16)GET_SEL32V(object, y); - - if (s->_kernel->_selectorCache.z > -1) - z = (int16)GET_SEL32V(object, z); - else - z = 0; - - y -= z; // Subtract z offset - - view = (int16)GET_SEL32V(object, view); - loop = sign_extend_byte((int16)GET_SEL32V(object, loop)); - cel = sign_extend_byte((int16)GET_SEL32V(object, cel)); - - retval = calculate_nsrect(s, x, y, view, loop, cel); - - if (clip) { - int priority = (int16)GET_SEL32V(object, priority); - return nsrect_clip(s, y, retval, priority); - } - - return retval; -} - - -// ====================================================================================================== static reg_t kSetCursorSci0(EngineState *s, int argc, reg_t *argv) { Common::Point pos; GuiResourceId cursorId = argv[0].toSint16(); @@ -1073,8 +715,12 @@ void _k_GenericDrawControl(EngineState *s, reg_t controlObject, bool hilite) { case SCI_CONTROLS_TYPE_ICON: viewId = GET_SEL32V(controlObject, view); - loopNo = sign_extend_byte(GET_SEL32V(controlObject, loop)); - celNo = sign_extend_byte(GET_SEL32V(controlObject, cel)); + { + int l = GET_SEL32V(controlObject, loop); + loopNo = (l & 0x80) ? l - 256 : l; + int c = GET_SEL32V(controlObject, cel); + celNo = (c & 0x80) ? c - 256 : c; + } debugC(2, kDebugLevelGraphics, "drawing icon control %04x:%04x to %d,%d\n", PRINT_REG(controlObject), x, y - 1); s->_gui->drawControlIcon(rect, controlObject, viewId, loopNo, celNo, style, hilite); return; diff --git a/engines/sci/gui32/gui32.cpp b/engines/sci/gui32/gui32.cpp index 83c12d5c37..e6a525dd9b 100644 --- a/engines/sci/gui32/gui32.cpp +++ b/engines/sci/gui32/gui32.cpp @@ -66,6 +66,393 @@ namespace Sci { +#undef DEBUG_LSRECT + +// This is the real width of a text with a specified width of 0 +#define MAX_TEXT_WIDTH_MAGIC_VALUE 192 + +#define ADD_TO_CURRENT_PORT(widget) \ + {if (s->port) \ + s->port->add((GfxContainer *)s->port, widget); \ + else \ + s->picture_port->add((GfxContainer *)s->visual, widget);} + +#define ADD_TO_CURRENT_PICTURE_PORT(widget) \ + {if (s->port) \ + s->port->add((GfxContainer *)s->port, widget); \ + else \ + s->picture_port->add((GfxContainer *)s->picture_port, widget);} + +#define ADD_TO_WINDOW_PORT(widget) \ + s->wm_port->add((GfxContainer *)s->wm_port, widget); + +#define FULL_REDRAW()\ + if (s->visual) \ + s->visual->draw(gfxw_point_zero); \ + gfxop_update(s->gfx_state); + +#if 0 +// Used for debugging +#define FULL_INSPECTION()\ + if (s->visual) \ + s->visual->print(s->visual, 0); +#endif + +// was static +void assert_primary_widget_lists(EngineState *s) { + if (!s->dyn_views) { + rect_t bounds = s->picture_port->_bounds; + + s->dyn_views = gfxw_new_list(bounds, GFXW_LIST_SORTED); + s->dyn_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; + ADD_TO_CURRENT_PICTURE_PORT(s->dyn_views); + } + + if (!s->drop_views) { + rect_t bounds = s->picture_port->_bounds; + + s->drop_views = gfxw_new_list(bounds, GFXW_LIST_SORTED); + s->drop_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; + ADD_TO_CURRENT_PICTURE_PORT(s->drop_views); + } +} + +// static +void reparentize_primary_widget_lists(EngineState *s, GfxPort *newport) { + if (!newport) + newport = s->picture_port; + + if (s->dyn_views) { + gfxw_remove_widget_from_container(s->dyn_views->_parent, s->dyn_views); + + newport->add((GfxContainer *)newport, s->dyn_views); + } +} + +int _find_view_priority(EngineState *s, int y) { + /*if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1) + ++y; */ + + if (s->pic_priority_table) { // SCI01 priority table set? + int j; + for (j = 0; j < 15; j++) + if (y < s->pic_priority_table[j+1]) + return j; + return 14; // Maximum + } else { + if (!s->usesOldGfxFunctions()) + return SCI0_VIEW_PRIORITY_14_ZONES(y); + else + return SCI0_VIEW_PRIORITY(y) == 15 ? 14 : SCI0_VIEW_PRIORITY(y); + } +} + +int _find_priority_band(EngineState *s, int nr) { + if (!s->usesOldGfxFunctions() && (nr < 0 || nr > 14)) { + if (nr == 15) + return 0xffff; + else { + warning("Attempt to get priority band %d", nr); + } + return 0; + } + + if (s->usesOldGfxFunctions() && (nr < 0 || nr > 15)) { + warning("Attempt to get priority band %d", nr); + return 0; + } + + if (s->pic_priority_table) // SCI01 priority table set? + return s->pic_priority_table[nr]; + else { + int retval; + + if (!s->usesOldGfxFunctions()) + retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES(nr); + else + retval = SCI0_PRIORITY_BAND_FIRST(nr); + +/* if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1) + --retval; */ + return retval; + } +} + +reg_t graph_save_box(EngineState *s, rect_t area) { + reg_t handle = kalloc(s->_segMan, "graph_save_box()", sizeof(gfxw_snapshot_t *)); + gfxw_snapshot_t **ptr = (gfxw_snapshot_t **)kmem(s->_segMan, handle); + + // FIXME: gfxw_make_snapshot returns a pointer. Now why do we store a + // pointer to real memory inside the SCI heap? + // If we save and the load again, this cannot work in general. + // This seems like bad design. Either the snapshot data itself should be + // stored in the heap, or a unique persistent id. + *ptr = gfxw_make_snapshot(s->visual, area); + + return handle; +} + +void graph_restore_box(EngineState *s, reg_t handle) { + gfxw_snapshot_t **ptr; + int port_nr = s->port->_ID; + + if (!handle.segment) { + warning("Attempt to restore box with zero handle"); + return; + } + + ptr = (gfxw_snapshot_t **)kmem(s->_segMan, handle); + + if (!ptr) { + warning("Attempt to restore invalid handle %04x:%04x", PRINT_REG(handle)); + return; + } + + while (port_nr > 2 && !(s->port->_flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS) && (gfxw_widget_matches_snapshot(*ptr, s->port))) { + // This shouldn't ever happen, actually, since windows (ports w/ ID > 2) should all be immune + GfxPort *newport = s->visual->getPort(port_nr); + error("Port %d is not immune against snapshots", s->port->_ID); + port_nr--; + if (newport) + s->port = newport; + } + + if (s->dyn_views && gfxw_widget_matches_snapshot(*ptr, s->dyn_views->_parent)) { + GfxContainer *parent = s->dyn_views->_parent; + + do { + parent = parent->_parent; + } while (parent && (gfxw_widget_matches_snapshot(*ptr, parent))); + + if (!parent) { + error("Attempted widget mass destruction by a snapshot"); + } + + reparentize_primary_widget_lists(s, (GfxPort *) parent); + } + + + if (!ptr) { + error("Attempt to restore invalid snaphot with handle %04x:%04x", PRINT_REG(handle)); + return; + } + + gfxw_restore_snapshot(s->visual, *ptr); + free(*ptr); + *ptr = NULL; + + kfree(s->_segMan, handle); +} + +PaletteEntry get_pic_color(EngineState *s, int color) { + if (!s->resMan->isVGA()) + return s->ega_colors[color].visual; + + if (color == -1 || color == 255) // -1 occurs in Eco Quest 1. Not sure if this is the best approach, but it seems to work + return PaletteEntry(255,255,255); + else if (color < s->gfx_state->gfxResMan->getColorCount()) + return s->gfx_state->gfxResMan->getColor(color); + else { + // Happens in the beginning of EcoQuest 2, when the dialog box of the customs officer shows up + warning("Color index %d out of bounds for pic %d (%d max)", color, s->gfx_state->pic_nr, s->gfx_state->gfxResMan->getColorCount()); + return PaletteEntry(0,0,0); + } +} + +void _k_redraw_box(EngineState *s, int x1, int y1, int x2, int y2) { + warning("_k_redraw_box(): Unimplemented"); +#if 0 + int i; + ViewObject *list = s->dyn_views; + + printf("Reanimating views\n", s->dyn_views_nr); + + for (i = 0;i < s->dyn_views_nr;i++) { + *(list[i].underBitsp) = graph_save_box(s, list[i].nsLeft, list[i].nsTop, list[i].nsRight - list[i].nsLeft, + list[i].nsBottom - list[i].nsTop, SCI_MAP_VISUAL | SCI_MAP_PRIORITY); + draw_view0(s->pic, s->ports[0], list[i].nsLeft, list[i].nsTop, list[i].priority, list[i].loop, + list[i].cel, 0, list[i].view); + } + + graph_update_box(s, x1, y1, x2 - x1, y2 - y1); + + for (i = 0;i < s->dyn_views_nr;i++) { + graph_restore_box(s, *(list[i].underBitsp)); + list[i].underBits = 0; + } +#endif +} + +Common::Rect set_base(EngineState *s, reg_t object) { + SegManager *segMan = s->_segMan; + int x, y, original_y, z, ystep, xsize, ysize; + int xbase, ybase, xend, yend; + int view, loop, cel; + int oldloop, oldcel; + int xmod = 0, ymod = 0; + Common::Rect retval; + + x = (int16)GET_SEL32V(object, x); + original_y = y = (int16)GET_SEL32V(object, y); + + if (s->_kernel->_selectorCache.z > -1) + z = (int16)GET_SEL32V(object, z); + else + z = 0; + + y -= z; // Subtract z offset + + ystep = (int16)GET_SEL32V(object, yStep); + + view = (int16)GET_SEL32V(object, view); + int l = GET_SEL32V(object, loop); + oldloop = loop = (l & 0x80) ? l - 256 : l; + int c = GET_SEL32V(object, cel); + oldcel = cel = (c & 0x80) ? c - 256 : c; + + Common::Point offset = Common::Point(0, 0); + + if (loop != oldloop) { + loop = 0; + PUT_SEL32V(object, loop, 0); + debugC(2, kDebugLevelGraphics, "Resetting loop for %04x:%04x!\n", PRINT_REG(object)); + } + + if (cel != oldcel) { + cel = 0; + PUT_SEL32V(object, cel, 0); + } + + gfxop_get_cel_parameters(s->gfx_state, view, loop, cel, &xsize, &ysize, &offset); + + xmod = offset.x; + ymod = offset.y; + + xbase = x - xmod - (xsize >> 1); + xend = xbase + xsize; + yend = y /* - ymod */ + 1; + ybase = yend - ystep; + + debugC(2, kDebugLevelBaseSetter, "(%d,%d)+/-(%d,%d), (%d x %d) -> (%d, %d) to (%d, %d)\n", + x, y, xmod, ymod, xsize, ysize, xbase, ybase, xend, yend); + + retval.left = xbase; + retval.top = ybase; + retval.right = xend; + retval.bottom = yend; + + return retval; +} + +static Common::Rect nsrect_clip(EngineState *s, int y, Common::Rect retval, int priority) { + int pri_top; + + if (priority == -1) + priority = _find_view_priority(s, y); + + pri_top = _find_priority_band(s, priority) + 1; + // +1: Don't know why, but this seems to be happening + + if (retval.top < pri_top) + retval.top = pri_top; + + if (retval.bottom < retval.top) + retval.top = retval.bottom - 1; + + return retval; +} + +static Common::Rect calculate_nsrect(EngineState *s, int x, int y, int view, int loop, int cel) { + int xbase, ybase, xend, yend, xsize, ysize; + int xmod = 0, ymod = 0; + Common::Rect retval(0, 0, 0, 0); + + Common::Point offset = Common::Point(0, 0); + + gfxop_get_cel_parameters(s->gfx_state, view, loop, cel, &xsize, &ysize, &offset); + + xmod = offset.x; + ymod = offset.y; + + xbase = x - xmod - (xsize >> 1); + xend = xbase + xsize; + yend = y - ymod + 1; // +1: magic modifier + ybase = yend - ysize; + + retval.left = xbase; + retval.top = ybase; + retval.right = xend; + retval.bottom = yend; + + return retval; +} + +Common::Rect get_nsrect(EngineState *s, reg_t object, byte clip) { + SegManager *segMan = s->_segMan; + int x, y, z; + int view, loop, cel; + Common::Rect retval; + + x = (int16)GET_SEL32V(object, x); + y = (int16)GET_SEL32V(object, y); + + if (s->_kernel->_selectorCache.z > -1) + z = (int16)GET_SEL32V(object, z); + else + z = 0; + + y -= z; // Subtract z offset + + view = (int16)GET_SEL32V(object, view); + int l = (int16)GET_SEL32V(object, loop); + loop = (l & 0x80) ? l - 256 : l; + int c = (int16)GET_SEL32V(object, cel); + cel = (c & 0x80) ? c - 256 : c; + + retval = calculate_nsrect(s, x, y, view, loop, cel); + + if (clip) { + int priority = (int16)GET_SEL32V(object, priority); + return nsrect_clip(s, y, retval, priority); + } + + return retval; +} + +Common::Rect get_nsrect32(EngineState *s, reg_t object, byte clip) { + SegManager *segMan = s->_segMan; + int x, y, z; + int view, loop, cel; + Common::Rect retval; + + x = (int16)GET_SEL32V(object, x); + y = (int16)GET_SEL32V(object, y); + + if (s->_kernel->_selectorCache.z > -1) + z = (int16)GET_SEL32V(object, z); + else + z = 0; + + y -= z; // Subtract z offset + + view = (int16)GET_SEL32V(object, view); + int l = (int16)GET_SEL32V(object, loop); + loop = (l & 0x80) ? l - 256 : l; + int c = (int16)GET_SEL32V(object, cel); + cel = (c & 0x80) ? c - 256 : c; + + retval = calculate_nsrect(s, x, y, view, loop, cel); + + if (clip) { + int priority = (int16)GET_SEL32V(object, priority); + return nsrect_clip(s, y, retval, priority); + } + + return retval; +} + +// ====================================================================================================== + SciGui32::SciGui32( EngineState *state, SciGuiScreen *screen, SciGuiPalette *palette, SciGuiCursor *cursor) : s(state) { _cursor = cursor; @@ -1081,79 +1468,6 @@ enum { _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP = 4 }; -static Common::Rect nsrect_clip(EngineState *s, int y, Common::Rect retval, int priority) { - int pri_top; - - if (priority == -1) - priority = _find_view_priority(s, y); - - pri_top = _find_priority_band(s, priority) + 1; - // +1: Don't know why, but this seems to be happening - - if (retval.top < pri_top) - retval.top = pri_top; - - if (retval.bottom < retval.top) - retval.top = retval.bottom - 1; - - return retval; -} - -static Common::Rect calculate_nsrect(EngineState *s, int x, int y, int view, int loop, int cel) { - int xbase, ybase, xend, yend, xsize, ysize; - int xmod = 0, ymod = 0; - Common::Rect retval(0, 0, 0, 0); - - Common::Point offset = Common::Point(0, 0); - - gfxop_get_cel_parameters(s->gfx_state, view, loop, cel, &xsize, &ysize, &offset); - - xmod = offset.x; - ymod = offset.y; - - xbase = x - xmod - (xsize >> 1); - xend = xbase + xsize; - yend = y - ymod + 1; // +1: magic modifier - ybase = yend - ysize; - - retval.left = xbase; - retval.top = ybase; - retval.right = xend; - retval.bottom = yend; - - return retval; -} - -Common::Rect get_nsrect32(EngineState *s, reg_t object, byte clip) { - SegManager *segMan = s->_segMan; - int x, y, z; - int view, loop, cel; - Common::Rect retval; - - x = (int16)GET_SEL32V(object, x); - y = (int16)GET_SEL32V(object, y); - - if (s->_kernel->_selectorCache.z > -1) - z = (int16)GET_SEL32V(object, z); - else - z = 0; - - y -= z; // Subtract z offset - - view = (int16)GET_SEL32V(object, view); - loop = sign_extend_byte((int16)GET_SEL32V(object, loop)); - cel = sign_extend_byte((int16)GET_SEL32V(object, cel)); - - retval = calculate_nsrect(s, x, y, view, loop, cel); - - if (clip) { - int priority = (int16)GET_SEL32V(object, priority); - return nsrect_clip(s, y, retval, priority); - } - - return retval; -} - GfxDynView *SciGui32::_k_make_dynview_obj(reg_t obj, int options, int nr, int argc, reg_t *argv) { SegManager *segMan = s->_segMan; short oldloop, oldcel; |