[Scummvm-cvs-logs] SF.net SVN: scummvm:[44606] scummvm/trunk/engines/sci

m_kiewitz at users.sourceforge.net m_kiewitz at users.sourceforge.net
Sun Oct 4 16:59:52 CEST 2009


Revision: 44606
          http://scummvm.svn.sourceforge.net/scummvm/?rev=44606&view=rev
Author:   m_kiewitz
Date:     2009-10-04 14:59:51 +0000 (Sun, 04 Oct 2009)

Log Message:
-----------
SCI: kAddToPic, kAnimate and kSetNowSeen transferred to SciGUI32, not yet implemented in newgui

Modified Paths:
--------------
    scummvm/trunk/engines/sci/engine/kgraphics.cpp
    scummvm/trunk/engines/sci/gui/gui.cpp
    scummvm/trunk/engines/sci/gui/gui.h
    scummvm/trunk/engines/sci/gui/gui_gfx.cpp
    scummvm/trunk/engines/sci/gui/gui_view.cpp
    scummvm/trunk/engines/sci/gui32/gui32.cpp
    scummvm/trunk/engines/sci/gui32/gui32.h
    scummvm/trunk/engines/sci/sci.cpp

Modified: scummvm/trunk/engines/sci/engine/kgraphics.cpp
===================================================================
--- scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/engine/kgraphics.cpp	2009-10-04 14:59:51 UTC (rev 44606)
@@ -1078,25 +1078,8 @@
 	return retval;
 }
 
-static void _k_set_now_seen(EngineState *s, reg_t object) {
-	SegManager *segMan = s->segMan;
-	Common::Rect absrect = get_nsrect(s, object, 0);
-
-	if (lookup_selector(s->segMan, object, s->_kernel->_selectorCache.nsTop, NULL, NULL) != kSelectorVariable) {
-		return;
-	} // This isn't fatal
-
-	PUT_SEL32V(object, nsLeft, absrect.left);
-	PUT_SEL32V(object, nsRight, absrect.right);
-	PUT_SEL32V(object, nsTop, absrect.top);
-	PUT_SEL32V(object, nsBottom, absrect.bottom);
-}
-
 reg_t kSetNowSeen(EngineState *s, int argc, reg_t *argv) {
-	reg_t object = argv[0];
-
-	_k_set_now_seen(s, object);
-
+	s->gui->setNowSeen(argv[0]);
 	return s->r_acc;
 }
 
@@ -1556,91 +1539,6 @@
 	}
 }
 
-
-static void draw_rect_to_control_map(EngineState *s, Common::Rect abs_zone) {
-	GfxBox *box;
-	gfx_color_t color;
-
-	gfxop_set_color(s->gfx_state, &color, -1, -1, -1, -1, -1, 0xf);
-
-	debugC(2, kDebugLevelGraphics, "    adding control block (%d,%d)to(%d,%d)\n", abs_zone.left, abs_zone.top, abs_zone.right, abs_zone.bottom);
-
-	box = gfxw_new_box(s->gfx_state, gfx_rect(abs_zone.left, abs_zone.top, abs_zone.width(),
-						abs_zone.height()), color, color, GFX_BOX_SHADE_FLAT);
-
-	assert_primary_widget_lists(s);
-
-	ADD_TO_CURRENT_PICTURE_PORT(box);
-}
-
-static void draw_obj_to_control_map(EngineState *s, GfxDynView *view) {
-	reg_t obj = make_reg(view->_ID, view->_subID);
-
-	if (!s->segMan->isObject(obj))
-		warning("View %d does not contain valid object reference %04x:%04x", view->_ID, PRINT_REG(obj));
-
-	reg_t* sp = view->signalp.getPointer(s->segMan);
-	if (!(sp && (sp->offset & _K_VIEW_SIG_FLAG_IGNORE_ACTOR))) {
-		Common::Rect abs_zone = get_nsrect(s, make_reg(view->_ID, view->_subID), 1);
-		draw_rect_to_control_map(s, abs_zone);
-	}
-}
-
-static void _k_view_list_do_postdraw(EngineState *s, GfxList *list) {
-	SegManager *segMan = s->segMan;
-	GfxDynView *widget = (GfxDynView *) list->_contents;
-
-	while (widget) {
-		reg_t obj = make_reg(widget->_ID, widget->_subID);
-
-		/*
-		 * this fixes a few problems, but doesn't match SSCI's logic.
-		 * The semantics of the private flag need to be verified before this can be uncommented.
-		 * Fixes bug #326 (CB1, ego falls down stairs)
-		 * if ((widget->signal & (_K_VIEW_SIG_FLAG_PRIVATE | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)) == _K_VIEW_SIG_FLAG_PRIVATE) {
-		 */
-		if ((widget->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)) == 0) {
-			int has_nsrect = lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.nsBottom, NULL, NULL) == kSelectorVariable;
-
-			if (has_nsrect) {
-				int temp;
-
-				temp = GET_SEL32V(obj, nsLeft);
-				PUT_SEL32V(obj, lsLeft, temp);
-
-				temp = GET_SEL32V(obj, nsRight);
-				PUT_SEL32V(obj, lsRight, temp);
-
-				temp = GET_SEL32V(obj, nsTop);
-				PUT_SEL32V(obj, lsTop, temp);
-
-				temp = GET_SEL32V(obj, nsBottom);
-				PUT_SEL32V(obj, lsBottom, temp);
-#ifdef DEBUG_LSRECT
-				fprintf(stderr, "lsRected %04x:%04x\n", PRINT_REG(obj));
-#endif
-			}
-#ifdef DEBUG_LSRECT
-			else
-				fprintf(stderr, "Not lsRecting %04x:%04x because %d\n", PRINT_REG(obj), lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.nsBottom, NULL, NULL));
-#endif
-
-			if (widget->signal & _K_VIEW_SIG_FLAG_HIDDEN)
-				widget->signal |= _K_VIEW_SIG_FLAG_REMOVE;
-		}
-#ifdef DEBUG_LSRECT
-		fprintf(stderr, "obj %04x:%04x has pflags %x\n", PRINT_REG(obj), (widget->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)));
-#endif
-
-		reg_t* sp = widget->signalp.getPointer(s->segMan);
-		if (sp) {
-			*sp = make_reg(0, widget->signal & 0xffff); /* Write back signal */
-		}
-
-		widget = (GfxDynView *)widget->_next;
-	}
-}
-
 void _k_view_list_mark_free(EngineState *s, reg_t off) {
 	if (s->dyn_views) {
 
@@ -1657,554 +1555,30 @@
 	}
 }
 
