2009-10-03 20:49:18 +00:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version .
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
* $ URL $
* $ Id $
*
*/
2009-10-07 14:53:15 +00:00
# include "graphics/cursorman.h"
2009-10-03 20:49:18 +00:00
# include "common/util.h"
# include "sci/sci.h"
# include "sci/engine/state.h"
# include "sci/debug.h" // for g_debug_sleeptime_factor
# include "sci/resource.h"
# include "sci/engine/state.h"
# include "sci/engine/kernel.h"
# include "sci/gfx/gfx_gui.h"
# include "sci/gfx/gfx_widgets.h"
# include "sci/gfx/gfx_state_internal.h" // required for GfxContainer, GfxPort, GfxVisual
# include "sci/gui32/gui32.h"
2009-10-13 16:22:07 +00:00
# include "sci/gui/gui_cursor.h"
2009-10-03 20:49:18 +00:00
// This is the real width of a text with a specified width of 0
# define MAX_TEXT_WIDTH_MAGIC_VALUE 192
# define K_DRAWPIC_FLAG_MIRRORED (1 << 14)
namespace Sci {
2009-10-13 20:25:51 +00:00
# undef DEBUG_LSRECT
// This is the real width of a text with a specified width of 0
# define MAX_TEXT_WIDTH_MAGIC_VALUE 192
# define ADD_TO_CURRENT_PORT(widget) \
2009-10-14 09:28:58 +00:00
{ if ( _s - > port ) \
_s - > port - > add ( ( GfxContainer * ) _s - > port , widget ) ; \
2009-10-13 20:25:51 +00:00
else \
2009-10-14 09:28:58 +00:00
_s - > picture_port - > add ( ( GfxContainer * ) _s - > visual , widget ) ; }
2009-10-13 20:25:51 +00:00
# define ADD_TO_CURRENT_PICTURE_PORT(widget) \
2009-10-14 09:28:58 +00:00
{ if ( _s - > port ) \
_s - > port - > add ( ( GfxContainer * ) _s - > port , widget ) ; \
2009-10-13 20:25:51 +00:00
else \
2009-10-14 09:28:58 +00:00
_s - > picture_port - > add ( ( GfxContainer * ) _s - > picture_port , widget ) ; }
2009-10-13 20:25:51 +00:00
# define ADD_TO_WINDOW_PORT(widget) \
2009-10-14 09:28:58 +00:00
_s - > wm_port - > add ( ( GfxContainer * ) _s - > wm_port , widget ) ;
2009-10-13 20:25:51 +00:00
# define FULL_REDRAW()\
2009-10-14 09:28:58 +00:00
if ( _s - > visual ) \
_s - > visual - > draw ( gfxw_point_zero ) ; \
gfxop_update ( _s - > gfx_state ) ;
2009-10-13 20:25:51 +00:00
#if 0
// Used for debugging
# define FULL_INSPECTION()\
2009-10-14 09:28:58 +00:00
if ( _s - > visual ) \
_s - > visual - > print ( _s - > visual , 0 ) ;
2009-10-13 20:25:51 +00:00
# endif
// was static
void assert_primary_widget_lists ( EngineState * s ) {
2009-10-14 09:28:58 +00:00
EngineState * _s = s ;
2009-10-13 20:25:51 +00:00
if ( ! s - > dyn_views ) {
2009-10-14 09:28:58 +00:00
rect_t bounds = _s - > picture_port - > _bounds ;
2009-10-13 20:25:51 +00:00
s - > dyn_views = gfxw_new_list ( bounds , GFXW_LIST_SORTED ) ;
s - > dyn_views - > _flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
2009-10-14 09:28:58 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( _s - > dyn_views ) ;
2009-10-13 20:25:51 +00:00
}
if ( ! s - > drop_views ) {
2009-10-14 09:28:58 +00:00
rect_t bounds = _s - > picture_port - > _bounds ;
2009-10-13 20:25:51 +00:00
s - > drop_views = gfxw_new_list ( bounds , GFXW_LIST_SORTED ) ;
s - > drop_views - > _flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
2009-10-14 09:28:58 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( _s - > drop_views ) ;
2009-10-13 20:25:51 +00:00
}
}
// static
void reparentize_primary_widget_lists ( EngineState * s , GfxPort * newport ) {
if ( ! newport )
newport = s - > picture_port ;
if ( s - > dyn_views ) {
gfxw_remove_widget_from_container ( s - > dyn_views - > _parent , s - > dyn_views ) ;
newport - > add ( ( GfxContainer * ) newport , s - > dyn_views ) ;
}
}
int _find_view_priority ( EngineState * s , int y ) {
2009-10-14 09:28:58 +00:00
/*if (_s->version <= SCI_VERSION_LTU_PRIORITY_OB1)
2009-10-13 20:25:51 +00:00
+ + y ; */
if ( s - > pic_priority_table ) { // SCI01 priority table set?
int j ;
for ( j = 0 ; j < 15 ; j + + )
if ( y < s - > pic_priority_table [ j + 1 ] )
return j ;
return 14 ; // Maximum
} else {
if ( ! s - > usesOldGfxFunctions ( ) )
return SCI0_VIEW_PRIORITY_14_ZONES ( y ) ;
else
return SCI0_VIEW_PRIORITY ( y ) = = 15 ? 14 : SCI0_VIEW_PRIORITY ( y ) ;
}
}
int _find_priority_band ( EngineState * s , int nr ) {
if ( ! s - > usesOldGfxFunctions ( ) & & ( nr < 0 | | nr > 14 ) ) {
if ( nr = = 15 )
return 0xffff ;
else {
warning ( " Attempt to get priority band %d " , nr ) ;
}
return 0 ;
}
if ( s - > usesOldGfxFunctions ( ) & & ( nr < 0 | | nr > 15 ) ) {
warning ( " Attempt to get priority band %d " , nr ) ;
return 0 ;
}
if ( s - > pic_priority_table ) // SCI01 priority table set?
return s - > pic_priority_table [ nr ] ;
else {
int retval ;
if ( ! s - > usesOldGfxFunctions ( ) )
retval = SCI0_PRIORITY_BAND_FIRST_14_ZONES ( nr ) ;
else
retval = SCI0_PRIORITY_BAND_FIRST ( nr ) ;
2009-10-14 09:28:58 +00:00
/* if (_s->version <= SCI_VERSION_LTU_PRIORITY_OB1)
2009-10-13 20:25:51 +00:00
- - retval ; */
return retval ;
}
}
reg_t graph_save_box ( EngineState * s , rect_t area ) {
reg_t handle = kalloc ( s - > _segMan , " graph_save_box() " , sizeof ( gfxw_snapshot_t * ) ) ;
gfxw_snapshot_t * * ptr = ( gfxw_snapshot_t * * ) kmem ( s - > _segMan , handle ) ;
// FIXME: gfxw_make_snapshot returns a pointer. Now why do we store a
// pointer to real memory inside the SCI heap?
// If we save and the load again, this cannot work in general.
// This seems like bad design. Either the snapshot data itself should be
// stored in the heap, or a unique persistent id.
* ptr = gfxw_make_snapshot ( s - > visual , area ) ;
return handle ;
}
void graph_restore_box ( EngineState * s , reg_t handle ) {
gfxw_snapshot_t * * ptr ;
int port_nr = s - > port - > _ID ;
if ( ! handle . segment ) {
warning ( " Attempt to restore box with zero handle " ) ;
return ;
}
ptr = ( gfxw_snapshot_t * * ) kmem ( s - > _segMan , handle ) ;
if ( ! ptr ) {
warning ( " Attempt to restore invalid handle %04x:%04x " , PRINT_REG ( handle ) ) ;
return ;
}
while ( port_nr > 2 & & ! ( s - > port - > _flags & GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ) & & ( gfxw_widget_matches_snapshot ( * ptr , s - > port ) ) ) {
// This shouldn't ever happen, actually, since windows (ports w/ ID > 2) should all be immune
GfxPort * newport = s - > visual - > getPort ( port_nr ) ;
error ( " Port %d is not immune against snapshots " , s - > port - > _ID ) ;
port_nr - - ;
if ( newport )
s - > port = newport ;
}
if ( s - > dyn_views & & gfxw_widget_matches_snapshot ( * ptr , s - > dyn_views - > _parent ) ) {
GfxContainer * parent = s - > dyn_views - > _parent ;
do {
parent = parent - > _parent ;
} while ( parent & & ( gfxw_widget_matches_snapshot ( * ptr , parent ) ) ) ;
if ( ! parent ) {
error ( " Attempted widget mass destruction by a snapshot " ) ;
}
reparentize_primary_widget_lists ( s , ( GfxPort * ) parent ) ;
}
if ( ! ptr ) {
error ( " Attempt to restore invalid snaphot with handle %04x:%04x " , PRINT_REG ( handle ) ) ;
return ;
}
gfxw_restore_snapshot ( s - > visual , * ptr ) ;
free ( * ptr ) ;
* ptr = NULL ;
kfree ( s - > _segMan , handle ) ;
}
PaletteEntry get_pic_color ( EngineState * s , int color ) {
if ( ! s - > resMan - > isVGA ( ) )
return s - > ega_colors [ color ] . visual ;
if ( color = = - 1 | | color = = 255 ) // -1 occurs in Eco Quest 1. Not sure if this is the best approach, but it seems to work
return PaletteEntry ( 255 , 255 , 255 ) ;
else if ( color < s - > gfx_state - > gfxResMan - > getColorCount ( ) )
return s - > gfx_state - > gfxResMan - > getColor ( color ) ;
else {
// Happens in the beginning of EcoQuest 2, when the dialog box of the customs officer shows up
warning ( " Color index %d out of bounds for pic %d (%d max) " , color , s - > gfx_state - > pic_nr , s - > gfx_state - > gfxResMan - > getColorCount ( ) ) ;
return PaletteEntry ( 0 , 0 , 0 ) ;
}
}
void _k_redraw_box ( EngineState * s , int x1 , int y1 , int x2 , int y2 ) {
warning ( " _k_redraw_box(): Unimplemented " ) ;
#if 0
int i ;
ViewObject * list = s - > dyn_views ;
2009-10-14 09:28:58 +00:00
printf ( " Reanimating views \n " , _s - > dyn_views_nr ) ;
2009-10-13 20:25:51 +00:00
for ( i = 0 ; i < s - > dyn_views_nr ; i + + ) {
2009-10-14 09:28:58 +00:00
* ( list [ i ] . underBitsp ) = graph_save_box ( _s , list [ i ] . nsLeft , list [ i ] . nsTop , list [ i ] . nsRight - list [ i ] . nsLeft ,
2009-10-13 20:25:51 +00:00
list [ i ] . nsBottom - list [ i ] . nsTop , SCI_MAP_VISUAL | SCI_MAP_PRIORITY ) ;
2009-10-14 09:28:58 +00:00
draw_view0 ( _s - > pic , _s - > ports [ 0 ] , list [ i ] . nsLeft , list [ i ] . nsTop , list [ i ] . priority , list [ i ] . loop ,
2009-10-13 20:25:51 +00:00
list [ i ] . cel , 0 , list [ i ] . view ) ;
}
2009-10-14 09:28:58 +00:00
graph_update_box ( _s , x1 , y1 , x2 - x1 , y2 - y1 ) ;
2009-10-13 20:25:51 +00:00
for ( i = 0 ; i < s - > dyn_views_nr ; i + + ) {
2009-10-14 09:28:58 +00:00
graph_restore_box ( _s , * ( list [ i ] . underBitsp ) ) ;
2009-10-13 20:25:51 +00:00
list [ i ] . underBits = 0 ;
}
# endif
}
Common : : Rect set_base ( EngineState * s , reg_t object ) {
SegManager * segMan = s - > _segMan ;
int x , y , original_y , z , ystep , xsize , ysize ;
int xbase , ybase , xend , yend ;
int view , loop , cel ;
int oldloop , oldcel ;
int xmod = 0 , ymod = 0 ;
Common : : Rect retval ;
x = ( int16 ) GET_SEL32V ( object , x ) ;
original_y = y = ( int16 ) GET_SEL32V ( object , y ) ;
if ( s - > _kernel - > _selectorCache . z > - 1 )
z = ( int16 ) GET_SEL32V ( object , z ) ;
else
z = 0 ;
y - = z ; // Subtract z offset
ystep = ( int16 ) GET_SEL32V ( object , yStep ) ;
view = ( int16 ) GET_SEL32V ( object , view ) ;
int l = GET_SEL32V ( object , loop ) ;
oldloop = loop = ( l & 0x80 ) ? l - 256 : l ;
int c = GET_SEL32V ( object , cel ) ;
oldcel = cel = ( c & 0x80 ) ? c - 256 : c ;
Common : : Point offset = Common : : Point ( 0 , 0 ) ;
if ( loop ! = oldloop ) {
loop = 0 ;
PUT_SEL32V ( object , loop , 0 ) ;
debugC ( 2 , kDebugLevelGraphics , " Resetting loop for %04x:%04x! \n " , PRINT_REG ( object ) ) ;
}
if ( cel ! = oldcel ) {
cel = 0 ;
PUT_SEL32V ( object , cel , 0 ) ;
}
gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & xsize , & ysize , & offset ) ;
xmod = offset . x ;
ymod = offset . y ;
xbase = x - xmod - ( xsize > > 1 ) ;
xend = xbase + xsize ;
yend = y /* - ymod */ + 1 ;
ybase = yend - ystep ;
debugC ( 2 , kDebugLevelBaseSetter , " (%d,%d)+/-(%d,%d), (%d x %d) -> (%d, %d) to (%d, %d) \n " ,
x , y , xmod , ymod , xsize , ysize , xbase , ybase , xend , yend ) ;
retval . left = xbase ;
retval . top = ybase ;
retval . right = xend ;
retval . bottom = yend ;
return retval ;
}
static Common : : Rect nsrect_clip ( EngineState * s , int y , Common : : Rect retval , int priority ) {
int pri_top ;
if ( priority = = - 1 )
priority = _find_view_priority ( s , y ) ;
pri_top = _find_priority_band ( s , priority ) + 1 ;
// +1: Don't know why, but this seems to be happening
if ( retval . top < pri_top )
retval . top = pri_top ;
if ( retval . bottom < retval . top )
retval . top = retval . bottom - 1 ;
return retval ;
}
static Common : : Rect calculate_nsrect ( EngineState * s , int x , int y , int view , int loop , int cel ) {
int xbase , ybase , xend , yend , xsize , ysize ;
int xmod = 0 , ymod = 0 ;
Common : : Rect retval ( 0 , 0 , 0 , 0 ) ;
Common : : Point offset = Common : : Point ( 0 , 0 ) ;
gfxop_get_cel_parameters ( s - > gfx_state , view , loop , cel , & xsize , & ysize , & offset ) ;
xmod = offset . x ;
ymod = offset . y ;
xbase = x - xmod - ( xsize > > 1 ) ;
xend = xbase + xsize ;
yend = y - ymod + 1 ; // +1: magic modifier
ybase = yend - ysize ;
retval . left = xbase ;
retval . top = ybase ;
retval . right = xend ;
retval . bottom = yend ;
return retval ;
}
Common : : Rect get_nsrect ( EngineState * s , reg_t object , byte clip ) {
SegManager * segMan = s - > _segMan ;
int x , y , z ;
int view , loop , cel ;
Common : : Rect retval ;
x = ( int16 ) GET_SEL32V ( object , x ) ;
y = ( int16 ) GET_SEL32V ( object , y ) ;
if ( s - > _kernel - > _selectorCache . z > - 1 )
z = ( int16 ) GET_SEL32V ( object , z ) ;
else
z = 0 ;
y - = z ; // Subtract z offset
view = ( int16 ) GET_SEL32V ( object , view ) ;
int l = ( int16 ) GET_SEL32V ( object , loop ) ;
loop = ( l & 0x80 ) ? l - 256 : l ;
int c = ( int16 ) GET_SEL32V ( object , cel ) ;
cel = ( c & 0x80 ) ? c - 256 : c ;
retval = calculate_nsrect ( s , x , y , view , loop , cel ) ;
if ( clip ) {
int priority = ( int16 ) GET_SEL32V ( object , priority ) ;
return nsrect_clip ( s , y , retval , priority ) ;
}
return retval ;
}
Common : : Rect get_nsrect32 ( EngineState * s , reg_t object , byte clip ) {
SegManager * segMan = s - > _segMan ;
int x , y , z ;
int view , loop , cel ;
Common : : Rect retval ;
x = ( int16 ) GET_SEL32V ( object , x ) ;
y = ( int16 ) GET_SEL32V ( object , y ) ;
if ( s - > _kernel - > _selectorCache . z > - 1 )
z = ( int16 ) GET_SEL32V ( object , z ) ;
else
z = 0 ;
y - = z ; // Subtract z offset
view = ( int16 ) GET_SEL32V ( object , view ) ;
int l = ( int16 ) GET_SEL32V ( object , loop ) ;
loop = ( l & 0x80 ) ? l - 256 : l ;
int c = ( int16 ) GET_SEL32V ( object , cel ) ;
cel = ( c & 0x80 ) ? c - 256 : c ;
retval = calculate_nsrect ( s , x , y , view , loop , cel ) ;
if ( clip ) {
int priority = ( int16 ) GET_SEL32V ( object , priority ) ;
return nsrect_clip ( s , y , retval , priority ) ;
}
return retval ;
}
// ======================================================================================================
2009-10-14 09:28:58 +00:00
SciGui32 : : SciGui32 ( EngineState * state , SciGuiScreen * screen , SciGuiPalette * palette , SciGuiCursor * cursor ) {
_s = state ;
_screen = screen ;
_palette = palette ;
2009-10-13 16:22:07 +00:00
_cursor = cursor ;
2009-10-03 20:49:18 +00:00
}
2009-10-05 07:10:01 +00:00
SciGui32 : : ~ SciGui32 ( ) {
2009-10-03 20:49:18 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : init ( bool oldGfxFunctions ) {
2009-10-03 20:49:18 +00:00
_usesOldGfxFunctions = oldGfxFunctions ;
2009-10-04 14:59:51 +00:00
_k_animate_ran = false ;
2009-10-03 20:49:18 +00:00
activated_icon_bar = false ;
port_origin_x = 0 ;
port_origin_y = 0 ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : wait ( int16 ticks ) {
2009-10-03 20:49:18 +00:00
uint32 time ;
time = g_system - > getMillis ( ) ;
2009-10-14 09:28:58 +00:00
_s - > r_acc = make_reg ( 0 , ( ( long ) time - ( long ) _s - > last_wait_time ) * 60 / 1000 ) ;
_s - > last_wait_time = time ;
2009-10-03 20:49:18 +00:00
ticks * = g_debug_sleeptime_factor ;
2009-10-14 09:28:58 +00:00
gfxop_sleep ( _s - > gfx_state , ticks * 1000 / 60 ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : setPort ( uint16 portPtr ) {
2009-10-03 20:49:18 +00:00
GfxPort * 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-10-14 09:28:58 +00:00
if ( portPtr = = 65535 ) portPtr = _s - > iconbar_port - > _ID ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
new_port = _s - > visual - > getPort ( portPtr ) ;
2009-10-03 20:49:18 +00:00
if ( ! new_port ) {
warning ( " Invalid port %04x requested " , portPtr ) ;
return ;
}
2009-10-14 09:28:58 +00:00
_s - > port - > draw ( gfxw_point_zero ) ; // Update the port we're leaving
_s - > port = new_port ;
2009-10-03 20:49:18 +00:00
}
2009-10-13 16:18:17 +00:00
void SciGui32 : : setPortPic ( Common : : Rect rect , int16 picTop , int16 picLeft , bool initPriorityBandsFlag ) {
2009-10-03 20:49:18 +00:00
if ( activated_icon_bar ) {
port_origin_x = port_origin_y = 0 ;
activated_icon_bar = false ;
return ;
}
port_origin_y = rect . top ;
port_origin_x = rect . left ;
if ( rect . top = = - 10 ) {
2009-10-14 09:28:58 +00:00
_s - > port - > draw ( gfxw_point_zero ) ; // Update the port we're leaving
_s - > port = _s - > iconbar_port ;
2009-10-03 20:49:18 +00:00
activated_icon_bar = true ;
return ;
}
// Notify the graphics resource manager that the pic port bounds changed
2009-10-14 09:28:58 +00:00
_s - > gfx_state - > gfxResMan - > changePortBounds ( picLeft , picTop , rect . right + picLeft , rect . bottom + picTop ) ;
2009-10-03 20:49:18 +00:00
2009-10-05 07:10:01 +00:00
// LSL6 calls kSetPort to extend the screen to draw the Gui. If we free all resources
2009-10-03 20:49:18 +00:00
// here, the background picture is freed too, and this makes everything a big mess.
// FIXME/TODO: This code really needs to be rewritten to conform to the original behavior
2009-10-14 09:28:58 +00:00
if ( _s - > _gameName ! = " lsl6 " ) {
_s - > gfx_state - > pic_port_bounds = gfx_rect ( picLeft , picTop , rect . right , rect . bottom ) ;
2009-10-03 20:49:18 +00:00
// FIXME: Should really only invalidate all loaded pic resources here;
// this is overkill
2009-10-14 09:28:58 +00:00
_s - > gfx_state - > gfxResMan - > freeAllResources ( ) ;
2009-10-03 20:49:18 +00:00
} else {
// WORKAROUND for LSL6
warning ( " SetPort case 6 called in LSL6. " ) ;
}
}
2009-10-05 07:10:01 +00:00
reg_t SciGui32 : : getPort ( ) {
2009-10-14 09:28:58 +00:00
return make_reg ( 0 , _s - > port - > _ID ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : globalToLocal ( int16 * x , int16 * y ) {
2009-10-14 09:28:58 +00:00
* x = * x - _s - > port - > zone . x ;
* y = * y - _s - > port - > zone . y ;
2009-10-03 20:49:18 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : localToGlobal ( int16 * x , int16 * y ) {
2009-10-14 09:28:58 +00:00
* x = * x + _s - > port - > zone . x ;
* y = * y + _s - > port - > zone . y ;
2009-10-03 20:49:18 +00:00
}
2009-10-09 13:15:37 +00:00
int16 SciGui32 : : coordinateToPriority ( int16 y ) {
2009-10-14 09:28:58 +00:00
return _find_view_priority ( _s , y ) ;
2009-10-09 13:15:37 +00:00
}
int16 SciGui32 : : priorityToCoordinate ( int16 priority ) {
2009-10-14 09:28:58 +00:00
return _find_priority_band ( _s , priority ) ;
2009-10-09 13:15:37 +00:00
}
2009-10-05 07:10:01 +00:00
reg_t SciGui32 : : newWindow ( Common : : Rect dims , Common : : Rect restoreRect , uint16 style , int16 priority , int16 colorPen , int16 colorBack , const char * title ) {
2009-10-03 20:49:18 +00:00
GfxPort * window ;
int x , y , xl , yl ;
gfx_color_t bgcolor ;
gfx_color_t fgcolor ;
gfx_color_t black ;
gfx_color_t lWhite ;
2009-10-04 15:44:10 +00:00
y = dims . top ;
x = dims . left ;
yl = dims . height ( ) ;
xl = dims . width ( ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
y + = _s - > wm_port - > _bounds . y ;
2009-10-03 20:49:18 +00:00
if ( x + xl > 319 )
x - = ( ( x + xl ) - 319 ) ;
bgcolor . mask = 0 ;
if ( colorBack > = 0 ) {
2009-10-14 09:28:58 +00:00
if ( ! _s - > resMan - > isVGA ( ) )
bgcolor . visual = get_pic_color ( _s , MIN < int > ( colorBack , 15 ) ) ;
2009-10-03 20:49:18 +00:00
else
2009-10-14 09:28:58 +00:00
bgcolor . visual = get_pic_color ( _s , colorBack ) ;
2009-10-03 20:49:18 +00:00
bgcolor . mask = GFX_MASK_VISUAL ;
} else {
bgcolor . visual = PaletteEntry ( 0 , 0 , 0 ) ;
}
bgcolor . priority = priority ;
bgcolor . mask | = priority > = 0 ? GFX_MASK_PRIORITY : 0 ;
bgcolor . alpha = 0 ;
bgcolor . control = - 1 ;
2009-10-04 15:44:10 +00:00
debugC ( 2 , kDebugLevelGraphics , " New window with params %d, %d, %d, %d \n " , dims . top , dims . left , dims . height ( ) , dims . width ( ) ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
fgcolor . visual = get_pic_color ( _s , colorPen ) ;
2009-10-03 20:49:18 +00:00
fgcolor . mask = GFX_MASK_VISUAL ;
fgcolor . control = - 1 ;
fgcolor . priority = - 1 ;
fgcolor . alpha = 0 ;
2009-10-14 09:28:58 +00:00
black . visual = get_pic_color ( _s , 0 ) ;
2009-10-03 20:49:18 +00:00
black . mask = GFX_MASK_VISUAL ;
black . alpha = 0 ;
black . control = - 1 ;
black . priority = - 1 ;
2009-10-14 09:28:58 +00:00
lWhite . visual = get_pic_color ( _s , ! _s - > resMan - > isVGA ( ) ? 15 : 255 ) ;
2009-10-03 20:49:18 +00:00
lWhite . mask = GFX_MASK_VISUAL ;
lWhite . alpha = 0 ;
lWhite . priority = - 1 ;
lWhite . control = - 1 ;
2009-10-14 09:28:58 +00:00
window = sciw_new_window ( _s , gfx_rect ( x , y , xl , yl ) , _s - > titlebar_port - > _font , fgcolor , bgcolor ,
_s - > titlebar_port - > _font , lWhite , black , title ? _s - > strSplit ( title , NULL ) . c_str ( ) : NULL , style ) ;
2009-10-03 20:49:18 +00:00
// PQ3 and SCI1.1 games have the interpreter store underBits implicitly
2009-10-04 15:44:10 +00:00
if ( restoreRect . top ! = 0 & & restoreRect . left ! = 0 & & restoreRect . height ( ) ! = 0 & & restoreRect . width ( ) ! = 0 )
2009-10-14 09:28:58 +00:00
gfxw_port_auto_restore_background ( _s - > visual , window , gfx_rect ( restoreRect . left , restoreRect . top + _s - > wm_port - > _bounds . y ,
restoreRect . width ( ) , restoreRect . height ( ) ) ) ;
2009-10-03 20:49:18 +00:00
ADD_TO_WINDOW_PORT ( window ) ;
FULL_REDRAW ( ) ;
window - > draw ( gfxw_point_zero ) ;
2009-10-14 09:28:58 +00:00
gfxop_update ( _s - > gfx_state ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > port = window ; // Set active port
2009-10-03 20:49:18 +00:00
return make_reg ( 0 , window - > _ID ) ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : disposeWindow ( uint16 windowPtr , int16 arg2 ) {
2009-10-03 20:49:18 +00:00
GfxPort * goner ;
GfxPort * pred ;
2009-10-14 09:28:58 +00:00
goner = _s - > visual - > getPort ( windowPtr ) ;
2009-10-03 20:49:18 +00:00
if ( ( windowPtr < 3 ) | | ( goner = = NULL ) ) {
error ( " Removal of invalid window %04x requested " , windowPtr ) ;
return ;
}
2009-10-14 09:28:58 +00:00
if ( _s - > dyn_views & & ( GfxContainer * ) _s - > dyn_views - > _parent = = ( GfxContainer * ) goner ) {
reparentize_primary_widget_lists ( _s , ( GfxPort * ) goner - > _parent ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-14 09:28:58 +00:00
if ( _s - > drop_views & & ( GfxContainer * ) _s - > drop_views - > _parent = = ( GfxContainer * ) goner )
_s - > drop_views = NULL ; // Kill it
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
pred = gfxw_remove_port ( _s - > visual , goner ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
if ( goner = = _s - > port ) // Did we kill the active port?
_s - > port = pred ;
2009-10-03 20:49:18 +00:00
// Find the last port that exists and that isn't marked no-switch
2009-10-14 09:28:58 +00:00
int id = _s - > visual - > _portRefs . size ( ) - 1 ;
while ( id > 0 & & ( ! _s - > visual - > _portRefs [ id ] | | ( _s - > visual - > _portRefs [ id ] - > _flags & GFXW_FLAG_NO_IMPLICIT_SWITCH ) ) )
2009-10-03 20:49:18 +00:00
id - - ;
debugC ( 2 , kDebugLevelGraphics , " Activating port %d after disposing window %d \n " , id , windowPtr ) ;
2009-10-14 09:28:58 +00:00
_s - > port = ( id > = 0 ) ? _s - > visual - > _portRefs [ id ] : 0 ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
if ( ! _s - > port )
_s - > port = gfxw_find_default_port ( _s - > visual ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
gfxop_update ( _s - > gfx_state ) ;
2009-10-03 20:49:18 +00:00
}
# define K_DISPLAY_SET_COORDS 100
# define K_DISPLAY_SET_ALIGNMENT 101
# define K_DISPLAY_SET_COLOR 102
# define K_DISPLAY_SET_BGCOLOR 103
# define K_DISPLAY_SET_GRAYTEXT 104
# define K_DISPLAY_SET_FONT 105
# define K_DISPLAY_WIDTH 106
# define K_DISPLAY_SAVE_UNDER 107
# define K_DISPLAY_RESTORE_UNDER 108
# define K_DONT_UPDATE_IMMEDIATELY 121
2009-10-05 07:10:01 +00:00
void SciGui32 : : display ( const char * text , int argc , reg_t * argv ) {
2009-10-03 20:49:18 +00:00
int argpt = 0 ;
int temp ;
bool save_under = false ;
gfx_color_t transparent = { PaletteEntry ( ) , 0 , - 1 , - 1 , 0 } ;
2009-10-14 09:28:58 +00:00
GfxPort * port = ( _s - > port ) ? _s - > port : _s - > picture_port ;
2009-10-03 20:49:18 +00:00
bool update_immediately = true ;
gfx_color_t color0 , * color1 , bg_color ;
gfx_alignment_t halign = ALIGN_LEFT ;
rect_t area = gfx_rect ( port - > draw_pos . x , port - > draw_pos . y , 320 - port - > draw_pos . x , 200 - port - > draw_pos . y ) ;
int gray = port - > gray_text ;
int font_nr = port - > _font ;
GfxText * text_handle ;
color0 = port - > _color ;
bg_color = port - > _bgcolor ;
// TODO: in SCI1VGA the default colors for text and background are #0 (black)
// SCI0 case should be checked
2009-10-14 09:28:58 +00:00
if ( _s - > resMan - > isVGA ( ) ) {
2009-10-03 20:49:18 +00:00
// This priority check fixes the colors in the menus in KQ5
// TODO/FIXME: Is this correct?
if ( color0 . priority > = 0 )
2009-10-14 09:28:58 +00:00
color0 . visual = get_pic_color ( _s , 0 ) ;
2009-10-03 20:49:18 +00:00
if ( bg_color . priority > = 0 )
2009-10-14 09:28:58 +00:00
bg_color . visual = get_pic_color ( _s , 0 ) ;
2009-10-03 20:49:18 +00:00
}
while ( argpt < argc ) {
switch ( argv [ argpt + + ] . toUint16 ( ) ) {
case K_DISPLAY_SET_COORDS :
area . x = argv [ argpt + + ] . toUint16 ( ) ;
area . y = argv [ argpt + + ] . toUint16 ( ) ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_coords(%d, %d) \n " , area . x , area . y ) ;
break ;
case K_DISPLAY_SET_ALIGNMENT :
halign = ( gfx_alignment_t ) argv [ argpt + + ] . toSint16 ( ) ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_align(%d) \n " , halign ) ;
break ;
case K_DISPLAY_SET_COLOR :
temp = argv [ argpt + + ] . toSint16 ( ) ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_color(%d) \n " , temp ) ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > resMan - > isVGA ( ) & & temp > = 0 & & temp < = 15 )
color0 = ( _s - > ega_colors [ temp ] ) ;
2009-10-03 20:49:18 +00:00
else
2009-10-14 09:28:58 +00:00
if ( _s - > resMan - > isVGA ( ) & & temp > = 0 & & temp < 256 ) {
color0 . visual = get_pic_color ( _s , temp ) ;
2009-10-03 20:49:18 +00:00
color0 . mask = GFX_MASK_VISUAL ;
} else
if ( temp = = - 1 )
color0 = transparent ;
else
warning ( " Display: Attempt to set invalid fg color %d " , temp ) ;
break ;
case K_DISPLAY_SET_BGCOLOR :
temp = argv [ argpt + + ] . toSint16 ( ) ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_bg_color(%d) \n " , temp ) ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > resMan - > isVGA ( ) & & temp > = 0 & & temp < = 15 )
bg_color = _s - > ega_colors [ temp ] ;
2009-10-03 20:49:18 +00:00
else
2009-10-14 09:28:58 +00:00
if ( _s - > resMan - > isVGA ( ) & & temp > = 0 & & temp < = 256 ) {
bg_color . visual = get_pic_color ( _s , temp ) ;
2009-10-03 20:49:18 +00:00
bg_color . mask = GFX_MASK_VISUAL ;
} else
if ( temp = = - 1 )
bg_color = transparent ;
else
warning ( " Display: Attempt to set invalid fg color %d " , temp ) ;
break ;
case K_DISPLAY_SET_GRAYTEXT :
gray = argv [ argpt + + ] . toSint16 ( ) ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_graytext(%d) \n " , gray ) ;
break ;
case K_DISPLAY_SET_FONT :
font_nr = argv [ argpt + + ] . toUint16 ( ) ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_font( \" font.%03d \" ) \n " , font_nr ) ;
break ;
case K_DISPLAY_WIDTH :
area . width = argv [ argpt + + ] . toUint16 ( ) ;
if ( area . width = = 0 )
area . width = MAX_TEXT_WIDTH_MAGIC_VALUE ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_width(%d) \n " , area . width ) ;
break ;
case K_DISPLAY_SAVE_UNDER :
save_under = true ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_save_under() \n " ) ;
break ;
case K_DISPLAY_RESTORE_UNDER :
debugC ( 2 , kDebugLevelGraphics , " Display: restore_under(%04x) \n " , argv [ argpt ] . toUint16 ( ) ) ;
2009-10-14 09:28:58 +00:00
graph_restore_box ( _s , argv [ argpt + + ] ) ;
2009-10-03 20:49:18 +00:00
update_immediately = true ;
argpt + + ;
return ;
case K_DONT_UPDATE_IMMEDIATELY :
update_immediately = false ;
debugC ( 2 , kDebugLevelGraphics , " Display: set_dont_update() \n " ) ;
argpt + + ;
break ;
default :
debugC ( 2 , kDebugLevelGraphics , " Unknown Display() command %x \n " , argv [ argpt - 1 ] . toUint16 ( ) ) ;
return ;
}
}
if ( halign = = ALIGN_LEFT ) {
// If the text does not fit on the screen, move it to the left and upwards until it does
2009-10-14 09:28:58 +00:00
gfxop_get_text_params ( _s - > gfx_state , font_nr , text , area . width , & area . width , & area . height , 0 , NULL , NULL , NULL ) ;
2009-10-03 20:49:18 +00:00
// Make the text fit on the screen
if ( area . x + area . width > 320 )
area . x + = 320 - area . x - area . width ; // Plus negative number = subtraction
if ( area . y + area . height > 200 )
area . y + = 200 - area . y - area . height ; // Plus negative number = subtraction
} else {
// If the text does not fit on the screen, clip it till it does
2009-10-14 09:28:58 +00:00
if ( area . x + area . width > _s - > gfx_state - > pic_port_bounds . width )
area . width = _s - > gfx_state - > pic_port_bounds . width - area . x ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
if ( area . y + area . height > _s - > gfx_state - > pic_port_bounds . height )
area . height = _s - > gfx_state - > pic_port_bounds . height - area . y ;
2009-10-03 20:49:18 +00:00
}
if ( gray )
color1 = & bg_color ;
else
color1 = & color0 ;
2009-10-14 09:28:58 +00:00
assert_primary_widget_lists ( _s ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
text_handle = gfxw_new_text ( _s - > gfx_state , area , font_nr , _s - > strSplit ( text ) . c_str ( ) , halign , ALIGN_TOP , color0 , * color1 , bg_color , 0 ) ;
2009-10-03 20:49:18 +00:00
if ( ! text_handle ) {
error ( " Display: Failed to create text widget " ) ;
return ;
}
if ( save_under ) { // Backup
rect_t save_area = text_handle - > _bounds ;
save_area . x + = port - > _bounds . x ;
save_area . y + = port - > _bounds . y ;
2009-10-14 09:28:58 +00:00
_s - > r_acc = graph_save_box ( _s , save_area ) ;
2009-10-03 20:49:18 +00:00
text_handle - > _serial + + ; // This is evil!
2009-10-14 09:28:58 +00:00
debugC ( 2 , kDebugLevelGraphics , " Saving (%d, %d) size (%d, %d) as %04x:%04x \n " , save_area . x , save_area . y , save_area . width , save_area . height , PRINT_REG ( _s - > r_acc ) ) ;
2009-10-03 20:49:18 +00:00
}
debugC ( 2 , kDebugLevelGraphics , " Display: Commiting text '%s' \n " , text ) ;
//ADD_TO_CURRENT_PICTURE_PORT(text_handle);
ADD_TO_CURRENT_PICTURE_PORT ( text_handle ) ;
2009-10-14 09:28:58 +00:00
if ( ( ! _s - > pic_not_valid ) & & update_immediately ) { // Refresh if drawn to valid picture
2009-10-03 20:49:18 +00:00
FULL_REDRAW ( ) ;
debugC ( 2 , kDebugLevelGraphics , " Refreshing display... \n " ) ;
}
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : textSize ( const char * text , int16 fontId , int16 maxWidth , int16 * textWidth , int16 * textHeight ) {
2009-10-03 20:49:18 +00:00
int width , height ;
if ( maxWidth < 0 )
maxWidth = 0 ;
2009-10-14 09:28:58 +00:00
gfxop_get_text_params ( _s - > gfx_state , fontId , text , maxWidth ? maxWidth : MAX_TEXT_WIDTH_MAGIC_VALUE ,
2009-10-03 20:49:18 +00:00
& width , & height , 0 , NULL , NULL , NULL ) ;
* textWidth = width ; * textHeight = height ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : textFonts ( int argc , reg_t * argv ) {
2009-10-03 20:49:18 +00:00
// stub
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : textColors ( int argc , reg_t * argv ) {
2009-10-03 20:49:18 +00:00
// stub
}
2009-10-05 19:20:52 +00:00
void SciGui32 : : drawStatus ( const char * text , int16 colorPen , int16 colorBack ) {
2009-10-14 09:28:58 +00:00
_s - > titlebar_port - > _color . visual = get_pic_color ( _s , colorPen ) ;
_s - > titlebar_port - > _color . mask = GFX_MASK_VISUAL ;
_s - > titlebar_port - > _bgcolor . visual = get_pic_color ( _s , colorBack ) ;
_s - > titlebar_port - > _bgcolor . mask = GFX_MASK_VISUAL ;
2009-10-05 19:20:52 +00:00
2009-10-14 09:28:58 +00:00
_s - > status_bar_foreground = colorPen ;
_s - > status_bar_background = colorBack ;
_s - > _statusBarText = text ;
2009-10-05 19:20:52 +00:00
2009-10-14 09:28:58 +00:00
sciw_set_status_bar ( _s , _s - > titlebar_port , _s - > _statusBarText , colorPen , colorBack ) ;
2009-10-05 19:20:52 +00:00
2009-10-14 09:28:58 +00:00
gfxop_update ( _s - > gfx_state ) ;
2009-10-05 19:20:52 +00:00
}
2009-10-09 17:47:33 +00:00
void SciGui32 : : drawMenuBar ( ) {
2009-10-14 09:28:58 +00:00
sciw_set_menubar ( _s , _s - > titlebar_port , _s - > _menubar , - 1 ) ;
_s - > titlebar_port - > draw ( Common : : Point ( 0 , 0 ) ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-09 17:47:33 +00:00
}
void SciGui32 : : clearMenuBar ( ) {
2009-10-14 09:28:58 +00:00
sciw_set_status_bar ( _s , _s - > titlebar_port , " " , 0 , 0 ) ;
_s - > titlebar_port - > draw ( Common : : Point ( 0 , 0 ) ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-09 17:47:33 +00:00
}
2009-10-14 18:09:54 +00:00
void SciGui32 : : drawPicture ( GuiResourceId pictureId , int16 animationNr , bool animationBlackoutFlag , bool mirroredFlag , bool addToFlag , int16 EGApaletteNo ) {
2009-10-14 09:28:58 +00:00
gfx_color_t transparent = _s - > wm_port - > _bgcolor ;
2009-10-03 20:49:18 +00:00
int picFlags = DRAWPIC01_FLAG_FILL_NORMALLY ;
2009-10-12 17:21:23 +00:00
int palNo = ( EGApaletteNo ! = - 1 ) ? EGApaletteNo : 0 ;
2009-10-03 20:49:18 +00:00
2009-10-07 20:58:33 +00:00
if ( mirroredFlag )
2009-10-03 20:49:18 +00:00
picFlags | = DRAWPIC1_FLAG_MIRRORED ;
2009-10-14 09:28:58 +00:00
gfxop_disable_dirty_frames ( _s - > gfx_state ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
if ( NULL ! = _s - > old_screen ) {
gfxop_free_pixmap ( _s - > gfx_state , _s - > old_screen ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-14 09:28:58 +00:00
_s - > old_screen = gfxop_grab_pixmap ( _s - > gfx_state , gfx_rect ( 0 , 10 , 320 , 190 ) ) ;
2009-10-03 20:49:18 +00:00
debugC ( 2 , kDebugLevelGraphics , " Drawing pic.%03d \n " , pictureId ) ;
2009-10-07 20:58:33 +00:00
if ( addToFlag ) {
2009-10-14 09:28:58 +00:00
gfxop_add_to_pic ( _s - > gfx_state , pictureId , picFlags , palNo ) ;
2009-10-03 20:49:18 +00:00
} else {
2009-10-14 09:28:58 +00:00
gfxop_new_pic ( _s - > gfx_state , pictureId , picFlags , palNo ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-14 09:28:58 +00:00
delete _s - > wm_port ;
delete _s - > picture_port ;
delete _s - > iconbar_port ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > wm_port = new GfxPort ( _s - > visual , _s - > gfx_state - > pic_port_bounds , _s - > ega_colors [ 0 ] , transparent ) ;
_s - > picture_port = new GfxPort ( _s - > visual , _s - > gfx_state - > pic_port_bounds , _s - > ega_colors [ 0 ] , transparent ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > iconbar_port = new GfxPort ( _s - > visual , gfx_rect ( 0 , 0 , 320 , 200 ) , _s - > ega_colors [ 0 ] , transparent ) ;
_s - > iconbar_port - > _flags | = GFXW_FLAG_NO_IMPLICIT_SWITCH ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > visual - > add ( ( GfxContainer * ) _s - > visual , _s - > picture_port ) ;
_s - > visual - > add ( ( GfxContainer * ) _s - > visual , _s - > wm_port ) ;
_s - > visual - > add ( ( GfxContainer * ) _s - > visual , _s - > iconbar_port ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > port = _s - > picture_port ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > pic_priority_table = gfxop_get_pic_metainfo ( _s - > gfx_state ) ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > pic_animate = animationNr ; // The animation used during kAnimate() later on
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > dyn_views = NULL ;
_s - > drop_views = NULL ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > priority_first = 42 ;
2009-10-03 20:49:18 +00:00
if ( _usesOldGfxFunctions )
2009-10-14 09:28:58 +00:00
_s - > priority_last = 200 ;
2009-10-03 20:49:18 +00:00
else
2009-10-14 09:28:58 +00:00
_s - > priority_last = 190 ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
_s - > pic_not_valid = 1 ;
_s - > pic_is_new = 1 ;
2009-10-03 20:49:18 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : drawCel ( GuiResourceId viewId , GuiViewLoopNo loopNo , GuiViewCelNo celNo , uint16 leftPos , uint16 topPos , int16 priority , uint16 paletteNo ) {
2009-10-03 20:49:18 +00:00
int loop = loopNo ;
2009-10-05 07:10:01 +00:00
int cel = celNo ;
2009-10-03 20:49:18 +00:00
GfxView * new_view ;
2009-10-14 09:28:58 +00:00
gfxop_check_cel ( _s - > gfx_state , viewId , & loop , & cel ) ;
2009-10-03 20:49:18 +00:00
debugC ( 2 , kDebugLevelGraphics , " DrawCel((%d,%d), (view.%d, %d, %d), p=%d) \n " , leftPos , topPos , viewId , loop , cel , priority ) ;
2009-10-14 09:28:58 +00:00
new_view = gfxw_new_view ( _s - > gfx_state , Common : : Point ( leftPos , topPos ) , viewId , loop , cel , 0 , priority , - 1 ,
2009-10-03 20:49:18 +00:00
ALIGN_LEFT , ALIGN_TOP , GFXW_VIEW_FLAG_DONT_MODIFY_OFFSET ) ;
ADD_TO_CURRENT_PICTURE_PORT ( new_view ) ;
FULL_REDRAW ( ) ;
}
2009-10-06 16:36:28 +00:00
void SciGui32 : : drawControlButton ( Common : : Rect rect , reg_t obj , const char * text , int16 fontId , int16 style , bool hilite ) {
2009-10-03 20:49:18 +00:00
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
2009-10-14 09:28:58 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_button_control ( _s - > port , obj , area , text , fontId ,
2009-10-06 16:36:28 +00:00
( int8 ) ( style & kControlStateFramed ) , ( int8 ) hilite , ( int8 ) ( style & kControlStateDisabled ) ) ) ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > pic_not_valid ) FULL_REDRAW ( ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-06 16:36:28 +00:00
void SciGui32 : : drawControlText ( Common : : Rect rect , reg_t obj , const char * text , int16 fontId , int16 mode , int16 style , bool hilite ) {
2009-10-03 20:49:18 +00:00
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
2009-10-14 09:28:58 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_text_control ( _s - > port , obj , area , text , fontId , ( gfx_alignment_t ) mode ,
2009-10-06 16:36:28 +00:00
( int8 ) ( ! ! ( style & kControlStateDitherFramed ) ) , ( int8 ) hilite ) ) ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > pic_not_valid ) FULL_REDRAW ( ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-11 14:28:20 +00:00
void SciGui32 : : drawControlTextEdit ( Common : : Rect rect , reg_t obj , const char * text , int16 fontId , int16 mode , int16 style , int16 cursorPos , int16 maxChars , bool hilite ) {
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
2009-10-11 14:30:55 +00:00
int16 textLength = strlen ( text ) ;
2009-10-11 14:28:20 +00:00
2009-10-11 14:30:55 +00:00
if ( cursorPos > textLength )
cursorPos = textLength ;
2009-10-11 14:28:20 +00:00
// update_cursor_limits(&s->save_dir_edit_offset, &cursor, max); FIXME: get rid of this?
2009-10-14 09:28:58 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_edit_control ( _s - > port , obj , area , text , fontId , ( unsigned ) cursorPos , ( int8 ) hilite ) ) ;
if ( ! _s - > pic_not_valid ) FULL_REDRAW ( ) ;
2009-10-11 14:28:20 +00:00
}
2009-10-06 16:36:28 +00:00
void SciGui32 : : drawControlIcon ( Common : : Rect rect , reg_t obj , GuiResourceId viewId , GuiViewLoopNo loopNo , GuiViewCelNo cellNo , int16 style , bool hilite ) {
2009-10-05 11:42:04 +00:00
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
2009-10-14 09:28:58 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_icon_control ( _s - > port , obj , area , viewId , loopNo , cellNo ,
2009-10-06 16:36:28 +00:00
( int8 ) ( style & kControlStateFramed ) , ( int8 ) hilite ) ) ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > pic_not_valid ) FULL_REDRAW ( ) ;
2009-10-05 11:42:04 +00:00
}
2009-10-11 15:41:52 +00:00
void SciGui32 : : drawControlList ( Common : : Rect rect , reg_t obj , int16 maxChars , int16 count , const char * * entries , GuiResourceId fontId , int16 style , int16 upperPos , int16 cursorPos , bool isAlias , bool hilite ) {
2009-10-11 14:28:20 +00:00
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
2009-10-14 09:28:58 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( sciw_new_list_control ( _s - > port , obj , area , fontId , entries , count , upperPos , cursorPos , ( int8 ) hilite ) ) ;
if ( ! _s - > pic_not_valid ) FULL_REDRAW ( ) ;
2009-10-11 14:28:20 +00:00
}
2009-10-11 12:15:17 +00:00
// Control types and flags
enum {
K_CONTROL_BUTTON = 1 ,
K_CONTROL_TEXT = 2 ,
K_CONTROL_EDIT = 3 ,
K_CONTROL_ICON = 4 ,
K_CONTROL_CONTROL = 6 ,
K_CONTROL_CONTROL_ALIAS = 7 ,
K_CONTROL_BOX = 10
} ;
# define _K_EDIT_DELETE \
if ( cursor < textlen ) { \
text . deleteChar ( cursor ) ; \
}
# define _K_EDIT_BACKSPACE \
if ( cursor ) { \
- - cursor ; \
text . deleteChar ( cursor ) ; \
- - textlen ; \
}
void update_cursor_limits ( int * display_offset , int * cursor , int max_displayed ) {
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 ;
}
2009-10-11 14:28:20 +00:00
void _k_GenericDrawControl ( EngineState * s , reg_t controlObject , bool hilite ) ;
2009-10-11 12:45:40 +00:00
static inline int sign_extend_byte ( int value ) {
if ( value & 0x80 )
return value - 256 ;
else
return value ;
}
2009-10-11 12:15:17 +00:00
void SciGui32 : : editControl ( reg_t controlObject , reg_t eventObject ) {
2009-10-14 09:28:58 +00:00
SegManager * segMan = _s - > _segMan ;
2009-10-11 12:15:17 +00:00
uint16 ct_type = GET_SEL32V ( controlObject , type ) ;
switch ( ct_type ) {
case 0 :
break ; // NOP
case K_CONTROL_EDIT :
if ( eventObject . segment & & ( ( GET_SEL32V ( eventObject , type ) ) = = SCI_EVT_KEYBOARD ) ) {
int max_displayed = GET_SEL32V ( controlObject , max ) ;
int max = max_displayed ;
int cursor = GET_SEL32V ( controlObject , cursor ) ;
int modifiers = GET_SEL32V ( eventObject , modifiers ) ;
int key = GET_SEL32V ( eventObject , message ) ;
reg_t text_pos = GET_SEL32 ( controlObject , text ) ;
int display_offset = 0 ;
2009-10-14 09:28:58 +00:00
Common : : String text = _s - > _segMan - > getString ( text_pos ) ;
2009-10-11 12:15:17 +00:00
int textlen ;
#if 0
if ( ! text ) {
warning ( " Could not draw control: %04x:%04x does not reference text " , PRINT_REG ( text_pos ) ) ;
2009-10-14 09:28:58 +00:00
return _s - > r_acc ;
2009-10-11 12:15:17 +00:00
}
# endif
textlen = text . size ( ) ;
cursor + = display_offset ;
if ( cursor > textlen )
cursor = textlen ;
if ( modifiers & SCI_EVM_CTRL ) {
switch ( tolower ( ( char ) key ) ) {
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 = Common : : String ( text . c_str ( ) , cursor ) ;
break ; // Terminate string
case ' h ' :
_K_EDIT_BACKSPACE ;
break ;
case ' d ' :
_K_EDIT_DELETE ;
break ;
}
PUT_SEL32V ( eventObject , claimed , 1 ) ;
} else if ( modifiers & SCI_EVM_ALT ) { // Ctrl has precedence over Alt
switch ( key ) {
case 0x2100 /* A-f */ :
while ( ( cursor < textlen ) & & ( text [ cursor + + ] ! = ' ' ) )
;
break ;
case 0x3000 /* A-b */ :
while ( ( cursor > 0 ) & & ( text [ - - cursor - 1 ] ! = ' ' ) )
;
break ;
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 ( eventObject , claimed , 1 ) ;
} else if ( key < 31 ) {
PUT_SEL32V ( eventObject , claimed , 1 ) ;
switch ( key ) {
case SCI_K_BACKSPACE :
_K_EDIT_BACKSPACE ;
break ;
default :
PUT_SEL32V ( eventObject , claimed , 0 ) ;
}
} else if ( key & 0xff00 ) {
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 ;
}
PUT_SEL32V ( eventObject , 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 + = key ;
cursor + + ;
}
} else if ( inserting ) {
if ( textlen < max ) {
int i ;
for ( i = textlen + 2 ; i > = cursor ; i - - )
text . setChar ( text [ i - 1 ] , i ) ;
text . setChar ( key , cursor + + ) ;
}
} else { // Overwriting
text . setChar ( key , cursor + + ) ;
}
if ( max_displayed < max )
update_cursor_limits ( & display_offset , & cursor , max_displayed ) ;
cursor - = display_offset ;
PUT_SEL32V ( eventObject , claimed , 1 ) ;
}
PUT_SEL32V ( controlObject , cursor , cursor ) ; // Write back cursor position
2009-10-14 09:28:58 +00:00
_s - > _segMan - > strcpy ( text_pos , text . c_str ( ) ) ; // Write back string
2009-10-11 12:15:17 +00:00
}
if ( eventObject . segment ) PUT_SEL32V ( eventObject , claimed , 1 ) ;
2009-10-14 09:28:58 +00:00
_k_GenericDrawControl ( _s , controlObject , false ) ;
2009-10-11 12:15:17 +00:00
return ;
case K_CONTROL_ICON :
case K_CONTROL_BOX :
case K_CONTROL_BUTTON :
return ;
case K_CONTROL_TEXT : {
int state = GET_SEL32V ( controlObject , state ) ;
PUT_SEL32V ( controlObject , state , state | kControlStateDitherFramed ) ;
2009-10-14 09:28:58 +00:00
_k_GenericDrawControl ( _s , controlObject , false ) ;
2009-10-11 12:15:17 +00:00
PUT_SEL32V ( controlObject , state , state ) ;
}
break ;
default :
warning ( " Attempt to edit control type %d " , ct_type ) ;
}
}
2009-10-03 20:49:18 +00:00
static gfx_color_t graph_map_color ( EngineState * s , int color , int priority , int control ) {
gfx_color_t retval ;
if ( ! s - > resMan - > isVGA ( ) ) {
retval = s - > ega_colors [ ( color > = 0 & & color < 16 ) ? color : 0 ] ;
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 {
retval . visual = get_pic_color ( s , color ) ;
retval . alpha = 0 ;
retval . priority = priority ;
retval . control = control ;
retval . mask = GFX_MASK_VISUAL | ( ( priority > = 0 ) ? GFX_MASK_PRIORITY : 0 ) | ( ( control > = 0 ) ? GFX_MASK_CONTROL : 0 ) ;
} ;
return retval ;
}
void _k_graph_rebuild_port_with_color ( EngineState * s , gfx_color_t newbgcolor ) {
GfxPort * port = s - > port ;
GfxPort * newport ;
newport = sciw_new_window ( s , port - > zone , port - > _font , port - > _color , newbgcolor ,
s - > titlebar_port - > _font , s - > ega_colors [ 15 ] , s - > ega_colors [ 8 ] ,
port - > _title_text . c_str ( ) , port - > port_flags & ~ kWindowTransparent ) ;
if ( s - > dyn_views ) {
int found = 0 ;
GfxContainer * parent = s - > dyn_views - > _parent ;
while ( parent & & ! ( found | = ( parent = = port ) ) )
parent = parent - > _parent ;
s - > dyn_views = NULL ;
}
port - > _parent - > add ( ( GfxContainer * ) port - > _parent , newport ) ;
delete port ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : graphFillBoxForeground ( Common : : Rect rect ) {
2009-10-14 09:28:58 +00:00
_k_graph_rebuild_port_with_color ( _s , _s - > port - > _color ) ;
2009-10-03 20:49:18 +00:00
//port = _s->port;
FULL_REDRAW ( ) ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : graphFillBoxBackground ( Common : : Rect rect ) {
2009-10-14 09:28:58 +00:00
_k_graph_rebuild_port_with_color ( _s , _s - > port - > _bgcolor ) ;
2009-10-03 20:49:18 +00:00
//port = _s->port;
FULL_REDRAW ( ) ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : graphFillBox ( Common : : Rect rect , uint16 colorMask , int16 color , int16 priority , int16 control ) {
2009-10-14 09:28:58 +00:00
gfx_color_t fillColor = graph_map_color ( _s , color , priority , control ) ;
2009-10-03 20:49:18 +00:00
fillColor . mask = ( byte ) colorMask ;
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
//debugC(2, kDebugLevelGraphics, "fill_box_any((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d)\n",
// argv[2].toSint16(), argv[1].toSint16(), argv[4].toSint16(), argv[3].toSint16(), argv[6].toSint16(), priority, control, argv[5].toUint16());
// FIXME/TODO: this is not right, as some of the dialogs are drawn *behind* some widgets. But at least it works for now
2009-10-14 09:28:58 +00:00
//ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(_s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT)); // old code
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
// FillBox seems to be meant again _s->port instead of _s->picture_port, at least in QfG3
2009-10-03 20:49:18 +00:00
// warning("Fillbox");
2009-10-14 09:28:58 +00:00
// ADD_TO_CURRENT_PICTURE_PORT(gfxw_new_box(_s->gfx_state, area, color, color, GFX_BOX_SHADE_FLAT));
_s - > picture_port - > add ( ( GfxContainer * ) _s - > picture_port , gfxw_new_box ( _s - > gfx_state , area , fillColor , fillColor , GFX_BOX_SHADE_FLAT ) ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-05 13:33:26 +00:00
void SciGui32 : : graphDrawLine ( Common : : Point startPoint , Common : : Point endPoint , int16 color , int16 priority , int16 control ) {
2009-10-14 09:28:58 +00:00
gfx_color_t gfxcolor = graph_map_color ( _s , color , priority , control ) ;
2009-10-03 20:49:18 +00:00
debugC ( 2 , kDebugLevelGraphics , " draw_line((%d, %d), (%d, %d), col=%d, p=%d, c=%d, mask=%d) \n " ,
2009-10-05 13:33:26 +00:00
startPoint . x , startPoint . y , endPoint . x , endPoint . y , color , priority , control , gfxcolor . mask ) ;
2009-10-03 20:49:18 +00:00
2009-10-05 13:33:26 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( gfxw_new_line ( startPoint , endPoint ,
2009-10-03 20:49:18 +00:00
gfxcolor , GFX_LINE_MODE_CORRECT , GFX_LINE_STYLE_NORMAL ) ) ;
FULL_REDRAW ( ) ;
}
2009-10-05 07:10:01 +00:00
reg_t SciGui32 : : graphSaveBox ( Common : : Rect rect , uint16 flags ) {
2009-10-03 20:49:18 +00:00
rect_t area ;
2009-10-14 09:28:58 +00:00
area . x = rect . left + _s - > port - > zone . x + port_origin_x ;
area . y = rect . top + _s - > port - > zone . y + port_origin_y ;
2009-10-03 20:49:18 +00:00
area . width = rect . width ( ) - port_origin_x ;
area . height = rect . height ( ) - port_origin_y ;
2009-10-14 09:28:58 +00:00
return graph_save_box ( _s , area ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : graphRestoreBox ( reg_t handle ) {
2009-10-14 09:28:58 +00:00
graph_restore_box ( _s , handle ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-12 07:11:22 +00:00
void SciGui32 : : graphUpdateBox ( Common : : Rect rect ) {
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
2009-10-14 09:28:58 +00:00
area . x + = _s - > port - > zone . x ;
area . y + = _s - > port - > zone . y ;
2009-10-12 07:11:22 +00:00
2009-10-14 09:28:58 +00:00
gfxop_update_box ( _s - > gfx_state , area ) ;
2009-10-12 07:11:22 +00:00
}
2009-10-12 11:36:42 +00:00
void SciGui32 : : graphRedrawBox ( Common : : Rect rect ) {
rect_t area = gfx_rect ( rect . left , rect . top , rect . width ( ) , rect . height ( ) ) ;
2009-10-14 09:28:58 +00:00
area . x + = _s - > port - > zone . x ;
area . y + = _s - > port - > zone . y ;
2009-10-12 11:36:42 +00:00
2009-10-14 09:28:58 +00:00
if ( _s - > dyn_views & & _s - > dyn_views - > _parent = = ( GfxContainer * ) _s - > port )
_s - > dyn_views - > draw ( Common : : Point ( 0 , 0 ) ) ;
2009-10-12 11:36:42 +00:00
2009-10-14 09:28:58 +00:00
gfxop_update_box ( _s - > gfx_state , area ) ;
2009-10-12 11:36:42 +00:00
}
2009-10-12 07:30:55 +00:00
int16 SciGui32 : : picNotValid ( int16 newPicNotValid ) {
2009-10-14 09:28:58 +00:00
int16 oldPicNotValid = _s - > pic_not_valid ;
2009-10-12 07:30:55 +00:00
if ( newPicNotValid ! = - 1 )
2009-10-14 09:28:58 +00:00
_s - > pic_not_valid = newPicNotValid ;
2009-10-12 07:30:55 +00:00
return oldPicNotValid ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : paletteSet ( int resourceNo , int flags ) {
2009-10-03 20:49:18 +00:00
//warning("STUB");
}
2009-10-05 07:10:01 +00:00
int16 SciGui32 : : paletteFind ( int r , int g , int b ) {
2009-10-03 20:49:18 +00:00
int i , delta , bestindex = - 1 , bestdelta = 200000 ;
2009-10-14 09:28:58 +00:00
for ( i = 0 ; i < _s - > gfx_state - > gfxResMan - > getColorCount ( ) ; i + + ) {
int dr = abs ( _s - > gfx_state - > gfxResMan - > getColor ( i ) . r - r ) ;
int dg = abs ( _s - > gfx_state - > gfxResMan - > getColor ( i ) . g - g ) ;
int db = abs ( _s - > gfx_state - > gfxResMan - > getColor ( i ) . b - b ) ;
2009-10-03 20:49:18 +00:00
delta = dr * dr + dg * dg + db * db ;
if ( delta < bestdelta ) {
bestdelta = delta ;
bestindex = i ;
}
}
// Don't warn about inexact mappings -- it's actually the
// rule rather than the exception
return bestindex ;
}
2009-10-14 18:35:15 +00:00
void SciGui32 : : paletteSetIntensity ( int fromColor , int toColor , int intensity ) {
2009-10-04 19:49:47 +00:00
#if 0
2009-10-14 09:28:58 +00:00
_s - > gfx_state - > gfxResMan - > setPaletteIntensity ( fromColor , toColor , intensity ) ;
2009-10-04 19:49:47 +00:00
# endif
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : paletteAnimate ( int fromColor , int toColor , int speed ) {
2009-10-05 19:30:17 +00:00
//warning("STUB");
2009-10-03 20:49:18 +00:00
}
2009-10-11 08:52:23 +00:00
# define SHAKE_DOWN 1
# define SHAKE_RIGHT 2
void SciGui32 : : shakeScreen ( uint16 shakeCount , uint16 directions ) {
2009-10-14 09:28:58 +00:00
gfx_pixmap_t * screen = gfxop_grab_pixmap ( _s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 200 ) ) ;
2009-10-11 08:52:23 +00:00
int i ;
if ( directions & ~ 3 )
debugC ( 2 , kDebugLevelGraphics , " ShakeScreen(): Direction bits are %x (unknown) \n " , directions ) ;
2009-10-14 09:28:58 +00:00
gfxop_set_clip_zone ( _s - > gfx_state , gfx_rect_fullscreen ) ;
2009-10-11 08:52:23 +00:00
for ( i = 0 ; i < shakeCount ; i + + ) {
int shake_down = ( directions & SHAKE_DOWN ) ? 10 : 0 ;
int shake_right = ( directions & SHAKE_RIGHT ) ? 10 : 0 ;
if ( directions & SHAKE_DOWN )
2009-10-14 09:28:58 +00:00
gfxop_draw_box ( _s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 10 ) , _s - > ega_colors [ 0 ] , _s - > ega_colors [ 0 ] , GFX_BOX_SHADE_FLAT ) ;
2009-10-11 08:52:23 +00:00
if ( directions & SHAKE_RIGHT )
2009-10-14 09:28:58 +00:00
gfxop_draw_box ( _s - > gfx_state , gfx_rect ( 0 , 0 , 10 , 200 ) , _s - > ega_colors [ 0 ] , _s - > ega_colors [ 0 ] , GFX_BOX_SHADE_FLAT ) ;
2009-10-11 08:52:23 +00:00
2009-10-14 09:28:58 +00:00
gfxop_draw_pixmap ( _s - > gfx_state , screen , gfx_rect ( 0 , 0 , 320 - shake_right , 200 - shake_down ) ,
2009-10-11 08:52:23 +00:00
Common : : Point ( shake_right , shake_down ) ) ;
2009-10-14 09:28:58 +00:00
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , 50 ) ;
2009-10-11 08:52:23 +00:00
2009-10-14 09:28:58 +00:00
gfxop_draw_pixmap ( _s - > gfx_state , screen , gfx_rect ( 0 , 0 , 320 , 200 ) , Common : : Point ( 0 , 0 ) ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , 50 ) ;
2009-10-11 08:52:23 +00:00
}
2009-10-14 09:28:58 +00:00
gfxop_free_pixmap ( _s - > gfx_state , screen ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-11 08:52:23 +00:00
}
2009-10-09 16:51:10 +00:00
uint16 SciGui32 : : onControl ( byte screenMask , Common : : Rect rect ) {
2009-10-04 10:42:18 +00:00
gfx_map_mask_t map = ( gfx_map_mask_t ) screenMask ;
rect_t gfxrect = gfx_rect ( rect . left , rect . top + 10 , rect . width ( ) , rect . height ( ) ) ;
2009-10-14 09:28:58 +00:00
return gfxop_scan_bitmask ( _s - > gfx_state , gfxrect , map ) ;
2009-10-04 14:59:51 +00:00
// old code, just for reference
2009-10-04 10:42:18 +00:00
// 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) argv[0].toSint16();
// }
//
// ystart = argv[arg + 1].toSint16();
// xstart = argv[arg].toSint16();
//
// if (argc > 3) {
// ylen = argv[arg + 3].toSint16() - ystart;
// xlen = argv[arg + 2].toSint16() - xstart;
// }
//
2009-10-14 09:28:58 +00:00
// return make_reg(0, gfxop_scan_bitmask(_s->gfx_state, gfx_rect(xstart, ystart + 10, xlen, ylen), map));
2009-10-04 10:42:18 +00:00
}
2009-10-04 14:59:51 +00:00
enum {
_K_MAKE_VIEW_LIST_CYCLE = 1 ,
_K_MAKE_VIEW_LIST_CALC_PRIORITY = 2 ,
_K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP = 4
} ;
2009-10-05 07:10:01 +00:00
GfxDynView * SciGui32 : : _k_make_dynview_obj ( reg_t obj , int options , int nr , int argc , reg_t * argv ) {
2009-10-14 09:28:58 +00:00
SegManager * segMan = _s - > _segMan ;
2009-10-04 14:59:51 +00:00
short oldloop , oldcel ;
int cel , loop , view_nr = ( int16 ) GET_SEL32V ( obj , view ) ;
int palette ;
int signal ;
reg_t under_bits ;
Common : : Point pos ;
int z ;
GfxDynView * widget ;
debugC ( 2 , kDebugLevelGraphics , " - Adding %04x:%04x \n " , PRINT_REG ( obj ) ) ;
obj = obj ;
pos . x = ( int16 ) GET_SEL32V ( obj , x ) ;
pos . y = ( int16 ) GET_SEL32V ( obj , y ) ;
pos . y + + ; // magic: Sierra appears to do something like this
z = ( int16 ) GET_SEL32V ( obj , z ) ;
// !-- nsRect used to be checked here!
loop = oldloop = sign_extend_byte ( GET_SEL32V ( obj , loop ) ) ;
cel = oldcel = sign_extend_byte ( GET_SEL32V ( obj , cel ) ) ;
2009-10-14 09:28:58 +00:00
if ( _s - > _kernel - > _selectorCache . palette )
2009-10-04 14:59:51 +00:00
palette = GET_SEL32V ( obj , palette ) ;
else
palette = 0 ;
// Clip loop and cel, write back if neccessary
2009-10-14 09:28:58 +00:00
gfxop_check_cel ( _s - > gfx_state , view_nr , & loop , & cel ) ;
2009-10-04 14:59:51 +00:00
if ( loop ! = oldloop )
loop = 0 ;
if ( cel ! = oldcel )
cel = 0 ;
if ( oldloop ! = loop )
PUT_SEL32V ( obj , loop , loop ) ;
if ( oldcel ! = cel ) {
PUT_SEL32V ( obj , cel , cel ) ;
}
ObjVarRef under_bitsp ;
2009-10-14 09:28:58 +00:00
if ( lookup_selector ( _s - > _segMan , obj , _s - > _kernel - > _selectorCache . underBits , & ( under_bitsp ) , NULL ) ! = kSelectorVariable ) {
2009-10-04 14:59:51 +00:00
under_bitsp . obj = NULL_REG ;
under_bits = NULL_REG ;
debugC ( 2 , kDebugLevelGraphics , " Object at %04x:%04x has no underBits \n " , PRINT_REG ( obj ) ) ;
} else
2009-10-14 09:28:58 +00:00
under_bits = * under_bitsp . getPointer ( _s - > _segMan ) ;
2009-10-04 14:59:51 +00:00
ObjVarRef signalp ;
2009-10-14 09:28:58 +00:00
if ( lookup_selector ( _s - > _segMan , obj , _s - > _kernel - > _selectorCache . signal , & ( signalp ) , NULL ) ! = kSelectorVariable ) {
2009-10-04 14:59:51 +00:00
signalp . obj = NULL_REG ;
signal = 0 ;
debugC ( 2 , kDebugLevelGraphics , " Object at %04x:%04x has no signal selector \n " , PRINT_REG ( obj ) ) ;
} else {
2009-10-14 09:28:58 +00:00
signal = signalp . getPointer ( _s - > _segMan ) - > offset ;
2009-10-04 14:59:51 +00:00
debugC ( 2 , kDebugLevelGraphics , " with signal = %04x \n " , signal ) ;
}
2009-10-14 09:28:58 +00:00
widget = gfxw_new_dyn_view ( _s - > gfx_state , pos , z , view_nr , loop , cel , palette , - 1 , - 1 , ALIGN_CENTER , ALIGN_BOTTOM , nr ) ;
2009-10-04 14:59:51 +00:00
if ( widget ) {
widget = ( GfxDynView * ) gfxw_set_id ( widget , obj . segment , obj . offset ) ;
widget = gfxw_dyn_view_set_params ( widget , under_bits . segment , under_bitsp , signal , signalp ) ;
widget - > _flags | = GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ; // Only works the first time 'round'
return widget ;
} else {
warning ( " Could not generate dynview widget for %d/%d/%d " , view_nr , loop , cel ) ;
return NULL ;
}
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_make_view_list ( GfxList * * widget_list , List * list , int options , int argc , reg_t * argv ) {
2009-10-04 14:59:51 +00:00
/* Creates a view_list from a node list in heap space. Returns the list, stores the
* * number of list entries in * list_nr . Calls doit for each entry if cycle is set .
* * argc , argv should be the same as in the calling kernel function .
*/
2009-10-14 09:28:58 +00:00
EngineState * s = _s ;
SegManager * segMan = _s - > _segMan ;
2009-10-04 14:59:51 +00:00
Node * node ;
int sequence_nr = 0 ;
GfxDynView * widget ;
if ( ! * widget_list ) {
error ( " make_view_list with widget_list == () " ) ;
} ;
2009-10-14 09:28:58 +00:00
assert_primary_widget_lists ( _s ) ;
2009-10-04 14:59:51 +00:00
// In case one of the views' doit() does a DrawPic...
// Yes, this _does_ happen!
if ( ! list ) { // list sanity check
error ( " Attempt to make list from non-list " ) ;
}
reg_t next_node = list - > first ;
2009-10-14 09:28:58 +00:00
node = _s - > _segMan - > lookupNode ( next_node ) ;
2009-10-04 14:59:51 +00:00
while ( node ) {
reg_t obj = node - > value ; // The object we're using
GfxDynView * tempWidget ;
if ( options & _K_MAKE_VIEW_LIST_CYCLE ) {
unsigned int signal = GET_SEL32V ( obj , signal ) ;
if ( ! ( signal & _K_VIEW_SIG_FLAG_FROZEN ) ) {
debugC ( 2 , kDebugLevelGraphics , " invoking %04x:%04x::doit() \n " , PRINT_REG ( obj ) ) ;
invoke_selector ( INV_SEL ( obj , doit , kContinueOnInvalidSelector ) , 0 ) ; // Call obj::doit() if neccessary
// Lookup node again, since the NodeTable it was in may
// have been re-allocated.
2009-10-14 09:28:58 +00:00
node = _s - > _segMan - > lookupNode ( next_node ) ;
2009-10-04 14:59:51 +00:00
}
}
next_node = node - > succ ; // In case the cast list was changed
if ( list - > first . segment = = 0 & & list - > first . offset = = 0 ) // The cast list was completely emptied!
break ;
tempWidget = _k_make_dynview_obj ( obj , options , sequence_nr - - , argc , argv ) ;
if ( tempWidget )
( * widget_list ) - > add ( ( GfxContainer * ) ( * widget_list ) , tempWidget ) ;
2009-10-14 09:28:58 +00:00
node = _s - > _segMan - > lookupNode ( next_node ) ; // Next node
2009-10-04 14:59:51 +00:00
}
widget = ( GfxDynView * ) ( * widget_list ) - > _contents ;
while ( widget ) { // Read back widget values
2009-10-14 09:28:58 +00:00
reg_t * sp = widget - > signalp . getPointer ( _s - > _segMan ) ;
2009-10-04 14:59:51 +00:00
if ( sp )
widget - > signal = sp - > offset ;
widget = ( GfxDynView * ) widget - > _next ;
}
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : draw_rect_to_control_map ( Common : : Rect abs_zone ) {
2009-10-04 14:59:51 +00:00
GfxBox * box ;
gfx_color_t color ;
2009-10-14 09:28:58 +00:00
gfxop_set_color ( _s - > gfx_state , & color , - 1 , - 1 , - 1 , - 1 , - 1 , 0xf ) ;
2009-10-04 14:59:51 +00:00
debugC ( 2 , kDebugLevelGraphics , " adding control block (%d,%d)to(%d,%d) \n " , abs_zone . left , abs_zone . top , abs_zone . right , abs_zone . bottom ) ;
2009-10-14 09:28:58 +00:00
box = gfxw_new_box ( _s - > gfx_state , gfx_rect ( abs_zone . left , abs_zone . top , abs_zone . width ( ) ,
2009-10-04 14:59:51 +00:00
abs_zone . height ( ) ) , color , color , GFX_BOX_SHADE_FLAT ) ;
2009-10-14 09:28:58 +00:00
assert_primary_widget_lists ( _s ) ;
2009-10-04 14:59:51 +00:00
ADD_TO_CURRENT_PICTURE_PORT ( box ) ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : draw_obj_to_control_map ( GfxDynView * view ) {
2009-10-04 14:59:51 +00:00
reg_t obj = make_reg ( view - > _ID , view - > _subID ) ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > _segMan - > isObject ( obj ) )
2009-10-04 14:59:51 +00:00
warning ( " View %d does not contain valid object reference %04x:%04x " , view - > _ID , PRINT_REG ( obj ) ) ;
2009-10-14 09:28:58 +00:00
reg_t * sp = view - > signalp . getPointer ( _s - > _segMan ) ;
2009-10-04 14:59:51 +00:00
if ( ! ( sp & & ( sp - > offset & _K_VIEW_SIG_FLAG_IGNORE_ACTOR ) ) ) {
2009-10-14 09:28:58 +00:00
Common : : Rect abs_zone = get_nsrect32 ( _s , make_reg ( view - > _ID , view - > _subID ) , 1 ) ;
2009-10-04 14:59:51 +00:00
draw_rect_to_control_map ( abs_zone ) ;
}
}
2009-10-05 07:10:01 +00:00
int SciGui32 : : _k_view_list_dispose_loop ( List * list , GfxDynView * widget , int argc , reg_t * argv ) {
2009-10-04 14:59:51 +00:00
// disposes all list members flagged for disposal
// returns non-zero IFF views were dropped
int signal ;
int dropped = 0 ;
2009-10-14 09:28:58 +00:00
EngineState * s = _s ;
SegManager * segMan = _s - > _segMan ;
2009-10-04 14:59:51 +00:00
_k_animate_ran = false ;
if ( widget ) {
int retval ;
// Recurse:
retval = _k_view_list_dispose_loop ( list , ( GfxDynView * ) widget - > _next , argc , argv ) ;
if ( retval = = - 1 ) // Bail out on annihilation, rely on re-start from Animate()
return - 1 ;
if ( GFXW_IS_DYN_VIEW ( widget ) & & ( widget - > _ID ! = GFXW_NO_ID ) ) {
signal = widget - > signalp . getPointer ( segMan ) - > offset ;
if ( signal & _K_VIEW_SIG_FLAG_DISPOSE_ME ) {
reg_t obj = make_reg ( widget - > _ID , widget - > _subID ) ;
reg_t under_bits = NULL_REG ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > _segMan - > isObject ( obj ) ) {
2009-10-04 14:59:51 +00:00
error ( " Non-object %04x:%04x present in view list during delete time " , PRINT_REG ( obj ) ) ;
obj = NULL_REG ;
} else {
reg_t * ubp = widget - > under_bitsp . getPointer ( segMan ) ;
if ( ubp ) { // Is there a bg picture left to clean?
reg_t mem_handle = * ubp ;
if ( mem_handle . segment ) {
2009-10-14 09:28:58 +00:00
if ( ! kfree ( _s - > _segMan , mem_handle ) ) {
2009-10-04 14:59:51 +00:00
* ubp = make_reg ( 0 , widget - > under_bits = 0 ) ;
} else {
warning ( " Treating viewobj %04x:%04x as no longer present " , PRINT_REG ( obj ) ) ;
obj = NULL_REG ;
}
}
}
}
if ( segMan - > isObject ( obj ) ) {
if ( invoke_selector ( INV_SEL ( obj , delete_ , kContinueOnInvalidSelector ) , 0 ) )
warning ( " Object at %04x:%04x requested deletion, but does not have a delete funcselector " , PRINT_REG ( obj ) ) ;
if ( _k_animate_ran ) {
warning ( " Object at %04x:%04x invoked kAnimate() during deletion " , PRINT_REG ( obj ) ) ;
return dropped ;
}
reg_t * ubp = widget - > under_bitsp . getPointer ( segMan ) ;
if ( ubp )
under_bits = * ubp ;
if ( under_bits . segment ) {
* ubp = make_reg ( 0 , 0 ) ;
2009-10-14 09:28:58 +00:00
graph_restore_box ( _s , under_bits ) ;
2009-10-04 14:59:51 +00:00
}
debugC ( 2 , kDebugLevelGraphics , " Freeing %04x:%04x with signal=%04x \n " , PRINT_REG ( obj ) , signal ) ;
if ( ! ( signal & _K_VIEW_SIG_FLAG_HIDDEN ) ) {
debugC ( 2 , kDebugLevelGraphics , " Adding view at %04x:%04x to background \n " , PRINT_REG ( obj ) ) ;
if ( ! ( gfxw_remove_id ( widget - > _parent , widget - > _ID , widget - > _subID ) = = widget ) ) {
error ( " Attempt to remove view with ID %x:%x from list failed " , widget - > _ID , widget - > _subID ) ;
}
s - > drop_views - > add ( ( GfxContainer * ) s - > drop_views , gfxw_picviewize_dynview ( widget ) ) ;
draw_obj_to_control_map ( widget ) ;
widget - > draw_bounds . y + = s - > dyn_views - > _bounds . y - widget - > _parent - > _bounds . y ;
widget - > draw_bounds . x + = s - > dyn_views - > _bounds . x - widget - > _parent - > _bounds . x ;
dropped = 1 ;
} else {
debugC ( 2 , kDebugLevelGraphics , " Deleting view at %04x:%04x \n " , PRINT_REG ( obj ) ) ;
widget - > _flags | = GFXW_FLAG_VISIBLE ;
gfxw_annihilate ( widget ) ;
return - 1 ; // restart: Done in Animate()
}
}
}
}
}
return dropped ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_set_now_seen ( reg_t object ) {
2009-10-14 09:28:58 +00:00
SegManager * segMan = _s - > _segMan ;
Common : : Rect absrect = get_nsrect32 ( _s , object , 0 ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
if ( lookup_selector ( _s - > _segMan , object , _s - > _kernel - > _selectorCache . nsTop , NULL , NULL ) ! = kSelectorVariable ) {
2009-10-04 14:59:51 +00:00
return ;
} // This isn't fatal
PUT_SEL32V ( object , nsLeft , absrect . left ) ;
PUT_SEL32V ( object , nsRight , absrect . right ) ;
PUT_SEL32V ( object , nsTop , absrect . top ) ;
PUT_SEL32V ( object , nsBottom , absrect . bottom ) ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_prepare_view_list ( GfxList * list , int options ) {
2009-10-14 09:28:58 +00:00
SegManager * segMan = _s - > _segMan ;
2009-10-04 14:59:51 +00:00
GfxDynView * view = ( GfxDynView * ) list - > _contents ;
while ( view ) {
reg_t obj = make_reg ( view - > _ID , view - > _subID ) ;
int priority , _priority ;
2009-10-14 09:28:58 +00:00
int has_nsrect = ( view - > _ID < = 0 ) ? 0 : lookup_selector ( _s - > _segMan , obj , _s - > _kernel - > _selectorCache . nsBottom , NULL , NULL ) = = kSelectorVariable ;
2009-10-04 14:59:51 +00:00
int oldsignal = view - > signal ;
_k_set_now_seen ( obj ) ;
_priority = /*GET_SELECTOR(obj, y); */ ( ( view - > _pos . y ) ) ;
2009-10-14 09:28:58 +00:00
_priority = _find_view_priority ( _s , _priority - 1 ) ;
2009-10-04 14:59:51 +00:00
if ( options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) { // Picview
priority = ( int16 ) GET_SEL32V ( obj , priority ) ;
if ( priority < 0 )
priority = _priority ; // Always for picviews
} else { // Dynview
if ( has_nsrect & & ! ( view - > signal & _K_VIEW_SIG_FLAG_FIX_PRI_ON ) ) { // Calculate priority
if ( options & _K_MAKE_VIEW_LIST_CALC_PRIORITY )
PUT_SEL32V ( obj , priority , _priority ) ;
priority = _priority ;
} else // DON'T calculate the priority
priority = ( int16 ) GET_SEL32V ( obj , priority ) ;
}
view - > _color . priority = priority ;
if ( priority > - 1 )
view - > _color . mask | = GFX_MASK_PRIORITY ;
else
view - > _color . mask & = ~ GFX_MASK_PRIORITY ;
// CR (from :Bob Heitman:) stopupdated views (like pic views) have
// their clipped nsRect drawn to the control map
if ( view - > signal & _K_VIEW_SIG_FLAG_STOP_UPDATE ) {
view - > signal | = _K_VIEW_SIG_FLAG_STOPUPD ;
debugC ( 2 , kDebugLevelGraphics , " Setting magic STOP_UPD for %04x:%04x \n " , PRINT_REG ( obj ) ) ;
}
if ( ( options & _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) )
draw_obj_to_control_map ( view ) ;
// Extreme Pattern Matching ugliness ahead...
if ( view - > signal & _K_VIEW_SIG_FLAG_NO_UPDATE ) {
if ( ( ( view - > signal & ( _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_FORCE_UPDATE ) ) ) // 9.1.1.1
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE ) ) = = _K_VIEW_SIG_FLAG_HIDDEN )
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE ) ) = = _K_VIEW_SIG_FLAG_REMOVE ) // 9.1.1.2
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) // 9.1.1.3
| | ( ( view - > signal & ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = ( _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) ) { // 9.1.1.4
2009-10-14 09:28:58 +00:00
_s - > pic_not_valid + + ;
2009-10-04 14:59:51 +00:00
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 ) {
2009-10-14 09:28:58 +00:00
_s - > pic_not_valid + + ;
2009-10-04 14:59:51 +00:00
view - > signal & = ~ _K_VIEW_SIG_FLAG_FORCE_UPDATE ;
} else { // if not STOP_UPDATE
if ( view - > signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE )
2009-10-14 09:28:58 +00:00
_s - > pic_not_valid + + ;
2009-10-04 14:59:51 +00:00
view - > signal & = ~ _K_VIEW_SIG_FLAG_FORCE_UPDATE ;
}
}
debugC ( 2 , kDebugLevelGraphics , " dv[%04x:%04x]: signal %04x -> %04x \n " , PRINT_REG ( obj ) , oldsignal , view - > signal ) ;
// Never happens
/* if (view->signal & 0) {
view - > signal & = ~ _K_VIEW_SIG_FLAG_STOPUPD ;
2009-10-14 09:28:58 +00:00
fprintf ( _stderr , " Unsetting magic StopUpd for view %04x:%04x \n " , PRINT_REG ( obj ) ) ;
2009-10-04 14:59:51 +00:00
} */
view = ( GfxDynView * ) view - > _next ;
}
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_update_signals_in_view_list ( GfxList * old_list , GfxList * new_list ) {
2009-10-04 14:59:51 +00:00
// O(n^2)... a bit painful, but much faster than the redraws it helps prevent
GfxDynView * old_widget = ( GfxDynView * ) old_list - > _contents ;
/* Traverses all old widgets, updates them with signals from the new widgets.
* * This is done to avoid evil hacks in widget . c ; widgets with unique IDs are
* * replaced there iff they are NOT equal_to a new widget with the same ID .
* * If they were replaced every time , we ' d be doing far too many redraws .
*/
while ( old_widget ) {
GfxDynView * new_widget = ( GfxDynView * ) new_list - > _contents ;
while ( new_widget
& & ( new_widget - > _ID ! = old_widget - > _ID
| | new_widget - > _subID ! = old_widget - > _subID ) )
new_widget = ( GfxDynView * ) new_widget - > _next ;
if ( new_widget ) {
int carry = old_widget - > signal & _K_VIEW_SIG_FLAG_STOPUPD ;
// Transfer 'stopupd' flag
if ( ( new_widget - > _pos . x ! = old_widget - > _pos . x )
| | ( new_widget - > _pos . y ! = old_widget - > _pos . y )
// No idea why this is supposed to be bad
/* || (new_widget->z != old_widget->z)
| | ( new_widget - > view ! = old_widget - > view )
| | ( new_widget - > loop ! = old_widget - > loop )
| | ( new_widget - > cel ! = old_widget - > cel )
*/ )
carry = 0 ;
old_widget - > signal = new_widget - > signal | = carry ;
}
old_widget = ( GfxDynView * ) old_widget - > _next ;
}
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_view_list_kryptonize ( GfxWidget * v ) {
2009-10-04 14:59:51 +00:00
if ( v ) {
v - > _flags & = ~ GFXW_FLAG_IMMUNE_TO_SNAPSHOTS ;
_k_view_list_kryptonize ( v - > _next ) ;
}
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_raise_topmost_in_view_list ( GfxList * list , GfxDynView * view ) {
2009-10-04 14:59:51 +00:00
if ( view ) {
GfxDynView * next = ( GfxDynView * ) view - > _next ;
// step 11
if ( ( view - > signal & ( _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_HIDDEN | _K_VIEW_SIG_FLAG_ALWAYS_UPDATE ) ) = = 0 ) {
debugC ( 2 , kDebugLevelGraphics , " Forcing precedence 2 at [%04x:%04x] with %04x \n " , PRINT_REG ( make_reg ( view - > _ID , view - > _subID ) ) , view - > signal ) ;
view - > force_precedence = 2 ;
if ( ( view - > signal & ( _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_HIDDEN ) ) = = _K_VIEW_SIG_FLAG_REMOVE ) {
view - > signal & = ~ _K_VIEW_SIG_FLAG_REMOVE ;
}
}
gfxw_remove_widget_from_container ( view - > _parent , view ) ;
if ( view - > signal & _K_VIEW_SIG_FLAG_HIDDEN )
gfxw_hide_widget ( view ) ;
else
gfxw_show_widget ( view ) ;
list - > add ( ( GfxContainer * ) list , view ) ;
_k_raise_topmost_in_view_list ( list , next ) ;
}
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_redraw_view_list ( GfxList * list ) {
2009-10-04 14:59:51 +00:00
GfxDynView * view = ( GfxDynView * ) list - > _contents ;
while ( view ) {
debugC ( 2 , kDebugLevelGraphics , " dv[%04x:%04x]: signal %04x \n " , PRINT_REG ( make_reg ( view - > _ID , view - > _subID ) ) , view - > signal ) ;
// step 1 of subalgorithm
if ( view - > signal & _K_VIEW_SIG_FLAG_NO_UPDATE ) {
if ( view - > signal & _K_VIEW_SIG_FLAG_FORCE_UPDATE )
view - > signal & = ~ _K_VIEW_SIG_FLAG_FORCE_UPDATE ;
if ( view - > signal & _K_VIEW_SIG_FLAG_UPDATED )
view - > signal & = ~ ( _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE ) ;
} else { // NO_UPD is not set
if ( view - > signal & _K_VIEW_SIG_FLAG_STOP_UPDATE ) {
view - > signal & = ~ _K_VIEW_SIG_FLAG_STOP_UPDATE ;
view - > signal | = _K_VIEW_SIG_FLAG_NO_UPDATE ;
}
}
debugC ( 2 , kDebugLevelGraphics , " at substep 6: signal %04x \n " , view - > signal ) ;
if ( view - > signal & _K_VIEW_SIG_FLAG_ALWAYS_UPDATE )
view - > signal & = ~ ( _K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE ) ;
debugC ( 2 , kDebugLevelGraphics , " at substep 11/14: signal %04x \n " , view - > signal ) ;
if ( view - > signal & _K_VIEW_SIG_FLAG_NO_UPDATE ) {
if ( view - > signal & _K_VIEW_SIG_FLAG_HIDDEN )
view - > signal | = _K_VIEW_SIG_FLAG_REMOVE ;
else
view - > signal & = ~ _K_VIEW_SIG_FLAG_REMOVE ;
} else if ( ! ( view - > signal & _K_VIEW_SIG_FLAG_HIDDEN ) )
view - > force_precedence = 1 ;
debugC ( 2 , kDebugLevelGraphics , " -> signal %04x \n " , view - > signal ) ;
view = ( GfxDynView * ) view - > _next ;
}
}
// Flags for _k_draw_view_list
// Whether some magic with the base object's "signal" selector should be done:
# define _K_DRAW_VIEW_LIST_USE_SIGNAL 1
// This flag draws all views with the "DISPOSE_ME" flag set:
# define _K_DRAW_VIEW_LIST_DISPOSEABLE 2
// Use this one to draw all views with "DISPOSE_ME" NOT set:
# define _K_DRAW_VIEW_LIST_NONDISPOSEABLE 4
// Draw as picviews
# define _K_DRAW_VIEW_LIST_PICVIEW 8
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_draw_view_list ( GfxList * list , int flags ) {
2009-10-04 14:59:51 +00:00
// Draws list_nr members of list to s->pic.
GfxDynView * widget = ( GfxDynView * ) list - > _contents ;
2009-10-14 09:28:58 +00:00
if ( ( GfxContainer * ) _s - > port ! = ( GfxContainer * ) _s - > dyn_views - > _parent )
2009-10-04 14:59:51 +00:00
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-10-14 09:28:58 +00:00
uint16 signal = ( flags & _K_DRAW_VIEW_LIST_USE_SIGNAL ) ? widget - > signalp . getPointer ( _s - > _segMan ) - > offset : 0 ;
2009-10-04 14:59:51 +00:00
if ( signal & _K_VIEW_SIG_FLAG_HIDDEN )
gfxw_hide_widget ( widget ) ;
else
gfxw_show_widget ( widget ) ;
if ( ! ( flags & _K_DRAW_VIEW_LIST_USE_SIGNAL )
| | ( ( flags & _K_DRAW_VIEW_LIST_DISPOSEABLE ) & & ( signal & _K_VIEW_SIG_FLAG_DISPOSE_ME ) )
| | ( ( flags & _K_DRAW_VIEW_LIST_NONDISPOSEABLE ) & & ! ( signal & _K_VIEW_SIG_FLAG_DISPOSE_ME ) ) ) {
if ( flags & _K_DRAW_VIEW_LIST_USE_SIGNAL ) {
signal & = ~ ( _K_VIEW_SIG_FLAG_STOP_UPDATE | _K_VIEW_SIG_FLAG_UPDATED | _K_VIEW_SIG_FLAG_NO_UPDATE | _K_VIEW_SIG_FLAG_FORCE_UPDATE ) ;
// Clear all of those flags
if ( signal & _K_VIEW_SIG_FLAG_HIDDEN )
gfxw_hide_widget ( widget ) ;
else
gfxw_show_widget ( widget ) ;
2009-10-14 09:28:58 +00:00
* widget - > signalp . getPointer ( _s - > _segMan ) = make_reg ( 0 , signal ) ; // Write the changes back
2009-10-04 14:59:51 +00:00
} ;
} // ...if we're drawing disposeables and this one is disposeable, or if we're drawing non-
// disposeables and this one isn't disposeable
}
widget = ( GfxDynView * ) widget - > _next ;
} // while (widget)
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : _k_view_list_do_postdraw ( GfxList * list ) {
2009-10-14 09:28:58 +00:00
SegManager * segMan = _s - > _segMan ;
2009-10-04 14:59:51 +00:00
GfxDynView * widget = ( GfxDynView * ) list - > _contents ;
while ( widget ) {
reg_t obj = make_reg ( widget - > _ID , widget - > _subID ) ;
/*
* this fixes a few problems , but doesn ' t match SSCI ' s logic .
* The semantics of the private flag need to be verified before this can be uncommented .
* Fixes bug # 326 ( CB1 , ego falls down stairs )
* if ( ( widget - > signal & ( _K_VIEW_SIG_FLAG_PRIVATE | _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) = = _K_VIEW_SIG_FLAG_PRIVATE ) {
*/
if ( ( widget - > signal & ( _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) = = 0 ) {
2009-10-14 09:28:58 +00:00
int has_nsrect = lookup_selector ( _s - > _segMan , obj , _s - > _kernel - > _selectorCache . nsBottom , NULL , NULL ) = = kSelectorVariable ;
2009-10-04 14:59:51 +00:00
if ( has_nsrect ) {
int temp ;
temp = GET_SEL32V ( obj , nsLeft ) ;
PUT_SEL32V ( obj , lsLeft , temp ) ;
temp = GET_SEL32V ( obj , nsRight ) ;
PUT_SEL32V ( obj , lsRight , temp ) ;
temp = GET_SEL32V ( obj , nsTop ) ;
PUT_SEL32V ( obj , lsTop , temp ) ;
temp = GET_SEL32V ( obj , nsBottom ) ;
PUT_SEL32V ( obj , lsBottom , temp ) ;
# ifdef DEBUG_LSRECT
2009-10-14 09:28:58 +00:00
fprintf ( _stderr , " lsRected %04x:%04x \n " , PRINT_REG ( obj ) ) ;
2009-10-04 14:59:51 +00:00
# endif
}
# ifdef DEBUG_LSRECT
else
2009-10-14 09:28:58 +00:00
fprintf ( _stderr , " Not lsRecting %04x:%04x because %d \n " , PRINT_REG ( obj ) , lookup_selector ( _s - > _segMan , obj , _s - > _kernel - > _selectorCache . nsBottom , NULL , NULL ) ) ;
2009-10-04 14:59:51 +00:00
# endif
if ( widget - > signal & _K_VIEW_SIG_FLAG_HIDDEN )
widget - > signal | = _K_VIEW_SIG_FLAG_REMOVE ;
}
# ifdef DEBUG_LSRECT
2009-10-14 09:28:58 +00:00
fprintf ( _stderr , " obj %04x:%04x has pflags %x \n " , PRINT_REG ( obj ) , ( widget - > signal & ( _K_VIEW_SIG_FLAG_REMOVE | _K_VIEW_SIG_FLAG_NO_UPDATE ) ) ) ;
2009-10-04 14:59:51 +00:00
# endif
2009-10-14 09:28:58 +00:00
reg_t * sp = widget - > signalp . getPointer ( _s - > _segMan ) ;
2009-10-04 14:59:51 +00:00
if ( sp ) {
* sp = make_reg ( 0 , widget - > signal & 0xffff ) ; /* Write back signal */
}
widget = ( GfxDynView * ) widget - > _next ;
}
}
# define K_ANIMATE_CENTER_OPEN_H 0 // horizontally open from center
# define K_ANIMATE_CENTER_OPEN_V 1 // vertically open from center
# define K_ANIMATE_RIGHT_OPEN 2 // open from right
# define K_ANIMATE_LEFT_OPEN 3 // open from left
# define K_ANIMATE_BOTTOM_OPEN 4 // open from bottom
# define K_ANIMATE_TOP_OPEN 5 // open from top
# define K_ANIMATE_BORDER_OPEN_F 6 // open from edges to center
# define K_ANIMATE_CENTER_OPEN_F 7 // open from center to edges
# define K_ANIMATE_OPEN_CHECKERS 8 // open random checkboard
# define K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H 9 // horizontally close to center,reopen from center
# define K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V 10 // vertically close to center, reopen from center
# define K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN 11 // close to right, reopen from right
# define K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN 12 // close to left, reopen from left
# define K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN 13 // close to bottom, reopen from bottom
# define K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN 14 // close to top, reopen from top
# define K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F 15 // close from center to edges,
// reopen from edges to center
# define K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F 16 // close from edges to center, reopen from
// center to edges */
# define K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS 17 // close random checkboard, reopen
# define K_ANIMATE_PALETTE_FADEOUT_FADEIN 0x1e
# define K_ANIMATE_SCROLL_LEFT 0x28
# define K_ANIMATE_SCROLL_RIGHT 0x29
# define K_ANIMATE_SCROLL_DOWN 0x2a
# define K_ANIMATE_SCROLL_UP 0x2b
2009-10-14 09:28:58 +00:00
# define GRAPH_BLANK_BOX(_s, x, y, xl, yl, color) gfxop_fill_box(_s->gfx_state, \
gfx_rect ( x , ( ( ( y ) < 10 ) ? 10 : ( y ) ) , xl , ( ( ( y ) < 10 ) ? ( ( y ) - 10 ) : 0 ) + ( yl ) ) , _s - > ega_colors [ color ] ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
# define GRAPH_UPDATE_BOX(_s, x, y, xl, yl) gfxop_draw_pixmap(_s->gfx_state, newscreen, \
2009-10-04 14:59:51 +00:00
gfx_rect ( x , ( ( ( y ) < 10 ) ? 10 : ( y ) ) - 10 , xl , ( ( ( y ) < 10 ) ? ( ( y ) - 10 ) : 0 ) + ( yl ) ) , Common : : Point ( x , ( ( y ) < 10 ) ? 10 : ( y ) ) ) ;
2009-10-05 07:10:01 +00:00
void SciGui32 : : animate_do_animation ( int argc , reg_t * argv ) {
2009-10-04 14:59:51 +00:00
long animation_delay = 5 ;
int i , remaining_checkers ;
int update_counter ;
// Number of animation steps to perform betwen updates for transition animations
int animation_granularity = 4 ;
int granularity0 = animation_granularity < < 1 ;
int granularity1 = animation_granularity ;
int granularity2 = animation_granularity > > 2 ;
int granularity3 = animation_granularity > > 4 ;
char checkers [ 32 * 19 ] ;
2009-10-14 09:28:58 +00:00
gfx_pixmap_t * newscreen = gfxop_grab_pixmap ( _s - > gfx_state , gfx_rect ( 0 , 10 , 320 , 190 ) ) ;
2009-10-04 14:59:51 +00:00
if ( ! granularity2 )
granularity2 = 1 ;
if ( ! granularity3 )
granularity3 = 1 ;
2009-10-14 09:28:58 +00:00
gfxop_set_clip_zone ( _s - > gfx_state , gfx_rect_fullscreen ) ;
2009-10-04 14:59:51 +00:00
if ( ! newscreen ) {
error ( " Failed to allocate 'newscreen' " ) ;
return ;
}
2009-10-14 09:28:58 +00:00
gfxop_draw_pixmap ( _s - > gfx_state , _s - > old_screen , gfx_rect ( 0 , 0 , 320 , 190 ) , Common : : Point ( 0 , 10 ) ) ;
gfxop_update_box ( _s - > gfx_state , gfx_rect ( 0 , 0 , 320 , 200 ) ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
//debugC(2, kDebugLevelGraphics, "Animating pic opening type %x\n", _s->pic_animate);
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
gfxop_enable_dirty_frames ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
switch ( _s - > pic_animate ) {
2009-10-04 14:59:51 +00:00
case K_ANIMATE_BORDER_CLOSE_H_CENTER_OPEN_H :
for ( i = 0 ; i < 159 + granularity1 ; i + = granularity1 ) {
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , i , 10 , granularity1 , 190 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_BLANK_BOX ( _s , 319 - i , 10 , granularity1 , 190 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , 10 , 320 , 190 , 0 ) ;
2009-10-04 14:59:51 +00:00
case K_ANIMATE_CENTER_OPEN_H :
for ( i = 159 ; i > = 1 - granularity1 ; i - = granularity1 ) {
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , i , 10 , granularity1 , 190 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( _s , 319 - i , 10 , granularity1 , 190 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_BORDER_CLOSE_V_CENTER_OPEN_V :
for ( i = 0 ; i < 94 + granularity2 ; i + = granularity2 ) {
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , i + 10 , 320 , granularity2 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_BLANK_BOX ( _s , 0 , 199 - i , 320 , granularity2 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , 2 * animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , 10 , 320 , 190 , 0 ) ;
2009-10-04 14:59:51 +00:00
case K_ANIMATE_CENTER_OPEN_V :
for ( i = 94 ; i > = 1 - granularity2 ; i - = granularity2 ) {
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , i + 10 , 320 , granularity2 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( _s , 0 , 199 - i , 320 , granularity2 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , 2 * animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_LEFT_CLOSE_RIGHT_OPEN :
for ( i = 0 ; i < 319 + granularity0 ; i + = granularity0 ) {
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , i , 10 , granularity0 , 190 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 2 / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , 10 , 320 , 190 , 0 ) ;
2009-10-04 14:59:51 +00:00
case K_ANIMATE_RIGHT_OPEN :
for ( i = 319 ; i > = 1 - granularity0 ; i - = granularity0 ) {
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , i , 10 , granularity0 , 190 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 2 / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_RIGHT_CLOSE_LEFT_OPEN :
for ( i = 319 ; i > = 1 - granularity0 ; i - = granularity0 ) {
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , i , 10 , granularity0 , 190 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 2 / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , 10 , 320 , 190 , 0 ) ;
2009-10-04 14:59:51 +00:00
case K_ANIMATE_LEFT_OPEN :
for ( i = 0 ; i < 319 + granularity0 ; i + = granularity0 ) {
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , i , 10 , granularity0 , 190 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 2 / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_TOP_CLOSE_BOTTOM_OPEN :
for ( i = 10 ; i < 199 + granularity1 ; i + = granularity1 ) {
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , i , 320 , granularity1 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , 10 , 320 , 190 , 0 ) ;
2009-10-04 14:59:51 +00:00
case K_ANIMATE_BOTTOM_OPEN :
for ( i = 199 ; i > = 11 - granularity1 ; i - = granularity1 ) {
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , i , 320 , granularity1 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_BOTTOM_CLOSE_TOP_OPEN :
for ( i = 199 ; i > = 11 - granularity1 ; i - = granularity1 ) {
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , i , 320 , granularity1 , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , 0 , 10 , 320 , 190 , 0 ) ;
2009-10-04 14:59:51 +00:00
case K_ANIMATE_TOP_OPEN :
for ( i = 10 ; i < 199 + granularity1 ; i + = granularity1 ) {
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , i , 320 , granularity1 ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_CENTER_CLOSE_F_BORDER_OPEN_F :
for ( i = 31 ; i > = 1 - granularity3 ; i - = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
int height_l = 3 * ( granularity3 - real_i + i ) ;
int width_l = 5 * ( granularity3 - real_i + i ) ;
int height = real_i * 3 ;
int width = real_i * 5 ;
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_BLANK_BOX ( _s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , width , 10 + height , 320 - 2 * width , height_l , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_BLANK_BOX ( _s , width , 200 - height_l - height , 320 - 2 * width , height_l , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
gfxop_sleep ( _s - > gfx_state , 4 * animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
case K_ANIMATE_BORDER_OPEN_F :
for ( i = 0 ; i < 31 + granularity3 ; i + = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
int height_l = 3 * ( granularity3 - real_i + i ) ;
int width_l = 5 * ( granularity3 - real_i + i ) ;
int height = real_i * 3 ;
int width = real_i * 5 ;
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , width , 10 + height , width_l , 190 - 2 * height ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( _s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , width , 10 + height , 320 - 2 * width , height_l ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( _s , width , 200 - height_l - height , 320 - 2 * width , height_l ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
gfxop_sleep ( _s - > gfx_state , 4 * animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_BORDER_CLOSE_F_CENTER_OPEN_F :
for ( i = 0 ; i < 31 + granularity3 ; i + = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
int height_l = 3 * ( granularity3 - real_i + i ) ;
int width_l = 5 * ( granularity3 - real_i + i ) ;
int height = real_i * 3 ;
int width = real_i * 5 ;
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_BLANK_BOX ( _s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , width , 10 + height , 320 - 2 * width , height_l , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_BLANK_BOX ( _s , width , 200 - height_l - height , 320 - 2 * width , height_l , 0 ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
gfxop_sleep ( _s - > gfx_state , 7 * animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
case K_ANIMATE_CENTER_OPEN_F :
for ( i = 31 ; i > = 1 - granularity3 ; i - = granularity3 ) {
int real_i = ( i < 0 ) ? 0 : i ;
int height_l = 3 * ( granularity3 - real_i + i ) ;
int width_l = 5 * ( granularity3 - real_i + i ) ;
int height = real_i * 3 ;
int width = real_i * 5 ;
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , width , 10 + height , width_l , 190 - 2 * height ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( _s , 320 - width_l - width , 10 + height , width_l , 190 - 2 * height ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , width , 10 + height , 320 - 2 * width , height_l ) ;
gfxop_update ( _s - > gfx_state ) ;
GRAPH_UPDATE_BOX ( _s , width , 200 - height_l - height , 320 - 2 * width , height_l ) ;
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
gfxop_sleep ( _s - > gfx_state , 7 * animation_delay / 1000 ) ;
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_PALETTE_FADEOUT_FADEIN :
warning ( " TODO: Palette fadeout/fadein " ) ;
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , 10 , 320 , 190 ) ;
2009-10-04 14:59:51 +00:00
break ;
case K_ANIMATE_CLOSE_CHECKERS_OPEN_CHECKERS :
memset ( checkers , 0 , sizeof ( checkers ) ) ;
remaining_checkers = 19 * 32 ;
update_counter = granularity1 ;
while ( remaining_checkers ) {
int x , y , checker = 1 + ( int ) ( 1.0 * remaining_checkers * rand ( ) / ( RAND_MAX + 1.0 ) ) ;
i = - 1 ;
while ( checker )
if ( checkers [ + + i ] = = 0 )
- - checker ;
checkers [ i ] = 1 ; // Mark checker as used
x = i % 32 ;
y = i / 32 ;
2009-10-14 09:28:58 +00:00
GRAPH_BLANK_BOX ( _s , x * 10 , 10 + y * 10 , 10 , 10 , 0 ) ;
2009-10-04 14:59:51 +00:00
if ( ! ( update_counter - - ) | | ( remaining_checkers = = 1 ) ) {
2009-10-14 09:28:58 +00:00
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
update_counter = granularity1 ;
}
if ( remaining_checkers & 1 ) {
2009-10-14 09:28:58 +00:00
gfxop_sleep ( _s - > gfx_state , animation_delay / 4 / 1000 ) ;
2009-10-04 14:59:51 +00:00
}
- - remaining_checkers ;
2009-10-14 09:28:58 +00:00
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
case K_ANIMATE_OPEN_CHECKERS :
memset ( checkers , 0 , sizeof ( checkers ) ) ;
remaining_checkers = 19 * 32 ;
update_counter = granularity1 ;
while ( remaining_checkers ) {
int x , y , checker = 1 + ( int ) ( 1.0 * remaining_checkers * rand ( ) / ( RAND_MAX + 1.0 ) ) ;
i = - 1 ;
while ( checker )
if ( checkers [ + + i ] = = 0 ) - - checker ;
checkers [ i ] = 1 ; // Mark checker as used
x = i % 32 ;
y = i / 32 ;
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , x * 10 , 10 + y * 10 , 10 , 10 ) ;
2009-10-04 14:59:51 +00:00
if ( ! ( update_counter - - ) | | ( remaining_checkers = = 1 ) ) {
2009-10-14 09:28:58 +00:00
gfxop_update ( _s - > gfx_state ) ;
2009-10-04 14:59:51 +00:00
update_counter = granularity1 ;
}
if ( remaining_checkers & 1 ) {
2009-10-14 09:28:58 +00:00
gfxop_sleep ( _s - > gfx_state , animation_delay / 4 / 1000 ) ;
2009-10-04 14:59:51 +00:00
}
- - remaining_checkers ;
2009-10-14 09:28:58 +00:00
process_sound_events ( _s ) ;
2009-10-04 14:59:51 +00:00
}
break ;
case K_ANIMATE_SCROLL_LEFT :
for ( i = 0 ; i < 319 ; i + = granularity0 ) {
2009-10-14 09:28:58 +00:00
gfxop_draw_pixmap ( _s - > gfx_state , newscreen , gfx_rect ( 320 - i , 0 , i , 190 ) , Common : : Point ( 0 , 10 ) ) ;
gfxop_draw_pixmap ( _s - > gfx_state , _s - > old_screen , gfx_rect ( 0 , 0 , 320 - i , 190 ) , Common : : Point ( i , 10 ) ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , 10 , 320 , 190 ) ;
2009-10-04 14:59:51 +00:00
break ;
case K_ANIMATE_SCROLL_RIGHT :
for ( i = 0 ; i < 319 ; i + = granularity0 ) {
2009-10-14 09:28:58 +00:00
gfxop_draw_pixmap ( _s - > gfx_state , newscreen , gfx_rect ( 0 , 0 , i , 190 ) , Common : : Point ( 319 - i , 10 ) ) ;
gfxop_draw_pixmap ( _s - > gfx_state , _s - > old_screen , gfx_rect ( i , 0 , 320 - i , 190 ) , Common : : Point ( 0 , 10 ) ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , 10 , 320 , 190 ) ;
2009-10-04 14:59:51 +00:00
break ;
case K_ANIMATE_SCROLL_UP :
for ( i = 0 ; i < 189 ; i + = granularity0 ) {
2009-10-14 09:28:58 +00:00
gfxop_draw_pixmap ( _s - > gfx_state , newscreen , gfx_rect ( 0 , 190 - i , 320 , i ) , Common : : Point ( 0 , 10 ) ) ;
gfxop_draw_pixmap ( _s - > gfx_state , _s - > old_screen , gfx_rect ( 0 , 0 , 320 , 190 - i ) , Common : : Point ( 0 , 10 + i ) ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , 10 , 320 , 190 ) ;
2009-10-04 14:59:51 +00:00
break ;
case K_ANIMATE_SCROLL_DOWN :
for ( i = 0 ; i < 189 ; i + = granularity0 ) {
2009-10-14 09:28:58 +00:00
gfxop_draw_pixmap ( _s - > gfx_state , newscreen , gfx_rect ( 0 , 0 , 320 , i ) , Common : : Point ( 0 , 200 - i ) ) ;
gfxop_draw_pixmap ( _s - > gfx_state , _s - > old_screen , gfx_rect ( 0 , i , 320 , 190 - i ) , Common : : Point ( 0 , 10 ) ) ;
gfxop_update ( _s - > gfx_state ) ;
gfxop_sleep ( _s - > gfx_state , ( animation_delay > > 3 ) / 1000 ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
GRAPH_UPDATE_BOX ( _s , 0 , 10 , 320 , 190 ) ;
2009-10-04 14:59:51 +00:00
break ;
default :
2009-10-14 09:28:58 +00:00
warning ( " Unknown opening animation 0x%02x " , _s - > pic_animate ) ;
GRAPH_UPDATE_BOX ( _s , 0 , 10 , 320 , 190 ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-14 09:28:58 +00:00
gfxop_free_pixmap ( _s - > gfx_state , _s - > old_screen ) ;
gfxop_free_pixmap ( _s - > gfx_state , newscreen ) ;
_s - > old_screen = NULL ;
2009-10-04 14:59:51 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : animate ( reg_t listReference , bool cycle , int argc , reg_t * argv ) {
2009-10-04 14:59:51 +00:00
// Animations are supposed to take a maximum of animation_delay milliseconds.
List * cast_list = NULL ;
int open_animation = 0 ;
_k_animate_ran = true ; // Used by some of the invoked functions to check for recursion, which may,
// after all, damage the cast list
if ( listReference . segment ) {
2009-10-14 09:28:58 +00:00
cast_list = _s - > _segMan - > lookupList ( listReference ) ;
2009-10-04 14:59:51 +00:00
if ( ! cast_list )
return ;
}
2009-10-14 09:28:58 +00:00
open_animation = ( _s - > pic_is_new ) & & ( _s - > pic_not_valid ) ;
_s - > pic_is_new = 0 ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
assert_primary_widget_lists ( _s ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
if ( ! _s - > dyn_views - > _contents // Only reparentize empty dynview list
& & ( ( ( GfxContainer * ) _s - > port ! = ( GfxContainer * ) _s - > dyn_views - > _parent ) // If dynviews are on other port...
| | ( _s - > dyn_views - > _next ) ) ) // ... or not on top of the view list
reparentize_primary_widget_lists ( _s , _s - > port ) ;
2009-10-04 14:59:51 +00:00
if ( cast_list ) {
2009-10-14 09:28:58 +00:00
GfxList * templist = gfxw_new_list ( _s - > dyn_views - > _bounds , 0 ) ;
2009-10-04 14:59:51 +00:00
_k_make_view_list ( & ( templist ) , cast_list , ( cycle ? _K_MAKE_VIEW_LIST_CYCLE : 0 )
| _K_MAKE_VIEW_LIST_CALC_PRIORITY , argc , ( reg_t * ) argv ) ;
// Make sure that none of the doits() did something evil
2009-10-14 09:28:58 +00:00
assert_primary_widget_lists ( _s ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
if ( ! _s - > dyn_views - > _contents // Only reparentize empty dynview list
& & ( ( ( GfxContainer * ) _s - > port ! = ( GfxContainer * ) _s - > dyn_views - > _parent ) // If dynviews are on other port...
| | ( _s - > dyn_views - > _next ) ) ) // ... or not on top of the view list
reparentize_primary_widget_lists ( _s , _s - > port ) ;
2009-10-04 14:59:51 +00:00
// End of doit() recovery code
2009-10-14 09:28:58 +00:00
if ( _s - > pic_is_new ) { // Happens if DrawPic() is executed by a dynview (yes, that happens)
2009-10-04 14:59:51 +00:00
animate ( listReference , cycle , argc , argv ) ; /* Tail-recurse */
return ;
}
debugC ( 2 , kDebugLevelGraphics , " Handling Dynviews (..step 9 inclusive): \n " ) ;
_k_prepare_view_list ( templist , _K_MAKE_VIEW_LIST_CALC_PRIORITY ) ;
2009-10-14 09:28:58 +00:00
if ( _s - > pic_not_valid ) {
debugC ( 2 , kDebugLevelGraphics , " PicNotValid=%d -> Subalgorithm: \n " , _s - > pic_not_valid ) ;
2009-10-04 14:59:51 +00:00
_k_redraw_view_list ( templist ) ;
}
2009-10-14 09:28:58 +00:00
_k_update_signals_in_view_list ( _s - > dyn_views , templist ) ;
_s - > dyn_views - > tag ( ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
_k_raise_topmost_in_view_list ( _s - > dyn_views , ( GfxDynView * ) templist - > _contents ) ;
2009-10-04 14:59:51 +00:00
delete templist ;
2009-10-14 09:28:58 +00:00
_s - > dyn_views - > free_tagged ( ( GfxContainer * ) _s - > dyn_views ) ; // Free obsolete dynviews
2009-10-04 14:59:51 +00:00
} // if (cast_list)
if ( open_animation ) {
2009-10-14 09:28:58 +00:00
gfxop_clear_box ( _s - > gfx_state , gfx_rect ( 0 , 10 , 320 , 190 ) ) ; // Propagate pic
_s - > visual - > add_dirty_abs ( ( GfxContainer * ) _s - > visual , gfx_rect_fullscreen , 0 ) ;
2009-10-04 14:59:51 +00:00
// Mark screen as dirty so picviews will be drawn correctly
FULL_REDRAW ( ) ;
animate_do_animation ( argc , ( reg_t * ) argv ) ;
} // if (open_animation)
if ( cast_list ) {
int retval ;
int reparentize = 0 ;
2009-10-14 09:28:58 +00:00
_s - > pic_not_valid = 0 ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
_k_view_list_do_postdraw ( _s - > dyn_views ) ;
2009-10-04 14:59:51 +00:00
// _k_view_list_dispose_loop() returns -1 if it requested a re-start, so we do just that.
2009-10-14 09:28:58 +00:00
while ( ( retval = _k_view_list_dispose_loop ( cast_list , ( GfxDynView * ) _s - > dyn_views - > _contents , argc , ( reg_t * ) argv ) < 0 ) )
2009-10-04 14:59:51 +00:00
reparentize = 1 ;
2009-10-14 09:28:58 +00:00
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 ) ;
2009-10-04 14:59:51 +00:00
} else {
2009-10-14 09:28:58 +00:00
assert ( _s - > drop_views ) ;
gfxw_remove_widget_from_container ( _s - > drop_views - > _parent , _s - > drop_views ) ;
ADD_TO_CURRENT_PICTURE_PORT ( _s - > drop_views ) ;
2009-10-04 14:59:51 +00:00
}
if ( ( reparentize | retval )
2009-10-14 09:28:58 +00:00
& & ( ( GfxContainer * ) _s - > port = = ( GfxContainer * ) _s - > dyn_views - > _parent ) // If dynviews are on the same port...
& & ( _s - > dyn_views - > _next ) ) // ... and not on top of the view list...
reparentize_primary_widget_lists ( _s , _s - > port ) ; // ...then reparentize.
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
_k_view_list_kryptonize ( _s - > dyn_views - > _contents ) ;
2009-10-04 14:59:51 +00:00
}
FULL_REDRAW ( ) ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : addToPicList ( reg_t listReference , int argc , reg_t * argv ) {
2009-10-04 14:59:51 +00:00
List * list ;
GfxList * pic_views ;
2009-10-14 09:28:58 +00:00
assert_primary_widget_lists ( _s ) ;
2009-10-04 14:59:51 +00:00
if ( ! listReference . segment ) {
warning ( " Attempt to AddToPic single non-list: %04x:%04x " , PRINT_REG ( listReference ) ) ;
return ;
}
2009-10-14 09:28:58 +00:00
list = _s - > _segMan - > lookupList ( listReference ) ;
2009-10-04 14:59:51 +00:00
2009-10-14 09:28:58 +00:00
pic_views = gfxw_new_list ( _s - > picture_port - > _bounds , 1 ) ;
2009-10-04 14:59:51 +00:00
debugC ( 2 , kDebugLevelGraphics , " Preparing picview list... \n " ) ;
_k_make_view_list ( & pic_views , list , 0 , argc , argv ) ;
_k_prepare_view_list ( pic_views , _K_MAKE_VIEW_LIST_DRAW_TO_CONTROL_MAP ) ;
// Store pic views for later re-use
debugC ( 2 , kDebugLevelGraphics , " Drawing picview list... \n " ) ;
ADD_TO_CURRENT_PICTURE_PORT ( pic_views ) ;
_k_draw_view_list ( pic_views , _K_DRAW_VIEW_LIST_NONDISPOSEABLE | _K_DRAW_VIEW_LIST_DISPOSEABLE | _K_DRAW_VIEW_LIST_PICVIEW ) ;
// Draw relative to the bottom center
debugC ( 2 , kDebugLevelGraphics , " Returning. \n " ) ;
2009-10-14 09:28:58 +00:00
reparentize_primary_widget_lists ( _s , _s - > port ) ;
2009-10-04 14:59:51 +00:00
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : addToPicView ( GuiResourceId viewId , GuiViewLoopNo loopNo , GuiViewCelNo celNo , int16 leftPos , int16 topPos , int16 priority , int16 control ) {
2009-10-14 09:28:58 +00:00
assert_primary_widget_lists ( _s ) ;
2009-10-04 14:59:51 +00:00
GfxWidget * widget ;
topPos + + ; // magic +1
2009-10-14 09:28:58 +00:00
widget = gfxw_new_dyn_view ( _s - > gfx_state , Common : : Point ( leftPos , topPos ) , 0 , viewId , loopNo , celNo , 0 , priority , - 1 /* No priority */ , ALIGN_CENTER , ALIGN_BOTTOM , 0 ) ;
2009-10-04 14:59:51 +00:00
if ( ! widget ) {
2009-10-05 07:10:01 +00:00
error ( " Attempt to single-add invalid picview (%d/%d/%d) " , viewId , loopNo , celNo ) ;
2009-10-04 14:59:51 +00:00
} else {
widget - > _ID = - 1 ;
if ( control > = 0 ) {
2009-10-14 09:28:58 +00:00
Common : : Rect abs_zone = nsrect_clip ( _s , topPos , calculate_nsrect ( _s , leftPos , topPos , viewId , loopNo , celNo ) , priority ) ;
2009-10-04 14:59:51 +00:00
draw_rect_to_control_map ( abs_zone ) ;
}
ADD_TO_CURRENT_PICTURE_PORT ( gfxw_picviewize_dynview ( ( GfxDynView * ) widget ) ) ;
}
return ;
}
2009-10-05 07:10:01 +00:00
void SciGui32 : : setNowSeen ( reg_t objectReference ) {
2009-10-04 14:59:51 +00:00
_k_set_now_seen ( objectReference ) ;
}
2009-10-09 16:51:10 +00:00
static int collides_with ( EngineState * s , Common : : Rect area , reg_t other_obj , int use_nsrect , int view_mask ) {
SegManager * segMan = s - > _segMan ;
int other_signal = GET_SEL32V ( other_obj , signal ) ;
int other_priority = GET_SEL32V ( other_obj , priority ) ;
int y = ( int16 ) GET_SEL32V ( other_obj , y ) ;
Common : : Rect 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 . left = GET_SEL32V ( other_obj , brLeft ) ;
other_area . right = GET_SEL32V ( other_obj , brRight ) ;
other_area . top = GET_SEL32V ( other_obj , brTop ) ;
other_area . bottom = GET_SEL32V ( other_obj , brBottom ) ;
}
if ( other_area . right < 0 | | other_area . bottom < 0 | | area . right < 0 | | area . bottom < 0 )
return 0 ; // Out of scope
if ( other_area . left > = 320 | | other_area . top > = 190 | | area . right > = 320 | | area . bottom > = 190 )
return 0 ; // Out of scope
debugC ( 2 , kDebugLevelBresen , " OtherSignal=%04x, z=%04x obj=%04x:%04x \n " , other_signal , ( other_signal & view_mask ) , PRINT_REG ( other_obj ) ) ;
if ( ( other_signal & ( view_mask ) ) = = 0 ) {
// check whether the other object ignores actors
debugC ( 2 , kDebugLevelBresen , " against (%d,%d) to (%d,%d) \n " , other_area . left , other_area . top , other_area . right , other_area . bottom ) ;
if ( area . intersects ( other_area ) )
return 1 ;
/* CR (from :Bob Heitman:) Collision rects have Mac semantics, ((0,0),(1,1)) only
* * covers the coordinate ( 0 , 0 ) */
}
debugC ( 2 , kDebugLevelBresen , " (no) \n " ) ;
return 0 ;
}
# 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)
bool SciGui32 : : canBeHere ( reg_t curObject , reg_t listReference ) {
2009-10-14 09:28:58 +00:00
SegManager * segMan = _s - > _segMan ;
2009-10-09 16:51:10 +00:00
List * cliplist = NULL ;
2009-10-14 09:28:58 +00:00
GfxPort * port = _s - > picture_port ;
2009-10-09 16:51:10 +00:00
uint16 signal ;
bool retval ;
Common : : Rect abs_zone ;
rect_t zone ;
uint16 edgehit ;
uint16 illegal_bits ;
abs_zone . left = ( int16 ) GET_SEL32V ( curObject , brLeft ) ;
abs_zone . right = ( int16 ) GET_SEL32V ( curObject , brRight ) ;
abs_zone . top = ( int16 ) GET_SEL32V ( curObject , brTop ) ;
abs_zone . bottom = ( int16 ) GET_SEL32V ( curObject , brBottom ) ;
zone = gfx_rect ( abs_zone . left + port - > zone . x , abs_zone . top + port - > zone . y , abs_zone . width ( ) , abs_zone . height ( ) ) ;
signal = GET_SEL32V ( curObject , signal ) ;
debugC ( 2 , kDebugLevelBresen , " Checking collision: (%d,%d) to (%d,%d) ([%d..%d]x[%d..%d]), obj=%04x:%04x, sig=%04x, cliplist=%04x:%04x \n " ,
GFX_PRINT_RECT ( zone ) , abs_zone . left , abs_zone . right , abs_zone . top , abs_zone . bottom ,
PRINT_REG ( curObject ) , signal , PRINT_REG ( listReference ) ) ;
illegal_bits = GET_SEL32V ( curObject , illegalBits ) ;
2009-10-14 09:28:58 +00:00
retval = ! ( illegal_bits & ( edgehit = gfxop_scan_bitmask ( _s - > gfx_state , zone , GFX_MASK_CONTROL ) ) ) ;
2009-10-09 16:51:10 +00:00
debugC ( 2 , kDebugLevelBresen , " edgehit = %04x (illegalBits %04x) \n " , edgehit , illegal_bits ) ;
if ( ! retval ) {
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
return false ; // Can't BeHere
}
retval = false ;
if ( ( illegal_bits & 0x8000 ) // If we are vulnerable to those views at all...
2009-10-14 09:28:58 +00:00
& & _s - > dyn_views ) { // ...check against all stop-updated dynviews
GfxDynView * widget = ( GfxDynView * ) _s - > dyn_views - > _contents ;
2009-10-09 16:51:10 +00:00
debugC ( 2 , kDebugLevelBresen , " Checking vs dynviews: \n " ) ;
while ( widget ) {
if ( widget - > _ID & & ( widget - > signal & _K_VIEW_SIG_FLAG_STOPUPD )
& & ( ( widget - > _ID ! = curObject . segment ) | | ( widget - > _subID ! = curObject . offset ) )
2009-10-14 09:28:58 +00:00
& & _s - > _segMan - > isObject ( make_reg ( widget - > _ID , widget - > _subID ) ) )
if ( collides_with ( _s , abs_zone , make_reg ( widget - > _ID , widget - > _subID ) , 1 , GASEOUS_VIEW_MASK_ACTIVE ) )
2009-10-09 16:51:10 +00:00
return false ;
widget = ( GfxDynView * ) widget - > _next ;
}
}
if ( signal & GASEOUS_VIEW_MASK_ACTIVE ) {
retval = ( signal & GASEOUS_VIEW_MASK_ACTIVE ) ? true : false ; // CanBeHere- it's either being disposed, or it ignores actors anyway
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
return retval ; // CanBeHere
}
if ( listReference . segment )
2009-10-14 09:28:58 +00:00
cliplist = _s - > _segMan - > lookupList ( listReference ) ;
2009-10-09 16:51:10 +00:00
if ( cliplist ) {
2009-10-14 09:28:58 +00:00
Node * node = _s - > _segMan - > lookupNode ( cliplist - > first ) ;
2009-10-09 16:51:10 +00:00
retval = false ; // Assume that we Can'tBeHere...
while ( node ) { // Check each object in the list against our bounding rectangle
reg_t other_obj = node - > value ;
debugC ( 2 , kDebugLevelBresen , " comparing against %04x:%04x \n " , PRINT_REG ( other_obj ) ) ;
2009-10-14 09:28:58 +00:00
if ( ! _s - > _segMan - > isObject ( other_obj ) ) {
2009-10-09 16:51:10 +00:00
warning ( " CanBeHere() cliplist contains non-object %04x:%04x " , PRINT_REG ( other_obj ) ) ;
} else if ( other_obj ! = curObject ) { // Clipping against yourself is not recommended
2009-10-14 09:28:58 +00:00
if ( collides_with ( _s , abs_zone , other_obj , 0 , GASEOUS_VIEW_MASK_PASSIVE ) ) {
2009-10-09 16:51:10 +00:00
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
return false ;
}
} // if (other_obj != obj)
2009-10-14 09:28:58 +00:00
node = _s - > _segMan - > lookupNode ( node - > succ ) ; // move on
2009-10-09 16:51:10 +00:00
}
}
if ( ! retval )
retval = true ;
debugC ( 2 , kDebugLevelBresen , " -> %04x \n " , retval ) ;
return retval ;
}
2009-10-07 21:29:47 +00:00
void SciGui32 : : hideCursor ( ) {
2009-10-13 16:22:07 +00:00
_cursor - > hide ( ) ;
2009-10-07 14:53:15 +00:00
}
2009-10-07 21:29:47 +00:00
void SciGui32 : : showCursor ( ) {
2009-10-13 16:22:07 +00:00
_cursor - > show ( ) ;
2009-10-07 14:53:15 +00:00
}
void SciGui32 : : setCursorShape ( GuiResourceId cursorId ) {
2009-10-13 16:22:07 +00:00
_cursor - > setShape ( cursorId ) ;
2009-10-07 14:53:15 +00:00
}
2009-10-13 17:09:32 +00:00
void SciGui32 : : setCursorView ( GuiResourceId viewNum , int loopNum , int cellNum , Common : : Point * hotspot ) {
_cursor - > setView ( viewNum , loopNum , cellNum , hotspot ) ;
}
2009-10-07 12:47:53 +00:00
void SciGui32 : : setCursorPos ( Common : : Point pos ) {
2009-10-14 09:28:58 +00:00
pos . y + = _s - > port - > _bounds . y ;
pos . x + = _s - > port - > _bounds . x ;
2009-10-07 12:47:53 +00:00
moveCursor ( pos ) ;
}
2009-10-04 14:59:51 +00:00
2009-10-07 12:47:53 +00:00
void SciGui32 : : moveCursor ( Common : : Point pos ) {
2009-10-14 09:28:58 +00:00
pos . y + = _s - > port - > zone . y ;
pos . x + = _s - > port - > zone . x ;
2009-10-03 20:49:18 +00:00
2009-10-14 09:28:58 +00:00
if ( pos . x > _s - > port - > zone . x + _s - > port - > zone . width )
pos . x = _s - > port - > zone . x + _s - > port - > zone . width ;
if ( pos . y > _s - > port - > zone . y + _s - > port - > zone . height )
pos . y = _s - > port - > zone . y + _s - > port - > zone . height ;
2009-10-03 20:49:18 +00:00
2009-10-07 12:47:53 +00:00
if ( pos . x < 0 ) pos . x = 0 ;
if ( pos . y < 0 ) pos . y = 0 ;
2009-10-05 16:43:24 +00:00
2009-10-07 12:47:53 +00:00
if ( pos . x > 320 | | pos . y > 200 ) {
debug ( " [GFX] Attempt to place pointer at invalid coordinates (%d, %d) \n " , pos . x , pos . y ) ;
2009-10-05 16:43:24 +00:00
return ; // Not fatal
}
2009-10-07 12:47:53 +00:00
g_system - > warpMouse ( pos . x , pos . y ) ;
2009-10-05 16:43:24 +00:00
// Trigger event reading to make sure the mouse coordinates will
// actually have changed the next time we read them.
2009-10-14 09:28:58 +00:00
gfxop_get_event ( _s - > gfx_state , SCI_EVT_PEEK ) ;
2009-10-03 20:49:18 +00:00
}
2009-10-07 21:47:34 +00:00
bool SciGui32 : : debugUndither ( bool flag ) {
return true ;
}
2009-10-07 15:53:34 +00:00
bool SciGui32 : : debugShowMap ( int mapNo ) {
2009-10-14 09:28:58 +00:00
gfxop_set_clip_zone ( _s - > gfx_state , gfx_rect_fullscreen ) ;
2009-10-07 15:53:34 +00:00
switch ( mapNo ) {
case 0 :
2009-10-14 09:28:58 +00:00
_s - > visual - > add_dirty_abs ( ( GfxContainer * ) _s - > visual , gfx_rect ( 0 , 0 , 320 , 200 ) , 0 ) ;
_s - > visual - > draw ( Common : : Point ( 0 , 0 ) ) ;
2009-10-07 15:53:34 +00:00
break ;
case 1 :
2009-10-14 09:28:58 +00:00
gfx_xlate_pixmap ( _s - > gfx_state - > pic - > priority_map , _s - > gfx_state - > driver - > getMode ( ) ) ;
gfxop_draw_pixmap ( _s - > gfx_state , _s - > gfx_state - > pic - > priority_map , gfx_rect ( 0 , 0 , 320 , 200 ) , Common : : Point ( 0 , 0 ) ) ;
2009-10-07 15:53:34 +00:00
break ;
case 2 :
2009-10-14 09:28:58 +00:00
gfx_xlate_pixmap ( _s - > gfx_state - > control_map , _s - > gfx_state - > driver - > getMode ( ) ) ;
gfxop_draw_pixmap ( _s - > gfx_state , _s - > gfx_state - > control_map , gfx_rect ( 0 , 0 , 320 , 200 ) , Common : : Point ( 0 , 0 ) ) ;
2009-10-07 15:53:34 +00:00
break ;
}
2009-10-14 09:28:58 +00:00
gfxop_update ( _s - > gfx_state ) ;
2009-10-07 15:53:34 +00:00
return false ;
}
2009-10-03 20:49:18 +00:00
} // End of namespace Sci