diff options
Diffstat (limited to 'engines/sci/console.cpp')
| -rw-r--r-- | engines/sci/console.cpp | 239 | 
1 files changed, 238 insertions, 1 deletions
| diff --git a/engines/sci/console.cpp b/engines/sci/console.cpp index 685d0fbb91..26ff08d065 100644 --- a/engines/sci/console.cpp +++ b/engines/sci/console.cpp @@ -63,6 +63,7 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {  	DVar_Register("simulated_key",		&g_debug_simulated_key, DVAR_INT, 0);  	DVar_Register("track_mouse_clicks",	&g_debug_track_mouse_clicks, DVAR_BOOL, 0);  	DVar_Register("weak_validations",	&g_debug_weak_validations, DVAR_BOOL, 0); +	DVar_Register("script_abort_flag",	&script_abort_flag, DVAR_INT, 0);  	// General  	DCmd_Register("help",				WRAP_METHOD(Console, cmdHelp)); @@ -115,6 +116,9 @@ Console::Console(SciEngine *vm) : GUI::Debugger() {  	DCmd_Register("dynamic_views",		WRAP_METHOD(Console, cmdDynamicViews));  	DCmd_Register("dropped_views",		WRAP_METHOD(Console, cmdDroppedViews));  	DCmd_Register("status_bar",			WRAP_METHOD(Console, cmdStatusBarColors)); +#ifdef GFXW_DEBUG_WIDGETS +	DCmd_Register("print_widget",		WRAP_METHOD(Console, cmdPrintWidget)); +#endif  	// Segments  	DCmd_Register("segment_table",		WRAP_METHOD(Console, cmdPrintSegmentTable));  	DCmd_Register("segment_info",		WRAP_METHOD(Console, cmdSegmentInfo)); @@ -182,6 +186,14 @@ void Console::postEnter() {  	_vm->_mixer->pauseAll(false);  } + +#if 0 +// Unused +#define LOOKUP_SPECIES(species) (\ +	(species >= 1000) ? species : *(s->_classtable[species].scriptposp) \ +		+ s->_classtable[species].class_offset) +#endif +  bool Console::cmdHelp(int argc, const char **argv) {  	DebugPrintf("\n");  	DebugPrintf("Variables\n"); @@ -191,6 +203,7 @@ bool Console::cmdHelp(int argc, const char **argv) {  	DebugPrintf("simulated_key: Add a key with the specified scan code to the event list\n");  	DebugPrintf("track_mouse_clicks: Toggles mouse click tracking to the console\n");  	DebugPrintf("weak_validations: Turns some validation errors into warnings\n"); +	DebugPrintf("script_abort_flag: Set to 1 to abort script execution. Set to 2 to force a replay afterwards\n");  	DebugPrintf("\n");  	DebugPrintf("Commands\n");  	DebugPrintf("--------\n"); @@ -248,6 +261,9 @@ bool Console::cmdHelp(int argc, const char **argv) {  	DebugPrintf(" dynamic_views - Lists active dynamic views\n");  	DebugPrintf(" dropped_views - Lists dropped dynamic views\n");  	DebugPrintf(" status_bar - Sets the colors of the status bar\n"); +#ifdef GFXW_DEBUG_WIDGETS +	DebugPrintf(" print_widget - Shows active widgets (no params) or information on the specified widget indices\n"); +#endif  	DebugPrintf("\n");  	DebugPrintf("Segments:\n");  	DebugPrintf(" segment_table - Lists all segments\n"); @@ -667,7 +683,7 @@ bool Console::cmdRestoreGame(int argc, const char **argv) {  	if (newstate) {  		g_EngineState->successor = newstate; // Set successor -		script_abort_flag = SCRIPT_ABORT_WITH_REPLAY; // Abort current game +		script_abort_flag = 2; // Abort current game with replay  		g_debugstate_valid = 0;  		shrink_execution_stack(g_EngineState, g_EngineState->execution_stack_base + 1); @@ -2678,4 +2694,225 @@ int printObject(EngineState *s, reg_t pos) {  	return 0;  } +#define GETRECT(ll, rr, tt, bb) \ +	ll = GET_SELECTOR(pos, ll); \ +	rr = GET_SELECTOR(pos, rr); \ +	tt = GET_SELECTOR(pos, tt); \ +	bb = GET_SELECTOR(pos, bb); + +#if 0 +// TODO Re-implement this +static void viewobjinfo(EngineState *s, HeapPtr pos) { +	char *signals[16] = { +		"stop_update", +		"updated", +		"no_update", +		"hidden", +		"fixed_priority", +		"always_update", +		"force_update", +		"remove", +		"frozen", +		"is_extra", +		"hit_obstacle", +		"doesnt_turn", +		"no_cycler", +		"ignore_horizon", +		"ignore_actor", +		"dispose!" +	}; + +	int x, y, z, priority; +	int cel, loop, view, signal; +	int nsLeft, nsRight, nsBottom, nsTop; +	int lsLeft, lsRight, lsBottom, lsTop; +	int brLeft, brRight, brBottom, brTop; +	int i; +	int have_rects = 0; +	Common::Rect nsrect, nsrect_clipped, brrect; + +	if (lookup_selector(s, pos, s->_kernel->_selectorMap.nsBottom, NULL) == kSelectorVariable) { +		GETRECT(nsLeft, nsRight, nsBottom, nsTop); +		GETRECT(lsLeft, lsRight, lsBottom, lsTop); +		GETRECT(brLeft, brRight, brBottom, brTop); +		have_rects = 1; +	} + +	GETRECT(view, loop, signal, cel); + +	sciprintf("\n-- View information:\ncel %d/%d/%d at ", view, loop, cel); + +	x = GET_SELECTOR(pos, x); +	y = GET_SELECTOR(pos, y); +	priority = GET_SELECTOR(pos, priority); +	if (s->_kernel->_selectorMap.z > 0) { +		z = GET_SELECTOR(pos, z); +		sciprintf("(%d,%d,%d)\n", x, y, z); +	} else +		sciprintf("(%d,%d)\n", x, y); + +	if (priority == -1) +		sciprintf("No priority.\n\n"); +	else +		sciprintf("Priority = %d (band starts at %d)\n\n", priority, PRIORITY_BAND_FIRST(priority)); + +	if (have_rects) { +		sciprintf("nsRect: [%d..%d]x[%d..%d]\n", nsLeft, nsRight, nsTop, nsBottom); +		sciprintf("lsRect: [%d..%d]x[%d..%d]\n", lsLeft, lsRight, lsTop, lsBottom); +		sciprintf("brRect: [%d..%d]x[%d..%d]\n", brLeft, brRight, brTop, brBottom); +	} + +	nsrect = get_nsrect(s, pos, 0); +	nsrect_clipped = get_nsrect(s, pos, 1); +	brrect = set_base(s, pos); +	sciprintf("new nsRect: [%d..%d]x[%d..%d]\n", nsrect.x, nsrect.xend, nsrect.y, nsrect.yend); +	sciprintf("new clipped nsRect: [%d..%d]x[%d..%d]\n", nsrect_clipped.x, nsrect_clipped.xend, nsrect_clipped.y, nsrect_clipped.yend); +	sciprintf("new brRect: [%d..%d]x[%d..%d]\n", brrect.x, brrect.xend, brrect.y, brrect.yend); +	sciprintf("\n signals = %04x:\n", signal); + +	for (i = 0; i < 16; i++) +		if (signal & (1 << i)) +			sciprintf("  %04x: %s\n", 1 << i, signals[i]); +} +#endif +#undef GETRECT + +#define GETRECT(ll, rr, tt, bb) \ +	ll = GET_SELECTOR(pos, ll); \ +	rr = GET_SELECTOR(pos, rr); \ +	tt = GET_SELECTOR(pos, tt); \ +	bb = GET_SELECTOR(pos, bb); + +#if 0 +// Draws the nsRect and brRect of a dynview object. nsRect is green, brRect is blue. +// TODO: Re-implement this +static int c_gfx_draw_viewobj(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { +	HeapPtr pos = (HeapPtr)(cmdParams[0].val); +	int is_view; +	int x, y, priority; +	int nsLeft, nsRight, nsBottom, nsTop; +	int brLeft, brRight, brBottom, brTop; + +	if (!s) { +		sciprintf("Not in debug state!\n"); +		return 1; +	} + +	if ((pos < 4) || (pos > 0xfff0)) { +		sciprintf("Invalid address.\n"); +		return 1; +	} + +	if (((int16)READ_LE_UINT16(s->heap + pos + SCRIPT_OBJECT_MAGIC_OFFSET)) != SCRIPT_OBJECT_MAGIC_NUMBER) { +		sciprintf("Not an object.\n"); +		return 0; +	} + + +	is_view = (lookup_selector(s, pos, s->_kernel->_selectorMap.x, NULL) == kSelectorVariable) && +	    (lookup_selector(s, pos, s->_kernel->_selectorMap.brLeft, NULL) == kSelectorVariable) && +	    (lookup_selector(s, pos, s->_kernel->_selectorMap.signal, NULL) == kSelectorVariable) && +	    (lookup_selector(s, pos, s->_kernel->_selectorMap.nsTop, NULL) == kSelectorVariable); + +	if (!is_view) { +		sciprintf("Not a dynamic View object.\n"); +		return 0; +	} + +	x = GET_SELECTOR(pos, x); +	y = GET_SELECTOR(pos, y); +	priority = GET_SELECTOR(pos, priority); +	GETRECT(brLeft, brRight, brBottom, brTop); +	GETRECT(nsLeft, nsRight, nsBottom, nsTop); +	gfxop_set_clip_zone(s->gfx_state, gfx_rect_fullscreen); + +	brTop += 10; +	brBottom += 10; +	nsTop += 10; +	nsBottom += 10; + +	gfxop_fill_box(s->gfx_state, gfx_rect(nsLeft, nsTop, nsRight - nsLeft + 1, nsBottom - nsTop + 1), s->ega_colors[2]); +	gfxop_fill_box(s->gfx_state, gfx_rect(brLeft, brTop, brRight - brLeft + 1, brBottom - brTop + 1), s->ega_colors[1]); +	gfxop_fill_box(s->gfx_state, gfx_rect(x - 1, y - 1, 3, 3), s->ega_colors[0]); +	gfxop_fill_box(s->gfx_state, gfx_rect(x - 1, y, 3, 1), s->ega_colors[priority]); +	gfxop_fill_box(s->gfx_state, gfx_rect(x, y - 1, 1, 3), s->ega_colors[priority]); +	gfxop_update(s->gfx_state); + +	return 0; +} +#endif +#undef GETRECT + +#if 0 +// Executes one operation skipping over sends +// TODO Re-implement this +int c_stepover(EngineState *s, const Common::Array<cmd_param_t> &cmdParams) { +	int opcode, opnumber; + +	if (!g_debugstate_valid) { +		sciprintf("Not in debug state\n"); +		return 1; +	} + +	g_debugstate_valid = 0; +	opcode = s->_heap[*p_pc]; +	opnumber = opcode >> 1; +	if (opnumber == 0x22 /* callb */ || opnumber == 0x23 /* calle */ || +	        opnumber == 0x25 /* send */ || opnumber == 0x2a /* self */ || opnumber == 0x2b /* super */) { +		g_debug_seeking = _DEBUG_SEEK_SO; +		s_debug_seek_level = s->_executionStack.size()-1; +		// Store in s_debug_seek_special the offset of the next command after send +		switch (opcode) { +		case 0x46: // calle W +			s_debug_seek_special = *p_pc + 5; +			break; + +		case 0x44: // callb W +		case 0x47: // calle B +		case 0x56: // super W +			s_debug_seek_special = *p_pc + 4; +			break; + +		case 0x45: // callb B +		case 0x57: // super B +		case 0x4A: // send W +		case 0x54: // self W +			s_debug_seek_special = *p_pc + 3; +			break; + +		default: +			s_debug_seek_special = *p_pc + 2; +		} +	} + +	return 0; +} +#endif + +#ifdef GFXW_DEBUG_WIDGETS +extern GfxWidget *debug_widgets[]; +extern int debug_widget_pos; + +// If called with no parameters, it shows which widgets are active +// With parameters, it lists the widget corresponding to the numerical index specified (for each parameter). +bool Console::cmdPrintWidget(int argc, const char **argv) { +	if (argc > 1) { +		for (int i = 0; i < argc; i++) { +			int widget_nr = atoi(argv[1]); + +			DebugPrintf("===== Widget #%d:\n", widget_nr); +			debug_widgets[widget_nr]->print(0); +		} +	} else if (debug_widget_pos > 1) { +		DebugPrintf("Widgets 0-%d are active\n", debug_widget_pos - 1); +	} else if (debug_widget_pos == 1) { +		DebugPrintf("Widget 0 is active\n"); +	} else { +		DebugPrintf("No widgets are active\n"); +	} + +	return true; +} +#endif +  } // End of namespace Sci | 