-static bool _k_animate_ran = false;	// FIXME: Avoid non-const global vars
-
-int _k_view_list_dispose_loop(EngineState *s, List *list, GfxDynView *widget, int argc, reg_t *argv) {
-// disposes all list members flagged for disposal
-// returns non-zero IFF views were dropped
-	int signal;
-	int dropped = 0;
-	SegManager *segMan = s->segMan;
-
-	_k_animate_ran = false;
-
-	if (widget) {
-		int retval;
-		// Recurse:
-		retval = _k_view_list_dispose_loop(s, list, (GfxDynView *)widget->_next, argc, argv);
-
-		if (retval == -1) // Bail out on annihilation, rely on re-start from Animate()
-			return -1;
-
-		if (GFXW_IS_DYN_VIEW(widget) && (widget->_ID != GFXW_NO_ID)) {
-			signal = widget->signalp.getPointer(segMan)->offset;
-			if (signal & _K_VIEW_SIG_FLAG_DISPOSE_ME) {
-				reg_t obj = make_reg(widget->_ID, widget->_subID);
-				reg_t under_bits = NULL_REG;
-
-				if (!s->segMan->isObject(obj)) {
-					error("Non-object %04x:%04x present in view list during delete time", PRINT_REG(obj));
-					obj = NULL_REG;
-				} else {
-					reg_t *ubp = widget->under_bitsp.getPointer(segMan);
-					if (ubp) { // Is there a bg picture left to clean?
-						reg_t mem_handle = *ubp;
-
-						if (mem_handle.segment) {
-							if (!kfree(s->segMan, mem_handle)) {
-								*ubp = make_reg(0, widget->under_bits = 0);
-							} else {
-								warning("Treating viewobj %04x:%04x as no longer present", PRINT_REG(obj));
-								obj = NULL_REG;
-							}
-						}
-					}
-				}
-				if (segMan->isObject(obj)) {
-					if (invoke_selector(INV_SEL(obj, delete_, kContinueOnInvalidSelector), 0))
-						warning("Object at %04x:%04x requested deletion, but does not have a delete funcselector", PRINT_REG(obj));
-					if (_k_animate_ran) {
-						warning("Object at %04x:%04x invoked kAnimate() during deletion", PRINT_REG(obj));
-						return dropped;
-					}
-
-					reg_t *ubp = widget->under_bitsp.getPointer(segMan);
-					if (ubp)
-						under_bits = *ubp;
-
-					if (under_bits.segment) {
-						*ubp = make_reg(0, 0);
-						graph_restore_box(s, under_bits);
-					}
-
-					debugC(2, kDebugLevelGraphics, "Freeing %04x:%04x with signal=%04x\n", PRINT_REG(obj), signal);
-
-					if (!(signal & _K_VIEW_SIG_FLAG_HIDDEN)) {
-						debugC(2, kDebugLevelGraphics, "Adding view at %04x:%04x to background\n", PRINT_REG(obj));
-						if (!(gfxw_remove_id(widget->_parent, widget->_ID, widget->_subID) == widget)) {
-							error("Attempt to remove view with ID %x:%x from list failed", widget->_ID, widget->_subID);
-						}
-
-						s->drop_views->add((GfxContainer *)s->drop_views, gfxw_picviewize_dynview(widget));
-
-						draw_obj_to_control_map(s, widget);
-						widget->draw_bounds.y += s->dyn_views->_bounds.y - widget->_parent->_bounds.y;
-						widget->draw_bounds.x += s->dyn_views->_bounds.x - widget->_parent->_bounds.x;
-						dropped = 1;
-					} else {
-						debugC(2, kDebugLevelGraphics, "Deleting view at %04x:%04x\n", PRINT_REG(obj));
-						widget->_flags |= GFXW_FLAG_VISIBLE;
-						gfxw_annihilate(widget);
-						return -1; // restart: Done in Animate()
-					}
-				}
-			}
-		}
-
-	}
-
-	return dropped;
-}
-
-enum {
-	_K_MAKE_VIEW_LIST_CYCLE = 1,
-	_K_MAKE_VIEW_LIST_CALC_PRIORITY = 2,
-	_K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP = 4
-};
-
-static GfxDynView *_k_make_dynview_obj(EngineState *s, reg_t obj, int options, int nr, int argc, reg_t *argv) {
-	SegManager *segMan = s->segMan;
-	short oldloop, oldcel;
-	int cel, loop, view_nr = (int16)GET_SEL32V(obj, view);
-	int palette;
-	int signal;
-	reg_t under_bits;
-	Common::Point pos;
-	int z;
-	GfxDynView *widget;
-
-	debugC(2, kDebugLevelGraphics, " - Adding %04x:%04x\n", PRINT_REG(obj));
-
-	obj = obj;
-
-	pos.x = (int16)GET_SEL32V(obj, x);
-	pos.y = (int16)GET_SEL32V(obj, y);
-
-	pos.y++; // magic: Sierra appears to do something like this
-
-	z = (int16)GET_SEL32V(obj, z);
-
-	// !-- nsRect used to be checked here!
-	loop = oldloop = sign_extend_byte(GET_SEL32V(obj, loop));
-	cel = oldcel = sign_extend_byte(GET_SEL32V(obj, cel));
-
-	if (s->_kernel->_selectorCache.palette)
-		palette = GET_SEL32V(obj, palette);
-	else
-		palette = 0;
-
-	// Clip loop and cel, write back if neccessary
-	gfxop_check_cel(s->gfx_state, view_nr, &loop, &cel);
-
-	if (loop != oldloop)
-		loop = 0;
-	if (cel != oldcel)
-		cel = 0;
-
-	if (oldloop != loop)
-		PUT_SEL32V(obj, loop, loop);
-
-	if (oldcel != cel) {
-		PUT_SEL32V(obj, cel, cel);
-	}
-
-	ObjVarRef under_bitsp;
-	if (lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.underBits, &(under_bitsp), NULL) != kSelectorVariable) {
-		under_bitsp.obj = NULL_REG;
-		under_bits = NULL_REG;
-		debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no underBits\n", PRINT_REG(obj));
-	} else
-		under_bits = *under_bitsp.getPointer(s->segMan);
-
-	ObjVarRef signalp;
-	if (lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.signal, &(signalp), NULL) != kSelectorVariable) {
-		signalp.obj = NULL_REG;
-		signal = 0;
-		debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no signal selector\n", PRINT_REG(obj));
-	} else {
-		signal = signalp.getPointer(s->segMan)->offset;
-		debugC(2, kDebugLevelGraphics, "    with signal = %04x\n", signal);
-	}
-
-	widget = gfxw_new_dyn_view(s->gfx_state, pos, z, view_nr, loop, cel, palette, -1, -1, ALIGN_CENTER, ALIGN_BOTTOM, nr);
-
-	if (widget) {
-		widget = (GfxDynView *) gfxw_set_id(widget, obj.segment, obj.offset);
-		widget = gfxw_dyn_view_set_params(widget, under_bits.segment, under_bitsp, signal, signalp);
-		widget->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; // Only works the first time 'round'
-
-		return widget;
-	} else {
-		warning("Could not generate dynview widget for %d/%d/%d", view_nr, loop, cel);
-		return NULL;
-	}
-}
-
-static void _k_make_view_list(EngineState *s, GfxList **widget_list, List *list, int options, int argc, reg_t *argv) {
-/* Creates a view_list from a node list in heap space. Returns the list, stores the
-** number of list entries in *list_nr. Calls doit for each entry if cycle is set.
-** argc, argv should be the same as in the calling kernel function.
-*/
-	SegManager *segMan = s->segMan;
-	Node *node;
-	int sequence_nr = 0;
-	GfxDynView *widget;
-
-	if (!*widget_list) {
-		error("make_view_list with widget_list == ()");
-	};
-
-	assert_primary_widget_lists(s);
-	// In case one of the views' doit() does a DrawPic...
-	// Yes, this _does_ happen!
-
-	if (!list) { // list sanity check
-		error("Attempt to make list from non-list");
-	}
-
-	reg_t next_node = list->first;
-	node = lookup_node(s, next_node);
-	while (node) {
-		reg_t obj = node->value; // The object we're using
-		GfxDynView *tempWidget;
-
-		if (options & _K_MAKE_VIEW_LIST_CYCLE) {
-			unsigned int signal = GET_SEL32V(obj, signal);
-
-			if (!(signal & _K_VIEW_SIG_FLAG_FROZEN)) {
-
-				debugC(2, kDebugLevelGraphics, "  invoking %04x:%04x::doit()\n", PRINT_REG(obj));
-				invoke_selector(INV_SEL(obj, doit, kContinueOnInvalidSelector), 0); // Call obj::doit() if neccessary
-
-
-				// Lookup node again, since the NodeTable it was in may
-				// have been re-allocated.
-				node = lookup_node(s, next_node);
-			}
-		}
-
-		next_node = node->succ; // In case the cast list was changed
-
-		if (list->first.segment == 0 && list->first.offset == 0) // The cast list was completely emptied!
-			break;
-
-		tempWidget = _k_make_dynview_obj(s, obj, options, sequence_nr--, argc, argv);
-		if (tempWidget)
-			(*widget_list)->add((GfxContainer *)(*widget_list), tempWidget);
-
-		node = lookup_node(s, next_node); // Next node
-	}
-
-	widget = (GfxDynView *)(*widget_list)->_contents;
-
-	while (widget) { // Read back widget values
-		reg_t *sp = widget->signalp.getPointer(s->segMan);
-		if (sp)
-			widget->signal = sp->offset;
-
-		widget = (GfxDynView *)widget->_next;
-	}
-}
-
-static void _k_prepare_view_list(EngineState *s, GfxList *list, int options) {
-	SegManager *segMan = s->segMan;
-	GfxDynView *view = (GfxDynView *) list->_contents;
-	while (view) {
-		reg_t obj = make_reg(view->_ID, view->_subID);
-		int priority, _priority;
-		int has_nsrect = (view->_ID <= 0) ? 0 : lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.nsBottom, NULL, NULL) == kSelectorVariable;
-		int oldsignal = view->signal;
-
-		_k_set_now_seen(s, obj);
-		_priority = /*GET_SELECTOR(obj, y); */((view->_pos.y));
-		_priority = _find_view_priority(s, _priority - 1);
-
-		if (options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP) { // Picview
-			priority = (int16)GET_SEL32V(obj, priority);
-			if (priority < 0)
-				priority = _priority; // Always for picviews
-		} else { // Dynview
-			if (has_nsrect && !(view->signal & _K_VIEW_SIG_FLAG_FIX_PRI_ON)) { // Calculate priority
-				if (options & _K_MAKE_VIEW_LIST_CALC_PRIORITY)
-					PUT_SEL32V(obj, priority, _priority);
-
-				priority = _priority;
-
-			} else // DON'T calculate the priority
-				priority = (int16)GET_SEL32V(obj, priority);
-		}
-
-		view->_color.priority = priority;
-
-		if (priority > -1)
-			view->_color.mask |= GFX_MASK_PRIORITY;
-		else
-			view->_color.mask &= ~GFX_MASK_PRIORITY;
-
-		// CR (from :Bob Heitman:) stopupdated views (like pic views) have
-		// their clipped nsRect drawn to the control map
-		if (view->signal & _K_VIEW_SIG_FLAG_STOP_UPDATE) {
-			view->signal |= _K_VIEW_SIG_FLAG_STOPUPD;
-			debugC(2, kDebugLevelGraphics, "Setting magic STOP_UPD for %04x:%04x\n", PRINT_REG(obj));
-		}
-
-		if ((options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP))
-			draw_obj_to_control_map(s, view);
-
-		// Extreme Pattern Matching ugliness ahead...
-		if (view->signal & _K_VIEW_SIG_FLAG_NO_UPDATE) {
-			if (((view->signal & (_K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_FORCE_UPDATE))) // 9.1.1.1
-			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE)) == _K_VIEW_SIG_FLAG_HIDDEN)
-			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE)) == _K_VIEW_SIG_FLAG_REMOVE) // 9.1.1.2
-			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == _K_VIEW_SIG_FLAG_ALWAYS_UPDATE) // 9.1.1.3
-			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE))) { // 9.1.1.4
-				s->pic_not_valid++;
-				view->signal &= ~_K_VIEW_SIG_FLAG_STOP_UPDATE;
-			}
-
-			else if (((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == 0)
-			         || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE))
-			         || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE))
-			         || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == _K_VIEW_SIG_FLAG_HIDDEN)) {
-				view->signal &= ~_K_VIEW_SIG_FLAG_STOP_UPDATE;
-			}
-		} else {
-			if (view->signal & _K_VIEW_SIG_FLAG_STOP_UPDATE) {
-				s->pic_not_valid++;
-				view->signal &= ~_K_VIEW_SIG_FLAG_FORCE_UPDATE;
-			} else { // if not STOP_UPDATE
-				if (view->signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)
-					s->pic_not_valid++;
-				view->signal &= ~_K_VIEW_SIG_FLAG_FORCE_UPDATE;
-			}
-		}
-
-		debugC(2, kDebugLevelGraphics, "  dv[%04x:%04x]: signal %04x -> %04x\n", PRINT_REG(obj), oldsignal, view->signal);
-
-		// Never happens
-/*		if (view->signal & 0) {
-			view->signal &= ~_K_VIEW_SIG_FLAG_STOPUPD;
-			fprintf(stderr, "Unsetting magic StopUpd for view %04x:%04x\n", PRINT_REG(obj));
-		} */
-
-		view = (GfxDynView *)view->_next;
-	}
-}
-
-static void _k_update_signals_in_view_list(GfxList *old_list, GfxList *new_list) {
-	// O(n^2)... a bit painful, but much faster than the redraws it helps prevent
-	GfxDynView *old_widget = (GfxDynView *)old_list->_contents;
-
-	/* Traverses all old widgets, updates them with signals from the new widgets.
-	** This is done to avoid evil hacks in widget.c; widgets with unique IDs are
-	** replaced there iff they are NOT equal_to a new widget with the same ID.
-	** If they were replaced every time, we'd be doing far too many redraws.
-	*/
-
-	while (old_widget) {
-		GfxDynView *new_widget = (GfxDynView *) new_list->_contents;
-
-		while (new_widget
-		        && (new_widget->_ID != old_widget->_ID
-		            || new_widget->_subID != old_widget->_subID))
-			new_widget = (GfxDynView *)new_widget->_next;
-
-		if (new_widget) {
-			int carry = old_widget->signal & _K_VIEW_SIG_FLAG_STOPUPD;
-			// Transfer 'stopupd' flag
-
-			if ((new_widget->_pos.x != old_widget->_pos.x)
-			        || (new_widget->_pos.y != old_widget->_pos.y)
-					// No idea why this is supposed to be bad
-/*			        || (new_widget->z != old_widget->z)
-			        || (new_widget->view != old_widget->view)
-			        || (new_widget->loop != old_widget->loop)
-			        || (new_widget->cel != old_widget->cel)
-			        */)
-				carry = 0;
-
-			old_widget->signal = new_widget->signal |= carry;
-		}
-
-		old_widget = (GfxDynView *)old_widget->_next;
-	}
-}
-
-static void _k_view_list_kryptonize(GfxWidget *v) {
-	if (v) {
-		v->_flags &= ~GFXW_FLAG_IMMUNE_TO_SNAPSHOTS;
-		_k_view_list_kryptonize(v->_next);
-	}
-}
-
-static void _k_raise_topmost_in_view_list(EngineState *s, GfxList *list, GfxDynView *view) {
-	if (view) {
-		GfxDynView *next = (GfxDynView *)view->_next;
-
-		// step 11
-		if ((view->signal & (_K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == 0) {
-			debugC(2, kDebugLevelGraphics, "Forcing precedence 2 at [%04x:%04x] with %04x\n", PRINT_REG(make_reg(view->_ID, view->_subID)), view->signal);
-			view->force_precedence = 2;
-
-			if ((view->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_HIDDEN)) == _K_VIEW_SIG_FLAG_REMOVE) {
-				view->signal &= ~_K_VIEW_SIG_FLAG_REMOVE;
-			}
-		}
-
-		gfxw_remove_widget_from_container(view->_parent, view);
-
-		if (view->signal & _K_VIEW_SIG_FLAG_HIDDEN)
-			gfxw_hide_widget(view);
-		else
-			gfxw_show_widget(view);
-
-		list->add((GfxContainer *)list, view);
-
-		_k_raise_topmost_in_view_list(s, list, next);
-	}
-}
-
-static void _k_redraw_view_list(EngineState *s, GfxList *list) {
-	GfxDynView *view = (GfxDynView *) list->_contents;
-	while (view) {
-
-		debugC(2, kDebugLevelGraphics, "  dv[%04x:%04x]: signal %04x\n", PRINT_REG(make_reg(view->_ID, view->_subID)), view->signal);
-
-		// step 1 of subalgorithm
-		if (view->signal & _K_VIEW_SIG_FLAG_NO_UPDATE) {
-			if (view->signal & _K_VIEW_SIG_FLAG_FORCE_UPDATE)
-				view->signal &= ~_K_VIEW_SIG_FLAG_FORCE_UPDATE;
-
-			if (view->signal & _K_VIEW_SIG_FLAG_UPDATED)
-				view->signal &= ~(_K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE);
-		} else { // NO_UPD is not set
-			if (view->signal & _K_VIEW_SIG_FLAG_STOP_UPDATE) {
-				view->signal &= ~_K_VIEW_SIG_FLAG_STOP_UPDATE;
-				view->signal |= _K_VIEW_SIG_FLAG_NO_UPDATE;
-			}
-		}
-
-		debugC(2, kDebugLevelGraphics, "    at substep 6: signal %04x\n", view->signal);
-
-		if (view->signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)
-			view->signal &= ~(_K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE);
-
-		debugC(2, kDebugLevelGraphics, "    at substep 11/14: signal %04x\n", view->signal);
-
-		if (view->signal & _K_VIEW_SIG_FLAG_NO_UPDATE) {
-			if (view->signal & _K_VIEW_SIG_FLAG_HIDDEN)
-				view->signal |= _K_VIEW_SIG_FLAG_REMOVE;
-			else
-				view->signal &= ~_K_VIEW_SIG_FLAG_REMOVE;
-		} else if (!(view->signal & _K_VIEW_SIG_FLAG_HIDDEN))
-			view->force_precedence = 1;
-
-		debugC(2, kDebugLevelGraphics, "    -> signal %04x\n", view->signal);
-
-		view = (GfxDynView *)view->_next;
-	}
-}
-
-// Flags for _k_draw_view_list
-// Whether some magic with the base object's "signal" selector should be done:
-#define _K_DRAW_VIEW_LIST_USE_SIGNAL 1
-// This flag draws all views with the "DISPOSE_ME" flag set:
-#define _K_DRAW_VIEW_LIST_DISPOSEABLE 2
-// Use this one to draw all views with "DISPOSE_ME" NOT set:
-#define _K_DRAW_VIEW_LIST_NONDISPOSEABLE 4
-// Draw as picviews
-#define _K_DRAW_VIEW_LIST_PICVIEW 8
-
-void _k_draw_view_list(EngineState *s, GfxList *list, int flags) {
-	// Draws list_nr members of list to s->pic.
-	GfxDynView *widget = (GfxDynView *) list->_contents;
-
-	if ((GfxContainer *)s->port != (GfxContainer *)s->dyn_views->_parent)
-		return; // Return if the pictures are meant for a different port
-
-	while (widget) {
-		if (flags & _K_DRAW_VIEW_LIST_PICVIEW)
-			widget = gfxw_picviewize_dynview(widget);
-
-		if (GFXW_IS_DYN_VIEW(widget) && widget->_ID) {
-			uint16 signal = (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) ? widget->signalp.getPointer(s->segMan)->offset : 0;
-
-			if (signal & _K_VIEW_SIG_FLAG_HIDDEN)
-				gfxw_hide_widget(widget);
-			else
-				gfxw_show_widget(widget);
-
-			if (!(flags & _K_DRAW_VIEW_LIST_USE_SIGNAL)
-			        || ((flags & _K_DRAW_VIEW_LIST_DISPOSEABLE) && (signal & _K_VIEW_SIG_FLAG_DISPOSE_ME))
-			        || ((flags & _K_DRAW_VIEW_LIST_NONDISPOSEABLE) && !(signal & _K_VIEW_SIG_FLAG_DISPOSE_ME))) {
-
-				if (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) {
-					signal &= ~(_K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE);
-					// Clear all of those flags
-
-					if (signal & _K_VIEW_SIG_FLAG_HIDDEN)
-						gfxw_hide_widget(widget);
-					else
-						gfxw_show_widget(widget);
-
-					*widget->signalp.getPointer(s->segMan) = make_reg(0, signal); // Write the changes back
-				};
-
-			} // ...if we're drawing disposeables and this one is disposeable, or if we're drawing non-
-			  // disposeables and this one isn't disposeable
-		}
-
-		widget = (GfxDynView *)widget->_next;
-	} // while (widget)
-
-}
-
 reg_t kAddToPic(EngineState *s, int argc, reg_t *argv) {
-	GfxList *pic_views;
-	reg_t list_ref = argv[0];
+	sciResourceId viewId;
+	uint16 loopNo, cellNo;
+	int16 leftPos, topPos, priority, control;
 
-	assert_primary_widget_lists(s);
-
-	if (argc > 1) {
-		int view, cel, loop, x, y, priority, control;
-		GfxWidget *widget;
-
-		view = argv[0].toUint16();
-		loop = argv[1].toUint16();
-		cel = argv[2].toUint16();
-		x = argv[3].toSint16();
-		y = argv[4].toSint16() + 1 /* magic + 1 */;
+	switch (argc) {
+	case 0:
+		break;
+	case 1:
+		s->gui->addToPicList(argv[0], argc, argv);
+		break;
+	case 7:
+		viewId = argv[0].toUint16();
+		loopNo = argv[1].toUint16();
+		cellNo = argv[2].toUint16();
+		leftPos = argv[3].toSint16();
+		topPos = argv[4].toSint16();
 		priority = argv[5].toSint16();
 		control = argv[6].toSint16();
-
-		widget = gfxw_new_dyn_view(s->gfx_state, Common::Point(x, y), 0, view, loop, cel, 0,
-		                                priority, -1 /* No priority */ , ALIGN_CENTER, ALIGN_BOTTOM, 0);
-
-		if (!widget) {
-			error("Attempt to single-add invalid picview (%d/%d/%d)", view, loop, cel);
-		} else {
-			widget->_ID = -1;
-			if (control >= 0) {
-				Common::Rect abs_zone = nsrect_clip(s, y, calculate_nsrect(s, x, y, view, loop, cel), priority);
-				draw_rect_to_control_map(s, abs_zone);
-			}
-			ADD_TO_CURRENT_PICTURE_PORT(gfxw_picviewize_dynview((GfxDynView *) widget));
-		}
-	} else {
-		List *list;
-
-		if (!list_ref.segment) {
-			warning("Attempt to AddToPic single non-list: %04x:%04x", PRINT_REG(list_ref));
-			return s->r_acc;
-		}
-
-		list = lookup_list(s, list_ref);
-
-		pic_views = gfxw_new_list(s->picture_port->_bounds, 1);
-
-		debugC(2, kDebugLevelGraphics, "Preparing picview list...\n");
-		_k_make_view_list(s, &pic_views, list, 0, argc, argv);
-		_k_prepare_view_list(s, pic_views, _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP);
-		// Store pic views for later re-use
-
-		debugC(2, kDebugLevelGraphics, "Drawing picview list...\n");
-		ADD_TO_CURRENT_PICTURE_PORT(pic_views);
-		_k_draw_view_list(s, pic_views, _K_DRAW_VIEW_LIST_NONDISPOSEABLE | _K_DRAW_VIEW_LIST_DISPOSEABLE | _K_DRAW_VIEW_LIST_PICVIEW);
-		// Draw relative to the bottom center
-		debugC(2, kDebugLevelGraphics, "Returning.\n");
+		s->gui->addToPicView(viewId, loopNo, cellNo, leftPos, topPos, priority, control);
+		break;
+	default:
+		error("kAddToPic with unsupported parameter count %d", argc);		
 	}
-	reparentize_primary_widget_lists(s, s->port);
-
 	return s->r_acc;
 }
 
@@ -2285,527 +1659,11 @@
 	return s->gui->newWindow(rect1, rect2, style, priority, colorPen, colorBack, title.c_str());
 }
 
-#define K_ANIMATE_CENTER_OPEN_H  0 // horizontally open from center
-#define K_ANIMATE_CENTER_OPEN_V  1 // vertically open from center
-#define K_ANIMATE_RIGHT_OPEN     2 // open from right
-#define K_ANIMATE_LEFT_OPEN      3 // open from left
-#define K_ANIMATE_BOTTOM_OPEN    4 // open from bottom
-#define K_ANIMATE_TOP_OPEN       5 // open from top
-#define K_ANIMATE_BORDER_OPEN_F  6 // open from edges to center
-#define K_ANIMATE_CENTER_OPEN_F  7 // open from center to edges
-#define K_ANIMATE_OPEN_CHECKERS  8 // open random checkboard
-#define K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H  9 // horizontally close to center,reopen from center
-#define K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V 10 // vertically close to center, reopen from center
-#define K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN        11 // close to right, reopen from right
-#define K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN        12 // close to left,  reopen from left
-#define K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN        13 // close to bottom, reopen from bottom
-#define K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN        14 // close to top, reopen from top
-#define K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F 15 // close from center to edges,
-// reopen from edges to center
-#define K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F 16 // close from edges to center, reopen from
-// center to edges */
-#define K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS 17 // close random checkboard, reopen
-#define K_ANIMATE_PALETTE_FADEOUT_FADEIN       0x1e
-#define K_ANIMATE_SCROLL_LEFT                  0x28
-#define K_ANIMATE_SCROLL_RIGHT                 0x29
-#define K_ANIMATE_SCROLL_DOWN                  0x2a
-#define K_ANIMATE_SCROLL_UP                    0x2b
-
-#define GRAPH_BLANK_BOX(s, x, y, xl, yl, color) gfxop_fill_box(s->gfx_state, \
-	gfx_rect(x, (((y) < 10)? 10 : (y)), xl, (((y) < 10)? ((y) - 10) : 0) + (yl)), s->ega_colors[color]);
-
-#define GRAPH_UPDATE_BOX(s, x, y, xl, yl) gfxop_draw_pixmap(s->gfx_state, newscreen, \
-	gfx_rect(x, (((y) < 10)? 10 : (y)) - 10, xl, (((y) < 10)? ((y) - 10) : 0) + (yl)), Common::Point(x, ((y) < 10)? 10 : (y) ));
-
-static void animate_do_animation(EngineState *s, int argc, reg_t *argv) {
-	long animation_delay = 5;
-	int i, remaining_checkers;
-	int update_counter;
-	// Number of animation steps to perform betwen updates for transition animations
-	int animation_granularity = 4;
-	int granularity0 = animation_granularity << 1;
-	int granularity1 = animation_granularity;
-	int granularity2 = animation_granularity >> 2;
-	int granularity3 = animation_granularity >> 4;
-	char checkers[32 * 19];
-	gfx_pixmap_t *newscreen = gfxop_grab_pixmap(s->gfx_state, gfx_rect(0, 10, 320, 190));
-
-	if (!granularity2)
-		granularity2 = 1;
-	if (!granularity3)
-		granularity3 = 1;
-
-	gfxop_set_clip_zone(s->gfx_state, gfx_rect_fullscreen);
-
-	if (!newscreen) {
-		error("Failed to allocate 'newscreen'");
-		return;
-	}
-
-	gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, 0, 320, 190), Common::Point(0, 10));
-	gfxop_update_box(s->gfx_state, gfx_rect(0, 0, 320, 200));
-
-	//debugC(2, kDebugLevelGraphics, "Animating pic opening type %x\n", s->pic_animate);
-
-	gfxop_enable_dirty_frames(s->gfx_state);
-
-	switch (s->pic_animate) {
-	case K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H :
-		for (i = 0; i < 159 + granularity1; i += granularity1) {
-			GRAPH_BLANK_BOX(s, i, 10, granularity1, 190, 0);
-			gfxop_update(s->gfx_state);
-			GRAPH_BLANK_BOX(s, 319 - i, 10, granularity1, 190, 0);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 1000);
-			process_sound_events(s);
-		}
-		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
-
-	case K_ANIMATE_CENTER_OPEN_H :
-
-		for (i = 159; i >= 1 - granularity1; i -= granularity1) {
-			GRAPH_UPDATE_BOX(s, i, 10, granularity1, 190);
-			gfxop_update(s->gfx_state);
-			GRAPH_UPDATE_BOX(s, 319 - i, 10, granularity1, 190);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 1000);
-			process_sound_events(s);
-		}
-		break;
-
-
-	case K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V :
-
-		for (i = 0; i < 94 + granularity2; i += granularity2) {
-			GRAPH_BLANK_BOX(s, 0, i + 10, 320, granularity2, 0);
-			gfxop_update(s->gfx_state);
-			GRAPH_BLANK_BOX(s, 0, 199 - i, 320, granularity2, 0);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, 2 * animation_delay / 1000);
-			process_sound_events(s);
-		}
-		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
-
-	case K_ANIMATE_CENTER_OPEN_V :
-
-		for (i = 94; i >= 1 - granularity2; i -= granularity2) {
-			GRAPH_UPDATE_BOX(s, 0, i + 10, 320, granularity2);
-			gfxop_update(s->gfx_state);
-			GRAPH_UPDATE_BOX(s, 0, 199 - i, 320, granularity2);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, 2 * animation_delay / 1000);
-			process_sound_events(s);
-		}
-		break;
-
-
-	case K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN :
-
-		for (i = 0; i < 319 + granularity0; i += granularity0) {
-			GRAPH_BLANK_BOX(s, i, 10, granularity0, 190, 0);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
-			process_sound_events(s);
-		}
-		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
-
-	case K_ANIMATE_RIGHT_OPEN :
-		for (i = 319; i >= 1 - granularity0; i -= granularity0) {
-			GRAPH_UPDATE_BOX(s, i, 10, granularity0, 190);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
-			process_sound_events(s);
-		}
-		break;
-
-
-	case K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN :
-
-		for (i = 319; i >= 1 - granularity0; i -= granularity0) {
-			GRAPH_BLANK_BOX(s, i, 10, granularity0, 190, 0);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
-			process_sound_events(s);
-		}
-		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
-
-	case K_ANIMATE_LEFT_OPEN :
-
-		for (i = 0; i < 319 + granularity0; i += granularity0) {
-			GRAPH_UPDATE_BOX(s, i, 10, granularity0, 190);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
-			process_sound_events(s);
-		}
-		break;
-
-
-	case K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN :
-
-		for (i = 10; i < 199 + granularity1; i += granularity1) {
-			GRAPH_BLANK_BOX(s, 0, i, 320, granularity1, 0);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 1000);
-			process_sound_events(s);
-		}
-		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
-
-	case K_ANIMATE_BOTTOM_OPEN :
-
-		for (i = 199; i >= 11 - granularity1; i -= granularity1) {
-			GRAPH_UPDATE_BOX(s, 0, i, 320, granularity1);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 1000);
-			process_sound_events(s);
-		}
-		break;
-
-
-	case K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN :
-
-		for (i = 199; i >= 11 - granularity1; i -= granularity1) {
-			GRAPH_BLANK_BOX(s, 0, i, 320, granularity1, 0);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 1000);
-			process_sound_events(s);
-		}
-		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
-
-	case K_ANIMATE_TOP_OPEN :
-
-		for (i = 10; i < 199 + granularity1; i += granularity1) {
-			GRAPH_UPDATE_BOX(s, 0, i, 320, granularity1);
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, animation_delay / 1000);
-			process_sound_events(s);
-		}
-		break;
-
-
-	case K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F :
-
-		for (i = 31; i >= 1 - granularity3; i -= granularity3) {
-			int real_i = (i < 0) ? 0 : i;
-			int height_l = 3 * (granularity3 - real_i + i);
-			int width_l = 5 * (granularity3 - real_i + i);
-			int height = real_i * 3;
-			int width = real_i * 5;
-
-			GRAPH_BLANK_BOX(s, width, 10 + height, width_l, 190 - 2 * height, 0);
-			gfxop_update(s->gfx_state);
-			GRAPH_BLANK_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height, 0);
-			gfxop_update(s->gfx_state);
-
-			GRAPH_BLANK_BOX(s, width, 10 + height, 320 - 2 * width, height_l, 0);
-			gfxop_update(s->gfx_state);
-			GRAPH_BLANK_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0);
-			gfxop_update(s->gfx_state);
-
-			gfxop_sleep(s->gfx_state, 4 * animation_delay / 1000);
-			process_sound_events(s);
-		}
-
-	case K_ANIMATE_BORDER_OPEN_F :
-
-		for (i = 0; i < 31 + granularity3; i += granularity3) {
-			int real_i = (i < 0) ? 0 : i;
-			int height_l = 3 * (granularity3 - real_i + i);
-			int width_l = 5 * (granularity3 - real_i + i);
-			int height = real_i * 3;
-			int width = real_i * 5;
-
-			GRAPH_UPDATE_BOX(s, width, 10 + height, width_l, 190 - 2 * height);
-			gfxop_update(s->gfx_state);
-			GRAPH_UPDATE_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height);
-			gfxop_update(s->gfx_state);
-
-			GRAPH_UPDATE_BOX(s, width, 10 + height, 320 - 2 * width, height_l);
-			gfxop_update(s->gfx_state);
-			GRAPH_UPDATE_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l);
-			gfxop_update(s->gfx_state);
-
-			gfxop_sleep(s->gfx_state, 4 * animation_delay / 1000);
-			process_sound_events(s);
-		}
-
-		break;
-
-	case K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F :
-
-		for (i = 0; i < 31 + granularity3; i += granularity3) {
-			int real_i = (i < 0) ? 0 : i;
-			int height_l = 3 * (granularity3 - real_i + i);
-			int width_l = 5 * (granularity3 - real_i + i);
-			int height = real_i * 3;
-			int width = real_i * 5;
-
-			GRAPH_BLANK_BOX(s, width, 10 + height, width_l, 190 - 2 * height, 0);
-			gfxop_update(s->gfx_state);
-			GRAPH_BLANK_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height, 0);
-			gfxop_update(s->gfx_state);
-
-			GRAPH_BLANK_BOX(s, width, 10 + height, 320 - 2 * width, height_l, 0);
-			gfxop_update(s->gfx_state);
-			GRAPH_BLANK_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0);
-			gfxop_update(s->gfx_state);
-
-			gfxop_sleep(s->gfx_state, 7 * animation_delay / 1000);
-			process_sound_events(s);
-		}
-
-	case K_ANIMATE_CENTER_OPEN_F :
-
-		for (i = 31; i >= 1 - granularity3; i -= granularity3) {
-			int real_i = (i < 0) ? 0 : i;
-			int height_l = 3 * (granularity3 - real_i + i);
-			int width_l = 5 * (granularity3 - real_i + i);
-			int height = real_i * 3;
-			int width = real_i * 5;
-
-			GRAPH_UPDATE_BOX(s, width, 10 + height, width_l, 190 - 2 * height);
-			gfxop_update(s->gfx_state);
-			GRAPH_UPDATE_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2*height);
-			gfxop_update(s->gfx_state);
-
-			GRAPH_UPDATE_BOX(s, width, 10 + height, 320 - 2 * width, height_l);
-			gfxop_update(s->gfx_state);
-			GRAPH_UPDATE_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l);
-			gfxop_update(s->gfx_state);
-
-			gfxop_sleep(s->gfx_state, 7 * animation_delay / 1000);
-			process_sound_events(s);
-		}
-		break;
-
-	case K_ANIMATE_PALETTE_FADEOUT_FADEIN:
-		warning("TODO: Palette fadeout/fadein");
-		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
-		break;
-
-	case K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS :
-
-		memset(checkers, 0, sizeof(checkers));
-		remaining_checkers = 19 * 32;
-		update_counter = granularity1;
-
-		while (remaining_checkers) {
-			int x, y, checker = 1 + (int)(1.0 * remaining_checkers * rand() / (RAND_MAX + 1.0));
-			i = -1;
-
-			while (checker)
-				if (checkers[++i] == 0)
-					--checker;
-			checkers[i] = 1; // Mark checker as used
-
-			x = i % 32;
-			y = i / 32;
-
-			GRAPH_BLANK_BOX(s, x * 10, 10 + y * 10, 10, 10, 0);
-			if (!(update_counter--) || (remaining_checkers == 1)) {
-				gfxop_update(s->gfx_state);
-				update_counter = granularity1;
-			}
-
-			if (remaining_checkers & 1) {
-				gfxop_sleep(s->gfx_state, animation_delay / 4 / 1000);
-			}
-
-			--remaining_checkers;
-			process_sound_events(s);
-		}
-
-	case K_ANIMATE_OPEN_CHECKERS :
-
-		memset(checkers, 0, sizeof(checkers));
-		remaining_checkers = 19 * 32;
-		update_counter = granularity1;
-
-		while (remaining_checkers) {
-			int x, y, checker = 1 + (int)(1.0 * remaining_checkers * rand() / (RAND_MAX + 1.0));
-			i = -1;
-
-			while (checker)
-				if (checkers[++i] == 0) --checker;
-			checkers[i] = 1; // Mark checker as used
-
-			x = i % 32;
-			y = i / 32;
-
-			GRAPH_UPDATE_BOX(s, x * 10, 10 + y * 10, 10, 10);
-
-			if (!(update_counter--) || (remaining_checkers == 1)) {
-				gfxop_update(s->gfx_state);
-				update_counter = granularity1;
-			}
-
-			if (remaining_checkers & 1) {
-				gfxop_sleep(s->gfx_state, animation_delay / 4 / 1000);
-			}
-
-			--remaining_checkers;
-			process_sound_events(s);
-		}
-		break;
-
-
-	case K_ANIMATE_SCROLL_LEFT :
-
-		for (i = 0; i < 319; i += granularity0) {
-			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(320 - i, 0, i, 190), Common::Point(0, 10));
-			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, 0, 320 - i, 190), Common::Point(i, 10));
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
-		}
-		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
-		break;
-
-	case K_ANIMATE_SCROLL_RIGHT :
-
-		for (i = 0; i < 319; i += granularity0) {
-			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(0, 0, i, 190), Common::Point(319 - i, 10));
-			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(i, 0, 320 - i, 190), Common::Point(0, 10));
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
-		}
-		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
-		break;
-
-	case K_ANIMATE_SCROLL_UP :
-
-		for (i = 0; i < 189; i += granularity0) {
-			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(0, 190 - i, 320, i), Common::Point(0, 10));
-			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, 0, 320, 190 - i), Common::Point(0, 10 + i));
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
-		}
-		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
-		break;
-
-	case K_ANIMATE_SCROLL_DOWN :
-
-		for (i = 0; i < 189; i += granularity0) {
-			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(0, 0, 320, i), Common::Point(0, 200 - i));
-			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, i, 320, 190 - i), Common::Point(0, 10));
-			gfxop_update(s->gfx_state);
-			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
-		}
-		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
-		break;
-
-	default:
-		warning("Unknown opening animation 0x%02x", s->pic_animate);
-		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
-
-	}
-
-	gfxop_free_pixmap(s->gfx_state, s->old_screen);
-	gfxop_free_pixmap(s->gfx_state, newscreen);
-	s->old_screen = NULL;
-}
-
 reg_t kAnimate(EngineState *s, int argc, reg_t *argv) {
-	// Animations are supposed to take a maximum of animation_delay milliseconds.
-	reg_t cast_list_ref = (argc > 0) ? argv[0] : NULL_REG;
-	int cycle = (argc > 1) ? argv[1].toUint16() : 0;
-	List *cast_list = NULL;
-	int open_animation = 0;
+	reg_t castListReference = (argc > 0) ? argv[0] : NULL_REG;
+	bool cycle = (argc > 1) ? ((argv[1].toUint16()) ? true : false) : false;
 
-	process_sound_events(s); // Take care of incoming events (kAnimate is called semi-regularly)
-	_k_animate_ran = true; // Used by some of the invoked functions to check for recursion, which may,
-						// after all, damage the cast list
-
-	if (cast_list_ref.segment) {
-		cast_list = lookup_list(s, cast_list_ref);
-		if (!cast_list)
-			return s->r_acc;
-	}
-
-	open_animation = (s->pic_is_new) && (s->pic_not_valid);
-	s->pic_is_new = 0;
-
-	assert_primary_widget_lists(s);
-
-	if (!s->dyn_views->_contents // Only reparentize empty dynview list
-	        && (((GfxContainer *)s->port != (GfxContainer *)s->dyn_views->_parent) // If dynviews are on other port...
-	            || (s->dyn_views->_next))) // ... or not on top of the view list
-		reparentize_primary_widget_lists(s, s->port);
-
-	if (cast_list) {
-		GfxList *templist = gfxw_new_list(s->dyn_views->_bounds, 0);
-
-		_k_make_view_list(s, &(templist), cast_list, (cycle ? _K_MAKE_VIEW_LIST_CYCLE : 0)
-		                  | _K_MAKE_VIEW_LIST_CALC_PRIORITY, argc, argv);
-
-		// Make sure that none of the doits() did something evil
-		assert_primary_widget_lists(s);
-
-		if (!s->dyn_views->_contents // Only reparentize empty dynview list
-		        && (((GfxContainer *)s->port != (GfxContainer *)s->dyn_views->_parent) // If dynviews are on other port...
-		            || (s->dyn_views->_next))) // ... or not on top of the view list
-			reparentize_primary_widget_lists(s, s->port);
-		// End of doit() recovery code
-
-		if (s->pic_is_new) { // Happens if DrawPic() is executed by a dynview (yes, that happens)
-			return kAnimate(s, argc, argv); /* Tail-recurse */
-		}
-
-		debugC(2, kDebugLevelGraphics, "Handling Dynviews (..step 9 inclusive):\n");
-		_k_prepare_view_list(s, templist, _K_MAKE_VIEW_LIST_CALC_PRIORITY);
-
-		if (s->pic_not_valid) {
-			debugC(2, kDebugLevelGraphics, "PicNotValid=%d -> Subalgorithm:\n", s->pic_not_valid);
-			_k_redraw_view_list(s, templist);
-		}
-
-		_k_update_signals_in_view_list(s->dyn_views, templist);
-		s->dyn_views->tag();
-
-		_k_raise_topmost_in_view_list(s, s->dyn_views, (GfxDynView *)templist->_contents);
-
-		delete templist;
-		s->dyn_views->free_tagged((GfxContainer *)s->dyn_views); // Free obsolete dynviews
-	} // if (cast_list)
-
-	if (open_animation) {
-		gfxop_clear_box(s->gfx_state, gfx_rect(0, 10, 320, 190)); // Propagate pic
-		s->visual->add_dirty_abs((GfxContainer *)s->visual, gfx_rect_fullscreen, 0);
-		// Mark screen as dirty so picviews will be drawn correctly
-		FULL_REDRAW();
-
-		animate_do_animation(s, argc, argv);
-	} // if (open_animation)
-
-	if (cast_list) {
-		int retval;
-		int reparentize = 0;
-
-		s->pic_not_valid = 0;
-
-		_k_view_list_do_postdraw(s, s->dyn_views);
-
-		// _k_view_list_dispose_loop() returns -1 if it requested a re-start, so we do just that.
-		while ((retval = _k_view_list_dispose_loop(s, cast_list, (GfxDynView *) s->dyn_views->_contents, argc, argv) < 0))
-			reparentize = 1;
-
-		if (s->drop_views->_contents) {
-			s->drop_views = gfxw_new_list(s->dyn_views->_bounds, GFXW_LIST_SORTED);
-			s->drop_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS;
-			ADD_TO_CURRENT_PICTURE_PORT(s->drop_views);
-		} else {
-			assert(s->drop_views);
-			gfxw_remove_widget_from_container(s->drop_views->_parent, s->drop_views);
-			ADD_TO_CURRENT_PICTURE_PORT(s->drop_views);
-		}
-
-		if ((reparentize | retval)
-		        && ((GfxContainer *)s->port == (GfxContainer *)s->dyn_views->_parent) // If dynviews are on the same port...
-		        && (s->dyn_views->_next)) // ... and not on top of the view list...
-			reparentize_primary_widget_lists(s, s->port); // ...then reparentize.
-
-		_k_view_list_kryptonize(s->dyn_views->_contents);
-	}
-
-	FULL_REDRAW();
+	s->gui->animate(castListReference, cycle, argc, argv);
 	return s->r_acc;
 }
 

