2006-03-20 16:43:15 +00:00
/*
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
SOFTWARE CORPORATION ( " PARALLAX " ) . PARALLAX , IN DISTRIBUTING THE CODE TO
END - USERS , AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN , GRANTS A
ROYALTY - FREE , PERPETUAL LICENSE TO SUCH END - USERS FOR USE BY SUCH END - USERS
IN USING , DISPLAYING , AND CREATING DERIVATIVE WORKS THEREOF , SO LONG AS
SUCH USE , DISPLAY OR CREATION IS FOR NON - COMMERCIAL , ROYALTY OR REVENUE
FREE PURPOSES . IN NO EVENT SHALL THE END - USER USE THE COMPUTER CODE
CONTAINED HEREIN FOR REVENUE - BEARING PURPOSES . THE END - USER UNDERSTANDS
2009-08-22 07:21:19 +00:00
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE .
2006-03-20 16:43:15 +00:00
COPYRIGHT 1993 - 1998 PARALLAX SOFTWARE CORPORATION . ALL RIGHTS RESERVED .
*/
2008-04-06 20:23:28 +00:00
2006-03-20 16:43:15 +00:00
/*
2008-04-06 20:23:28 +00:00
*
2006-03-20 16:43:15 +00:00
* Functions to save / restore game state .
2008-04-06 20:23:28 +00:00
*
2006-03-20 16:43:15 +00:00
*/
# include <stdio.h>
# include <stdlib.h>
# include <math.h>
# include <string.h>
2009-08-22 07:21:19 +00:00
# include "pstypes.h"
2006-03-20 16:43:15 +00:00
# include "inferno.h"
# include "segment.h"
# include "textures.h"
# include "wall.h"
# include "object.h"
# include "gamemine.h"
# include "error.h"
2009-08-22 07:21:19 +00:00
# include "gamefont.h"
2006-03-20 16:43:15 +00:00
# include "gameseg.h"
# include "switch.h"
# include "game.h"
# include "newmenu.h"
2006-09-04 22:22:54 +00:00
# include "cfile.h"
2006-03-20 16:43:15 +00:00
# include "fuelcen.h"
# include "hash.h"
# include "key.h"
# include "piggy.h"
# include "player.h"
# include "cntrlcen.h"
# include "morph.h"
# include "weapon.h"
# include "render.h"
# include "gameseq.h"
# include "gauges.h"
# include "newdemo.h"
# include "automap.h"
# include "piggy.h"
# include "paging.h"
# include "titles.h"
# include "text.h"
# include "mission.h"
# include "pcx.h"
# include "u_mem.h"
# include "args.h"
2009-08-22 07:21:19 +00:00
# include "ai.h"
# include "state.h"
2009-03-20 12:10:38 +00:00
# include "multi.h"
2009-08-22 07:21:19 +00:00
# include "gr.h"
2009-09-11 05:15:53 +00:00
# ifdef OGL
# include "ogl_init.h"
2006-03-20 16:43:15 +00:00
# endif
2008-01-23 17:25:09 +00:00
# include "physfsx.h"
2006-03-20 16:43:15 +00:00
# define STATE_VERSION 7
# define STATE_COMPATIBLE_VERSION 6
// 0 - Put DGSS (Descent Game State Save) id at tof.
// 1 - Added Difficulty level save
// 2 - Added Cheats_enabled flag
// 3 - Added between levels save.
// 4 - Added mission support
// 5 - Mike changed ai and object structure.
// 6 - Added buggin' cheat save
// 7 - Added other cheat saves and game_id.
# define NUM_SAVES 10
# define THUMBNAIL_W 100
# define THUMBNAIL_H 50
# define DESC_LENGTH 20
extern int Do_appearance_effect ;
extern int Laser_rapid_fire , Ugly_robot_cheat , Ugly_robot_texture ;
extern int Physics_cheat_flag ;
2009-08-22 07:21:19 +00:00
extern int Lunacy ;
2006-03-20 16:43:15 +00:00
extern void do_lunacy_on ( void ) ;
extern void do_lunacy_off ( void ) ;
int state_save_all_sub ( char * filename , char * desc , int between_levels ) ;
2007-10-31 00:49:24 +00:00
int state_restore_all_sub ( char * filename ) ;
2006-03-20 16:43:15 +00:00
int sc_last_item = 0 ;
char dgss_id [ 4 ] = " DGSS " ;
uint state_game_id ;
2006-08-13 16:23:43 +00:00
2009-08-22 07:21:19 +00:00
//-------------------------------------------------------------------
2010-01-07 14:49:07 +00:00
int state_callback ( newmenu * menu , d_event * event , grs_bitmap * sc_bmp [ ] )
2006-03-20 16:43:15 +00:00
{
2010-01-07 14:49:07 +00:00
newmenu_item * items = newmenu_get_items ( menu ) ;
int citem = newmenu_get_citem ( menu ) ;
2006-03-20 16:43:15 +00:00
2010-01-30 03:24:19 +00:00
if ( ( citem > 0 ) & & ( event - > type = = EVENT_NEWMENU_DRAW ) )
2008-02-24 14:41:27 +00:00
{
if ( sc_bmp [ citem - 1 ] ) {
grs_canvas * save_canv = grd_curcanv ;
grs_canvas * temp_canv = gr_create_canvas ( THUMBNAIL_W * 2 , ( THUMBNAIL_H * 24 / 10 ) ) ;
grs_point vertbuf [ 3 ] = { { 0 , 0 } , { 0 , 0 } , { i2f ( THUMBNAIL_W * 2 ) , i2f ( THUMBNAIL_H * 24 / 10 ) } } ;
gr_set_current_canvas ( temp_canv ) ;
scale_bitmap ( sc_bmp [ citem - 1 ] , vertbuf ) ;
gr_set_current_canvas ( save_canv ) ;
2006-08-13 15:52:49 +00:00
# ifndef OGL
2008-02-24 14:41:27 +00:00
gr_bitmap ( ( grd_curcanv - > cv_bitmap . bm_w - THUMBNAIL_W * 2 ) / 2 , items [ 0 ] . y - 3 , & temp_canv - > cv_bitmap ) ;
2006-08-13 15:52:49 +00:00
# else
2010-09-19 11:53:39 +00:00
ogl_ubitmapm_cs ( ( grd_curcanv - > cv_bitmap . bm_w / 2 ) - FSPACX ( THUMBNAIL_W / 2 ) , items [ 0 ] . y - FSPACY ( 3 ) , FSPACX ( THUMBNAIL_W ) , FSPACY ( THUMBNAIL_H ) , & temp_canv - > cv_bitmap , - 1 , F1_0 ) ;
2006-08-13 15:52:49 +00:00
# endif
2008-02-24 14:41:27 +00:00
gr_free_canvas ( temp_canv ) ;
2006-03-20 16:43:15 +00:00
}
2010-01-07 14:49:07 +00:00
return 1 ;
2008-02-24 14:41:27 +00:00
}
2010-01-07 14:49:07 +00:00
return 0 ;
2006-03-20 16:43:15 +00:00
}
2006-10-06 00:12:16 +00:00
#if 0
2006-03-20 16:43:15 +00:00
void rpad_string ( char * string , int max_chars )
{
int i , end_found ;
end_found = 0 ;
for ( i = 0 ; i < max_chars ; i + + ) {
if ( * string = = 0 )
end_found = 1 ;
if ( end_found )
* string = ' ' ;
string + + ;
}
* string = 0 ; // NULL terminate
}
2006-10-06 00:12:16 +00:00
# endif
2006-03-20 16:43:15 +00:00
2010-07-19 17:07:12 +00:00
static int state_default_item = 0 ;
//Since state_default_item should ALWAYS point to a valid savegame slot, we use this to check if we once already actually SAVED a game. If yes, state_quick_item will be equal state_default_item, otherwise it should be -1 on every new mission and tell us we need to select a slot for quicksave.
int state_quick_item = - 1 ;
2010-02-25 03:08:10 +00:00
2006-03-20 16:43:15 +00:00
/* Present a menu for selection of a savegame filename.
* For saving , dsc should be a pre - allocated buffer into which the new
* savegame description will be stored .
* For restoring , dsc should be NULL , in which case empty slots will not be
* selectable and savagames descriptions will not be editable .
*/
2010-02-25 03:08:10 +00:00
int state_get_savegame_filename ( char * fname , char * dsc , char * caption , int blind_save )
2006-03-20 16:43:15 +00:00
{
2008-01-23 17:25:09 +00:00
PHYSFS_file * fp ;
2006-03-20 16:43:15 +00:00
int i , choice , version , nsaves ;
newmenu_item m [ NUM_SAVES + 1 ] ;
2008-04-24 14:27:54 +00:00
char filename [ NUM_SAVES ] [ FILENAME_LEN + 9 ] ;
2006-03-20 16:43:15 +00:00
char desc [ NUM_SAVES ] [ DESC_LENGTH + 16 ] ;
2010-01-07 14:49:07 +00:00
grs_bitmap * sc_bmp [ NUM_SAVES ] ;
2006-03-20 16:43:15 +00:00
char id [ 5 ] ;
int valid ;
nsaves = 0 ;
2006-09-04 22:22:54 +00:00
m [ 0 ] . type = NM_TYPE_TEXT ; m [ 0 ] . text = " \n \n \n \n " ;
2006-03-20 16:43:15 +00:00
for ( i = 0 ; i < NUM_SAVES ; i + + ) {
sc_bmp [ i ] = NULL ;
2007-10-31 00:49:24 +00:00
sprintf ( filename [ i ] , GameArg . SysUsePlayersDir ? " Players/%s.sg%x " : " %s.sg%x " , Players [ Player_num ] . callsign , i ) ;
2006-03-20 16:43:15 +00:00
valid = 0 ;
2008-01-23 17:25:09 +00:00
fp = PHYSFSX_openReadBuffered ( filename [ i ] ) ;
2006-03-20 16:43:15 +00:00
if ( fp ) {
//Read id
2008-01-23 17:25:09 +00:00
PHYSFS_read ( fp , id , sizeof ( char ) * 4 , 1 ) ;
2006-03-20 16:43:15 +00:00
if ( ! memcmp ( id , dgss_id , 4 ) ) {
//Read version
2008-01-23 17:25:09 +00:00
PHYSFS_read ( fp , & version , sizeof ( int ) , 1 ) ;
2009-10-05 02:51:37 +00:00
if ( ( version > = STATE_COMPATIBLE_VERSION ) | | ( SWAPINT ( version ) > = STATE_COMPATIBLE_VERSION ) ) {
2006-03-20 16:43:15 +00:00
// Read description
2008-01-23 17:25:09 +00:00
PHYSFS_read ( fp , desc [ i ] , sizeof ( char ) * DESC_LENGTH , 1 ) ;
2006-03-20 16:43:15 +00:00
//rpad_string( desc[i], DESC_LENGTH-1 );
if ( dsc = = NULL ) m [ i + 1 ] . type = NM_TYPE_MENU ;
// Read thumbnail
sc_bmp [ i ] = gr_create_bitmap ( THUMBNAIL_W , THUMBNAIL_H ) ;
2008-01-23 17:25:09 +00:00
PHYSFS_read ( fp , sc_bmp [ i ] - > bm_data , THUMBNAIL_W * THUMBNAIL_H , 1 ) ;
2006-03-20 16:43:15 +00:00
nsaves + + ;
valid = 1 ;
2006-09-04 22:22:54 +00:00
}
2006-03-20 16:43:15 +00:00
}
2008-01-23 17:25:09 +00:00
PHYSFS_close ( fp ) ;
2006-03-20 16:43:15 +00:00
}
if ( ! valid ) {
strcpy ( desc [ i ] , TXT_EMPTY ) ;
//rpad_string( desc[i], DESC_LENGTH-1 );
if ( dsc = = NULL ) m [ i + 1 ] . type = NM_TYPE_TEXT ;
}
if ( dsc ! = NULL ) {
m [ i + 1 ] . type = NM_TYPE_INPUT_MENU ;
}
m [ i + 1 ] . text_len = DESC_LENGTH - 1 ;
m [ i + 1 ] . text = desc [ i ] ;
}
if ( dsc = = NULL & & nsaves < 1 ) {
nm_messagebox ( NULL , 1 , " Ok " , " No saved games were found! " ) ;
return 0 ;
}
sc_last_item = - 1 ;
2010-02-25 03:08:10 +00:00
2010-07-19 17:07:12 +00:00
if ( blind_save & & state_quick_item < 0 )
2010-02-25 03:08:10 +00:00
blind_save = 0 ; // haven't picked a slot yet
if ( blind_save )
choice = state_default_item + 1 ;
else
2010-04-03 07:24:50 +00:00
choice = newmenu_do2 ( NULL , caption , NUM_SAVES + 1 , m , ( int ( * ) ( newmenu * , d_event * , void * ) ) state_callback , sc_bmp , state_default_item + 1 , NULL ) ;
2006-03-20 16:43:15 +00:00
for ( i = 0 ; i < NUM_SAVES ; i + + ) {
if ( sc_bmp [ i ] )
gr_free_bitmap ( sc_bmp [ i ] ) ;
}
if ( choice > 0 ) {
2009-08-22 07:21:19 +00:00
strcpy ( fname , filename [ choice - 1 ] ) ;
2006-03-20 16:43:15 +00:00
if ( dsc ! = NULL ) strcpy ( dsc , desc [ choice - 1 ] ) ;
2010-07-19 17:07:12 +00:00
state_quick_item = state_default_item = choice - 1 ;
2006-03-20 16:43:15 +00:00
return choice ;
}
return 0 ;
}
2010-02-25 03:08:10 +00:00
int state_get_save_file ( char * fname , char * dsc , int blind_save )
2006-03-20 16:43:15 +00:00
{
2010-02-25 03:08:10 +00:00
return state_get_savegame_filename ( fname , dsc , " Save Game " , blind_save ) ;
2006-03-20 16:43:15 +00:00
}
2007-10-31 00:49:24 +00:00
int state_get_restore_file ( char * fname )
2006-03-20 16:43:15 +00:00
{
2010-02-25 03:08:10 +00:00
return state_get_savegame_filename ( fname , NULL , " Select Game to Restore " , 0 ) ;
2006-03-20 16:43:15 +00:00
}
int state_save_old_game ( int slotnum , char * sg_name , player * sg_player ,
int sg_difficulty_level , int sg_primary_weapon ,
int sg_secondary_weapon , int sg_next_level_num )
{
2007-06-11 09:06:14 +00:00
int i ;
2006-03-20 16:43:15 +00:00
int temp_int ;
ubyte temp_byte ;
char desc [ DESC_LENGTH + 1 ] ;
char filename [ 128 ] ;
grs_canvas * cnv ;
2008-01-23 17:25:09 +00:00
PHYSFS_file * fp ;
2007-03-22 11:32:22 +00:00
ubyte * pal ;
# ifdef OGL
2007-06-11 09:06:14 +00:00
int j ;
2007-03-22 11:32:22 +00:00
GLint gl_draw_buffer ;
# endif
2006-03-20 16:43:15 +00:00
2007-09-28 15:14:09 +00:00
sprintf ( filename , ( GameArg . SysUsePlayersDir ? " Players/%s.sg%d " : " %s.sg%d " ) , sg_player - > callsign , slotnum ) ;
2008-01-23 17:25:09 +00:00
fp = PHYSFSX_openWriteBuffered ( filename ) ;
2006-03-20 16:43:15 +00:00
if ( ! fp ) return 0 ;
//Save id
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , dgss_id , sizeof ( char ) * 4 , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save version
temp_int = STATE_VERSION ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save description
strncpy ( desc , sg_name , DESC_LENGTH ) ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , desc , sizeof ( char ) * DESC_LENGTH , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the current screen shot...
cnv = gr_create_canvas ( THUMBNAIL_W , THUMBNAIL_H ) ;
2007-03-22 11:32:22 +00:00
if ( cnv )
{
# ifdef OGL
ubyte * buf ;
int k ;
# endif
grs_canvas * cnv_save ;
cnv_save = grd_curcanv ;
2006-03-20 16:43:15 +00:00
gr_set_current_canvas ( cnv ) ;
2007-03-22 11:32:22 +00:00
render_frame ( 0 ) ;
# ifdef OGL
2008-01-23 17:25:09 +00:00
buf = d_malloc ( THUMBNAIL_W * THUMBNAIL_H * 3 ) ;
2007-03-22 11:32:22 +00:00
glGetIntegerv ( GL_DRAW_BUFFER , & gl_draw_buffer ) ;
glReadBuffer ( gl_draw_buffer ) ;
glReadPixels ( 0 , SHEIGHT - THUMBNAIL_H , THUMBNAIL_W , THUMBNAIL_H , GL_RGB , GL_UNSIGNED_BYTE , buf ) ;
k = THUMBNAIL_H ;
for ( i = 0 ; i < THUMBNAIL_W * THUMBNAIL_H ; i + + ) {
if ( ! ( j = i % THUMBNAIL_W ) )
k - - ;
cnv - > cv_bitmap . bm_data [ THUMBNAIL_W * k + j ] =
gr_find_closest_color ( buf [ 3 * i ] / 4 , buf [ 3 * i + 1 ] / 4 , buf [ 3 * i + 2 ] / 4 ) ;
2006-03-20 16:43:15 +00:00
}
2008-01-23 17:25:09 +00:00
d_free ( buf ) ;
2007-03-22 11:32:22 +00:00
# endif
pal = gr_palette ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , cnv - > cv_bitmap . bm_data , THUMBNAIL_W * THUMBNAIL_H , 1 ) ;
2007-03-22 11:32:22 +00:00
gr_set_current_canvas ( cnv_save ) ;
2006-03-20 16:43:15 +00:00
gr_free_canvas ( cnv ) ;
2007-03-22 11:32:22 +00:00
}
else
{
2006-03-20 16:43:15 +00:00
ubyte color = 0 ;
for ( i = 0 ; i < THUMBNAIL_W * THUMBNAIL_H ; i + + )
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & color , sizeof ( ubyte ) , 1 ) ;
2006-03-20 16:43:15 +00:00
}
// Save the Between levels flag...
temp_int = 1 ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the mission info...
2006-10-06 00:12:16 +00:00
# ifndef SHAREWARE
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , Current_mission_filename , 9 * sizeof ( char ) , 1 ) ;
2006-10-06 00:12:16 +00:00
# else
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , " \0 \0 \0 \0 \0 \0 \0 \0 " , 9 * sizeof ( char ) , 1 ) ;
2006-10-06 00:12:16 +00:00
# endif
2006-03-20 16:43:15 +00:00
//Save level info
temp_int = sg_player - > level ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
temp_int = sg_next_level_num ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save GameTime
temp_int = 0 ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( fix ) , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save player info
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & sg_player , sizeof ( player ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the current weapon info
temp_byte = sg_primary_weapon ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_byte , sizeof ( sbyte ) , 1 ) ;
2006-03-20 16:43:15 +00:00
temp_byte = sg_secondary_weapon ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_byte , sizeof ( sbyte ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the difficulty level
temp_int = sg_difficulty_level ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the Cheats_enabled
temp_int = 0 ;
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
temp_int = 0 ; // turbo mode
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & temp_int , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
2008-01-23 17:25:09 +00:00
PHYSFS_write ( fp , & state_game_id , sizeof ( uint ) , 1 ) ;
PHYSFS_write ( fp , & Laser_rapid_fire , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Ugly_robot_cheat , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Ugly_robot_texture , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Physics_cheat_flag , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Lunacy , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
2008-01-23 17:25:09 +00:00
PHYSFS_close ( fp ) ;
2006-03-20 16:43:15 +00:00
return 1 ;
}
2009-08-22 07:21:19 +00:00
// -----------------------------------------------------------------------------------
2010-02-25 03:08:10 +00:00
int state_save_all ( int between_levels , int blind_save )
2006-03-20 16:43:15 +00:00
{
2009-08-22 07:21:19 +00:00
int rval ;
char filename [ 128 ] , desc [ DESC_LENGTH + 1 ] ;
2006-03-20 16:43:15 +00:00
2009-08-22 07:21:19 +00:00
# ifdef NETWORK
2006-03-20 16:43:15 +00:00
if ( Game_mode & GM_MULTI ) {
return 0 ;
}
2006-10-06 00:12:16 +00:00
# endif
2006-03-20 16:43:15 +00:00
stop_time ( ) ;
2010-02-25 03:08:10 +00:00
if ( ! state_get_save_file ( filename , desc , blind_save ) )
{
2006-03-20 16:43:15 +00:00
start_time ( ) ;
return 0 ;
}
2008-01-23 17:25:09 +00:00
rval = state_save_all_sub ( filename , desc , between_levels ) ;
if ( rval )
2010-07-13 06:35:25 +00:00
HUD_init_message ( HM_DEFAULT , " Game saved " ) ;
2008-01-23 17:25:09 +00:00
return rval ;
2006-03-20 16:43:15 +00:00
}
int state_save_all_sub ( char * filename , char * desc , int between_levels )
{
int i , j ;
2009-08-22 07:21:19 +00:00
PHYSFS_file * fp ;
2006-03-20 16:43:15 +00:00
grs_canvas * cnv ;
2007-03-22 11:32:22 +00:00
ubyte * pal ;
# ifdef OGL
GLint gl_draw_buffer ;
# endif
2006-03-20 16:43:15 +00:00
2009-08-22 07:21:19 +00:00
# ifndef NDEBUG
if ( GameArg . SysUsePlayersDir & & strncmp ( filename , " Players/ " , 8 ) )
Int3 ( ) ;
# endif
2008-01-23 17:25:09 +00:00
fp = PHYSFSX_openWriteBuffered ( filename ) ;
2006-03-20 16:43:15 +00:00
if ( ! fp ) {
2009-08-22 07:21:19 +00:00
nm_messagebox ( NULL , 1 , TXT_OK , " Error writing savegame. \n Possibly out of disk \n space. " ) ;
2006-03-20 16:43:15 +00:00
start_time ( ) ;
return 0 ;
}
//Save id
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , dgss_id , sizeof ( char ) * 4 , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save version
i = STATE_VERSION ;
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & i , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save description
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , desc , sizeof ( char ) * DESC_LENGTH , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the current screen shot...
2009-08-22 07:21:19 +00:00
2006-03-20 16:43:15 +00:00
cnv = gr_create_canvas ( THUMBNAIL_W , THUMBNAIL_H ) ;
2007-03-22 11:32:22 +00:00
if ( cnv )
{
2006-03-20 16:43:15 +00:00
# ifdef OGL
2007-03-22 11:32:22 +00:00
ubyte * buf ;
int k ;
2006-03-20 16:43:15 +00:00
# endif
2007-03-22 11:32:22 +00:00
grs_canvas * cnv_save ;
cnv_save = grd_curcanv ;
gr_set_current_canvas ( cnv ) ;
render_frame ( 0 ) ;
2009-08-22 07:21:19 +00:00
# if defined(OGL)
2008-01-23 17:25:09 +00:00
buf = d_malloc ( THUMBNAIL_W * THUMBNAIL_H * 3 ) ;
2007-03-22 11:32:22 +00:00
glGetIntegerv ( GL_DRAW_BUFFER , & gl_draw_buffer ) ;
glReadBuffer ( gl_draw_buffer ) ;
glReadPixels ( 0 , SHEIGHT - THUMBNAIL_H , THUMBNAIL_W , THUMBNAIL_H , GL_RGB , GL_UNSIGNED_BYTE , buf ) ;
k = THUMBNAIL_H ;
for ( i = 0 ; i < THUMBNAIL_W * THUMBNAIL_H ; i + + ) {
if ( ! ( j = i % THUMBNAIL_W ) )
k - - ;
cnv - > cv_bitmap . bm_data [ THUMBNAIL_W * k + j ] =
gr_find_closest_color ( buf [ 3 * i ] / 4 , buf [ 3 * i + 1 ] / 4 , buf [ 3 * i + 2 ] / 4 ) ;
2006-03-20 16:43:15 +00:00
}
2008-01-23 17:25:09 +00:00
d_free ( buf ) ;
2007-03-22 11:32:22 +00:00
# endif
2009-08-22 07:21:19 +00:00
2007-03-22 11:32:22 +00:00
pal = gr_palette ;
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , cnv - > cv_bitmap . bm_data , THUMBNAIL_W * THUMBNAIL_H , 1 ) ;
2007-03-22 11:32:22 +00:00
gr_set_current_canvas ( cnv_save ) ;
2006-03-20 16:43:15 +00:00
gr_free_canvas ( cnv ) ;
2007-03-22 11:32:22 +00:00
}
else
{
2006-03-20 16:43:15 +00:00
ubyte color = 0 ;
for ( i = 0 ; i < THUMBNAIL_W * THUMBNAIL_H ; i + + )
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & color , sizeof ( ubyte ) , 1 ) ;
}
2006-03-20 16:43:15 +00:00
// Save the Between levels flag...
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & between_levels , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the mission info...
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , Current_mission_filename , 9 * sizeof ( char ) , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save level info
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Current_level_num , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Next_level_num , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save GameTime
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & GameTime , sizeof ( fix ) , 1 ) ;
2006-03-20 16:43:15 +00:00
//Save player info
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Players [ Player_num ] , sizeof ( player ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the current weapon info
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Primary_weapon , sizeof ( sbyte ) , 1 ) ;
PHYSFS_write ( fp , & Secondary_weapon , sizeof ( sbyte ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the difficulty level
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Difficulty_level , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
2009-08-22 07:21:19 +00:00
// Save cheats enabled
PHYSFS_write ( fp , & Cheats_enabled , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Game_turbo_mode , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
if ( ! between_levels ) {
//Finish all morph objects
for ( i = 0 ; i < = Highest_object_index ; i + + ) {
if ( ( Objects [ i ] . type ! = OBJ_NONE ) & & ( Objects [ i ] . render_type = = RT_MORPH ) ) {
morph_data * md ;
md = find_morph_data ( & Objects [ i ] ) ;
if ( md ) {
md - > obj - > control_type = md - > morph_save_control_type ;
md - > obj - > movement_type = md - > morph_save_movement_type ;
md - > obj - > render_type = RT_POLYOBJ ;
md - > obj - > mtype . phys_info = md - > morph_save_phys_info ;
md - > obj = NULL ;
} else { //maybe loaded half-morphed from disk
Objects [ i ] . flags | = OF_SHOULD_BE_DEAD ;
Objects [ i ] . render_type = RT_POLYOBJ ;
Objects [ i ] . control_type = CT_NONE ;
Objects [ i ] . movement_type = MT_NONE ;
}
}
}
//Save object info
i = Highest_object_index + 1 ;
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & i , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , Objects , sizeof ( object ) , i ) ;
2006-03-20 16:43:15 +00:00
//Save wall info
i = Num_walls ;
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & i , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , Walls , sizeof ( wall ) , i ) ;
2006-03-20 16:43:15 +00:00
//Save door info
i = Num_open_doors ;
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & i , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , ActiveDoors , sizeof ( active_door ) , i ) ;
2006-03-20 16:43:15 +00:00
//Save trigger info
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Num_triggers , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , Triggers , sizeof ( trigger ) , Num_triggers ) ;
2006-03-20 16:43:15 +00:00
//Save tmap info
2009-08-22 07:21:19 +00:00
for ( i = 0 ; i < = Highest_segment_index ; i + + )
{
for ( j = 0 ; j < 6 ; j + + )
{
PHYSFS_write ( fp , & Segments [ i ] . sides [ j ] . wall_num , sizeof ( short ) , 1 ) ;
PHYSFS_write ( fp , & Segments [ i ] . sides [ j ] . tmap_num , sizeof ( short ) , 1 ) ;
PHYSFS_write ( fp , & Segments [ i ] . sides [ j ] . tmap_num2 , sizeof ( short ) , 1 ) ;
2006-03-20 16:43:15 +00:00
}
}
// Save the fuelcen info
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Control_center_destroyed , sizeof ( int ) , 1 ) ;
2010-03-20 13:21:53 +00:00
PHYSFS_write ( fp , & Countdown_seconds_left , sizeof ( int ) , 1 ) ;
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Num_robot_centers , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , RobotCenters , sizeof ( matcen_info ) , Num_robot_centers ) ;
PHYSFS_write ( fp , & ControlCenterTriggers , sizeof ( control_center_triggers ) , 1 ) ;
PHYSFS_write ( fp , & Num_fuelcenters , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , Station , sizeof ( FuelCenter ) , Num_fuelcenters ) ;
2006-03-20 16:43:15 +00:00
// Save the control cen info
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & Control_center_been_hit , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Control_center_player_been_seen , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Control_center_next_fire_time , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Control_center_present , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Dead_controlcen_object_num , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
// Save the AI state
ai_save_state ( fp ) ;
// Save the automap visited info
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , Automap_visited , sizeof ( ubyte ) , MAX_SEGMENTS ) ;
2006-03-20 16:43:15 +00:00
}
2009-08-22 07:21:19 +00:00
PHYSFS_write ( fp , & state_game_id , sizeof ( uint ) , 1 ) ;
PHYSFS_write ( fp , & Laser_rapid_fire , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Ugly_robot_cheat , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Ugly_robot_texture , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Physics_cheat_flag , sizeof ( int ) , 1 ) ;
PHYSFS_write ( fp , & Lunacy , sizeof ( int ) , 1 ) ;
2006-03-20 16:43:15 +00:00
2008-01-23 17:25:09 +00:00
PHYSFS_close ( fp ) ;
2006-03-20 16:43:15 +00:00
start_time ( ) ;
return 1 ;
}
2009-08-22 07:21:19 +00:00
// -----------------------------------------------------------------------------------
2006-03-20 16:43:15 +00:00
int state_restore_all ( int in_game )
{
char filename [ 128 ] ;
2009-08-22 07:21:19 +00:00
# ifdef NETWORK
2006-03-20 16:43:15 +00:00
if ( Game_mode & GM_MULTI ) {
return 0 ;
}
2007-07-22 19:24:26 +00:00
# endif
2006-03-20 16:43:15 +00:00
if ( Newdemo_state = = ND_STATE_RECORDING )
newdemo_stop_recording ( ) ;
if ( Newdemo_state ! = ND_STATE_NORMAL )
return 0 ;
stop_time ( ) ;
2007-10-31 00:49:24 +00:00
if ( ! state_get_restore_file ( filename ) ) {
2006-03-20 16:43:15 +00:00
start_time ( ) ;
return 0 ;
}
if ( in_game ) {
int choice ;
choice = nm_messagebox ( NULL , 2 , " Yes " , " No " , " Restore Game? " ) ;
if ( choice ! = 0 ) {
start_time ( ) ;
return 0 ;
}
}
start_time ( ) ;
2007-10-31 00:49:24 +00:00
return state_restore_all_sub ( filename ) ;
2006-03-20 16:43:15 +00:00
}
2007-10-31 00:49:24 +00:00
int state_restore_all_sub ( char * filename )
2006-03-20 16:43:15 +00:00
{
int ObjectStartLocation ;
int BogusSaturnShit = 0 ;
int version , i , j , segnum ;
object * obj ;
2008-01-23 17:25:09 +00:00
PHYSFS_file * fp ;
2009-10-05 02:51:37 +00:00
int swap = 0 ; // if file is not endian native, have to swap all shorts and ints
2006-03-20 16:43:15 +00:00
int current_level , next_level ;
int between_levels ;
char mission [ 16 ] ;
char desc [ DESC_LENGTH + 1 ] ;
char id [ 5 ] ;
char org_callsign [ CALLSIGN_LEN + 16 ] ;
2009-08-22 07:21:19 +00:00
# ifndef NDEBUG
if ( GameArg . SysUsePlayersDir & & strncmp ( filename , " Players/ " , 8 ) )
Int3 ( ) ;
# endif
2008-01-23 17:25:09 +00:00
fp = PHYSFSX_openReadBuffered ( filename ) ;
2006-03-20 16:43:15 +00:00
if ( ! fp ) return 0 ;
//Read id
2009-08-22 07:21:19 +00:00
PHYSFS_read ( fp , id , sizeof ( char ) * 4 , 1 ) ;
2006-03-20 16:43:15 +00:00
if ( memcmp ( id , dgss_id , 4 ) ) {
2008-01-23 17:25:09 +00:00
PHYSFS_close ( fp ) ;
2006-03-20 16:43:15 +00:00
return 0 ;
}
//Read version
2009-10-05 02:51:37 +00:00
//Check for swapped file here, as dgss_id is written as a string (i.e. endian independent)
2009-08-22 07:21:19 +00:00
PHYSFS_read ( fp , & version , sizeof ( int ) , 1 ) ;
2009-10-05 02:51:37 +00:00
if ( version & 0xffff0000 )
{
swap = 1 ;
version = SWAPINT ( version ) ;
}
2006-03-20 16:43:15 +00:00
if ( version < STATE_COMPATIBLE_VERSION ) {
2008-01-23 17:25:09 +00:00
PHYSFS_close ( fp ) ;
2006-03-20 16:43:15 +00:00
return 0 ;
}
// Read description
2009-08-22 07:21:19 +00:00
PHYSFS_read ( fp , desc , sizeof ( char ) * DESC_LENGTH , 1 ) ;
2006-03-20 16:43:15 +00:00
// Skip the current screen shot...
2008-01-23 17:25:09 +00:00
PHYSFS_seek ( fp , PHYSFS_tell ( fp ) + THUMBNAIL_W * THUMBNAIL_H ) ;
2006-03-20 16:43:15 +00:00
// Read the Between levels flag...
2009-10-05 02:51:37 +00:00
between_levels = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
// Read the mission info...
2009-08-22 07:21:19 +00:00
PHYSFS_read ( fp , mission , sizeof ( char ) * 9 , 1 ) ;
2006-03-20 16:43:15 +00:00
if ( ! load_mission_by_name ( mission ) ) {
nm_messagebox ( NULL , 1 , " Ok " , " Error! \n Unable to load mission \n '%s' \n " , mission ) ;
2008-01-23 17:25:09 +00:00
PHYSFS_close ( fp ) ;
2006-03-20 16:43:15 +00:00
return 0 ;
}
//Read level info
2009-10-05 02:51:37 +00:00
current_level = PHYSFSX_readSXE32 ( fp , swap ) ;
next_level = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
//Restore GameTime
2009-10-05 02:51:37 +00:00
GameTime = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
// Start new game....
2007-10-31 00:49:24 +00:00
Game_mode = GM_NORMAL ;
2006-03-20 16:43:15 +00:00
# ifdef NETWORK
2007-10-31 00:49:24 +00:00
change_playernum_to ( 0 ) ;
2006-03-20 16:43:15 +00:00
# endif
2007-10-31 00:49:24 +00:00
strcpy ( org_callsign , Players [ 0 ] . callsign ) ;
N_players = 1 ;
InitPlayerObject ( ) ; //make sure player's object set up
init_player_stats_game ( ) ; //clear all stats
2010-07-30 17:59:21 +00:00
if ( Game_wind )
window_set_visible ( Game_wind , 0 ) ;
2006-03-20 16:43:15 +00:00
//Read player info
if ( between_levels ) {
int saved_offset ;
2009-10-05 02:51:37 +00:00
player_read_swap ( & Players [ Player_num ] , swap , fp ) ;
2008-01-23 17:25:09 +00:00
saved_offset = PHYSFS_tell ( fp ) ;
PHYSFS_close ( fp ) ;
2010-03-01 07:27:51 +00:00
do_briefing_screens ( Briefing_text_filename , next_level ) ;
2008-01-23 17:25:09 +00:00
fp = PHYSFSX_openReadBuffered ( filename ) ;
PHYSFS_seek ( fp , saved_offset ) ;
2006-03-20 16:43:15 +00:00
StartNewLevelSub ( next_level , 1 ) ; //use page_in_textures here to fix OGL texture precashing crash -MPM
} else {
StartNewLevelSub ( current_level , 1 ) ; //use page_in_textures here to fix OGL texture precashing crash -MPM
2009-10-05 02:51:37 +00:00
player_read_swap ( & Players [ Player_num ] , swap , fp ) ;
2006-03-20 16:43:15 +00:00
}
strcpy ( Players [ Player_num ] . callsign , org_callsign ) ;
// Set the right level
if ( between_levels )
Players [ Player_num ] . level = next_level ;
// Restore the weapon states
2008-01-23 17:25:09 +00:00
PHYSFS_read ( fp , & Primary_weapon , sizeof ( sbyte ) , 1 ) ;
PHYSFS_read ( fp , & Secondary_weapon , sizeof ( sbyte ) , 1 ) ;
2006-03-20 16:43:15 +00:00
select_weapon ( Primary_weapon , 0 , 0 , 0 ) ;
select_weapon ( Secondary_weapon , 1 , 0 , 0 ) ;
// Restore the difficulty level
2009-10-05 02:51:37 +00:00
Difficulty_level = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
// Restore the cheats enabled flag
2009-08-22 07:21:19 +00:00
2009-10-05 02:51:37 +00:00
Cheats_enabled = PHYSFSX_readSXE32 ( fp , swap ) ;
Game_turbo_mode = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
if ( ! between_levels ) {
Do_appearance_effect = 0 ; // Don't do this for middle o' game stuff.
2009-08-22 07:21:19 +00:00
ObjectStartLocation = PHYSFS_tell ( fp ) ;
2006-03-20 16:43:15 +00:00
RetryObjectLoading :
//Clear out all the objects from the lvl file
for ( segnum = 0 ; segnum < = Highest_segment_index ; segnum + + )
Segments [ segnum ] . objects = - 1 ;
reset_objects ( 1 ) ;
//Read objects, and pop 'em into their respective segments.
2009-10-05 02:51:37 +00:00
i = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
Highest_object_index = i - 1 ;
2009-10-05 02:51:37 +00:00
if ( ! BogusSaturnShit )
object_read_n_swap ( Objects , i , swap , fp ) ;
2006-03-20 16:43:15 +00:00
else {
ubyte tmp_object [ sizeof ( object ) ] ;
for ( i = 0 ; i < = Highest_object_index ; i + + ) {
2008-01-23 17:25:09 +00:00
PHYSFS_read ( fp , tmp_object , sizeof ( object ) - 3 , 1 ) ;
2009-10-05 02:51:37 +00:00
object_swap ( ( object * ) tmp_object , swap ) ;
2006-03-20 16:43:15 +00:00
// Insert 3 bytes after the read in obj->rtype.pobj_info.alt_textures field.
memcpy ( & Objects [ i ] , tmp_object , sizeof ( object ) - 3 ) ;
Objects [ i ] . rtype . pobj_info . alt_textures = - 1 ;
}
}
for ( i = 0 ; i < = Highest_object_index ; i + + ) {
obj = & Objects [ i ] ;
obj - > rtype . pobj_info . alt_textures = - 1 ;
segnum = obj - > segnum ;
obj - > next = obj - > prev = obj - > segnum = - 1 ;
if ( obj - > type ! = OBJ_NONE ) {
// Check for a bogus Saturn version!!!!
if ( ! BogusSaturnShit ) {
if ( ( segnum < 0 ) | | ( segnum > Highest_segment_index ) ) {
BogusSaturnShit = 1 ;
2008-01-23 17:25:09 +00:00
PHYSFS_seek ( fp , ObjectStartLocation ) ;
2006-03-20 16:43:15 +00:00
goto RetryObjectLoading ;
}
}
obj_link ( i , segnum ) ;
}
2010-02-08 13:24:42 +00:00
// If weapon, restore the most recent hitobj to the list
if ( obj - > type = = OBJ_WEAPON )
{
if ( obj - > ctype . laser_info . last_hitobj > 0 & & obj - > ctype . laser_info . last_hitobj < MAX_OBJECTS )
{
memset ( & hitobj_list [ i ] , 0 , sizeof ( ubyte ) * MAX_OBJECTS ) ;
hitobj_list [ i ] [ obj - > ctype . laser_info . last_hitobj ] = 1 ;
printf ( " RESTORE WEAPON[%i] LHO[%i] \n " , i , obj - > ctype . laser_info . last_hitobj ) ;
}
}
2006-03-20 16:43:15 +00:00
}
special_reset_objects ( ) ;
//Restore wall info
2009-10-05 02:51:37 +00:00
Num_walls = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
// Check for a bogus Saturn version!!!!
if ( ! BogusSaturnShit ) {
if ( ( Num_walls < 0 ) | | ( Num_walls > MAX_WALLS ) ) {
BogusSaturnShit = 1 ;
2008-01-23 17:25:09 +00:00
PHYSFS_seek ( fp , ObjectStartLocation ) ;
2006-03-20 16:43:15 +00:00
goto RetryObjectLoading ;
}
}
2009-10-05 02:51:37 +00:00
wall_read_n_swap ( Walls , Num_walls , swap , fp ) ;
2006-03-20 16:43:15 +00:00
// Check for a bogus Saturn version!!!!
if ( ! BogusSaturnShit ) {
for ( i = 0 ; i < Num_walls ; i + + ) {
if ( ( Walls [ i ] . segnum < 0 ) | | ( Walls [ i ] . segnum > Highest_segment_index ) | | ( Walls [ i ] . sidenum < - 1 ) | | ( Walls [ i ] . sidenum > 5 ) ) {
BogusSaturnShit = 1 ;
2008-01-23 17:25:09 +00:00
PHYSFS_seek ( fp , ObjectStartLocation ) ;
2006-03-20 16:43:15 +00:00
goto RetryObjectLoading ;
}
}
}
2009-08-22 07:21:19 +00:00
2006-03-20 16:43:15 +00:00
//Restore door info
2009-10-05 02:51:37 +00:00
Num_open_doors = PHYSFSX_readSXE32 ( fp , swap ) ;
active_door_read_n_swap ( ActiveDoors , Num_open_doors , swap , fp ) ;
2006-03-20 16:43:15 +00:00
//Restore trigger info
2009-10-05 02:51:37 +00:00
Num_triggers = PHYSFSX_readSXE32 ( fp , swap ) ;
trigger_read_n_swap ( Triggers , Num_triggers , swap , fp ) ;
2006-03-20 16:43:15 +00:00
//Restore tmap info
for ( i = 0 ; i < = Highest_segment_index ; i + + ) {
for ( j = 0 ; j < 6 ; j + + ) {
2009-10-05 02:51:37 +00:00
Segments [ i ] . sides [ j ] . wall_num = PHYSFSX_readSXE16 ( fp , swap ) ;
Segments [ i ] . sides [ j ] . tmap_num = PHYSFSX_readSXE16 ( fp , swap ) ;
Segments [ i ] . sides [ j ] . tmap_num2 = PHYSFSX_readSXE16 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
}
}
//Restore the fuelcen info
2009-10-05 02:51:37 +00:00
Control_center_destroyed = PHYSFSX_readSXE32 ( fp , swap ) ;
2010-03-20 13:21:53 +00:00
Countdown_seconds_left = PHYSFSX_readSXE32 ( fp , swap ) ;
2009-10-05 02:51:37 +00:00
Num_robot_centers = PHYSFSX_readSXE32 ( fp , swap ) ;
matcen_info_read_n_swap ( RobotCenters , Num_robot_centers , swap , fp ) ;
control_center_triggers_read_n_swap ( & ControlCenterTriggers , 1 , swap , fp ) ;
Num_fuelcenters = PHYSFSX_readSXE32 ( fp , swap ) ;
fuelcen_read_n_swap ( Station , Num_fuelcenters , swap , fp ) ;
2006-03-20 16:43:15 +00:00
// Restore the control cen info
2009-10-05 02:51:37 +00:00
Control_center_been_hit = PHYSFSX_readSXE32 ( fp , swap ) ;
Control_center_player_been_seen = PHYSFSX_readSXE32 ( fp , swap ) ;
Control_center_next_fire_time = PHYSFSX_readSXE32 ( fp , swap ) ;
Control_center_present = PHYSFSX_readSXE32 ( fp , swap ) ;
Dead_controlcen_object_num = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
// Restore the AI state
2009-10-05 02:51:37 +00:00
ai_restore_state ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
// Restore the automap visited info
2008-01-23 17:25:09 +00:00
PHYSFS_read ( fp , Automap_visited , sizeof ( ubyte ) , MAX_SEGMENTS ) ;
2006-03-20 16:43:15 +00:00
// Restore hacked up weapon system stuff.
Auto_fire_fusion_cannon_time = 0 ;
Next_laser_fire_time = GameTime ;
Next_missile_fire_time = GameTime ;
Last_laser_fired_time = GameTime ;
}
state_game_id = 0 ;
if ( version > = 7 ) {
int tmp_Lunacy ;
2009-10-05 02:51:37 +00:00
state_game_id = PHYSFSX_readSXE32 ( fp , swap ) ;
Laser_rapid_fire = PHYSFSX_readSXE32 ( fp , swap ) ;
Ugly_robot_cheat = PHYSFSX_readSXE32 ( fp , swap ) ;
Ugly_robot_texture = PHYSFSX_readSXE32 ( fp , swap ) ;
Physics_cheat_flag = PHYSFSX_readSXE32 ( fp , swap ) ;
tmp_Lunacy = PHYSFSX_readSXE32 ( fp , swap ) ;
2006-03-20 16:43:15 +00:00
if ( tmp_Lunacy )
do_lunacy_on ( ) ;
}
2008-01-23 17:25:09 +00:00
PHYSFS_close ( fp ) ;
2006-03-20 16:43:15 +00:00
2010-07-30 17:59:21 +00:00
if ( Game_wind )
if ( ! window_is_visible ( Game_wind ) )
window_set_visible ( Game_wind , 1 ) ;
reset_time ( ) ;
2006-03-20 16:43:15 +00:00
return 1 ;
}