2009-02-15 06:10:59 +00:00
/***************************************************************************
kgraphics . c Copyright ( C ) 1999 , 2000. .04 Christoph Reichenbach
This program may be modified and copied freely according to the terms of
the GNU general public license ( GPL ) , as long as the above copyright
notice and the licensing information contained herein are preserved .
Please refer to www . gnu . org for licensing details .
This work is provided AS IS , without warranty of any kind , expressed or
implied , including but not limited to the warranties of merchantibility ,
noninfringement , and fitness for a specific purpose . The author will not
be held liable for any damage caused by this work or derivatives of it .
By using this source code , you agree to the licensing terms as stated
above .
Please contact the maintainer for bug reports or inquiries .
Current Maintainer :
Christoph Reichenbach ( CR ) [ creichen @ gmail . com ]
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-02-15 08:34:13 +00:00
# include "sci/include/sciresource.h"
# include "sci/include/engine.h"
# include "sci/include/gfx_widgets.h"
# include "sci/engine/sci_graphics.h"
# include "sci/include/sci_widgets.h"
2009-02-15 06:10:59 +00:00
# undef DEBUG_LSRECT
/* Graph subfunctions */
# define K_GRAPH_GET_COLORS_NR 2
# define K_GRAPH_DRAW_LINE 4
# define K_GRAPH_SAVE_BOX 7
# define K_GRAPH_RESTORE_BOX 8
# define K_GRAPH_FILL_BOX_BACKGROUND 9
# define K_GRAPH_FILL_BOX_FOREGROUND 10
# define K_GRAPH_FILL_BOX_ANY 11
# define K_GRAPH_UPDATE_BOX 12
# define K_GRAPH_REDRAW_BOX 13
# define K_GRAPH_ADJUST_PRIORITY 14
/* Control types and flags */
# define K_CONTROL_BUTTON 1
# define K_CONTROL_TEXT 2
# define K_CONTROL_EDIT 3
# define K_CONTROL_ICON 4
# define K_CONTROL_CONTROL 6
# define K_CONTROL_CONTROL_ALIAS 7
# define K_CONTROL_BOX 10
# define ADD_TO_CURRENT_PORT(widget) \
{ if ( s - > port ) \
s - > port - > add ( GFXWC ( s - > port ) , GFXW ( widget ) ) ; \
else \
s - > picture_port - > add ( GFXWC ( s - > visual ) , GFXW ( widget ) ) ; }
# define ADD_TO_CURRENT_PICTURE_PORT(widget) \
{ if ( s - > port ) \
s - > port - > add ( GFXWC ( s - > port ) , GFXW ( widget ) ) ; \
else \
s - > picture_port - > add ( GFXWC ( s - > picture_port ) , GFXW ( widget ) ) ; }
# define ADD_TO_WINDOW_PORT(widget) \
s - > wm_port - > add ( GFXWC ( s - > wm_port ) , GFXW ( widget ) ) ;
# define ADD_TO_CURRENT_FG_WIDGETS(widget) \
ADD_TO_CURRENT_PICTURE_PORT ( widget )
# define ADD_TO_CURRENT_BG_WIDGETS(widget) \
ADD_TO_CURRENT_PICTURE_PORT ( widget )
# define FULL_REDRAW()\
if ( s - > visual ) \
s - > visual - > draw ( GFXW ( s - > visual ) , gfxw_point_zero ) ; \
gfxop_update ( s - > gfx_state ) ;
# define FULL_INSPECTION()\
if ( s - > visual ) \
s - > visual - > print ( GFXW ( s - > visual ) , 0 ) ;
# define GFX_ASSERT(x) { \
int val = ! ! ( x ) ; \
if ( val ) { \
if ( val = = GFX_ERROR ) \
SCIkwarn ( SCIkWARNING , " GFX subsystem returned error on \" " # x " \" ! \n " ) ; \
else { \
SCIkwarn ( SCIkERROR , " GFX subsystem fatal error condition on \" " # x " \" ! \n " ) ; \
vm_handle_fatal_error ( s , __LINE__ , __FILE__ ) ; \
} \
} \
}
# define ASSERT(x) { \
int val = ! ! ( x ) ; \
if ( ! val ) { \
SCIkwarn ( SCIkERROR , " Fatal error condition on \" " # x " \" ! \n " ) ; \
BREAKPOINT ( ) ; \
vm_handle_fatal_error ( s , __LINE__ , __FILE__ ) ; \
} \
}
static inline int
2009-02-15 22:28:12 +00:00
sign_extend_byte ( int value ) {
2009-02-15 06:10:59 +00:00
if ( value & 0x80 )
return value - 256 ;
else
return value ;
}
static void
2009-02-15 22:28:12 +00:00
assert_primary_widget_lists ( state_t * s ) {
2009-02-15 06:10:59 +00:00
if ( ! s - > dyn_views ) {
rect_t bounds = s - > picture_port - > bounds ;
s - > dyn_views = gfxw_new_list ( bounds , GFXW_LIST_SORTED ) ;
s - > dyn_views - > flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
ADD_TO_CURRENT_PICTURE_PORT ( s - > dyn_views ) ;
}
if ( ! s - > drop_views ) {
rect_t bounds = s - > picture_port - > bounds ;
s - > drop_views = gfxw_new_list ( bounds , GFXW_LIST_SORTED ) ;
s - > drop_views - > flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
ADD_TO_CURRENT_PICTURE_PORT ( s - > drop_views ) ;
}
}
static void
2009-02-15 22:28:12 +00:00
reparentize_primary_widget_lists ( state_t * s , gfxw_port_t * newport ) {
2009-02-15 06:10:59 +00:00
if ( ! newport )
newport = s - > picture_port ;
if ( s - > dyn_views ) {
gfxw_remove_widget_from_container ( s - > dyn_views - > parent , GFXW ( s - > dyn_views ) ) ;
newport - > add ( GFXWC ( newport ) , GFXW ( s - > dyn_views ) ) ;
}
}
int
2009-02-15 22:28:12 +00:00
_find_view_priority ( state_t * s , int y ) {
/* if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1)
+ + y ; */
2009-02-15 06:10:59 +00:00
if ( s - > pic_priority_table ) { /* SCI01 priority table set? */
int j ;
for ( j = 0 ; j < 15 ; j + + )
if ( y < s - > pic_priority_table [ j + 1 ] )
return j ;
return 14 ; /* Maximum */
2009-02-15 22:28:12 +00:00
} else {
2009-02-15 06:10:59 +00:00
if ( s - > version > = SCI_VERSION_FTU_PRIORITY_14_ZONES )
return SCI0_VIEW_PRIORITY_14_ZONES ( y ) ;
else
return SCI0_VIEW_PRIORITY ( y ) = = 15 ? 14 :
2009-02-15 22:28:12 +00:00
SCI0_VIEW_PRIORITY ( y ) ;
2009-02-15 06:10:59 +00:00
}
}
2009-02-15 21:57:51 +00:00
int
2009-02-15 22:28:12 +00:00
_find_priority_band ( state_t * s , int nr ) {
2009-02-15 06:10:59 +00:00
if ( s - > version > = SCI_VERSION_FTU_PRIORITY_14_ZONES & & ( nr < 0 | | nr > 14 ) ) {
if ( nr = = 15 )
return 0xffff ;
else {
SCIkwarn ( SCIkWARNING , " Attempt to get priority band %d \n " , nr ) ;
}
return 0 ;
}
if ( s - > version < SCI_VERSION_FTU_PRIORITY_14_ZONES & & ( nr < 0 | | nr > 15 ) ) {
SCIkwarn ( SCIkWARNING , " Attempt to get priority band %d \n " , nr ) ;
return 0 ;
}
if ( s - > pic_priority_table ) /* SCI01 priority table set? */
return s - > pic_priority_table [ nr ] ;
else {
int retval ;
if ( s - > version > = SCI_VERSION_FTU_PRIORITY_14_ZONES )
retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES ( nr ) ;
else
retval = SCI0_PRIORITY_BAND_FIRST ( nr ) ;
/* if (s->version <= SCI_VERSION_LTU_PRIORITY_OB1)
- - retval ; */
return retval ;
}
}
reg_t
2009-02-15 22:28:12 +00:00
graph_save_box ( state_t * s , rect_t area ) {
2009-02-15 06:10:59 +00:00
reg_t handle = kalloc ( s , " graph_save_box() " , sizeof ( gfxw_snapshot_t * ) ) ;
gfxw_snapshot_t * * ptr = ( gfxw_snapshot_t * * ) kmem ( s , handle ) ;
* ptr = gfxw_make_snapshot ( s - > visual , area ) ;
return handle ;
}
void
2009-02-15 22:28:12 +00:00
graph_restore_box ( state_t * s , reg_t handle ) {
2009-02-15 06:10:59 +00:00
gfxw_snapshot_t * * ptr ;
int port_nr = s - > port - > ID ;
if ( ! handle . segment ) {
SCIkwarn ( SCIkWARNING , " Attempt to restore box with zero handle \n " ) ;
return ;
}
ptr = ( gfxw_snapshot_t * * ) kmem ( s , handle ) ;
if ( ! ptr ) {
SCIkwarn ( SCIkWARNING , " Attempt to restore invalid handle %04x \n " , handle ) ;
return ;
}
while ( port_nr > 2 & & ! ( s - > port - > flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS )
2009-02-15 22:28:12 +00:00
& & ( gfxw_widget_matches_snapshot ( * ptr , GFXW ( s - > port ) ) ) ) {
2009-02-15 06:10:59 +00:00
/* This shouldn't ever happen, actually, since windows (ports w/ ID > 2) should all be immune */
gfxw_port_t * newport = gfxw_find_port ( s - > visual , port_nr ) ;
SCIkwarn ( SCIkERROR , " Port %d is not immune against snapshots! \n " , s - > port - > ID ) ;
port_nr - - ;
if ( newport )
s - > port = newport ;
}
if ( s - > dyn_views & & gfxw_widget_matches_snapshot ( * ptr , GFXW ( s - > dyn_views - > parent ) ) ) {
gfxw_container_t * parent = s - > dyn_views - > parent ;
do {
parent = parent - > parent ;
} while ( parent & & ( gfxw_widget_matches_snapshot ( * ptr , GFXW ( parent ) ) ) ) ;
if ( ! parent ) {
SCIkwarn ( SCIkERROR , " Attempted widget mass destruction by a snapshot \n " ) ;
BREAKPOINT ( ) ;
}
reparentize_primary_widget_lists ( s , ( gfxw_port_t * ) parent ) ;
}
if ( ! ptr ) {
SCIkwarn ( SCIkERROR , " Attempt to restore invalid snaphot with handle %04x! \n " , handle ) ;
return ;
}
gfxw_restore_snapshot ( s - > visual , * ptr ) ;
free ( * ptr ) ;
* ptr = NULL ;
kfree ( s , handle ) ;
}
#if 0
# define KERNEL_COLOR_PALETTE s->gfx_state->pic->visual_map->colors
# define KERNEL_COLORS_NR s->gfx_state->pic->visual_map->colors_nr
# else
# define KERNEL_COLOR_PALETTE s->gfx_state->resstate->static_palette
# define KERNEL_COLORS_NR s->gfx_state->resstate->static_palette_entries
# endif
static gfx_pixmap_color_t white = { GFX_COLOR_INDEX_UNMAPPED , 255 , 255 , 255 } ;
gfx_pixmap_color_t *
2009-02-15 22:28:12 +00:00
get_pic_color ( state_t * s , int color ) {
if ( s - > resmgr - > sci_version < SCI_VERSION_01_VGA )
2009-02-15 06:10:59 +00:00
return & ( s - > ega_colors [ color ] . visual ) ;
if ( color = = 255 )
return & white ;
else if ( color < KERNEL_COLORS_NR )
2009-02-15 22:28:12 +00:00
return & ( KERNEL_COLOR_PALETTE [ color ] ) ;
else {
SCIkwarn ( SCIkERROR , " Color index %d out of bounds for pic %d (%d max) " ,
color , s - > gfx_state - > pic_nr , KERNEL_COLORS_NR ) ;
BREAKPOINT ( ) ;
return NULL ; /* Well, rather, not return. But gcc gets scared here. */
}
2009-02-15 06:10:59 +00:00
}
static gfx_color_t
2009-02-15 22:28:12 +00:00
graph_map_color ( state_t * s , int color , int priority , int control ) {
2009-02-15 06:10:59 +00:00
gfx_color_t retval ;
2009-02-15 22:28:12 +00:00
if ( s - > resmgr - > sci_version < SCI_VERSION_01_VGA ) {
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-02-15 06:10:59 +00:00
retval . visual = * ( get_pic_color ( s , color ) ) ;
retval . alpha = 0 ;
retval . priority = priority ;
retval . control = control ;
2009-02-15 22:28:12 +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 ;
}
/* --- */
reg_t
2009-02-15 22:28:12 +00:00
kSetCursor_SCI11 ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
switch ( argc ) {
2009-02-15 06:10:59 +00:00
case 1 :
2009-02-15 22:28:12 +00:00
if ( UKPV ( 0 ) = = 0 ) {
2009-02-15 06:10:59 +00:00
s - > save_mouse_pointer_view = s - > mouse_pointer_view ;
s - > save_mouse_pointer_loop = s - > mouse_pointer_loop ;
s - > save_mouse_pointer_cel = s - > mouse_pointer_cel ;
s - > mouse_pointer_view = s - > mouse_pointer_loop = s - > mouse_pointer_cel = - 1 ;
gfxop_set_pointer_cursor ( s - > gfx_state , GFXOP_NO_POINTER ) ;
2009-02-15 22:28:12 +00:00
} else {
2009-02-15 06:10:59 +00:00
s - > mouse_pointer_view = s - > save_mouse_pointer_view ;
s - > mouse_pointer_loop = s - > save_mouse_pointer_loop ;
s - > mouse_pointer_cel = s - > save_mouse_pointer_cel ;
}
2009-02-15 22:28:12 +00:00
case 2 : {
2009-02-15 06:10:59 +00:00
point_t pt ;
pt . x = UKPV ( 0 ) ;
pt . y = UKPV ( 1 ) ;
GFX_ASSERT ( gfxop_set_pointer_position ( s - > gfx_state , pt ) ) ;
break ;
}
case 3 :
2009-02-15 22:28:12 +00:00
GFX_ASSERT ( gfxop_set_pointer_view ( s - > gfx_state , UKPV ( 0 ) , UKPV ( 1 ) , UKPV ( 2 ) , NULL ) ) ;
2009-02-15 06:10:59 +00:00
s - > mouse_pointer_view = UKPV ( 0 ) ;
s - > mouse_pointer_loop = UKPV ( 1 ) ;
s - > mouse_pointer_cel = UKPV ( 2 ) ;
break ;
case 9 : {
point_t hotspot = gfx_point ( SKPV ( 3 ) , SKPV ( 4 ) ) ;
2009-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
// sciprintf("Setting hotspot at %d/%d\n", hotspot.x, hotspot.y);
gfxop_set_pointer_view ( s - > gfx_state , UKPV ( 0 ) , UKPV ( 1 ) , UKPV ( 2 ) , & hotspot ) ;
break ;
}
default :
SCIkwarn ( SCIkERROR , " kSetCursor: Unhandled case: %d arguments given! \n " , argc ) ;
break ;
}
return s - > r_acc ;
}
reg_t
2009-02-15 22:28:12 +00:00
kSetCursor ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
if ( s - > version > = SCI_VERSION ( 1 , 001 , 000 ) | |
has_kernel_function ( s , " MoveCursor " ) ) {
2009-02-15 06:10:59 +00:00
return kSetCursor_SCI11 ( s , funct_nr , argc , argv ) ;
}
2009-02-15 22:28:12 +00:00
if ( SKPV_OR_ALT ( 1 , 1 ) ) {
2009-02-15 06:10:59 +00:00
s - > mouse_pointer_view = SKPV ( 0 ) ;
} else
s - > mouse_pointer_view = GFXOP_NO_POINTER ;
s - > mouse_pointer_loop = s - > mouse_pointer_cel = 0 ; /* Not used with cursor-format pointers */
GFX_ASSERT ( gfxop_set_pointer_cursor ( s - > gfx_state , s - > mouse_pointer_view ) ) ;
if ( argc > 2 ) {
point_t newpos = gfx_point ( SKPV ( 2 ) + s - > port - > bounds . x ,
2009-02-15 22:28:12 +00:00
SKPV ( 3 ) + s - > port - > bounds . y ) ;
2009-02-15 06:10:59 +00:00
GFX_ASSERT ( gfxop_set_pointer_position ( s - > gfx_state , newpos ) ) ;
}
return s - > r_acc ;
}
extern int oldx , oldy ;
reg_t
2009-02-15 22:28:12 +00:00
kMoveCursor ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
point_t newpos ;
2009-02-15 22:28:12 +00:00
static point_t oldpos = { 0 , 0 } ;
2009-02-15 06:10:59 +00:00
newpos = s - > gfx_state - > pointer_pos ;
2009-02-15 22:28:12 +00:00
if ( argc = = 1 ) {
2009-02-15 06:10:59 +00:00
/* Case ignored on IBM PC */
2009-02-15 22:28:12 +00:00
} else {
newpos . x = SKPV ( 0 ) + s - > port - > zone . x ;
newpos . y = SKPV ( 1 ) + s - > port - > zone . y ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
if ( newpos . x > s - > port - > zone . x + s - > port - > zone . xl )
newpos . x = s - > port - > zone . x + s - > port - > zone . xl ;
if ( newpos . y > s - > port - > zone . y + s - > port - > zone . yl )
newpos . y = s - > port - > zone . y + s - > port - > zone . yl ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
if ( newpos . x < 0 ) newpos . x = 0 ;
if ( newpos . y < 0 ) newpos . y = 0 ;
2009-02-15 06:10:59 +00:00
oldpos = newpos ;
}
GFX_ASSERT ( gfxop_set_pointer_position ( s - > gfx_state , newpos ) ) ;
return s - > r_acc ;
}
static inline void
2009-02-15 22:28:12 +00:00
_ascertain_port_contents ( gfxw_port_t * port ) {
2009-02-15 06:10:59 +00:00
if ( ! port - > contents )
port - > contents = ( gfxw_widget_t * ) gfxw_new_list ( port - > bounds , 0 ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kShow ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int old_map = s - > pic_visible_map ;
s - > pic_visible_map = ( gfx_map_mask_t ) UKPV_OR_ALT ( 0 , 1 ) ;
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 ) {
if ( s - > pic_visible_map = = GFX_MASK_VISUAL ) /* Full widget redraw */
2009-02-15 22:28:12 +00:00
s - > visual - > draw ( GFXW ( s - > visual ) , gfx_point ( 0 , 0 ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
sciprintf ( " Switching visible map to %x \n " , s - > pic_visible_map ) ;
}
break ;
default :
SCIkwarn ( SCIkWARNING , " Show(%x) selects unknown map \n " , s - > pic_visible_map ) ;
}
s - > pic_not_valid = 2 ;
return s - > r_acc ;
}
reg_t
2009-02-15 22:28:12 +00:00
kPicNotValid ( state_t * 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 )
s - > pic_not_valid = ( byte ) UKPV ( 0 ) ;
return s - > r_acc ;
}
void
2009-02-15 22:28:12 +00:00
_k_redraw_box ( state_t * s , int x1 , int y1 , int x2 , int y2 ) {
2009-02-15 06:10:59 +00:00
sciprintf ( " _k_redraw_box(): Unimplemented! \n " ) ;
#if 0
int i ;
view_object_t * list = s - > dyn_views ;
sciprintf ( " Reanimating views \n " , s - > dyn_views_nr ) ;
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
* ( list [ i ] . underBitsp ) = graph_save_box ( s ,
2009-02-15 22:28:12 +00:00
list [ i ] . nsLeft ,
list [ i ] . nsTop ,
list [ i ] . nsRight - list [ i ] . nsLeft ,
list [ i ] . nsBottom - list [ i ] . nsTop ,
SCI_MAP_VISUAL | SCI_MAP_PRIORITY ) ;
2009-02-15 06:10:59 +00:00
draw_view0 ( s - > pic , s - > ports [ 0 ] ,
2009-02-15 22:28:12 +00:00
list [ i ] . nsLeft , list [ i ] . nsTop ,
list [ i ] . priority , list [ i ] . loop ,
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
}
void
2009-02-15 22:28:12 +00:00
_k_graph_rebuild_port_with_color ( state_t * s , gfx_color_t newbgcolor ) {
2009-02-15 06:10:59 +00:00
gfxw_port_t * port = s - > port ;
gfxw_port_t * newport ;
2009-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
newport = sciw_new_window ( s , port - > zone , port - > font_nr , port - > color , newbgcolor ,
2009-02-15 22:28:12 +00:00
s - > titlebar_port - > font_nr , s - > ega_colors [ 15 ] , s - > ega_colors [ 8 ] ,
port - > title_text , port - > port_flags & ~ WINDOW_FLAG_TRANSPARENT ) ;
2009-02-15 06:10:59 +00:00
if ( s - > dyn_views ) {
int found = 0 ;
gfxw_container_t * parent = s - > dyn_views - > parent ;
while ( parent & & ! ( found | = ( GFXW ( parent ) = = GFXW ( port ) ) ) )
parent = parent - > parent ;
s - > dyn_views = NULL ;
}
port - > parent - > add ( GFXWC ( port - > parent ) , GFXW ( newport ) ) ;
port - > widfree ( GFXW ( port ) ) ;
}
static int activated_icon_bar ;
static int port_origin_x ;
static int port_origin_y ;
reg_t
2009-02-15 22:28:12 +00:00
kGraph ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
rect_t area ;
gfxw_port_t * port = s - > port ;
int redraw_port = 0 ;
area = gfx_rect ( SKPV ( 2 ) , SKPV ( 1 ) , SKPV ( 4 ) , SKPV ( 3 ) ) ;
area . xl = area . xl - area . x ; /* Since the actual coordinates are absolute */
area . yl = area . yl - area . y ;
2009-02-15 22:28:12 +00:00
switch ( SKPV ( 0 ) ) {
2009-02-15 06:10:59 +00:00
case K_GRAPH_GET_COLORS_NR :
return make_reg ( 0 , ( s - > resmgr - > sci_version < SCI_VERSION_01_VGA ) ? 0x10 : 0x100 ) ;
break ;
case K_GRAPH_DRAW_LINE : {
gfx_color_t gfxcolor = graph_map_color ( s , SKPV ( 5 ) & 0xf , SKPV_OR_ALT ( 6 , - 1 ) , SKPV_OR_ALT ( 7 , - 1 ) ) ;
SCIkdebug ( SCIkGRAPHICS , " draw_line((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d) \n " ,
2009-02-15 22:28:12 +00:00
SKPV ( 2 ) , SKPV ( 1 ) , SKPV ( 4 ) , SKPV ( 3 ) , SKPV ( 5 ) , SKPV_OR_ALT ( 6 , - 1 ) , SKPV_OR_ALT ( 7 , - 1 ) ,
gfxcolor . mask ) ;
2009-02-15 06:10:59 +00:00
redraw_port = 1 ;
ADD_TO_CURRENT_BG_WIDGETS ( GFXW ( gfxw_new_line ( gfx_point ( SKPV ( 2 ) , SKPV ( 1 ) ) ,
2009-02-15 22:28:12 +00:00
gfx_point ( SKPV ( 4 ) , SKPV ( 3 ) ) ,
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 ;
area . xl + = - port_origin_x ;
area . yl + = - port_origin_y ;
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 :
_k_graph_rebuild_port_with_color ( s , port - > bgcolor ) ;
port = s - > port ;
redraw_port = 1 ;
break ;
case K_GRAPH_FILL_BOX_FOREGROUND :
_k_graph_rebuild_port_with_color ( s , port - > color ) ;
port = s - > port ;
redraw_port = 1 ;
break ;
case K_GRAPH_FILL_BOX_ANY : {
gfx_color_t color = graph_map_color ( s , SKPV ( 6 ) , SKPV_OR_ALT ( 7 , - 1 ) , SKPV_OR_ALT ( 8 , - 1 ) ) ;
color . mask = ( byte ) UKPV ( 5 ) ;
SCIkdebug ( SCIkGRAPHICS , " fill_box_any((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d) \n " ,
2009-02-15 22:28:12 +00:00
SKPV ( 2 ) , SKPV ( 1 ) , SKPV ( 4 ) , SKPV ( 3 ) , SKPV ( 6 ) , SKPV_OR_ALT ( 7 , - 1 ) , SKPV_OR_ALT ( 8 , - 1 ) ,
UKPV ( 5 ) ) ;
2009-02-15 06:10:59 +00:00
ADD_TO_CURRENT_BG_WIDGETS ( gfxw_new_box ( s - > gfx_state , area , color , color , GFX_BOX_SHADE_FLAT ) ) ;
}
break ;
case K_GRAPH_UPDATE_BOX : {
SCIkdebug ( SCIkGRAPHICS , " update_box(%d, %d, %d, %d) \n " ,
2009-02-15 22:28:12 +00:00
SKPV ( 1 ) , SKPV ( 2 ) , SKPV ( 3 ) , SKPV ( 4 ) ) ;
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 : {
SCIkdebug ( SCIkGRAPHICS , " redraw_box(%d, %d, %d, %d) \n " ,
2009-02-15 22:28:12 +00:00
SKPV ( 1 ) , SKPV ( 2 ) , SKPV ( 3 ) , SKPV ( 4 ) ) ;
2009-02-15 06:10:59 +00:00
area . x + = s - > port - > zone . x ;
area . y + = s - > port - > zone . y ;
if ( s - > dyn_views & & s - > dyn_views - > parent = = GFXWC ( s - > port ) )
s - > dyn_views - > draw ( GFXW ( s - > dyn_views ) , gfx_point ( 0 , 0 ) ) ;
gfxop_update_box ( s - > gfx_state , area ) ;
}
break ;
case K_GRAPH_ADJUST_PRIORITY :
SCIkdebug ( SCIkGRAPHICS , " adjust_priority(%d, %d) \n " , SKPV ( 1 ) , SKPV ( 2 ) ) ;
s - > priority_first = SKPV ( 1 ) - 10 ;
s - > priority_last = SKPV ( 2 ) - 10 ;
break ;
default :
SCIkdebug ( SCIkSTUB , " Unhandled Graph() operation %04x \n " , SKPV ( 0 ) ) ;
}
if ( redraw_port )
FULL_REDRAW ( ) ;
gfxop_update ( s - > gfx_state ) ;
return s - > r_acc ;
}
reg_t
2009-02-15 22:28:12 +00:00
kTextSize ( state_t * 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 ;
reg_t * dest = kernel_dereference_reg_pointer ( s , argv [ 0 ] , 4 ) ;
int maxwidth = KP_UINT ( KP_ALT ( 3 , NULL_REG ) ) ;
int font_nr = KP_UINT ( argv [ 2 ] ) ;
if ( maxwidth < 0 )
maxwidth = 0 ;
dest [ 0 ] = dest [ 1 ] = NULL_REG ;
if ( ! text | | ! * text | | ! dest ) { /* Empty text */
dest [ 2 ] = dest [ 3 ] = make_reg ( 0 , 0 ) ;
SCIkdebug ( SCIkSTRINGS , " GetTextSize: Empty string \n " ) ;
return s - > r_acc ;
}
GFX_ASSERT ( gfxop_get_text_params ( s - > gfx_state , font_nr , text ,
2009-02-15 22:28:12 +00:00
maxwidth ? maxwidth : MAX_TEXT_WIDTH_MAGIC_VALUE ,
& width , & height , 0 ,
NULL , NULL , NULL ) ) ;
2009-02-15 06:10:59 +00:00
SCIkdebug ( SCIkSTRINGS , " GetTextSize '%s' -> %dx%d \n " , text , width , height ) ;
dest [ 2 ] = make_reg ( 0 , height ) ;
// dest[3] = make_reg(0, maxwidth? maxwidth : width);
dest [ 3 ] = make_reg ( 0 , width ) ;
return s - > r_acc ;
}
int debug_sleeptime_factor = 1 ;
reg_t
2009-02-15 22:28:12 +00:00
kWait ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
GTimeVal time ;
int sleep_time = UKPV ( 0 ) ;
2009-02-15 22:28:12 +00:00
sci_get_current_time ( & time ) ;
2009-02-15 06:10:59 +00:00
s - > r_acc = make_reg ( 0 , ( ( time . tv_usec - s - > last_wait_time . tv_usec ) * 60 / 1000000 ) +
2009-02-15 22:28:12 +00:00
( time . tv_sec - s - > last_wait_time . tv_sec ) * 60 ) ;
2009-02-15 06:10:59 +00:00
memcpy ( & ( s - > last_wait_time ) , & time , sizeof ( GTimeVal ) ) ;
/* Reset optimization flags: Game is playing along nicely anyway */
s - > kernel_opt_flags & = ~ ( KERNEL_OPT_FLAG_GOT_EVENT
2009-02-15 22:28:12 +00:00
| KERNEL_OPT_FLAG_GOT_2NDEVENT ) ;
2009-02-15 06:10:59 +00:00
sleep_time * = debug_sleeptime_factor ;
GFX_ASSERT ( gfxop_usleep ( s - > gfx_state , sleep_time * 1000000 / 60 ) ) ;
return s - > r_acc ;
}
reg_t
2009-02-15 22:28:12 +00:00
kCoordPri ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int y = SKPV ( 0 ) ;
return make_reg ( 0 , VIEW_PRIORITY ( y ) ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kPriCoord ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int priority = SKPV ( 0 ) ;
return make_reg ( 0 , PRIORITY_BAND_FIRST ( priority ) ) ;
}
void
_k_dirloop ( reg_t obj , word angle , state_t * s , int funct_nr ,
2009-02-15 22:28:12 +00:00
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 ;
if ( s - > version > = SCI_VERSION_FTU_2ND_ANGLES ) {
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 ) {
SCIkwarn ( SCIkERROR , " Invalid view.%03d \n " , view ) ;
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 ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kDirLoop ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
_k_dirloop ( argv [ 0 ] , UKPV ( 1 ) , s , funct_nr , argc , argv ) ;
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)
abs_rect_t
set_base ( struct _state * s , reg_t object ) ;
inline abs_rect_t
get_nsrect ( struct _state * s , reg_t object , byte clip ) ;
static inline abs_rect_t
nsrect_clip ( state_t * s , int y , abs_rect_t retval , int priority ) ;
static int
collides_with ( state_t * s , abs_rect_t area , reg_t other_obj , int use_nsrect , int view_mask , int funct_nr , int argc ,
2009-02-15 22:28:12 +00:00
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 ) ;
abs_rect_t other_area ;
if ( use_nsrect ) {
other_area = get_nsrect ( s , other_obj , 0 ) ;
other_area = nsrect_clip ( s , y , other_area , other_priority ) ;
} else {
other_area . x = GET_SEL32V ( other_obj , brLeft ) ;
other_area . xend = GET_SEL32V ( other_obj , brRight ) ;
other_area . y = GET_SEL32V ( other_obj , brTop ) ;
other_area . yend = GET_SEL32V ( other_obj , brBottom ) ;
}
if ( other_area . xend < 0 | | other_area . yend < 0 | | area . xend < 0 | | area . yend < 0 )
return 0 ; /* Out of scope */
if ( other_area . x > = 320 | | other_area . y > = 190 | | area . xend > = 320 | | area . yend > = 190 )
return 0 ; /* Out of scope */
SCIkdebug ( SCIkBRESEN , " OtherSignal=%04x, z=%04x obj= " PREG " \n " , other_signal ,
2009-02-15 22:28:12 +00:00
( other_signal & view_mask ) , PRINT_REG ( other_obj ) ) ;
2009-02-15 06:10:59 +00:00
if ( ( other_signal & ( view_mask ) ) = = 0 ) {
2009-02-15 22:28:12 +00:00
/* check whether the other object ignores actors */
2009-02-15 06:10:59 +00:00
SCIkdebug ( SCIkBRESEN , " against (%d,%d) to (%d,%d) \n " ,
2009-02-15 22:28:12 +00:00
other_area . x , other_area . y , other_area . xend , other_area . yend ) ;
2009-02-15 06:10:59 +00:00
if ( ( ( other_area . xend > area . x )
2009-02-15 22:28:12 +00:00
& & ( other_area . x < area . xend ) ) /* [other_x, other_xend] intersects [x, xend])? */
& &
( ( other_area . yend > area . y )
& & ( other_area . y < area . yend ) ) ) /* [other_y, other_yend] intersects [y, yend]? */
2009-02-15 06:10:59 +00:00
return 1 ;
/* CR (from :Bob Heitman:) Collision rects have Mac semantics, ((0,0),(1,1)) only
* * covers the coordinate ( 0 , 0 ) */
}
SCIkdebug ( SCIkBRESEN , " (no) \n " ) ;
return 0 ;
}
reg_t
2009-02-15 22:28:12 +00:00
kCanBeHere ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
reg_t obj = argv [ 0 ] ;
reg_t cliplist_ref = KP_ALT ( 1 , NULL_REG ) ;
list_t * cliplist = NULL ;
gfxw_port_t * port = s - > picture_port ;
word signal ;
int retval ;
abs_rect_t abs_zone ;
rect_t zone ;
word edgehit ;
word illegal_bits ;
abs_zone . x = GET_SEL32SV ( obj , brLeft ) ;
abs_zone . xend = GET_SEL32SV ( obj , brRight ) ;
abs_zone . y = GET_SEL32SV ( obj , brTop ) ;
abs_zone . yend = GET_SEL32SV ( obj , brBottom ) ;
zone = gfx_rect ( abs_zone . x + port - > zone . x , abs_zone . y + port - > zone . y ,
2009-02-15 22:28:12 +00:00
abs_zone . xend - abs_zone . x , abs_zone . yend - abs_zone . y ) ;
2009-02-15 06:10:59 +00:00
signal = GET_SEL32V ( obj , signal ) ;
2009-02-15 22:28:12 +00:00
SCIkdebug ( SCIkBRESEN , " Checking collision: (%d,%d) to (%d,%d) ([%d..%d]x[%d..%d]), obj= " PREG " , sig=%04x, cliplist= " PREG " \n " ,
GFX_PRINT_RECT ( zone ) ,
abs_zone . x , abs_zone . xend , abs_zone . y , abs_zone . yend ,
PRINT_REG ( obj ) , signal , PRINT_REG ( cliplist_ref ) ) ;
2009-02-15 06:10:59 +00:00
illegal_bits = GET_SEL32V ( obj , illegalBits ) ;
retval = ! ( illegal_bits
2009-02-15 22:28:12 +00:00
& ( edgehit = gfxop_scan_bitmask ( s - > gfx_state , zone , GFX_MASK_CONTROL ) ) ) ;
2009-02-15 06:10:59 +00:00
SCIkdebug ( SCIkBRESEN , " edgehit = %04x (illegalBits %04x) \n " , edgehit , illegal_bits ) ;
if ( retval = = 0 ) {
SCIkdebug ( SCIkBRESEN , " -> %04x \n " , retval ) ;
return not_register ( s , NULL_REG ) ; /* Can'tBeHere */
}
retval = 0 ;
2009-02-15 22:28:12 +00:00
if ( ( illegal_bits & 0x8000 ) /* If we are vulnerable to those views at all... */
& & s - > dyn_views ) { /* ...check against all stop-updated dynviews */
gfxw_dyn_view_t * widget = ( gfxw_dyn_view_t * ) s - > dyn_views - > contents ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
SCIkdebug ( SCIkBRESEN , " Checking vs dynviews: \n " ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
while ( widget ) {
if ( widget - > ID
& & ( widget - > signal & _K_VIEW_SIG_FLAG_FREESCI_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 ) )
return not_register ( s , NULL_REG ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
widget = ( gfxw_dyn_view_t * ) widget - > next ;
}
}
2009-02-15 06:10:59 +00:00
if ( signal & GASEOUS_VIEW_MASK_ACTIVE ) {
retval = signal & GASEOUS_VIEW_MASK_ACTIVE ; /* CanBeHere- it's either being disposed, or it ignores actors anyway */
SCIkdebug ( SCIkBRESEN , " -> %04x \n " , retval ) ;
return not_register ( s , make_reg ( 0 , retval ) ) ; /* CanBeHere */
}
if ( cliplist_ref . segment )
cliplist = LOOKUP_LIST ( cliplist_ref ) ;
if ( cliplist ) {
node_t * node = LOOKUP_NODE ( cliplist - > first ) ;
retval = 0 ; /* Assume that we Can'tBeHere... */
while ( node ) { /* Check each object in the list against our bounding rectangle */
reg_t other_obj = node - > value ;
SCIkdebug ( SCIkBRESEN , " comparing against " PREG " \n " , PRINT_REG ( other_obj ) ) ;
if ( ! is_object ( s , other_obj ) ) {
SCIkdebug ( SCIkWARNING , " CanBeHere() cliplist contains non-object %04x \n " , other_obj ) ;
} else if ( ! REG_EQ ( other_obj , obj ) ) { /* Clipping against yourself is not recommended */
if ( collides_with ( s , abs_zone , other_obj , 0 , GASEOUS_VIEW_MASK_PASSIVE , funct_nr , argc , argv ) ) {
SCIkdebug ( SCIkBRESEN , " -> %04x \n " , retval ) ;
return not_register ( s , NULL_REG ) ;
}
} /* if (other_obj != obj) */
node = LOOKUP_NODE ( node - > succ ) ; /* move on */
}
}
if ( ! retval )
retval = 1 ;
SCIkdebug ( SCIkBRESEN , " -> %04x \n " , retval ) ;
return not_register ( s , make_reg ( 0 , retval ) ) ;
} /* CanBeHere */
reg_t
2009-02-15 22:28:12 +00:00
kIsItSkip ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int view = SKPV ( 0 ) ;
int loop = SKPV ( 1 ) ;
int cel = SKPV ( 2 ) ;
int x = UKPV ( 3 ) ;
int y = UKPV ( 4 ) ;
gfxr_view_t * res = NULL ;
gfx_pixmap_t * pxm = NULL ;
if ( ! ( res = gfxr_get_view ( s - > gfx_state - > resstate , view , & loop , & cel , 0 ) ) ) {
GFXWARN ( " Attempt to get cel parameters for invalid view %d \n " , view ) ;
return make_reg ( 0 , - 1 ) ;
}
pxm = res - > loops [ loop ] . cels [ cel ] ;
2009-02-15 22:28:12 +00:00
if ( x > pxm - > index_xl ) x = pxm - > index_xl - 1 ;
if ( y > pxm - > index_yl ) y = pxm - > index_yl - 1 ;
2009-02-15 06:10:59 +00:00
return make_reg ( 0 ,
2009-02-15 22:28:12 +00:00
pxm - > index_data [ y * pxm - > index_xl + x ] = =
pxm - > color_key ) ;
2009-02-15 06:10:59 +00:00
}
reg_t
2009-02-15 22:28:12 +00:00
kCelHigh ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int view = SKPV ( 0 ) ;
int loop = SKPV ( 1 ) ;
int cel = SKPV ( 2 ) ;
int height , width ;
point_t offset ;
if ( argc ! = 3 ) {
SCIkwarn ( SCIkWARNING , " CelHigh called with %d parameters! \n " , argc ) ;
}
if ( gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & width , & height , & offset ) ) {
SCIkwarn ( SCIkERROR , " Invalid loop (%d) or cel (%d) in view.%d (0x%x), or view invalid \n " , loop , cel , view , view ) ;
return NULL_REG ;
} else
return make_reg ( 0 , height ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kCelWide ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int view = SKPV ( 0 ) ;
int loop = SKPV ( 1 ) ;
int cel = SKPV ( 2 ) ;
int height , width ;
point_t offset ;
if ( argc ! = 3 ) {
SCIkwarn ( SCIkWARNING , " CelHigh called with %d parameters! \n " , argc ) ;
}
if ( gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & width , & height , & offset ) ) {
SCIkwarn ( SCIkERROR , " Invalid loop (%d) or cel (%d) in view.%d (0x%x), or view invalid \n " , loop , cel , view , view ) ;
return NULL_REG ;
} else
return make_reg ( 0 , width ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kNumLoops ( state_t * 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 ) {
SCIkwarn ( SCIkERROR , " view.%d (0x%x) not found \n " , view , view ) ;
return NULL_REG ;
}
SCIkdebug ( SCIkGRAPHICS , " NumLoops(view.%d) = %d \n " , view , loops_nr ) ;
return make_reg ( 0 , loops_nr ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kNumCels ( state_t * 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 ;
if ( gfxop_check_cel ( s - > gfx_state , view , & loop , & cel ) ) { /* OK, this is a hack and there's a
* * real function to calculate cel numbers . . . */
SCIkwarn ( SCIkERROR , " view.%d (0x%x) not found \n " , view , view ) ;
return NULL_REG ;
}
2009-02-15 22:28:12 +00:00
SCIkdebug ( SCIkGRAPHICS , " NumCels(view.%d, %d) = %d \n " , view , loop , cel + 1 ) ;
2009-02-15 06:10:59 +00:00
return make_reg ( 0 , cel + 1 ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kOnControl ( state_t * 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 ;
map = ( gfx_map_mask_t ) SKPV ( 0 ) ;
}
2009-02-15 22:28:12 +00:00
ystart = SKPV ( arg + 1 ) ;
2009-02-15 06:10:59 +00:00
xstart = SKPV ( arg ) ;
if ( argc > 3 ) {
2009-02-15 22:28:12 +00:00
ylen = SKPV ( arg + 3 ) - ystart ;
xlen = SKPV ( arg + 2 ) - 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 ) ) ;
}
void
_k_view_list_free_backgrounds ( state_t * s , view_object_t * list , int list_nr ) ;
int sci01_priority_table_flags = 0 ;
reg_t
2009-02-15 22:28:12 +00:00
kDrawPic ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int pic_nr = SKPV ( 0 ) ;
int add_to_pic = 1 ;
int palette = SKPV_OR_ALT ( 3 , 0 ) ;
gfx_color_t transparent = s - > wm_port - > bgcolor ;
CHECK_THIS_KERNEL_FUNCTION ;
if ( s - > version < SCI_VERSION_FTU_NEWER_DRAWPIC_PARAMETERS ) {
if ( ! SKPV_OR_ALT ( 2 , 0 ) )
add_to_pic = 0 ;
} else
if ( SKPV_OR_ALT ( 2 , 1 ) )
add_to_pic = 0 ;
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-02-15 22:28:12 +00:00
SCIkdebug ( SCIkGRAPHICS , " Drawing pic.%03d \n " , SKPV ( 0 ) ) ;
2009-02-15 06:10:59 +00:00
if ( ! s - > pics ) {
s - > pics = ( drawn_pic_t * ) sci_malloc ( sizeof ( drawn_pic_t ) * ( s - > pics_nr = 8 ) ) ;
s - > pics_drawn_nr = 0 ;
}
if ( add_to_pic ) {
if ( s - > pics_nr = = s - > pics_drawn_nr ) {
s - > pics_nr + = 4 ;
s - > pics = ( drawn_pic_t * ) sci_realloc ( s - > pics , sizeof ( drawn_pic_t ) * s - > pics_nr ) ;
}
s - > pics [ s - > pics_drawn_nr ] . palette = palette ;
s - > pics [ s - > pics_drawn_nr + + ] . nr = pic_nr ;
GFX_ASSERT ( gfxop_add_to_pic ( s - > gfx_state , pic_nr , 1 , palette ) ) ;
} else {
s - > pics_drawn_nr = 1 ;
s - > pics [ 0 ] . nr = pic_nr ;
s - > pics [ 0 ] . palette = palette ;
GFX_ASSERT ( gfxop_new_pic ( s - > gfx_state , pic_nr , 1 , palette ) ) ;
}
gfxw_widget_kill_chrono ( s - > visual , 0 ) ;
s - > wm_port - > widfree ( GFXW ( s - > wm_port ) ) ;
s - > picture_port - > widfree ( GFXW ( s - > picture_port ) ) ;
s - > iconbar_port - > widfree ( GFXW ( s - > iconbar_port ) ) ;
s - > wm_port = gfxw_new_port ( s - > visual , NULL , s - > gfx_state - > options - > pic_port_bounds , s - > ega_colors [ 0 ] , transparent ) ;
s - > picture_port = gfxw_new_port ( s - > visual , NULL , s - > gfx_state - > options - > pic_port_bounds , s - > ega_colors [ 0 ] , transparent ) ;
s - > iconbar_port = gfxw_new_port ( s - > visual , NULL , gfx_rect ( 0 , 0 , 320 , 200 ) , s - > ega_colors [ 0 ] , transparent ) ;
s - > iconbar_port - > flags | = GFXW_FLAG_NO_IMPLICIT_SWITCH ;
s - > visual - > add ( GFXWC ( s - > visual ) , GFXW ( s - > picture_port ) ) ;
s - > visual - > add ( GFXWC ( s - > visual ) , GFXW ( s - > wm_port ) ) ;
s - > visual - > add ( GFXWC ( s - > visual ) , GFXW ( s - > iconbar_port ) ) ;
s - > port = s - > picture_port ;
s - > pic_priority_table = ( int * ) gfxop_get_pic_metainfo ( s - > gfx_state ) ;
if ( sci01_priority_table_flags & 0x2 ) {
if ( s - > pic_priority_table ) {
int i ;
2009-02-15 22:28:12 +00:00
fprintf ( stderr , " --------------------------- \n Priority table: \n " ) ;
2009-02-15 06:10:59 +00:00
for ( i = 0 ; i < 16 ; i + + )
2009-02-15 22:28:12 +00:00
fprintf ( stderr , " \t %d: \t %d \n " , i , s - > pic_priority_table [ i ] ) ;
fprintf ( stderr , " --------------------------- \n " ) ;
2009-02-15 06:10:59 +00:00
}
}
if ( sci01_priority_table_flags & 0x1 )
s - > pic_priority_table = NULL ;
if ( argc > 1 )
s - > pic_animate = SKPV ( 1 ) ; /* The animation used during kAnimate() later on */
s - > dyn_views = NULL ;
s - > drop_views = NULL ;
s - > priority_first = 42 ;
if ( s - > version < SCI_VERSION_FTU_PRIORITY_14_ZONES )
s - > priority_last = 200 ;
else
s - > priority_last = 190 ;
s - > pic_not_valid = 1 ;
s - > pic_is_new = 1 ;
return s - > r_acc ;
}
abs_rect_t
2009-02-15 22:28:12 +00:00
set_base ( state_t * 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 ;
abs_rect_t retval ;
x = GET_SEL32SV ( object , x ) ;
original_y = y = GET_SEL32SV ( object , y ) ;
if ( s - > selector_map . z > - 1 )
z = GET_SEL32SV ( object , z ) ;
else
z = 0 ;
y - = z ; /* Subtract z offset */
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 {
point_t offset = gfx_point ( 0 , 0 ) ;
if ( loop ! = oldloop ) {
loop = 0 ;
PUT_SEL32V ( object , loop , 0 ) ;
SCIkdebug ( SCIkGRAPHICS , " Resetting loop for " PREG " ! \n " , PRINT_REG ( object ) ) ;
}
if ( cel ! = oldcel ) {
cel = 0 ;
PUT_SEL32V ( object , cel , 0 ) ;
}
gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel ,
2009-02-15 22:28:12 +00:00
& 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 ;
SCIkdebug ( SCIkBASESETTER , " (%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
retval . x = xbase ;
retval . y = ybase ;
retval . xend = xend ;
retval . yend = yend ;
return retval ;
}
void
2009-02-15 22:28:12 +00:00
_k_base_setter ( state_t * s , reg_t object ) {
2009-02-15 06:10:59 +00:00
abs_rect_t absrect = set_base ( s , object ) ;
if ( lookup_selector ( s , object , s - > selector_map . brLeft , NULL , NULL )
2009-02-15 22:28:12 +00:00
! = SELECTOR_VARIABLE )
2009-02-15 06:10:59 +00:00
return ; /* non-fatal */
if ( s - > version < = SCI_VERSION_LTU_BASE_OB1 )
- - absrect . y ; /* Compensate for early SCI OB1 'bug' */
PUT_SEL32V ( object , brLeft , absrect . x ) ;
PUT_SEL32V ( object , brRight , absrect . xend ) ;
PUT_SEL32V ( object , brTop , absrect . y ) ;
PUT_SEL32V ( object , brBottom , absrect . yend ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kBaseSetter ( state_t * 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 ;
} /* kBaseSetter */
static inline abs_rect_t
2009-02-15 22:28:12 +00:00
nsrect_clip ( state_t * s , int y , abs_rect_t retval , int priority ) {
2009-02-15 06:10:59 +00:00
int pri_top ;
if ( priority = = - 1 )
priority = VIEW_PRIORITY ( y ) ;
pri_top = PRIORITY_BAND_FIRST ( priority ) + 1 ;
/* +1: Don't know why, but this seems to be happening */
if ( retval . y < pri_top )
retval . y = pri_top ;
if ( retval . yend < retval . y )
retval . y = retval . yend - 1 ;
return retval ;
}
inline abs_rect_t
2009-02-15 22:28:12 +00:00
calculate_nsrect ( state_t * 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-02-15 22:28:12 +00:00
abs_rect_t 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 {
point_t offset = gfx_point ( 0 , 0 ) ;
gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel ,
2009-02-15 22:28:12 +00:00
& 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 ; /* +1: magic modifier */
ybase = yend - ysize ;
retval . x = xbase ;
retval . y = ybase ;
retval . xend = xend ;
retval . yend = yend ;
return retval ;
}
inline abs_rect_t
2009-02-15 22:28:12 +00:00
get_nsrect ( state_t * s , reg_t object , byte clip ) {
2009-02-15 06:10:59 +00:00
int x , y , z ;
int view , loop , cel ;
abs_rect_t retval ;
x = GET_SEL32SV ( object , x ) ;
y = GET_SEL32SV ( object , y ) ;
if ( s - > selector_map . z > - 1 )
z = GET_SEL32SV ( object , z ) ;
else
z = 0 ;
y - = z ; /* Subtract z offset */
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 ;
}
static void
2009-02-15 22:28:12 +00:00
_k_set_now_seen ( state_t * s , reg_t object ) {
2009-02-15 06:10:59 +00:00
abs_rect_t absrect = get_nsrect ( s , object , 0 ) ;
if ( lookup_selector ( s , object , s - > selector_map . nsTop , NULL , NULL )
2009-02-15 22:28:12 +00:00
! = SELECTOR_VARIABLE ) { return ; } /* This isn't fatal */
2009-02-15 06:10:59 +00:00
PUT_SEL32V ( object , nsLeft , absrect . x ) ;
PUT_SEL32V ( object , nsRight , absrect . xend ) ;
PUT_SEL32V ( object , nsTop , absrect . y ) ;
PUT_SEL32V ( object , nsBottom , absrect . yend ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kSetNowSeen ( state_t * 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 ;
} /* kSetNowSeen */
reg_t
2009-02-15 22:28:12 +00:00
kPalette ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
switch ( UKPV ( 0 ) ) {
2009-02-15 06:10:59 +00:00
case 5 : {
int r = UKPV ( 1 ) ;
int g = UKPV ( 2 ) ;
int b = UKPV ( 3 ) ;
int i , delta , bestindex = - 1 , bestdelta = 200000 ;
for ( i = 0 ; i < KERNEL_COLORS_NR ; i + + ) {
2009-02-15 22:28:12 +00:00
int dr = abs ( KERNEL_COLOR_PALETTE [ i ] . r - r ) ;
int dg = abs ( KERNEL_COLOR_PALETTE [ i ] . g - g ) ;
int db = abs ( KERNEL_COLOR_PALETTE [ 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-15 22:28:12 +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-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
case 4 :
case 6 :
break ;
default :
SCIkdebug ( SCIkWARNING , " Unimplemented subfunction: %d \n " , UKPV ( 0 ) ) ;
}
return s - > r_acc ;
}
static void
_k_draw_control ( state_t * s , reg_t obj , int inverse ) ;
static void
2009-02-15 22:28:12 +00:00
_k_disable_delete_for_now ( state_t * s , reg_t obj ) {
reg_t text_pos = GET_SEL32 ( obj , text ) ;
char * text = IS_NULL_REG ( text_pos ) ? NULL : ( char * ) sm_dereference ( & s - > seg_manager , text_pos , NULL ) ;
2009-02-15 06:10:59 +00:00
int type = GET_SEL32V ( obj , type ) ;
int state = GET_SEL32V ( obj , state ) ;
if ( type = = K_CONTROL_BUTTON & & text & &
2009-02-15 22:28:12 +00:00
! strcmp ( s - > game_name , " sq4 " ) & &
s - > version < SCI_VERSION ( 1 , 001 , 000 ) & &
! strcmp ( text , " Delete " ) )
2009-02-15 06:10:59 +00:00
PUT_SEL32V ( obj , state , ( state | CONTROL_STATE_GRAY ) & ~ CONTROL_STATE_ENABLED ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kDrawControl ( state_t * 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 ;
}
reg_t
2009-02-15 22:28:12 +00:00
kHiliteControl ( state_t * 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 ) ;
return s - > r_acc ;
}
void
2009-02-15 22:28:12 +00:00
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 \
if ( cursor < textlen ) { \
memmove ( text + cursor , text + cursor + 1 , textlen - cursor + 1 ) ; \
}
# define _K_EDIT_BACKSPACE \
if ( cursor ) { \
- - cursor ; \
memmove ( text + cursor , text + cursor + 1 , textlen - cursor + 1 ) ; \
- - textlen ; \
}
reg_t
2009-02-15 22:28:12 +00:00
kEditControl ( state_t * 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 ) {
word ct_type = GET_SEL32V ( obj , type ) ;
switch ( ct_type ) {
2009-02-15 22:28:12 +00:00
case 0 :
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 ;
char * text = ( char * ) sm_dereference ( & s - > seg_manager , text_pos , NULL ) ;
int textlen ;
if ( ! text ) {
SCIkdebug ( SCIkWARNING , " Could not draw control: " PREG " does not reference text! \n " ,
2009-02-15 22:28:12 +00:00
PRINT_REG ( text_pos ) ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
if ( REG_EQ ( text_pos , s - > save_dir_copy ) ) {
max = MAX_SAVE_DIR_SIZE - 1 ;
display_offset = s - > save_dir_edit_offset ;
}
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 ;
break ; /* Terminate string */
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 ) ;
} else if ( modifiers & SCI_EVM_ALT ) { /* Ctrl has precedence over Alt */
switch ( key ) {
2009-02-15 22:28:12 +00:00
case 0x2100 /* A-f */ :
while ( ( cursor < textlen ) & & ( text [ cursor + + ] ! = ' ' ) ) ;
break ;
case 0x3000 /* A-b */ :
while ( ( cursor > 0 ) & & ( text [ - - cursor - 1 ] ! = ' ' ) ) ;
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 ) {
case SCI_K_BACKSPACE :
_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 ) {
case SCI_K_HOME :
cursor = 0 ;
break ;
case SCI_K_END :
cursor = textlen ;
break ;
case SCI_K_RIGHT :
if ( cursor + 1 < = textlen ) + + cursor ;
break ;
case SCI_K_LEFT :
if ( cursor > 0 ) - - cursor ;
break ;
case SCI_K_DELETE :
_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 ;
text [ cursor ] = 0 ; /* Terminate string */
}
} else if ( inserting ) {
if ( textlen < max ) {
int i ;
for ( i = textlen + 2 ; i > = cursor ; i - - )
text [ i ] = text [ i - 1 ] ;
text [ cursor + + ] = key ;
}
} else { /* Overwriting */
text [ cursor + + ] = key ;
}
if ( max_displayed < max )
update_cursor_limits ( & display_offset , & cursor , max_displayed ) ;
if ( REG_EQ ( text_pos , s - > save_dir_copy ) )
s - > save_dir_edit_offset = display_offset ;
cursor - = display_offset ;
PUT_SEL32V ( event , claimed , 1 ) ;
}
PUT_SEL32V ( obj , cursor , cursor ) ; /* Write back cursor position */
}
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 ) ;
PUT_SEL32V ( obj , state , state | CONTROL_STATE_DITHER_FRAMED ) ;
_k_draw_control ( s , obj , 0 ) ;
PUT_SEL32V ( obj , state , state ) ;
}
break ;
default :
SCIkwarn ( SCIkWARNING , " Attempt to edit control type %d \n " , ct_type ) ;
}
}
return s - > r_acc ;
}
static void
2009-02-15 22:28:12 +00:00
_k_draw_control ( state_t * 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-02-15 22:28:12 +00:00
char * text = IS_NULL_REG ( text_pos ) ? NULL : ( char * ) sm_dereference ( & s - > seg_manager , 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 ;
if ( REG_EQ ( text_pos , s - > save_dir_copy ) ) {
SCIkdebug ( SCIkGRAPHICS , " Displaying the save_dir copy \n " ) ;
}
switch ( type ) {
case K_CONTROL_BUTTON :
SCIkdebug ( SCIkGRAPHICS , " drawing button " PREG " to %d,%d \n " , PRINT_REG ( obj ) , x , y ) ;
ADD_TO_CURRENT_BG_WIDGETS ( sciw_new_button_control ( s - > port , obj , area , text , font_nr ,
2009-02-15 22:28:12 +00:00
( gint8 ) ( state & CONTROL_STATE_FRAMED ) ,
( gint8 ) inverse , ( gint8 ) ( state & CONTROL_STATE_GRAY ) ) ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_CONTROL_TEXT :
mode = ( gfx_alignment_t ) GET_SEL32V ( obj , mode ) ;
SCIkdebug ( SCIkGRAPHICS , " drawing text " PREG " to %d,%d, mode=%d \n " , PRINT_REG ( obj ) , x , y , mode ) ;
ADD_TO_CURRENT_BG_WIDGETS (
2009-02-15 22:28:12 +00:00
sciw_new_text_control ( s - > port , obj , area , text , font_nr , mode ,
( gint8 ) ( ! ! ( state & CONTROL_STATE_DITHER_FRAMED ) ) ,
( gint8 ) inverse ) ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_CONTROL_EDIT :
SCIkdebug ( SCIkGRAPHICS , " drawing edit control " PREG " to %d,%d \n " , PRINT_REG ( obj ) , x , y ) ;
max = GET_SEL32V ( obj , max ) ;
cursor = GET_SEL32V ( obj , cursor ) ;
if ( cursor > ( signed ) strlen ( text ) )
cursor = strlen ( text ) ;
if ( REG_EQ ( text_pos , s - > save_dir_copy ) )
update_cursor_limits ( & s - > save_dir_edit_offset , & cursor , max ) ;
update_cursor_limits ( & s - > save_dir_edit_offset , & cursor , max ) ;
ADD_TO_CURRENT_BG_WIDGETS ( sciw_new_edit_control ( s - > port , obj , area , text , font_nr , ( unsigned ) cursor , ( gint8 ) inverse ) ) ;
break ;
case K_CONTROL_ICON :
2009-02-15 22:28:12 +00:00
SCIkdebug ( SCIkGRAPHICS , " drawing icon control " PREG " to %d,%d \n " , PRINT_REG ( obj ) , x , y - 1 ) ;
2009-02-15 06:10:59 +00:00
ADD_TO_CURRENT_BG_WIDGETS ( sciw_new_icon_control ( s - > port , obj , area , view , loop , cel ,
2009-02-15 22:28:12 +00:00
( gint8 ) ( state & CONTROL_STATE_FRAMED ) , ( gint8 ) inverse ) ) ;
2009-02-15 06:10:59 +00:00
break ;
case K_CONTROL_CONTROL :
case K_CONTROL_CONTROL_ALIAS : {
char * * entries_list = NULL ;
char * seeker ;
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 ;
SCIkdebug ( SCIkGRAPHICS , " drawing list control %04x to %d,%d, diff %d \n " , obj , x , y ,
2009-02-15 22:28:12 +00:00
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 ;
while ( seeker [ 0 ] ) { /* Count string entries in NULL terminated string list */
+ + entries_nr ;
seeker + = entry_size ;
}
if ( entries_nr ) { /* determine list_top, selection, and the entries_list */
seeker = text ;
entries_list = ( char * * ) sci_malloc ( sizeof ( char * ) * entries_nr ) ;
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 ;
}
}
ADD_TO_CURRENT_BG_WIDGETS ( sciw_new_list_control ( s - > port , obj , area , font_nr , entries_list , entries_nr ,
2009-02-15 22:28:12 +00:00
list_top , selection , ( gint8 ) inverse ) ) ;
2009-02-15 06:10:59 +00:00
if ( entries_nr )
free ( entries_list ) ;
}
break ;
case K_CONTROL_BOX :
break ;
default :
SCIkwarn ( SCIkWARNING , " Unknown control type: %d at " PREG " , at (%d, %d) size %d x %d \n " ,
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 ( ) ;
}
}
static void
2009-02-15 22:28:12 +00:00
draw_rect_to_control_map ( state_t * s , abs_rect_t abs_zone ) {
2009-02-15 06:10:59 +00:00
gfxw_box_t * box ;
gfx_color_t color ;
gfxop_set_color ( s - > gfx_state , & color , - 1 , - 1 , - 1 , - 1 , - 1 , 0xf ) ;
2009-02-15 22:28:12 +00:00
SCIkdebug ( SCIkGRAPHICS , " adding control block (%d,%d)to(%d,%d) \n " ,
abs_zone . x , abs_zone . y , abs_zone . xend , abs_zone . yend ) ;
2009-02-15 06:10:59 +00:00
box = gfxw_new_box ( s - > gfx_state ,
2009-02-15 22:28:12 +00:00
gfx_rect ( abs_zone . x , abs_zone . y ,
abs_zone . xend - abs_zone . x ,
abs_zone . yend - abs_zone . y ) ,
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 ) ;
}
static inline void
2009-02-15 22:28:12 +00:00
draw_obj_to_control_map ( state_t * s , gfxw_dyn_view_t * view ) {
2009-02-15 06:10:59 +00:00
reg_t obj = make_reg ( view - > ID , view - > subID ) ;
if ( ! is_object ( s , obj ) )
SCIkwarn ( SCIkWARNING , " View %d does not contain valid object reference " PREG " \n " , view - > ID , PRINT_REG ( obj ) ) ;
if ( ! ( view - > signalp & & ( ( ( reg_t * ) view - > signalp ) - > offset & _K_VIEW_SIG_FLAG_IGNORE_ACTOR ) ) ) {
abs_rect_t 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
}
}
static void
2009-02-15 22:28:12 +00:00
_k_view_list_do_postdraw ( state_t * s , gfxw_list_t * list ) {
2009-02-15 06:10:59 +00:00
gfxw_dyn_view_t * widget = ( gfxw_dyn_view_t * ) list - > contents ;
while ( widget ) {
reg_t obj = make_reg ( widget - > ID , widget - > subID ) ;
if ( widget - > type = = GFXW_SORTED_LIST )
_k_view_list_do_postdraw ( s , GFXWC ( widget ) ) ;
if ( widget - > type ! = GFXW_DYN_VIEW ) {
widget = ( gfxw_dyn_view_t * ) widget - > next ;
continue ;
}
/*
* this fixes a few problems , but doesn ' t match SSCI ' s logic .
* The semantics of the private flag need to be verified before this can be uncommented .
* Fixes bug # 326 ( CB1 , ego falls down stairs )
* if ( ( widget - > signal & ( _K_VIEW_SIG_FLAG_FREESCI_PRIVATE | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) = = _K_VIEW_SIG_FLAG_FREESCI_PRIVATE ) {
*/
if ( ( widget - > signal & ( _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) = = 0 ) {
int has_nsrect = lookup_selector ( s , obj , s - > selector_map . nsBottom , NULL , NULL ) = = SELECTOR_VARIABLE ;
if ( has_nsrect ) {
int temp ;
temp = GET_SEL32V ( obj , nsLeft ) ;
PUT_SEL32V ( obj , lsLeft , temp ) ;
temp = GET_SEL32V ( obj , nsRight ) ;
PUT_SEL32V ( obj , lsRight , temp ) ;
temp = GET_SEL32V ( obj , nsTop ) ;
PUT_SEL32V ( obj , lsTop , temp ) ;
temp = GET_SEL32V ( obj , nsBottom ) ;
PUT_SEL32V ( obj , lsBottom , temp ) ;
# ifdef DEBUG_LSRECT
fprintf ( stderr , " lsRected " PREG " \n " , PRINT_REG ( obj ) ) ;
# endif
}
# ifdef DEBUG_LSRECT
else fprintf ( stderr , " Not lsRecting " PREG " because %d \n " , PRINT_REG ( obj ) ,
2009-02-15 22:28:12 +00:00
lookup_selector ( s , obj , s - > selector_map . 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
fprintf ( stderr , " obj " PREG " has pflags %x \n " , PRINT_REG ( obj ) , ( widget - > signal & ( _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) ) ;
# endif
if ( widget - > signalp ) {
* ( ( reg_t * ) ( widget - > signalp ) ) = make_reg ( 0 , widget - > signal & 0xffff ) ; /* Write back signal */
}
widget = ( gfxw_dyn_view_t * ) widget - > next ;
}
}
void
2009-02-15 22:28:12 +00:00
_k_view_list_mark_free ( state_t * s , reg_t off ) {
2009-02-15 06:10:59 +00:00
if ( s - > dyn_views ) {
gfxw_dyn_view_t * w = ( gfxw_dyn_view_t * ) s - > dyn_views - > contents ;
while ( w ) {
if ( w - > ID = = off . segment
2009-02-15 22:28:12 +00:00
& & w - > subID = = off . offset ) {
2009-02-15 06:10:59 +00:00
w - > under_bitsp = NULL ;
}
w = ( gfxw_dyn_view_t * ) w - > next ;
}
}
}
static int _k_animate_ran = 0 ;
int
_k_view_list_dispose_loop ( state_t * s , list_t * list , gfxw_dyn_view_t * widget ,
2009-02-15 22:28:12 +00:00
int funct_nr , int argc , reg_t * argv )
/* 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 ;
_k_animate_ran = 0 ;
if ( widget ) {
int retval ;
/* Recurse: */
retval = _k_view_list_dispose_loop ( s , list , ( gfxw_dyn_view_t * ) widget - > next , funct_nr , argc , argv ) ;
if ( retval = = - 1 ) /* Bail out on annihilation, rely on re-start from Animate() */
return - 1 ;
if ( GFXW_IS_DYN_VIEW ( widget ) & & ( widget - > ID ! = GFXW_NO_ID ) ) {
signal = ( ( reg_t * ) widget - > signalp ) - > offset ;
if ( signal & _K_VIEW_SIG_FLAG_DISPOSE_ME ) {
reg_t obj = make_reg ( widget - > ID , widget - > subID ) ;
reg_t under_bits = NULL_REG ;
if ( ! is_object ( s , obj ) ) {
SCIkwarn ( SCIkERROR , " Non-object " PREG " present "
2009-02-15 22:28:12 +00:00
" in view list during delete time \n " ,
PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
obj = NULL_REG ;
} else
2009-02-15 22:28:12 +00:00
if ( widget - > under_bitsp ) { /* Is there a bg picture left to clean? */
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
reg_t mem_handle = * ( ( reg_t * ) ( widget - > under_bitsp ) ) ;
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 ) ) {
* ( ( reg_t * ) ( widget - > under_bitsp ) ) = make_reg ( 0 , widget - > under_bits = 0 ) ;
} else {
SCIkwarn ( SCIkWARNING ,
" Treating viewobj " PREG
" as no longer "
" present \n " , PRINT_REG ( obj ) ) ;
obj = NULL_REG ;
}
2009-02-15 06:10:59 +00:00
}
}
if ( is_object ( s , obj ) ) {
2009-02-15 22:01:09 +00:00
if ( invoke_selector ( INV_SEL ( obj , delete_ , 1 ) , 0 ) )
2009-02-15 06:10:59 +00:00
SCIkwarn ( SCIkWARNING , " Object at " PREG " requested deletion, but does not have "
2009-02-15 22:28:12 +00:00
" a delete funcselector \n " , PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
if ( _k_animate_ran ) {
SCIkwarn ( SCIkWARNING , " Object at " PREG " invoked kAnimate() during deletion! \n " ,
2009-02-15 22:28:12 +00:00
PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
return dropped ;
}
if ( widget - > under_bitsp )
under_bits = * ( ( reg_t * ) ( widget - > under_bitsp ) ) ;
if ( under_bits . segment ) {
* ( ( reg_t * ) ( widget - > under_bitsp ) ) = make_reg ( 0 , 0 ) ;
graph_restore_box ( s , under_bits ) ;
}
SCIkdebug ( SCIkGRAPHICS , " Freeing " PREG " with signal=%04x \n " ,
2009-02-15 22:28:12 +00:00
PRINT_REG ( obj ) , signal ) ;
2009-02-15 06:10:59 +00:00
if ( ! ( signal & _K_VIEW_SIG_FLAG_HIDDEN ) ) {
SCIkdebug ( SCIkGRAPHICS , " Adding view at " PREG " to background \n " ,
2009-02-15 22:28:12 +00:00
PRINT_REG ( obj ) ) ;
2009-02-15 06:10:59 +00:00
if ( ! ( gfxw_remove_id ( widget - > parent , widget - > ID , widget - > subID ) = = GFXW ( widget ) ) ) {
SCIkwarn ( SCIkERROR , " Attempt to remove view with ID %x:%x from list failed! \n " ,
2009-02-15 22:28:12 +00:00
widget - > ID , widget - > subID ) ;
2009-02-15 06:10:59 +00:00
BREAKPOINT ( ) ;
}
s - > drop_views - > add ( GFXWC ( s - > drop_views ) , GFXW ( gfxw_picviewize_dynview ( widget ) ) ) ;
draw_obj_to_control_map ( s , widget ) ;
widget - > draw_bounds . y + = s - > dyn_views - > bounds . y - widget - > parent - > bounds . y ;
widget - > draw_bounds . x + = s - > dyn_views - > bounds . x - widget - > parent - > bounds . x ;
dropped = 1 ;
2009-02-15 22:28:12 +00:00
} else {
2009-02-15 06:10:59 +00:00
SCIkdebug ( SCIkGRAPHICS , " Deleting view at " PREG " \n " , PRINT_REG ( obj ) ) ;
widget - > flags | = GFXW_FLAG_VISIBLE ;
gfxw_annihilate ( GFXW ( widget ) ) ;
return - 1 ; /* restart: Done in Animate() */
}
}
}
}
}
return dropped ;
}
# define _K_MAKE_VIEW_LIST_CYCLE 1
# define _K_MAKE_VIEW_LIST_CALC_PRIORITY 2
# define _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP 4
static gfxw_dyn_view_t *
2009-02-15 22:28:12 +00:00
_k_make_dynview_obj ( state_t * 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 ;
reg_t * under_bitsp , * signalp ;
point_t pos ;
int z ;
gfxw_dyn_view_t * widget ;
SCIkdebug ( SCIkGRAPHICS , " - Adding " PREG " \n " , PRINT_REG ( obj ) ) ;
obj = obj ;
pos . x = GET_SEL32SV ( obj , x ) ;
pos . y = GET_SEL32SV ( obj , y ) ;
pos . y + + ; /* magic: Sierra appears to do something like this */
z = GET_SEL32SV ( obj , z ) ;
/* !-- nsRect used to be checked here! */
loop = oldloop = sign_extend_byte ( GET_SEL32V ( obj , loop ) ) ;
cel = oldcel = sign_extend_byte ( GET_SEL32V ( obj , cel ) ) ;
if ( s - > selector_map . palette )
2009-02-15 22:28:12 +00:00
palette = GET_SEL32V ( obj , palette ) ;
else
palette = 0 ;
2009-02-15 06:10:59 +00:00
/* Clip loop and cel, write back if neccessary */
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 ) ;
}
if ( lookup_selector ( s , obj , s - > selector_map . underBits , & ( under_bitsp ) , NULL )
2009-02-15 22:28:12 +00:00
! = SELECTOR_VARIABLE ) {
2009-02-15 06:10:59 +00:00
under_bitsp = NULL ;
under_bits = NULL_REG ;
SCIkdebug ( SCIkGRAPHICS , " Object at " PREG " has no underBits \n " , PRINT_REG ( obj ) ) ;
} else
under_bits = * ( ( reg_t * ) under_bitsp ) ;
if ( lookup_selector ( s , obj , s - > selector_map . signal , & ( signalp ) , NULL )
2009-02-15 22:28:12 +00:00
! = SELECTOR_VARIABLE ) {
2009-02-15 06:10:59 +00:00
signalp = NULL ;
signal = 0 ;
SCIkdebug ( SCIkGRAPHICS , " Object at " PREG " has no signal selector \n " , PRINT_REG ( obj ) ) ;
} else {
signal = signalp - > offset ;
SCIkdebug ( SCIkGRAPHICS , " with signal = %04x \n " , signal ) ;
}
widget = gfxw_new_dyn_view ( s - > gfx_state , pos , z , view_nr , loop , cel , palette ,
2009-02-15 22:28:12 +00:00
- 1 , - 1 , ALIGN_CENTER , ALIGN_BOTTOM , nr ) ;
2009-02-15 06:10:59 +00:00
if ( widget ) {
widget = ( gfxw_dyn_view_t * ) gfxw_set_id ( GFXW ( widget ) , obj . segment , obj . offset ) ;
widget = gfxw_dyn_view_set_params ( widget , under_bits . segment ,
2009-02-15 22:28:12 +00:00
under_bitsp , signal , signalp ) ;
2009-02-15 06:10:59 +00:00
widget - > flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ; /* Only works the first time 'round */
return widget ;
} else {
SCIkwarn ( SCIkWARNING , " Could not generate dynview widget for %d/%d/%d \n " , view_nr , loop , cel ) ;
return NULL ;
}
}
static void
_k_make_view_list ( state_t * s , gfxw_list_t * * widget_list , list_t * list , int options ,
2009-02-15 22:28:12 +00:00
int funct_nr , int argc , reg_t * argv )
/* Creates a view_list from a node list in heap space. Returns the list, stores the
* * number of list entries in * list_nr . Calls doit for each entry if cycle is set .
* * argc , argv , funct_nr should be the same as in the calling kernel function .
*/
2009-02-15 06:10:59 +00:00
{
node_t * node ;
int sequence_nr = 0 ;
gfxw_dyn_view_t * widget ;
if ( ! * widget_list ) {
SCIkwarn ( SCIkERROR , " make_view_list with widget_list == () \n " ) ;
BREAKPOINT ( ) ;
} ;
assert_primary_widget_lists ( s ) ;
/* In case one of the views' doit() does a DrawPic... */
/* Yes, this _does_ happen! */
if ( ! list ) { /* list sanity check */
SCIkwarn ( SCIkERROR , " Attempt to make list from non-list! \n " ) ;
BREAKPOINT ( ) ;
}
node = LOOKUP_NODE ( list - > first ) ;
while ( node ) {
reg_t obj = node - > value ; /* The object we're using */
reg_t next_node ;
2009-02-15 15:06:14 +00:00
gfxw_dyn_view_t * 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 ) ) {
SCIkdebug ( SCIkGRAPHICS , " invoking " PREG " ::doit() \n " , PRINT_REG ( obj ) ) ;
invoke_selector ( INV_SEL ( obj , doit , 1 ) , 0 ) ; /* Call obj::doit() if neccessary */
}
}
next_node = node - > succ ; /* In case the cast list was changed */
if ( list - > first . segment = = 0 & &
2009-02-15 22:28:12 +00:00
list - > first . offset = = 0 ) /* The cast list was completely emptied! */
2009-02-15 06:10:59 +00:00
break ;
2009-02-15 15:06:14 +00:00
tempWidget = _k_make_dynview_obj ( s , obj , options , sequence_nr - - ,
2009-02-15 22:28:12 +00:00
funct_nr , argc , argv ) ;
if ( tempWidget )
2009-02-15 15:06:14 +00:00
GFX_ASSERT ( ( * widget_list ) - > add ( GFXWC ( * widget_list ) , GFXW ( tempWidget ) ) ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
node = LOOKUP_NODE ( next_node ) ; /* Next node */
}
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
widget = ( gfxw_dyn_view_t * ) ( * widget_list ) - > contents ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
while ( widget ) { /* Read back widget values */
2009-02-15 06:10:59 +00:00
if ( widget - > signalp )
widget - > signal = ( ( reg_t * ) ( widget - > signalp ) ) - > offset ;
widget = ( gfxw_dyn_view_t * ) widget - > next ;
}
}
static void
2009-02-15 22:28:12 +00:00
_k_prepare_view_list ( state_t * s , gfxw_list_t * list , int options ) {
2009-02-15 06:10:59 +00:00
gfxw_dyn_view_t * view = ( gfxw_dyn_view_t * ) list - > contents ;
while ( view ) {
reg_t obj = make_reg ( view - > ID , view - > subID ) ;
int priority , _priority ;
2009-02-15 22:28:12 +00:00
int has_nsrect = ( view - > ID < = 0 ) ? 0 : lookup_selector ( s , obj , s - > selector_map . nsBottom , NULL , NULL ) = = SELECTOR_VARIABLE ;
2009-02-15 06:10:59 +00:00
int oldsignal = view - > signal ;
_k_set_now_seen ( s , obj ) ;
_priority = /*GET_SELECTOR(obj, y); */ ( ( view - > pos . y ) ) ; /**/
_priority = _find_view_priority ( s , _priority - 1 ) ;
if ( options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) { /* Picview */
priority = GET_SEL32SV ( obj , priority ) ;
if ( priority < 0 )
priority = _priority ; /* Always for picviews */
} else { /* Dynview */
if ( has_nsrect
2009-02-15 22:28:12 +00:00
& & ! ( 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 ;
} else /* DON'T calculate the priority */
priority = GET_SEL32SV ( obj , priority ) ;
}
view - > color . priority = priority ;
if ( priority > - 1 )
view - > color . mask | = GFX_MASK_PRIORITY ;
else
view - > color . mask & = ~ GFX_MASK_PRIORITY ;
/* CR (from :Bob Heitman:) stopupdated views (like pic views) have
* * their clipped nsRect drawn to the control map */
if ( view - > signal & _K_VIEW_SIG_FLAG_STOP_UPDATE ) {
view - > signal | = _K_VIEW_SIG_FLAG_FREESCI_STOPUPD ;
SCIkdebug ( SCIkGRAPHICS , " Setting magic STOP_UPD for " PREG " \n " , PRINT_REG ( obj ) ) ;
}
if ( ( options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) )
draw_obj_to_control_map ( s , view ) ;
/* Extreme Pattern Matching ugliness ahead... */
2009-02-15 22:28:12 +00:00
if ( view - > signal & _K_VIEW_SIG_FLAG_NO_UPDATE ) {
if ( ( ( view - > signal & ( _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_FORCE_UPDATE ) ) ) /* 9.1.1.1 */
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE ) ) = = _K_VIEW_SIG_FLAG_HIDDEN )
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE ) ) = = _K_VIEW_SIG_FLAG_REMOVE ) /* 9.1.1.2 */
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) /* 9.1.1.3 */
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) ) { /* 9.1.1.4 */
s - > pic_not_valid + + ;
view - > signal & = ~ _K_VIEW_SIG_FLAG_STOP_UPDATE ;
}
else if ( ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = 0 )
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE ) )
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) )
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = _K_VIEW_SIG_FLAG_HIDDEN ) ) {
view - > signal & = ~ _K_VIEW_SIG_FLAG_STOP_UPDATE ;
}
} else {
if ( view - > signal & _K_VIEW_SIG_FLAG_STOP_UPDATE ) {
s - > pic_not_valid + + ;
view - > signal & = ~ _K_VIEW_SIG_FLAG_FORCE_UPDATE ;
} else { /* if not STOP_UPDATE */
if ( view - > signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE )
s - > pic_not_valid + + ;
view - > signal & = ~ _K_VIEW_SIG_FLAG_FORCE_UPDATE ;
}
2009-02-15 06:10:59 +00:00
}
SCIkdebug ( SCIkGRAPHICS , " dv[ " PREG " ]: signal %04x -> %04x \n " , PRINT_REG ( obj ) , oldsignal , view - > signal ) ;
/* Never happens
if ( view - > signal & 0 ) {
view - > signal & = ~ _K_VIEW_SIG_FLAG_FREESCI_STOPUPD ;
fprintf ( stderr , " Unsetting magic StopUpd for view " PREG " \n " , PRINT_REG ( obj ) ) ;
} */
view = ( gfxw_dyn_view_t * ) view - > next ;
}
}
static void
2009-02-15 22:28:12 +00:00
_k_update_signals_in_view_list ( gfxw_list_t * old_list , gfxw_list_t * new_list ) { /* O(n^2)... a bit painful, but much faster than the redraws it helps prevent */
2009-02-15 06:10:59 +00:00
gfxw_dyn_view_t * old_widget = ( gfxw_dyn_view_t * ) old_list - > contents ;
/* Traverses all old widgets, updates them with signals from the new widgets.
* * This is done to avoid evil hacks in widget . c ; widgets with unique IDs are
* * replaced there iff they are NOT equal_to a new widget with the same ID .
* * If they were replaced every time , we ' d be doing far too many redraws .
*/
while ( old_widget ) {
gfxw_dyn_view_t * new_widget = ( gfxw_dyn_view_t * ) new_list - > contents ;
while ( new_widget
2009-02-15 22:28:12 +00:00
& & ( new_widget - > ID ! = old_widget - > ID
| | new_widget - > subID ! = old_widget - > subID ) )
2009-02-15 06:10:59 +00:00
new_widget = ( gfxw_dyn_view_t * ) new_widget - > next ;
if ( new_widget ) {
int carry = old_widget - > signal & _K_VIEW_SIG_FLAG_FREESCI_STOPUPD ;
/* Transfer 'stopupd' flag */
if ( ( new_widget - > pos . x ! = old_widget - > pos . x )
2009-02-15 22:28:12 +00:00
| | ( new_widget - > pos . y ! = old_widget - > pos . y )
/* ** No idea why this is supposed to be bad **
| | ( new_widget - > z ! = old_widget - > z )
| | ( new_widget - > view ! = old_widget - > view )
| | ( new_widget - > loop ! = old_widget - > loop )
| | ( new_widget - > cel ! = old_widget - > cel )
*/
)
2009-02-15 06:10:59 +00:00
carry = 0 ;
old_widget - > signal = new_widget - > signal | = carry ;
}
old_widget = ( gfxw_dyn_view_t * ) old_widget - > next ;
}
}
static void
2009-02-15 22:28:12 +00:00
_k_view_list_kryptonize ( gfxw_widget_t * v ) {
2009-02-15 06:10:59 +00:00
if ( v ) {
v - > flags & = ~ GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
_k_view_list_kryptonize ( v - > next ) ;
}
}
static void
2009-02-15 22:28:12 +00:00
_k_raise_topmost_in_view_list ( state_t * s , gfxw_list_t * list , gfxw_dyn_view_t * view ) {
2009-02-15 06:10:59 +00:00
if ( view ) {
gfxw_dyn_view_t * next = ( gfxw_dyn_view_t * ) view - > next ;
/* step 11 */
if ( ( view - > signal & ( _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = 0 ) {
SCIkdebug ( SCIkGRAPHICS , " Forcing precedence 2 at [ " PREG " ] with %04x \n " , PRINT_REG ( make_reg ( view - > ID , view - > subID ) ) , view - > signal ) ;
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
}
gfxw_remove_widget_from_container ( view - > parent , GFXW ( view ) ) ;
gfxw_widget_reparent_chrono ( s - > visual , GFXW ( view ) , GFXWC ( list ) ) ;
if ( view - > signal & _K_VIEW_SIG_FLAG_HIDDEN )
gfxw_hide_widget ( GFXW ( view ) ) ;
2009-02-15 22:28:12 +00:00
else
2009-02-15 06:10:59 +00:00
gfxw_show_widget ( GFXW ( view ) ) ;
list - > add ( GFXWC ( list ) , GFXW ( view ) ) ;
_k_raise_topmost_in_view_list ( s , list , next ) ;
}
}
static void
2009-02-15 22:28:12 +00:00
_k_redraw_view_list ( state_t * s , gfxw_list_t * list ) {
2009-02-15 06:10:59 +00:00
gfxw_dyn_view_t * view = ( gfxw_dyn_view_t * ) list - > contents ;
while ( view ) {
SCIkdebug ( SCIkGRAPHICS , " dv[ " PREG " ]: signal %04x \n " , make_reg ( view - > ID , view - > subID ) , view - > signal ) ;
/* step 1 of subalgorithm */
if ( view - > signal & _K_VIEW_SIG_FLAG_NO_UPDATE ) {
if ( view - > signal & _K_VIEW_SIG_FLAG_FORCE_UPDATE )
view - > signal & = ~ _K_VIEW_SIG_FLAG_FORCE_UPDATE ;
if ( view - > signal & _K_VIEW_SIG_FLAG_UPDATED )
view - > signal & = ~ ( _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE ) ;
} else { /* NO_UPD is not set */
if ( view - > signal & _K_VIEW_SIG_FLAG_STOP_UPDATE ) {
view - > signal & = ~ _K_VIEW_SIG_FLAG_STOP_UPDATE ;
view - > signal | = _K_VIEW_SIG_FLAG_NO_UPDATE ;
}
}
SCIkdebug ( SCIkGRAPHICS , " at substep 6: signal %04x \n " , view - > signal ) ;
if ( view - > signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE )
view - > signal & = ~ ( _K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED
2009-02-15 22:28:12 +00:00
| _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE ) ;
2009-02-15 06:10:59 +00:00
SCIkdebug ( SCIkGRAPHICS , " at substep 11/14: signal %04x \n " , view - > signal ) ;
if ( view - > signal & _K_VIEW_SIG_FLAG_NO_UPDATE ) {
if ( view - > signal & _K_VIEW_SIG_FLAG_HIDDEN )
view - > signal | = _K_VIEW_SIG_FLAG_REMOVE ;
else
view - > signal & = ~ _K_VIEW_SIG_FLAG_REMOVE ;
} else if ( ! ( view - > signal & _K_VIEW_SIG_FLAG_HIDDEN ) )
view - > force_precedence = 1 ;
SCIkdebug ( SCIkGRAPHICS , " -> signal %04x \n " , view - > signal ) ;
view = ( gfxw_dyn_view_t * ) view - > next ;
}
}
/* Flags for _k_draw_view_list */
/* Whether some magic with the base object's "signal" selector should be done: */
# define _K_DRAW_VIEW_LIST_USE_SIGNAL 1
/* This flag draws all views with the "DISPOSE_ME" flag set: */
# define _K_DRAW_VIEW_LIST_DISPOSEABLE 2
/* Use this one to draw all views with "DISPOSE_ME" NOT set: */
# define _K_DRAW_VIEW_LIST_NONDISPOSEABLE 4
/* Draw as picviews */
# define _K_DRAW_VIEW_LIST_PICVIEW 8
void
_k_draw_view_list ( state_t * s , gfxw_list_t * list , int flags )
2009-02-15 22:28:12 +00:00
/* Draws list_nr members of list to s->pic. */
2009-02-15 06:10:59 +00:00
{
gfxw_dyn_view_t * widget = ( gfxw_dyn_view_t * ) list - > contents ;
if ( GFXWC ( s - > port ) ! = GFXWC ( s - > dyn_views - > parent ) )
return ; /* Return if the pictures are meant for a different port */
while ( widget ) {
if ( flags & _K_DRAW_VIEW_LIST_PICVIEW )
widget = gfxw_picviewize_dynview ( widget ) ;
if ( GFXW_IS_DYN_VIEW ( widget ) & & widget - > ID ) {
2009-02-15 22:28:12 +00:00
word signal = ( flags & _K_DRAW_VIEW_LIST_USE_SIGNAL ) ? ( ( reg_t * ) ( widget - > signalp ) ) - > offset : 0 ;
2009-02-15 06:10:59 +00:00
if ( signal & _K_VIEW_SIG_FLAG_HIDDEN )
gfxw_hide_widget ( GFXW ( widget ) ) ;
else
gfxw_show_widget ( GFXW ( widget ) ) ;
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 ) {
signal & = ~ ( _K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED |
2009-02-15 22:28:12 +00:00
_K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE ) ;
2009-02-15 06:10:59 +00:00
/* Clear all of those flags */
if ( signal & _K_VIEW_SIG_FLAG_HIDDEN )
gfxw_hide_widget ( GFXW ( widget ) ) ;
else
gfxw_show_widget ( GFXW ( widget ) ) ;
* ( ( reg_t * ) ( widget - > signalp ) ) = make_reg ( 0 , signal ) ; /* Write the changes back */
} ;
} /* ...if we're drawing disposeables and this one is disposeable, or if we're drawing non-
* * disposeables and this one isn ' t disposeable */
}
widget = ( gfxw_dyn_view_t * ) widget - > next ;
} /* while (widget) */
}
reg_t
2009-02-15 22:28:12 +00:00
kAddToPic ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
gfxw_list_t * pic_views ;
reg_t list_ref = argv [ 0 ] ;
assert_primary_widget_lists ( s ) ;
if ( argc > 1 ) {
int view , cel , loop , x , y , priority , control ;
gfxw_widget_t * widget ;
view = KP_UINT ( argv [ 0 ] ) ;
loop = KP_UINT ( argv [ 1 ] ) ;
cel = KP_UINT ( argv [ 2 ] ) ;
x = KP_SINT ( argv [ 3 ] ) ;
y = KP_SINT ( argv [ 4 ] ) + 1 /* magic + 1 */ ;
priority = KP_SINT ( argv [ 5 ] ) ;
control = KP_SINT ( argv [ 6 ] ) ;
widget = GFXW ( gfxw_new_dyn_view ( s - > gfx_state , gfx_point ( x , y ) , 0 , view , loop , cel , 0 ,
2009-02-15 22:28:12 +00:00
priority , - 1 /* No priority */ , ALIGN_CENTER , ALIGN_BOTTOM , 0 ) ) ;
2009-02-15 06:10:59 +00:00
if ( ! widget ) {
SCIkwarn ( SCIkERROR , " Attempt to single-add invalid picview (%d/%d/%d) \n " , view , loop , cel ) ;
} else {
widget - > ID = - 1 ;
if ( control > = 0 ) {
abs_rect_t abs_zone = nsrect_clip ( s , y ,
2009-02-15 22:28:12 +00:00
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 ) ;
}
ADD_TO_CURRENT_PICTURE_PORT ( gfxw_picviewize_dynview ( ( gfxw_dyn_view_t * ) widget ) ) ;
}
} else {
list_t * list ;
if ( ! list_ref . segment ) {
SCIkdebug ( SCIkWARNING , " Attempt to AddToPic single non-list: " PREG " \n " ,
2009-02-15 22:28:12 +00:00
PRINT_REG ( list_ref ) ) ;
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
2009-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
list = LOOKUP_LIST ( list_ref ) ;
pic_views = gfxw_new_list ( s - > picture_port - > bounds , 1 ) ;
SCIkdebug ( SCIkGRAPHICS , " Preparing picview list... \n " ) ;
_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 ) ;
/* Store pic views for later re-use */
SCIkdebug ( SCIkGRAPHICS , " Drawing picview list... \n " ) ;
ADD_TO_CURRENT_PICTURE_PORT ( pic_views ) ;
_k_draw_view_list ( s , pic_views , _K_DRAW_VIEW_LIST_NONDISPOSEABLE | _K_DRAW_VIEW_LIST_DISPOSEABLE | _K_DRAW_VIEW_LIST_PICVIEW ) ;
/* Draw relative to the bottom center */
SCIkdebug ( SCIkGRAPHICS , " Returning. \n " ) ;
}
reparentize_primary_widget_lists ( s , s - > port ) ;
return s - > r_acc ;
}
reg_t
2009-02-15 22:28:12 +00:00
kGetPort ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
return make_reg ( 0 , s - > port - > ID ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kSetPort ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
if ( activated_icon_bar & & argc = = 6 ) {
2009-02-15 06:10:59 +00:00
port_origin_x = port_origin_y = 0 ;
activated_icon_bar = 0 ;
return s - > r_acc ;
}
2009-02-15 22:28:12 +00:00
switch ( argc ) {
2009-02-15 06:10:59 +00:00
case 1 : {
unsigned int port_nr = SKPV ( 0 ) ;
gfxw_port_t * new_port ;
/* 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-02-15 22:28:12 +00:00
if ( port_nr = = ( unsigned int ) - 1 ) port_nr = s - > iconbar_port - > ID ;
2009-02-15 06:10:59 +00:00
new_port = gfxw_find_port ( s - > visual , port_nr ) ;
if ( ! new_port ) {
SCIkwarn ( SCIkERROR , " Invalid port %04x requested \n " , port_nr ) ;
return NULL_REG ;
}
s - > port - > draw ( GFXW ( s - > port ) , gfxw_point_zero ) ; /* Update the port we're leaving */
s - > port = new_port ;
return s - > r_acc ;
}
case 6 : {
port_origin_y = SKPV ( 0 ) ;
port_origin_x = SKPV ( 1 ) ;
2009-02-15 22:28:12 +00:00
if ( SKPV ( 0 ) = = - 10 ) {
2009-02-15 06:10:59 +00:00
s - > port - > draw ( GFXW ( s - > port ) , gfxw_point_zero ) ; /* Update the port we're leaving */
s - > port = s - > iconbar_port ;
activated_icon_bar = 1 ;
return s - > r_acc ;
}
s - > gfx_state - > options - > pic_port_bounds = gfx_rect ( UKPV ( 5 ) , UKPV ( 4 ) ,
2009-02-15 22:28:12 +00:00
UKPV ( 3 ) , UKPV ( 2 ) ) ;
2009-02-15 06:10:59 +00:00
/* FIXME: Should really only invalidate all loaded pic resources here;
this is overkill */
gfxr_free_all_resources ( s - > gfx_state - > driver , s - > gfx_state - > resstate ) ;
break ;
}
default :
SCIkwarn ( SCIkERROR , " SetPort was called with %d parameters \n " , argc ) ;
break ;
}
return NULL_REG ;
}
static inline void
2009-02-15 22:28:12 +00:00
add_to_chrono ( state_t * s , gfxw_widget_t * widget ) {
2009-02-15 06:10:59 +00:00
gfxw_port_t * chrono_port ;
gfxw_list_t * tw ;
chrono_port = gfxw_get_chrono_port ( s - > visual , & tw , 0 ) ;
tw - > add ( GFXWC ( tw ) , widget ) ;
if ( ! chrono_port - > parent )
ADD_TO_CURRENT_PORT ( chrono_port ) ;
}
reg_t
2009-02-15 22:28:12 +00:00
kDrawCel ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int view = SKPV ( 0 ) ;
int loop = SKPV ( 1 ) ;
int cel = SKPV ( 2 ) ;
int x = SKPV ( 3 ) ;
int y = SKPV ( 4 ) ;
int priority = SKPV_OR_ALT ( 5 , - 1 ) ;
gfxw_view_t * new_view ;
2009-02-15 22:28:12 +00:00
/*
if ( ! view ) {
SCIkwarn ( SCIkERROR , " Attempt to draw non-existing view.%03d \n " , view ) ;
return ;
}
*/
2009-02-15 06:10:59 +00:00
if ( gfxop_check_cel ( s - > gfx_state , view , & loop , & cel ) ) {
SCIkwarn ( SCIkERROR , " Attempt to draw non-existing view.%03d \n " , view ) ;
return s - > r_acc ;
}
SCIkdebug ( SCIkGRAPHICS , " DrawCel((%d,%d), (view.%d, %d, %d), p=%d) \n " , x , y , view , loop ,
2009-02-15 22:28:12 +00:00
cel , priority ) ;
2009-02-15 06:10:59 +00:00
new_view = gfxw_new_view ( s - > gfx_state , gfx_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
#if 0
add_to_chrono ( s , GFXW ( new_view ) ) ;
# else
ADD_TO_CURRENT_PICTURE_PORT ( GFXW ( new_view ) ) ;
# endif
FULL_REDRAW ( ) ;
2009-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
return s - > r_acc ;
}
reg_t
2009-02-15 22:28:12 +00:00
kDisposeWindow ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
unsigned int goner_nr = SKPV ( 0 ) ;
gfxw_port_t * goner ;
gfxw_port_t * pred ;
int id = s - > visual - > port_refs_nr ;
gfxw_widget_kill_chrono ( s - > visual , goner_nr ) ;
goner = gfxw_find_port ( s - > visual , goner_nr ) ;
if ( ( goner_nr < 3 ) | | ( goner = = NULL ) ) {
SCIkwarn ( SCIkERROR , " Removal of invalid window %04x requested \n " , goner_nr ) ;
return s - > r_acc ;
}
if ( s - > dyn_views & & GFXWC ( s - > dyn_views - > parent ) = = GFXWC ( goner ) ) {
reparentize_primary_widget_lists ( s , ( gfxw_port_t * ) goner - > parent ) ;
}
if ( s - > drop_views & & GFXWC ( s - > drop_views - > parent ) = = GFXWC ( goner ) )
s - > drop_views = NULL ; /* Kill it */
pred = gfxw_remove_port ( s - > visual , goner ) ;
if ( goner = = s - > port ) /* Did we kill the active port? */
s - > port = pred ;
2009-02-15 22:28:12 +00:00
/* Find the last port that exists and that isn't marked no-switch */
2009-02-15 06:10:59 +00:00
while ( ( ! s - > visual - > port_refs [ id ] & & id > = 0 ) | |
2009-02-15 22:28:12 +00:00
( s - > visual - > port_refs [ id ] - > flags & GFXW_FLAG_NO_IMPLICIT_SWITCH ) )
2009-02-15 06:10:59 +00:00
id - - ;
sciprintf ( " Activating port %d after disposing window %d \n " , id , goner_nr ) ;
s - > port = s - > visual - > port_refs [ id ] ;
if ( ! s - > port )
s - > port = gfxw_find_default_port ( s - > visual ) ;
gfxop_update ( s - > gfx_state ) ;
return s - > r_acc ;
}
reg_t
2009-02-15 22:28:12 +00:00
kNewWindow ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
gfxw_port_t * window ;
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 ;
int argextra = argc = = 13 ? 4 : 0 ; /* Triggers in PQ3 */
y = SKPV ( 0 ) ;
x = SKPV ( 1 ) ;
yl = SKPV ( 2 ) - y ;
xl = SKPV ( 3 ) - x ;
y + = s - > wm_port - > bounds . y ;
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-02-15 22:28:12 +00:00
flags = SKPV ( 5 + argextra ) ;
2009-02-15 06:10:59 +00:00
2009-02-15 22:28:12 +00:00
priority = SKPV_OR_ALT ( 6 + argextra , - 1 ) ;
2009-02-15 06:10:59 +00:00
bgcolor . mask = 0 ;
2009-02-15 22:28:12 +00:00
if ( SKPV_OR_ALT ( 8 + argextra , 255 ) > = 0 ) {
2009-02-15 06:10:59 +00:00
if ( s - > resmgr - > sci_version < SCI_VERSION_01_VGA )
2009-02-15 22:28:12 +00:00
bgcolor . visual = * ( get_pic_color ( s , SKPV_OR_ALT ( 8 + argextra , 15 ) ) ) ;
2009-02-15 06:10:59 +00:00
else
2009-02-15 22:28:12 +00:00
bgcolor . visual = * ( get_pic_color ( s , SKPV_OR_ALT ( 8 + argextra , 255 ) ) ) ;
2009-02-15 06:10:59 +00:00
bgcolor . mask = GFX_MASK_VISUAL ;
}
bgcolor . priority = priority ;
bgcolor . mask | = priority > = 0 ? GFX_MASK_PRIORITY : 0 ;
bgcolor . alpha = 0 ;
SCIkdebug ( SCIkGRAPHICS , " New window with params %d, %d, %d, %d \n " , SKPV ( 0 ) , SKPV ( 1 ) , SKPV ( 2 ) , SKPV ( 3 ) ) ;
2009-02-15 22:28:12 +00:00
fgcolor . visual = * ( get_pic_color ( s , SKPV_OR_ALT ( 7 + argextra , 0 ) ) ) ;
2009-02-15 06:10:59 +00:00
fgcolor . mask = GFX_MASK_VISUAL ;
fgcolor . alpha = 0 ;
black . visual = * ( get_pic_color ( s , 0 ) ) ;
black . mask = GFX_MASK_VISUAL ;
black . alpha = 0 ;
2009-02-15 15:06:14 +00:00
lWhite . visual = * ( get_pic_color ( s , s - > resmgr - > sci_version < SCI_VERSION_01_VGA ? 15 : 255 ) ) ,
2009-02-15 22:28:12 +00:00
lWhite . mask = GFX_MASK_VISUAL ;
2009-02-15 15:06:14 +00:00
lWhite . alpha = 0 ;
2009-02-15 06:10:59 +00:00
window = sciw_new_window ( s , gfx_rect ( x , y , xl , yl ) , s - > titlebar_port - > font_nr ,
2009-02-15 22:28:12 +00:00
fgcolor , bgcolor , s - > titlebar_port - > font_nr ,
lWhite ,
black ,
argv [ 4 + argextra ] . segment ? kernel_dereference_char_pointer ( s , argv [ 4 + argextra ] , 0 ) : NULL ,
flags ) ;
2009-02-15 06:10:59 +00:00
/* PQ3 has the interpreter store underBits implicitly.
The feature was promptly removed after its release , never to be seen again . */
if ( argextra )
2009-02-15 22:28:12 +00:00
gfxw_port_auto_restore_background ( s - > visual , window ,
gfx_rect ( SKPV ( 5 ) , SKPV ( 4 ) ,
SKPV ( 7 ) - SKPV ( 5 ) , SKPV ( 6 ) - SKPV ( 4 ) ) ) ;
2009-02-15 06:10:59 +00:00
ADD_TO_WINDOW_PORT ( window ) ;
FULL_REDRAW ( ) ;
window - > draw ( GFXW ( window ) , gfxw_point_zero ) ;
gfxop_update ( s - > gfx_state ) ;
s - > port = window ; /* Set active port */
return make_reg ( 0 , window - > ID ) ;
}
# 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,
2009-02-15 22:28:12 +00:00
* * reopen from edges to center */
2009-02-15 06:10:59 +00:00
# define K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F 16 / * close from edges to center, reopen from
2009-02-15 22:28:12 +00:00
* * center to edges */
2009-02-15 06:10:59 +00:00
# define K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS 17 /* close random checkboard, reopen */
# define K_ANIMATE_SCROLL_LEFT 0x28
# define K_ANIMATE_SCROLL_RIGHT 0x29
# define K_ANIMATE_SCROLL_DOWN 0x2a
# define K_ANIMATE_SCROLL_UP 0x2b
# define K_ANIMATE_OPEN_SIMPLE 100 /* No animation */
# define GRAPH_BLANK_BOX(s, x, y, xl, yl, color) GFX_ASSERT(gfxop_fill_box(s->gfx_state, \
gfx_rect ( x , ( ( ( y ) < 10 ) ? 10 : ( y ) ) , xl , ( ( ( y ) < 10 ) ? ( ( y ) - 10 ) : 0 ) + ( yl ) ) , s - > ega_colors [ color ] ) ) ;
# define GRAPH_UPDATE_BOX(s, x, y, xl, yl) GFX_ASSERT(gfxop_draw_pixmap(s->gfx_state, newscreen, \
gfx_rect ( x , ( ( ( y ) < 10 ) ? 10 : ( y ) ) - 10 , xl , ( ( ( y ) < 10 ) ? ( ( y ) - 10 ) : 0 ) + ( yl ) ) , gfx_point ( x , ( ( y ) < 10 ) ? 10 : ( y ) ) ) ) ;
static void
2009-02-15 22:28:12 +00:00
animate_do_animation ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
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 ) {
SCIkwarn ( SCIkERROR , " Failed to allocate 'newscreen'! \n " ) ;
return ;
}
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen , gfx_rect ( 0 , 0 , 320 , 190 ) , gfx_point ( 0 , 10 ) ) ) ;
gfxop_update_box ( s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 200 ) ) ;
/*SCIkdebug(SCIkGRAPHICS, "Animating pic opening type %x\n", s->pic_animate);*/
gfxop_enable_dirty_frames ( s - > gfx_state ) ;
if ( s - > animation_delay < 1 )
s - > pic_animate = K_ANIMATE_OPEN_SIMPLE ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay ) ;
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V :
for ( i = 0 ; i < 94 + granularity2 ; i + = granularity2 ) {
GRAPH_BLANK_BOX ( s , 0 , i + 10 , 320 , granularity2 , 0 ) ;
gfxop_update ( s - > gfx_state ) ;
GRAPH_BLANK_BOX ( s , 0 , 199 - i , 320 , granularity2 , 0 ) ;
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 2 * s - > animation_delay ) ;
process_sound_events ( s ) ;
}
GRAPH_BLANK_BOX ( s , 0 , 10 , 320 , 190 , 0 ) ;
case K_ANIMATE_CENTER_OPEN_V :
for ( i = 94 ; i > = 1 - granularity2 ; i - = granularity2 ) {
GRAPH_UPDATE_BOX ( s , 0 , i + 10 , 320 , granularity2 ) ;
gfxop_update ( s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( s , 0 , 199 - i , 320 , granularity2 ) ;
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 2 * s - > animation_delay ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay / 2 ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay / 2 ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay / 2 ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay / 2 ) ;
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN :
for ( i = 10 ; i < 199 + granularity1 ; i + = granularity1 ) {
GRAPH_BLANK_BOX ( s , 0 , i , 320 , granularity1 , 0 ) ;
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay ) ;
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 ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay ) ;
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 ;
GRAPH_BLANK_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_BLANK_BOX ( s , 320 - width_l - width ,
2009-02-15 22:28:12 +00:00
10 + height , width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_BLANK_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_BLANK_BOX ( s , width , 200 - height_l - height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 4 * s - > animation_delay ) ;
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 ;
GRAPH_UPDATE_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( s , 320 - width_l - width ,
2009-02-15 22:28:12 +00:00
10 + height , width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( s , width , 200 - height_l - height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 4 * s - > animation_delay ) ;
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 ;
GRAPH_BLANK_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_BLANK_BOX ( s , 320 - width_l - width ,
2009-02-15 22:28:12 +00:00
10 + height , width_l , 190 - 2 * height , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_BLANK_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_BLANK_BOX ( s , width , 200 - height_l - height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l , 0 ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 7 * s - > animation_delay ) ;
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 ;
GRAPH_UPDATE_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( s , 320 - width_l - width ,
2009-02-15 22:28:12 +00:00
10 + height , width_l , 190 - 2 * height ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( s , width , 10 + height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( s , width , 200 - height_l - height ,
2009-02-15 22:28:12 +00:00
320 - 2 * width , height_l ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 7 * s - > animation_delay ) ;
process_sound_events ( s ) ;
}
break ;
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 )
if ( checkers [ + + i ] = = 0 ) - - checker ;
checkers [ i ] = 1 ; /* Mark checker as used */
x = i % 32 ;
y = i / 32 ;
GRAPH_BLANK_BOX ( s , x * 10 , 10 + y * 10 , 10 , 10 , 0 ) ;
if ( ! ( update_counter - - ) | | ( remaining_checkers = = 1 ) ) {
gfxop_update ( s - > gfx_state ) ;
update_counter = granularity1 ;
}
if ( remaining_checkers & 1 ) {
gfxop_usleep ( s - > gfx_state , s - > animation_delay / 4 ) ;
}
- - 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 ;
checkers [ i ] = 1 ; /* Mark checker as used */
x = i % 32 ;
y = i / 32 ;
GRAPH_UPDATE_BOX ( s , x * 10 , 10 + y * 10 , 10 , 10 ) ;
if ( ! ( update_counter - - ) | | ( remaining_checkers = = 1 ) ) {
gfxop_update ( s - > gfx_state ) ;
update_counter = granularity1 ;
}
if ( remaining_checkers & 1 ) {
gfxop_usleep ( s - > gfx_state , s - > animation_delay / 4 ) ;
}
- - remaining_checkers ;
process_sound_events ( s ) ;
}
break ;
case K_ANIMATE_SCROLL_LEFT :
for ( i = 0 ; i < 319 ; i + = granularity0 ) {
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( 320 - i , 0 , i , 190 ) ,
gfx_point ( 0 , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( 0 , 0 , 320 - i , 190 ) ,
gfx_point ( i , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay > > 3 ) ;
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
case K_ANIMATE_SCROLL_RIGHT :
for ( i = 0 ; i < 319 ; i + = granularity0 ) {
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( 0 , 0 , i , 190 ) ,
gfx_point ( 319 - i , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( i , 0 , 320 - i , 190 ) ,
gfx_point ( 0 , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay > > 3 ) ;
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
case K_ANIMATE_SCROLL_UP :
for ( i = 0 ; i < 189 ; i + = granularity0 ) {
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( 0 , 190 - i , 320 , i ) ,
gfx_point ( 0 , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( 0 , 0 , 320 , 190 - i ) ,
gfx_point ( 0 , 10 + i ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay > > 3 ) ;
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
case K_ANIMATE_SCROLL_DOWN :
for ( i = 0 ; i < 189 ; i + = granularity0 ) {
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , newscreen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( 0 , 0 , 320 , i ) ,
gfx_point ( 0 , 200 - i ) ) ) ;
2009-02-15 06:10:59 +00:00
GFX_ASSERT ( gfxop_draw_pixmap ( s - > gfx_state , s - > old_screen ,
2009-02-15 22:28:12 +00:00
gfx_rect ( 0 , i , 320 , 190 - i ) ,
gfx_point ( 0 , 10 ) ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , s - > animation_delay > > 3 ) ;
}
GRAPH_UPDATE_BOX ( s , 0 , 10 , 320 , 190 ) ;
break ;
default :
if ( s - > pic_animate ! = K_ANIMATE_OPEN_SIMPLE )
SCIkwarn ( SCIkWARNING , " Unknown opening animation 0x%02x \n " , s - > pic_animate ) ;
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 ;
}
reg_t
kAnimate ( state_t * s , int funct_nr , int argc , reg_t * argv )
2009-02-15 22:28:12 +00:00
/* Animations are supposed to take a maximum of s->animation_delay milliseconds. */
2009-02-15 06:10:59 +00:00
{
reg_t cast_list_ref = KP_ALT ( 0 , NULL_REG ) ;
int cycle = ( KP_ALT ( 1 , NULL_REG ) ) . offset ;
list_t * cast_list = NULL ;
int open_animation = 0 ;
process_sound_events ( s ) ; /* Take care of incoming events (kAnimate is called semi-regularly) */
_k_animate_ran = 1 ; /* Used by some of the invoked functions to check for recursion, which may,
* * after all , damage the cast list */
if ( cast_list_ref . segment ) {
cast_list = LOOKUP_LIST ( cast_list_ref ) ;
if ( ! cast_list )
return s - > r_acc ;
}
open_animation = ( s - > pic_is_new ) & & ( s - > pic_not_valid ) ;
s - > pic_is_new = 0 ;
assert_primary_widget_lists ( s ) ;
if ( ! s - > dyn_views - > contents /* Only reparentize empty dynview list */
2009-02-15 22:28:12 +00:00
& & ( ( GFXWC ( s - > port ) ! = GFXWC ( s - > dyn_views - > parent ) ) /* If dynviews are on other port... */
| | ( 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 ) {
gfxw_list_t * templist = gfxw_new_list ( s - > dyn_views - > bounds , 0 ) ;
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
/* Make sure that none of the doits() did something evil */
assert_primary_widget_lists ( s ) ;
if ( ! s - > dyn_views - > contents /* Only reparentize empty dynview list */
2009-02-15 22:28:12 +00:00
& & ( ( GFXWC ( s - > port ) ! = GFXWC ( s - > dyn_views - > parent ) ) /* If dynviews are on other port... */
| | ( 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 ) ;
/* End of doit() recovery code */
if ( s - > pic_is_new ) { /* Happens if DrawPic() is executed by a dynview (yes, that happens) */
kAnimate ( s , funct_nr , argc , argv ) ; /* Tail-recurse */
return s - > r_acc ;
}
SCIkdebug ( SCIkGRAPHICS , " Handling Dynviews (..step 9 inclusive): \n " ) ;
_k_prepare_view_list ( s , templist , _K_MAKE_VIEW_LIST_CALC_PRIORITY ) ;
if ( s - > pic_not_valid ) {
SCIkdebug ( SCIkGRAPHICS , " PicNotValid=%d -> Subalgorithm: \n " ) ;
_k_redraw_view_list ( s , templist ) ;
}
_k_update_signals_in_view_list ( s - > dyn_views , templist ) ;
s - > dyn_views - > tag ( GFXW ( s - > dyn_views ) ) ;
_k_raise_topmost_in_view_list ( s , s - > dyn_views , ( gfxw_dyn_view_t * ) templist - > contents ) ;
templist - > widfree ( GFXW ( templist ) ) ;
s - > dyn_views - > free_tagged ( GFXWC ( s - > dyn_views ) ) ; /* Free obsolete dynviews */
} /* if (cast_list) */
if ( open_animation ) {
gfxop_clear_box ( s - > gfx_state , gfx_rect ( 0 , 10 , 320 , 190 ) ) ; /* Propagate pic */
s - > visual - > add_dirty_abs ( GFXWC ( s - > visual ) , gfx_rect_fullscreen , 0 ) ;
/* Mark screen as dirty so picviews will be drawn correctly */
FULL_REDRAW ( ) ;
animate_do_animation ( s , funct_nr , argc , argv ) ;
} /* if (open_animation) */
if ( cast_list ) {
int retval ;
int reparentize = 0 ;
s - > pic_not_valid = 0 ;
_k_view_list_do_postdraw ( s , s - > dyn_views ) ;
/* _k_view_list_dispose_loop() returns -1 if it requested a re-start, so we do just that. */
while ( ( retval = _k_view_list_dispose_loop ( s , cast_list , ( gfxw_dyn_view_t * ) s - > dyn_views - > contents , funct_nr , argc , argv ) < 0 ) )
reparentize = 1 ;
if ( s - > drop_views - > contents ) {
s - > drop_views = gfxw_new_list ( s - > dyn_views - > bounds , GFXW_LIST_SORTED ) ;
s - > drop_views - > flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
ADD_TO_CURRENT_PICTURE_PORT ( s - > drop_views ) ;
} else {
assert ( s - > drop_views ) ;
gfxw_remove_widget_from_container ( s - > drop_views - > parent , GFXW ( s - > drop_views ) ) ;
ADD_TO_CURRENT_PICTURE_PORT ( s - > drop_views ) ;
}
if ( ( reparentize | retval )
2009-02-15 22:28:12 +00:00
& & ( GFXWC ( s - > port ) = = GFXWC ( s - > dyn_views - > parent ) ) /* If dynviews are on the same port... */
& & ( s - > dyn_views - > next ) ) /* ... and not on top of the view list... */
2009-02-15 06:10:59 +00:00
reparentize_primary_widget_lists ( s , s - > port ) ; /* ...then reparentize. */
_k_view_list_kryptonize ( s - > dyn_views - > contents ) ;
}
FULL_REDRAW ( ) ;
return s - > r_acc ;
}
# define SHAKE_DOWN 1
# define SHAKE_RIGHT 2
reg_t
2009-02-15 22:28:12 +00:00
kShakeScreen ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int shakes = SKPV_OR_ALT ( 0 , 1 ) ;
int directions = SKPV_OR_ALT ( 1 , 1 ) ;
gfx_pixmap_t * screen = gfxop_grab_pixmap ( s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 200 ) ) ;
int i ;
if ( directions & ~ 3 )
SCIkdebug ( SCIkGRAPHICS , " ShakeScreen(): Direction bits are %x (unknown) \n " , directions ) ;
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-15 22:28:12 +00:00
gfx_point ( shake_right , shake_down ) ) ;
2009-02-15 06:10:59 +00:00
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 50000 ) ;
gfxop_draw_pixmap ( s - > gfx_state , screen , gfx_rect ( 0 , 0 , 320 , 200 ) , gfx_point ( 0 , 0 ) ) ;
gfxop_update ( s - > gfx_state ) ;
gfxop_usleep ( s - > gfx_state , 50000 ) ;
}
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
reg_t
2009-02-15 22:28:12 +00:00
kDisplay ( state_t * s , int funct_nr , int argc , reg_t * argv ) {
2009-02-15 06:10:59 +00:00
int argpt ;
reg_t textp = argv [ 0 ] ;
int index = UKPV_OR_ALT ( 1 , 0 ) ;
int temp ;
int save_under = 0 ;
gfx_color_t transparent ;
char * text ;
2009-02-15 22:28:12 +00:00
gfxw_port_t * port = ( s - > port ) ? s - > port : s - > picture_port ;
2009-02-15 06:10:59 +00:00
int update_immediately = 1 ;
gfx_color_t color0 , * color1 , bg_color ;
gfx_alignment_t halign = ALIGN_LEFT ;
2009-02-15 22:28:12 +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 ;
int font_nr = port - > font_nr ;
gfxw_text_t * text_handle ;
transparent . mask = 0 ;
color0 = port - > color ;
bg_color = port - > bgcolor ;
if ( textp . segment ) {
argpt = 1 ;
text = ( char * ) kernel_dereference_bulk_pointer ( s , textp , 0 ) ;
} else {
argpt = 2 ;
text = kernel_lookup_text ( s , textp , index ) ;
}
if ( ! text ) {
SCIkdebug ( SCIkERROR , " Display with invalid reference " PREG " ! \n " , PRINT_REG ( textp ) ) ;
return NULL_REG ;
}
while ( argpt < argc ) {
2009-02-15 22:28:12 +00:00
switch ( UKPV ( argpt + + ) ) {
2009-02-15 06:10:59 +00:00
case K_DISPLAY_SET_COORDS :
area . x = UKPV ( argpt + + ) ;
area . y = UKPV ( argpt + + ) ;
SCIkdebug ( SCIkGRAPHICS , " Display: set_coords(%d, %d) \n " , area . x , area . y ) ;
break ;
case K_DISPLAY_SET_ALIGNMENT :
halign = ( gfx_alignment_t ) KP_SINT ( argv [ argpt + + ] ) ;
SCIkdebug ( SCIkGRAPHICS , " Display: set_align(%d) \n " , halign ) ;
break ;
case K_DISPLAY_SET_COLOR :
temp = KP_SINT ( argv [ argpt + + ] ) ;
SCIkdebug ( SCIkGRAPHICS , " Display: set_color(%d) \n " , temp ) ;
if ( ( s - > resmgr - > sci_version < SCI_VERSION_01_VGA ) & & temp > = 0 & & temp < = 15 )
color0 = ( s - > ega_colors [ temp ] ) ;
2009-02-15 22:28:12 +00:00
else
2009-02-15 06:10:59 +00:00
if ( ( s - > resmgr - > sci_version > = SCI_VERSION_01_VGA ) & & temp > = 0 & & temp < 256 ) {
color0 . visual = * ( get_pic_color ( s , temp ) ) ;
color0 . mask = GFX_MASK_VISUAL ;
} else
if ( temp = = - 1 )
color0 = transparent ;
else
SCIkwarn ( SCIkWARNING , " Display: Attempt to set invalid fg color %d \n " , temp ) ;
break ;
case K_DISPLAY_SET_BGCOLOR :
temp = KP_SINT ( argv [ argpt + + ] ) ;
SCIkdebug ( SCIkGRAPHICS , " Display: set_bg_color(%d) \n " , temp ) ;
if ( ( s - > resmgr - > sci_version < SCI_VERSION_01_VGA ) & & temp > = 0 & & temp < = 15 )
bg_color = s - > ega_colors [ temp ] ;
2009-02-15 22:28:12 +00:00
else
2009-02-15 06:10:59 +00:00
if ( ( s - > resmgr - > sci_version > = SCI_VERSION_01_VGA ) & & temp > = 0 & & temp < = 256 ) {
2009-02-15 22:28:12 +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
SCIkwarn ( SCIkWARNING , " Display: Attempt to set invalid fg color %d \n " , temp ) ;
break ;
case K_DISPLAY_SET_GRAYTEXT :
gray = KP_SINT ( argv [ argpt + + ] ) ;
SCIkdebug ( SCIkGRAPHICS , " Display: set_graytext(%d) \n " , gray ) ;
break ;
case K_DISPLAY_SET_FONT :
font_nr = KP_UINT ( argv [ argpt + + ] ) ;
2009-02-15 22:28:12 +00:00
2009-02-15 06:10:59 +00:00
SCIkdebug ( SCIkGRAPHICS , " Display: set_font( \" font.%03d \" ) \n " , font_nr ) ;
break ;
case K_DISPLAY_WIDTH :
area . xl = UKPV ( argpt + + ) ;
if ( area . xl = = 0 )
area . xl = MAX_TEXT_WIDTH_MAGIC_VALUE ;
SCIkdebug ( SCIkGRAPHICS , " Display: set_width(%d) \n " , area . xl ) ;
break ;
case K_DISPLAY_SAVE_UNDER :
save_under = 1 ;
SCIkdebug ( SCIkGRAPHICS , " Display: set_save_under() \n " ) ;
break ;
case K_DISPLAY_RESTORE_UNDER :
SCIkdebug ( SCIkGRAPHICS , " Display: restore_under(%04x) \n " , UKPV ( argpt ) ) ;
graph_restore_box ( s , argv [ argpt + + ] ) ;
update_immediately = 1 ;
argpt + + ;
return s - > r_acc ;
case K_DONT_UPDATE_IMMEDIATELY :
2009-02-15 22:28:12 +00:00
update_immediately = 0 ;
2009-02-15 06:10:59 +00:00
SCIkdebug ( SCIkGRAPHICS , " Display: set_dont_update() \n " ) ;
argpt + + ;
break ;
default :
2009-02-15 22:28:12 +00:00
SCIkdebug ( SCIkGRAPHICS , " Unknown Display() command %x \n " , UKPV ( argpt - 1 ) ) ;
2009-02-15 06:10:59 +00:00
return NULL_REG ;
}
}
if ( s - > version > = SCI_VERSION_FTU_DISPLAY_COORDS_FUZZY ) {
if ( halign = = ALIGN_LEFT )
GFX_ASSERT ( gfxop_get_text_params ( s - > gfx_state , font_nr , text ,
2009-02-15 22:28:12 +00:00
area . xl , & area . xl , & area . yl , 0 ,
NULL , NULL , NULL ) ) ;
2009-02-15 06:10:59 +00:00
/* Make the text fit on the screen */
if ( area . x + area . xl > 320 )
area . x + = 320 - area . x - area . xl ; /* Plus negative number = subtraction */
2009-02-15 22:28:12 +00:00
if ( area . y + area . yl > 200 ) {
2009-02-15 06:10:59 +00:00
area . y + = 200 - area . y - area . yl ; /* Plus negative number = subtraction */
}
}
if ( gray )
color1 = & bg_color ;
else
color1 = & color0 ;
assert_primary_widget_lists ( s ) ;
text_handle = gfxw_new_text ( s - > gfx_state , area , font_nr , text , halign ,
2009-02-15 22:28:12 +00:00
ALIGN_TOP , color0 , * color1 , bg_color , 0 ) ;
2009-02-15 06:10:59 +00:00
if ( ! text_handle ) {
SCIkwarn ( SCIkERROR , " Display: Failed to create text widget! \n " ) ;
return NULL_REG ;
}
if ( save_under ) { /* Backup */
rect_t save_area = text_handle - > bounds ;
save_area . x + = port - > bounds . x ;
save_area . y + = port - > bounds . y ;
s - > r_acc = graph_save_box ( s , save_area ) ;
text_handle - > serial + + ; /* This is evil! */
SCIkdebug ( SCIkGRAPHICS , " Saving (%d, %d) size (%d, %d) as " PREG " \n " ,
2009-02-15 22:28:12 +00:00
save_area . x , save_area . y , save_area . xl , save_area . yl , s - > r_acc ) ;
2009-02-15 06:10:59 +00:00
}
SCIkdebug ( SCIkGRAPHICS , " Display: Commiting text '%s' \n " , text ) ;
/*
ADD_TO_CURRENT_FG_WIDGETS ( text_handle ) ;
*/
ADD_TO_CURRENT_FG_WIDGETS ( GFXW ( text_handle ) ) ;
2009-02-15 22:28:12 +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 ( ) ;
SCIkdebug ( SCIkGRAPHICS , " Refreshing display... \n " ) ;
}
return s - > r_acc ;
}