Modified: scummvm/trunk/engines/sci/gui/gui.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui.cpp	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/gui/gui.cpp	2009-10-04 14:59:51 UTC (rev 44606)
@@ -325,6 +325,22 @@
 	return result;
 }
 
+void SciGUI::animate(reg_t castListReference, bool cycle, int argc, reg_t *argv) {
+	// FIXME: port over from gregs engine
+}
+
+void SciGUI::addToPicList(reg_t listReference, int argc, reg_t *argv) {
+	// FIXME: port over from gregs engine
+}
+
+void SciGUI::addToPicView(sciResourceId viewId, uint16 loopNo, uint16 cellNo, int16 leftPos, int16 topPos, int16 priority, int16 control) {
+	// FIXME: port over from gregs engine
+}
+
+void SciGUI::setNowSeen(reg_t objectReference) {
+	// FIXME: port over from gregs engine
+}
+
 void SciGUI::moveCursor(int16 x, int16 y) {
 	Common::Point newPos;
 	

Modified: scummvm/trunk/engines/sci/gui/gui.h
===================================================================
--- scummvm/trunk/engines/sci/gui/gui.h	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/gui/gui.h	2009-10-04 14:59:51 UTC (rev 44606)
@@ -75,6 +75,11 @@
 	virtual void paletteAnimate(int fromColor, int toColor, int speed);
 
 	virtual int16 onControl(byte screenMask, Common::Rect rect);
+	// FIXME: argc/argv because of gui32.cpp, should get removed sometime
+	virtual void animate(reg_t listReference, bool cycle, int argc, reg_t *argv);
+	virtual void addToPicList(reg_t listReference, int argc, reg_t *argv);
+	virtual void addToPicView(sciResourceId viewId, uint16 loopNo, uint16 cellNo, int16 leftPos, int16 topPos, int16 priority, int16 control);
+	virtual void setNowSeen(reg_t objectReference);
 
 	virtual void moveCursor(int16 x, int16 y);
 

Modified: scummvm/trunk/engines/sci/gui/gui_gfx.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_gfx.cpp	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/gui/gui_gfx.cpp	2009-10-04 14:59:51 UTC (rev 44606)
@@ -916,7 +916,7 @@
 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++)
