2003-07-28 01:44:38 +00:00
/* Copyright (C) 1994-2003 Revolution Software Ltd
*
* 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 . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* $ Header $
*/
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
// BUILD_DISPLAY.CPP like the old spr_engi but slightly more aptly named
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
# include <stdio.h>
2003-07-28 03:12:49 +00:00
# include "stdafx.h"
2003-07-28 01:44:38 +00:00
# include "build_display.h"
# include "console.h"
# include "defs.h"
# include "interpreter.h"
# include "layers.h"
# include "maketext.h"
# include "mouse.h"
# include "object.h"
# include "protocol.h"
# include "resman.h"
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
buildit bgp0_list [ MAX_bgp0_sprites ] ;
buildit bgp1_list [ MAX_bgp1_sprites ] ;
buildit back_list [ MAX_back_sprites ] ;
buildit sort_list [ MAX_sort_sprites ] ;
buildit fore_list [ MAX_fore_sprites ] ;
buildit fgp0_list [ MAX_fgp0_sprites ] ;
buildit fgp1_list [ MAX_fgp1_sprites ] ;
2003-09-02 09:54:42 +00:00
// holds the order of the sort list
// i.e the list stays static and we sort this
uint16 sort_order [ MAX_sort_sprites ] ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
uint32 cur_bgp0 ;
uint32 cur_bgp1 ;
uint32 cur_back ;
uint32 cur_sort ;
uint32 cur_fore ;
uint32 cur_fgp0 ;
uint32 cur_fgp1 ;
2003-07-28 01:44:38 +00:00
2003-07-30 19:25:31 +00:00
# ifdef _SWORD2_DEBUG
2003-09-02 09:54:42 +00:00
uint32 largest_layer_area = 0 ; // should be reset to zero at start of each screen change
uint32 largest_sprite_area = 0 ; // - " -
char largest_layer_info [ 128 ] = { " largest layer: none registered " } ;
char largest_sprite_info [ 128 ] = { " largest sprite: none registered " } ;
2003-07-28 01:44:38 +00:00
# endif
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
// last palette used - so that we can restore the correct one after a pause
// (which dims the screen) and it's not always the main screen palette that we
// want, eg. during the eclipse
2003-07-28 01:44:38 +00:00
// This flag gets set in Start_new_palette() and SetFullPalette()
2003-09-02 09:54:42 +00:00
uint32 lastPaletteRes = 0 ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
// 'frames per second' counting stuff
2003-09-02 09:54:42 +00:00
uint32 fps = 0 ;
uint32 cycleTime = 0 ;
uint32 frameCount = 0 ;
// So I know if the control Panel can be activated - CJR 1-5-97
extern uint32 mouse_status ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
// function prototypes not needed externally
2003-09-02 09:54:42 +00:00
void Start_new_palette ( void ) ; //Tony25Sept96
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
void Register_frame ( int32 * params , buildit * build_unit ) ; // (1nov96JEL)
void Process_layer ( uint32 layer_number ) ; //Tony24Sept96
void Sort_the_sort_list ( void ) ; //Tony18Sept96
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
void Send_back_par0_frames ( void ) ; //James23Jan97
void Send_back_par1_frames ( void ) ; //James23Jan97
void Send_back_frames ( void ) ; //Tony23Sept96
void Send_sort_frames ( void ) ;
void Send_fore_frames ( void ) ;
void Send_fore_par0_frames ( void ) ; //James23Jan97
void Send_fore_par1_frames ( void ) ; //James23Jan97
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
//
// PC Build_display
//
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
void Build_display ( void ) { //Tony21Sept96
2003-09-24 06:40:23 +00:00
bool end ;
2003-07-30 19:25:31 +00:00
# ifdef _SWORD2_DEBUG
2003-09-02 09:54:42 +00:00
uint8 pal [ 12 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 255 , 0 , 0 } ;
2003-07-28 02:10:24 +00:00
# endif
2003-09-02 09:54:42 +00:00
uint8 * file ;
2003-07-28 01:44:38 +00:00
_multiScreenHeader * screenLayerTable ;
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG // only used by console
_spriteInfo spriteInfo ;
uint32 rv ; // drivers error return value
2003-07-28 01:44:38 +00:00
# endif
2003-09-02 09:54:42 +00:00
if ( ! console_status & & this_screen . new_palette ) {
// start the layer palette fading up
Start_new_palette ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG // (James23jun97)
largest_layer_area = 0 ; // should be reset to zero at start of each screen change
largest_sprite_area = 0 ; // - " -
# endif
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// there is a valid screen to run
if ( ! console_status & & this_screen . background_layer_id ) {
// set the scroll position
SetScrollTarget ( this_screen . scroll_offset_x , this_screen . scroll_offset_y ) ;
// increment the mouse frame
AnimateMouse ( ) ;
2003-07-28 01:44:38 +00:00
StartRenderCycle ( ) ;
2003-09-02 09:54:42 +00:00
while ( 1 ) {
// START OF RENDER CYCLE
// ---------------------------------------------------
// clear the back buffer, before building up the new
// screen from the back forwards
2003-08-29 06:42:34 +00:00
// FIXME: I'm not convinced that this is needed. Isn't
// the whole screen redrawn each time?
2003-09-02 09:54:42 +00:00
2003-08-29 06:42:34 +00:00
// EraseBackBuffer();
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// first background parallax + related anims
2003-09-02 09:54:42 +00:00
// open the screen resource
file = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
screenLayerTable = ( _multiScreenHeader * ) ( ( uint8 * ) file + sizeof ( _standardHeader ) ) ;
2003-09-02 09:54:42 +00:00
if ( screenLayerTable - > bg_parallax [ 0 ] ) {
2003-07-28 01:44:38 +00:00
RenderParallax ( FetchBackgroundParallaxLayer ( file , 0 ) , 0 ) ;
2003-09-02 09:54:42 +00:00
// release the screen resource before cacheing
// the sprites
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
Send_back_par0_frames ( ) ;
2003-09-02 09:54:42 +00:00
} else {
// release the screen resource
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// second background parallax + related anims
2003-09-02 09:54:42 +00:00
// open the screen resource
file = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
screenLayerTable = ( _multiScreenHeader * ) ( ( uint8 * ) file + sizeof ( _standardHeader ) ) ;
2003-09-02 09:54:42 +00:00
if ( screenLayerTable - > bg_parallax [ 1 ] ) {
2003-07-28 01:44:38 +00:00
RenderParallax ( FetchBackgroundParallaxLayer ( file , 1 ) , 1 ) ;
2003-09-02 09:54:42 +00:00
// release the screen resource before cacheing
// the sprites
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
Send_back_par1_frames ( ) ;
2003-09-02 09:54:42 +00:00
} else {
// release the screen resource
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// normal backround layer (just the one!)
2003-09-02 09:54:42 +00:00
// open the screen resource
file = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
RenderParallax ( FetchBackgroundLayer ( file ) , 2 ) ;
2003-09-02 09:54:42 +00:00
// release the screen resource
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// sprites & layers
2003-09-02 09:54:42 +00:00
Send_back_frames ( ) ; // background sprites
2003-07-28 01:44:38 +00:00
Sort_the_sort_list ( ) ;
2003-09-02 09:54:42 +00:00
Send_sort_frames ( ) ; // sorted sprites & layers
Send_fore_frames ( ) ; // foreground sprites
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// first foreground parallax + related anims
2003-09-02 09:54:42 +00:00
// open the screen resource
file = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
screenLayerTable = ( _multiScreenHeader * ) ( ( uint8 * ) file + sizeof ( _standardHeader ) ) ;
2003-09-02 09:54:42 +00:00
if ( screenLayerTable - > fg_parallax [ 0 ] ) {
2003-07-28 01:44:38 +00:00
RenderParallax ( FetchForegroundParallaxLayer ( file , 0 ) , 3 ) ;
2003-09-02 09:54:42 +00:00
// release the screen resource before cacheing
// the sprites
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
Send_fore_par0_frames ( ) ;
2003-09-02 09:54:42 +00:00
} else {
// release the screen resource
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
}
//----------------------------------------------------
// second foreground parallax + related anims
2003-09-02 09:54:42 +00:00
// open the screen resource
file = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
screenLayerTable = ( _multiScreenHeader * ) ( ( uint8 * ) file + sizeof ( _standardHeader ) ) ;
2003-09-02 09:54:42 +00:00
if ( screenLayerTable - > fg_parallax [ 1 ] ) {
2003-07-28 01:44:38 +00:00
RenderParallax ( FetchForegroundParallaxLayer ( file , 1 ) , 4 ) ;
2003-09-02 09:54:42 +00:00
// release the screen resource before cacheing
// the sprites
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
Send_fore_par1_frames ( ) ;
2003-09-02 09:54:42 +00:00
} else {
// release the screen resource
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
// walkgrid, mouse & player markers & mouse area
// rectangle
2003-07-28 01:44:38 +00:00
Draw_debug_graphics ( ) ; // JAMES (08apr97)
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// text blocks
2003-09-02 09:54:42 +00:00
// speech blocks and headup debug text
Print_text_blocs ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// menu bar & icons
ProcessMenu ( ) ;
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
// ready - blit to screen
2003-09-09 12:45:33 +00:00
ServiceWindows ( ) ;
2003-07-28 01:44:38 +00:00
//----------------------------------------------------
// update our fps reading
2003-09-02 09:54:42 +00:00
frameCount + + ;
if ( SVM_timeGetTime ( ) > cycleTime ) {
2003-07-28 01:44:38 +00:00
fps = frameCount ;
2003-08-29 06:46:52 +00:00
debug ( 2 , " FPS: %d " , fps ) ;
2003-07-28 01:44:38 +00:00
frameCount = 0 ;
2003-07-28 07:47:21 +00:00
cycleTime = SVM_timeGetTime ( ) + 1000 ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
// check if we've got time to render the screen again
// this cycle (so drivers can smooth out the scrolling
// in between normal game cycles)
2003-07-28 01:44:38 +00:00
EndRenderCycle ( & end ) ;
2003-09-02 09:54:42 +00:00
// if we haven't got time to render again this cycle,
// drop out of 'render cycle' while-loop
if ( end )
2003-07-28 01:44:38 +00:00
break ;
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------
2003-07-28 01:44:38 +00:00
} // END OF RENDER CYCLE
}
2003-07-30 19:25:31 +00:00
# ifdef _SWORD2_DEBUG
2003-09-02 09:54:42 +00:00
else if ( console_status ) {
spriteInfo . x = 0 ;
spriteInfo . y = con_y ;
spriteInfo . w = con_width ;
spriteInfo . h = con_depth ;
spriteInfo . scale = 0 ;
spriteInfo . scaledWidth = 0 ;
spriteInfo . scaledHeight = 0 ;
spriteInfo . type = RDSPR_DISPLAYALIGN + RDSPR_NOCOMPRESSION ;
spriteInfo . blend = 0 ;
spriteInfo . data = console_sprite - > ad ;
spriteInfo . colourTable = 0 ;
rv = DrawSprite ( & spriteInfo ) ;
2003-07-28 01:44:38 +00:00
if ( rv )
ExitWithReport ( " Driver Error %.8x (drawing console) [%s line %u] " , rv , __FILE__ , __LINE__ ) ;
CopyScreenBuffer ( ) ;
2003-09-02 09:54:42 +00:00
} else {
2003-07-28 01:44:38 +00:00
StartConsole ( ) ;
2003-09-02 09:54:42 +00:00
// force the palette
BS2_SetPalette ( 0 , 3 , pal , RDPAL_INSTANT ) ;
2003-07-28 01:44:38 +00:00
Print_to_console ( " no valid screen? " ) ;
}
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
//
// Fades down and displays a message on the screen for time seconds
//
2003-09-02 09:54:42 +00:00
void DisplayMsg ( uint8 * text , int time ) { // Chris 15May97
2003-07-28 01:44:38 +00:00
mem * text_spr ;
_frameHeader * frame ;
2003-09-02 09:54:42 +00:00
_spriteInfo spriteInfo ;
_palEntry pal [ 256 ] ;
_palEntry oldPal [ 256 ] ;
int16 oldY ;
int16 oldX ;
uint32 rv ; // drivers error return value
2003-07-28 01:44:38 +00:00
warning ( " DisplayMsg: %s " , ( char * ) text ) ;
2003-09-02 09:54:42 +00:00
if ( GetFadeStatus ( ) ! = RDFADE_BLACK ) {
2003-07-28 01:44:38 +00:00
FadeDown ( ( float ) 0.75 ) ;
2003-09-09 12:14:08 +00:00
WaitForFade ( ) ;
2003-07-28 01:44:38 +00:00
}
2003-07-28 03:49:25 +00:00
Set_mouse ( 0 ) ;
2003-09-02 09:54:42 +00:00
Set_luggage ( 0 ) ; //tw28Aug
2003-07-28 01:44:38 +00:00
2003-09-08 06:32:37 +00:00
CloseMenuImmediately ( ) ;
2003-09-19 06:42:22 +00:00
EraseBackBuffer ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
text_spr = MakeTextSprite ( text , 640 , 187 , speech_font_id ) ;
2003-07-28 01:44:38 +00:00
frame = ( _frameHeader * ) text_spr - > ad ;
2003-09-02 09:54:42 +00:00
spriteInfo . x = screenWide / 2 - frame - > width / 2 ;
2003-07-28 01:44:38 +00:00
if ( ! time )
2003-09-02 09:54:42 +00:00
spriteInfo . y = screenDeep / 2 - frame - > height / 2 - RDMENU_MENUDEEP ;
2003-07-28 01:44:38 +00:00
else
2003-09-02 09:54:42 +00:00
spriteInfo . y = 400 - frame - > height ;
spriteInfo . w = frame - > width ;
spriteInfo . h = frame - > height ;
spriteInfo . scale = 0 ;
spriteInfo . scaledWidth = 0 ;
2003-07-28 01:44:38 +00:00
spriteInfo . scaledHeight = 0 ;
2003-09-02 09:54:42 +00:00
spriteInfo . type = RDSPR_DISPLAYALIGN + RDSPR_NOCOMPRESSION + RDSPR_TRANS ;
spriteInfo . blend = 0 ;
spriteInfo . data = text_spr - > ad + sizeof ( _frameHeader ) ;
spriteInfo . colourTable = 0 ;
oldX = spriteInfo . x ;
oldY = spriteInfo . y ;
rv = DrawSprite ( & spriteInfo ) ;
2003-07-28 01:44:38 +00:00
if ( rv )
ExitWithReport ( " Driver Error %.8x (in DisplayMsg) [%s line %u] " , rv , __FILE__ , __LINE__ ) ;
spriteInfo . x = oldX ;
spriteInfo . y = oldY ;
2003-09-02 09:54:42 +00:00
memcpy ( ( char * ) oldPal , ( char * ) palCopy , 256 * sizeof ( _palEntry ) ) ;
2003-07-28 01:44:38 +00:00
memset ( pal , 0 , 256 * sizeof ( _palEntry ) ) ;
2003-09-02 09:54:42 +00:00
pal [ 187 ] . red = 255 ;
2003-07-28 01:44:38 +00:00
pal [ 187 ] . green = 255 ;
2003-09-02 09:54:42 +00:00
pal [ 187 ] . blue = 255 ;
2003-08-23 14:42:37 +00:00
BS2_SetPalette ( 0 , 256 , ( uint8 * ) pal , RDPAL_FADE ) ;
2003-07-28 01:44:38 +00:00
CopyScreenBuffer ( ) ;
2003-09-02 09:54:42 +00:00
FadeUp ( ( float ) 0.75 ) ;
2003-07-28 01:44:38 +00:00
Free_mem ( text_spr ) ;
2003-09-09 12:14:08 +00:00
WaitForFade ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
uint32 targetTime = SVM_timeGetTime ( ) + ( time * 1000 ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
while ( SVM_timeGetTime ( ) < targetTime ) {
2003-09-09 12:45:33 +00:00
ServiceWindows ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-19 06:42:22 +00:00
EraseBackBuffer ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
rv = DrawSprite ( & spriteInfo ) ; // Keep the message there even when the user task swaps.
2003-07-28 01:44:38 +00:00
if ( rv )
ExitWithReport ( " Driver Error %.8x (in DisplayMsg) [%s line %u] " , rv , __FILE__ , __LINE__ ) ;
2003-09-02 09:54:42 +00:00
// Drivers change the y co-ordinate, don't know why...
spriteInfo . y = oldY ;
2003-07-28 01:44:38 +00:00
spriteInfo . x = oldX ;
CopyScreenBuffer ( ) ;
}
2003-08-23 14:42:37 +00:00
BS2_SetPalette ( 0 , 256 , ( uint8 * ) oldPal , RDPAL_FADE ) ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
2003-07-28 01:44:38 +00:00
//
// Fades message down and removes it, fading up again afterwards
//
2003-09-02 09:54:42 +00:00
void RemoveMsg ( void ) { // Chris 15May97
FadeDown ( ( float ) 0.75 ) ;
2003-09-09 12:14:08 +00:00
WaitForFade ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-19 06:42:22 +00:00
EraseBackBuffer ( ) ;
2003-07-28 01:44:38 +00:00
CopyScreenBuffer ( ) ;
2003-09-02 09:54:42 +00:00
// FadeUp((float) 0.75);
// removed by JEL (08oct97) to prevent "eye" smacker corruption when
// restarting game from CD2 and also to prevent palette flicker when
// restoring game to a different CD since the "insert CD" message uses
// this routine to clean up!
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
void Send_back_par0_frames ( void ) { //James23Jan97
2003-07-28 01:44:38 +00:00
uint32 j ;
2003-09-02 09:54:42 +00:00
// could be none at all - theoretically at least
for ( j = 0 ; j < cur_bgp0 ; j + + ) {
// frame attached to 1st background parallax
Process_image ( & bgp0_list [ j ] ) ;
2003-07-28 01:44:38 +00:00
}
}
2003-09-02 09:54:42 +00:00
void Send_back_par1_frames ( void ) { //James23Jan97
2003-07-28 01:44:38 +00:00
uint32 j ;
2003-09-02 09:54:42 +00:00
// could be none at all - theoretically at least
for ( j = 0 ; j < cur_bgp1 ; j + + ) {
// frame attached to 1nd background parallax
Process_image ( & bgp1_list [ j ] ) ;
2003-07-28 01:44:38 +00:00
}
}
2003-09-02 09:54:42 +00:00
void Send_back_frames ( void ) { //Tony23Sept96
2003-07-28 01:44:38 +00:00
uint32 j ;
2003-09-02 09:54:42 +00:00
// could be none at all - theoretically at least
for ( j = 0 ; j < cur_back ; j + + ) {
2003-07-28 01:44:38 +00:00
Process_image ( & back_list [ j ] ) ;
}
}
2003-09-02 09:54:42 +00:00
void Send_sort_frames ( void ) { //Tony23Sept96
// send the sort frames for printing - layers, shrinkers & normal flat
// sprites
2003-07-28 01:44:38 +00:00
uint32 j ;
2003-09-02 09:54:42 +00:00
// could be none at all - theoretically at least
for ( j = 0 ; j < cur_sort ; j + + ) {
if ( sort_list [ sort_order [ j ] ] . layer_number ) {
// its a layer - minus 1 for true layer number
// we need to know from the buildit because the layers
// will have been sorted in random order
Process_layer ( sort_list [ sort_order [ j ] ] . layer_number - 1 ) ;
} else {
// sprite
Process_image ( & sort_list [ sort_order [ j ] ] ) ;
}
2003-07-28 01:44:38 +00:00
}
}
2003-09-02 09:54:42 +00:00
void Send_fore_frames ( void ) { //Tony23Sept96
2003-07-28 01:44:38 +00:00
uint32 j ;
2003-09-02 09:54:42 +00:00
// could be none at all - theoretically at least
for ( j = 0 ; j < cur_fore ; j + + ) {
2003-07-28 01:44:38 +00:00
Process_image ( & fore_list [ j ] ) ;
}
}
2003-09-02 09:54:42 +00:00
void Send_fore_par0_frames ( void ) { //James23Jan97
2003-07-28 01:44:38 +00:00
uint32 j ;
2003-09-02 09:54:42 +00:00
// could be none at all - theoretically at least
for ( j = 0 ; j < cur_fgp0 ; j + + ) {
// frame attached to 1st foreground parallax
Process_image ( & fgp0_list [ j ] ) ;
2003-07-28 01:44:38 +00:00
}
}
2003-09-02 09:54:42 +00:00
void Send_fore_par1_frames ( void ) { //James23Jan97
2003-07-28 01:44:38 +00:00
uint32 j ;
2003-09-02 09:54:42 +00:00
// could be none at all - theoretically at least
for ( j = 0 ; j < cur_fgp1 ; j + + ) {
// frame attached to 2nd foreground parallax
Process_image ( & fgp1_list [ j ] ) ;
2003-07-28 01:44:38 +00:00
}
}
2003-09-02 09:54:42 +00:00
void Process_layer ( uint32 layer_number ) { //Tony24Sept96
uint8 * file ;
_layerHeader * layer_head ;
_spriteInfo spriteInfo ;
uint32 rv ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
uint32 current_layer_area = 0 ;
# endif
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// file points to 1st byte in the layer file
file = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// point to layer header
layer_head = FetchLayerHeader ( file , layer_number ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
spriteInfo . x = layer_head - > x ;
spriteInfo . y = layer_head - > y ;
spriteInfo . w = layer_head - > width ;
spriteInfo . scale = 0 ;
spriteInfo . scaledWidth = 0 ;
spriteInfo . scaledHeight = 0 ;
spriteInfo . h = layer_head - > height ;
spriteInfo . type = RDSPR_TRANS + RDSPR_RLE256FAST ;
spriteInfo . blend = 0 ;
spriteInfo . data = file + sizeof ( _standardHeader ) + layer_head - > offset ;
spriteInfo . colourTable = 0 ;
2003-07-28 01:44:38 +00:00
//------------------------------------------
// check for largest layer for debug info
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-07-28 01:44:38 +00:00
current_layer_area = layer_head - > width * layer_head - > height ;
2003-09-02 09:54:42 +00:00
if ( current_layer_area > largest_layer_area ) {
2003-07-28 01:44:38 +00:00
largest_layer_area = current_layer_area ;
2003-09-02 09:54:42 +00:00
sprintf ( largest_layer_info ,
" largest layer: %s layer(%d) is %dx%d " ,
FetchObjectName ( this_screen . background_layer_id ) ,
layer_number , layer_head - > width , layer_head - > height ) ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
//------------------------------------------
2003-09-02 09:54:42 +00:00
rv = DrawSprite ( & spriteInfo ) ;
2003-07-28 01:44:38 +00:00
if ( rv )
ExitWithReport ( " Driver Error %.8x in Process_layer(%d) [%s line %u] " , rv , layer_number , __FILE__ , __LINE__ ) ;
res_man . Res_close ( this_screen . background_layer_id ) ;
}
2003-09-02 09:54:42 +00:00
void Process_image ( buildit * build_unit ) { // (5nov96 JEL)
uint8 * file , * colTablePtr = NULL ;
_animHeader * anim_head ;
_frameHeader * frame_head ;
_cdtEntry * cdt_entry ;
_spriteInfo spriteInfo ;
uint32 spriteType ;
uint32 rv ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
uint32 current_sprite_area = 0 ;
# endif
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// open anim resource file & point to base
file = res_man . Res_open ( build_unit - > anim_resource ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
anim_head = FetchAnimHeader ( file ) ;
cdt_entry = FetchCdtEntry ( file , build_unit - > anim_pc ) ;
frame_head = FetchFrameHeader ( file , build_unit - > anim_pc ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// so that 0-colour is transparent
spriteType = RDSPR_TRANS ;
2003-07-28 01:44:38 +00:00
if ( anim_head - > blend )
spriteType + = RDSPR_BLEND ;
2003-09-02 09:54:42 +00:00
// if the frame is to be flipped (only really applicable to frames
// using offsets)
if ( cdt_entry - > frameType & FRAME_FLIPPED )
2003-07-28 01:44:38 +00:00
spriteType + = RDSPR_FLIP ;
2003-09-02 09:54:42 +00:00
if ( cdt_entry - > frameType & FRAME_256_FAST ) {
// scaling, shading & blending don't work with RLE256FAST
// but the same compression can be decompressed using the
// RLE256 routines!
// NOTE: If this restriction refers to DrawSprite(), I don't
// think we have it any more. But I'm not sure.
if ( build_unit - > scale | | anim_head - > blend | | build_unit - > shadingFlag )
spriteType + = RDSPR_RLE256 ;
2003-07-28 01:44:38 +00:00
else
spriteType + = RDSPR_RLE256FAST ;
2003-09-02 09:54:42 +00:00
} else {
// what compression was used?
switch ( anim_head - > runTimeComp ) {
2003-09-21 16:11:26 +00:00
case NONE :
spriteType + = RDSPR_NOCOMPRESSION ;
break ;
case RLE256 :
spriteType + = RDSPR_RLE256 ;
break ;
case RLE16 :
spriteType + = RDSPR_RLE16 ;
// points to just after last cdt_entry, ie.
// start of colour table
colTablePtr = ( uint8 * ) ( anim_head + 1 ) + anim_head - > noAnimFrames * sizeof ( _cdtEntry ) ;
break ;
2003-07-28 01:44:38 +00:00
}
}
2003-09-02 09:54:42 +00:00
// if we want this frame to be affected by the shading mask,
// add the status bit
if ( build_unit - > shadingFlag = = 1 )
spriteType + = RDSPR_SHADOW ;
spriteInfo . x = build_unit - > x ;
spriteInfo . y = build_unit - > y ;
spriteInfo . w = frame_head - > width ;
spriteInfo . h = frame_head - > height ;
spriteInfo . scale = build_unit - > scale ;
spriteInfo . scaledWidth = build_unit - > scaled_width ;
2003-07-28 01:44:38 +00:00
spriteInfo . scaledHeight = build_unit - > scaled_height ;
2003-09-02 09:54:42 +00:00
spriteInfo . type = spriteType ;
spriteInfo . blend = anim_head - > blend ;
// points to just after frame header, ie. start of sprite data
spriteInfo . data = ( uint8 * ) ( frame_head + 1 ) ;
2003-07-28 01:44:38 +00:00
spriteInfo . colourTable = colTablePtr ;
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-07-28 01:44:38 +00:00
//------------------------------------------
// check for largest layer for debug info
2003-09-02 09:54:42 +00:00
2003-07-28 01:44:38 +00:00
current_sprite_area = frame_head - > width * frame_head - > height ;
2003-09-02 09:54:42 +00:00
if ( current_sprite_area > largest_sprite_area ) {
2003-07-28 01:44:38 +00:00
largest_sprite_area = current_sprite_area ;
2003-09-02 09:54:42 +00:00
sprintf ( largest_sprite_info ,
" largest sprite: %s frame(%d) is %dx%d " ,
FetchObjectName ( build_unit - > anim_resource ) ,
build_unit - > anim_pc ,
frame_head - > width ,
frame_head - > height ) ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
if ( SYSTEM_TESTING_ANIMS ) { // see anims.cpp
// bring the anim into the visible screen
// but leave extra pixel at edge for box
if ( spriteInfo . x + spriteInfo . scaledWidth > = 639 )
spriteInfo . x = 639 - spriteInfo . scaledWidth ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
if ( spriteInfo . y + spriteInfo . scaledHeight > = 399 )
spriteInfo . y = 399 - spriteInfo . scaledHeight ;
2003-07-28 01:44:38 +00:00
if ( spriteInfo . x < 1 )
spriteInfo . x = 1 ;
if ( spriteInfo . y < 1 )
spriteInfo . y = 1 ;
2003-09-02 09:54:42 +00:00
// create box to surround sprite - just outside sprite box
rect_x1 = spriteInfo . x - 1 ;
2003-07-28 01:44:38 +00:00
rect_y1 = spriteInfo . y - 1 ;
rect_x2 = spriteInfo . x + spriteInfo . scaledWidth ;
rect_y2 = spriteInfo . y + spriteInfo . scaledHeight ;
}
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// #ifdef _SWORD2_DEBUG
// if (frame_head->width <= 1) {
2003-07-28 01:44:38 +00:00
// Zdebug(8,"WARNING: 1-pixel-wide frame found in %s (%d)", FetchObjectName(build_unit->anim_resource), build_unit->anim_resource);
// }
2003-09-02 09:54:42 +00:00
// #endif
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
rv = DrawSprite ( & spriteInfo ) ;
2003-07-28 01:44:38 +00:00
if ( rv )
ExitWithReport ( " Driver Error %.8x with sprite %s (%d) in Process_image [%s line %u] " , rv , FetchObjectName ( build_unit - > anim_resource ) , build_unit - > anim_resource , __FILE__ , __LINE__ ) ;
2003-09-02 09:54:42 +00:00
// release the anim resource
res_man . Res_close ( build_unit - > anim_resource ) ;
}
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
void Reset_render_lists ( void ) { //Tony18Sept96
// reset the sort lists - do this before a logic loop
// takes into account the fact that the start of the list is pre-built
// with the special sortable layers
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
uint32 j ;
cur_bgp0 = 0 ;
cur_bgp1 = 0 ;
cur_back = 0 ;
// beginning of sort list is setup with the special sort layers
cur_sort = this_screen . number_of_layers ;
cur_fore = 0 ;
cur_fgp0 = 0 ;
cur_fgp1 = 0 ;
if ( cur_sort ) {
// there are some layers - so rebuild the sort order
// positioning
for ( j = 0 ; j < cur_sort ; j + + )
sort_order [ j ] = j ; //rebuild the order list
}
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
void Sort_the_sort_list ( void ) { //Tony18Sept96
//sort the list
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
//cannot bubble sort 0 or 1 items!
if ( cur_sort < = 1 )
return ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
uint16 i , j , swap ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
for ( i = 0 ; i < cur_sort - 1 ; i + + ) {
for ( j = 0 ; j < cur_sort - 1 ; j + + ) {
//this > next then swap
if ( sort_list [ sort_order [ j ] ] . sort_y > sort_list [ sort_order [ j + 1 ] ] . sort_y ) {
swap = sort_order [ j ] ;
sort_order [ j ] = sort_order [ j + 1 ] ;
sort_order [ j + 1 ] = swap ;
}
}
}
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
void Register_frame ( int32 * params , buildit * build_unit ) { // (1nov96JEL)
// params: 0 pointer to mouse structure or NULL for no write to mouse
// list (non-zero means write sprite-shape to mouse list)
// 1 pointer to graphic structure
// 2 pointer to mega structure
Object_mega * ob_mega ;
Object_graphic * ob_graph ;
Object_mouse * ob_mouse ;
uint8 * file ;
_frameHeader * frame_head ;
_animHeader * anim_head ;
_cdtEntry * cdt_entry ;
int scale = 0 ;
2003-07-28 01:44:38 +00:00
//-------------------------------------------
// open animation file & set up the necessary pointers
2003-09-02 09:54:42 +00:00
ob_graph = ( Object_graphic * ) params [ 1 ] ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-07-28 01:44:38 +00:00
if ( ob_graph - > anim_resource = = 0 )
Con_fatal_error ( " ERROR: %s(%d) has no anim resource in Register_frame [line=%d file=%s] " , FetchObjectName ( ID ) , ID , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
file = res_man . Res_open ( ob_graph - > anim_resource ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
anim_head = FetchAnimHeader ( file ) ;
cdt_entry = FetchCdtEntry ( file , ob_graph - > anim_pc ) ;
frame_head = FetchFrameHeader ( file , ob_graph - > anim_pc ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
// update player graphic details for on-screen debug info
if ( ID = = CUR_PLAYER_ID ) {
playerGraphic . type = ob_graph - > type ;
playerGraphic . anim_resource = ob_graph - > anim_resource ;
// counting 1st frame as 'frame 1'
playerGraphic . anim_pc = ob_graph - > anim_pc + 1 ;
player_graphic_no_frames = anim_head - > noAnimFrames ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
//-------------------------------------------
// fill in the buildit structure for this frame
2003-09-02 09:54:42 +00:00
//retrieve the resource
build_unit - > anim_resource = ob_graph - > anim_resource ;
//retrieve the frame
build_unit - > anim_pc = ob_graph - > anim_pc ;
//not a layer
build_unit - > layer_number = 0 ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// Affected by shading mask?
2003-07-28 01:44:38 +00:00
if ( ob_graph - > type & SHADED_SPRITE )
2003-09-02 09:54:42 +00:00
build_unit - > shadingFlag = 1 ;
2003-07-28 01:44:38 +00:00
else
2003-09-02 09:54:42 +00:00
build_unit - > shadingFlag = 0 ;
2003-07-28 01:44:38 +00:00
//-------------------------------------------
// check if this frame has offsets ie. this is a scalable mega frame
2003-09-02 09:54:42 +00:00
if ( cdt_entry - > frameType & FRAME_OFFSET ) {
// param 2 is pointer to mega structure
ob_mega = ( Object_mega * ) params [ 2 ] ;
// calc scale at which to print the sprite, based on feet
// y-coord & scaling constants (NB. 'scale' is actually
// 256 * true_scale, to maintain accuracy)
// Ay+B gives 256 * scale ie. 256 * 256 * true_scale for even
// better accuracy, ie. scale = (Ay + B) / 256
scale = ( ob_mega - > scale_a * ob_mega - > feet_y + ob_mega - > scale_b ) / 256 ;
// calc final render coordinates (top-left of sprite), based
// on feet coords & scaled offsets
// add scaled offsets to feet coords
build_unit - > x = ob_mega - > feet_x + ( cdt_entry - > x * scale ) / 256 ;
build_unit - > y = ob_mega - > feet_y + ( cdt_entry - > y * scale ) / 256 ;
2003-07-28 01:44:38 +00:00
// work out new width and height
2003-09-02 09:54:42 +00:00
// always divide by 256 after everything else, to maintain
// accurary
build_unit - > scaled_width = ( ( scale * frame_head - > width ) / 256 ) ;
build_unit - > scaled_height = ( ( scale * frame_head - > height ) / 256 ) ;
} else {
// it's a non-scaling anim
2003-07-28 01:44:38 +00:00
// get render coords for sprite, from cdt
2003-09-02 09:54:42 +00:00
build_unit - > x = cdt_entry - > x ;
build_unit - > y = cdt_entry - > y ;
2003-07-28 01:44:38 +00:00
// get width and height
2003-09-02 09:54:42 +00:00
build_unit - > scaled_width = frame_head - > width ;
build_unit - > scaled_height = frame_head - > height ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// either 0 or required scale, depending on whether 'scale' computed
build_unit - > scale = scale ;
2003-07-28 01:44:38 +00:00
// calc the bottom y-coord for sorting purposes
2003-09-02 09:54:42 +00:00
build_unit - > sort_y = build_unit - > y + build_unit - > scaled_height - 1 ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
if ( params [ 0 ] ) {
// passed a mouse structure, so add to the mouse_list
2003-07-28 01:44:38 +00:00
ob_mouse = ( Object_mouse * ) params [ 0 ] ;
2003-09-02 09:54:42 +00:00
// only if 'pointer' isn't NULL (James13feb97)
if ( ob_mouse - > pointer ) {
# ifdef _SWORD2_DEBUG
if ( cur_mouse = = TOTAL_mouse_list )
2003-07-28 01:44:38 +00:00
Con_fatal_error ( " ERROR: mouse_list full [%s line %u] " , __FILE__ , __LINE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
mouse_list [ cur_mouse ] . x1 = build_unit - > x ;
mouse_list [ cur_mouse ] . y1 = build_unit - > y ;
mouse_list [ cur_mouse ] . x2 = build_unit - > x + build_unit - > scaled_width ;
mouse_list [ cur_mouse ] . y2 = build_unit - > y + build_unit - > scaled_height ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
mouse_list [ cur_mouse ] . priority = ob_mouse - > priority ;
mouse_list [ cur_mouse ] . pointer = ob_mouse - > pointer ;
2003-07-28 01:44:38 +00:00
// (James17jun97)
2003-09-02 09:54:42 +00:00
// check if pointer text field is set due to previous
// object using this slot (ie. not correct for this
// one)
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// if 'pointer_text' field is set, but the 'id' field
// isn't same is current id
// then we don't want this "left over" pointer text
if ( mouse_list [ cur_mouse ] . pointer_text & & mouse_list [ cur_mouse ] . id ! = ( int32 ) ID )
mouse_list [ cur_mouse ] . pointer_text = 0 ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
mouse_list [ cur_mouse ] . id = ID ;
// not using sprite as detection mask
mouse_list [ cur_mouse ] . anim_resource = 0 ;
mouse_list [ cur_mouse ] . anim_pc = 0 ;
2003-07-28 01:44:38 +00:00
cur_mouse + + ;
}
}
2003-09-02 09:54:42 +00:00
// close animation file
res_man . Res_close ( ob_graph - > anim_resource ) ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
int32 FN_register_frame ( int32 * params ) { // (27nov96 JEL)
2003-07-28 01:44:38 +00:00
//this call would be made from an objects service script 0
2003-09-02 09:54:42 +00:00
// params: 0 pointer to mouse structure or NULL for no write to mouse
// list (non-zero means write sprite-shape to mouse list)
// 1 pointer to graphic structure
// 2 pointer to mega structure or NULL if not a mega
2003-07-28 01:44:38 +00:00
Object_graphic * ob_graph = ( Object_graphic * ) params [ 1 ] ;
2003-09-02 09:54:42 +00:00
// check low word for sprite type
switch ( ob_graph - > type & 0x0000ffff ) {
2003-09-21 16:11:26 +00:00
case BGP0_SPRITE :
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-09-21 16:11:26 +00:00
if ( cur_bgp0 = = MAX_bgp0_sprites )
Con_fatal_error ( " ERROR: bgp0_list full in FN_register_frame [line=%d file=%s] " , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-21 16:11:26 +00:00
Register_frame ( params , & bgp0_list [ cur_bgp0 ] ) ;
cur_bgp0 + + ;
break ;
case BGP1_SPRITE :
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-09-21 16:11:26 +00:00
if ( cur_bgp1 = = MAX_bgp1_sprites )
Con_fatal_error ( " ERROR: bgp1_list full in FN_register_frame [line=%d file=%s] " , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-21 16:11:26 +00:00
Register_frame ( params , & bgp1_list [ cur_bgp1 ] ) ;
cur_bgp1 + + ;
break ;
case BACK_SPRITE :
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-09-21 16:11:26 +00:00
if ( cur_back = = MAX_back_sprites )
Con_fatal_error ( " ERROR: back_list full in FN_register_frame [line=%d file=%s] " , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-21 16:11:26 +00:00
Register_frame ( params , & back_list [ cur_back ] ) ;
cur_back + + ;
break ;
case SORT_SPRITE :
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-09-21 16:11:26 +00:00
if ( cur_sort = = MAX_sort_sprites )
Con_fatal_error ( " ERROR: sort_list full in FN_register_frame [line=%d file=%s] " , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-21 16:11:26 +00:00
sort_order [ cur_sort ] = cur_sort ;
Register_frame ( params , & sort_list [ cur_sort ] ) ;
cur_sort + + ;
break ;
case FORE_SPRITE :
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-09-21 16:11:26 +00:00
if ( cur_fore = = MAX_fore_sprites )
Con_fatal_error ( " ERROR: fore_list full in FN_register_frame [line=%d file=%s] " , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-21 16:11:26 +00:00
Register_frame ( params , & fore_list [ cur_fore ] ) ;
cur_fore + + ;
break ;
case FGP0_SPRITE :
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-09-21 16:11:26 +00:00
if ( cur_fgp0 = = MAX_fgp0_sprites )
Con_fatal_error ( " ERROR: fgp0_list full in FN_register_frame [line=%d file=%s] " , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-21 16:11:26 +00:00
Register_frame ( params , & fgp0_list [ cur_fgp0 ] ) ;
cur_fgp0 + + ;
break ;
case FGP1_SPRITE :
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-09-21 16:11:26 +00:00
if ( cur_fgp1 = = MAX_fgp1_sprites )
Con_fatal_error ( " ERROR: fgp1_list full in FN_register_frame [line=%d file=%s] " , __LINE__ , __FILE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
2003-07-28 01:44:38 +00:00
2003-09-21 16:11:26 +00:00
Register_frame ( params , & fgp1_list [ cur_fgp1 ] ) ;
cur_fgp1 + + ;
break ;
default :
// NO_SPRITE no registering!
break ;
2003-09-02 09:54:42 +00:00
}
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
return IR_CONT ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
void Start_new_palette ( void ) { //Tony25Sept96
2003-07-28 01:44:38 +00:00
//start layer palette fading up
uint8 * screenFile ;
2003-09-02 09:54:42 +00:00
// if the screen is still fading down then wait for black - could
// happen when everythings cached into a large memory model
2003-09-09 12:14:08 +00:00
WaitForFade ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// open the screen file
screenFile = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
UpdatePaletteMatchTable ( ( uint8 * ) FetchPaletteMatchTable ( screenFile ) ) ;
2003-08-23 14:42:37 +00:00
BS2_SetPalette ( 0 , 256 , FetchPalette ( screenFile ) , RDPAL_FADE ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// indicating that it's a screen palette
lastPaletteRes = 0 ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// close screen file
res_man . Res_close ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// start fade up
// FadeUp((float) 1.75);
FadeUp ( ( float ) 0.75 ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// reset
this_screen . new_palette = 0 ;
}
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
int32 FN_update_player_stats ( int32 * params ) { //Tony28Nov96
//engine needs to know certain info about the player
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
Object_mega * ob_mega = ( Object_mega * ) params [ 0 ] ;
2003-07-28 01:44:38 +00:00
this_screen . player_feet_x = ob_mega - > feet_x ;
this_screen . player_feet_y = ob_mega - > feet_y ;
2003-09-02 09:54:42 +00:00
//for the script
PLAYER_FEET_X = ob_mega - > feet_x ;
PLAYER_FEET_Y = ob_mega - > feet_y ;
PLAYER_CUR_DIR = ob_mega - > current_dir ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
SCROLL_OFFSET_X = this_screen . scroll_offset_x ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// Zdebug(42,"%d %d", ob_mega->feet_x, ob_mega->feet_y);
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
return IR_CONT ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
int32 FN_fade_down ( int32 * params ) { //Tony5Dec96
// NONE means up! can only be called when screen is fully faded up -
// multiple calls wont have strange effects
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
if ( GetFadeStatus ( ) = = RDFADE_NONE )
FadeDown ( ( float ) 0.75 ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
return IR_CONT ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
int32 FN_fade_up ( int32 * params ) { //Chris 15May97
2003-09-09 12:14:08 +00:00
WaitForFade ( ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
if ( GetFadeStatus ( ) = = RDFADE_BLACK )
FadeUp ( ( float ) 0.75 ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
return IR_CONT ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
// ---------------------------------------------------------------------------
// typedef struct {
// uint8 red;
// uint8 green;
// uint8 blue;
// uint8 alpha;
// } _palEntry;
// ---------------------------------------------------------------------------
// typedef struct {
// // first colour number in this palette (0..255)
// uint8 firstEntry;
// // number of Entries-1 (0..255) to be taken as (1..256)
// uint8 noEntries;
// } _paletteHeader;
int32 FN_set_palette ( int32 * params ) { // James05jun97
SetFullPalette ( params [ 0 ] ) ;
return IR_CONT ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
void SetFullPalette ( int32 palRes ) { // James17jun97
2003-07-28 01:44:38 +00:00
// params 0 resource number of palette file
2003-09-02 09:54:42 +00:00
// or 0 if it's to be the palette from the current screen
2003-07-28 01:44:38 +00:00
uint8 * file ;
_standardHeader * head ;
//----------------------------------
// fudge for hut interior
2003-09-02 09:54:42 +00:00
// - unpausing should restore last palette as normal (could be screen
// palette or 'dark_palette_13')
// - but restoring the screen palette after 'dark_plaette_13' should
// now work properly too!
// hut interior
if ( LOCATION = = 13 ) {
// unpausing
if ( palRes = = - 1 ) {
// restore whatever palette was last set (screen
// palette or 'dark_palette_13')
palRes = lastPaletteRes ;
}
} else {
2003-07-28 01:44:38 +00:00
// (James 03sep97)
// check if we're just restoring the current screen palette
2003-09-02 09:54:42 +00:00
// because we might actually need to use a separate palette
// file anyway eg. for pausing & unpausing during the eclipse
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// unpausing (fudged for location 13)
if ( palRes = = - 1 ) {
// we really meant '0'
palRes = 0 ;
}
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
if ( palRes = = 0 & & lastPaletteRes )
2003-07-28 01:44:38 +00:00
palRes = lastPaletteRes ;
}
//----------------------------------
2003-09-02 09:54:42 +00:00
// non-zero: set palette to this separate palette file
if ( palRes ) {
// open the palette file
head = ( _standardHeader * ) res_man . Res_open ( palRes ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
# ifdef _SWORD2_DEBUG
2003-07-28 01:44:38 +00:00
if ( head - > fileType ! = PALETTE_FILE )
Con_fatal_error ( " FN_set_palette() called with invalid resource! (%s line %u) " , __FILE__ , __LINE__ ) ;
2003-09-02 09:54:42 +00:00
# endif
file = ( uint8 * ) ( head + 1 ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// always set colour 0 to black because most background screen
// palettes have a bright colour 0 although it should come out
// as black in the game!
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
file [ 0 ] = 0 ;
file [ 1 ] = 0 ;
file [ 2 ] = 0 ;
2003-07-28 01:44:38 +00:00
file [ 3 ] = 0 ;
2003-09-02 09:54:42 +00:00
// not yet in separate palette files
// UpdatePaletteMatchTable(file + (256 * 4));
2003-07-28 01:44:38 +00:00
2003-08-23 14:42:37 +00:00
BS2_SetPalette ( 0 , 256 , file , RDPAL_INSTANT ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
if ( palRes ! = CONTROL_PANEL_PALETTE ) { // (James 03sep97)
// indicating that it's a separate palette resource
lastPaletteRes = palRes ;
}
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// close palette file
res_man . Res_close ( palRes ) ;
} else {
// 0: set palette to current screen palette
if ( this_screen . background_layer_id ) {
// open the screen file
file = res_man . Res_open ( this_screen . background_layer_id ) ;
2003-07-28 01:44:38 +00:00
UpdatePaletteMatchTable ( ( uint8 * ) FetchPaletteMatchTable ( file ) ) ;
2003-08-23 14:42:37 +00:00
BS2_SetPalette ( 0 , 256 , FetchPalette ( file ) , RDPAL_INSTANT ) ;
2003-07-28 01:44:38 +00:00
2003-09-02 09:54:42 +00:00
// indicating that it's a screen palette
lastPaletteRes = 0 ;
// close screen file
res_man . Res_close ( this_screen . background_layer_id ) ;
} else
2003-07-28 01:44:38 +00:00
Con_fatal_error ( " FN_set_palette(0) called, but no current screen available! (%s line %u) " , __FILE__ , __LINE__ ) ;
}
}
2003-09-02 09:54:42 +00:00
int32 FN_restore_game ( int32 * params ) {
return IR_CONT ;
2003-07-28 01:44:38 +00:00
}
2003-09-02 09:54:42 +00:00
int32 FN_change_shadows ( int32 * params ) {
2003-07-28 01:44:38 +00:00
uint32 rv ;
2003-09-02 09:54:42 +00:00
// if last screen was using a shading mask (see below) (James 08apr97)
if ( this_screen . mask_flag ) {
2003-07-28 01:44:38 +00:00
rv = CloseLightMask ( ) ;
if ( rv )
ExitWithReport ( " Driver Error %.8x [%s line %u] " , rv , __FILE__ , __LINE__ ) ;
this_screen . mask_flag = 0 ;
}
2003-09-02 09:54:42 +00:00
return IR_CONT ;
2003-07-28 01:44:38 +00:00
}