2009-09-03 20:59:17 +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 .
*
2009-09-03 21:20:13 +00:00
* $ URL $
* $ Id $
2009-09-03 20:59:17 +00:00
*/
2009-09-04 20:08:33 +00:00
# include "teenagent/scene.h"
# include "teenagent/resources.h"
# include "teenagent/surface.h"
2009-09-03 20:59:17 +00:00
# include "common/debug.h"
2009-09-04 20:08:33 +00:00
# include "teenagent/objects.h"
# include "teenagent/teenagent.h"
# include "teenagent/dialog.h"
# include "teenagent/music.h"
2009-09-03 20:59:17 +00:00
2009-09-04 20:08:33 +00:00
namespace TeenAgent {
2009-09-03 20:59:17 +00:00
2009-09-15 08:54:06 +00:00
Scene : : Scene ( ) : intro ( false ) , _engine ( NULL ) ,
_system ( NULL ) ,
2009-09-26 15:04:09 +00:00
_id ( 0 ) , ons ( 0 ) ,
2009-11-15 10:54:29 +00:00
orientation ( Object : : kActorRight ) , actor_talking ( false ) ,
2009-11-08 23:32:01 +00:00
message_timer ( 0 ) , message_first_frame ( 0 ) , message_last_frame ( 0 ) , message_animation ( NULL ) ,
2009-11-08 22:37:03 +00:00
current_event ( SceneEvent : : kNone ) , hide_actor ( false ) , callback ( 0 ) , callback_timer ( 0 ) { }
2009-09-03 20:59:17 +00:00
2009-09-15 08:54:06 +00:00
void Scene : : warp ( const Common : : Point & _point , byte o ) {
2009-09-03 20:59:17 +00:00
Common : : Point point ( _point ) ;
2009-11-14 11:32:58 +00:00
position = point ;
path . clear ( ) ;
2009-09-03 20:59:17 +00:00
if ( o )
orientation = o ;
}
2009-11-14 11:32:58 +00:00
struct Splitter {
typedef Common : : List < int > ListType ;
ListType values ;
uint _size ;
Splitter ( ) : values ( ) , _size ( 0 ) { }
void insert ( int v ) {
ListType : : iterator i ;
for ( i = values . begin ( ) ; i ! = values . end ( ) ; + + i ) {
if ( v = = * i )
return ;
if ( v < * i )
break ;
}
values . insert ( i , v ) ;
+ + _size ;
}
uint size ( ) const { return _size ; }
} ;
struct Node {
Rect rect ;
int step ;
int prev ;
Node ( ) : step ( 0 ) , prev ( 0 ) { }
} ;
static void search ( Node * nodes , int n , int m , int i , int j , int prev_idx , int end , int level ) {
if ( i < 0 | | i > = n | | j < 0 | | j > = m )
return ;
int idx = j + i * m ;
int v = nodes [ idx ] . step ;
//debug(1, "search (%d, %d) %d, value = %d", i, j, level, v);
if ( v ! = 0 & & ( v = = - 1 | | v < = level ) )
return ;
2009-11-17 07:55:24 +00:00
2009-11-14 11:32:58 +00:00
nodes [ idx ] . step = level ; //mark as visited
nodes [ idx ] . prev = prev_idx ;
+ + level ;
search ( nodes , n , m , i - 1 , j , idx , end , level ) ;
search ( nodes , n , m , i + 1 , j , idx , end , level ) ;
search ( nodes , n , m , i , j - 1 , idx , end , level ) ;
search ( nodes , n , m , i , j + 1 , idx , end , level ) ;
}
bool Scene : : findPath ( Scene : : Path & p , const Common : : Point & src , const Common : : Point & dst ) const {
const Common : : Array < Walkbox > & scene_walkboxes = walkboxes [ _id - 1 ] ;
if ( dst . x < 0 | | dst . x > 319 | | dst . y < 0 | | dst . y > 199 )
return false ;
debug ( 1 , " findPath %d,%d -> %d,%d " , src . x , src . y , dst . x , dst . y ) ;
Splitter hsplit , vsplit ;
for ( byte i = 0 ; i < scene_walkboxes . size ( ) ; + + i ) {
const Walkbox & w = scene_walkboxes [ i ] ;
if ( w . rect . valid ( ) ) {
hsplit . insert ( w . rect . left ) ;
hsplit . insert ( w . rect . right ) ;
vsplit . insert ( w . rect . top ) ;
vsplit . insert ( w . rect . bottom ) ;
}
}
int n = ( int ) vsplit . size ( ) - 1 , m = ( int ) hsplit . size ( ) - 1 ;
debug ( 1 , " split: %ux%u " , n , m ) ;
if ( n < = 0 | | m < = 0 ) {
p . push_back ( Common : : Point ( src . x , dst . y ) ) ;
p . push_back ( dst ) ;
return true ;
}
Node * nodes = new Node [ n * m ] ;
int start = - 1 , end = - 1 ;
{
int idx = 0 ;
for ( Splitter : : ListType : : const_iterator i = vsplit . values . begin ( ) ; i ! = vsplit . values . end ( ) ; + + i ) {
Splitter : : ListType : : const_iterator in = i ; + + in ;
if ( in = = vsplit . values . end ( ) )
break ;
for ( Splitter : : ListType : : const_iterator j = hsplit . values . begin ( ) ; j ! = hsplit . values . end ( ) ; + + j ) {
Splitter : : ListType : : const_iterator jn = j ; + + jn ;
if ( jn = = hsplit . values . end ( ) )
break ;
Rect & r = nodes [ idx ] . rect ;
r = Rect ( * j , * i , * jn , * in ) ;
if ( r . in ( src ) )
start = idx ;
if ( r . in ( dst ) )
end = idx ;
byte k = 0 ;
for ( k = 0 ; k < scene_walkboxes . size ( ) ; + + k ) {
const Walkbox & w = scene_walkboxes [ k ] ;
if ( w . rect . contains ( r ) )
break ;
}
2009-11-17 07:55:24 +00:00
nodes [ idx ] . step = k > = scene_walkboxes . size ( ) ? 0 : - 1 ;
nodes [ idx ] . prev = - 1 ;
+ + idx ;
2009-11-14 11:32:58 +00:00
}
}
}
debug ( 1 , " %d -> %d " , start , end ) ;
if ( start = = - 1 | | end = = - 1 )
return false ;
2009-11-17 07:55:24 +00:00
2009-11-14 11:32:58 +00:00
search ( nodes , n , m , start / m , start % m , - 1 , end , 1 ) ;
int v = end ;
2009-11-14 11:45:15 +00:00
Common : : Point prev ( dst ) ;
2009-11-14 11:32:58 +00:00
do {
debug ( 1 , " backtrace %d " , v ) ;
2009-11-14 11:45:15 +00:00
Common : : Point c = nodes [ v ] . rect . closest_to ( prev ) ;
prev = c ;
2009-11-14 11:32:58 +00:00
p . push_front ( c ) ;
if ( v = = start )
break ;
v = nodes [ v ] . prev ;
} while ( v > = 0 ) ;
debug ( 1 , " end vertex = %d " , v ) ;
#if 0
{
int idx = 0 ;
for ( int i = 0 ; i < n ; + + i ) {
Common : : String line ;
for ( int j = 0 ; j < m ; + + j ) {
line + = Common : : String : : printf ( " %2d.%2d " , nodes [ idx ] . step , nodes [ idx ] . prev ) ;
+ + idx ;
}
debug ( 1 , " map: %s " , line . c_str ( ) ) ;
}
}
# endif
2009-11-17 07:55:24 +00:00
if ( v ! = start )
return false ;
2009-11-14 11:32:58 +00:00
delete [ ] nodes ;
return true ;
}
2009-09-15 08:54:06 +00:00
void Scene : : moveTo ( const Common : : Point & _point , byte orient , bool validate ) {
2009-09-03 20:59:17 +00:00
Common : : Point point ( _point ) ;
debug ( 0 , " moveTo(%d, %d, %u) " , point . x , point . y , orient ) ;
2009-11-14 11:32:58 +00:00
const Common : : Array < Walkbox > & scene_walkboxes = walkboxes [ _id - 1 ] ;
2009-09-03 20:59:17 +00:00
if ( validate ) {
2009-09-26 15:04:09 +00:00
for ( byte i = 0 ; i < scene_walkboxes . size ( ) ; + + i ) {
const Walkbox & w = scene_walkboxes [ i ] ;
if ( w . rect . in ( point ) ) {
2009-09-03 20:59:17 +00:00
debug ( 0 , " bumped into walkbox %u " , i ) ;
2009-11-07 09:19:49 +00:00
w . dump ( ) ;
2009-09-26 15:04:09 +00:00
byte o = w . orientation ;
2009-09-15 08:54:06 +00:00
switch ( o ) {
2009-09-08 19:24:20 +00:00
case 1 :
2009-09-26 15:04:09 +00:00
point . y = w . rect . top - 1 ;
2009-09-08 19:24:20 +00:00
break ;
2009-09-15 08:54:06 +00:00
case 2 :
2009-09-26 15:04:09 +00:00
point . x = w . rect . right + 1 ;
2009-09-08 19:24:20 +00:00
break ;
case 3 :
2009-09-26 15:04:09 +00:00
point . y = w . rect . bottom + 1 ;
2009-09-08 19:24:20 +00:00
break ;
case 4 :
2009-09-26 15:04:09 +00:00
point . x = w . rect . left - 1 ;
2009-09-08 19:24:20 +00:00
break ;
default :
return ;
}
2009-09-03 20:59:17 +00:00
}
}
}
if ( point = = position ) {
if ( orient ! = 0 )
orientation = orient ;
nextEvent ( ) ;
return ;
}
2009-11-14 11:32:58 +00:00
path . clear ( ) ;
if ( scene_walkboxes . empty ( ) ) {
path . push_back ( point ) ;
return ;
}
if ( ! findPath ( path , position , point ) ) {
_engine - > cancel ( ) ;
return ;
}
2009-09-03 20:59:17 +00:00
orientation = orient ;
}
2009-09-15 07:41:05 +00:00
void Scene : : init ( TeenAgentEngine * engine , OSystem * system ) {
2009-09-03 20:59:17 +00:00
_engine = engine ;
_system = system ;
2009-09-15 08:54:06 +00:00
2009-09-15 07:41:05 +00:00
Resources * res = Resources : : instance ( ) ;
Common : : SeekableReadStream * s = res - > varia . getStream ( 1 ) ;
2009-09-03 20:59:17 +00:00
if ( s = = NULL )
error ( " invalid resource data " ) ;
2009-09-15 20:21:18 +00:00
teenagent . load ( s , Animation : : kTypeVaria ) ;
2009-09-09 20:42:44 +00:00
if ( teenagent . empty ( ) )
error ( " invalid mark animation " ) ;
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
s = res - > varia . getStream ( 2 ) ;
if ( s = = NULL )
error ( " invalid resource data " ) ;
2009-09-15 08:54:06 +00:00
2009-09-15 20:21:18 +00:00
teenagent_idle . load ( s , Animation : : kTypeVaria ) ;
2009-09-09 20:42:44 +00:00
if ( teenagent_idle . empty ( ) )
error ( " invalid mark animation " ) ;
2009-11-08 19:11:57 +00:00
loadObjectData ( ) ;
}
void Scene : : loadObjectData ( ) {
Resources * res = Resources : : instance ( ) ;
2009-09-26 15:04:09 +00:00
//loading objects & walkboxes
objects . resize ( 42 ) ;
walkboxes . resize ( 42 ) ;
2009-09-30 16:16:53 +00:00
for ( byte i = 0 ; i < 42 ; + + i ) {
2009-09-26 15:04:09 +00:00
Common : : Array < Object > & scene_objects = objects [ i ] ;
scene_objects . clear ( ) ;
uint16 scene_table = res - > dseg . get_word ( 0x7254 + i * 2 ) ;
uint16 object_addr ;
while ( ( object_addr = res - > dseg . get_word ( scene_table ) ) ! = 0 ) {
Object obj ;
obj . load ( res - > dseg . ptr ( object_addr ) ) ;
//obj.dump();
scene_objects . push_back ( obj ) ;
scene_table + = 2 ;
}
debug ( 0 , " scene[%u] has %u object(s) " , i + 1 , scene_objects . size ( ) ) ;
byte * walkboxes_base = res - > dseg . ptr ( READ_LE_UINT16 ( res - > dseg . ptr ( 0x6746 + i * 2 ) ) ) ;
byte walkboxes_n = * walkboxes_base + + ;
debug ( 0 , " scene[%u] has %u walkboxes " , i + 1 , walkboxes_n ) ;
Common : : Array < Walkbox > & scene_walkboxes = walkboxes [ i ] ;
for ( byte j = 0 ; j < walkboxes_n ; + + j ) {
Walkbox w ;
w . load ( walkboxes_base + 14 * j ) ;
//walkbox[i]->dump();
scene_walkboxes . push_back ( w ) ;
}
}
}
Object * Scene : : findObject ( const Common : : Point & point ) {
if ( _id = = 0 )
return NULL ;
Common : : Array < Object > & scene_objects = objects [ _id - 1 ] ;
2009-09-30 16:16:53 +00:00
for ( uint i = 0 ; i < scene_objects . size ( ) ; + + i ) {
2009-09-26 15:04:09 +00:00
Object & obj = scene_objects [ i ] ;
if ( obj . enabled ! = 0 & & obj . rect . in ( point ) )
return & obj ;
}
return NULL ;
2009-09-03 20:59:17 +00:00
}
2009-09-26 15:04:09 +00:00
2009-09-03 20:59:17 +00:00
byte * Scene : : getOns ( int id ) {
2009-09-15 07:41:05 +00:00
Resources * res = Resources : : instance ( ) ;
2009-09-03 20:59:17 +00:00
return res - > dseg . ptr ( res - > dseg . get_word ( 0xb4f5 + ( id - 1 ) * 2 ) ) ;
}
2009-09-15 07:41:05 +00:00
byte * Scene : : getLans ( int id ) {
Resources * res = Resources : : instance ( ) ;
2009-09-03 20:59:17 +00:00
return res - > dseg . ptr ( 0xd89e + ( id - 1 ) * 4 ) ;
}
void Scene : : loadOns ( ) {
debug ( 0 , " loading ons animation " ) ;
2009-09-15 07:41:05 +00:00
Resources * res = Resources : : instance ( ) ;
2009-09-03 20:59:17 +00:00
uint16 addr = res - > dseg . get_word ( 0xb4f5 + ( _id - 1 ) * 2 ) ;
//debug(0, "ons index: %04x", addr);
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
ons_count = 0 ;
byte b ;
byte on_id [ 16 ] ;
2009-09-04 20:09:29 +00:00
while ( ( b = res - > dseg . get_byte ( addr ) ) ! = 0xff ) {
2009-09-03 20:59:17 +00:00
debug ( 0 , " on: %04x = %02x " , addr , b ) ;
+ + addr ;
if ( b = = 0 )
continue ;
on_id [ ons_count + + ] = b ;
}
delete [ ] ons ;
ons = NULL ;
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
if ( ons_count > 0 ) {
ons = new Surface [ ons_count ] ;
2009-09-04 20:09:29 +00:00
for ( uint32 i = 0 ; i < ons_count ; + + i ) {
2009-09-15 07:41:05 +00:00
Common : : SeekableReadStream * s = res - > ons . getStream ( on_id [ i ] ) ;
2009-09-03 20:59:17 +00:00
if ( s ! = NULL )
2009-09-15 20:21:18 +00:00
ons [ i ] . load ( s , Surface : : kTypeOns ) ;
2009-09-03 20:59:17 +00:00
}
}
}
void Scene : : loadLans ( ) {
debug ( 0 , " loading lans animation " ) ;
2009-09-15 07:41:05 +00:00
Resources * res = Resources : : instance ( ) ;
2009-09-03 20:59:17 +00:00
//load lan000
2009-09-15 08:54:06 +00:00
2009-09-15 22:34:08 +00:00
for ( byte i = 0 ; i < 4 ; + + i ) {
2009-09-15 19:21:45 +00:00
animation [ i ] . free ( ) ;
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
uint16 bx = 0xd89e + ( _id - 1 ) * 4 + i ;
byte bxv = res - > dseg . get_byte ( bx ) ;
2009-09-14 21:05:43 +00:00
uint16 res_id = 4 * ( _id - 1 ) + i + 1 ;
2009-09-15 22:34:08 +00:00
debug ( 0 , " lan[%u]@%04x = %02x, resource id: %u " , i , bx , bxv , res_id ) ;
2009-09-03 20:59:17 +00:00
if ( bxv = = 0 )
continue ;
2009-09-15 07:41:05 +00:00
Common : : SeekableReadStream * s = res - > loadLan000 ( res_id ) ;
2009-09-03 20:59:17 +00:00
if ( s ! = NULL ) {
2009-09-15 20:21:18 +00:00
animation [ i ] . load ( s , Animation : : kTypeLan ) ;
2009-09-15 08:54:06 +00:00
if ( bxv ! = 0 & & bxv ! = 0xff )
2009-09-15 19:21:45 +00:00
animation [ i ] . id = bxv ;
2009-09-03 20:59:17 +00:00
delete s ;
}
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
//uint16 bp = res->dseg.get_word();
}
}
void Scene : : init ( int id , const Common : : Point & pos ) {
debug ( 0 , " init(%d) " , id ) ;
_id = id ;
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
if ( background . pixels = = NULL )
background . create ( 320 , 200 , 1 ) ;
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
warp ( pos ) ;
2009-09-15 07:41:05 +00:00
Resources * res = Resources : : instance ( ) ;
2009-09-03 20:59:17 +00:00
res - > loadOff ( background , palette , id ) ;
if ( id = = 24 ) {
//dark scene
if ( res - > dseg . get_byte ( 0xDBA4 ) ! = 1 ) {
//dim down palette
uint i ;
2009-09-04 20:09:29 +00:00
for ( i = 0 ; i < 624 ; + + i ) {
2009-09-15 08:54:06 +00:00
palette [ i ] = palette [ i ] > 0x20 ? palette [ i ] - 0x20 : 0 ;
2009-09-03 20:59:17 +00:00
}
2009-09-04 20:09:29 +00:00
for ( i = 726 ; i < 768 ; + + i ) {
2009-09-15 08:54:06 +00:00
palette [ i ] = palette [ i ] > 0x20 ? palette [ i ] - 0x20 : 0 ;
2009-09-03 20:59:17 +00:00
}
}
}
setPalette ( _system , palette , 4 ) ;
Common : : SeekableReadStream * stream = res - > on . getStream ( id ) ;
2009-11-17 20:47:03 +00:00
int sub_hack = 0 ;
if ( id = = 7 ) { //something patched in the captains room
switch ( res - > dseg . get_byte ( 0xdbe6 ) ) {
case 2 :
break ;
case 1 :
sub_hack = 1 ;
break ;
default :
sub_hack = 2 ;
}
}
2009-11-17 21:42:56 +00:00
on . load ( stream , SurfaceList : : kTypeOn , sub_hack ) ;
2009-09-03 20:59:17 +00:00
delete stream ;
loadOns ( ) ;
loadLans ( ) ;
2009-09-15 08:54:06 +00:00
2009-09-08 14:26:14 +00:00
//check music
int now_playing = _engine - > music - > getId ( ) ;
2009-09-15 08:54:06 +00:00
if ( now_playing ! = res - > dseg . get_byte ( 0xDB90 ) )
2009-09-08 14:26:14 +00:00
_engine - > music - > load ( res - > dseg . get_byte ( 0xDB90 ) ) ;
2009-09-03 20:59:17 +00:00
}
2009-11-09 07:58:27 +00:00
void Scene : : playAnimation ( byte idx , uint id , bool loop , bool paused , bool ignore ) {
2009-09-09 20:42:44 +00:00
assert ( idx < 4 ) ;
2009-09-15 07:41:05 +00:00
Common : : SeekableReadStream * s = Resources : : instance ( ) - > loadLan ( id + 1 ) ;
2009-09-03 20:59:17 +00:00
if ( s = = NULL )
error ( " playing animation %u failed " , id ) ;
2009-09-15 19:21:45 +00:00
custom_animation [ idx ] . load ( s ) ;
custom_animation [ idx ] . loop = loop ;
custom_animation [ idx ] . paused = paused ;
2009-11-09 07:58:27 +00:00
custom_animation [ idx ] . ignore = ignore ;
2009-09-09 20:42:44 +00:00
}
2009-11-09 07:58:27 +00:00
void Scene : : playActorAnimation ( uint id , bool loop , bool ignore ) {
2009-09-15 07:41:05 +00:00
Common : : SeekableReadStream * s = Resources : : instance ( ) - > loadLan ( id + 1 ) ;
2009-09-09 20:42:44 +00:00
if ( s = = NULL )
error ( " playing animation %u failed " , id ) ;
actor_animation . load ( s ) ;
actor_animation . loop = loop ;
2009-11-09 07:58:27 +00:00
actor_animation . ignore = ignore ;
2009-09-03 20:59:17 +00:00
}
2009-11-09 07:58:27 +00:00
Animation * Scene : : getAnimation ( byte slot ) {
2009-11-08 23:32:01 +00:00
assert ( slot < 4 ) ;
2009-11-09 07:58:27 +00:00
return custom_animation + slot ;
2009-11-08 23:32:01 +00:00
}
2009-09-03 20:59:17 +00:00
void Scene : : push ( const SceneEvent & event ) {
//debug(0, "push");
//event.dump();
events . push_back ( event ) ;
}
bool Scene : : processEvent ( const Common : : Event & event ) {
2009-09-15 08:54:06 +00:00
switch ( event . type ) {
2009-09-13 10:50:29 +00:00
case Common : : EVENT_LBUTTONDOWN :
2009-09-15 08:54:06 +00:00
case Common : : EVENT_RBUTTONDOWN :
2009-11-08 20:00:31 +00:00
if ( ! message . empty ( ) & & message_first_frame = = 0 ) {
2009-11-08 19:11:57 +00:00
clearMessage ( ) ;
2009-09-03 20:59:17 +00:00
nextEvent ( ) ;
return true ;
}
2009-09-13 10:50:29 +00:00
return false ;
2009-11-07 09:19:49 +00:00
case Common : : EVENT_KEYDOWN :
2009-11-15 19:12:46 +00:00
switch ( event . kbd . keycode ) {
case Common : : KEYCODE_ESCAPE :
case Common : : KEYCODE_SPACE : {
2009-11-07 12:05:59 +00:00
if ( intro & & event . kbd . keycode = = Common : : KEYCODE_ESCAPE ) {
2009-11-07 09:19:49 +00:00
intro = false ;
2009-11-08 19:11:57 +00:00
clearMessage ( ) ;
2009-11-07 09:19:49 +00:00
events . clear ( ) ;
sounds . clear ( ) ;
current_event . clear ( ) ;
message_color = 0xd1 ;
for ( int i = 0 ; i < 4 ; + + i )
custom_animation [ i ] . free ( ) ;
_engine - > playMusic ( 4 ) ;
init ( 10 , Common : : Point ( 136 , 153 ) ) ;
return true ;
}
2009-11-08 20:00:31 +00:00
if ( ! message . empty ( ) & & message_first_frame = = 0 ) {
2009-11-08 19:11:57 +00:00
clearMessage ( ) ;
2009-11-07 09:19:49 +00:00
nextEvent ( ) ;
return true ;
}
2009-11-15 19:12:46 +00:00
break ;
}
case ' 1 ' :
case ' 2 ' :
case ' 3 ' :
case ' 4 ' :
2009-11-17 07:35:57 +00:00
case ' 5 ' :
case ' 6 ' :
case ' 7 ' :
case ' 8 ' :
case ' 9 ' :
2009-11-15 19:12:46 +00:00
if ( event . kbd . flags & Common : : KBD_CTRL ) {
uint feature = event . kbd . keycode - ' 1 ' ;
2009-11-17 07:35:57 +00:00
if ( feature < DebugFeatures : : kMax ) {
debug_features . feature [ feature ] = ! debug_features . feature [ feature ] ;
debug ( 0 , " switched feature %u %s " , feature , debug_features . feature [ feature ] ? " on " : " off " ) ;
}
2009-11-15 19:12:46 +00:00
}
break ;
default :
break ;
2009-09-13 10:50:29 +00:00
}
default :
return false ;
2009-09-03 20:59:17 +00:00
}
}
2009-09-15 07:41:05 +00:00
bool Scene : : render ( OSystem * system ) {
Resources * res = Resources : : instance ( ) ;
2009-09-13 13:59:55 +00:00
bool busy ;
bool restart ;
2009-09-03 20:59:17 +00:00
2009-09-13 13:59:55 +00:00
do {
restart = false ;
busy = processEventQueue ( ) ;
2009-11-07 09:40:11 +00:00
if ( ! message . empty ( ) & & message_timer ! = 0 ) {
if ( - - message_timer = = 0 ) {
2009-11-08 19:11:57 +00:00
clearMessage ( ) ;
2009-11-07 09:40:11 +00:00
nextEvent ( ) ;
continue ;
}
}
2009-10-31 18:49:47 +00:00
if ( current_event . type = = SceneEvent : : kCreditsMessage ) {
system - > fillScreen ( 0 ) ;
Graphics : : Surface * surface = system - > lockScreen ( ) ;
if ( current_event . lan = = 8 ) {
res - > font8 . shadow_color = current_event . orientation ;
2009-11-08 19:11:57 +00:00
res - > font8 . render ( surface , current_event . dst . x , current_event . dst . y , message , current_event . color ) ;
2009-10-31 18:49:47 +00:00
} else {
2009-11-08 19:11:57 +00:00
res - > font7 . render ( surface , current_event . dst . x , current_event . dst . y , message , 0xd1 ) ;
2009-10-31 18:49:47 +00:00
}
system - > unlockScreen ( ) ;
return true ;
}
2009-11-15 19:12:46 +00:00
if ( background . pixels & & debug_features . feature [ DebugFeatures : : kShowBack ] )
2009-11-09 21:26:07 +00:00
system - > copyRectToScreen ( ( const byte * ) background . pixels , background . pitch , 0 , 0 , background . w , background . h ) ;
else
system - > fillScreen ( 0 ) ;
2009-09-13 13:59:55 +00:00
2009-09-15 07:41:05 +00:00
Graphics : : Surface * surface = system - > lockScreen ( ) ;
2009-09-13 13:59:55 +00:00
2009-11-15 21:31:04 +00:00
bool got_any_animation = false ;
2009-11-08 23:56:06 +00:00
2009-11-15 19:12:46 +00:00
if ( ons ! = NULL & & debug_features . feature [ DebugFeatures : : kShowOns ] ) {
2009-09-13 13:59:55 +00:00
for ( uint32 i = 0 ; i < ons_count ; + + i ) {
2009-09-15 07:41:05 +00:00
Surface * s = ons + i ;
2009-09-13 13:59:55 +00:00
if ( s ! = NULL )
s - > render ( surface ) ;
}
}
2009-11-17 07:44:40 +00:00
for ( byte i = 0 ; i < 4 ; + + i ) {
Animation * a = custom_animation + i ;
Surface * s = a - > currentFrame ( ) ;
if ( s ! = NULL ) {
if ( ! a - > ignore )
busy = true ;
else
busy = false ;
if ( ! a - > paused & & ! a - > loop )
got_any_animation = true ;
} else {
a = animation + i ;
if ( ! custom_animation [ i ] . empty ( ) ) {
debug ( 0 , " custom animation ended, restart animation in the same slot. " ) ;
custom_animation [ i ] . free ( ) ;
a - > restart ( ) ;
}
s = a - > currentFrame ( ) ;
}
if ( current_event . type = = SceneEvent : : kWaitLanAnimationFrame & & current_event . slot = = i ) {
if ( s = = NULL ) {
restart | = nextEvent ( ) ;
continue ;
}
int index = a - > currentIndex ( ) ;
if ( index = = current_event . animation ) {
debug ( 0 , " kWaitLanAnimationFrame(%d, %d) complete " , current_event . slot , current_event . animation ) ;
restart | = nextEvent ( ) ;
}
}
if ( s = = NULL )
continue ;
if ( debug_features . feature [ DebugFeatures : : kShowLan ] )
animation_position [ i ] = s - > render ( surface ) ;
if ( a - > id = = 0 )
continue ;
Object * obj = getObject ( a - > id ) ;
if ( obj ! = NULL ) {
obj - > rect . left = s - > x ;
obj - > rect . top = s - > y ;
obj - > rect . right = s - > w + s - > x ;
obj - > rect . bottom = s - > h + s - > y ;
obj - > rect . save ( ) ;
//obj->dump();
}
}
2009-11-17 21:42:56 +00:00
if ( debug_features . feature [ DebugFeatures : : kShowOn ] ) {
2009-11-17 08:57:51 +00:00
if ( _id ! = 16 | | getOns ( 16 ) [ 0 ] ! = 0 ) {
2009-11-17 21:42:56 +00:00
on . render ( surface , actor_animation_position . bottom , false ) ; //do not render boat on isle. I double checked all callbacks, there's no code switching off the boat :(
2009-11-17 08:57:51 +00:00
}
}
2009-09-15 22:34:08 +00:00
{
2009-09-15 07:41:05 +00:00
Surface * mark = actor_animation . currentFrame ( ) ;
2009-09-15 22:34:08 +00:00
if ( mark ! = NULL ) {
actor_animation_position = mark - > render ( surface ) ;
2009-11-09 07:58:27 +00:00
if ( ! actor_animation . ignore )
busy = true ;
else
busy = false ;
2009-09-15 22:34:08 +00:00
got_any_animation = true ;
} else if ( ! hide_actor ) {
2009-09-13 13:59:55 +00:00
actor_animation . free ( ) ;
2009-11-17 22:09:16 +00:00
uint zoom = 256 ;
2009-11-17 22:22:40 +00:00
const int zoom_min = 115 , zoom_max = 150 ;
if ( _id = = 18 & & position . y < zoom_max ) { //zoom hack
if ( position . y > = zoom_min )
zoom = 128 + 128 * ( position . y - zoom_min ) / ( zoom_max - zoom_min ) ;
else
zoom = 128 ;
2009-11-17 22:09:16 +00:00
}
2009-09-13 13:59:55 +00:00
2009-11-14 11:32:58 +00:00
if ( ! path . empty ( ) ) {
2009-11-07 09:19:49 +00:00
const int speed_x = 10 , speed_y = 5 ;
2009-11-14 11:32:58 +00:00
const Common : : Point & destination = path . front ( ) ;
2009-11-07 09:19:49 +00:00
Common : : Point dp ( destination . x - position . x , destination . y - position . y ) ;
switch ( orientation ) {
case 2 : //left or right
case 4 :
if ( dp . y ! = 0 )
dp . x = 0 ; //first, walking up-down
break ;
default :
if ( dp . x ! = 0 )
dp . y = 0 ; //first, walking left-right
}
2009-09-13 13:59:55 +00:00
int o ;
if ( ABS ( dp . x ) > ABS ( dp . y ) )
2009-09-15 20:21:18 +00:00
o = dp . x > 0 ? Object : : kActorRight : Object : : kActorLeft ;
2009-09-13 13:59:55 +00:00
else
2009-09-15 20:21:18 +00:00
o = dp . y > 0 ? Object : : kActorDown : Object : : kActorUp ;
2009-09-13 13:59:55 +00:00
2009-11-07 09:19:49 +00:00
position . x + = ( ABS ( dp . x ) < speed_x ? dp . x : SIGN ( dp . x ) * speed_x ) ;
position . y + = ( ABS ( dp . y ) < speed_y ? dp . y : SIGN ( dp . y ) * speed_y ) ;
2009-11-17 22:09:16 +00:00
actor_animation_position = teenagent . render ( surface , position , o , 1 , false , zoom ) ;
2009-11-07 09:19:49 +00:00
if ( position = = destination ) {
2009-11-14 11:32:58 +00:00
path . pop_front ( ) ;
if ( path . empty ( ) ) {
if ( orientation = = 0 )
orientation = o ; //save last orientation
nextEvent ( ) ;
got_any_animation = true ;
restart = true ;
}
busy = true ;
2009-09-13 13:59:55 +00:00
} else
busy = true ;
2009-11-15 11:07:52 +00:00
} else
2009-11-17 22:09:16 +00:00
actor_animation_position = teenagent . render ( surface , position , orientation , 0 , actor_talking , zoom ) ;
2009-09-13 13:59:55 +00:00
}
2009-09-15 22:34:08 +00:00
}
2009-09-03 20:59:17 +00:00
2009-11-15 19:12:46 +00:00
//render on
2009-11-17 21:42:56 +00:00
if ( debug_features . feature [ DebugFeatures : : kShowOn ] ) {
2009-11-15 19:12:46 +00:00
if ( _id ! = 16 | | getOns ( 16 ) [ 0 ] ! = 0 ) {
2009-11-17 21:42:56 +00:00
on . render ( surface , actor_animation_position . bottom , true ) ; //do not render boat on isle. I double checked all callbacks, there's no code switching off the boat :(
2009-11-15 19:12:46 +00:00
}
}
2009-09-13 13:59:55 +00:00
if ( ! message . empty ( ) ) {
2009-11-08 20:00:31 +00:00
bool visible = true ;
2009-11-08 23:32:01 +00:00
if ( message_first_frame ! = 0 & & message_animation ! = NULL ) {
int index = message_animation - > currentIndex ( ) + 1 ;
2009-11-09 07:58:27 +00:00
//debug(0, "message: %s first: %u index: %u", message.c_str(), message_first_frame, index);
2009-11-08 20:00:31 +00:00
if ( index < message_first_frame )
visible = false ;
2009-11-08 20:01:07 +00:00
if ( index > message_last_frame ) {
2009-11-08 20:00:31 +00:00
clearMessage ( ) ;
2009-11-08 20:01:07 +00:00
visible = false ;
}
2009-11-08 20:00:31 +00:00
}
if ( visible ) {
res - > font7 . render ( surface , message_pos . x , message_pos . y , message , message_color ) ;
busy = true ;
}
2009-09-13 13:59:55 +00:00
}
2009-11-08 22:37:03 +00:00
2009-11-08 23:32:01 +00:00
if ( callback_timer ) {
2009-11-08 22:37:03 +00:00
if ( - - callback_timer = = 0 ) {
if ( _engine - > inventory - > active ( ) )
_engine - > inventory - > activate ( false ) ;
_engine - > processCallback ( callback ) ;
}
}
2009-09-03 20:59:17 +00:00
2009-09-13 13:59:55 +00:00
//if (!current_event.empty())
// current_event.dump();
2009-11-14 11:32:58 +00:00
2009-11-17 07:35:57 +00:00
if ( ! debug_features . feature [ DebugFeatures : : kHidePath ] ) {
2009-09-26 15:04:09 +00:00
const Common : : Array < Walkbox > & scene_walkboxes = walkboxes [ _id - 1 ] ;
for ( uint i = 0 ; i < scene_walkboxes . size ( ) ; + + i ) {
scene_walkboxes [ i ] . rect . render ( surface , 0xd0 + i ) ;
}
2009-11-14 11:32:58 +00:00
Common : : Point last_p = position ;
for ( Path : : const_iterator p = path . begin ( ) ; p ! = path . end ( ) ; + + p ) {
const Common : : Point dp ( p - > x - last_p . x , p - > y - last_p . y ) ;
if ( dp . x ! = 0 ) {
surface - > hLine ( last_p . x , last_p . y , p - > x , 0xfe ) ;
} else if ( dp . y ! = 0 ) {
surface - > vLine ( last_p . x , last_p . y , p - > y , 0xfe ) ;
}
last_p = * p ;
}
2009-09-13 12:48:57 +00:00
}
2009-09-03 20:59:17 +00:00
2009-11-14 11:32:58 +00:00
system - > unlockScreen ( ) ;
if ( ! restart & & current_event . type = = SceneEvent : : kWaitForAnimation & & ! got_any_animation ) {
debug ( 0 , " no animations, nextevent " ) ;
nextEvent ( ) ;
restart = true ;
}
2009-09-15 08:54:06 +00:00
} while ( restart ) ;
for ( Sounds : : iterator i = sounds . begin ( ) ; i ! = sounds . end ( ) ; ) {
2009-09-05 15:04:37 +00:00
Sound & sound = * i ;
if ( sound . delay = = 0 ) {
2009-11-14 11:32:58 +00:00
debug ( 1 , " sound %u started " , sound . id ) ;
2009-09-05 15:04:37 +00:00
_engine - > playSoundNow ( sound . id ) ;
i = sounds . erase ( i ) ;
} else {
- - sound . delay ;
+ + i ;
2009-09-03 20:59:17 +00:00
}
}
2009-09-15 08:54:06 +00:00
2009-09-03 20:59:17 +00:00
return busy ;
}
bool Scene : : processEventQueue ( ) {
while ( ! events . empty ( ) & & current_event . empty ( ) ) {
//debug(0, "processing next event");
current_event = events . front ( ) ;
events . pop_front ( ) ;
2009-09-15 08:54:06 +00:00
switch ( current_event . type ) {
2009-09-15 20:21:18 +00:00
case SceneEvent : : kSetOn : {
2009-09-15 08:54:06 +00:00
byte * ptr = getOns ( current_event . scene = = 0 ? _id : current_event . scene ) ;
2009-09-03 20:59:17 +00:00
debug ( 0 , " on[%u] = %02x " , current_event . ons - 1 , current_event . color ) ;
ptr [ current_event . ons - 1 ] = current_event . color ;
loadOns ( ) ;
current_event . clear ( ) ;
2009-09-15 08:54:06 +00:00
}
break ;
2009-09-15 20:21:18 +00:00
case SceneEvent : : kSetLan : {
2009-09-03 20:59:17 +00:00
if ( current_event . lan ! = 0 ) {
debug ( 0 , " lan[%u] = %02x " , current_event . lan - 1 , current_event . color ) ;
2009-09-15 08:54:06 +00:00
byte * ptr = getLans ( current_event . scene = = 0 ? _id : current_event . scene ) ;
2009-09-03 20:59:17 +00:00
ptr [ current_event . lan - 1 ] = current_event . color ;
}
loadLans ( ) ;
current_event . clear ( ) ;
2009-09-15 08:54:06 +00:00
}
break ;
2009-09-15 20:21:18 +00:00
case SceneEvent : : kLoadScene : {
2009-11-09 21:26:07 +00:00
if ( current_event . scene ! = 0 ) {
init ( current_event . scene , current_event . dst ) ;
sounds . clear ( ) ;
} else {
//special case, empty scene
background . free ( ) ;
on . free ( ) ;
delete [ ] ons ;
ons = NULL ;
for ( byte i = 0 ; i < 4 ; + + i ) {
animation [ i ] . free ( ) ;
custom_animation [ i ] . free ( ) ;
}
}
2009-09-03 20:59:17 +00:00
current_event . clear ( ) ;
2009-09-15 08:54:06 +00:00
}
break ;
2009-09-15 20:21:18 +00:00
case SceneEvent : : kWalk : {
2009-09-05 17:15:28 +00:00
Common : : Point dst = current_event . dst ;
if ( ( current_event . color & 2 ) ! = 0 ) { //relative move
dst . x + = position . x ;
dst . y + = position . y ;
}
if ( ( current_event . color & 1 ) ! = 0 ) {
warp ( dst , current_event . orientation ) ;
2009-09-03 20:59:17 +00:00
current_event . clear ( ) ;
} else
2009-09-05 17:15:28 +00:00
moveTo ( dst , current_event . orientation ) ;
2009-09-15 08:54:06 +00:00
}
break ;
2009-09-15 20:21:18 +00:00
case SceneEvent : : kCreditsMessage :
case SceneEvent : : kMessage : {
2009-09-15 20:08:28 +00:00
message = current_event . message ;
2009-11-08 23:32:01 +00:00
message_animation = NULL ;
2009-11-08 20:00:31 +00:00
if ( current_event . first_frame ) {
message_timer = 0 ;
message_first_frame = current_event . first_frame ;
message_last_frame = current_event . last_frame ;
2009-11-12 10:32:29 +00:00
if ( current_event . slot > 0 ) {
message_animation = custom_animation + ( current_event . slot - 1 ) ;
2009-11-08 23:32:01 +00:00
//else if (!animation[current_event.slot].empty())
// message_animation = animation + current_event.slot;
} else
message_animation = & actor_animation ;
debug ( 0 , " async message %d-%d (slot %u) " , message_first_frame , message_last_frame , current_event . slot ) ;
2009-11-08 20:00:31 +00:00
} else {
message_timer = messageDuration ( message ) ;
message_first_frame = message_last_frame = 0 ;
}
Common : : Point p ;
if ( current_event . dst . x = = 0 & & current_event . dst . y = = 0 ) {
p = Common : : Point ( ( actor_animation_position . left + actor_animation_position . right ) / 2 ,
actor_animation_position . top ) ;
} else {
p = current_event . dst ;
}
2009-11-12 10:32:29 +00:00
byte message_slot = current_event . slot ;
if ( message_slot ! = 0 ) {
- - message_slot ;
assert ( message_slot < 4 ) ;
const Surface * s = custom_animation [ message_slot ] . currentFrame ( 0 ) ;
2009-09-15 20:08:28 +00:00
if ( s = = NULL )
2009-11-12 10:32:29 +00:00
s = animation [ message_slot ] . currentFrame ( 0 ) ;
2009-09-15 20:08:28 +00:00
if ( s ! = NULL ) {
p . x = s - > x + s - > w / 2 ;
p . y = s - > y ;
} else
2009-11-12 10:32:29 +00:00
warning ( " no animation in slot %u " , message_slot ) ;
2009-09-15 20:08:28 +00:00
}
message_pos = messagePosition ( message , p ) ;
message_color = current_event . color ;
2009-11-08 20:37:33 +00:00
if ( message_first_frame )
current_event . clear ( ) ; //async message, clearing event
2009-09-15 20:08:28 +00:00
}
2009-09-14 22:23:35 +00:00
break ;
2009-09-15 08:54:06 +00:00
2009-11-12 10:32:29 +00:00
case SceneEvent : : kPlayAnimation : {
byte slot = current_event . slot & 7 ; //0 - mark's
if ( current_event . animation ! = 0 ) {
2009-11-15 11:07:52 +00:00
debug ( 0 , " playing animation %u in slot %u " , current_event . animation , slot ) ;
2009-11-12 10:32:29 +00:00
if ( slot ! = 0 ) {
- - slot ;
assert ( slot < 4 ) ;
playAnimation ( slot , current_event . animation , ( current_event . slot & 0x80 ) ! = 0 , ( slot & 0x40 ) ! = 0 , ( slot & 0x20 ) ! = 0 ) ;
2009-11-15 11:07:52 +00:00
} else
actor_talking = true ;
2009-11-12 10:32:29 +00:00
} else {
if ( slot ! = 0 ) {
- - slot ;
debug ( 0 , " cancelling animation in slot %u " , slot ) ;
assert ( slot < 4 ) ;
custom_animation [ slot ] . free ( ) ;
2009-11-15 11:07:52 +00:00
} else
actor_talking = true ;
2009-11-12 10:32:29 +00:00
}
current_event . clear ( ) ;
2009-11-10 07:29:06 +00:00
}
2009-09-14 22:23:35 +00:00
break ;
2009-09-09 20:42:44 +00:00
2009-11-15 11:07:52 +00:00
case SceneEvent : : kPauseAnimation : {
byte slot = current_event . slot & 7 ; //0 - mark's
if ( slot ! = 0 ) {
- - slot ;
debug ( 0 , " pause animation in slot %u " , slot ) ;
custom_animation [ slot ] . paused = ( current_event . slot & 0x80 ) ! = 0 ;
} else {
actor_talking = false ;
}
current_event . clear ( ) ;
2009-11-12 10:32:29 +00:00
}
2009-09-14 22:23:35 +00:00
break ;
2009-09-15 20:21:18 +00:00
case SceneEvent : : kClearAnimations :
2009-09-15 08:54:06 +00:00
for ( byte i = 0 ; i < 4 ; + + i )
2009-09-15 19:21:45 +00:00
custom_animation [ i ] . free ( ) ;
2009-11-15 11:07:52 +00:00
actor_talking = false ;
2009-09-14 22:23:35 +00:00
current_event . clear ( ) ;
break ;
2009-09-15 08:54:06 +00:00
2009-09-15 20:21:18 +00:00
case SceneEvent : : kPlayActorAnimation :
2009-09-14 22:23:35 +00:00
debug ( 0 , " playing actor animation %u " , current_event . animation ) ;
2009-11-09 07:58:27 +00:00
playActorAnimation ( current_event . animation , ( current_event . slot & 0x80 ) ! = 0 , ( current_event . slot & 0x20 ) ! = 0 ) ;
2009-09-14 22:23:35 +00:00
current_event . clear ( ) ;
break ;
2009-09-15 08:54:06 +00:00
2009-09-15 20:21:18 +00:00
case SceneEvent : : kPlayMusic :
2009-09-03 20:59:17 +00:00
debug ( 0 , " setting music %u " , current_event . music ) ;
_engine - > setMusic ( current_event . music ) ;
Resources : : instance ( ) - > dseg . set_byte ( 0xDB90 , current_event . music ) ;
current_event . clear ( ) ;
2009-09-14 22:23:35 +00:00
break ;
2009-09-03 20:59:17 +00:00
2009-09-15 20:21:18 +00:00
case SceneEvent : : kPlaySound :
2009-09-03 20:59:17 +00:00
debug ( 0 , " playing sound %u, delay: %u " , current_event . sound , current_event . color ) ;
2009-09-15 19:21:45 +00:00
sounds . push_back ( Sound ( current_event . sound , current_event . color ) ) ;
2009-09-03 20:59:17 +00:00
current_event . clear ( ) ;
2009-09-14 22:23:35 +00:00
break ;
2009-09-15 08:54:06 +00:00
2009-09-15 20:21:18 +00:00
case SceneEvent : : kEnableObject : {
2009-09-15 08:54:06 +00:00
debug ( 0 , " %s object #%u " , current_event . color ? " enabling " : " disabling " , current_event . object - 1 ) ;
Object * obj = getObject ( current_event . object - 1 , current_event . scene = = 0 ? _id : current_event . scene ) ;
obj - > enabled = current_event . color ;
2009-09-27 05:17:00 +00:00
obj - > save ( ) ;
2009-09-15 08:54:06 +00:00
current_event . clear ( ) ;
}
break ;
2009-09-15 20:21:18 +00:00
case SceneEvent : : kHideActor :
2009-09-13 12:48:57 +00:00
hide_actor = current_event . color ! = 0 ;
current_event . clear ( ) ;
2009-09-14 22:23:35 +00:00
break ;
2009-09-15 08:54:06 +00:00
2009-09-15 20:21:18 +00:00
case SceneEvent : : kWaitForAnimation :
2009-09-03 20:59:17 +00:00
debug ( 0 , " waiting for the animation " ) ;
break ;
2009-09-15 08:54:06 +00:00
2009-11-07 12:00:56 +00:00
case SceneEvent : : kWaitLanAnimationFrame :
2009-11-08 20:00:31 +00:00
debug ( 0 , " waiting for the frame %d in slot %d " , current_event . animation , current_event . slot ) ;
2009-11-07 12:00:56 +00:00
break ;
2009-11-08 22:37:03 +00:00
case SceneEvent : : kTimer :
callback = current_event . callback ;
callback_timer = current_event . timer ;
debug ( 0 , " triggering callback %04x in %u frames " , callback , callback_timer ) ;
current_event . clear ( ) ;
break ;
2009-11-07 12:00:56 +00:00
2009-09-15 20:21:18 +00:00
case SceneEvent : : kQuit :
2009-09-07 22:47:50 +00:00
debug ( 0 , " quit! " ) ;
_engine - > quitGame ( ) ;
break ;
2009-09-15 08:54:06 +00:00
default :
2009-09-03 20:59:17 +00:00
error ( " empty/unhandler event[%d] " , ( int ) current_event . type ) ;
}
}
2009-09-13 12:48:57 +00:00
if ( events . empty ( ) ) {
2009-09-14 21:05:43 +00:00
message_color = 0xd1 ;
2009-09-13 12:48:57 +00:00
hide_actor = false ;
}
2009-09-03 20:59:17 +00:00
return ! current_event . empty ( ) ;
}
2009-09-15 07:41:05 +00:00
void Scene : : setPalette ( OSystem * system , const byte * buf , unsigned mul ) {
2009-09-03 20:59:17 +00:00
byte p [ 1024 ] ;
memset ( p , 0 , 1024 ) ;
2009-09-04 20:09:29 +00:00
for ( int i = 0 ; i < 256 ; + + i ) {
2009-09-15 08:54:06 +00:00
for ( int c = 0 ; c < 3 ; + + c )
2009-09-03 20:59:17 +00:00
p [ i * 4 + c ] = buf [ i * 3 + c ] * mul ;
}
system - > setPalette ( p , 0 , 256 ) ;
}
2009-09-15 07:41:05 +00:00
Object * Scene : : getObject ( int id , int scene_id ) {
2009-09-26 15:04:09 +00:00
assert ( id > 0 ) ;
2009-09-03 20:59:17 +00:00
if ( scene_id = = 0 )
scene_id = _id ;
2009-09-15 08:54:06 +00:00
2009-09-26 15:04:09 +00:00
if ( scene_id = = 0 )
return NULL ;
2009-09-03 20:59:17 +00:00
2009-09-26 15:04:09 +00:00
return & objects [ scene_id - 1 ] [ id - 1 ] ;
2009-09-03 20:59:17 +00:00
}
2009-09-15 20:08:28 +00:00
Common : : Point Scene : : messagePosition ( const Common : : String & str , Common : : Point position ) {
2009-09-15 07:41:05 +00:00
Resources * res = Resources : : instance ( ) ;
2009-11-08 19:11:57 +00:00
uint w = res - > font7 . render ( NULL , 0 , 0 , str , 0 ) ;
2009-11-07 12:33:59 +00:00
uint h = res - > font7 . height + 3 ;
2009-09-15 20:08:28 +00:00
position . x - = w / 2 ;
2009-11-07 12:33:59 +00:00
position . y - = h ;
2009-09-15 20:08:28 +00:00
if ( position . x + w > 320 )
position . x = 320 - w ;
if ( position . x < 0 )
position . x = 0 ;
2009-11-07 12:33:59 +00:00
if ( position . y + h > 320 )
position . y = 200 - h ;
if ( position . y < 0 )
position . y = 0 ;
2009-09-15 20:08:28 +00:00
return position ;
2009-09-03 20:59:17 +00:00
}
2009-11-07 09:40:11 +00:00
uint Scene : : messageDuration ( const Common : : String & str ) {
2009-11-15 11:24:20 +00:00
uint chars = str . size ( ) ;
//to be discovered
if ( chars < 10 )
chars = 10 ;
return chars ;
2009-11-07 09:40:11 +00:00
}
2009-11-15 17:43:47 +00:00
void Scene : : displayMessage ( const Common : : String & str , byte color , const Common : : Point & pos ) {
2009-10-18 10:46:42 +00:00
//assert(!str.empty());
//debug(0, "displayMessage: %s", str.c_str());
2009-09-03 20:59:17 +00:00
message = str ;
2009-11-15 17:43:47 +00:00
message_pos = ( pos . x | pos . y ) ? pos : messagePosition ( str , position ) ;
2009-09-14 21:05:43 +00:00
message_color = color ;
2009-11-07 09:40:11 +00:00
message_timer = messageDuration ( message ) ;
2009-09-03 20:59:17 +00:00
}
void Scene : : clear ( ) {
2009-11-08 19:11:57 +00:00
clearMessage ( ) ;
2009-09-03 20:59:17 +00:00
events . clear ( ) ;
current_event . clear ( ) ;
2009-10-31 19:34:27 +00:00
for ( int i = 0 ; i < 4 ; + + i ) {
animation [ i ] . free ( ) ;
custom_animation [ i ] . free ( ) ;
}
2009-11-08 22:37:03 +00:00
callback = 0 ;
callback_timer = 0 ;
2009-09-03 20:59:17 +00:00
}
2009-09-04 20:08:33 +00:00
2009-11-08 19:11:57 +00:00
void Scene : : clearMessage ( ) {
message . clear ( ) ;
message_timer = 0 ;
message_color = 0xd1 ;
2009-11-08 20:00:31 +00:00
message_first_frame = 0 ;
message_last_frame = 0 ;
2009-11-08 23:32:01 +00:00
message_animation = NULL ;
2009-11-08 19:11:57 +00:00
}
2009-09-04 20:08:33 +00:00
} // End of namespace TeenAgent