+	for (int i = left; i < right; i++)
 		_screen->Put_Pixel(i, top, flag, color, prio, control);
 }
 
@@ -924,7 +924,7 @@
 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++)
+	for (int i = top; i < bottom; i++)
 		_screen->Put_Pixel(left, i, flag, color, prio, control);
 }
 

Modified: scummvm/trunk/engines/sci/gui/gui_view.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui/gui_view.cpp	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/gui/gui_view.cpp	2009-10-04 14:59:51 UTC (rev 44606)
@@ -241,7 +241,6 @@
 
 	uint16 width = _loop[loopNo].cell[cellNo].width;
 	uint16 height = _loop[loopNo].cell[cellNo].height;
-//	byte *ptr = _resourceData + _loop[loopNo].cell[cellNo].offset;
 	// allocating memory to store cel's bitmap
 	assert(width * height <= 64000);
 	uint16 pixelCount = width * height;

Modified: scummvm/trunk/engines/sci/gui32/gui32.cpp
===================================================================
--- scummvm/trunk/engines/sci/gui32/gui32.cpp	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/gui32/gui32.cpp	2009-10-04 14:59:51 UTC (rev 44606)
@@ -73,6 +73,7 @@
 
 void SciGUI32::init(bool oldGfxFunctions) {
 	_usesOldGfxFunctions = oldGfxFunctions;
+	_k_animate_ran = false;
 	activated_icon_bar = false;
 	port_origin_x = 0;
 	port_origin_y = 0;
@@ -716,7 +717,7 @@
 	rect_t gfxrect = gfx_rect(rect.left, rect.top + 10, rect.width(), rect.height());
 
 	return gfxop_scan_bitmask(s->gfx_state, gfxrect, map);
-// old code
+// old code, just for reference
 //	int xstart, ystart;
 //	int xlen = 1, ylen = 1;
 //
@@ -738,6 +739,1251 @@
 //	return make_reg(0, gfxop_scan_bitmask(s->gfx_state, gfx_rect(xstart, ystart + 10, xlen, ylen), map));
 }
 
