2009-02-17 15:02:16 +00:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
* $ URL $
* $ Id $
*
*/
2009-02-15 06:10:59 +00:00
2009-02-21 15:40:14 +00:00
# include "common/system.h"
2009-05-21 22:03:23 +00:00
# include "common/events.h"
2009-07-03 14:18:20 +00:00
# include "graphics/cursorman.h"
2009-02-21 15:40:14 +00:00
2009-05-13 16:52:41 +00:00
# include "sci/sci.h"
2009-06-04 11:28:05 +00:00
# include "sci/debug.h" // for g_debug_sleeptime_factor
2009-05-15 14:07:45 +00:00
# include "sci/resource.h"
2009-02-27 02:23:40 +00:00
# include "sci/engine/state.h"
2009-03-07 19:23:47 +00:00
# include "sci/engine/kernel.h"
2009-03-25 12:52:03 +00:00
# include "sci/gfx/gfx_gui.h"
2009-02-21 19:33:01 +00:00
# include "sci/gfx/gfx_widgets.h"
2009-04-24 10:46:20 +00:00
# include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual
2009-05-21 22:03:23 +00:00
# include "sci/gfx/seq_decoder.h"
2009-02-15 06:10:59 +00:00
2009-02-21 10:23:36 +00:00
namespace Sci {
2009-02-15 06:10:59 +00:00
# undef DEBUG_LSRECT
2009-02-26 02:21:55 +00:00
// This is the real width of a text with a specified width of 0
# define MAX_TEXT_WIDTH_MAGIC_VALUE 192
2009-02-19 20:50:55 +00:00
// Graph subfunctions
2009-04-24 10:43:42 +00:00
enum {
K_GRAPH_GET_COLORS_NR = 2 ,
K_GRAPH_DRAW_LINE = 4 ,
K_GRAPH_SAVE_BOX = 7 ,
K_GRAPH_RESTORE_BOX = 8 ,
K_GRAPH_FILL_BOX_BACKGROUND = 9 ,
K_GRAPH_FILL_BOX_FOREGROUND = 10 ,
K_GRAPH_FILL_BOX_ANY = 11 ,
K_GRAPH_UPDATE_BOX = 12 ,
K_GRAPH_REDRAW_BOX = 13 ,
K_GRAPH_ADJUST_PRIORITY = 14
} ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
// Control types and flags
2009-04-24 10:43:42 +00:00
enum {
K_CONTROL_BUTTON = 1 ,
K_CONTROL_TEXT = 2 ,
K_CONTROL_EDIT = 3 ,
K_CONTROL_ICON = 4 ,
K_CONTROL_CONTROL = 6 ,
K_CONTROL_CONTROL_ALIAS = 7 ,
K_CONTROL_BOX = 10
} ;
2009-02-15 06:10:59 +00:00
# define ADD_TO_CURRENT_PORT(widget) \
2009-02-22 13:11:43 +00:00
{ if ( s - > port ) \
2009-05-30 14:30:39 +00:00
s - > port - > add ( ( GfxContainer * ) s - > port , widget ) ; \
2009-02-22 13:11:43 +00:00
else \
2009-05-30 14:30:39 +00:00
s - > picture_port - > add ( ( GfxContainer * ) s - > visual , widget ) ; }
2009-02-15 06:10:59 +00:00
# define ADD_TO_CURRENT_PICTURE_PORT(widget) \
2009-02-22 13:11:43 +00:00
{ if ( s - > port ) \
2009-05-30 14:30:39 +00:00
s - > port - > add ( ( GfxContainer * ) s - > port , widget ) ; \
2009-02-22 13:11:43 +00:00
else \
2009-05-30 14:30:39 +00:00
s - > picture_port - > add ( ( GfxContainer * ) s - > picture_port , widget ) ; }
2009-02-15 06:10:59 +00:00
# define ADD_TO_WINDOW_PORT(widget) \
2009-05-30 14:30:39 +00:00
s - > wm_port - > add ( ( GfxContainer * ) s - > wm_port , widget ) ;
2009-02-15 06:10:59 +00:00
# define FULL_REDRAW()\
2009-02-22 13:11:43 +00:00
if ( s - > visual ) \
2009-04-24 14:22:14 +00:00
s - > visual - > draw ( gfxw_point_zero ) ; \
2009-02-22 13:11:43 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-15 06:10:59 +00:00
2009-04-21 21:37:03 +00:00
#if 0
// Used for debugging
2009-02-15 06:10:59 +00:00
# define FULL_INSPECTION()\
2009-02-22 13:11:43 +00:00
if ( s - > visual ) \
2009-04-24 10:48:25 +00:00
s - > visual - > print ( s - > visual , 0 ) ;
2009-04-21 21:37:03 +00:00
# endif
2009-02-15 06:10:59 +00:00
# define GFX_ASSERT(x) { \
int val = ! ! ( x ) ; \
if ( val ) { \
if ( val = = GFX_ERROR ) \
2009-02-20 20:11:12 +00:00
warning ( " GFX subsystem returned error on \" " # x " \" " ) ; \
2009-02-15 06:10:59 +00:00
else { \
2009-05-31 10:02:16 +00:00
error ( " GFX subsystem fatal error condition on \" " # x " \" " ) ; \
2009-02-15 06:10:59 +00:00
vm_handle_fatal_error ( s , __LINE__ , __FILE__ ) ; \
2009-02-19 20:50:55 +00:00
} \
} \
2009-02-15 06:10:59 +00:00
}
# define ASSERT(x) { \
2009-02-19 20:50:55 +00:00
int val = ! ! ( x ) ; \
if ( ! val ) { \
2009-05-31 10:02:16 +00:00
error ( " Fatal error condition on \" " # x " \" " ) ; \
2009-02-19 20:50:55 +00:00
BREAKPOINT ( ) ; \
vm_handle_fatal_error ( s , __LINE__ , __FILE__ ) ; \
} \
2009-02-15 06:10:59 +00:00
}
2009-02-19 20:50:55 +00:00
static inline int sign_extend_byte ( int value ) {
2009-02-15 06:10:59 +00:00
if ( value & 0x80 )
return value - 256 ;
else
return value ;
}
2009-02-21 10:47:56 +00:00
static void assert_primary_widget_lists ( EngineState * s ) {
2009-02-15 06:10:59 +00:00
if ( ! s - > dyn_views ) {
2009-04-24 10:45:09 +00:00
rect_t bounds = s - > picture_port - > _bounds ;
2009-02-15 06:10:59 +00:00
s - > dyn_views = gfxw_new_list ( bounds , GFXW_LIST_SORTED ) ;
2009-04-24 10:45:09 +00:00
s - > dyn_views - > _flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
2009-02-15 06:10:59 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( s - > dyn_views ) ;
}
if ( ! s - > drop_views ) {
2009-04-24 10:45:09 +00:00
rect_t bounds = s - > picture_port - > _bounds ;
2009-02-15 06:10:59 +00:00
s - > drop_views = gfxw_new_list ( bounds , GFXW_LIST_SORTED ) ;
2009-04-24 10:45:09 +00:00
s - > drop_views - > _flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
2009-02-15 06:10:59 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( s - > drop_views ) ;
}
}
2009-04-24 10:46:20 +00:00
static void reparentize_primary_widget_lists ( EngineState * s , GfxPort * newport ) {
2009-02-15 06:10:59 +00:00
if ( ! newport )
newport = s - > picture_port ;
if ( s - > dyn_views ) {
2009-04-24 10:48:25 +00:00
gfxw_remove_widget_from_container ( s - > dyn_views - > _parent , s - > dyn_views ) ;
2009-02-15 06:10:59 +00:00
2009-05-30 14:30:39 +00:00
newport - > add ( ( GfxContainer * ) newport , s - > dyn_views ) ;
2009-02-15 06:10:59 +00:00
}
}
2009-02-21 10:47:56 +00:00
int _find_view_priority ( EngineState * s , int y ) {
2009-02-19 20:50:55 +00:00
/*if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1)
+ + y ; */
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
if ( s - > pic_priority_table ) { // SCI01 priority table set?
2009-02-15 06:10:59 +00:00
int j ;
for ( j = 0 ; j < 15 ; j + + )
if ( y < s - > pic_priority_table [ j + 1 ] )
return j ;
2009-02-19 20:50:55 +00:00
return 14 ; // Maximum
2009-02-15 22:28:12 +00:00
} else {
2009-07-11 23:45:54 +00:00
if ( ! ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > usesOldGfxFunctions ( ) )
2009-02-15 06:10:59 +00:00
return SCI0_VIEW_PRIORITY_14_ZONES ( y ) ;
else
2009-02-19 20:50:55 +00:00
return SCI0_VIEW_PRIORITY ( y ) = = 15 ? 14 : SCI0_VIEW_PRIORITY ( y ) ;
2009-02-15 06:10:59 +00:00
}
}
2009-02-21 10:47:56 +00:00
int _find_priority_band ( EngineState * s , int nr ) {
2009-07-11 23:45:54 +00:00
if ( ! ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > usesOldGfxFunctions ( ) & & ( nr < 0 | | nr > 14 ) ) {
2009-02-15 06:10:59 +00:00
if ( nr = = 15 )
return 0xffff ;
else {
2009-02-20 20:11:12 +00:00
warning ( " Attempt to get priority band %d " , nr ) ;
2009-02-15 06:10:59 +00:00
}
return 0 ;
}
2009-07-11 23:45:54 +00:00
if ( ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > usesOldGfxFunctions ( ) & & ( nr < 0 | | nr > 15 ) ) {
2009-02-20 20:11:12 +00:00
warning ( " Attempt to get priority band %d " , nr ) ;
2009-02-15 06:10:59 +00:00
return 0 ;
}
2009-02-19 20:50:55 +00:00
if ( s - > pic_priority_table ) // SCI01 priority table set?
2009-02-15 06:10:59 +00:00
return s - > pic_priority_table [ nr ] ;
else {
int retval ;
2009-07-11 23:45:54 +00:00
if ( ! ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > usesOldGfxFunctions ( ) )
2009-02-15 06:10:59 +00:00
retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES ( nr ) ;
else
retval = SCI0_PRIORITY_BAND_FIRST ( nr ) ;
2009-02-19 20:50:55 +00:00
/* if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1)
- - retval ; */
2009-02-15 06:10:59 +00:00
return retval ;
}
}
2009-02-21 10:47:56 +00:00
reg_t graph_save_box ( EngineState * s , rect_t area ) {
2009-02-15 06:10:59 +00:00
reg_t handle = kalloc ( s , " graph_save_box() " , sizeof ( gfxw_snapshot_t * ) ) ;
2009-05-18 12:34:25 +00:00
gfxw_snapshot_t * * ptr = ( gfxw_snapshot_t * * ) kmem ( s , handle ) ;
2009-02-15 06:10:59 +00:00
2009-05-18 12:34:25 +00:00
// FIXME: gfxw_make_snapshot returns a pointer. Now why do we store a
// pointer to real memory inside the SCI heap?
// If we save and the load again, this cannot work in general.
// This seems like bad design. Either the snapshot data itself should be
// stored in the heap, or a unique persistent id.
2009-02-15 06:10:59 +00:00
* ptr = gfxw_make_snapshot ( s - > visual , area ) ;
return handle ;
}
2009-02-21 10:47:56 +00:00
void graph_restore_box ( EngineState * s , reg_t handle ) {
2009-02-15 06:10:59 +00:00
gfxw_snapshot_t * * ptr ;
2009-04-24 10:45:09 +00:00
int port_nr = s - > port - > _ID ;
2009-02-15 06:10:59 +00:00
if ( ! handle . segment ) {
2009-02-20 20:11:12 +00:00
warning ( " Attempt to restore box with zero handle " ) ;
2009-02-15 06:10:59 +00:00
return ;
}
2009-02-21 03:25:23 +00:00
ptr = ( gfxw_snapshot_t * * ) kmem ( s , handle ) ;
2009-02-15 06:10:59 +00:00
if ( ! ptr ) {
2009-05-21 17:18:46 +00:00
warning ( " Attempt to restore invalid handle %04x:%04x " , PRINT_REG ( handle ) ) ;
2009-02-15 06:10:59 +00:00
return ;
}
2009-04-24 10:48:25 +00:00
while ( port_nr > 2 & & ! ( s - > port - > _flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ) & & ( gfxw_widget_matches_snapshot ( * ptr , s - > port ) ) ) {
2009-02-19 20:50:55 +00:00
// This shouldn't ever happen, actually, since windows (ports w/ ID > 2) should all be immune
2009-06-02 14:16:59 +00:00
GfxPort * newport = s - > visual - > getPort ( port_nr ) ;
2009-05-18 11:53:04 +00:00
error ( " Port %d is not immune against snapshots " , s - > port - > _ID ) ;
2009-02-15 06:10:59 +00:00
port_nr - - ;
if ( newport )
s - > port = newport ;
}
2009-04-24 10:48:25 +00:00
if ( s - > dyn_views & & gfxw_widget_matches_snapshot ( * ptr , s - > dyn_views - > _parent ) ) {
2009-04-24 10:46:20 +00:00
GfxContainer * parent = s - > dyn_views - > _parent ;
2009-02-15 06:10:59 +00:00
do {
2009-04-24 10:45:09 +00:00
parent = parent - > _parent ;
2009-04-24 10:48:25 +00:00
} while ( parent & & ( gfxw_widget_matches_snapshot ( * ptr , parent ) ) ) ;
2009-02-15 06:10:59 +00:00
if ( ! parent ) {
2009-05-18 11:53:04 +00:00
error ( " Attempted widget mass destruction by a snapshot " ) ;
2009-02-15 06:10:59 +00:00
}
2009-04-24 10:46:20 +00:00
reparentize_primary_widget_lists ( s , ( GfxPort * ) parent ) ;
2009-02-15 06:10:59 +00:00
}
if ( ! ptr ) {
2009-05-21 17:18:46 +00:00
error ( " Attempt to restore invalid snaphot with handle %04x:%04x " , PRINT_REG ( handle ) ) ;
2009-02-15 06:10:59 +00:00
return ;
}
gfxw_restore_snapshot ( s - > visual , * ptr ) ;
free ( * ptr ) ;
* ptr = NULL ;
kfree ( s , handle ) ;
}
2009-03-08 20:17:01 +00:00
PaletteEntry get_pic_color ( EngineState * s , int color ) {
2009-07-07 07:44:25 +00:00
if ( ! s - > resmgr - > isVGA ( ) )
2009-03-08 20:17:01 +00:00
return s - > ega_colors [ color ] . visual ;
2009-02-15 06:10:59 +00:00
2009-03-29 01:56:03 +00:00
if ( color = = - 1 | | color = = 255 ) // -1 occurs in Eco Quest 1. Not sure if this is the best approach, but it seems to work
2009-03-08 20:17:01 +00:00
return PaletteEntry ( 255 , 255 , 255 ) ;
2009-03-23 08:43:53 +00:00
else if ( color < s - > gfx_state - > gfxResMan - > getColorCount ( ) )
return s - > gfx_state - > gfxResMan - > getColor ( color ) ;
2009-02-15 22:28:12 +00:00
else {
2009-05-27 17:13:42 +00:00
// Happens in the beginning of EcoQuest 2, when the dialog box of the customs officer shows up
warning ( " Color index %d out of bounds for pic %d (%d max) " , color , s - > gfx_state - > pic_nr , s - > gfx_state - > gfxResMan - > getColorCount ( ) ) ;
2009-05-20 17:53:31 +00:00
return PaletteEntry ( 0 , 0 , 0 ) ;
2009-02-15 22:28:12 +00:00
}
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
static gfx_color_t graph_map_color ( EngineState * s , int color , int priority , int control ) {
2009-02-15 06:10:59 +00:00
gfx_color_t retval ;
2009-07-07 07:44:25 +00:00
if ( ! s - > resmgr - > isVGA ( ) ) {
2009-02-15 06:10:59 +00:00
retval = s - > ega_colors [ ( color > = 0 & & color < 16 ) ? color : 0 ] ;
2009-02-15 22:28:12 +00:00
gfxop_set_color ( s - > gfx_state , & retval , ( color < 0 ) ? - 1 : retval . visual . r , retval . visual . g , retval . visual . b ,
( color = = - 1 ) ? 255 : 0 , priority , control ) ;
} else {
2009-03-08 20:17:01 +00:00
retval . visual = get_pic_color ( s , color ) ;
2009-02-15 06:10:59 +00:00
retval . alpha = 0 ;
retval . priority = priority ;
retval . control = control ;
2009-02-19 20:50:55 +00:00
retval . mask = GFX_MASK_VISUAL | ( ( priority > = 0 ) ? GFX_MASK_PRIORITY : 0 ) | ( ( control > = 0 ) ? GFX_MASK_CONTROL : 0 ) ;
2009-02-15 06:10:59 +00:00
} ;
return retval ;
}
2009-04-24 16:47:56 +00:00
reg_t kSetCursor ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 22:28:12 +00:00
switch ( argc ) {
2009-05-29 09:42:11 +00:00
case 1 :
2009-07-04 16:30:20 +00:00
if ( s - > _version < SCI_VERSION_1 ) {
GFX_ASSERT ( gfxop_set_pointer_cursor ( s - > gfx_state , argv [ 0 ] . toSint16 ( ) ) ) ;
} else if ( s - > _version = = SCI_VERSION_1 ) {
2009-06-07 15:53:30 +00:00
if ( argv [ 0 ] . toSint16 ( ) < = 1 ) {
2009-05-29 10:14:58 +00:00
// Newer (SCI1.1) semantics: show/hide cursor
2009-07-03 14:18:20 +00:00
CursorMan . showMouse ( argv [ 0 ] . toSint16 ( ) ! = 0 ) ;
2009-05-29 10:14:58 +00:00
} else {
// Pre-SCI1.1: set cursor according to the first parameter
2009-06-07 15:53:30 +00:00
GFX_ASSERT ( gfxop_set_pointer_cursor ( s - > gfx_state , argv [ 0 ] . toSint16 ( ) ) ) ;
2009-05-29 10:14:58 +00:00
}
2009-07-04 16:30:20 +00:00
} else if ( s - > _version > = SCI_VERSION_1_1 ) {
2009-05-29 10:14:58 +00:00
// SCI1.1: Show/hide cursor
2009-07-03 14:18:20 +00:00
CursorMan . showMouse ( argv [ 0 ] . toSint16 ( ) ! = 0 ) ;
2009-05-29 09:42:11 +00:00
}
2009-05-29 08:25:42 +00:00
break ;
case 2 :
2009-07-04 16:30:20 +00:00
if ( s - > _version < SCI_VERSION_1 ) {
GFX_ASSERT ( gfxop_set_pointer_cursor ( s - > gfx_state ,
argv [ 1 ] . toSint16 ( ) = = 0 ? GFXOP_NO_POINTER : argv [ 0 ] . toSint16 ( ) ) ) ;
} else if ( s - > _version = = SCI_VERSION_1 ) {
2009-05-29 08:25:42 +00:00
// Pre-SCI1.1: set cursor according to the first parameter, and toggle its
// visibility based on the second parameter
// Some late SCI1 games actually use the SCI1.1 version of this call (EcoQuest 1
// and KQ5 CD, but I haven't seen this case happen), but we can determine the
// semantics from the second parameter passed.
// Rationale: with the older behavior, the second parameter can either be 0
// (hide cursor) or 1/-1 (show cursor). This could be problematic if the engine
// tries to place the cursor at (x, 0) or (x, 1), but no SCI1 game does that, as
// this would open the menu on top. LSL5 is an exception, as the game can open
// the menu when the player presses a button during the intro, but the cursor is
// not placed on (x, 0) or (x, 1)
2009-06-07 15:53:30 +00:00
if ( argv [ 1 ] . toSint16 ( ) < = 1 ) {
2009-05-29 08:25:42 +00:00
GFX_ASSERT ( gfxop_set_pointer_cursor ( s - > gfx_state ,
2009-06-07 15:53:30 +00:00
argv [ 1 ] . toSint16 ( ) = = 0 ? GFXOP_NO_POINTER : argv [ 0 ] . toSint16 ( ) ) ) ;
2009-05-29 08:25:42 +00:00
} else { // newer (SCI1.1) semantics: set pointer position
GFX_ASSERT ( gfxop_set_pointer_position ( s - > gfx_state ,
2009-06-07 15:53:30 +00:00
Common : : Point ( argv [ 0 ] . toUint16 ( ) , argv [ 1 ] . toUint16 ( ) ) ) ) ;
2009-05-29 08:25:42 +00:00
}
2009-07-04 16:30:20 +00:00
} else if ( s - > _version > = SCI_VERSION_1_1 ) {
2009-05-29 08:25:42 +00:00
// SCI1.1 and newer: set pointer position
GFX_ASSERT ( gfxop_set_pointer_position ( s - > gfx_state ,
2009-06-07 15:53:30 +00:00
Common : : Point ( argv [ 0 ] . toUint16 ( ) , argv [ 1 ] . toUint16 ( ) ) ) ) ;
2009-02-15 06:10:59 +00:00
}
2009-05-29 08:25:42 +00:00
break ;
2009-04-24 16:47:56 +00:00
case 4 :
2009-05-29 08:25:42 +00:00
GFX_ASSERT ( gfxop_set_pointer_cursor ( s - > gfx_state ,
2009-06-07 15:53:30 +00:00
argv [ 0 ] . toUint16 ( ) = = 0 ? GFXOP_NO_POINTER : argv [ 0 ] . toSint16 ( ) ) ) ;
2009-04-24 16:47:56 +00:00
2009-05-29 08:25:42 +00:00
// Set pointer position, if requested
if ( argc > 2 ) {
2009-06-07 15:53:30 +00:00
Common : : Point newPos = Common : : Point ( argv [ 2 ] . toSint16 ( ) + s - > port - > _bounds . x , argv [ 3 ] . toSint16 ( ) + s - > port - > _bounds . y ) ;
2009-06-06 16:43:13 +00:00
GFX_ASSERT ( gfxop_set_pointer_position ( s - > gfx_state , newPos ) ) ;
2009-04-24 16:47:56 +00:00
}
2009-02-15 06:10:59 +00:00
break ;
2009-05-29 08:25:42 +00:00
case 3 :
case 5 :
case 9 :
if ( argc > 3 ) {
2009-06-07 15:53:30 +00:00
Common : : Point hotspot = Common : : Point ( argv [ 3 ] . toSint16 ( ) , argv [ 4 ] . toSint16 ( ) ) ;
GFX_ASSERT ( gfxop_set_pointer_view ( s - > gfx_state , argv [ 0 ] . toUint16 ( ) , argv [ 1 ] . toUint16 ( ) , argv [ 2 ] . toUint16 ( ) , & hotspot ) ) ;
2009-05-29 08:25:42 +00:00
} else {
2009-06-07 15:53:30 +00:00
GFX_ASSERT ( gfxop_set_pointer_view ( s - > gfx_state , argv [ 0 ] . toUint16 ( ) , argv [ 1 ] . toUint16 ( ) , argv [ 2 ] . toUint16 ( ) , NULL ) ) ;
2009-05-29 08:25:42 +00:00
}
2009-02-15 06:10:59 +00:00
break ;
default :
2009-05-18 11:53:04 +00:00
error ( " kSetCursor: Unhandled case: %d arguments given " , argc ) ;
2009-02-15 06:10:59 +00:00
break ;
}
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kMoveCursor ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-06 16:43:13 +00:00
Common : : Point newPos ;
2009-02-15 06:10:59 +00:00
2009-06-06 16:43:13 +00:00
newPos = s - > gfx_state - > pointer_pos ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
if ( argc = = 1 ) {
2009-02-19 20:50:55 +00:00
// Case ignored on IBM PC
2009-02-15 22:28:12 +00:00
} else {
2009-06-07 15:53:30 +00:00
newPos . x = argv [ 0 ] . toSint16 ( ) + s - > port - > zone . x ;
newPos . y = argv [ 1 ] . toSint16 ( ) + s - > port - > zone . y ;
2009-02-15 06:10:59 +00:00
2009-06-06 16:43:13 +00:00
if ( newPos . x > s - > port - > zone . x + s - > port - > zone . width )
newPos . x = s - > port - > zone . x + s - > port - > zone . width ;
if ( newPos . y > s - > port - > zone . y + s - > port - > zone . height )
newPos . y = s - > port - > zone . y + s - > port - > zone . height ;
2009-02-15 06:10:59 +00:00
2009-06-06 16:43:13 +00:00
if ( newPos . x < 0 ) newPos . x = 0 ;
if ( newPos . y < 0 ) newPos . y = 0 ;
2009-02-15 06:10:59 +00:00
}
2009-06-06 16:43:13 +00:00
GFX_ASSERT ( gfxop_set_pointer_position ( s - > gfx_state , newPos ) ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kShow ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int old_map = s - > pic_visible_map ;
2009-06-07 16:50:34 +00:00
s - > pic_visible_map = ( argc > 0 ) ? ( gfx_map_mask_t ) argv [ 0 ] . toUint16 ( ) : GFX_MASK_VISUAL ;
2009-02-15 06:10:59 +00:00
switch ( s - > pic_visible_map ) {
case GFX_MASK_VISUAL :
case GFX_MASK_PRIORITY :
case GFX_MASK_CONTROL :
gfxop_set_visible_map ( s - > gfx_state , s - > pic_visible_map ) ;
if ( old_map ! = s - > pic_visible_map ) {
2009-02-19 20:50:55 +00:00
if ( s - > pic_visible_map = = GFX_MASK_VISUAL ) // Full widget redraw
2009-04-24 14:22:14 +00:00
s - > visual - > draw ( Common : : Point ( 0 , 0 ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-07-06 10:39:22 +00:00
debugC ( 2 , kDebugLevelGraphics , " Switching visible map to %x \n " , s - > pic_visible_map ) ;
2009-02-15 06:10:59 +00:00
}
break ;
default :
2009-02-20 20:11:12 +00:00
warning ( " Show(%x) selects unknown map " , s - > pic_visible_map ) ;
2009-02-15 06:10:59 +00:00
}
s - > pic_not_valid = 2 ;
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kPicNotValid ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
s - > r_acc = make_reg ( 0 , s - > pic_not_valid ) ;
if ( argc )
2009-06-07 15:53:30 +00:00
s - > pic_not_valid = ( byte ) argv [ 0 ] . toUint16 ( ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
void _k_redraw_box ( EngineState * s , int x1 , int y1 , int x2 , int y2 ) {
2009-07-06 10:39:22 +00:00
warning ( " _k_redraw_box(): Unimplemented " ) ;
2009-02-15 06:10:59 +00:00
#if 0
int i ;
2009-02-28 11:12:59 +00:00
ViewObject * list = s - > dyn_views ;
2009-02-15 06:10:59 +00:00
2009-07-06 10:39:22 +00:00
printf ( " Reanimating views \n " , s - > dyn_views_nr ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
for ( i = 0 ; i < s - > dyn_views_nr ; i + + ) {
2009-02-19 20:50:55 +00:00
* ( list [ i ] . underBitsp ) = graph_save_box ( s , list [ i ] . nsLeft , list [ i ] . nsTop , list [ i ] . nsRight - list [ i ] . nsLeft ,
list [ i ] . nsBottom - list [ i ] . nsTop , SCI_MAP_VISUAL | SCI_MAP_PRIORITY ) ;
draw_view0 ( s - > pic , s - > ports [ 0 ] , list [ i ] . nsLeft , list [ i ] . nsTop , list [ i ] . priority , list [ i ] . loop ,
2009-02-15 22:28:12 +00:00
list [ i ] . cel , 0 , list [ i ] . view ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-15 22:28:12 +00:00
graph_update_box ( s , x1 , y1 , x2 - x1 , y2 - y1 ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
for ( i = 0 ; i < s - > dyn_views_nr ; i + + ) {
2009-02-15 06:10:59 +00:00
graph_restore_box ( s , * ( list [ i ] . underBitsp ) ) ;
2009-02-15 22:28:12 +00:00
list [ i ] . underBits = 0 ;
2009-02-15 06:10:59 +00:00
}
# endif
}
2009-02-21 10:47:56 +00:00
void _k_graph_rebuild_port_with_color ( EngineState * s , gfx_color_t newbgcolor ) {
2009-04-24 10:46:20 +00:00
GfxPort * port = s - > port ;
GfxPort * newport ;
2009-02-15 22:28:12 +00:00
2009-04-24 10:47:38 +00:00
newport = sciw_new_window ( s , port - > zone , port - > _font , port - > _color , newbgcolor ,
s - > titlebar_port - > _font , s - > ega_colors [ 15 ] , s - > ega_colors [ 8 ] ,
2009-03-25 12:07:10 +00:00
port - > title_text , port - > port_flags & ~ kWindowTransparent ) ;
2009-02-15 06:10:59 +00:00
if ( s - > dyn_views ) {
int found = 0 ;
2009-04-24 10:46:20 +00:00
GfxContainer * parent = s - > dyn_views - > _parent ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:48:25 +00:00
while ( parent & & ! ( found | = ( parent = = port ) ) )
2009-04-24 10:45:09 +00:00
parent = parent - > _parent ;
2009-02-15 06:10:59 +00:00
s - > dyn_views = NULL ;
}
2009-05-30 14:30:39 +00:00
port - > _parent - > add ( ( GfxContainer * ) port - > _parent , newport ) ;
2009-04-24 10:48:25 +00:00
delete port ;
2009-02-15 06:10:59 +00:00
}
2009-05-31 01:11:06 +00:00
static bool activated_icon_bar = false ; // FIXME: Avoid non-const global vars
static int port_origin_x = 0 ; // FIXME: Avoid non-const global vars
static int port_origin_y = 0 ; // FIXME: Avoid non-const global vars
2009-02-15 06:10:59 +00:00
2009-02-21 10:47:56 +00:00
reg_t kGraph ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
rect_t area ;
2009-04-24 10:46:20 +00:00
GfxPort * port = s - > port ;
2009-02-15 06:10:59 +00:00
int redraw_port = 0 ;
2009-06-07 15:53:30 +00:00
area = gfx_rect ( argv [ 2 ] . toSint16 ( ) , argv [ 1 ] . toSint16 ( ) , argv [ 4 ] . toSint16 ( ) , argv [ 3 ] . toSint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
2009-03-16 00:07:12 +00:00
area . width = area . width - area . x ; // Since the actual coordinates are absolute
area . height = area . height - area . y ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
switch ( argv [ 0 ] . toSint16 ( ) ) {
2009-02-15 06:10:59 +00:00
case K_GRAPH_GET_COLORS_NR :
2009-07-07 07:44:25 +00:00
return make_reg ( 0 , ! s - > resmgr - > isVGA ( ) ? 0x10 : 0x100 ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_GRAPH_DRAW_LINE : {
2009-06-07 16:50:34 +00:00
int16 priority = ( argc > 6 ) ? argv [ 6 ] . toSint16 ( ) : - 1 ;
int16 control = ( argc > 7 ) ? argv [ 7 ] . toSint16 ( ) : - 1 ;
gfx_color_t gfxcolor = graph_map_color ( s , argv [ 5 ] . toSint16 ( ) , priority , control ) ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " draw_line((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d) \n " ,
2009-06-07 16:50:34 +00:00
argv [ 2 ] . toSint16 ( ) , argv [ 1 ] . toSint16 ( ) , argv [ 4 ] . toSint16 ( ) , argv [ 3 ] . toSint16 ( ) , argv [ 5 ] . toSint16 ( ) , priority , control , gfxcolor . mask ) ;
2009-02-15 06:10:59 +00:00
redraw_port = 1 ;
2009-03-26 21:52:04 +00:00
// Note: it's quite possible that the coordinates of the line will *not* form a valid rectangle (e.g. it might
// have negative width/height). The actual dirty rectangle is constructed in gfxdr_add_dirty().
// FIXME/TODO: We need to change the semantics of this call, so that no fake rectangles are used. As it is, it's
// not possible change rect_t to Common::Rect, as we assume that Common::Rect forms a *valid* rectangle.
2009-06-07 15:53:30 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( gfxw_new_line ( Common : : Point ( argv [ 2 ] . toSint16 ( ) , argv [ 1 ] . toSint16 ( ) ) , Common : : Point ( argv [ 4 ] . toSint16 ( ) , argv [ 3 ] . toSint16 ( ) ) ,
2009-04-24 10:48:25 +00:00
gfxcolor , GFX_LINE_MODE_CORRECT , GFX_LINE_STYLE_NORMAL ) ) ;
2009-02-15 06:10:59 +00:00
}
break ;
case K_GRAPH_SAVE_BOX :
area . x + = s - > port - > zone . x + port_origin_x ;
area . y + = s - > port - > zone . y + port_origin_y ;
2009-03-16 00:07:12 +00:00
area . width + = - port_origin_x ;
area . height + = - port_origin_y ;
2009-02-15 06:10:59 +00:00
return ( graph_save_box ( s , area ) ) ;
break ;
case K_GRAPH_RESTORE_BOX :
graph_restore_box ( s , argv [ 1 ] ) ;
break ;
case K_GRAPH_FILL_BOX_BACKGROUND :
2009-04-24 10:45:09 +00:00
_k_graph_rebuild_port_with_color ( s , port - > _bgcolor ) ;
2009-02-15 06:10:59 +00:00
port = s - > port ;
redraw_port = 1 ;
break ;
case K_GRAPH_FILL_BOX_FOREGROUND :
2009-04-24 10:45:09 +00:00
_k_graph_rebuild_port_with_color ( s , port - > _color ) ;
2009-02-15 06:10:59 +00:00
port = s - > port ;
redraw_port = 1 ;
break ;
case K_GRAPH_FILL_BOX_ANY : {
2009-06-07 16:50:34 +00:00
int16 priority = ( argc > 7 ) ? argv [ 7 ] . toSint16 ( ) : - 1 ;
int16 control = ( argc > 8 ) ? argv [ 8 ] . toSint16 ( ) : - 1 ;
gfx_color_t color = graph_map_color ( s , argv [ 6 ] . toSint16 ( ) , priority , control ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
color . mask = ( byte ) argv [ 5 ] . toUint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " fill_box_any((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d) \n " ,
2009-06-07 16:50:34 +00:00
argv [ 2 ] . toSint16 ( ) , argv [ 1 ] . toSint16 ( ) , argv [ 4 ] . toSint16 ( ) , argv [ 3 ] . toSint16 ( ) , argv [ 6 ] . toSint16 ( ) , priority , control , argv [ 5 ] . toUint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
2009-04-21 21:37:03 +00:00
// FIXME/TODO: this is not right, as some of the dialogs are drawn *behind* some widgets. But at least it works for now
//ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT)); // old code
2009-05-30 14:30:39 +00:00
s - > picture_port - > add ( ( GfxContainer * ) s - > picture_port , gfxw_new_box ( s - > gfx_state , area , color , color , GFX_BOX_SHADE_FLAT ) ) ;
2009-02-15 06:10:59 +00:00
}
break ;
case K_GRAPH_UPDATE_BOX : {
2009-06-07 15:53:30 +00:00
debugC ( 2 , kDebugLevelGraphics , " update_box(%d, %d, %d, %d) \n " , argv [ 1 ] . toSint16 ( ) , argv [ 2 ] . toSint16 ( ) , argv [ 3 ] . toSint16 ( ) , argv [ 4 ] . toSint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
area . x + = s - > port - > zone . x ;
area . y + = s - > port - > zone . y ;
gfxop_update_box ( s - > gfx_state , area ) ;
}
break ;
case K_GRAPH_REDRAW_BOX : {
2009-06-07 15:53:30 +00:00
debugC ( 2 , kDebugLevelGraphics , " redraw_box(%d, %d, %d, %d) \n " , argv [ 1 ] . toSint16 ( ) , argv [ 2 ] . toSint16 ( ) , argv [ 3 ] . toSint16 ( ) , argv [ 4 ] . toSint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
area . x + = s - > port - > zone . x ;
area . y + = s - > port - > zone . y ;
2009-05-30 14:30:39 +00:00
if ( s - > dyn_views & & s - > dyn_views - > _parent = = ( GfxContainer * ) s - > port )
2009-04-24 14:22:14 +00:00
s - > dyn_views - > draw ( Common : : Point ( 0 , 0 ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update_box ( s - > gfx_state , area ) ;
}
break ;
case K_GRAPH_ADJUST_PRIORITY :
2009-06-07 15:53:30 +00:00
debugC ( 2 , kDebugLevelGraphics , " adjust_priority(%d, %d) \n " , argv [ 1 ] . toSint16 ( ) , argv [ 2 ] . toSint16 ( ) ) ;
s - > priority_first = argv [ 1 ] . toSint16 ( ) - 10 ;
s - > priority_last = argv [ 2 ] . toSint16 ( ) - 10 ;
2009-02-15 06:10:59 +00:00
break ;
default :
2009-06-07 15:53:30 +00:00
warning ( " Unhandled Graph() operation %04x " , argv [ 0 ] . toSint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
}
if ( redraw_port )
FULL_REDRAW ( ) ;
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kTextSize ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int width , height ;
char * text = argv [ 1 ] . segment ? ( char * ) kernel_dereference_bulk_pointer ( s , argv [ 1 ] , 0 ) : NULL ;
2009-06-24 19:12:45 +00:00
const char * sep = NULL ;
2009-02-15 06:10:59 +00:00
reg_t * dest = kernel_dereference_reg_pointer ( s , argv [ 0 ] , 4 ) ;
2009-06-07 16:50:34 +00:00
int maxwidth = ( argc > 3 ) ? argv [ 3 ] . toUint16 ( ) : 0 ;
2009-06-07 15:53:30 +00:00
int font_nr = argv [ 2 ] . toUint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-06-24 19:12:45 +00:00
if ( ( argc > 4 ) & & ( argv [ 4 ] . segment ) )
sep = ( const char * ) kernel_dereference_bulk_pointer ( s , argv [ 4 ] , 0 ) ;
2009-02-15 06:10:59 +00:00
if ( maxwidth < 0 )
maxwidth = 0 ;
dest [ 0 ] = dest [ 1 ] = NULL_REG ;
2009-02-19 20:50:55 +00:00
if ( ! text | | ! * text | | ! dest ) { // Empty text
2009-02-15 06:10:59 +00:00
dest [ 2 ] = dest [ 3 ] = make_reg ( 0 , 0 ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelStrings , " GetTextSize: Empty string \n " ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-06-24 19:12:45 +00:00
GFX_ASSERT ( gfxop_get_text_params ( s - > gfx_state , font_nr , s - > strSplit ( text , sep ) . c_str ( ) , maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE ,
2009-02-19 20:50:55 +00:00
& width , & height , 0 , NULL , NULL , NULL ) ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelStrings , " GetTextSize '%s' -> %dx%d \n " , text , width , height ) ;
2009-02-15 06:10:59 +00:00
dest [ 2 ] = make_reg ( 0 , height ) ;
// dest[3] = make_reg(0, maxwidth? maxwidth : width);
dest [ 3 ] = make_reg ( 0 , width ) ;
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kWait ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-21 15:40:14 +00:00
uint32 time ;
2009-06-07 15:53:30 +00:00
int sleep_time = argv [ 0 ] . toUint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-02-21 15:40:14 +00:00
time = g_system - > getMillis ( ) ;
2009-02-21 23:16:03 +00:00
s - > r_acc = make_reg ( 0 , ( ( long ) time - ( long ) s - > last_wait_time ) * 60 / 1000 ) ;
2009-02-21 15:40:14 +00:00
s - > last_wait_time = time ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
// Reset optimization flags: Game is playing along nicely anyway
s - > kernel_opt_flags & = ~ ( KERNEL_OPT_FLAG_GOT_EVENT | KERNEL_OPT_FLAG_GOT_2NDEVENT ) ;
2009-02-15 06:10:59 +00:00
2009-06-04 11:28:05 +00:00
sleep_time * = g_debug_sleeptime_factor ;
2009-02-24 20:50:09 +00:00
GFX_ASSERT ( gfxop_sleep ( s - > gfx_state , sleep_time * 1000 / 60 ) ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kCoordPri ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
int y = argv [ 0 ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
return make_reg ( 0 , _find_view_priority ( s , y ) ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
reg_t kPriCoord ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
int priority = argv [ 0 ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
return make_reg ( 0 , _find_priority_band ( s , priority ) ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-21 21:16:41 +00:00
void _k_dirloop ( reg_t obj , uint16 angle , EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int view = GET_SEL32V ( obj , view ) ;
int signal = GET_SEL32V ( obj , signal ) ;
int loop ;
int maxloops ;
if ( signal & _K_VIEW_SIG_FLAG_DOESNT_TURN )
return ;
angle % = 360 ;
2009-07-11 23:45:54 +00:00
if ( ! ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > hasOldScriptHeader ( ) ) {
2009-02-15 06:10:59 +00:00
if ( angle < 45 )
loop = 3 ;
else if ( angle < 136 )
loop = 0 ;
else if ( angle < 225 )
loop = 2 ;
else if ( angle < 316 )
loop = 1 ;
else
loop = 3 ;
} else {
if ( angle > = 330 | | angle < = 30 )
loop = 3 ;
else if ( angle < = 150 )
loop = 0 ;
else if ( angle < = 210 )
loop = 2 ;
else if ( angle < 330 )
loop = 1 ;
else loop = 0xffff ;
}
maxloops = gfxop_lookup_view_get_loops ( s - > gfx_state , view ) ;
if ( maxloops = = GFX_ERROR ) {
2009-05-18 11:53:04 +00:00
error ( " Invalid view.%03d " , view ) ;
2009-02-15 06:10:59 +00:00
return ;
2009-02-15 22:28:12 +00:00
} else if ( ( loop > 1 ) & & ( maxloops < 4 ) )
2009-02-15 06:10:59 +00:00
return ;
PUT_SEL32V ( obj , loop , loop ) ;
}
2009-02-21 10:47:56 +00:00
reg_t kDirLoop ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
_k_dirloop ( argv [ 0 ] , argv [ 1 ] . toUint16 ( ) , s , funct_nr , argc , argv ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
# define GASEOUS_VIEW_MASK_ACTIVE (_K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_IGNORE_ACTOR)
# define GASEOUS_VIEW_MASK_PASSIVE (_K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_IGNORE_ACTOR)
2009-03-18 16:43:12 +00:00
static Common : : Rect nsrect_clip ( EngineState * s , int y , Common : : Rect retval , int priority ) ;
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
static int collides_with ( EngineState * s , Common : : Rect area , reg_t other_obj , int use_nsrect , int view_mask , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int other_signal = GET_SEL32V ( other_obj , signal ) ;
int other_priority = GET_SEL32V ( other_obj , priority ) ;
int y = GET_SEL32SV ( other_obj , y ) ;
2009-03-18 16:43:12 +00:00
Common : : Rect other_area ;
2009-02-15 06:10:59 +00:00
if ( use_nsrect ) {
other_area = get_nsrect ( s , other_obj , 0 ) ;
other_area = nsrect_clip ( s , y , other_area , other_priority ) ;
} else {
2009-03-18 16:43:12 +00:00
other_area . left = GET_SEL32V ( other_obj , brLeft ) ;
other_area . right = GET_SEL32V ( other_obj , brRight ) ;
other_area . top = GET_SEL32V ( other_obj , brTop ) ;
other_area . bottom = GET_SEL32V ( other_obj , brBottom ) ;
2009-02-15 06:10:59 +00:00
}
2009-03-18 16:43:12 +00:00
if ( other_area . right < 0 | | other_area . bottom < 0 | | area . right < 0 | | area . bottom < 0 )
2009-02-19 20:50:55 +00:00
return 0 ; // Out of scope
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
if ( other_area . left > = 320 | | other_area . top > = 190 | | area . right > = 320 | | area . bottom > = 190 )
2009-02-19 20:50:55 +00:00
return 0 ; // Out of scope
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " OtherSignal=%04x, z=%04x obj=%04x:%04x \n " , other_signal , ( other_signal & view_mask ) , PRINT_REG ( other_obj ) ) ;
2009-02-15 06:10:59 +00:00
if ( ( other_signal & ( view_mask ) ) = = 0 ) {
2009-02-19 20:50:55 +00:00
// check whether the other object ignores actors
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " against (%d,%d) to (%d,%d) \n " , other_area . left , other_area . top , other_area . right , other_area . bottom ) ;
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
if ( area . intersects ( other_area ) )
2009-02-15 06:10:59 +00:00
return 1 ;
/* CR (from :Bob Heitman:) Collision rects have Mac semantics, ((0,0),(1,1)) only
2009-02-19 20:50:55 +00:00
* * covers the coordinate ( 0 , 0 ) */
2009-02-15 06:10:59 +00:00
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " (no) \n " ) ;
2009-02-15 06:10:59 +00:00
return 0 ;
}
2009-06-04 20:51:24 +00:00
reg_t kCanBeHere ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t obj = argv [ 0 ] ;
2009-06-07 16:50:34 +00:00
reg_t cliplist_ref = ( argc > 1 ) ? argv [ 1 ] : NULL_REG ;
2009-02-28 11:12:59 +00:00
List * cliplist = NULL ;
2009-04-24 10:46:20 +00:00
GfxPort * port = s - > picture_port ;
2009-02-21 21:16:41 +00:00
uint16 signal ;
2009-02-15 06:10:59 +00:00
int retval ;
2009-03-18 16:43:12 +00:00
Common : : Rect abs_zone ;
2009-02-15 06:10:59 +00:00
rect_t zone ;
2009-02-21 21:16:41 +00:00
uint16 edgehit ;
uint16 illegal_bits ;
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
abs_zone . left = GET_SEL32SV ( obj , brLeft ) ;
abs_zone . right = GET_SEL32SV ( obj , brRight ) ;
abs_zone . top = GET_SEL32SV ( obj , brTop ) ;
abs_zone . bottom = GET_SEL32SV ( obj , brBottom ) ;
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
zone = gfx_rect ( abs_zone . left + port - > zone . x , abs_zone . top + port - > zone . y , abs_zone . width ( ) , abs_zone . height ( ) ) ;
2009-02-15 06:10:59 +00:00
signal = GET_SEL32V ( obj , signal ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " Checking collision: (%d,%d) to (%d,%d) ([%d..%d]x[%d..%d]), obj=%04x:%04x, sig=%04x, cliplist=%04x:%04x \n " ,
2009-03-18 16:43:12 +00:00
GFX_PRINT_RECT ( zone ) , abs_zone . left , abs_zone . right , abs_zone . top , abs_zone . bottom ,
2009-02-15 22:28:12 +00:00
PRINT_REG ( obj ) , signal , PRINT_REG ( cliplist_ref ) ) ;
2009-02-15 06:10:59 +00:00
illegal_bits = GET_SEL32V ( obj , illegalBits ) ;
2009-02-19 20:50:55 +00:00
retval = ! ( illegal_bits & ( edgehit = gfxop_scan_bitmask ( s - > gfx_state , zone , GFX_MASK_CONTROL ) ) ) ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " edgehit = %04x (illegalBits %04x) \n " , edgehit , illegal_bits ) ;
2009-02-15 06:10:59 +00:00
if ( retval = = 0 ) {
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
2009-02-19 20:50:55 +00:00
return not_register ( s , NULL_REG ) ; // Can't BeHere
2009-02-15 06:10:59 +00:00
}
retval = 0 ;
2009-02-19 20:50:55 +00:00
if ( ( illegal_bits & 0x8000 ) // If we are vulnerable to those views at all...
& & s - > dyn_views ) { // ...check against all stop-updated dynviews
2009-04-27 12:29:51 +00:00
GfxDynView * widget = ( GfxDynView * ) s - > dyn_views - > _contents ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " Checking vs dynviews: \n " ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
while ( widget ) {
2009-04-24 10:45:09 +00:00
if ( widget - > _ID & & ( widget - > signal & _K_VIEW_SIG_FLAG_STOPUPD )
& & ( ( widget - > _ID ! = obj . segment ) | | ( widget - > _subID ! = obj . offset ) )
& & is_object ( s , make_reg ( widget - > _ID , widget - > _subID ) ) )
if ( collides_with ( s , abs_zone , make_reg ( widget - > _ID , widget - > _subID ) , 1 , GASEOUS_VIEW_MASK_ACTIVE , funct_nr , argc , argv ) )
2009-02-15 22:28:12 +00:00
return not_register ( s , NULL_REG ) ;
2009-02-15 06:10:59 +00:00
2009-04-27 12:29:51 +00:00
widget = ( GfxDynView * ) widget - > _next ;
2009-02-15 22:28:12 +00:00
}
}
2009-02-15 06:10:59 +00:00
if ( signal & GASEOUS_VIEW_MASK_ACTIVE ) {
2009-02-19 20:50:55 +00:00
retval = signal & GASEOUS_VIEW_MASK_ACTIVE ; // CanBeHere- it's either being disposed, or it ignores actors anyway
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
2009-02-19 20:50:55 +00:00
return not_register ( s , make_reg ( 0 , retval ) ) ; // CanBeHere
2009-02-15 06:10:59 +00:00
}
if ( cliplist_ref . segment )
2009-05-18 08:28:04 +00:00
cliplist = lookup_list ( s , cliplist_ref ) ;
2009-02-15 06:10:59 +00:00
if ( cliplist ) {
2009-05-18 08:28:04 +00:00
Node * node = lookup_node ( s , cliplist - > first ) ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
retval = 0 ; // Assume that we Can'tBeHere...
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
while ( node ) { // Check each object in the list against our bounding rectangle
2009-02-15 06:10:59 +00:00
reg_t other_obj = node - > value ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " comparing against %04x:%04x \n " , PRINT_REG ( other_obj ) ) ;
2009-02-15 06:10:59 +00:00
if ( ! is_object ( s , other_obj ) ) {
2009-05-21 17:18:46 +00:00
warning ( " CanBeHere() cliplist contains non-object %04x:%04x " , PRINT_REG ( other_obj ) ) ;
} else if ( other_obj ! = obj ) { // Clipping against yourself is not recommended
2009-02-15 06:10:59 +00:00
if ( collides_with ( s , abs_zone , other_obj , 0 , GASEOUS_VIEW_MASK_PASSIVE , funct_nr , argc , argv ) ) {
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
2009-02-15 06:10:59 +00:00
return not_register ( s , NULL_REG ) ;
}
2009-02-19 20:50:55 +00:00
} // if (other_obj != obj)
2009-05-18 08:28:04 +00:00
node = lookup_node ( s , node - > succ ) ; // move on
2009-02-15 06:10:59 +00:00
}
}
if ( ! retval )
retval = 1 ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
2009-02-15 06:10:59 +00:00
return not_register ( s , make_reg ( 0 , retval ) ) ;
2009-02-19 20:50:55 +00:00
} // CanBeHere
2009-02-15 06:10:59 +00:00
2009-02-21 10:47:56 +00:00
reg_t kIsItSkip ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
int view = argv [ 0 ] . toSint16 ( ) ;
int loop = argv [ 1 ] . toSint16 ( ) ;
int cel = argv [ 2 ] . toSint16 ( ) ;
int y = argv [ 3 ] . toUint16 ( ) ;
int x = argv [ 4 ] . toUint16 ( ) ;
2009-02-15 06:10:59 +00:00
gfxr_view_t * res = NULL ;
gfx_pixmap_t * pxm = NULL ;
2009-03-22 23:11:43 +00:00
res = s - > gfx_state - > gfxResMan - > getView ( view , & loop , & cel , 0 ) ;
2009-03-17 23:30:57 +00:00
if ( ! res ) {
2009-06-08 11:42:13 +00:00
warning ( " [GFX] Attempt to get cel parameters for invalid view %d " , view ) ;
2009-02-15 06:10:59 +00:00
return make_reg ( 0 , - 1 ) ;
}
pxm = res - > loops [ loop ] . cels [ cel ] ;
2009-03-16 00:07:12 +00:00
if ( x > pxm - > index_width )
x = pxm - > index_width - 1 ;
if ( y > pxm - > index_height )
y = pxm - > index_height - 1 ;
2009-02-15 06:10:59 +00:00
2009-03-16 00:07:12 +00:00
return make_reg ( 0 , pxm - > index_data [ y * pxm - > index_width + x ] = = pxm - > color_key ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
reg_t kCelHigh ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
int view = argv [ 0 ] . toSint16 ( ) ;
int loop = argv [ 1 ] . toSint16 ( ) ;
int cel = argv [ 2 ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
int height , width ;
2009-02-17 19:15:37 +00:00
Common : : Point offset ;
2009-02-15 06:10:59 +00:00
if ( argc ! = 3 ) {
2009-02-20 20:11:12 +00:00
warning ( " CelHigh called with %d parameters " , argc ) ;
2009-02-15 06:10:59 +00:00
}
if ( gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & width , & height , & offset ) ) {
2009-05-18 11:53:04 +00:00
error ( " Invalid loop (%d) or cel (%d) in view.%d (0x%x), or view invalid " , loop , cel , view , view ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
} else
return make_reg ( 0 , height ) ;
}
2009-02-21 10:47:56 +00:00
reg_t kCelWide ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
int view = argv [ 0 ] . toSint16 ( ) ;
int loop = argv [ 1 ] . toSint16 ( ) ;
int cel = argv [ 2 ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
int height , width ;
2009-02-17 19:15:37 +00:00
Common : : Point offset ;
2009-02-15 06:10:59 +00:00
if ( argc ! = 3 ) {
2009-02-20 20:11:12 +00:00
warning ( " CelHigh called with %d parameters " , argc ) ;
2009-02-15 06:10:59 +00:00
}
if ( gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & width , & height , & offset ) ) {
2009-05-18 11:53:04 +00:00
error ( " Invalid loop (%d) or cel (%d) in view.%d (0x%x), or view invalid " , loop , cel , view , view ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
} else
return make_reg ( 0 , width ) ;
}
2009-02-21 10:47:56 +00:00
reg_t kNumLoops ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t obj = argv [ 0 ] ;
int view = GET_SEL32V ( obj , view ) ;
int loops_nr = gfxop_lookup_view_get_loops ( s - > gfx_state , view ) ;
if ( loops_nr < 0 ) {
2009-05-18 11:53:04 +00:00
error ( " view.%d (0x%x) not found " , view , view ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " NumLoops(view.%d) = %d \n " , view , loops_nr ) ;
2009-02-15 06:10:59 +00:00
return make_reg ( 0 , loops_nr ) ;
}
2009-02-21 10:47:56 +00:00
reg_t kNumCels ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t obj = argv [ 0 ] ;
int loop = GET_SEL32V ( obj , loop ) ;
int view = GET_SEL32V ( obj , view ) ;
int cel = 0xffff ;
2009-02-22 13:11:43 +00:00
if ( gfxop_check_cel ( s - > gfx_state , view , & loop , & cel ) ) {
2009-02-19 20:50:55 +00:00
// OK, this is a hack and there's a
// real function to calculate cel numbers...
2009-05-18 11:53:04 +00:00
error ( " view.%d (0x%x) not found " , view , view ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " NumCels(view.%d, %d) = %d \n " , view , loop , cel + 1 ) ;
2009-02-15 06:10:59 +00:00
return make_reg ( 0 , cel + 1 ) ;
}
2009-02-21 10:47:56 +00:00
reg_t kOnControl ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int arg = 0 ;
gfx_map_mask_t map ;
int xstart , ystart ;
int xlen = 1 , ylen = 1 ;
if ( argc = = 2 | | argc = = 4 )
map = GFX_MASK_CONTROL ;
else {
arg = 1 ;
2009-06-07 15:53:30 +00:00
map = ( gfx_map_mask_t ) argv [ 0 ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
}
2009-06-07 15:53:30 +00:00
ystart = argv [ arg + 1 ] . toSint16 ( ) ;
xstart = argv [ arg ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
if ( argc > 3 ) {
2009-06-07 15:53:30 +00:00
ylen = argv [ arg + 3 ] . toSint16 ( ) - ystart ;
xlen = argv [ arg + 2 ] . toSint16 ( ) - xstart ;
2009-02-15 06:10:59 +00:00
}
return make_reg ( 0 , gfxop_scan_bitmask ( s - > gfx_state , gfx_rect ( xstart , ystart + 10 , xlen , ylen ) , map ) ) ;
}
2009-02-28 11:12:59 +00:00
void _k_view_list_free_backgrounds ( EngineState * s , ViewObject * list , int list_nr ) ;
2009-02-15 06:10:59 +00:00
2009-05-17 13:37:54 +00:00
# define K_DRAWPIC_FLAG_MIRRORED (1 << 14)
2009-02-21 10:47:56 +00:00
reg_t kDrawPic ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-05-10 20:13:43 +00:00
drawn_pic_t dp ;
2009-06-07 16:50:34 +00:00
bool add_to_pic = ( argc > 2 ) ? ! argv [ 2 ] . toSint16 ( ) : false ;
2009-04-24 10:45:09 +00:00
gfx_color_t transparent = s - > wm_port - > _bgcolor ;
2009-05-17 13:37:54 +00:00
int picFlags = DRAWPIC01_FLAG_FILL_NORMALLY ;
2009-02-15 06:10:59 +00:00
2009-07-11 23:45:54 +00:00
if ( ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > usesOldGfxFunctions ( ) )
2009-06-07 16:50:34 +00:00
add_to_pic = ( argc > 2 ) ? argv [ 2 ] . toSint16 ( ) : false ;
2009-06-07 15:53:30 +00:00
dp . nr = argv [ 0 ] . toSint16 ( ) ;
2009-06-07 16:50:34 +00:00
dp . palette = ( argc > 3 ) ? argv [ 3 ] . toSint16 ( ) : 0 ;
2009-05-10 20:13:43 +00:00
2009-06-07 15:53:30 +00:00
if ( ( argc > 1 ) & & ( argv [ 1 ] . toUint16 ( ) & K_DRAWPIC_FLAG_MIRRORED ) )
2009-05-17 13:37:54 +00:00
picFlags | = DRAWPIC1_FLAG_MIRRORED ;
2009-02-15 06:10:59 +00:00
gfxop_disable_dirty_frames ( s - > gfx_state ) ;
2009-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
if ( NULL ! = s - > old_screen ) {
gfxop_free_pixmap ( s - > gfx_state , s - > old_screen ) ;
}
s - > old_screen = gfxop_grab_pixmap ( s - > gfx_state , gfx_rect ( 0 , 10 , 320 , 190 ) ) ;
2009-06-07 15:53:30 +00:00
debugC ( 2 , kDebugLevelGraphics , " Drawing pic.%03d \n " , argv [ 0 ] . toSint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
if ( add_to_pic ) {
2009-05-10 20:13:43 +00:00
s - > _pics . push_back ( dp ) ;
2009-05-17 13:37:54 +00:00
GFX_ASSERT ( gfxop_add_to_pic ( s - > gfx_state , dp . nr , picFlags , dp . palette ) ) ;
2009-02-15 06:10:59 +00:00
} else {
2009-05-10 20:13:43 +00:00
s - > _pics . clear ( ) ;
s - > _pics . push_back ( dp ) ;
2009-05-17 13:37:54 +00:00
GFX_ASSERT ( gfxop_new_pic ( s - > gfx_state , dp . nr , picFlags , dp . palette ) ) ;
2009-02-15 06:10:59 +00:00
}
2009-04-24 10:48:25 +00:00
delete s - > wm_port ;
delete s - > picture_port ;
delete s - > iconbar_port ;
2009-02-15 06:10:59 +00:00
2009-06-02 14:16:59 +00:00
s - > wm_port = new GfxPort ( s - > visual , s - > gfx_state - > pic_port_bounds , s - > ega_colors [ 0 ] , transparent ) ;
s - > picture_port = new GfxPort ( s - > visual , s - > gfx_state - > pic_port_bounds , s - > ega_colors [ 0 ] , transparent ) ;
2009-04-02 16:38:33 +00:00
2009-06-02 14:16:59 +00:00
s - > iconbar_port = new GfxPort ( s - > visual , gfx_rect ( 0 , 0 , 320 , 200 ) , s - > ega_colors [ 0 ] , transparent ) ;
2009-04-24 10:45:09 +00:00
s - > iconbar_port - > _flags | = GFXW_FLAG_NO_IMPLICIT_SWITCH ;
2009-02-15 06:10:59 +00:00
2009-05-30 14:30:39 +00:00
s - > visual - > add ( ( GfxContainer * ) s - > visual , s - > picture_port ) ;
s - > visual - > add ( ( GfxContainer * ) s - > visual , s - > wm_port ) ;
s - > visual - > add ( ( GfxContainer * ) s - > visual , s - > iconbar_port ) ;
2009-02-15 06:10:59 +00:00
s - > port = s - > picture_port ;
2009-03-14 00:05:01 +00:00
s - > pic_priority_table = gfxop_get_pic_metainfo ( s - > gfx_state ) ;
2009-02-15 06:10:59 +00:00
if ( argc > 1 )
2009-06-07 15:53:30 +00:00
s - > pic_animate = argv [ 1 ] . toSint16 ( ) & 0xff ; // The animation used during kAnimate() later on
2009-02-15 06:10:59 +00:00
s - > dyn_views = NULL ;
s - > drop_views = NULL ;
s - > priority_first = 42 ;
2009-07-11 23:45:54 +00:00
if ( ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > usesOldGfxFunctions ( ) )
2009-02-15 06:10:59 +00:00
s - > priority_last = 200 ;
else
s - > priority_last = 190 ;
s - > pic_not_valid = 1 ;
s - > pic_is_new = 1 ;
return s - > r_acc ;
}
2009-03-18 16:43:12 +00:00
Common : : Rect set_base ( EngineState * s , reg_t object ) {
2009-02-15 06:10:59 +00:00
int x , y , original_y , z , ystep , xsize , ysize ;
int xbase , ybase , xend , yend ;
int view , loop , cel ;
int oldloop , oldcel ;
int xmod = 0 , ymod = 0 ;
2009-03-18 16:43:12 +00:00
Common : : Rect retval ;
2009-02-15 06:10:59 +00:00
x = GET_SEL32SV ( object , x ) ;
original_y = y = GET_SEL32SV ( object , y ) ;
2009-07-11 23:45:54 +00:00
if ( ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . z > - 1 )
2009-02-15 06:10:59 +00:00
z = GET_SEL32SV ( object , z ) ;
else
z = 0 ;
2009-02-19 20:50:55 +00:00
y - = z ; // Subtract z offset
2009-02-15 06:10:59 +00:00
ystep = GET_SEL32SV ( object , yStep ) ;
view = GET_SEL32SV ( object , view ) ;
oldloop = loop = sign_extend_byte ( GET_SEL32V ( object , loop ) ) ;
oldcel = cel = sign_extend_byte ( GET_SEL32V ( object , cel ) ) ;
if ( gfxop_check_cel ( s - > gfx_state , view , & loop , & cel ) ) {
xsize = ysize = xmod = ymod = 0 ;
} else {
2009-02-17 19:15:37 +00:00
Common : : Point offset = Common : : Point ( 0 , 0 ) ;
2009-02-15 06:10:59 +00:00
if ( loop ! = oldloop ) {
loop = 0 ;
PUT_SEL32V ( object , loop , 0 ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Resetting loop for %04x:%04x! \n " , PRINT_REG ( object ) ) ;
2009-02-15 06:10:59 +00:00
}
if ( cel ! = oldcel ) {
cel = 0 ;
PUT_SEL32V ( object , cel , 0 ) ;
}
2009-02-19 20:50:55 +00:00
gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & xsize , & ysize , & offset ) ;
2009-02-15 06:10:59 +00:00
xmod = offset . x ;
ymod = offset . y ;
}
xbase = x - xmod - ( xsize > > 1 ) ;
xend = xbase + xsize ;
yend = y /* - ymod */ + 1 ;
ybase = yend - ystep ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelBaseSetter , " (%d,%d)+/-(%d,%d), (%d x %d) -> (%d, %d) to (%d, %d) \n " ,
2009-02-15 22:28:12 +00:00
x , y , xmod , ymod , xsize , ysize , xbase , ybase , xend , yend ) ;
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
retval . left = xbase ;
retval . top = ybase ;
retval . right = xend ;
retval . bottom = yend ;
2009-02-15 06:10:59 +00:00
return retval ;
}
2009-02-21 10:47:56 +00:00
void _k_base_setter ( EngineState * s , reg_t object ) {
2009-03-18 16:43:12 +00:00
Common : : Rect absrect = set_base ( s , object ) ;
2009-02-15 06:10:59 +00:00
2009-07-11 23:45:54 +00:00
if ( lookup_selector ( s , object , ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . brLeft , NULL , NULL ) ! = kSelectorVariable )
2009-02-19 20:50:55 +00:00
return ; // non-fatal
2009-02-15 06:10:59 +00:00
2009-05-12 18:57:28 +00:00
// Note: there was a check here for a very old version of SCI, which supposedly needed
// to subtract 1 from absrect.top. The original check was for version 0.000.256, which
// does not exist (earliest one was KQ4 SCI, version 0.000.274). This code is left here
// for reference only
#if 0
2009-06-04 21:44:39 +00:00
if ( s - > _version < = SCI_VERSION_0 )
2009-03-18 16:43:12 +00:00
- - absrect . top ; // Compensate for early SCI OB1 'bug'
2009-05-12 18:57:28 +00:00
# endif
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
PUT_SEL32V ( object , brLeft , absrect . left ) ;
PUT_SEL32V ( object , brRight , absrect . right ) ;
PUT_SEL32V ( object , brTop , absrect . top ) ;
PUT_SEL32V ( object , brBottom , absrect . bottom ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
reg_t kBaseSetter ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t object = argv [ 0 ] ;
_k_base_setter ( s , object ) ;
return s - > r_acc ;
2009-02-19 20:50:55 +00:00
} // kBaseSetter
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
static Common : : Rect nsrect_clip ( EngineState * s , int y , Common : : Rect retval , int priority ) {
2009-02-15 06:10:59 +00:00
int pri_top ;
if ( priority = = - 1 )
2009-06-07 15:53:30 +00:00
priority = _find_view_priority ( s , y ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
pri_top = _find_priority_band ( s , priority ) + 1 ;
2009-02-19 20:50:55 +00:00
// +1: Don't know why, but this seems to be happening
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
if ( retval . top < pri_top )
retval . top = pri_top ;
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
if ( retval . bottom < retval . top )
retval . top = retval . bottom - 1 ;
2009-02-15 06:10:59 +00:00
return retval ;
}
2009-03-18 16:43:12 +00:00
static Common : : Rect calculate_nsrect ( EngineState * s , int x , int y , int view , int loop , int cel ) {
2009-02-15 06:10:59 +00:00
int xbase , ybase , xend , yend , xsize , ysize ;
int xmod = 0 , ymod = 0 ;
2009-03-18 16:43:12 +00:00
Common : : Rect retval ( 0 , 0 , 0 , 0 ) ;
2009-02-15 06:10:59 +00:00
if ( gfxop_check_cel ( s - > gfx_state , view , & loop , & cel ) ) {
xsize = ysize = xmod = ymod = 0 ;
} else {
2009-02-17 19:15:37 +00:00
Common : : Point offset = Common : : Point ( 0 , 0 ) ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & xsize , & ysize , & offset ) ;
2009-02-15 06:10:59 +00:00
xmod = offset . x ;
ymod = offset . y ;
}
xbase = x - xmod - ( xsize > > 1 ) ;
xend = xbase + xsize ;
2009-02-19 20:50:55 +00:00
yend = y - ymod + 1 ; // +1: magic modifier
2009-02-15 06:10:59 +00:00
ybase = yend - ysize ;
2009-03-18 16:43:12 +00:00
retval . left = xbase ;
retval . top = ybase ;
retval . right = xend ;
retval . bottom = yend ;
2009-02-15 06:10:59 +00:00
return retval ;
}
2009-03-18 16:43:12 +00:00
Common : : Rect get_nsrect ( EngineState * s , reg_t object , byte clip ) {
2009-02-15 06:10:59 +00:00
int x , y , z ;
int view , loop , cel ;
2009-03-18 16:43:12 +00:00
Common : : Rect retval ;
2009-02-15 06:10:59 +00:00
x = GET_SEL32SV ( object , x ) ;
y = GET_SEL32SV ( object , y ) ;
2009-07-11 23:45:54 +00:00
if ( ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . z > - 1 )
2009-02-15 06:10:59 +00:00
z = GET_SEL32SV ( object , z ) ;
else
z = 0 ;
2009-02-19 20:50:55 +00:00
y - = z ; // Subtract z offset
2009-02-15 06:10:59 +00:00
view = GET_SEL32SV ( object , view ) ;
loop = sign_extend_byte ( GET_SEL32SV ( object , loop ) ) ;
cel = sign_extend_byte ( GET_SEL32SV ( object , cel ) ) ;
retval = calculate_nsrect ( s , x , y , view , loop , cel ) ;
if ( clip ) {
int priority = GET_SEL32SV ( object , priority ) ;
return nsrect_clip ( s , y , retval , priority ) ;
}
return retval ;
}
2009-02-21 10:47:56 +00:00
static void _k_set_now_seen ( EngineState * s , reg_t object ) {
2009-03-18 16:43:12 +00:00
Common : : Rect absrect = get_nsrect ( s , object , 0 ) ;
2009-02-15 06:10:59 +00:00
2009-07-11 23:45:54 +00:00
if ( lookup_selector ( s , object , ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . nsTop , NULL , NULL ) ! = kSelectorVariable ) {
2009-02-22 13:11:43 +00:00
return ;
2009-02-19 20:50:55 +00:00
} // This isn't fatal
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
PUT_SEL32V ( object , nsLeft , absrect . left ) ;
PUT_SEL32V ( object , nsRight , absrect . right ) ;
PUT_SEL32V ( object , nsTop , absrect . top ) ;
PUT_SEL32V ( object , nsBottom , absrect . bottom ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
reg_t kSetNowSeen ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t object = argv [ 0 ] ;
_k_set_now_seen ( s , object ) ;
return s - > r_acc ;
2009-02-26 02:21:55 +00:00
}
2009-02-15 06:10:59 +00:00
2009-02-21 10:47:56 +00:00
reg_t kPalette ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
switch ( argv [ 0 ] . toUint16 ( ) ) {
2009-03-29 15:08:50 +00:00
case 1 :
2009-05-16 14:24:12 +00:00
debug ( 5 , " STUB: kPalette() effect 1, direct palette set " ) ;
2009-03-29 15:08:50 +00:00
break ;
case 2 :
2009-05-16 14:24:12 +00:00
debug ( 5 , " STUB: kPalette() effect 2, set flag to colors " ) ;
2009-03-29 15:08:50 +00:00
break ;
case 3 :
2009-05-16 14:24:12 +00:00
debug ( 5 , " STUB: kPalette() effect 3, clear flag to colors " ) ;
2009-03-29 15:08:50 +00:00
break ;
2009-04-01 20:32:45 +00:00
case 4 : { // Set palette intensity
#if 0
// Colors 0 (black) and 255 (white) cannot be changed
2009-06-07 15:53:30 +00:00
int16 from = CLIP < int16 > ( 1 , 255 , argv [ 2 ] . toUint16 ( ) ) ;
int16 to = CLIP < int16 > ( 1 , 255 , argv [ 3 ] . toUint16 ( ) ) ;
int16 intensity = argv [ 4 ] . toUint16 ( ) ;
2009-04-01 20:32:45 +00:00
2009-06-07 15:53:30 +00:00
if ( argc < 5 | | argv [ 5 ] . toUint16 ( ) = = 0 ) {
2009-04-01 20:32:45 +00:00
s - > gfx_state - > gfxResMan - > setPaletteIntensity ( from , to , intensity ) ;
} else {
warning ( " kPalette: argv[5] != 0 " ) ;
}
return s - > r_acc ;
# endif
2009-05-16 14:24:12 +00:00
debug ( 5 , " STUB: kPalette() effect 4, set color intensity " ) ;
2009-03-29 15:08:50 +00:00
break ;
2009-04-01 20:32:45 +00:00
}
case 5 : { // Find closest color
2009-06-07 15:53:30 +00:00
int r = argv [ 1 ] . toUint16 ( ) ;
int g = argv [ 2 ] . toUint16 ( ) ;
int b = argv [ 3 ] . toUint16 ( ) ;
2009-02-15 06:10:59 +00:00
int i , delta , bestindex = - 1 , bestdelta = 200000 ;
2009-03-23 08:43:53 +00:00
for ( i = 0 ; i < s - > gfx_state - > gfxResMan - > getColorCount ( ) ; i + + ) {
int dr = abs ( s - > gfx_state - > gfxResMan - > getColor ( i ) . r - r ) ;
int dg = abs ( s - > gfx_state - > gfxResMan - > getColor ( i ) . g - g ) ;
int db = abs ( s - > gfx_state - > gfxResMan - > getColor ( i ) . b - b ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
delta = dr * dr + dg * dg + db * db ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
if ( delta < bestdelta ) {
2009-02-15 06:10:59 +00:00
bestdelta = delta ;
bestindex = i ;
}
}
2009-02-19 20:50:55 +00:00
// Don't warn about inexact mappings -- it's actually the
// rule rather than the exception
2009-02-15 06:10:59 +00:00
return make_reg ( 0 , bestindex ) ;
}
2009-03-29 15:08:50 +00:00
case 6 :
2009-05-16 14:24:12 +00:00
debug ( 5 , " STUB: kPalette() effect 6, animate palette " ) ;
2009-02-15 06:10:59 +00:00
break ;
2009-03-29 15:08:50 +00:00
case 7 :
2009-05-16 14:24:12 +00:00
debug ( 5 , " STUB: kPalette() effect 7, save palette to heap " ) ;
2009-03-29 15:08:50 +00:00
break ;
case 8 :
2009-05-16 14:24:12 +00:00
debug ( 5 , " STUB: kPalette() effect 8, set stored palette " ) ;
2009-03-29 15:08:50 +00:00
break ;
default :
2009-06-07 15:53:30 +00:00
warning ( " kPalette(): Unimplemented subfunction: %d " , argv [ 0 ] . toUint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-19 20:50:55 +00:00
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
static void _k_draw_control ( EngineState * s , reg_t obj , int inverse ) ;
2009-02-15 06:10:59 +00:00
2009-02-21 10:47:56 +00:00
static void _k_disable_delete_for_now ( EngineState * s , reg_t obj ) {
2009-02-15 22:28:12 +00:00
reg_t text_pos = GET_SEL32 ( obj , text ) ;
2009-05-21 17:18:46 +00:00
char * text = text_pos . isNull ( ) ? NULL : ( char * ) s - > seg_manager - > dereference ( text_pos , NULL ) ;
2009-02-15 06:10:59 +00:00
int type = GET_SEL32V ( obj , type ) ;
int state = GET_SEL32V ( obj , state ) ;
2009-04-09 08:49:42 +00:00
/*
* WORKAROUND : The function is a " prevent the user from doing something
* nasty " type of thing, and goes back to the ugly way in which savegame
* deletion is implemented in SCI ( and even worse in SQ4 / Floppy , for
* which the workaround is intended ) . The result is basically that you
* can ' t implement savegame deletion for SQ4 / Floppy unless you duplicate
* the exact naming scheme of savefiles ( i . e . savefiles must be named
* SQ4SG . < number > ) and the exact file format of the savegame index
* ( SQ4SG . DIR ) . From the earlier discussions on file I / O handling -
* before as well as after the merge - I gather that this is not an
2009-05-20 17:53:31 +00:00
* option .
*
2009-04-09 08:49:42 +00:00
* SQ4 / Floppy is special , being the first game to implement savegame
* deletion at all . For later games , we manage to implement deletion by
* using gross hacks in kDeviceInfo ( ) ( essentially repurposing a few
* subfunctions ) . I decided at the time that SQ4 / Floppy was not worth the
* effort ( see above ) , and to simply disable the delete functionality for
* that game - bringing the save / load dialog on a par with SCI0 .
*/
2009-03-24 12:46:48 +00:00
if ( type = = K_CONTROL_BUTTON & & text & & ( s - > _gameName = = " sq4 " ) & &
2009-06-04 21:44:39 +00:00
s - > _version < SCI_VERSION_1_1 & & ! strcmp ( text , " Delete " ) ) {
2009-03-25 12:07:10 +00:00
PUT_SEL32V ( obj , state , ( state | kControlStateDisabled ) & ~ kControlStateEnabled ) ;
2009-02-19 20:50:55 +00:00
}
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
reg_t kDrawControl ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t obj = argv [ 0 ] ;
_k_disable_delete_for_now ( s , obj ) ;
_k_draw_control ( s , obj , 0 ) ;
FULL_REDRAW ( ) ;
return NULL_REG ;
}
2009-02-21 10:47:56 +00:00
reg_t kHiliteControl ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t obj = argv [ 0 ] ;
_k_draw_control ( s , obj , 1 ) ;
2009-02-19 20:50:55 +00:00
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-19 20:50:55 +00:00
void update_cursor_limits ( int * display_offset , int * cursor , int max_displayed ) {
2009-02-15 06:10:59 +00:00
if ( * cursor < * display_offset + 4 ) {
if ( * cursor < 8 )
* display_offset = 0 ;
else
* display_offset = * cursor - 8 ;
} else if ( * cursor - * display_offset > max_displayed - 8 )
* display_offset = 12 + * cursor - max_displayed ;
}
# define _K_EDIT_DELETE \
2009-02-19 20:50:55 +00:00
if ( cursor < textlen ) { \
memmove ( text + cursor , text + cursor + 1 , textlen - cursor + 1 ) ; \
}
2009-02-15 06:10:59 +00:00
# define _K_EDIT_BACKSPACE \
2009-02-19 20:50:55 +00:00
if ( cursor ) { \
- - cursor ; \
memmove ( text + cursor , text + cursor + 1 , textlen - cursor + 1 ) ; \
- - textlen ; \
}
2009-02-15 06:10:59 +00:00
2009-02-21 10:47:56 +00:00
reg_t kEditControl ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t obj = argv [ 0 ] ;
reg_t event = argv [ 1 ] ;
if ( obj . segment ) {
2009-02-21 21:16:41 +00:00
uint16 ct_type = GET_SEL32V ( obj , type ) ;
2009-02-15 06:10:59 +00:00
switch ( ct_type ) {
2009-02-15 22:28:12 +00:00
case 0 :
2009-02-19 20:50:55 +00:00
break ; // NOP
2009-02-15 06:10:59 +00:00
case K_CONTROL_EDIT :
if ( event . segment & & ( ( GET_SEL32V ( event , type ) ) = = SCI_EVT_KEYBOARD ) ) {
int max_displayed = GET_SEL32V ( obj , max ) ;
int max = max_displayed ;
int cursor = GET_SEL32V ( obj , cursor ) ;
int modifiers = GET_SEL32V ( event , modifiers ) ;
int key = GET_SEL32V ( event , message ) ;
reg_t text_pos = GET_SEL32 ( obj , text ) ;
int display_offset = 0 ;
2009-02-21 23:27:24 +00:00
char * text = ( char * ) s - > seg_manager - > dereference ( text_pos , NULL ) ;
2009-02-15 06:10:59 +00:00
int textlen ;
if ( ! text ) {
2009-05-21 17:18:46 +00:00
warning ( " Could not draw control: %04x:%04x does not reference text " , PRINT_REG ( text_pos ) ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
textlen = strlen ( text ) ;
cursor + = display_offset ;
if ( cursor > textlen )
cursor = textlen ;
if ( modifiers & SCI_EVM_CTRL ) {
switch ( tolower ( ( char ) key ) ) {
2009-02-15 22:28:12 +00:00
case ' a ' :
cursor = 0 ;
break ;
case ' e ' :
cursor = textlen ;
break ;
case ' f ' :
if ( cursor < textlen ) + + cursor ;
break ;
case ' b ' :
if ( cursor > 0 ) - - cursor ;
break ;
case ' k ' :
text [ cursor ] = 0 ;
2009-02-19 20:50:55 +00:00
break ; // Terminate string
2009-02-15 22:28:12 +00:00
case ' h ' :
_K_EDIT_BACKSPACE ;
break ;
case ' d ' :
_K_EDIT_DELETE ;
break ;
2009-02-15 06:10:59 +00:00
}
PUT_SEL32V ( event , claimed , 1 ) ;
2009-02-19 20:50:55 +00:00
} else if ( modifiers & SCI_EVM_ALT ) { // Ctrl has precedence over Alt
2009-02-15 06:10:59 +00:00
switch ( key ) {
2009-02-15 22:28:12 +00:00
case 0x2100 /* A-f */ :
2009-05-14 23:09:04 +00:00
while ( ( cursor < textlen ) & & ( text [ cursor + + ] ! = ' ' ) )
;
2009-02-15 22:28:12 +00:00
break ;
case 0x3000 /* A-b */ :
2009-05-14 23:09:04 +00:00
while ( ( cursor > 0 ) & & ( text [ - - cursor - 1 ] ! = ' ' ) )
;
2009-02-15 22:28:12 +00:00
break ;
2009-02-15 06:10:59 +00:00
case 0x2000 /* A-d */ : {
while ( ( cursor < textlen ) & & ( text [ cursor ] = = ' ' ) ) {
_K_EDIT_DELETE ;
textlen - - ;
}
while ( ( cursor < textlen ) & & ( text [ cursor ] ! = ' ' ) ) {
_K_EDIT_DELETE ;
textlen - - ;
}
break ;
}
}
PUT_SEL32V ( event , claimed , 1 ) ;
} else if ( key < 31 ) {
PUT_SEL32V ( event , claimed , 1 ) ;
2009-02-15 22:28:12 +00:00
switch ( key ) {
2009-02-25 19:52:17 +00:00
case SCI_K_BACKSPACE :
2009-02-15 22:28:12 +00:00
_K_EDIT_BACKSPACE ;
break ;
2009-02-15 06:10:59 +00:00
default :
PUT_SEL32V ( event , claimed , 0 ) ;
}
} else if ( key & 0xff00 ) {
2009-02-15 22:28:12 +00:00
switch ( key ) {
2009-02-25 19:52:17 +00:00
case SCI_K_HOME :
2009-02-15 22:28:12 +00:00
cursor = 0 ;
break ;
2009-02-25 19:52:17 +00:00
case SCI_K_END :
2009-02-15 22:28:12 +00:00
cursor = textlen ;
break ;
2009-02-25 19:52:17 +00:00
case SCI_K_RIGHT :
2009-02-22 13:11:43 +00:00
if ( cursor + 1 < = textlen )
2009-02-19 20:50:55 +00:00
+ + cursor ;
2009-02-15 22:28:12 +00:00
break ;
2009-02-25 19:52:17 +00:00
case SCI_K_LEFT :
2009-02-19 20:50:55 +00:00
if ( cursor > 0 )
- - cursor ;
2009-02-15 22:28:12 +00:00
break ;
2009-02-25 19:52:17 +00:00
case SCI_K_DELETE :
2009-02-15 22:28:12 +00:00
_K_EDIT_DELETE ;
break ;
2009-02-15 06:10:59 +00:00
}
PUT_SEL32V ( event , claimed , 1 ) ;
} else if ( ( key > 31 ) & & ( key < 128 ) ) {
int inserting = ( modifiers & SCI_EVM_INSERT ) ;
modifiers & = ~ ( SCI_EVM_RSHIFT | SCI_EVM_LSHIFT | SCI_EVM_CAPSLOCK ) ;
if ( cursor = = textlen ) {
if ( textlen < max ) {
text [ cursor + + ] = key ;
2009-02-19 20:50:55 +00:00
text [ cursor ] = 0 ; // Terminate string
2009-02-15 06:10:59 +00:00
}
} else if ( inserting ) {
if ( textlen < max ) {
int i ;
for ( i = textlen + 2 ; i > = cursor ; i - - )
text [ i ] = text [ i - 1 ] ;
text [ cursor + + ] = key ;
}
2009-02-19 20:50:55 +00:00
} else { // Overwriting
2009-02-15 06:10:59 +00:00
text [ cursor + + ] = key ;
}
if ( max_displayed < max )
update_cursor_limits ( & display_offset , & cursor , max_displayed ) ;
cursor - = display_offset ;
PUT_SEL32V ( event , claimed , 1 ) ;
}
2009-02-19 20:50:55 +00:00
PUT_SEL32V ( obj , cursor , cursor ) ; // Write back cursor position
2009-02-15 06:10:59 +00:00
}
case K_CONTROL_ICON :
case K_CONTROL_BOX :
case K_CONTROL_BUTTON :
if ( event . segment ) PUT_SEL32V ( event , claimed , 1 ) ;
_k_draw_control ( s , obj , 0 ) ;
return NULL_REG ;
break ;
case K_CONTROL_TEXT : {
int state = GET_SEL32V ( obj , state ) ;
2009-03-25 12:07:10 +00:00
PUT_SEL32V ( obj , state , state | kControlStateDitherFramed ) ;
2009-02-15 06:10:59 +00:00
_k_draw_control ( s , obj , 0 ) ;
PUT_SEL32V ( obj , state , state ) ;
}
break ;
default :
2009-02-20 20:11:12 +00:00
warning ( " Attempt to edit control type %d " , ct_type ) ;
2009-02-15 06:10:59 +00:00
}
}
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
static void _k_draw_control ( EngineState * s , reg_t obj , int inverse ) {
2009-02-15 06:10:59 +00:00
int x = GET_SEL32SV ( obj , nsLeft ) ;
int y = GET_SEL32SV ( obj , nsTop ) ;
int xl = GET_SEL32SV ( obj , nsRight ) - x ;
int yl = GET_SEL32SV ( obj , nsBottom ) - y ;
rect_t area = gfx_rect ( x , y , xl , yl ) ;
int font_nr = GET_SEL32V ( obj , font ) ;
reg_t text_pos = GET_SEL32 ( obj , text ) ;
2009-06-24 19:12:45 +00:00
const char * text = text_pos . isNull ( ) ? NULL : ( char * ) s - > seg_manager - > dereference ( text_pos , NULL ) ;
2009-02-15 06:10:59 +00:00
int view = GET_SEL32V ( obj , view ) ;
int cel = sign_extend_byte ( GET_SEL32V ( obj , cel ) ) ;
int loop = sign_extend_byte ( GET_SEL32V ( obj , loop ) ) ;
gfx_alignment_t mode ;
int type = GET_SEL32V ( obj , type ) ;
int state = GET_SEL32V ( obj , state ) ;
int cursor ;
int max ;
switch ( type ) {
case K_CONTROL_BUTTON :
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " drawing button %04x:%04x to %d,%d \n " , PRINT_REG ( obj ) , x , y ) ;
2009-06-24 19:12:45 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_button_control ( s - > port , obj , area , s - > strSplit ( text , NULL ) . c_str ( ) , font_nr ,
2009-03-25 12:07:10 +00:00
( int8 ) ( state & kControlStateFramed ) , ( int8 ) inverse , ( int8 ) ( state & kControlStateDisabled ) ) ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_CONTROL_TEXT :
mode = ( gfx_alignment_t ) GET_SEL32V ( obj , mode ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " drawing text %04x:%04x to %d,%d, mode=%d \n " , PRINT_REG ( obj ) , x , y , mode ) ;
2009-02-15 06:10:59 +00:00
2009-06-24 19:12:45 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_text_control ( s - > port , obj , area , s - > strSplit ( text ) . c_str ( ) , font_nr , mode ,
2009-03-25 12:07:10 +00:00
( int8 ) ( ! ! ( state & kControlStateDitherFramed ) ) , ( int8 ) inverse ) ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_CONTROL_EDIT :
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " drawing edit control %04x:%04x to %d,%d \n " , PRINT_REG ( obj ) , x , y ) ;
2009-02-15 06:10:59 +00:00
max = GET_SEL32V ( obj , max ) ;
cursor = GET_SEL32V ( obj , cursor ) ;
if ( cursor > ( signed ) strlen ( text ) )
cursor = strlen ( text ) ;
2009-05-21 21:50:11 +00:00
// update_cursor_limits(&s->save_dir_edit_offset, &cursor, max); FIXME: get rid of this?
2009-04-21 21:37:03 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_edit_control ( s - > port , obj , area , text , font_nr , ( unsigned ) cursor , ( int8 ) inverse ) ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_CONTROL_ICON :
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " drawing icon control %04x:%04x to %d,%d \n " , PRINT_REG ( obj ) , x , y - 1 ) ;
2009-02-15 06:10:59 +00:00
2009-04-21 21:37:03 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_icon_control ( s - > port , obj , area , view , loop , cel ,
2009-03-25 12:07:10 +00:00
( int8 ) ( state & kControlStateFramed ) , ( int8 ) inverse ) ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_CONTROL_CONTROL :
case K_CONTROL_CONTROL_ALIAS : {
2009-06-24 19:12:45 +00:00
const char * * entries_list = NULL ;
const char * seeker ;
2009-02-15 06:10:59 +00:00
int entries_nr ;
2009-02-15 22:28:12 +00:00
int lsTop = GET_SEL32V ( obj , lsTop ) - text_pos . offset ;
2009-02-15 06:10:59 +00:00
int list_top = 0 ;
int selection = 0 ;
int entry_size = GET_SEL32V ( obj , x ) ;
int i ;
2009-05-30 17:30:54 +00:00
debugC ( 2 , kDebugLevelGraphics , " drawing list control %04x:%04x to %d,%d, diff %d \n " , PRINT_REG ( obj ) , x , y , SCI_MAX_SAVENAME_LENGTH ) ;
2009-02-15 06:10:59 +00:00
cursor = GET_SEL32V ( obj , cursor ) - text_pos . offset ;
entries_nr = 0 ;
seeker = text ;
2009-02-19 20:50:55 +00:00
while ( seeker [ 0 ] ) { // Count string entries in NULL terminated string list
2009-02-15 06:10:59 +00:00
+ + entries_nr ;
seeker + = entry_size ;
}
2009-02-19 20:50:55 +00:00
if ( entries_nr ) { // determine list_top, selection, and the entries_list
2009-02-15 06:10:59 +00:00
seeker = text ;
2009-06-24 19:12:45 +00:00
entries_list = ( const char * * ) malloc ( sizeof ( char * ) * entries_nr ) ;
2009-02-15 06:10:59 +00:00
for ( i = 0 ; i < entries_nr ; i + + ) {
entries_list [ i ] = seeker ;
seeker + = entry_size ;
if ( ( seeker - text ) = = lsTop )
list_top = i + 1 ;
if ( ( seeker - text ) = = cursor )
selection = i + 1 ;
}
}
2009-04-21 21:37:03 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_list_control ( s - > port , obj , area , font_nr , entries_list , entries_nr ,
2009-02-21 21:16:41 +00:00
list_top , selection , ( int8 ) inverse ) ) ;
2009-02-15 06:10:59 +00:00
if ( entries_nr )
free ( entries_list ) ;
}
break ;
case K_CONTROL_BOX :
break ;
default :
2009-05-21 17:18:46 +00:00
warning ( " Unknown control type: %d at %04x:%04x, at (%d, %d) size %d x %d " ,
2009-02-15 22:28:12 +00:00
type , PRINT_REG ( obj ) , x , y , xl , yl ) ;
2009-02-15 06:10:59 +00:00
}
if ( ! s - > pic_not_valid ) {
FULL_REDRAW ( ) ;
}
}
2009-03-18 16:43:12 +00:00
static void draw_rect_to_control_map ( EngineState * s , Common : : Rect abs_zone ) {
2009-04-24 10:46:20 +00:00
GfxBox * box ;
2009-02-15 06:10:59 +00:00
gfx_color_t color ;
gfxop_set_color ( s - > gfx_state , & color , - 1 , - 1 , - 1 , - 1 , - 1 , 0xf ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " adding control block (%d,%d)to(%d,%d) \n " , abs_zone . left , abs_zone . top , abs_zone . right , abs_zone . bottom ) ;
2009-02-15 06:10:59 +00:00
2009-03-18 16:43:12 +00:00
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 ) ;
2009-02-15 06:10:59 +00:00
assert_primary_widget_lists ( s ) ;
ADD_TO_CURRENT_PICTURE_PORT ( box ) ;
}
2009-04-24 10:46:20 +00:00
static void draw_obj_to_control_map ( EngineState * s , GfxDynView * view ) {
2009-04-24 10:45:09 +00:00
reg_t obj = make_reg ( view - > _ID , view - > _subID ) ;
2009-02-15 06:10:59 +00:00
if ( ! is_object ( s , obj ) )
2009-05-21 17:18:46 +00:00
warning ( " View %d does not contain valid object reference %04x:%04x " , view - > _ID , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
2009-06-06 11:38:20 +00:00
reg_t * sp = view - > signalp . getPointer ( s ) ;
if ( ! ( sp & & ( sp - > offset & _K_VIEW_SIG_FLAG_IGNORE_ACTOR ) ) ) {
2009-04-24 10:45:09 +00:00
Common : : Rect abs_zone = get_nsrect ( s , make_reg ( view - > _ID , view - > _subID ) , 1 ) ;
2009-02-15 22:28:12 +00:00
draw_rect_to_control_map ( s , abs_zone ) ;
2009-02-15 06:10:59 +00:00
}
}
2009-04-24 10:46:20 +00:00
static void _k_view_list_do_postdraw ( EngineState * s , GfxList * list ) {
2009-04-24 14:20:31 +00:00
GfxDynView * widget = ( GfxDynView * ) list - > _contents ;
2009-02-15 06:10:59 +00:00
while ( widget ) {
2009-04-24 10:45:09 +00:00
reg_t obj = make_reg ( widget - > _ID , widget - > _subID ) ;
2009-02-15 06:10:59 +00:00
/*
* 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 )
2009-03-17 08:03:42 +00:00
* if ( ( widget - > signal & ( _K_VIEW_SIG_FLAG_PRIVATE | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) = = _K_VIEW_SIG_FLAG_PRIVATE ) {
2009-02-15 06:10:59 +00:00
*/
if ( ( widget - > signal & ( _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) = = 0 ) {
2009-07-11 23:45:54 +00:00
int has_nsrect = lookup_selector ( s , obj , ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . nsBottom , NULL , NULL ) = = kSelectorVariable ;
2009-02-15 06:10:59 +00:00
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
2009-05-21 17:18:46 +00:00
fprintf ( stderr , " lsRected %04x:%04x \n " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
# endif
}
# ifdef DEBUG_LSRECT
2009-02-22 13:11:43 +00:00
else
2009-07-11 23:45:54 +00:00
fprintf ( stderr , " Not lsRecting %04x:%04x because %d \n " , PRINT_REG ( obj ) , lookup_selector ( s , obj , ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . nsBottom , NULL , NULL ) ) ;
2009-02-15 06:10:59 +00:00
# endif
if ( widget - > signal & _K_VIEW_SIG_FLAG_HIDDEN )
widget - > signal | = _K_VIEW_SIG_FLAG_REMOVE ;
}
# ifdef DEBUG_LSRECT
2009-05-21 17:18:46 +00:00
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 ) ) ) ;
2009-02-15 06:10:59 +00:00
# endif
2009-06-06 11:38:20 +00:00
reg_t * sp = widget - > signalp . getPointer ( s ) ;
if ( sp ) {
* sp = make_reg ( 0 , widget - > signal & 0xffff ) ; /* Write back signal */
2009-02-15 06:10:59 +00:00
}
2009-04-27 12:29:51 +00:00
widget = ( GfxDynView * ) widget - > _next ;
2009-02-15 06:10:59 +00:00
}
}
2009-02-21 10:47:56 +00:00
void _k_view_list_mark_free ( EngineState * s , reg_t off ) {
2009-02-15 06:10:59 +00:00
if ( s - > dyn_views ) {
2009-04-24 14:20:31 +00:00
GfxDynView * w = ( GfxDynView * ) s - > dyn_views - > _contents ;
2009-02-15 06:10:59 +00:00
while ( w ) {
2009-04-24 10:45:09 +00:00
if ( w - > _ID = = off . segment
& & w - > _subID = = off . offset ) {
2009-06-06 11:38:20 +00:00
w - > under_bitsp . obj = NULL_REG ;
2009-02-15 06:10:59 +00:00
}
2009-04-24 14:20:31 +00:00
w = ( GfxDynView * ) w - > _next ;
2009-02-15 06:10:59 +00:00
}
}
}
2009-05-31 01:11:06 +00:00
static bool _k_animate_ran = false ; // FIXME: Avoid non-const global vars
2009-02-15 06:10:59 +00:00
2009-04-24 10:46:20 +00:00
int _k_view_list_dispose_loop ( EngineState * s , List * list , GfxDynView * widget , int funct_nr , int argc , reg_t * argv ) {
2009-02-19 20:50:55 +00:00
// disposes all list members flagged for disposal; funct_nr is the invoking kfunction
// returns non-zero IFF views were dropped
2009-02-15 06:10:59 +00:00
int signal ;
int dropped = 0 ;
2009-05-26 11:30:21 +00:00
_k_animate_ran = false ;
2009-02-15 06:10:59 +00:00
if ( widget ) {
int retval ;
2009-02-19 20:50:55 +00:00
// Recurse:
2009-04-27 12:29:51 +00:00
retval = _k_view_list_dispose_loop ( s , list , ( GfxDynView * ) widget - > _next , funct_nr , argc , argv ) ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
if ( retval = = - 1 ) // Bail out on annihilation, rely on re-start from Animate()
2009-02-15 06:10:59 +00:00
return - 1 ;
2009-04-24 10:45:09 +00:00
if ( GFXW_IS_DYN_VIEW ( widget ) & & ( widget - > _ID ! = GFXW_NO_ID ) ) {
2009-06-06 11:38:20 +00:00
signal = widget - > signalp . getPointer ( s ) - > offset ;
2009-02-15 06:10:59 +00:00
if ( signal & _K_VIEW_SIG_FLAG_DISPOSE_ME ) {
2009-04-24 10:45:09 +00:00
reg_t obj = make_reg ( widget - > _ID , widget - > _subID ) ;
2009-02-15 06:10:59 +00:00
reg_t under_bits = NULL_REG ;
if ( ! is_object ( s , obj ) ) {
2009-05-31 10:02:16 +00:00
error ( " Non-object %04x:%04x present in view list during delete time " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
obj = NULL_REG ;
2009-06-06 11:38:20 +00:00
} else {
reg_t * ubp = widget - > under_bitsp . getPointer ( s ) ;
if ( ubp ) { // Is there a bg picture left to clean?
reg_t mem_handle = * ubp ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
if ( mem_handle . segment ) {
if ( ! kfree ( s , mem_handle ) ) {
2009-06-06 11:38:20 +00:00
* ubp = make_reg ( 0 , widget - > under_bits = 0 ) ;
2009-02-15 22:28:12 +00:00
} else {
2009-05-21 17:18:46 +00:00
warning ( " Treating viewobj %04x:%04x as no longer present " , PRINT_REG ( obj ) ) ;
2009-02-15 22:28:12 +00:00
obj = NULL_REG ;
}
2009-02-15 06:10:59 +00:00
}
}
2009-06-06 11:38:20 +00:00
}
2009-02-15 06:10:59 +00:00
if ( is_object ( s , obj ) ) {
2009-06-01 08:00:58 +00:00
if ( invoke_selector ( INV_SEL ( obj , delete_ , kContinueOnInvalidSelector ) , 0 ) )
2009-05-21 17:18:46 +00:00
warning ( " Object at %04x:%04x requested deletion, but does not have a delete funcselector " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
if ( _k_animate_ran ) {
2009-05-21 17:18:46 +00:00
warning ( " Object at %04x:%04x invoked kAnimate() during deletion " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
return dropped ;
}
2009-06-06 11:38:20 +00:00
reg_t * ubp = widget - > under_bitsp . getPointer ( s ) ;
if ( ubp )
under_bits = * ubp ;
2009-02-15 06:10:59 +00:00
if ( under_bits . segment ) {
2009-06-06 11:38:20 +00:00
* ubp = make_reg ( 0 , 0 ) ;
2009-02-15 06:10:59 +00:00
graph_restore_box ( s , under_bits ) ;
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Freeing %04x:%04x with signal=%04x \n " , PRINT_REG ( obj ) , signal ) ;
2009-02-15 06:10:59 +00:00
if ( ! ( signal & _K_VIEW_SIG_FLAG_HIDDEN ) ) {
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Adding view at %04x:%04x to background \n " , PRINT_REG ( obj ) ) ;
2009-04-24 10:48:25 +00:00
if ( ! ( gfxw_remove_id ( widget - > _parent , widget - > _ID , widget - > _subID ) = = widget ) ) {
2009-05-31 10:02:16 +00:00
error ( " Attempt to remove view with ID %x:%x from list failed " , widget - > _ID , widget - > _subID ) ;
2009-02-15 06:10:59 +00:00
}
2009-05-30 14:30:39 +00:00
s - > drop_views - > add ( ( GfxContainer * ) s - > drop_views , gfxw_picviewize_dynview ( widget ) ) ;
2009-02-15 06:10:59 +00:00
draw_obj_to_control_map ( s , widget ) ;
2009-04-24 10:45:09 +00:00
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 ;
2009-02-15 06:10:59 +00:00
dropped = 1 ;
2009-02-15 22:28:12 +00:00
} else {
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Deleting view at %04x:%04x \n " , PRINT_REG ( obj ) ) ;
2009-04-24 10:45:09 +00:00
widget - > _flags | = GFXW_FLAG_VISIBLE ;
2009-04-24 10:48:25 +00:00
gfxw_annihilate ( widget ) ;
2009-02-19 20:50:55 +00:00
return - 1 ; // restart: Done in Animate()
2009-02-15 06:10:59 +00:00
}
}
}
}
}
return dropped ;
}
2009-05-26 11:30:21 +00:00
enum {
_K_MAKE_VIEW_LIST_CYCLE = 1 ,
_K_MAKE_VIEW_LIST_CALC_PRIORITY = 2 ,
_K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP = 4
} ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:46:20 +00:00
static GfxDynView * _k_make_dynview_obj ( EngineState * s , reg_t obj , int options , int nr , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
short oldloop , oldcel ;
int cel , loop , view_nr = GET_SEL32SV ( obj , view ) ;
int palette ;
int signal ;
reg_t under_bits ;
2009-02-17 19:15:37 +00:00
Common : : Point pos ;
2009-02-15 06:10:59 +00:00
int z ;
2009-04-24 10:46:20 +00:00
GfxDynView * widget ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " - Adding %04x:%04x \n " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
obj = obj ;
pos . x = GET_SEL32SV ( obj , x ) ;
pos . y = GET_SEL32SV ( obj , y ) ;
2009-02-19 20:50:55 +00:00
pos . y + + ; // magic: Sierra appears to do something like this
2009-02-15 06:10:59 +00:00
z = GET_SEL32SV ( obj , z ) ;
2009-02-19 20:50:55 +00:00
// !-- nsRect used to be checked here!
2009-02-15 06:10:59 +00:00
loop = oldloop = sign_extend_byte ( GET_SEL32V ( obj , loop ) ) ;
cel = oldcel = sign_extend_byte ( GET_SEL32V ( obj , cel ) ) ;
2009-07-11 23:45:54 +00:00
if ( ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . palette )
2009-02-15 22:28:12 +00:00
palette = GET_SEL32V ( obj , palette ) ;
else
palette = 0 ;
2009-02-19 20:50:55 +00:00
// Clip loop and cel, write back if neccessary
2009-02-15 06:10:59 +00:00
if ( gfxop_check_cel ( s - > gfx_state , view_nr , & loop , & cel ) ) {
return NULL ;
}
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 ) ;
}
2009-06-06 11:38:20 +00:00
ObjVarRef under_bitsp ;
2009-07-11 23:45:54 +00:00
if ( lookup_selector ( s , obj , ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . underBits , & ( under_bitsp ) , NULL ) ! = kSelectorVariable ) {
2009-06-06 11:38:20 +00:00
under_bitsp . obj = NULL_REG ;
2009-02-15 06:10:59 +00:00
under_bits = NULL_REG ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Object at %04x:%04x has no underBits \n " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
} else
2009-06-06 11:38:20 +00:00
under_bits = * under_bitsp . getPointer ( s ) ;
2009-02-15 06:10:59 +00:00
2009-06-06 11:38:20 +00:00
ObjVarRef signalp ;
2009-07-11 23:45:54 +00:00
if ( lookup_selector ( s , obj , ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . signal , & ( signalp ) , NULL ) ! = kSelectorVariable ) {
2009-06-06 11:38:20 +00:00
signalp . obj = NULL_REG ;
2009-02-15 06:10:59 +00:00
signal = 0 ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Object at %04x:%04x has no signal selector \n " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
} else {
2009-06-06 11:38:20 +00:00
signal = signalp . getPointer ( s ) - > offset ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " with signal = %04x \n " , signal ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-19 20:50:55 +00:00
widget = gfxw_new_dyn_view ( s - > gfx_state , pos , z , view_nr , loop , cel , palette , - 1 , - 1 , ALIGN_CENTER , ALIGN_BOTTOM , nr ) ;
2009-02-15 06:10:59 +00:00
if ( widget ) {
2009-04-24 10:48:25 +00:00
widget = ( GfxDynView * ) gfxw_set_id ( widget , obj . segment , obj . offset ) ;
2009-02-19 20:50:55 +00:00
widget = gfxw_dyn_view_set_params ( widget , under_bits . segment , under_bitsp , signal , signalp ) ;
2009-04-24 10:45:09 +00:00
widget - > _flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ; // Only works the first time 'round'
2009-02-15 06:10:59 +00:00
return widget ;
} else {
2009-02-20 20:11:12 +00:00
warning ( " Could not generate dynview widget for %d/%d/%d " , view_nr , loop , cel ) ;
2009-02-15 06:10:59 +00:00
return NULL ;
}
}
2009-04-24 10:46:20 +00:00
static void _k_make_view_list ( EngineState * s , GfxList * * widget_list , List * list , int options , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 22:28:12 +00:00
/* 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 , funct_nr should be the same as in the calling kernel function .
*/
2009-02-28 11:12:59 +00:00
Node * node ;
2009-02-15 06:10:59 +00:00
int sequence_nr = 0 ;
2009-04-24 10:46:20 +00:00
GfxDynView * widget ;
2009-02-15 06:10:59 +00:00
if ( ! * widget_list ) {
2009-05-31 10:02:16 +00:00
error ( " make_view_list with widget_list == () " ) ;
2009-02-15 06:10:59 +00:00
} ;
assert_primary_widget_lists ( s ) ;
2009-02-19 20:50:55 +00:00
// In case one of the views' doit() does a DrawPic...
// Yes, this _does_ happen!
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
if ( ! list ) { // list sanity check
2009-05-31 10:02:16 +00:00
error ( " Attempt to make list from non-list " ) ;
2009-02-15 06:10:59 +00:00
}
2009-05-30 19:59:53 +00:00
reg_t next_node = list - > first ;
node = lookup_node ( s , next_node ) ;
2009-02-15 06:10:59 +00:00
while ( node ) {
2009-02-19 20:50:55 +00:00
reg_t obj = node - > value ; // The object we're using
2009-04-24 10:46:20 +00:00
GfxDynView * tempWidget ;
2009-02-15 06:10:59 +00:00
if ( options & _K_MAKE_VIEW_LIST_CYCLE ) {
unsigned int signal = GET_SEL32V ( obj , signal ) ;
if ( ! ( signal & _K_VIEW_SIG_FLAG_FROZEN ) ) {
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " invoking %04x:%04x::doit() \n " , PRINT_REG ( obj ) ) ;
2009-06-01 08:00:58 +00:00
invoke_selector ( INV_SEL ( obj , doit , kContinueOnInvalidSelector ) , 0 ) ; // Call obj::doit() if neccessary
2009-05-30 19:59:53 +00:00
// Lookup node again, since the NodeTable it was in may
// have been re-allocated.
node = lookup_node ( s , next_node ) ;
2009-02-15 06:10:59 +00:00
}
}
2009-02-19 20:50:55 +00:00
next_node = node - > succ ; // In case the cast list was changed
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
if ( list - > first . segment = = 0 & & list - > first . offset = = 0 ) // The cast list was completely emptied!
2009-02-15 06:10:59 +00:00
break ;
2009-02-19 20:50:55 +00:00
tempWidget = _k_make_dynview_obj ( s , obj , options , sequence_nr - - , funct_nr , argc , argv ) ;
2009-02-15 22:28:12 +00:00
if ( tempWidget )
2009-05-30 14:30:39 +00:00
GFX_ASSERT ( ( * widget_list ) - > add ( ( GfxContainer * ) ( * widget_list ) , tempWidget ) ) ;
2009-02-15 06:10:59 +00:00
2009-05-18 08:28:04 +00:00
node = lookup_node ( s , next_node ) ; // Next node
2009-02-15 22:28:12 +00:00
}
2009-02-15 06:10:59 +00:00
2009-04-24 14:20:31 +00:00
widget = ( GfxDynView * ) ( * widget_list ) - > _contents ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
while ( widget ) { // Read back widget values
2009-06-06 11:38:20 +00:00
reg_t * sp = widget - > signalp . getPointer ( s ) ;
if ( sp )
widget - > signal = sp - > offset ;
2009-02-15 06:10:59 +00:00
2009-04-27 12:29:51 +00:00
widget = ( GfxDynView * ) widget - > _next ;
2009-02-15 06:10:59 +00:00
}
}
2009-04-24 10:46:20 +00:00
static void _k_prepare_view_list ( EngineState * s , GfxList * list , int options ) {
2009-04-24 14:20:31 +00:00
GfxDynView * view = ( GfxDynView * ) list - > _contents ;
2009-02-15 06:10:59 +00:00
while ( view ) {
2009-04-24 10:45:09 +00:00
reg_t obj = make_reg ( view - > _ID , view - > _subID ) ;
2009-02-15 06:10:59 +00:00
int priority , _priority ;
2009-07-11 23:45:54 +00:00
int has_nsrect = ( view - > _ID < = 0 ) ? 0 : lookup_selector ( s , obj , ( ( SciEngine * ) g_engine ) - > getKernel ( ) - > _selectorMap . nsBottom , NULL , NULL ) = = kSelectorVariable ;
2009-02-15 06:10:59 +00:00
int oldsignal = view - > signal ;
_k_set_now_seen ( s , obj ) ;
2009-04-24 10:45:09 +00:00
_priority = /*GET_SELECTOR(obj, y); */ ( ( view - > _pos . y ) ) ;
2009-02-15 06:10:59 +00:00
_priority = _find_view_priority ( s , _priority - 1 ) ;
2009-02-19 20:50:55 +00:00
if ( options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) { // Picview
2009-02-15 06:10:59 +00:00
priority = GET_SEL32SV ( obj , priority ) ;
if ( priority < 0 )
2009-02-19 20:50:55 +00:00
priority = _priority ; // Always for picviews
} else { // Dynview
if ( has_nsrect & & ! ( view - > signal & _K_VIEW_SIG_FLAG_FIX_PRI_ON ) ) { // Calculate priority
2009-02-15 06:10:59 +00:00
if ( options & _K_MAKE_VIEW_LIST_CALC_PRIORITY )
PUT_SEL32V ( obj , priority , _priority ) ;
priority = _priority ;
2009-02-19 20:50:55 +00:00
} else // DON'T calculate the priority
2009-02-15 06:10:59 +00:00
priority = GET_SEL32SV ( obj , priority ) ;
}
2009-04-24 10:45:09 +00:00
view - > _color . priority = priority ;
2009-02-15 06:10:59 +00:00
if ( priority > - 1 )
2009-04-24 10:45:09 +00:00
view - > _color . mask | = GFX_MASK_PRIORITY ;
2009-02-15 06:10:59 +00:00
else
2009-04-24 10:45:09 +00:00
view - > _color . mask & = ~ GFX_MASK_PRIORITY ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
// CR (from :Bob Heitman:) stopupdated views (like pic views) have
// their clipped nsRect drawn to the control map
2009-02-15 06:10:59 +00:00
if ( view - > signal & _K_VIEW_SIG_FLAG_STOP_UPDATE ) {
2009-03-17 08:03:42 +00:00
view - > signal | = _K_VIEW_SIG_FLAG_STOPUPD ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Setting magic STOP_UPD for %04x:%04x \n " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
}
if ( ( options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) )
draw_obj_to_control_map ( s , view ) ;
2009-02-19 20:50:55 +00:00
// Extreme Pattern Matching ugliness ahead...
2009-02-15 22:28:12 +00:00
if ( view - > signal & _K_VIEW_SIG_FLAG_NO_UPDATE ) {
2009-02-19 20:50:55 +00:00
if ( ( ( view - > signal & ( _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_FORCE_UPDATE ) ) ) // 9.1.1.1
2009-02-15 22:28:12 +00:00
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE ) ) = = _K_VIEW_SIG_FLAG_HIDDEN )
2009-02-19 20:50:55 +00:00
| | ( ( 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
2009-02-15 22:28:12 +00:00
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 ;
2009-02-19 20:50:55 +00:00
} else { // if not STOP_UPDATE
2009-02-15 22:28:12 +00:00
if ( view - > signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE )
s - > pic_not_valid + + ;
view - > signal & = ~ _K_VIEW_SIG_FLAG_FORCE_UPDATE ;
}
2009-02-15 06:10:59 +00:00
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " dv[%04x:%04x]: signal %04x -> %04x \n " , PRINT_REG ( obj ) , oldsignal , view - > signal ) ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
// Never happens
/* if (view->signal & 0) {
2009-03-17 08:03:42 +00:00
view - > signal & = ~ _K_VIEW_SIG_FLAG_STOPUPD ;
2009-05-21 17:18:46 +00:00
fprintf ( stderr , " Unsetting magic StopUpd for view %04x:%04x \n " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
} */
2009-04-27 12:29:51 +00:00
view = ( GfxDynView * ) view - > _next ;
2009-02-15 06:10:59 +00:00
}
}
2009-04-24 10:46:20 +00:00
static void _k_update_signals_in_view_list ( GfxList * old_list , GfxList * new_list ) {
2009-02-19 20:50:55 +00:00
// O(n^2)... a bit painful, but much faster than the redraws it helps prevent
2009-05-26 11:30:21 +00:00
GfxDynView * old_widget = ( GfxDynView * ) old_list - > _contents ;
2009-02-15 06:10:59 +00:00
/* 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 ) {
2009-04-24 14:20:31 +00:00
GfxDynView * new_widget = ( GfxDynView * ) new_list - > _contents ;
2009-02-15 06:10:59 +00:00
while ( new_widget
2009-04-24 10:45:09 +00:00
& & ( new_widget - > _ID ! = old_widget - > _ID
| | new_widget - > _subID ! = old_widget - > _subID ) )
2009-04-27 12:29:51 +00:00
new_widget = ( GfxDynView * ) new_widget - > _next ;
2009-02-15 06:10:59 +00:00
if ( new_widget ) {
2009-03-17 08:03:42 +00:00
int carry = old_widget - > signal & _K_VIEW_SIG_FLAG_STOPUPD ;
2009-02-19 20:50:55 +00:00
// Transfer 'stopupd' flag
2009-02-15 06:10:59 +00:00
2009-04-24 10:45:09 +00:00
if ( ( new_widget - > _pos . x ! = old_widget - > _pos . x )
| | ( new_widget - > _pos . y ! = old_widget - > _pos . y )
2009-02-19 20:50:55 +00:00
// No idea why this is supposed to be bad
/* || (new_widget->z != old_widget->z)
2009-02-15 22:28:12 +00:00
| | ( new_widget - > view ! = old_widget - > view )
| | ( new_widget - > loop ! = old_widget - > loop )
| | ( new_widget - > cel ! = old_widget - > cel )
2009-02-19 20:50:55 +00:00
*/ )
2009-02-15 06:10:59 +00:00
carry = 0 ;
old_widget - > signal = new_widget - > signal | = carry ;
}
2009-04-27 12:29:51 +00:00
old_widget = ( GfxDynView * ) old_widget - > _next ;
2009-02-15 06:10:59 +00:00
}
}
2009-04-24 10:46:20 +00:00
static void _k_view_list_kryptonize ( GfxWidget * v ) {
2009-02-15 06:10:59 +00:00
if ( v ) {
2009-04-24 10:45:09 +00:00
v - > _flags & = ~ GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
_k_view_list_kryptonize ( v - > _next ) ;
2009-02-15 06:10:59 +00:00
}
}
2009-04-24 10:46:20 +00:00
static void _k_raise_topmost_in_view_list ( EngineState * s , GfxList * list , GfxDynView * view ) {
2009-02-15 06:10:59 +00:00
if ( view ) {
2009-04-24 10:46:20 +00:00
GfxDynView * next = ( GfxDynView * ) view - > _next ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
// step 11
2009-02-15 06:10:59 +00:00
if ( ( view - > signal & ( _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = 0 ) {
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Forcing precedence 2 at [%04x:%04x] with %04x \n " , PRINT_REG ( make_reg ( view - > _ID , view - > _subID ) ) , view - > signal ) ;
2009-02-15 06:10:59 +00:00
view - > force_precedence = 2 ;
2009-02-15 22:28:12 +00:00
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 ;
}
2009-02-15 06:10:59 +00:00
}
2009-04-24 10:48:25 +00:00
gfxw_remove_widget_from_container ( view - > _parent , view ) ;
2009-02-15 06:10:59 +00:00
if ( view - > signal & _K_VIEW_SIG_FLAG_HIDDEN )
2009-04-24 10:48:25 +00:00
gfxw_hide_widget ( view ) ;
2009-02-15 22:28:12 +00:00
else
2009-04-24 10:48:25 +00:00
gfxw_show_widget ( view ) ;
2009-02-15 06:10:59 +00:00
2009-05-30 14:30:39 +00:00
list - > add ( ( GfxContainer * ) list , view ) ;
2009-02-15 06:10:59 +00:00
_k_raise_topmost_in_view_list ( s , list , next ) ;
}
}
2009-04-24 10:46:20 +00:00
static void _k_redraw_view_list ( EngineState * s , GfxList * list ) {
2009-04-24 14:20:31 +00:00
GfxDynView * view = ( GfxDynView * ) list - > _contents ;
2009-02-15 06:10:59 +00:00
while ( view ) {
2009-05-30 17:30:54 +00:00
debugC ( 2 , kDebugLevelGraphics , " dv[%04x:%04x]: signal %04x \n " , PRINT_REG ( make_reg ( view - > _ID , view - > _subID ) ) , view - > signal ) ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
// step 1 of subalgorithm
2009-02-15 06:10:59 +00:00
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 ) ;
2009-02-19 20:50:55 +00:00
} else { // NO_UPD is not set
2009-02-15 06:10:59 +00:00
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 ;
}
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " at substep 6: signal %04x \n " , view - > signal ) ;
2009-02-15 06:10:59 +00:00
if ( view - > signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE )
2009-02-19 20:50:55 +00:00
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 ) ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " at substep 11/14: signal %04x \n " , view - > signal ) ;
2009-02-15 06:10:59 +00:00
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 ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " -> signal %04x \n " , view - > signal ) ;
2009-02-15 06:10:59 +00:00
2009-04-27 12:29:51 +00:00
view = ( GfxDynView * ) view - > _next ;
2009-02-15 06:10:59 +00:00
}
}
2009-02-19 20:50:55 +00:00
// Flags for _k_draw_view_list
// Whether some magic with the base object's "signal" selector should be done:
2009-02-15 06:10:59 +00:00
# define _K_DRAW_VIEW_LIST_USE_SIGNAL 1
2009-02-19 20:50:55 +00:00
// This flag draws all views with the "DISPOSE_ME" flag set:
2009-02-15 06:10:59 +00:00
# define _K_DRAW_VIEW_LIST_DISPOSEABLE 2
2009-02-19 20:50:55 +00:00
// Use this one to draw all views with "DISPOSE_ME" NOT set:
2009-02-15 06:10:59 +00:00
# define _K_DRAW_VIEW_LIST_NONDISPOSEABLE 4
2009-02-19 20:50:55 +00:00
// Draw as picviews
2009-02-15 06:10:59 +00:00
# define _K_DRAW_VIEW_LIST_PICVIEW 8
2009-04-24 10:46:20 +00:00
void _k_draw_view_list ( EngineState * s , GfxList * list , int flags ) {
2009-02-19 20:50:55 +00:00
// Draws list_nr members of list to s->pic.
2009-04-24 14:20:31 +00:00
GfxDynView * widget = ( GfxDynView * ) list - > _contents ;
2009-02-15 06:10:59 +00:00
2009-05-30 14:30:39 +00:00
if ( ( GfxContainer * ) s - > port ! = ( GfxContainer * ) s - > dyn_views - > _parent )
2009-02-19 20:50:55 +00:00
return ; // Return if the pictures are meant for a different port
2009-02-15 06:10:59 +00:00
while ( widget ) {
if ( flags & _K_DRAW_VIEW_LIST_PICVIEW )
widget = gfxw_picviewize_dynview ( widget ) ;
2009-04-24 10:45:09 +00:00
if ( GFXW_IS_DYN_VIEW ( widget ) & & widget - > _ID ) {
2009-06-06 11:38:20 +00:00
uint16 signal = ( flags & _K_DRAW_VIEW_LIST_USE_SIGNAL ) ? widget - > signalp . getPointer ( s ) - > offset : 0 ;
2009-02-15 06:10:59 +00:00
if ( signal & _K_VIEW_SIG_FLAG_HIDDEN )
2009-04-24 10:48:25 +00:00
gfxw_hide_widget ( widget ) ;
2009-02-15 06:10:59 +00:00
else
2009-04-24 10:48:25 +00:00
gfxw_show_widget ( widget ) ;
2009-02-15 06:10:59 +00:00
if ( ! ( flags & _K_DRAW_VIEW_LIST_USE_SIGNAL )
2009-02-15 22:28:12 +00:00
| | ( ( 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 ) ) ) {
2009-02-15 06:10:59 +00:00
if ( flags & _K_DRAW_VIEW_LIST_USE_SIGNAL ) {
2009-02-19 20:50:55 +00:00
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
2009-02-15 06:10:59 +00:00
if ( signal & _K_VIEW_SIG_FLAG_HIDDEN )
2009-04-24 10:48:25 +00:00
gfxw_hide_widget ( widget ) ;
2009-02-15 06:10:59 +00:00
else
2009-04-24 10:48:25 +00:00
gfxw_show_widget ( widget ) ;
2009-02-15 06:10:59 +00:00
2009-06-06 11:38:20 +00:00
* widget - > signalp . getPointer ( s ) = make_reg ( 0 , signal ) ; // Write the changes back
2009-02-15 06:10:59 +00:00
} ;
2009-02-19 20:50:55 +00:00
} // ...if we're drawing disposeables and this one is disposeable, or if we're drawing non-
// disposeables and this one isn't disposeable
2009-02-15 06:10:59 +00:00
}
2009-04-27 12:29:51 +00:00
widget = ( GfxDynView * ) widget - > _next ;
2009-02-19 20:50:55 +00:00
} // while (widget)
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
reg_t kAddToPic ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-04-24 10:46:20 +00:00
GfxList * pic_views ;
2009-02-15 06:10:59 +00:00
reg_t list_ref = argv [ 0 ] ;
assert_primary_widget_lists ( s ) ;
if ( argc > 1 ) {
int view , cel , loop , x , y , priority , control ;
2009-04-24 10:46:20 +00:00
GfxWidget * widget ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
view = argv [ 0 ] . toUint16 ( ) ;
loop = argv [ 1 ] . toUint16 ( ) ;
cel = argv [ 2 ] . toUint16 ( ) ;
x = argv [ 3 ] . toSint16 ( ) ;
y = argv [ 4 ] . toSint16 ( ) + 1 /* magic + 1 */ ;
priority = argv [ 5 ] . toSint16 ( ) ;
control = argv [ 6 ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:48:25 +00:00
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 ) ;
2009-02-15 06:10:59 +00:00
if ( ! widget ) {
2009-05-31 10:02:16 +00:00
error ( " Attempt to single-add invalid picview (%d/%d/%d) " , view , loop , cel ) ;
2009-02-15 06:10:59 +00:00
} else {
2009-04-24 10:45:09 +00:00
widget - > _ID = - 1 ;
2009-02-15 06:10:59 +00:00
if ( control > = 0 ) {
2009-03-18 16:43:12 +00:00
Common : : Rect abs_zone = nsrect_clip ( s , y , calculate_nsrect ( s , x , y , view , loop , cel ) , priority ) ;
2009-02-15 06:10:59 +00:00
draw_rect_to_control_map ( s , abs_zone ) ;
}
2009-04-24 10:46:20 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( gfxw_picviewize_dynview ( ( GfxDynView * ) widget ) ) ;
2009-02-15 06:10:59 +00:00
}
} else {
2009-02-28 11:12:59 +00:00
List * list ;
2009-02-15 06:10:59 +00:00
if ( ! list_ref . segment ) {
2009-05-21 17:18:46 +00:00
warning ( " Attempt to AddToPic single non-list: %04x:%04x " , PRINT_REG ( list_ref ) ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-05-18 08:28:04 +00:00
list = lookup_list ( s , list_ref ) ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:45:09 +00:00
pic_views = gfxw_new_list ( s - > picture_port - > _bounds , 1 ) ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Preparing picview list... \n " ) ;
2009-02-15 06:10:59 +00:00
_k_make_view_list ( s , & pic_views , list , 0 , funct_nr , argc , argv ) ;
_k_prepare_view_list ( s , pic_views , _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) ;
2009-02-19 20:50:55 +00:00
// Store pic views for later re-use
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Drawing picview list... \n " ) ;
2009-02-15 06:10:59 +00:00
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 ) ;
2009-02-19 20:50:55 +00:00
// Draw relative to the bottom center
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Returning. \n " ) ;
2009-02-15 06:10:59 +00:00
}
reparentize_primary_widget_lists ( s , s - > port ) ;
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kGetPort ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-04-24 10:45:09 +00:00
return make_reg ( 0 , s - > port - > _ID ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-21 10:47:56 +00:00
reg_t kSetPort ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 22:28:12 +00:00
if ( activated_icon_bar & & argc = = 6 ) {
2009-02-15 06:10:59 +00:00
port_origin_x = port_origin_y = 0 ;
2009-05-26 11:30:21 +00:00
activated_icon_bar = false ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-15 22:28:12 +00:00
switch ( argc ) {
2009-02-15 06:10:59 +00:00
case 1 : {
2009-06-07 15:53:30 +00:00
unsigned int port_nr = argv [ 0 ] . toSint16 ( ) ;
2009-04-24 10:46:20 +00:00
GfxPort * new_port ;
2009-02-15 06:10:59 +00:00
/* We depart from official semantics here, sorry!
Reasoning : Sierra SCI does not clip ports while we do .
Therefore a draw to the titlebar port ( which is the
official semantics ) would cut off the lower part of the
icons in an SCI1 icon bar . Instead we have an
iconbar_port that does not exist in SSCI . */
2009-04-24 10:45:09 +00:00
if ( port_nr = = ( unsigned int ) - 1 ) port_nr = s - > iconbar_port - > _ID ;
2009-02-15 06:10:59 +00:00
2009-06-02 14:16:59 +00:00
new_port = s - > visual - > getPort ( port_nr ) ;
2009-02-15 06:10:59 +00:00
if ( ! new_port ) {
2009-05-31 10:02:16 +00:00
error ( " Invalid port %04x requested " , port_nr ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
}
2009-04-24 14:22:14 +00:00
s - > port - > draw ( gfxw_point_zero ) ; // Update the port we're leaving
2009-02-15 06:10:59 +00:00
s - > port = new_port ;
return s - > r_acc ;
}
case 6 : {
2009-06-07 15:53:30 +00:00
port_origin_y = argv [ 0 ] . toSint16 ( ) ;
port_origin_x = argv [ 1 ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
if ( argv [ 0 ] . toSint16 ( ) = = - 10 ) {
2009-04-24 14:22:14 +00:00
s - > port - > draw ( gfxw_point_zero ) ; // Update the port we're leaving
2009-02-15 06:10:59 +00:00
s - > port = s - > iconbar_port ;
2009-05-26 11:30:21 +00:00
activated_icon_bar = true ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-05-26 19:16:24 +00:00
// Notify the graphics resource manager that the pic port bounds changed
2009-06-07 15:53:30 +00:00
s - > gfx_state - > gfxResMan - > changePortBounds ( argv [ 5 ] . toUint16 ( ) , argv [ 4 ] . toUint16 ( ) , argv [ 3 ] . toUint16 ( ) + argv [ 5 ] . toUint16 ( ) , argv [ 2 ] . toUint16 ( ) + argv [ 4 ] . toUint16 ( ) ) ;
2009-05-26 19:16:24 +00:00
2009-05-18 09:07:31 +00:00
// LSL6 calls kSetPort to extend the screen to draw the GUI. If we free all resources
// here, the background picture is freed too, and this makes everything a big mess.
// FIXME/TODO: This code really needs to be rewritten to conform to the original behavior
if ( s - > _gameName ! = " LSL6 " ) {
2009-06-07 15:53:30 +00:00
s - > gfx_state - > pic_port_bounds = gfx_rect ( argv [ 5 ] . toUint16 ( ) , argv [ 4 ] . toUint16 ( ) , argv [ 3 ] . toUint16 ( ) , argv [ 2 ] . toUint16 ( ) ) ;
2009-05-18 09:07:31 +00:00
// FIXME: Should really only invalidate all loaded pic resources here;
// this is overkill
s - > gfx_state - > gfxResMan - > freeAllResources ( ) ;
} else {
// WORKAROUND for LSL6
2009-06-07 15:53:30 +00:00
printf ( " SetPort case 6 called in LSL6. Origin: %d, %d - Clip rect: %d, %d, %d, %d \n " , argv [ 1 ] . toSint16 ( ) , argv [ 0 ] . toSint16 ( ) , argv [ 5 ] . toUint16 ( ) , argv [ 4 ] . toUint16 ( ) , argv [ 3 ] . toUint16 ( ) , argv [ 2 ] . toUint16 ( ) ) ;
2009-05-18 09:07:31 +00:00
}
2009-02-15 06:10:59 +00:00
break ;
}
default :
2009-05-31 10:02:16 +00:00
error ( " SetPort was called with %d parameters " , argc ) ;
2009-02-15 06:10:59 +00:00
break ;
}
return NULL_REG ;
}
2009-02-21 10:47:56 +00:00
reg_t kDrawCel ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
int view = argv [ 0 ] . toSint16 ( ) ;
int loop = argv [ 1 ] . toSint16 ( ) ;
int cel = argv [ 2 ] . toSint16 ( ) ;
int x = argv [ 3 ] . toSint16 ( ) ;
int y = argv [ 4 ] . toSint16 ( ) ;
2009-06-07 16:50:34 +00:00
int priority = ( argc > 5 ) ? argv [ 5 ] . toSint16 ( ) : - 1 ;
2009-04-24 10:46:20 +00:00
GfxView * new_view ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
/*
if ( ! view ) {
2009-05-31 10:02:16 +00:00
error ( " Attempt to draw non-existing view.%03d " , view ) ;
2009-02-19 20:50:55 +00:00
return ;
}
*/
2009-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
if ( gfxop_check_cel ( s - > gfx_state , view , & loop , & cel ) ) {
2009-05-31 10:02:16 +00:00
error ( " Attempt to draw non-existing view.%03d " , view ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " DrawCel((%d,%d), (view.%d, %d, %d), p=%d) \n " , x , y , view , loop , cel , priority ) ;
2009-02-15 06:10:59 +00:00
2009-02-17 19:15:37 +00:00
new_view = gfxw_new_view ( s - > gfx_state , Common : : Point ( x , y ) , view , loop , cel , 0 , priority , - 1 ,
2009-02-15 22:28:12 +00:00
ALIGN_LEFT , ALIGN_TOP , GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET ) ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:48:25 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( new_view ) ;
2009-02-15 06:10:59 +00:00
FULL_REDRAW ( ) ;
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kDisposeWindow ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 15:53:30 +00:00
unsigned int goner_nr = argv [ 0 ] . toSint16 ( ) ;
2009-04-24 10:46:20 +00:00
GfxPort * goner ;
GfxPort * pred ;
2009-02-15 06:10:59 +00:00
2009-06-02 14:16:59 +00:00
goner = s - > visual - > getPort ( goner_nr ) ;
2009-02-15 06:10:59 +00:00
if ( ( goner_nr < 3 ) | | ( goner = = NULL ) ) {
2009-05-31 10:02:16 +00:00
error ( " Removal of invalid window %04x requested " , goner_nr ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-05-30 14:30:39 +00:00
if ( s - > dyn_views & & ( GfxContainer * ) s - > dyn_views - > _parent = = ( GfxContainer * ) goner ) {
2009-04-24 10:46:20 +00:00
reparentize_primary_widget_lists ( s , ( GfxPort * ) goner - > _parent ) ;
2009-02-15 06:10:59 +00:00
}
2009-05-30 14:30:39 +00:00
if ( s - > drop_views & & ( GfxContainer * ) s - > drop_views - > _parent = = ( GfxContainer * ) goner )
2009-02-19 20:50:55 +00:00
s - > drop_views = NULL ; // Kill it
2009-02-15 06:10:59 +00:00
pred = gfxw_remove_port ( s - > visual , goner ) ;
2009-02-19 20:50:55 +00:00
if ( goner = = s - > port ) // Did we kill the active port?
2009-02-15 06:10:59 +00:00
s - > port = pred ;
2009-02-19 20:50:55 +00:00
// Find the last port that exists and that isn't marked no-switch
2009-04-24 10:46:46 +00:00
int id = s - > visual - > _portRefs . size ( ) - 1 ;
while ( id > 0 & & ( ! s - > visual - > _portRefs [ id ] | | ( s - > visual - > _portRefs [ id ] - > _flags & GFXW_FLAG_NO_IMPLICIT_SWITCH ) ) )
2009-02-15 06:10:59 +00:00
id - - ;
2009-07-06 10:39:22 +00:00
debugC ( 2 , kDebugLevelGraphics , " Activating port %d after disposing window %d \n " , id , goner_nr ) ;
2009-04-24 10:46:46 +00:00
s - > port = ( id > = 0 ) ? s - > visual - > _portRefs [ id ] : 0 ;
2009-02-15 06:10:59 +00:00
if ( ! s - > port )
s - > port = gfxw_find_default_port ( s - > visual ) ;
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-21 10:47:56 +00:00
reg_t kNewWindow ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-04-24 10:46:20 +00:00
GfxPort * window ;
2009-02-15 06:10:59 +00:00
int x , y , xl , yl , flags ;
gfx_color_t bgcolor ;
gfx_color_t fgcolor ;
gfx_color_t black ;
2009-02-15 15:06:14 +00:00
gfx_color_t lWhite ;
2009-02-15 06:10:59 +00:00
int priority ;
2009-05-25 13:25:31 +00:00
int argextra = argc = = 13 ? 4 : 0 ; // Triggers in PQ3 and SCI1.1 games
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
y = argv [ 0 ] . toSint16 ( ) ;
x = argv [ 1 ] . toSint16 ( ) ;
yl = argv [ 2 ] . toSint16 ( ) - y ;
xl = argv [ 3 ] . toSint16 ( ) - x ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:45:09 +00:00
y + = s - > wm_port - > _bounds . y ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
if ( x + xl > 319 )
x - = ( ( x + xl ) - 319 ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 15:53:30 +00:00
flags = argv [ 5 + argextra ] . toSint16 ( ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 16:50:34 +00:00
priority = ( argc > 6 + argextra ) ? argv [ 6 + argextra ] . toSint16 ( ) : - 1 ;
2009-02-15 06:10:59 +00:00
bgcolor . mask = 0 ;
2009-06-07 16:50:34 +00:00
int16 bgColor = ( argc > 8 + argextra ) ? argv [ 8 + argextra ] . toSint16 ( ) : 255 ;
if ( bgColor > = 0 ) {
2009-07-07 07:44:25 +00:00
if ( ! s - > resmgr - > isVGA ( ) )
2009-06-07 16:50:34 +00:00
bgcolor . visual = get_pic_color ( s , MIN < int > ( bgColor , 15 ) ) ;
2009-02-15 06:10:59 +00:00
else
2009-06-07 16:50:34 +00:00
bgcolor . visual = get_pic_color ( s , bgColor ) ;
2009-02-15 06:10:59 +00:00
bgcolor . mask = GFX_MASK_VISUAL ;
2009-03-09 20:31:43 +00:00
} else {
bgcolor . visual = PaletteEntry ( 0 , 0 , 0 ) ;
2009-02-15 06:10:59 +00:00
}
bgcolor . priority = priority ;
bgcolor . mask | = priority > = 0 ? GFX_MASK_PRIORITY : 0 ;
bgcolor . alpha = 0 ;
2009-03-09 20:31:43 +00:00
bgcolor . control = - 1 ;
2009-06-07 15:53:30 +00:00
debugC ( 2 , kDebugLevelGraphics , " New window with params %d, %d, %d, %d \n " , argv [ 0 ] . toSint16 ( ) , argv [ 1 ] . toSint16 ( ) , argv [ 2 ] . toSint16 ( ) , argv [ 3 ] . toSint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
2009-06-07 16:50:34 +00:00
int16 visualColor = ( argc > 7 + argextra ) ? argv [ 7 + argextra ] . toSint16 ( ) : 0 ;
fgcolor . visual = get_pic_color ( s , visualColor ) ;
2009-02-15 06:10:59 +00:00
fgcolor . mask = GFX_MASK_VISUAL ;
2009-03-09 20:31:43 +00:00
fgcolor . control = - 1 ;
fgcolor . priority = - 1 ;
2009-02-15 06:10:59 +00:00
fgcolor . alpha = 0 ;
2009-03-08 20:17:01 +00:00
black . visual = get_pic_color ( s , 0 ) ;
2009-02-15 06:10:59 +00:00
black . mask = GFX_MASK_VISUAL ;
black . alpha = 0 ;
2009-03-09 20:31:43 +00:00
black . control = - 1 ;
black . priority = - 1 ;
2009-07-07 07:44:25 +00:00
lWhite . visual = get_pic_color ( s , ! s - > resmgr - > isVGA ( ) ? 15 : 255 ) ;
2009-03-08 20:17:01 +00:00
lWhite . mask = GFX_MASK_VISUAL ;
2009-02-15 15:06:14 +00:00
lWhite . alpha = 0 ;
2009-03-09 20:31:43 +00:00
lWhite . priority = - 1 ;
lWhite . control = - 1 ;
2009-06-24 19:12:45 +00:00
const char * title = argv [ 4 + argextra ] . segment ? kernel_dereference_char_pointer ( s , argv [ 4 + argextra ] , 0 ) : NULL ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:47:38 +00:00
window = sciw_new_window ( s , gfx_rect ( x , y , xl , yl ) , s - > titlebar_port - > _font , fgcolor , bgcolor ,
2009-06-24 19:12:45 +00:00
s - > titlebar_port - > _font , lWhite , black , title ? s - > strSplit ( title , NULL ) . c_str ( ) : NULL , flags ) ;
2009-02-15 06:10:59 +00:00
2009-05-25 13:25:31 +00:00
// PQ3 and SCI1.1 games have the interpreter store underBits implicitly
2009-02-15 06:10:59 +00:00
if ( argextra )
2009-06-07 15:53:30 +00:00
gfxw_port_auto_restore_background ( s - > visual , window , gfx_rect ( argv [ 5 ] . toSint16 ( ) , argv [ 4 ] . toSint16 ( ) , argv [ 7 ] . toSint16 ( ) - argv [ 5 ] . toSint16 ( ) , argv [ 6 ] . toSint16 ( ) - argv [ 4 ] . toSint16 ( ) ) ) ;
2009-02-15 06:10:59 +00:00
ADD_TO_WINDOW_PORT ( window ) ;
FULL_REDRAW ( ) ;
2009-04-24 14:22:14 +00:00
window - > draw ( gfxw_point_zero ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
s - > port = window ; // Set active port
2009-02-15 06:10:59 +00:00
2009-04-24 10:45:09 +00:00
return make_reg ( 0 , window - > _ID ) ;
2009-02-15 06:10:59 +00:00
}
2009-02-19 20:50:55 +00:00
# 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
2009-03-29 14:47:57 +00:00
# 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
2009-02-15 06:10:59 +00:00
# define GRAPH_BLANK_BOX(s, x, y, xl, yl, color) GFX_ASSERT(gfxop_fill_box(s->gfx_state, \
2009-02-22 13:11:43 +00:00
gfx_rect ( x , ( ( ( y ) < 10 ) ? 10 : ( y ) ) , xl , ( ( ( y ) < 10 ) ? ( ( y ) - 10 ) : 0 ) + ( yl ) ) , s - > ega_colors [ color ] ) ) ;
2009-02-15 06:10:59 +00:00
# define GRAPH_UPDATE_BOX(s, x, y, xl, yl) GFX_ASSERT(gfxop_draw_pixmap(s->gfx_state, newscreen, \
2009-02-22 13:11:43 +00:00
gfx_rect ( x , ( ( ( y ) < 10 ) ? 10 : ( y ) ) - 10 , xl , ( ( ( y ) < 10 ) ? ( ( y ) - 10 ) : 0 ) + ( yl ) ) , Common : : Point ( x , ( ( y ) < 10 ) ? 10 : ( y ) ) ) ) ;
2009-02-15 06:10:59 +00:00
2009-02-21 10:47:56 +00:00
static void animate_do_animation ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-02 07:59:04 +00:00
long animation_delay = 5 ;
2009-02-15 06:10:59 +00:00
int i , remaining_checkers ;
int update_counter ;
int granularity0 = s - > animation_granularity < < 1 ;
int granularity1 = s - > animation_granularity ;
int granularity2 = s - > animation_granularity > > 2 ;
int granularity3 = s - > 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 ) {
2009-05-31 10:02:16 +00:00
error ( " Failed to allocate 'newscreen' " ) ;
2009-02-15 06:10:59 +00:00
return ;
}
2009-02-17 19:15:37 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen , gfx_rect ( 0 , 0 , 320 , 190 ) , Common : : Point ( 0 , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update_box ( s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 200 ) ) ;
2009-05-30 15:40:49 +00:00
//debugC(2, kDebugLevelGraphics, "Animating pic opening type %x\n", s->pic_animate);
2009-02-15 06:10:59 +00:00
gfxop_enable_dirty_frames ( s - > gfx_state ) ;
2009-02-15 22:28:12 +00:00
switch ( s - > pic_animate ) {
2009-02-15 06:10:59 +00:00
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 ) ;
2009-02-15 22:28:12 +00:00
GRAPH_BLANK_BOX ( s , 319 - i , 10 , granularity1 , 190 , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
GRAPH_BLANK_BOX ( s , 0 , 10 , 320 , 190 , 0 ) ;
case K_ANIMATE_CENTER_OPEN_H :
2009-02-15 22:28:12 +00:00
for ( i = 159 ; i > = 1 - granularity1 ; i - = granularity1 ) {
2009-02-15 06:10:59 +00:00
GRAPH_UPDATE_BOX ( s , i , 10 , granularity1 , 190 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-02-15 22:28:12 +00:00
GRAPH_UPDATE_BOX ( s , 319 - i , 10 , granularity1 , 190 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
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 ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , 2 * animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
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 ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , 2 * animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN :
2009-02-15 22:28:12 +00:00
for ( i = 0 ; i < 319 + granularity0 ; i + = granularity0 ) {
2009-02-15 06:10:59 +00:00
GRAPH_BLANK_BOX ( s , i , 10 , granularity0 , 190 , 0 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 2 / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
GRAPH_BLANK_BOX ( s , 0 , 10 , 320 , 190 , 0 ) ;
case K_ANIMATE_RIGHT_OPEN :
2009-02-15 22:28:12 +00:00
for ( i = 319 ; i > = 1 - granularity0 ; i - = granularity0 ) {
2009-02-15 06:10:59 +00:00
GRAPH_UPDATE_BOX ( s , i , 10 , granularity0 , 190 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 2 / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN :
2009-02-15 22:28:12 +00:00
for ( i = 319 ; i > = 1 - granularity0 ; i - = granularity0 ) {
2009-02-15 06:10:59 +00:00
GRAPH_BLANK_BOX ( s , i , 10 , granularity0 , 190 , 0 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 2 / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
GRAPH_BLANK_BOX ( s , 0 , 10 , 320 , 190 , 0 ) ;
case K_ANIMATE_LEFT_OPEN :
2009-02-15 22:28:12 +00:00
for ( i = 0 ; i < 319 + granularity0 ; i + = granularity0 ) {
2009-02-15 06:10:59 +00:00
GRAPH_UPDATE_BOX ( s , i , 10 , granularity0 , 190 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 2 / 1000 ) ;
2009-02-15 06:10:59 +00:00
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 ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
GRAPH_BLANK_BOX ( s , 0 , 10 , 320 , 190 , 0 ) ;
case K_ANIMATE_BOTTOM_OPEN :
2009-02-15 22:28:12 +00:00
for ( i = 199 ; i > = 11 - granularity1 ; i - = granularity1 ) {
2009-02-15 06:10:59 +00:00
GRAPH_UPDATE_BOX ( s , 0 , i , 320 , granularity1 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN :
2009-02-15 22:28:12 +00:00
for ( i = 199 ; i > = 11 - granularity1 ; i - = granularity1 ) {
2009-02-15 06:10:59 +00:00
GRAPH_BLANK_BOX ( s , 0 , i , 320 , granularity1 , 0 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
GRAPH_BLANK_BOX ( s , 0 , 10 , 320 , 190 , 0 ) ;
case K_ANIMATE_TOP_OPEN :
2009-02-15 22:28:12 +00:00
for ( i = 10 ; i < 199 + granularity1 ; i + = granularity1 ) {
2009-02-15 06:10:59 +00:00
GRAPH_UPDATE_BOX ( s , 0 , i , 320 , granularity1 ) ;
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F :
2009-02-15 22:28:12 +00:00
for ( i = 31 ; i > = 1 - granularity3 ; i - = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
2009-02-15 06:10:59 +00:00
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 ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , width , 10 + height , 320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , width , 200 - height_l - height , 320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , 4 * animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
case K_ANIMATE_BORDER_OPEN_F :
2009-02-15 22:28:12 +00:00
for ( i = 0 ; i < 31 + granularity3 ; i + = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
2009-02-15 06:10:59 +00:00
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 ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , width , 10 + height , width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , width , 10 + height , 320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , width , 200 - height_l - height , 320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , 4 * animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F :
2009-02-15 22:28:12 +00:00
for ( i = 0 ; i < 31 + granularity3 ; i + = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
2009-02-15 06:10:59 +00:00
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 ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , width , 10 + height , 320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_BLANK_BOX ( s , width , 200 - height_l - height , 320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , 7 * animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
case K_ANIMATE_CENTER_OPEN_F :
2009-02-15 22:28:12 +00:00
for ( i = 31 ; i > = 1 - granularity3 ; i - = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
2009-02-15 06:10:59 +00:00
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 ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , width , 10 + height , width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , width , 10 + height , 320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-19 20:50:55 +00:00
GRAPH_UPDATE_BOX ( s , width , 200 - height_l - height , 320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , 7 * animation_delay / 1000 ) ;
2009-02-15 06:10:59 +00:00
process_sound_events ( s ) ;
}
break ;
2009-03-29 14:47:57 +00:00
case K_ANIMATE_PALETTE_FADEOUT_FADEIN :
warning ( " TODO: Palette fadeout/fadein " ) ;
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
2009-02-15 06:10:59 +00:00
case K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS :
memset ( checkers , 0 , sizeof ( checkers ) ) ;
remaining_checkers = 19 * 32 ;
update_counter = granularity1 ;
while ( remaining_checkers ) {
2009-02-15 22:28:12 +00:00
int x , y , checker = 1 + ( int ) ( 1.0 * remaining_checkers * rand ( ) / ( RAND_MAX + 1.0 ) ) ;
2009-02-15 06:10:59 +00:00
i = - 1 ;
while ( checker )
2009-02-19 20:50:55 +00:00
if ( checkers [ + + i ] = = 0 )
- - checker ;
checkers [ i ] = 1 ; // Mark checker as used
2009-02-15 06:10:59 +00:00
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 ) {
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 4 / 1000 ) ;
2009-02-15 06:10:59 +00:00
}
- - 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 ) {
2009-02-15 22:28:12 +00:00
int x , y , checker = 1 + ( int ) ( 1.0 * remaining_checkers * rand ( ) / ( RAND_MAX + 1.0 ) ) ;
2009-02-15 06:10:59 +00:00
i = - 1 ;
while ( checker )
if ( checkers [ + + i ] = = 0 ) - - checker ;
2009-02-19 20:50:55 +00:00
checkers [ i ] = 1 ; // Mark checker as used
2009-02-15 06:10:59 +00:00
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 ) {
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , animation_delay / 4 / 1000 ) ;
2009-02-15 06:10:59 +00:00
}
- - remaining_checkers ;
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_SCROLL_LEFT :
for ( i = 0 ; i < 319 ; i + = granularity0 ) {
2009-02-19 20:50:55 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen , gfx_rect ( 320 - i , 0 , i , 190 ) , Common : : Point ( 0 , 10 ) ) ) ;
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen , gfx_rect ( 0 , 0 , 320 - i , 190 ) , Common : : Point ( i , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-02-15 06:10:59 +00:00
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
case K_ANIMATE_SCROLL_RIGHT :
for ( i = 0 ; i < 319 ; i + = granularity0 ) {
2009-02-19 20:50:55 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen , gfx_rect ( 0 , 0 , i , 190 ) , Common : : Point ( 319 - i , 10 ) ) ) ;
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen , gfx_rect ( i , 0 , 320 - i , 190 ) , Common : : Point ( 0 , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-02-15 06:10:59 +00:00
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
case K_ANIMATE_SCROLL_UP :
for ( i = 0 ; i < 189 ; i + = granularity0 ) {
2009-02-19 20:50:55 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen , gfx_rect ( 0 , 190 - i , 320 , i ) , Common : : Point ( 0 , 10 ) ) ) ;
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen , gfx_rect ( 0 , 0 , 320 , 190 - i ) , Common : : Point ( 0 , 10 + i ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-02-15 06:10:59 +00:00
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
case K_ANIMATE_SCROLL_DOWN :
for ( i = 0 ; i < 189 ; i + = granularity0 ) {
2009-02-19 20:50:55 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen , gfx_rect ( 0 , 0 , 320 , i ) , Common : : Point ( 0 , 200 - i ) ) ) ;
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen , gfx_rect ( 0 , i , 320 , 190 - i ) , Common : : Point ( 0 , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-06-02 07:59:04 +00:00
gfxop_sleep ( s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-02-15 06:10:59 +00:00
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
default :
2009-06-02 07:59:04 +00:00
warning ( " Unknown opening animation 0x%02x " , s - > pic_animate ) ;
2009-02-15 06:10:59 +00:00
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
}
GFX_ASSERT ( gfxop_free_pixmap ( s - > gfx_state , s - > old_screen ) ) ;
GFX_ASSERT ( gfxop_free_pixmap ( s - > gfx_state , newscreen ) ) ;
s - > old_screen = NULL ;
}
2009-02-21 10:47:56 +00:00
reg_t kAnimate ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-02 07:59:04 +00:00
// Animations are supposed to take a maximum of animation_delay milliseconds.
2009-06-07 16:50:34 +00:00
reg_t cast_list_ref = ( argc > 0 ) ? argv [ 0 ] : NULL_REG ;
int cycle = ( argc > 1 ) ? argv [ 1 ] . toUint16 ( ) : 0 ;
2009-02-28 11:12:59 +00:00
List * cast_list = NULL ;
2009-02-15 06:10:59 +00:00
int open_animation = 0 ;
2009-02-19 20:50:55 +00:00
process_sound_events ( s ) ; // Take care of incoming events (kAnimate is called semi-regularly)
2009-05-26 11:30:21 +00:00
_k_animate_ran = true ; // Used by some of the invoked functions to check for recursion, which may,
2009-02-19 20:50:55 +00:00
// after all, damage the cast list
2009-02-15 06:10:59 +00:00
if ( cast_list_ref . segment ) {
2009-05-18 08:28:04 +00:00
cast_list = lookup_list ( s , cast_list_ref ) ;
2009-02-15 06:10:59 +00:00
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 ) ;
2009-04-24 14:20:31 +00:00
if ( ! s - > dyn_views - > _contents // Only reparentize empty dynview list
2009-05-30 14:30:39 +00:00
& & ( ( ( GfxContainer * ) s - > port ! = ( GfxContainer * ) s - > dyn_views - > _parent ) // If dynviews are on other port...
2009-04-24 10:45:09 +00:00
| | ( s - > dyn_views - > _next ) ) ) // ... or not on top of the view list
2009-02-15 06:10:59 +00:00
reparentize_primary_widget_lists ( s , s - > port ) ;
if ( cast_list ) {
2009-04-24 10:46:20 +00:00
GfxList * templist = gfxw_new_list ( s - > dyn_views - > _bounds , 0 ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
_k_make_view_list ( s , & ( templist ) , cast_list , ( cycle ? _K_MAKE_VIEW_LIST_CYCLE : 0 )
| _K_MAKE_VIEW_LIST_CALC_PRIORITY , funct_nr , argc , argv ) ;
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
// Make sure that none of the doits() did something evil
2009-02-15 06:10:59 +00:00
assert_primary_widget_lists ( s ) ;
2009-04-24 14:20:31 +00:00
if ( ! s - > dyn_views - > _contents // Only reparentize empty dynview list
2009-05-30 14:30:39 +00:00
& & ( ( ( GfxContainer * ) s - > port ! = ( GfxContainer * ) s - > dyn_views - > _parent ) // If dynviews are on other port...
2009-04-24 10:45:09 +00:00
| | ( s - > dyn_views - > _next ) ) ) // ... or not on top of the view list
2009-02-15 06:10:59 +00:00
reparentize_primary_widget_lists ( s , s - > port ) ;
2009-02-19 20:50:55 +00:00
// End of doit() recovery code
2009-02-15 06:10:59 +00:00
2009-02-19 20:50:55 +00:00
if ( s - > pic_is_new ) { // Happens if DrawPic() is executed by a dynview (yes, that happens)
2009-02-15 06:10:59 +00:00
kAnimate ( s , funct_nr , argc , argv ) ; /* Tail-recurse */
return s - > r_acc ;
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Handling Dynviews (..step 9 inclusive): \n " ) ;
2009-02-15 06:10:59 +00:00
_k_prepare_view_list ( s , templist , _K_MAKE_VIEW_LIST_CALC_PRIORITY ) ;
if ( s - > pic_not_valid ) {
2009-05-30 17:30:54 +00:00
debugC ( 2 , kDebugLevelGraphics , " PicNotValid=%d -> Subalgorithm: \n " , s - > pic_not_valid ) ;
2009-02-15 06:10:59 +00:00
_k_redraw_view_list ( s , templist ) ;
}
_k_update_signals_in_view_list ( s - > dyn_views , templist ) ;
2009-04-24 14:21:16 +00:00
s - > dyn_views - > tag ( ) ;
2009-02-15 06:10:59 +00:00
2009-04-24 14:20:31 +00:00
_k_raise_topmost_in_view_list ( s , s - > dyn_views , ( GfxDynView * ) templist - > _contents ) ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:48:25 +00:00
delete templist ;
2009-05-30 14:30:39 +00:00
s - > dyn_views - > free_tagged ( ( GfxContainer * ) s - > dyn_views ) ; // Free obsolete dynviews
2009-02-19 20:50:55 +00:00
} // if (cast_list)
2009-02-15 06:10:59 +00:00
if ( open_animation ) {
2009-02-19 20:50:55 +00:00
gfxop_clear_box ( s - > gfx_state , gfx_rect ( 0 , 10 , 320 , 190 ) ) ; // Propagate pic
2009-05-30 14:30:39 +00:00
s - > visual - > add_dirty_abs ( ( GfxContainer * ) s - > visual , gfx_rect_fullscreen , 0 ) ;
2009-02-19 20:50:55 +00:00
// Mark screen as dirty so picviews will be drawn correctly
2009-02-15 06:10:59 +00:00
FULL_REDRAW ( ) ;
animate_do_animation ( s , funct_nr , argc , argv ) ;
2009-02-19 20:50:55 +00:00
} // if (open_animation)
2009-02-15 06:10:59 +00:00
if ( cast_list ) {
int retval ;
int reparentize = 0 ;
s - > pic_not_valid = 0 ;
_k_view_list_do_postdraw ( s , s - > dyn_views ) ;
2009-02-19 20:50:55 +00:00
// _k_view_list_dispose_loop() returns -1 if it requested a re-start, so we do just that.
2009-04-24 14:20:31 +00:00
while ( ( retval = _k_view_list_dispose_loop ( s , cast_list , ( GfxDynView * ) s - > dyn_views - > _contents , funct_nr , argc , argv ) < 0 ) )
2009-02-15 06:10:59 +00:00
reparentize = 1 ;
2009-04-24 14:20:31 +00:00
if ( s - > drop_views - > _contents ) {
2009-04-24 10:45:09 +00:00
s - > drop_views = gfxw_new_list ( s - > dyn_views - > _bounds , GFXW_LIST_SORTED ) ;
s - > drop_views - > _flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
2009-02-15 06:10:59 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( s - > drop_views ) ;
} else {
assert ( s - > drop_views ) ;
2009-04-24 10:48:25 +00:00
gfxw_remove_widget_from_container ( s - > drop_views - > _parent , s - > drop_views ) ;
2009-02-15 06:10:59 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( s - > drop_views ) ;
}
if ( ( reparentize | retval )
2009-05-30 14:30:39 +00:00
& & ( ( GfxContainer * ) s - > port = = ( GfxContainer * ) s - > dyn_views - > _parent ) // If dynviews are on the same port...
2009-04-24 10:45:09 +00:00
& & ( s - > dyn_views - > _next ) ) // ... and not on top of the view list...
2009-02-19 20:50:55 +00:00
reparentize_primary_widget_lists ( s , s - > port ) ; // ...then reparentize.
2009-02-15 06:10:59 +00:00
2009-04-24 14:20:31 +00:00
_k_view_list_kryptonize ( s - > dyn_views - > _contents ) ;
2009-02-15 06:10:59 +00:00
}
FULL_REDRAW ( ) ;
return s - > r_acc ;
}
# define SHAKE_DOWN 1
# define SHAKE_RIGHT 2
2009-02-21 10:47:56 +00:00
reg_t kShakeScreen ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-06-07 16:50:34 +00:00
int shakes = ( argc > 0 ) ? argv [ 0 ] . toSint16 ( ) : 1 ;
int directions = ( argc > 1 ) ? argv [ 1 ] . toSint16 ( ) : 1 ;
2009-02-15 06:10:59 +00:00
gfx_pixmap_t * screen = gfxop_grab_pixmap ( s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 200 ) ) ;
int i ;
if ( directions & ~ 3 )
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " ShakeScreen(): Direction bits are %x (unknown) \n " , directions ) ;
2009-02-15 06:10:59 +00:00
gfxop_set_clip_zone ( s - > gfx_state , gfx_rect_fullscreen ) ;
for ( i = 0 ; i < shakes ; i + + ) {
2009-02-15 22:28:12 +00:00
int shake_down = ( directions & SHAKE_DOWN ) ? 10 : 0 ;
int shake_right = ( directions & SHAKE_RIGHT ) ? 10 : 0 ;
2009-02-15 06:10:59 +00:00
if ( directions & SHAKE_DOWN )
gfxop_draw_box ( s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 10 ) , s - > ega_colors [ 0 ] , s - > ega_colors [ 0 ] , GFX_BOX_SHADE_FLAT ) ;
if ( directions & SHAKE_RIGHT )
gfxop_draw_box ( s - > gfx_state , gfx_rect ( 0 , 0 , 10 , 200 ) , s - > ega_colors [ 0 ] , s - > ega_colors [ 0 ] , GFX_BOX_SHADE_FLAT ) ;
gfxop_draw_pixmap ( s - > gfx_state , screen , gfx_rect ( 0 , 0 , 320 - shake_right , 200 - shake_down ) ,
2009-02-17 19:15:37 +00:00
Common : : Point ( shake_right , shake_down ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-24 20:50:09 +00:00
gfxop_sleep ( s - > gfx_state , 50 ) ;
2009-02-15 06:10:59 +00:00
2009-02-17 19:15:37 +00:00
gfxop_draw_pixmap ( s - > gfx_state , screen , gfx_rect ( 0 , 0 , 320 , 200 ) , Common : : Point ( 0 , 0 ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
2009-02-24 20:50:09 +00:00
gfxop_sleep ( s - > gfx_state , 50 ) ;
2009-02-15 06:10:59 +00:00
}
gfxop_free_pixmap ( s - > gfx_state , screen ) ;
gfxop_update ( s - > gfx_state ) ;
return s - > r_acc ;
}
# define K_DISPLAY_SET_COORDS 100
# define K_DISPLAY_SET_ALIGNMENT 101
# define K_DISPLAY_SET_COLOR 102
# define K_DISPLAY_SET_BGCOLOR 103
# define K_DISPLAY_SET_GRAYTEXT 104
# define K_DISPLAY_SET_FONT 105
# define K_DISPLAY_WIDTH 106
# define K_DISPLAY_SAVE_UNDER 107
# define K_DISPLAY_RESTORE_UNDER 108
# define K_DONT_UPDATE_IMMEDIATELY 121
2009-02-21 10:47:56 +00:00
reg_t kDisplay ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int argpt ;
reg_t textp = argv [ 0 ] ;
2009-06-07 16:50:34 +00:00
int index = ( argc > 1 ) ? argv [ 1 ] . toUint16 ( ) : 0 ;
2009-02-15 06:10:59 +00:00
int temp ;
2009-03-03 14:27:49 +00:00
bool save_under = false ;
2009-03-08 20:17:01 +00:00
gfx_color_t transparent = { PaletteEntry ( ) , 0 , - 1 , - 1 , 0 } ;
2009-02-15 06:10:59 +00:00
char * text ;
2009-04-24 10:46:20 +00:00
GfxPort * port = ( s - > port ) ? s - > port : s - > picture_port ;
2009-03-03 14:27:49 +00:00
bool update_immediately = true ;
2009-02-15 06:10:59 +00:00
gfx_color_t color0 , * color1 , bg_color ;
gfx_alignment_t halign = ALIGN_LEFT ;
2009-02-19 20:50:55 +00:00
rect_t area = gfx_rect ( port - > draw_pos . x , port - > draw_pos . y , 320 - port - > draw_pos . x , 200 - port - > draw_pos . y ) ;
2009-02-15 06:10:59 +00:00
int gray = port - > gray_text ;
2009-04-24 10:47:38 +00:00
int font_nr = port - > _font ;
2009-04-24 10:46:20 +00:00
GfxText * text_handle ;
2009-02-15 06:10:59 +00:00
2009-04-24 10:45:09 +00:00
color0 = port - > _color ;
bg_color = port - > _bgcolor ;
2009-03-03 14:27:49 +00:00
// TODO: in SCI1VGA the default colors for text and background are #0 (black)
2009-05-20 17:53:31 +00:00
// SCI0 case should be checked
2009-07-07 07:44:25 +00:00
if ( s - > resmgr - > isVGA ( ) ) {
2009-03-29 12:28:24 +00:00
// This priority check fixes the colors in the menus in KQ5
// TODO/FIXME: Is this correct?
if ( color0 . priority > = 0 )
color0 . visual = get_pic_color ( s , 0 ) ;
if ( bg_color . priority > = 0 )
bg_color . visual = get_pic_color ( s , 0 ) ;
2009-03-03 14:27:49 +00:00
}
2009-02-15 06:10:59 +00:00
if ( textp . segment ) {
argpt = 1 ;
2009-02-19 20:50:55 +00:00
text = ( char * ) kernel_dereference_bulk_pointer ( s , textp , 0 ) ;
2009-02-15 06:10:59 +00:00
} else {
argpt = 2 ;
text = kernel_lookup_text ( s , textp , index ) ;
}
if ( ! text ) {
2009-05-31 10:02:16 +00:00
error ( " Display with invalid reference %04x:%04x " , PRINT_REG ( textp ) ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
}
while ( argpt < argc ) {
2009-06-07 15:53:30 +00:00
switch ( argv [ argpt + + ] . toUint16 ( ) ) {
2009-02-15 06:10:59 +00:00
case K_DISPLAY_SET_COORDS :
2009-06-07 15:53:30 +00:00
area . x = argv [ argpt + + ] . toUint16 ( ) ;
area . y = argv [ argpt + + ] . toUint16 ( ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_coords(%d, %d) \n " , area . x , area . y ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_SET_ALIGNMENT :
2009-06-07 15:53:30 +00:00
halign = ( gfx_alignment_t ) argv [ argpt + + ] . toSint16 ( ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_align(%d) \n " , halign ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_SET_COLOR :
2009-06-07 15:53:30 +00:00
temp = argv [ argpt + + ] . toSint16 ( ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_color(%d) \n " , temp ) ;
2009-07-07 07:44:25 +00:00
if ( ! s - > resmgr - > isVGA ( ) & & temp > = 0 & & temp < = 15 )
2009-02-15 06:10:59 +00:00
color0 = ( s - > ega_colors [ temp ] ) ;
2009-02-15 22:28:12 +00:00
else
2009-07-07 07:44:25 +00:00
if ( s - > resmgr - > isVGA ( ) & & temp > = 0 & & temp < 256 ) {
2009-03-08 20:17:01 +00:00
color0 . visual = get_pic_color ( s , temp ) ;
2009-02-15 06:10:59 +00:00
color0 . mask = GFX_MASK_VISUAL ;
} else
if ( temp = = - 1 )
color0 = transparent ;
else
2009-02-20 20:11:12 +00:00
warning ( " Display: Attempt to set invalid fg color %d " , temp ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_SET_BGCOLOR :
2009-06-07 15:53:30 +00:00
temp = argv [ argpt + + ] . toSint16 ( ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_bg_color(%d) \n " , temp ) ;
2009-07-07 07:44:25 +00:00
if ( ! s - > resmgr - > isVGA ( ) & & temp > = 0 & & temp < = 15 )
2009-02-15 06:10:59 +00:00
bg_color = s - > ega_colors [ temp ] ;
2009-02-15 22:28:12 +00:00
else
2009-07-07 07:44:25 +00:00
if ( s - > resmgr - > isVGA ( ) & & temp > = 0 & & temp < = 256 ) {
2009-03-08 20:17:01 +00:00
bg_color . visual = get_pic_color ( s , temp ) ;
2009-02-15 06:10:59 +00:00
bg_color . mask = GFX_MASK_VISUAL ;
} else
if ( temp = = - 1 )
bg_color = transparent ;
else
2009-02-20 20:11:12 +00:00
warning ( " Display: Attempt to set invalid fg color %d " , temp ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_SET_GRAYTEXT :
2009-06-07 15:53:30 +00:00
gray = argv [ argpt + + ] . toSint16 ( ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_graytext(%d) \n " , gray ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_SET_FONT :
2009-06-07 15:53:30 +00:00
font_nr = argv [ argpt + + ] . toUint16 ( ) ;
2009-02-15 22:28:12 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_font( \" font.%03d \" ) \n " , font_nr ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_WIDTH :
2009-06-07 15:53:30 +00:00
area . width = argv [ argpt + + ] . toUint16 ( ) ;
2009-03-16 00:07:12 +00:00
if ( area . width = = 0 )
area . width = MAX_TEXT_WIDTH_MAGIC_VALUE ;
2009-02-15 06:10:59 +00:00
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_width(%d) \n " , area . width ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_SAVE_UNDER :
2009-03-03 14:27:49 +00:00
save_under = true ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_save_under() \n " ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_DISPLAY_RESTORE_UNDER :
2009-06-07 15:53:30 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: restore_under(%04x) \n " , argv [ argpt ] . toUint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
graph_restore_box ( s , argv [ argpt + + ] ) ;
2009-03-03 14:27:49 +00:00
update_immediately = true ;
2009-02-15 06:10:59 +00:00
argpt + + ;
return s - > r_acc ;
case K_DONT_UPDATE_IMMEDIATELY :
2009-03-03 14:27:49 +00:00
update_immediately = false ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: set_dont_update() \n " ) ;
2009-02-15 06:10:59 +00:00
argpt + + ;
break ;
default :
2009-06-07 15:53:30 +00:00
debugC ( 2 , kDebugLevelGraphics , " Unknown Display() command %x \n " , argv [ argpt - 1 ] . toUint16 ( ) ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
}
}
2009-05-25 16:30:39 +00:00
if ( halign = = ALIGN_LEFT ) {
// If the text does not fit on the screen, move it to the left and upwards until it does
2009-05-14 07:28:06 +00:00
GFX_ASSERT ( gfxop_get_text_params ( s - > gfx_state , font_nr , text , area . width , & area . width , & area . height , 0 , NULL , NULL , NULL ) ) ;
2009-02-15 06:10:59 +00:00
2009-05-25 16:30:39 +00:00
// Make the text fit on the screen
if ( area . x + area . width > 320 )
area . x + = 320 - area . x - area . width ; // Plus negative number = subtraction
2009-02-15 06:10:59 +00:00
2009-05-25 16:30:39 +00:00
if ( area . y + area . height > 200 )
area . y + = 200 - area . y - area . height ; // Plus negative number = subtraction
} else {
// If the text does not fit on the screen, clip it till it does
if ( area . x + area . width > s - > gfx_state - > pic_port_bounds . width )
area . width = s - > gfx_state - > pic_port_bounds . width - area . x ;
2009-05-23 11:56:27 +00:00
2009-05-25 16:30:39 +00:00
if ( area . y + area . height > s - > gfx_state - > pic_port_bounds . height )
area . height = s - > gfx_state - > pic_port_bounds . height - area . y ;
2009-05-23 12:08:36 +00:00
}
2009-02-15 06:10:59 +00:00
if ( gray )
color1 = & bg_color ;
else
color1 = & color0 ;
assert_primary_widget_lists ( s ) ;
2009-06-24 19:12:45 +00:00
text_handle = gfxw_new_text ( s - > gfx_state , area , font_nr , s - > strSplit ( text ) . c_str ( ) , halign , ALIGN_TOP , color0 , * color1 , bg_color , 0 ) ;
2009-02-15 06:10:59 +00:00
if ( ! text_handle ) {
2009-05-31 10:02:16 +00:00
error ( " Display: Failed to create text widget " ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
}
2009-02-19 20:50:55 +00:00
if ( save_under ) { // Backup
2009-04-24 10:45:09 +00:00
rect_t save_area = text_handle - > _bounds ;
save_area . x + = port - > _bounds . x ;
save_area . y + = port - > _bounds . y ;
2009-02-15 06:10:59 +00:00
s - > r_acc = graph_save_box ( s , save_area ) ;
2009-04-24 10:45:09 +00:00
text_handle - > _serial + + ; // This is evil!
2009-02-15 06:10:59 +00:00
2009-05-30 17:30:54 +00:00
debugC ( 2 , kDebugLevelGraphics , " Saving (%d, %d) size (%d, %d) as %04x:%04x \n " , save_area . x , save_area . y , save_area . width , save_area . height , PRINT_REG ( s - > r_acc ) ) ;
2009-02-15 06:10:59 +00:00
}
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Display: Commiting text '%s' \n " , text ) ;
2009-02-15 06:10:59 +00:00
2009-04-21 21:37:03 +00:00
//ADD_TO_CURRENT_PICTURE_PORT(text_handle);
2009-02-15 06:10:59 +00:00
2009-04-24 10:48:25 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( text_handle ) ;
2009-02-19 20:50:55 +00:00
if ( ( ! s - > pic_not_valid ) & & update_immediately ) { // Refresh if drawn to valid picture
2009-02-15 06:10:59 +00:00
FULL_REDRAW ( ) ;
2009-05-30 15:40:49 +00:00
debugC ( 2 , kDebugLevelGraphics , " Refreshing display... \n " ) ;
2009-02-15 06:10:59 +00:00
}
return s - > r_acc ;
}
2009-02-21 10:23:36 +00:00
2009-05-21 22:03:23 +00:00
reg_t kShowMovie ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
const char * filename = kernel_dereference_char_pointer ( s , argv [ 0 ] , 0 ) ;
2009-06-07 15:53:30 +00:00
int framerate = argv [ 1 ] . toUint16 ( ) ; // FIXME: verify
2009-05-25 11:14:42 +00:00
int frameNr = 0 ;
2009-05-21 22:03:23 +00:00
SeqDecoder seq ;
2009-05-26 00:03:41 +00:00
if ( ! seq . loadFile ( filename ) & & ! seq . loadFile ( Common : : String ( " SEQ/ " ) + filename ) ) {
2009-05-21 22:03:23 +00:00
warning ( " Failed to open movie file %s " , filename ) ;
return s - > r_acc ;
}
bool play = true ;
while ( play ) {
gfx_pixmap_t * pixmap = seq . getFrame ( play ) ;
2009-05-25 11:14:42 +00:00
if ( frameNr + + = = 0 )
2009-06-06 10:21:48 +00:00
pixmap - > palette - > forceInto ( s - > gfx_state - > driver - > getMode ( ) - > palette ) ;
2009-05-25 11:14:42 +00:00
2009-06-06 10:21:48 +00:00
gfx_xlate_pixmap ( pixmap , s - > gfx_state - > driver - > getMode ( ) , GFX_XLATE_FILTER_NONE ) ;
2009-05-21 22:03:23 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , pixmap , gfx_rect ( 0 , 0 , 320 , 200 ) , Common : : Point ( pixmap - > xoffset , pixmap - > yoffset ) ) ) ;
gfxop_update_box ( s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 200 ) ) ;
gfx_free_pixmap ( pixmap ) ;
uint32 startTime = g_system - > getMillis ( ) ;
// Wait before showing the next frame
while ( play & & ( g_system - > getMillis ( ) < startTime + 1000 / framerate ) ) {
// FIXME: we should probably make a function that handles quitting in these kinds of situations
Common : : Event curEvent ;
Common : : EventManager * eventMan = g_system - > getEventManager ( ) ;
// Process quit events
while ( eventMan - > pollEvent ( curEvent ) ) {
if ( curEvent . type = = Common : : EVENT_QUIT ) {
play = false ;
quit_vm ( ) ;
}
}
g_system - > delayMillis ( 10 ) ;
}
}
return s - > r_acc ;
}
2009-05-23 13:26:45 +00:00
reg_t kSetVideoMode ( EngineState * s , int funct_nr , int argc , reg_t * argv ) {
// This call is used for KQ6's intro. It has one parameter, which is
// 1 when the intro begins, and 0 when it ends. It is suspected that
// this is actually a flag to enable video planar memory access, as
// the video decoder in KQ6 is specifically written for the planar
// memory model. Planar memory mode access was used for VGA "Mode X"
// (320x240 resolution, although the intro in KQ6 is 320x200).
// Refer to http://en.wikipedia.org/wiki/Mode_X
2009-06-07 15:53:30 +00:00
warning ( " STUB: SetVideoMode %d " , argv [ 0 ] . toUint16 ( ) ) ;
2009-05-23 13:26:45 +00:00
return s - > r_acc ;
}
2009-02-21 10:23:36 +00:00
} // End of namespace Sci