+enum {
+	_K_MAKE_VIEW_LIST_CYCLE = 1,
+	_K_MAKE_VIEW_LIST_CALC_PRIORITY = 2,
+	_K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP = 4
+};
+
+static inline int sign_extend_byte(int value) {
+	if (value & 0x80)
+		return value - 256;
+	else
+		return value;
+}
+
+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;
+	int cel, loop, view_nr = (int16)GET_SEL32V(obj, view);
+	int palette;
+	int signal;
+	reg_t under_bits;
+	Common::Point pos;
+	int z;
+	GfxDynView *widget;
+
+	debugC(2, kDebugLevelGraphics, " - Adding %04x:%04x\n", PRINT_REG(obj));
+
+	obj = obj;
+
+	pos.x = (int16)GET_SEL32V(obj, x);
+	pos.y = (int16)GET_SEL32V(obj, y);
+
+	pos.y++; // magic: Sierra appears to do something like this
+
+	z = (int16)GET_SEL32V(obj, z);
+
+	// !-- nsRect used to be checked here!
+	loop = oldloop = sign_extend_byte(GET_SEL32V(obj, loop));
+	cel = oldcel = sign_extend_byte(GET_SEL32V(obj, cel));
+
+	if (s->_kernel->_selectorCache.palette)
+		palette = GET_SEL32V(obj, palette);
+	else
+		palette = 0;
+
+	// Clip loop and cel, write back if neccessary
+	gfxop_check_cel(s->gfx_state, view_nr, &loop, &cel);
+
+	if (loop != oldloop)
+		loop = 0;
+	if (cel != oldcel)
+		cel = 0;
+
+	if (oldloop != loop)
+		PUT_SEL32V(obj, loop, loop);
+
+	if (oldcel != cel) {
+		PUT_SEL32V(obj, cel, cel);
+	}
+
+	ObjVarRef under_bitsp;
+	if (lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.underBits, &(under_bitsp), NULL) != kSelectorVariable) {
+		under_bitsp.obj = NULL_REG;
+		under_bits = NULL_REG;
+		debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no underBits\n", PRINT_REG(obj));
+	} else
+		under_bits = *under_bitsp.getPointer(s->segMan);
+
+	ObjVarRef signalp;
+	if (lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.signal, &(signalp), NULL) != kSelectorVariable) {
+		signalp.obj = NULL_REG;
+		signal = 0;
+		debugC(2, kDebugLevelGraphics, "Object at %04x:%04x has no signal selector\n", PRINT_REG(obj));
+	} else {
+		signal = signalp.getPointer(s->segMan)->offset;
+		debugC(2, kDebugLevelGraphics, "    with signal = %04x\n", signal);
+	}
+
+	widget = gfxw_new_dyn_view(s->gfx_state, pos, z, view_nr, loop, cel, palette, -1, -1, ALIGN_CENTER, ALIGN_BOTTOM, nr);
+
+	if (widget) {
+		widget = (GfxDynView *) gfxw_set_id(widget, obj.segment, obj.offset);
+		widget = gfxw_dyn_view_set_params(widget, under_bits.segment, under_bitsp, signal, signalp);
+		widget->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS; // Only works the first time 'round'
+
+		return widget;
+	} else {
+		warning("Could not generate dynview widget for %d/%d/%d", view_nr, loop, cel);
+		return NULL;
+	}
+}
+
+void SciGUI32::_k_make_view_list(GfxList **widget_list, List *list, int options, int argc, reg_t *argv) {
+/* Creates a view_list from a node list in heap space. Returns the list, stores the
+** number of list entries in *list_nr. Calls doit for each entry if cycle is set.
+** argc, argv should be the same as in the calling kernel function.
+*/
+	SegManager *segMan = s->segMan;
+	Node *node;
+	int sequence_nr = 0;
+	GfxDynView *widget;
+
+	if (!*widget_list) {
+		error("make_view_list with widget_list == ()");
+	};
+
+	assert_primary_widget_lists(s);
+	// In case one of the views' doit() does a DrawPic...
+	// Yes, this _does_ happen!
+
+	if (!list) { // list sanity check
+		error("Attempt to make list from non-list");
+	}
+
+	reg_t next_node = list->first;
+	node = lookup_node(s, next_node);
+	while (node) {
+		reg_t obj = node->value; // The object we're using
+		GfxDynView *tempWidget;
+
+		if (options & _K_MAKE_VIEW_LIST_CYCLE) {
+			unsigned int signal = GET_SEL32V(obj, signal);
+
+			if (!(signal & _K_VIEW_SIG_FLAG_FROZEN)) {
+
+				debugC(2, kDebugLevelGraphics, "  invoking %04x:%04x::doit()\n", PRINT_REG(obj));
+				invoke_selector(INV_SEL(obj, doit, kContinueOnInvalidSelector), 0); // Call obj::doit() if neccessary
+
+
+				// Lookup node again, since the NodeTable it was in may
+				// have been re-allocated.
+				node = lookup_node(s, next_node);
+			}
+		}
+
+		next_node = node->succ; // In case the cast list was changed
+
+		if (list->first.segment == 0 && list->first.offset == 0) // The cast list was completely emptied!
+			break;
+
+		tempWidget = _k_make_dynview_obj(obj, options, sequence_nr--, argc, argv);
+		if (tempWidget)
+			(*widget_list)->add((GfxContainer *)(*widget_list), tempWidget);
+
+		node = lookup_node(s, next_node); // Next node
+	}
+
+	widget = (GfxDynView *)(*widget_list)->_contents;
+
+	while (widget) { // Read back widget values
+		reg_t *sp = widget->signalp.getPointer(s->segMan);
+		if (sp)
+			widget->signal = sp->offset;
+
+		widget = (GfxDynView *)widget->_next;
+	}
+}
+
+void SciGUI32::draw_rect_to_control_map(Common::Rect abs_zone) {
+	GfxBox *box;
+	gfx_color_t color;
+
+	gfxop_set_color(s->gfx_state, &color, -1, -1, -1, -1, -1, 0xf);
+
+	debugC(2, kDebugLevelGraphics, "    adding control block (%d,%d)to(%d,%d)\n", abs_zone.left, abs_zone.top, abs_zone.right, abs_zone.bottom);
+
+	box = gfxw_new_box(s->gfx_state, gfx_rect(abs_zone.left, abs_zone.top, abs_zone.width(),
+						abs_zone.height()), color, color, GFX_BOX_SHADE_FLAT);
+
+	assert_primary_widget_lists(s);
+
+	ADD_TO_CURRENT_PICTURE_PORT(box);
+}
+
+void SciGUI32::draw_obj_to_control_map(GfxDynView *view) {
+	reg_t obj = make_reg(view->_ID, view->_subID);
+
+	if (!s->segMan->isObject(obj))
+		warning("View %d does not contain valid object reference %04x:%04x", view->_ID, PRINT_REG(obj));
+
+	reg_t* sp = view->signalp.getPointer(s->segMan);
+	if (!(sp && (sp->offset & _K_VIEW_SIG_FLAG_IGNORE_ACTOR))) {
+		Common::Rect abs_zone = get_nsrect32(s, make_reg(view->_ID, view->_subID), 1);
+		draw_rect_to_control_map(abs_zone);
+	}
+}
+
+int SciGUI32::_k_view_list_dispose_loop(List *list, GfxDynView *widget, int argc, reg_t *argv) {
+// disposes all list members flagged for disposal
+// returns non-zero IFF views were dropped
+	int signal;
+	int dropped = 0;
+	SegManager *segMan = s->segMan;
+
+	_k_animate_ran = false;
+
+	if (widget) {
+		int retval;
+		// Recurse:
+		retval = _k_view_list_dispose_loop(list, (GfxDynView *)widget->_next, argc, argv);
+
+		if (retval == -1) // Bail out on annihilation, rely on re-start from Animate()
+			return -1;
+
+		if (GFXW_IS_DYN_VIEW(widget) && (widget->_ID != GFXW_NO_ID)) {
+			signal = widget->signalp.getPointer(segMan)->offset;
+			if (signal & _K_VIEW_SIG_FLAG_DISPOSE_ME) {
+				reg_t obj = make_reg(widget->_ID, widget->_subID);
+				reg_t under_bits = NULL_REG;
+
+				if (!s->segMan->isObject(obj)) {
+					error("Non-object %04x:%04x present in view list during delete time", PRINT_REG(obj));
+					obj = NULL_REG;
+				} else {
+					reg_t *ubp = widget->under_bitsp.getPointer(segMan);
+					if (ubp) { // Is there a bg picture left to clean?
+						reg_t mem_handle = *ubp;
+
+						if (mem_handle.segment) {
+							if (!kfree(s->segMan, mem_handle)) {
+								*ubp = make_reg(0, widget->under_bits = 0);
+							} else {
+								warning("Treating viewobj %04x:%04x as no longer present", PRINT_REG(obj));
+								obj = NULL_REG;
+							}
+						}
+					}
+				}
+				if (segMan->isObject(obj)) {
+					if (invoke_selector(INV_SEL(obj, delete_, kContinueOnInvalidSelector), 0))
+						warning("Object at %04x:%04x requested deletion, but does not have a delete funcselector", PRINT_REG(obj));
+					if (_k_animate_ran) {
+						warning("Object at %04x:%04x invoked kAnimate() during deletion", PRINT_REG(obj));
+						return dropped;
+					}
+
+					reg_t *ubp = widget->under_bitsp.getPointer(segMan);
+					if (ubp)
+						under_bits = *ubp;
+
+					if (under_bits.segment) {
+						*ubp = make_reg(0, 0);
+						graph_restore_box(s, under_bits);
+					}
+
+					debugC(2, kDebugLevelGraphics, "Freeing %04x:%04x with signal=%04x\n", PRINT_REG(obj), signal);
+
+					if (!(signal & _K_VIEW_SIG_FLAG_HIDDEN)) {
+						debugC(2, kDebugLevelGraphics, "Adding view at %04x:%04x to background\n", PRINT_REG(obj));
+						if (!(gfxw_remove_id(widget->_parent, widget->_ID, widget->_subID) == widget)) {
+							error("Attempt to remove view with ID %x:%x from list failed", widget->_ID, widget->_subID);
+						}
+
+						s->drop_views->add((GfxContainer *)s->drop_views, gfxw_picviewize_dynview(widget));
+
+						draw_obj_to_control_map(widget);
+						widget->draw_bounds.y += s->dyn_views->_bounds.y - widget->_parent->_bounds.y;
+						widget->draw_bounds.x += s->dyn_views->_bounds.x - widget->_parent->_bounds.x;
+						dropped = 1;
+					} else {
+						debugC(2, kDebugLevelGraphics, "Deleting view at %04x:%04x\n", PRINT_REG(obj));
+						widget->_flags |= GFXW_FLAG_VISIBLE;
+						gfxw_annihilate(widget);
+						return -1; // restart: Done in Animate()
+					}
+				}
+			}
+		}
+
+	}
+
+	return dropped;
+}
+
+void SciGUI32::_k_set_now_seen(reg_t object) {
+	SegManager *segMan = s->segMan;
+	Common::Rect absrect = get_nsrect32(s, object, 0);
+
+	if (lookup_selector(s->segMan, object, s->_kernel->_selectorCache.nsTop, NULL, NULL) != kSelectorVariable) {
+		return;
+	} // This isn't fatal
+
+	PUT_SEL32V(object, nsLeft, absrect.left);
+	PUT_SEL32V(object, nsRight, absrect.right);
+	PUT_SEL32V(object, nsTop, absrect.top);
+	PUT_SEL32V(object, nsBottom, absrect.bottom);
+}
+
+void SciGUI32::_k_prepare_view_list(GfxList *list, int options) {
+	SegManager *segMan = s->segMan;
+	GfxDynView *view = (GfxDynView *) list->_contents;
+	while (view) {
+		reg_t obj = make_reg(view->_ID, view->_subID);
+		int priority, _priority;
+		int has_nsrect = (view->_ID <= 0) ? 0 : lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.nsBottom, NULL, NULL) == kSelectorVariable;
+		int oldsignal = view->signal;
+
+		_k_set_now_seen(obj);
+		_priority = /*GET_SELECTOR(obj, y); */((view->_pos.y));
+		_priority = _find_view_priority(s, _priority - 1);
+
+		if (options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP) { // Picview
+			priority = (int16)GET_SEL32V(obj, priority);
+			if (priority < 0)
+				priority = _priority; // Always for picviews
+		} else { // Dynview
+			if (has_nsrect && !(view->signal & _K_VIEW_SIG_FLAG_FIX_PRI_ON)) { // Calculate priority
+				if (options & _K_MAKE_VIEW_LIST_CALC_PRIORITY)
+					PUT_SEL32V(obj, priority, _priority);
+
+				priority = _priority;
+
+			} else // DON'T calculate the priority
+				priority = (int16)GET_SEL32V(obj, priority);
+		}
+
+		view->_color.priority = priority;
+
+		if (priority > -1)
+			view->_color.mask |= GFX_MASK_PRIORITY;
+		else
+			view->_color.mask &= ~GFX_MASK_PRIORITY;
+
+		// CR (from :Bob Heitman:) stopupdated views (like pic views) have
+		// their clipped nsRect drawn to the control map
+		if (view->signal & _K_VIEW_SIG_FLAG_STOP_UPDATE) {
+			view->signal |= _K_VIEW_SIG_FLAG_STOPUPD;
+			debugC(2, kDebugLevelGraphics, "Setting magic STOP_UPD for %04x:%04x\n", PRINT_REG(obj));
+		}
+
+		if ((options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP))
+			draw_obj_to_control_map(view);
+
+		// Extreme Pattern Matching ugliness ahead...
+		if (view->signal & _K_VIEW_SIG_FLAG_NO_UPDATE) {
+			if (((view->signal & (_K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_FORCE_UPDATE))) // 9.1.1.1
+			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE)) == _K_VIEW_SIG_FLAG_HIDDEN)
+			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE)) == _K_VIEW_SIG_FLAG_REMOVE) // 9.1.1.2
+			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == _K_VIEW_SIG_FLAG_ALWAYS_UPDATE) // 9.1.1.3
+			        || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE))) { // 9.1.1.4
+				s->pic_not_valid++;
+				view->signal &= ~_K_VIEW_SIG_FLAG_STOP_UPDATE;
+			}
+
+			else if (((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == 0)
+			         || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE))
+			         || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE))
+			         || ((view->signal & (_K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == _K_VIEW_SIG_FLAG_HIDDEN)) {
+				view->signal &= ~_K_VIEW_SIG_FLAG_STOP_UPDATE;
+			}
+		} else {
+			if (view->signal & _K_VIEW_SIG_FLAG_STOP_UPDATE) {
+				s->pic_not_valid++;
+				view->signal &= ~_K_VIEW_SIG_FLAG_FORCE_UPDATE;
+			} else { // if not STOP_UPDATE
+				if (view->signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)
+					s->pic_not_valid++;
+				view->signal &= ~_K_VIEW_SIG_FLAG_FORCE_UPDATE;
+			}
+		}
+
+		debugC(2, kDebugLevelGraphics, "  dv[%04x:%04x]: signal %04x -> %04x\n", PRINT_REG(obj), oldsignal, view->signal);
+
+		// Never happens
+/*		if (view->signal & 0) {
+			view->signal &= ~_K_VIEW_SIG_FLAG_STOPUPD;
+			fprintf(stderr, "Unsetting magic StopUpd for view %04x:%04x\n", PRINT_REG(obj));
+		} */
+
+		view = (GfxDynView *)view->_next;
+	}
+}
+
+void SciGUI32::_k_update_signals_in_view_list(GfxList *old_list, GfxList *new_list) {
+	// O(n^2)... a bit painful, but much faster than the redraws it helps prevent
+	GfxDynView *old_widget = (GfxDynView *)old_list->_contents;
+
+	/* Traverses all old widgets, updates them with signals from the new widgets.
+	** This is done to avoid evil hacks in widget.c; widgets with unique IDs are
+	** replaced there iff they are NOT equal_to a new widget with the same ID.
+	** If they were replaced every time, we'd be doing far too many redraws.
+	*/
+
+	while (old_widget) {
+		GfxDynView *new_widget = (GfxDynView *) new_list->_contents;
+
+		while (new_widget
+		        && (new_widget->_ID != old_widget->_ID
+		            || new_widget->_subID != old_widget->_subID))
+			new_widget = (GfxDynView *)new_widget->_next;
+
+		if (new_widget) {
+			int carry = old_widget->signal & _K_VIEW_SIG_FLAG_STOPUPD;
+			// Transfer 'stopupd' flag
+
+			if ((new_widget->_pos.x != old_widget->_pos.x)
+			        || (new_widget->_pos.y != old_widget->_pos.y)
+					// No idea why this is supposed to be bad
+/*			        || (new_widget->z != old_widget->z)
+			        || (new_widget->view != old_widget->view)
+			        || (new_widget->loop != old_widget->loop)
+			        || (new_widget->cel != old_widget->cel)
+			        */)
+				carry = 0;
+
+			old_widget->signal = new_widget->signal |= carry;
+		}
+
+		old_widget = (GfxDynView *)old_widget->_next;
+	}
+}
+
+void SciGUI32::_k_view_list_kryptonize(GfxWidget *v) {
+	if (v) {
+		v->_flags &= ~GFXW_FLAG_IMMUNE_TO_SNAPSHOTS;
+		_k_view_list_kryptonize(v->_next);
+	}
+}
+
+void SciGUI32::_k_raise_topmost_in_view_list(GfxList *list, GfxDynView *view) {
+	if (view) {
+		GfxDynView *next = (GfxDynView *)view->_next;
+
+		// step 11
+		if ((view->signal & (_K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)) == 0) {
+			debugC(2, kDebugLevelGraphics, "Forcing precedence 2 at [%04x:%04x] with %04x\n", PRINT_REG(make_reg(view->_ID, view->_subID)), view->signal);
+			view->force_precedence = 2;
+
+			if ((view->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_HIDDEN)) == _K_VIEW_SIG_FLAG_REMOVE) {
+				view->signal &= ~_K_VIEW_SIG_FLAG_REMOVE;
+			}
+		}
+
+		gfxw_remove_widget_from_container(view->_parent, view);
+
+		if (view->signal & _K_VIEW_SIG_FLAG_HIDDEN)
+			gfxw_hide_widget(view);
+		else
+			gfxw_show_widget(view);
+
+		list->add((GfxContainer *)list, view);
+
+		_k_raise_topmost_in_view_list(list, next);
+	}
+}
+
+void SciGUI32::_k_redraw_view_list(GfxList *list) {
+	GfxDynView *view = (GfxDynView *) list->_contents;
+	while (view) {
+
+		debugC(2, kDebugLevelGraphics, "  dv[%04x:%04x]: signal %04x\n", PRINT_REG(make_reg(view->_ID, view->_subID)), view->signal);
+
+		// step 1 of subalgorithm
+		if (view->signal & _K_VIEW_SIG_FLAG_NO_UPDATE) {
+			if (view->signal & _K_VIEW_SIG_FLAG_FORCE_UPDATE)
+				view->signal &= ~_K_VIEW_SIG_FLAG_FORCE_UPDATE;
+
+			if (view->signal & _K_VIEW_SIG_FLAG_UPDATED)
+				view->signal &= ~(_K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE);
+		} else { // NO_UPD is not set
+			if (view->signal & _K_VIEW_SIG_FLAG_STOP_UPDATE) {
+				view->signal &= ~_K_VIEW_SIG_FLAG_STOP_UPDATE;
+				view->signal |= _K_VIEW_SIG_FLAG_NO_UPDATE;
+			}
+		}
+
+		debugC(2, kDebugLevelGraphics, "    at substep 6: signal %04x\n", view->signal);
+
+		if (view->signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE)
+			view->signal &= ~(_K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE);
+
+		debugC(2, kDebugLevelGraphics, "    at substep 11/14: signal %04x\n", view->signal);
+
+		if (view->signal & _K_VIEW_SIG_FLAG_NO_UPDATE) {
+			if (view->signal & _K_VIEW_SIG_FLAG_HIDDEN)
+				view->signal |= _K_VIEW_SIG_FLAG_REMOVE;
+			else
+				view->signal &= ~_K_VIEW_SIG_FLAG_REMOVE;
+		} else if (!(view->signal & _K_VIEW_SIG_FLAG_HIDDEN))
+			view->force_precedence = 1;
+
+		debugC(2, kDebugLevelGraphics, "    -> signal %04x\n", view->signal);
+
+		view = (GfxDynView *)view->_next;
+	}
+}
+
+// Flags for _k_draw_view_list
+// Whether some magic with the base object's "signal" selector should be done:
+#define _K_DRAW_VIEW_LIST_USE_SIGNAL 1
+// This flag draws all views with the "DISPOSE_ME" flag set:
+#define _K_DRAW_VIEW_LIST_DISPOSEABLE 2
+// Use this one to draw all views with "DISPOSE_ME" NOT set:
+#define _K_DRAW_VIEW_LIST_NONDISPOSEABLE 4
+// Draw as picviews
+#define _K_DRAW_VIEW_LIST_PICVIEW 8
+
+void SciGUI32::_k_draw_view_list(GfxList *list, int flags) {
+	// Draws list_nr members of list to s->pic.
+	GfxDynView *widget = (GfxDynView *) list->_contents;
+
+	if ((GfxContainer *)s->port != (GfxContainer *)s->dyn_views->_parent)
+		return; // Return if the pictures are meant for a different port
+
+	while (widget) {
+		if (flags & _K_DRAW_VIEW_LIST_PICVIEW)
+			widget = gfxw_picviewize_dynview(widget);
+
+		if (GFXW_IS_DYN_VIEW(widget) && widget->_ID) {
+			uint16 signal = (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) ? widget->signalp.getPointer(s->segMan)->offset : 0;
+
+			if (signal & _K_VIEW_SIG_FLAG_HIDDEN)
+				gfxw_hide_widget(widget);
+			else
+				gfxw_show_widget(widget);
+
+			if (!(flags & _K_DRAW_VIEW_LIST_USE_SIGNAL)
+			        || ((flags & _K_DRAW_VIEW_LIST_DISPOSEABLE) && (signal & _K_VIEW_SIG_FLAG_DISPOSE_ME))
+			        || ((flags & _K_DRAW_VIEW_LIST_NONDISPOSEABLE) && !(signal & _K_VIEW_SIG_FLAG_DISPOSE_ME))) {
+
+				if (flags & _K_DRAW_VIEW_LIST_USE_SIGNAL) {
+					signal &= ~(_K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE);
+					// Clear all of those flags
+
+					if (signal & _K_VIEW_SIG_FLAG_HIDDEN)
+						gfxw_hide_widget(widget);
+					else
+						gfxw_show_widget(widget);
+
+					*widget->signalp.getPointer(s->segMan) = make_reg(0, signal); // Write the changes back
+				};
+
+			} // ...if we're drawing disposeables and this one is disposeable, or if we're drawing non-
+			  // disposeables and this one isn't disposeable
+		}
+
+		widget = (GfxDynView *)widget->_next;
+	} // while (widget)
+}
+
+void SciGUI32::_k_view_list_do_postdraw(GfxList *list) {
+	SegManager *segMan = s->segMan;
+	GfxDynView *widget = (GfxDynView *) list->_contents;
+
+	while (widget) {
+		reg_t obj = make_reg(widget->_ID, widget->_subID);
+
+		/*
+		 * this fixes a few problems, but doesn't match SSCI's logic.
+		 * The semantics of the private flag need to be verified before this can be uncommented.
+		 * Fixes bug #326 (CB1, ego falls down stairs)
+		 * if ((widget->signal & (_K_VIEW_SIG_FLAG_PRIVATE | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)) == _K_VIEW_SIG_FLAG_PRIVATE) {
+		 */
+		if ((widget->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)) == 0) {
+			int has_nsrect = lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.nsBottom, NULL, NULL) == kSelectorVariable;
+
+			if (has_nsrect) {
+				int temp;
+
+				temp = GET_SEL32V(obj, nsLeft);
+				PUT_SEL32V(obj, lsLeft, temp);
+
+				temp = GET_SEL32V(obj, nsRight);
+				PUT_SEL32V(obj, lsRight, temp);
+
+				temp = GET_SEL32V(obj, nsTop);
+				PUT_SEL32V(obj, lsTop, temp);
+
+				temp = GET_SEL32V(obj, nsBottom);
+				PUT_SEL32V(obj, lsBottom, temp);
+#ifdef DEBUG_LSRECT
+				fprintf(stderr, "lsRected %04x:%04x\n", PRINT_REG(obj));
+#endif
+			}
+#ifdef DEBUG_LSRECT
+			else
+				fprintf(stderr, "Not lsRecting %04x:%04x because %d\n", PRINT_REG(obj), lookup_selector(s->segMan, obj, s->_kernel->_selectorCache.nsBottom, NULL, NULL));
+#endif
+
+			if (widget->signal & _K_VIEW_SIG_FLAG_HIDDEN)
+				widget->signal |= _K_VIEW_SIG_FLAG_REMOVE;
+		}
+#ifdef DEBUG_LSRECT
+		fprintf(stderr, "obj %04x:%04x has pflags %x\n", PRINT_REG(obj), (widget->signal & (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE)));
+#endif
+
+		reg_t* sp = widget->signalp.getPointer(s->segMan);
+		if (sp) {
+			*sp = make_reg(0, widget->signal & 0xffff); /* Write back signal */
+		}
+
+		widget = (GfxDynView *)widget->_next;
+	}
+}
+
+#define K_ANIMATE_CENTER_OPEN_H  0 // horizontally open from center
+#define K_ANIMATE_CENTER_OPEN_V  1 // vertically open from center
+#define K_ANIMATE_RIGHT_OPEN     2 // open from right
+#define K_ANIMATE_LEFT_OPEN      3 // open from left
+#define K_ANIMATE_BOTTOM_OPEN    4 // open from bottom
+#define K_ANIMATE_TOP_OPEN       5 // open from top
+#define K_ANIMATE_BORDER_OPEN_F  6 // open from edges to center
+#define K_ANIMATE_CENTER_OPEN_F  7 // open from center to edges
+#define K_ANIMATE_OPEN_CHECKERS  8 // open random checkboard
+#define K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H  9 // horizontally close to center,reopen from center
+#define K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V 10 // vertically close to center, reopen from center
+#define K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN        11 // close to right, reopen from right
+#define K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN        12 // close to left,  reopen from left
+#define K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN        13 // close to bottom, reopen from bottom
+#define K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN        14 // close to top, reopen from top
+#define K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F 15 // close from center to edges,
+// reopen from edges to center
+#define K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F 16 // close from edges to center, reopen from
+// center to edges */
+#define K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS 17 // close random checkboard, reopen
+#define K_ANIMATE_PALETTE_FADEOUT_FADEIN       0x1e
+#define K_ANIMATE_SCROLL_LEFT                  0x28
+#define K_ANIMATE_SCROLL_RIGHT                 0x29
+#define K_ANIMATE_SCROLL_DOWN                  0x2a
+#define K_ANIMATE_SCROLL_UP                    0x2b
+
+#define GRAPH_BLANK_BOX(s, x, y, xl, yl, color) gfxop_fill_box(s->gfx_state, \
+	gfx_rect(x, (((y) < 10)? 10 : (y)), xl, (((y) < 10)? ((y) - 10) : 0) + (yl)), s->ega_colors[color]);
+
+#define GRAPH_UPDATE_BOX(s, x, y, xl, yl) gfxop_draw_pixmap(s->gfx_state, newscreen, \
+	gfx_rect(x, (((y) < 10)? 10 : (y)) - 10, xl, (((y) < 10)? ((y) - 10) : 0) + (yl)), Common::Point(x, ((y) < 10)? 10 : (y) ));
+
+void SciGUI32::animate_do_animation(int argc, reg_t *argv) {
+	long animation_delay = 5;
+	int i, remaining_checkers;
+	int update_counter;
+	// Number of animation steps to perform betwen updates for transition animations
+	int animation_granularity = 4;
+	int granularity0 = animation_granularity << 1;
+	int granularity1 = animation_granularity;
+	int granularity2 = animation_granularity >> 2;
+	int granularity3 = animation_granularity >> 4;
+	char checkers[32 * 19];
+	gfx_pixmap_t *newscreen = gfxop_grab_pixmap(s->gfx_state, gfx_rect(0, 10, 320, 190));
+
+	if (!granularity2)
+		granularity2 = 1;
+	if (!granularity3)
+		granularity3 = 1;
+
+	gfxop_set_clip_zone(s->gfx_state, gfx_rect_fullscreen);
+
+	if (!newscreen) {
+		error("Failed to allocate 'newscreen'");
+		return;
+	}
+
+	gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, 0, 320, 190), Common::Point(0, 10));
+	gfxop_update_box(s->gfx_state, gfx_rect(0, 0, 320, 200));
+
+	//debugC(2, kDebugLevelGraphics, "Animating pic opening type %x\n", s->pic_animate);
+
+	gfxop_enable_dirty_frames(s->gfx_state);
+
+	switch (s->pic_animate) {
+	case K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H :
+		for (i = 0; i < 159 + granularity1; i += granularity1) {
+			GRAPH_BLANK_BOX(s, i, 10, granularity1, 190, 0);
+			gfxop_update(s->gfx_state);
+			GRAPH_BLANK_BOX(s, 319 - i, 10, granularity1, 190, 0);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 1000);
+			process_sound_events(s);
+		}
+		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
+
+	case K_ANIMATE_CENTER_OPEN_H :
+
+		for (i = 159; i >= 1 - granularity1; i -= granularity1) {
+			GRAPH_UPDATE_BOX(s, i, 10, granularity1, 190);
+			gfxop_update(s->gfx_state);
+			GRAPH_UPDATE_BOX(s, 319 - i, 10, granularity1, 190);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 1000);
+			process_sound_events(s);
+		}
+		break;
+
+
+	case K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V :
+
+		for (i = 0; i < 94 + granularity2; i += granularity2) {
+			GRAPH_BLANK_BOX(s, 0, i + 10, 320, granularity2, 0);
+			gfxop_update(s->gfx_state);
+			GRAPH_BLANK_BOX(s, 0, 199 - i, 320, granularity2, 0);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, 2 * animation_delay / 1000);
+			process_sound_events(s);
+		}
+		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
+
+	case K_ANIMATE_CENTER_OPEN_V :
+
+		for (i = 94; i >= 1 - granularity2; i -= granularity2) {
+			GRAPH_UPDATE_BOX(s, 0, i + 10, 320, granularity2);
+			gfxop_update(s->gfx_state);
+			GRAPH_UPDATE_BOX(s, 0, 199 - i, 320, granularity2);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, 2 * animation_delay / 1000);
+			process_sound_events(s);
+		}
+		break;
+
+
+	case K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN :
+
+		for (i = 0; i < 319 + granularity0; i += granularity0) {
+			GRAPH_BLANK_BOX(s, i, 10, granularity0, 190, 0);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
+			process_sound_events(s);
+		}
+		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
+
+	case K_ANIMATE_RIGHT_OPEN :
+		for (i = 319; i >= 1 - granularity0; i -= granularity0) {
+			GRAPH_UPDATE_BOX(s, i, 10, granularity0, 190);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
+			process_sound_events(s);
+		}
+		break;
+
+
+	case K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN :
+
+		for (i = 319; i >= 1 - granularity0; i -= granularity0) {
+			GRAPH_BLANK_BOX(s, i, 10, granularity0, 190, 0);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
+			process_sound_events(s);
+		}
+		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
+
+	case K_ANIMATE_LEFT_OPEN :
+
+		for (i = 0; i < 319 + granularity0; i += granularity0) {
+			GRAPH_UPDATE_BOX(s, i, 10, granularity0, 190);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 2 / 1000);
+			process_sound_events(s);
+		}
+		break;
+
+
+	case K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN :
+
+		for (i = 10; i < 199 + granularity1; i += granularity1) {
+			GRAPH_BLANK_BOX(s, 0, i, 320, granularity1, 0);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 1000);
+			process_sound_events(s);
+		}
+		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
+
+	case K_ANIMATE_BOTTOM_OPEN :
+
+		for (i = 199; i >= 11 - granularity1; i -= granularity1) {
+			GRAPH_UPDATE_BOX(s, 0, i, 320, granularity1);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 1000);
+			process_sound_events(s);
+		}
+		break;
+
+
+	case K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN :
+
+		for (i = 199; i >= 11 - granularity1; i -= granularity1) {
+			GRAPH_BLANK_BOX(s, 0, i, 320, granularity1, 0);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 1000);
+			process_sound_events(s);
+		}
+		GRAPH_BLANK_BOX(s, 0, 10, 320, 190, 0);
+
+	case K_ANIMATE_TOP_OPEN :
+
+		for (i = 10; i < 199 + granularity1; i += granularity1) {
+			GRAPH_UPDATE_BOX(s, 0, i, 320, granularity1);
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, animation_delay / 1000);
+			process_sound_events(s);
+		}
+		break;
+
+
+	case K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F :
+
+		for (i = 31; i >= 1 - granularity3; i -= granularity3) {
+			int real_i = (i < 0) ? 0 : i;
+			int height_l = 3 * (granularity3 - real_i + i);
+			int width_l = 5 * (granularity3 - real_i + i);
+			int height = real_i * 3;
+			int width = real_i * 5;
+
+			GRAPH_BLANK_BOX(s, width, 10 + height, width_l, 190 - 2 * height, 0);
+			gfxop_update(s->gfx_state);
+			GRAPH_BLANK_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height, 0);
+			gfxop_update(s->gfx_state);
+
+			GRAPH_BLANK_BOX(s, width, 10 + height, 320 - 2 * width, height_l, 0);
+			gfxop_update(s->gfx_state);
+			GRAPH_BLANK_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0);
+			gfxop_update(s->gfx_state);
+
+			gfxop_sleep(s->gfx_state, 4 * animation_delay / 1000);
+			process_sound_events(s);
+		}
+
+	case K_ANIMATE_BORDER_OPEN_F :
+
+		for (i = 0; i < 31 + granularity3; i += granularity3) {
+			int real_i = (i < 0) ? 0 : i;
+			int height_l = 3 * (granularity3 - real_i + i);
+			int width_l = 5 * (granularity3 - real_i + i);
+			int height = real_i * 3;
+			int width = real_i * 5;
+
+			GRAPH_UPDATE_BOX(s, width, 10 + height, width_l, 190 - 2 * height);
+			gfxop_update(s->gfx_state);
+			GRAPH_UPDATE_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height);
+			gfxop_update(s->gfx_state);
+
+			GRAPH_UPDATE_BOX(s, width, 10 + height, 320 - 2 * width, height_l);
+			gfxop_update(s->gfx_state);
+			GRAPH_UPDATE_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l);
+			gfxop_update(s->gfx_state);
+
+			gfxop_sleep(s->gfx_state, 4 * animation_delay / 1000);
+			process_sound_events(s);
+		}
+
+		break;
+
+	case K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F :
+
+		for (i = 0; i < 31 + granularity3; i += granularity3) {
+			int real_i = (i < 0) ? 0 : i;
+			int height_l = 3 * (granularity3 - real_i + i);
+			int width_l = 5 * (granularity3 - real_i + i);
+			int height = real_i * 3;
+			int width = real_i * 5;
+
+			GRAPH_BLANK_BOX(s, width, 10 + height, width_l, 190 - 2 * height, 0);
+			gfxop_update(s->gfx_state);
+			GRAPH_BLANK_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2 * height, 0);
+			gfxop_update(s->gfx_state);
+
+			GRAPH_BLANK_BOX(s, width, 10 + height, 320 - 2 * width, height_l, 0);
+			gfxop_update(s->gfx_state);
+			GRAPH_BLANK_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l, 0);
+			gfxop_update(s->gfx_state);
+
+			gfxop_sleep(s->gfx_state, 7 * animation_delay / 1000);
+			process_sound_events(s);
+		}
+
+	case K_ANIMATE_CENTER_OPEN_F :
+
+		for (i = 31; i >= 1 - granularity3; i -= granularity3) {
+			int real_i = (i < 0) ? 0 : i;
+			int height_l = 3 * (granularity3 - real_i + i);
+			int width_l = 5 * (granularity3 - real_i + i);
+			int height = real_i * 3;
+			int width = real_i * 5;
+
+			GRAPH_UPDATE_BOX(s, width, 10 + height, width_l, 190 - 2 * height);
+			gfxop_update(s->gfx_state);
+			GRAPH_UPDATE_BOX(s, 320 - width_l - width, 10 + height, width_l, 190 - 2*height);
+			gfxop_update(s->gfx_state);
+
+			GRAPH_UPDATE_BOX(s, width, 10 + height, 320 - 2 * width, height_l);
+			gfxop_update(s->gfx_state);
+			GRAPH_UPDATE_BOX(s, width, 200 - height_l - height, 320 - 2 * width, height_l);
+			gfxop_update(s->gfx_state);
+
+			gfxop_sleep(s->gfx_state, 7 * animation_delay / 1000);
+			process_sound_events(s);
+		}
+		break;
+
+	case K_ANIMATE_PALETTE_FADEOUT_FADEIN:
+		warning("TODO: Palette fadeout/fadein");
+		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
+		break;
+
+	case K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS :
+
+		memset(checkers, 0, sizeof(checkers));
+		remaining_checkers = 19 * 32;
+		update_counter = granularity1;
+
+		while (remaining_checkers) {
+			int x, y, checker = 1 + (int)(1.0 * remaining_checkers * rand() / (RAND_MAX + 1.0));
+			i = -1;
+
+			while (checker)
+				if (checkers[++i] == 0)
+					--checker;
+			checkers[i] = 1; // Mark checker as used
+
+			x = i % 32;
+			y = i / 32;
+
+			GRAPH_BLANK_BOX(s, x * 10, 10 + y * 10, 10, 10, 0);
+			if (!(update_counter--) || (remaining_checkers == 1)) {
+				gfxop_update(s->gfx_state);
+				update_counter = granularity1;
+			}
+
+			if (remaining_checkers & 1) {
+				gfxop_sleep(s->gfx_state, animation_delay / 4 / 1000);
+			}
+
+			--remaining_checkers;
+			process_sound_events(s);
+		}
+
+	case K_ANIMATE_OPEN_CHECKERS :
+
+		memset(checkers, 0, sizeof(checkers));
+		remaining_checkers = 19 * 32;
+		update_counter = granularity1;
+
+		while (remaining_checkers) {
+			int x, y, checker = 1 + (int)(1.0 * remaining_checkers * rand() / (RAND_MAX + 1.0));
+			i = -1;
+
+			while (checker)
+				if (checkers[++i] == 0) --checker;
+			checkers[i] = 1; // Mark checker as used
+
+			x = i % 32;
+			y = i / 32;
+
+			GRAPH_UPDATE_BOX(s, x * 10, 10 + y * 10, 10, 10);
+
+			if (!(update_counter--) || (remaining_checkers == 1)) {
+				gfxop_update(s->gfx_state);
+				update_counter = granularity1;
+			}
+
+			if (remaining_checkers & 1) {
+				gfxop_sleep(s->gfx_state, animation_delay / 4 / 1000);
+			}
+
+			--remaining_checkers;
+			process_sound_events(s);
+		}
+		break;
+
+
+	case K_ANIMATE_SCROLL_LEFT :
+
+		for (i = 0; i < 319; i += granularity0) {
+			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(320 - i, 0, i, 190), Common::Point(0, 10));
+			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, 0, 320 - i, 190), Common::Point(i, 10));
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
+		}
+		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
+		break;
+
+	case K_ANIMATE_SCROLL_RIGHT :
+
+		for (i = 0; i < 319; i += granularity0) {
+			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(0, 0, i, 190), Common::Point(319 - i, 10));
+			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(i, 0, 320 - i, 190), Common::Point(0, 10));
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
+		}
+		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
+		break;
+
+	case K_ANIMATE_SCROLL_UP :
+
+		for (i = 0; i < 189; i += granularity0) {
+			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(0, 190 - i, 320, i), Common::Point(0, 10));
+			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, 0, 320, 190 - i), Common::Point(0, 10 + i));
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
+		}
+		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
+		break;
+
+	case K_ANIMATE_SCROLL_DOWN :
+
+		for (i = 0; i < 189; i += granularity0) {
+			gfxop_draw_pixmap(s->gfx_state, newscreen, gfx_rect(0, 0, 320, i), Common::Point(0, 200 - i));
+			gfxop_draw_pixmap(s->gfx_state, s->old_screen, gfx_rect(0, i, 320, 190 - i), Common::Point(0, 10));
+			gfxop_update(s->gfx_state);
+			gfxop_sleep(s->gfx_state, (animation_delay >> 3) / 1000);
+		}
+		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
+		break;
+
+	default:
+		warning("Unknown opening animation 0x%02x", s->pic_animate);
+		GRAPH_UPDATE_BOX(s, 0, 10, 320, 190);
+
+	}
+
+	gfxop_free_pixmap(s->gfx_state, s->old_screen);
+	gfxop_free_pixmap(s->gfx_state, newscreen);
+	s->old_screen = NULL;
+}
+
+void SciGUI32::animate(reg_t listReference, bool cycle, int argc, reg_t *argv) {
+	// Animations are supposed to take a maximum of animation_delay milliseconds.
+	List *cast_list = NULL;
+	int open_animation = 0;
+
+	process_sound_events(s); // Take care of incoming events (kAnimate is called semi-regularly)
+	_k_animate_ran = true; // Used by some of the invoked functions to check for recursion, which may,
+						// after all, damage the cast list
+
+	if (listReference.segment) {
+		cast_list = lookup_list(s, listReference);
+		if (!cast_list)
+			return;
+	}
+
+	open_animation = (s->pic_is_new) && (s->pic_not_valid);
+	s->pic_is_new = 0;
+
+	assert_primary_widget_lists(s);
+
+	if (!s->dyn_views->_contents // Only reparentize empty dynview list
+	        && (((GfxContainer *)s->port != (GfxContainer *)s->dyn_views->_parent) // If dynviews are on other port...
+	            || (s->dyn_views->_next))) // ... or not on top of the view list
+		reparentize_primary_widget_lists(s, s->port);
+
+	if (cast_list) {
+		GfxList *templist = gfxw_new_list(s->dyn_views->_bounds, 0);
+
+		_k_make_view_list(&(templist), cast_list, (cycle ? _K_MAKE_VIEW_LIST_CYCLE : 0)
+		                  | _K_MAKE_VIEW_LIST_CALC_PRIORITY, argc, (reg_t *)argv);
+
+		// Make sure that none of the doits() did something evil
+		assert_primary_widget_lists(s);
+
+		if (!s->dyn_views->_contents // Only reparentize empty dynview list
+		        && (((GfxContainer *)s->port != (GfxContainer *)s->dyn_views->_parent) // If dynviews are on other port...
+		            || (s->dyn_views->_next))) // ... or not on top of the view list
+			reparentize_primary_widget_lists(s, s->port);
+		// End of doit() recovery code
+
+		if (s->pic_is_new) { // Happens if DrawPic() is executed by a dynview (yes, that happens)
+			animate(listReference, cycle, argc, argv); /* Tail-recurse */
+			return;
+		}
+
+		debugC(2, kDebugLevelGraphics, "Handling Dynviews (..step 9 inclusive):\n");
+		_k_prepare_view_list(templist, _K_MAKE_VIEW_LIST_CALC_PRIORITY);
+
+		if (s->pic_not_valid) {
+			debugC(2, kDebugLevelGraphics, "PicNotValid=%d -> Subalgorithm:\n", s->pic_not_valid);
+			_k_redraw_view_list(templist);
+		}
+
+		_k_update_signals_in_view_list(s->dyn_views, templist);
+		s->dyn_views->tag();
+
+		_k_raise_topmost_in_view_list(s->dyn_views, (GfxDynView *)templist->_contents);
+
+		delete templist;
+		s->dyn_views->free_tagged((GfxContainer *)s->dyn_views); // Free obsolete dynviews
+	} // if (cast_list)
+
+	if (open_animation) {
+		gfxop_clear_box(s->gfx_state, gfx_rect(0, 10, 320, 190)); // Propagate pic
+		s->visual->add_dirty_abs((GfxContainer *)s->visual, gfx_rect_fullscreen, 0);
+		// Mark screen as dirty so picviews will be drawn correctly
+		FULL_REDRAW();
+
+		animate_do_animation(argc, (reg_t*)argv);
+	} // if (open_animation)
+
+	if (cast_list) {
+		int retval;
+		int reparentize = 0;
+
+		s->pic_not_valid = 0;
+
+		_k_view_list_do_postdraw(s->dyn_views);
+
+		// _k_view_list_dispose_loop() returns -1 if it requested a re-start, so we do just that.
+		while ((retval = _k_view_list_dispose_loop(cast_list, (GfxDynView *) s->dyn_views->_contents, argc, (reg_t *)argv) < 0))
+			reparentize = 1;
+
+		if (s->drop_views->_contents) {
+			s->drop_views = gfxw_new_list(s->dyn_views->_bounds, GFXW_LIST_SORTED);
+			s->drop_views->_flags |= GFXW_FLAG_IMMUNE_TO_SNAPSHOTS;
+			ADD_TO_CURRENT_PICTURE_PORT(s->drop_views);
+		} else {
+			assert(s->drop_views);
+			gfxw_remove_widget_from_container(s->drop_views->_parent, s->drop_views);
+			ADD_TO_CURRENT_PICTURE_PORT(s->drop_views);
+		}
+
+		if ((reparentize | retval)
+		        && ((GfxContainer *)s->port == (GfxContainer *)s->dyn_views->_parent) // If dynviews are on the same port...
+		        && (s->dyn_views->_next)) // ... and not on top of the view list...
+			reparentize_primary_widget_lists(s, s->port); // ...then reparentize.
+
+		_k_view_list_kryptonize(s->dyn_views->_contents);
+	}
+
+	FULL_REDRAW();
+}
+
+void SciGUI32::addToPicList(reg_t listReference, int argc, reg_t *argv) {
+	List *list;
+	GfxList *pic_views;
+
+	assert_primary_widget_lists(s);
+
+	if (!listReference.segment) {
+		warning("Attempt to AddToPic single non-list: %04x:%04x", PRINT_REG(listReference));
+		return;
+	}
+
+	list = lookup_list(s, listReference);
+
+	pic_views = gfxw_new_list(s->picture_port->_bounds, 1);
+
+	debugC(2, kDebugLevelGraphics, "Preparing picview list...\n");
+	_k_make_view_list(&pic_views, list, 0, argc, argv);
+	_k_prepare_view_list(pic_views, _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP);
+	// Store pic views for later re-use
+
+	debugC(2, kDebugLevelGraphics, "Drawing picview list...\n");
+	ADD_TO_CURRENT_PICTURE_PORT(pic_views);
+	_k_draw_view_list(pic_views, _K_DRAW_VIEW_LIST_NONDISPOSEABLE | _K_DRAW_VIEW_LIST_DISPOSEABLE | _K_DRAW_VIEW_LIST_PICVIEW);
+	// Draw relative to the bottom center
+	debugC(2, kDebugLevelGraphics, "Returning.\n");
+
+	reparentize_primary_widget_lists(s, s->port);
+}
+
+void SciGUI32::addToPicView(sciResourceId viewId, uint16 loopNo, uint16 cellNo, int16 leftPos, int16 topPos, int16 priority, int16 control) {
+	assert_primary_widget_lists(s);
+
+	GfxWidget *widget;
+
+	topPos++; // magic +1
+
+	widget = gfxw_new_dyn_view(s->gfx_state, Common::Point(leftPos, topPos), 0, viewId, loopNo, cellNo, 0, priority, -1 /* No priority */ , ALIGN_CENTER, ALIGN_BOTTOM, 0);
+
+	if (!widget) {
+		error("Attempt to single-add invalid picview (%d/%d/%d)", viewId, loopNo, cellNo);
+	} else {
+		widget->_ID = -1;
+		if (control >= 0) {
+			Common::Rect abs_zone = nsrect_clip(s, topPos, calculate_nsrect(s, leftPos, topPos, viewId, loopNo, cellNo), priority);
+			draw_rect_to_control_map(abs_zone);
+		}
+		ADD_TO_CURRENT_PICTURE_PORT(gfxw_picviewize_dynview((GfxDynView *) widget));
+	}
+	return;
+}
+
+void SciGUI32::setNowSeen(reg_t objectReference) {
+	_k_set_now_seen(objectReference);
+}
+
+
 void SciGUI32::moveCursor(int16 x, int16 y) {
 	Common::Point newPos;
 

Modified: scummvm/trunk/engines/sci/gui32/gui32.h
===================================================================
--- scummvm/trunk/engines/sci/gui32/gui32.h	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/gui32/gui32.h	2009-10-04 14:59:51 UTC (rev 44606)
@@ -68,6 +68,10 @@
 	void paletteAnimate(int fromColor, int toColor, int speed);
 
 	int16 onControl(byte screenMask, Common::Rect rect);
+	void animate(reg_t castListReference, bool cycle, int argc, reg_t *argv);
+	void addToPicList(reg_t listReference, int argc, reg_t *argv);
+	void addToPicView(sciResourceId viewId, uint16 loopNo, uint16 cellNo, int16 leftPos, int16 topPos, int16 priority, int16 control);
+	void setNowSeen(reg_t objectReference);
 
 	void moveCursor(int16 x, int16 y);
 
@@ -76,6 +80,23 @@
 	EngineState *s;
 	bool _usesOldGfxFunctions;
 
+	GfxDynView *_k_make_dynview_obj(reg_t obj, int options, int nr, int argc, reg_t *argv);
+	void _k_make_view_list(GfxList **widget_list, List *list, int options, int argc, reg_t *argv);
+	void draw_obj_to_control_map(GfxDynView *view);
+	void draw_rect_to_control_map(Common::Rect abs_zone);
+	int _k_view_list_dispose_loop(List *list, GfxDynView *widget, int argc, reg_t *argv);
+	void _k_set_now_seen(reg_t object);
+	void _k_prepare_view_list(GfxList *list, int options);
+	void _k_update_signals_in_view_list(GfxList *old_list, GfxList *new_list);
+	void _k_view_list_kryptonize(GfxWidget *v);
+	void _k_raise_topmost_in_view_list(GfxList *list, GfxDynView *view);
+	void _k_redraw_view_list(GfxList *list);
+	void _k_draw_view_list(GfxList *list, int flags);
+	void _k_view_list_do_postdraw(GfxList *list);
+	void animate_do_animation(int argc, reg_t *argv);
+
+	bool _k_animate_ran;	// FIXME: Avoid non-const global vars
+
 	bool activated_icon_bar;	// FIXME: Avoid non-const global vars
 	int port_origin_x;	// FIXME: Avoid non-const global vars
 	int port_origin_y;	// FIXME: Avoid non-const global vars

Modified: scummvm/trunk/engines/sci/sci.cpp
===================================================================
--- scummvm/trunk/engines/sci/sci.cpp	2009-10-04 13:29:35 UTC (rev 44605)
+++ scummvm/trunk/engines/sci/sci.cpp	2009-10-04 14:59:51 UTC (rev 44606)
@@ -35,6 +35,7 @@
 #include "sci/engine/state.h"
 #include "sci/engine/kernel.h"
 
+#include "sci/gfx/gfx_state_internal.h"	// required for GfxContainer, GfxPort, GfxVisual
 #include "sci/gui32/gui32.h"
 
 #include "sci/gfx/gfx_resource.h"


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