4294 lines
110 KiB
C++
4294 lines
110 KiB
C++
|
#include "game.h"
|
||
|
#include "ob.h"
|
||
|
#include "memory.h"
|
||
|
#include "fc.h"
|
||
|
#include "wmove.h"
|
||
|
#include "supermap.h"
|
||
|
#include "night.h"
|
||
|
#include "barrel.h"
|
||
|
#include "bike.h"
|
||
|
#include "eway.h"
|
||
|
#include "pap.h"
|
||
|
#include "ob.h"
|
||
|
#include "mav.h"
|
||
|
#include "road.h"
|
||
|
#include "balloon.h"
|
||
|
#include "tracks.h"
|
||
|
#include "ware.h"
|
||
|
#include "trip.h"
|
||
|
#include "psystem.h"
|
||
|
#include "env.h"
|
||
|
#include "bat.h"
|
||
|
#include "door.h"
|
||
|
#include "spark.h"
|
||
|
#ifndef PSX
|
||
|
#include "playcuts.h"
|
||
|
#endif
|
||
|
#include "eway.h"
|
||
|
#include "statedef.h"
|
||
|
#ifndef PSX
|
||
|
#include "poly.h"
|
||
|
#include "sound.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef PSX
|
||
|
#include <libsn.h>
|
||
|
#include <libcd.h>
|
||
|
#include <ctype.h>
|
||
|
#include "c:\fallen\psxlib\headers\myheap.h"
|
||
|
#endif
|
||
|
|
||
|
#ifdef PSX
|
||
|
#ifdef VERSION_PAL
|
||
|
|
||
|
#if !defined(MIKE)&&!defined(VERSION_DEMO)
|
||
|
#include "libcrypt.h"
|
||
|
UBYTE do_decrypt[]={0,0,0,0,0,0,0,1,0,1,
|
||
|
1,1,1,0,0,0,0,1,0,0,
|
||
|
1,0,0,1,0,0,0,0,0,0,
|
||
|
0,0,1,1,1,0};
|
||
|
#endif
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#ifndef PSX
|
||
|
#define NEW_LEVELS 1
|
||
|
#endif
|
||
|
|
||
|
//#define NEW_LEVELS 1
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef TARGET_DC
|
||
|
#include "target.h"
|
||
|
#endif
|
||
|
|
||
|
|
||
|
extern ULONG level_index;
|
||
|
/*
|
||
|
|
||
|
//
|
||
|
// e3.ucm 16 aug 99
|
||
|
//
|
||
|
|
||
|
MOSTspecialS 49
|
||
|
MOSTmeshS 138
|
||
|
MOSTtweenS 66
|
||
|
MOSTCARS 29
|
||
|
MOSTPEOPLE 66
|
||
|
|
||
|
SAVE INGAME
|
||
|
store data 4
|
||
|
Pap_Hi -> 98304 tot 98304 (16384)
|
||
|
Pap_Lo -> 8192 tot 106496 (1024)
|
||
|
net_peep -> 40 tot 106536 (10)
|
||
|
net_plyr -> 40 tot 106576 (10)
|
||
|
f-links -> 10666 tot 117242 (5333/32000)
|
||
|
dbuildings -> 4728 tot 121970 (197/1024)
|
||
|
dfacets -> 71968 tot 193938 (2768/16384)
|
||
|
dwalkables -> 5874 tot 199812 (267/2048)
|
||
|
dstyles -> 8746 tot 208558 (4373/10000)
|
||
|
dstoreys -> 3192 tot 211750 (532/10000)
|
||
|
paintmem -> 2379 tot 214129 (2379/64000)
|
||
|
insideStoreys -> 22 tot 214151 (1/2000)
|
||
|
insideStairs -> 10 tot 214161 (1/8000)
|
||
|
insideblock -> 1 tot 214162 (1/64000)
|
||
|
roof bounds -> 6 tot 214168 (1/2000)
|
||
|
prim_points -> 64170 tot 278338 (10695/65000)
|
||
|
prim face 4 psx = 98568 was 139638
|
||
|
prim_faces4 -> 98568 tot 376906 (4107/32760)
|
||
|
prim face3 psx = 131460 was 184044
|
||
|
prim_faces3 -> 131460 tot 508366 (6573/32000)
|
||
|
prim_objects -> 8928 tot 517294 (558/2000)
|
||
|
prim_Mobjects -> 136 tot 517430 (17/100)
|
||
|
ob_ob -> 5776 tot 523206 (722/2048)
|
||
|
ob_ mapwho -> 2048 tot 525254 (1024)
|
||
|
EWAY_mess -> 280 tot 525534 (70/128)
|
||
|
EWAY_mess buf -> 4651 tot 530185 (4651/8192)
|
||
|
EWAY_timer -> 0 tot 530185 (32)
|
||
|
EWAY_cond -> 114 tot 530299 (19/128)
|
||
|
EWAY_way -> 10272 tot 540571 (321/512)
|
||
|
EWAY_edef -> 900 tot 541471 (75/150)
|
||
|
EWAY_counter -> 10 tot 541481 (10)
|
||
|
vehicles -> 6120 tot 547601 (34)
|
||
|
people -> 11008 tot 558609 (86)
|
||
|
animals -> 120 tot 558729 (6)
|
||
|
choppers -> 336 tot 559065 (4)
|
||
|
pyro -> 2688 tot 561753 (32)
|
||
|
players -> 272 tot 562025 (2)
|
||
|
projectiles -> 80 tot 562105 (10)
|
||
|
special -> 1980 tot 564085 (99)
|
||
|
switches -> 56 tot 564141 (2)
|
||
|
bats -> 320 tot 564461 (10)
|
||
|
thing -> 23460 tot 587921 (391)
|
||
|
drawtween -> 4472 tot 592393 (86)
|
||
|
drawmesh -> 1680 tot 594073 (168)
|
||
|
barrelsphere -> 2240 tot 596313 (80)
|
||
|
barrels -> 354 tot 596667 (59/300)
|
||
|
plat -> 12 tot 596679 (1/32)
|
||
|
wmove -> 4608 tot 601287 (192)
|
||
|
mav_opt -> 3220 tot 604507 (805/1024)
|
||
|
mav_nav -> 32768 tot 637275 (16384)
|
||
|
road_noads -> 150 tot 637425 (25/256)
|
||
|
balloons -> 104 tot 637529 (1/32)
|
||
|
tracks -> 1600 tot 639129 (50)
|
||
|
roofface4 -> 31960 tot 671089 (3196/10000)
|
||
|
fastnav -> 2048 tot 673137 (2048)
|
||
|
night_slight -> 2048 tot 675185 (256/256)
|
||
|
night_smap -> 2048 tot 677233 (1024)
|
||
|
night_dlight -> 768 tot 678001 (64)
|
||
|
WARE_ware -> 32 tot 678033 (1/32)
|
||
|
WARE_nav -> 0 tot 678033 (0/4096)
|
||
|
WARE_height -> 0 tot 678033 (0/8192)
|
||
|
WARE_rooftex -> 0 tot 678033 (0/4096)
|
||
|
Trip_Wire -> 14 tot 678047 (1/32)
|
||
|
Road_edges -> 0 tot 678047 (0/8)
|
||
|
Thing_heads -> 38 tot 678085 (19)
|
||
|
psx_remap -> 256 tot 678341 (128)
|
||
|
psx_tex_xy -> 2000 tot 680341 (1000)
|
||
|
map_beacon -> 512 tot 680853 (32)
|
||
|
cutscene_data -> 0 tot 680853 (0/20)
|
||
|
cutscene_trks -> 0 tot 680853 (0/300)
|
||
|
cutscene_pkts -> 0 tot 680853 (0/38400)
|
||
|
cutscene_text -> 0 tot 680853 (0/4096)
|
||
|
darci normal -> 482 tot 681335 (241/1200)
|
||
|
|
||
|
*/
|
||
|
extern void BAT_normal(Thing *p_thing);
|
||
|
|
||
|
#ifndef PSX
|
||
|
#define M_(x) x
|
||
|
#else
|
||
|
#ifndef FS_ISO9660
|
||
|
#define M_(x) x
|
||
|
#else
|
||
|
#define M_(x) NULL
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
/*
|
||
|
|
||
|
extern SLONG FC_x;
|
||
|
extern SLONG FC_y;
|
||
|
extern SLONG FC_z;
|
||
|
extern SLONG FC_want_x;
|
||
|
extern SLONG FC_want_y;
|
||
|
extern SLONG FC_want_z;
|
||
|
extern SLONG FC_dx;
|
||
|
extern SLONG FC_dy;
|
||
|
extern SLONG FC_dz;
|
||
|
extern SLONG FC_yaw;
|
||
|
extern SLONG FC_pitch;
|
||
|
extern SLONG FC_roll;
|
||
|
extern SLONG FC_want_yaw;
|
||
|
extern SLONG FC_want_pitch;
|
||
|
extern SLONG FC_want_roll;
|
||
|
extern SLONG FC_lens ; // Initialise this here because of the game editor!
|
||
|
extern SLONG FC_toonear;
|
||
|
extern SLONG FC_rotate;
|
||
|
extern SLONG FC_nobehind;
|
||
|
extern SLONG FC_lookabove;
|
||
|
extern UBYTE FC_shake;
|
||
|
*/
|
||
|
|
||
|
extern ULONG NIGHT_amb_d3d_colour;
|
||
|
extern ULONG NIGHT_amb_d3d_specular;
|
||
|
extern SLONG NIGHT_amb_red;
|
||
|
extern SLONG NIGHT_amb_green;
|
||
|
extern SLONG NIGHT_amb_blue;
|
||
|
extern SLONG NIGHT_amb_norm_x;
|
||
|
extern SLONG NIGHT_amb_norm_y;
|
||
|
extern SLONG NIGHT_amb_norm_z;
|
||
|
|
||
|
extern UBYTE NIGHT_dlight_free;
|
||
|
extern UBYTE NIGHT_dlight_used;
|
||
|
extern ULONG NIGHT_flag;
|
||
|
extern UBYTE NIGHT_lampost_radius;
|
||
|
extern SBYTE NIGHT_lampost_red;
|
||
|
extern SBYTE NIGHT_lampost_green;
|
||
|
extern SBYTE NIGHT_lampost_blue;
|
||
|
extern NIGHT_Colour NIGHT_sky_colour;
|
||
|
|
||
|
extern UWORD EWAY_fake_wander_text_normal_index;
|
||
|
extern UWORD EWAY_fake_wander_text_normal_number;
|
||
|
extern UWORD EWAY_fake_wander_text_guilty_index;
|
||
|
extern UWORD EWAY_fake_wander_text_guilty_number;
|
||
|
extern UWORD EWAY_fake_wander_text_annoyed_index;
|
||
|
extern UWORD EWAY_fake_wander_text_annoyed_number;
|
||
|
|
||
|
extern UBYTE semtex;
|
||
|
extern UBYTE estate;
|
||
|
|
||
|
extern UWORD *thing_class_head;
|
||
|
extern SWORD world_type;
|
||
|
|
||
|
extern void PLAT_process(Thing *p_thing);
|
||
|
extern SLONG TEXTURE_set;
|
||
|
//extern Thing *CAM_focus;
|
||
|
|
||
|
void convert_index_to_pointers(void);
|
||
|
|
||
|
SLONG load_anim_prim_object(SLONG prim);
|
||
|
|
||
|
MAP_Beacon *MAP_beacon; //[MAP_MAX_BEACONS];
|
||
|
|
||
|
PSX_TEX *psx_textures_xy; //[200][5];
|
||
|
|
||
|
#ifdef TARGET_DC
|
||
|
// Don't allocate/free each time, just allocate it statically.
|
||
|
#define LAZY_LOADING_MEMORY_ON_DC_PLEASE_BOB
|
||
|
#endif
|
||
|
|
||
|
void *mem_all=0;
|
||
|
ULONG mem_all_size=0;
|
||
|
|
||
|
UWORD *psx_remap;
|
||
|
|
||
|
//
|
||
|
// supermap stuff to do with ingame facets facet textures inside buildings and walkable rooftops
|
||
|
//
|
||
|
|
||
|
SWORD *facet_links; //[MAX_FACET_LINK];
|
||
|
|
||
|
struct DBuilding *dbuildings;//[MAX_DBUILDINGS];
|
||
|
struct DFacet *dfacets; //[MAX_DFACETS ];
|
||
|
struct DWalkable *dwalkables;//[MAX_DWALKABLES];
|
||
|
SWORD *dstyles; //[MAX_DSTYLES ];
|
||
|
struct DStorey *dstoreys; //[MAX_DSTOREYS];
|
||
|
|
||
|
UBYTE *paint_mem; //[MAX_PAINTMEM];
|
||
|
|
||
|
|
||
|
//
|
||
|
// for compressed anims
|
||
|
//
|
||
|
|
||
|
struct PrimPoint *anim_mids;//[256];
|
||
|
ULONG next_anim_mids=0;
|
||
|
|
||
|
//
|
||
|
// from inside2
|
||
|
//
|
||
|
|
||
|
struct InsideStorey *inside_storeys;//[MAX_INSIDE_RECT];
|
||
|
struct Staircase *inside_stairs;//[MAX_INSIDE_STAIRS];
|
||
|
UBYTE *inside_block;//[MAX_INSIDE_MEM];
|
||
|
UBYTE inside_tex[64][16];
|
||
|
|
||
|
#ifdef PSX
|
||
|
UWORD next_inside_storey=1;
|
||
|
UWORD next_inside_stair=1;
|
||
|
SLONG next_inside_block=1;
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//
|
||
|
// from building.cpp
|
||
|
//
|
||
|
|
||
|
struct BoundBox *roof_bounds;//[MAX_ROOF_BOUND];
|
||
|
struct PrimPoint *prim_points;//[MAX_PRIM_POINTS];
|
||
|
struct PrimFace4 *prim_faces4;//[MAX_PRIM_FACES4];
|
||
|
struct PrimFace3 *prim_faces3;//[MAX_PRIM_FACES3];
|
||
|
struct PrimObject *prim_objects;//[MAX_PRIM_OBJECTS];
|
||
|
struct PrimMultiObject *prim_multi_objects;//[MAX_PRIM_MOBJECTS];
|
||
|
PrimNormal *prim_normal;//[MAX_PRIM_POINTS];
|
||
|
|
||
|
|
||
|
UWORD next_roof_face4=1;
|
||
|
struct RoofFace4 *roof_faces4;
|
||
|
|
||
|
|
||
|
|
||
|
extern SLONG EWAY_time_accurate; // 1600 ticks per second
|
||
|
extern SLONG EWAY_time; // 100 ticks per second
|
||
|
extern SLONG EWAY_tick; // The amount of time since the last process waypoints: (100 ticks per sec.)
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// The cut-scene camera.
|
||
|
//
|
||
|
|
||
|
extern SLONG EWAY_cam_active;
|
||
|
extern SLONG EWAY_cam_x; // Big coordinates...
|
||
|
extern SLONG EWAY_cam_y;
|
||
|
extern SLONG EWAY_cam_z;
|
||
|
extern SLONG EWAY_cam_dx;
|
||
|
extern SLONG EWAY_cam_dy;
|
||
|
extern SLONG EWAY_cam_dz;
|
||
|
extern SLONG EWAY_cam_yaw;
|
||
|
extern SLONG EWAY_cam_pitch;
|
||
|
extern SLONG EWAY_cam_waypoint;
|
||
|
extern SLONG EWAY_cam_target;
|
||
|
extern SLONG EWAY_cam_delay;
|
||
|
extern SLONG EWAY_cam_speed;
|
||
|
extern SLONG EWAY_cam_freeze; // Stop the player moving.
|
||
|
extern UBYTE *EWAY_counter;
|
||
|
extern SLONG EWAY_cam_cant_interrupt;
|
||
|
|
||
|
extern SLONG EWAY_cam_active;
|
||
|
extern SLONG EWAY_cam_goinactive;
|
||
|
extern SLONG EWAY_cam_x; // Big coordinates...
|
||
|
extern SLONG EWAY_cam_y;
|
||
|
extern SLONG EWAY_cam_z;
|
||
|
extern SLONG EWAY_cam_dx;
|
||
|
extern SLONG EWAY_cam_dy;
|
||
|
extern SLONG EWAY_cam_dz;
|
||
|
extern SLONG EWAY_cam_yaw;
|
||
|
extern SLONG EWAY_cam_pitch;
|
||
|
extern SLONG EWAY_cam_want_yaw;
|
||
|
extern SLONG EWAY_cam_want_pitch;
|
||
|
extern SLONG EWAY_cam_waypoint;
|
||
|
extern SLONG EWAY_cam_target;
|
||
|
extern SLONG EWAY_cam_delay;
|
||
|
extern SLONG EWAY_cam_speed;
|
||
|
extern SLONG EWAY_cam_freeze; // Stop the player moving.
|
||
|
extern SLONG EWAY_cam_cant_interrupt;
|
||
|
extern UWORD EWAY_cam_thing;
|
||
|
extern SLONG EWAY_cam_targx;
|
||
|
extern SLONG EWAY_cam_targy;
|
||
|
extern SLONG EWAY_cam_targz;
|
||
|
extern SLONG EWAY_cam_lens; // 16-bit fixed point
|
||
|
extern SLONG EWAY_cam_warehouse;
|
||
|
extern SLONG EWAY_cam_lock;
|
||
|
extern SLONG EWAY_cam_last_yaw;
|
||
|
extern SLONG EWAY_cam_last_x;
|
||
|
extern SLONG EWAY_cam_last_y;
|
||
|
extern SLONG EWAY_cam_last_z;
|
||
|
extern SLONG EWAY_cam_skip;
|
||
|
extern SLONG EWAY_cam_last_dyaw;
|
||
|
|
||
|
|
||
|
UWORD *darci_normal;
|
||
|
UWORD darci_normal_count=0;
|
||
|
|
||
|
void release_memory(void)
|
||
|
{
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
#define MEM_DYNAMIC 1
|
||
|
#define MEM_STATIC 2
|
||
|
|
||
|
struct MemTable save_table[]=
|
||
|
{
|
||
|
|
||
|
{M_("Pap_Hi") ,(void**)&PAP_hi ,MEM_STATIC, 0 ,0 ,PAP_SIZE_HI*PAP_SIZE_HI ,sizeof(PAP_Hi) ,0}, //0
|
||
|
{M_("Pap_Lo") ,(void**)&PAP_lo ,MEM_STATIC, 0 ,0 ,PAP_SIZE_LO*PAP_SIZE_LO ,sizeof(PAP_Lo) ,0}, //1
|
||
|
{M_("net_peep") ,(void**)&NETPERSON ,MEM_STATIC, 0 ,0 ,10 ,sizeof(Thing*) ,0}, //2
|
||
|
{M_("net_plyr") ,(void**)&NETPLAYERS ,MEM_STATIC, 0 ,0 ,10 ,sizeof(Thing*) ,0}, //3
|
||
|
{M_("f-links") ,(void**)&facet_links ,MEM_DYNAMIC,0 ,(UWORD*)&next_facet_link ,MAX_FACET_LINK ,sizeof(SWORD) ,0}, //4
|
||
|
{M_("dbuildings") ,(void**)&dbuildings ,MEM_DYNAMIC,&next_dbuilding ,0 ,MAX_DBUILDINGS ,sizeof(struct DBuilding) ,0}, //5
|
||
|
{M_("dfacets") ,(void**)&dfacets ,MEM_DYNAMIC,&next_dfacet ,0 ,MAX_DFACETS ,sizeof(struct DFacet) ,0}, //6
|
||
|
{M_("dwalkables") ,(void**)&dwalkables ,MEM_DYNAMIC,&next_dwalkable ,0 ,MAX_DWALKABLES ,sizeof(struct DWalkable) ,0}, //7
|
||
|
{M_("dstyles") ,(void**)&dstyles ,MEM_DYNAMIC,&next_dstyle ,0 ,MAX_DSTYLES ,sizeof(SWORD) ,0}, //8
|
||
|
{M_("dstoreys") ,(void**)&dstoreys ,MEM_DYNAMIC,0 ,(UWORD*)&next_dstorey ,MAX_DSTOREYS ,sizeof(struct DStorey ) ,0}, //9
|
||
|
{M_("paintmem") ,(void**)&paint_mem ,MEM_DYNAMIC,0 ,(UWORD*)&next_paint_mem ,MAX_PAINTMEM ,sizeof(UBYTE) ,0}, //10
|
||
|
{M_("insideStoreys"),(void**)&inside_storeys ,MEM_DYNAMIC,0 ,(UWORD*)&next_inside_storey,MAX_INSIDE_RECT ,sizeof(struct InsideStorey) ,0}, //11
|
||
|
{M_("insideStairs") ,(void**)&inside_stairs ,MEM_DYNAMIC,0 ,&next_inside_stair ,MAX_INSIDE_STAIRS ,sizeof(struct Staircase) ,0}, //12
|
||
|
{M_("insideblock") ,(void**)&inside_block ,MEM_DYNAMIC,&next_inside_block ,0 ,MAX_INSIDE_MEM ,sizeof(UBYTE) ,0}, //13
|
||
|
{M_("roof bounds") ,(void**)&roof_bounds ,MEM_DYNAMIC,0 ,&next_roof_bound ,MAX_ROOF_BOUND ,sizeof(struct BoundBox) ,0}, //14
|
||
|
{M_("prim_points") ,(void**)&prim_points ,MEM_DYNAMIC,0 ,&next_prim_point ,RMAX_PRIM_POINTS ,sizeof(struct PrimPoint) ,256}, //15
|
||
|
{M_("prim_faces4") ,(void**)&prim_faces4 ,MEM_DYNAMIC,0 ,&next_prim_face4 ,RMAX_PRIM_FACES4 ,sizeof(struct PrimFace4) ,64}, //16
|
||
|
{M_("prim_faces3") ,(void**)&prim_faces3 ,MEM_DYNAMIC,0 ,&next_prim_face3 ,MAX_PRIM_FACES3 ,sizeof(struct PrimFace3) ,0}, //17
|
||
|
{M_("prim_objects") ,(void**)&prim_objects ,MEM_DYNAMIC,0 ,&next_prim_object ,MAX_PRIM_OBJECTS ,sizeof(struct PrimObject) ,0}, //18
|
||
|
{M_("prim_Mobjects"),(void**)&prim_multi_objects ,MEM_DYNAMIC,0 ,&next_prim_multi_object ,MAX_PRIM_MOBJECTS ,sizeof(struct PrimMultiObject) ,0}, //19
|
||
|
|
||
|
/*
|
||
|
#ifdef TEST_DC
|
||
|
{M_("prim normal") ,(void**)&prim_normal ,MEM_DYNAMIC,0 ,&next_prim_point ,MAX_PRIM_POINTS ,sizeof(PrimNormal) },
|
||
|
#endif
|
||
|
*/
|
||
|
|
||
|
{M_("ob_ob") ,(void**)&OB_ob ,MEM_DYNAMIC,&OB_ob_upto ,0 ,OB_MAX_OBS ,sizeof(OB_Ob) ,0}, //20
|
||
|
{M_("ob_ mapwho") ,(void**)&OB_mapwho ,MEM_STATIC, 0 ,0 ,OB_SIZE*OB_SIZE ,sizeof(OB_Mapwho) ,0}, //21
|
||
|
{M_("EWAY_mess") ,(void**)&EWAY_mess ,MEM_DYNAMIC,&EWAY_mess_upto ,0 ,EWAY_MAX_MESSES ,sizeof(CBYTE*) ,0}, //22
|
||
|
{M_("EWAY_mess buf"),(void**)&EWAY_mess_buffer ,MEM_DYNAMIC,&EWAY_mess_buffer_upto ,0 ,EWAY_MESS_BUFFER_SIZE ,sizeof(CBYTE) ,0}, //23
|
||
|
#ifdef NEW_LEVELS
|
||
|
{M_("EWAY_timer") ,(void**)&EWAY_timer ,MEM_STATIC,0 ,0 ,EWAY_MAX_TIMERS ,sizeof(UWORD) ,0}, //24
|
||
|
#else
|
||
|
{M_("EWAY_timer") ,(void**)&EWAY_timer ,MEM_DYNAMIC,0 ,0 ,EWAY_MAX_TIMERS ,sizeof(UWORD) ,0}, //24
|
||
|
#endif
|
||
|
{M_("EWAY_cond") ,(void**)&EWAY_cond ,MEM_DYNAMIC,&EWAY_cond_upto ,0 ,EWAY_MAX_CONDS ,sizeof(EWAY_Cond) ,0}, //25
|
||
|
{M_("EWAY_way") ,(void**)&EWAY_way ,MEM_DYNAMIC,&EWAY_way_upto ,0 ,EWAY_MAX_WAYS ,sizeof(EWAY_Way) ,0}, //26
|
||
|
{M_("EWAY_edef") ,(void**)&EWAY_edef ,MEM_DYNAMIC,&EWAY_edef_upto ,0 ,EWAY_MAX_EDEFS ,sizeof(EWAY_Edef) ,0}, //27
|
||
|
{M_("EWAY_counter") ,(void**)&EWAY_counter ,MEM_STATIC ,0 ,0 ,EWAY_MAX_COUNTERS ,sizeof(UBYTE) ,0}, //28
|
||
|
|
||
|
{M_("vehicles") ,(void**)&VEHICLES ,MEM_STATIC, 0 ,0 ,RMAX_VEHICLES ,sizeof(Vehicle) ,32}, //29
|
||
|
{M_("people") ,(void**)&PEOPLE ,MEM_STATIC, 0 ,0 ,RMAX_PEOPLE ,sizeof(Person) ,128}, //30
|
||
|
{M_("animals") ,(void**)&ANIMALS ,MEM_STATIC, 0 ,0 ,MAX_ANIMALS ,sizeof(Animal) ,0}, //31
|
||
|
{M_("choppers") ,(void**)&CHOPPERS ,MEM_STATIC, 0 ,0 ,MAX_CHOPPERS ,sizeof(Chopper) ,0}, //32
|
||
|
{M_("pyro") ,(void**)&PYROS ,MEM_STATIC, 0 ,0 ,MAX_PYROS ,sizeof(Pyro) ,0}, //33
|
||
|
{M_("players") ,(void**)&PLAYERS ,MEM_STATIC, 0 ,0 ,MAX_PLAYERS ,sizeof(Player) ,0}, //34
|
||
|
{M_("projectiles") ,(void**)&PROJECTILES ,MEM_STATIC, 0 ,0 ,MAX_PROJECTILES ,sizeof(Projectile) ,0}, //35
|
||
|
{M_("special") ,(void**)&SPECIALS ,MEM_STATIC, 0 ,0 ,RMAX_SPECIALS ,sizeof(Special) ,128}, //36
|
||
|
{M_("switches") ,(void**)&SWITCHES ,MEM_STATIC, 0 ,0 ,MAX_SWITCHES ,sizeof(Switch) ,0}, //37
|
||
|
{M_("bats") ,(void**)&BATS ,MEM_STATIC, 0 ,0 ,RBAT_MAX_BATS ,sizeof(Bat) ,32}, //38
|
||
|
{M_("thing") ,(void**)&THINGS ,MEM_STATIC, 0 ,0 ,MAX_THINGS ,sizeof(Thing) ,0}, //39
|
||
|
{M_("drawtween") ,(void**)&DRAW_TWEENS ,MEM_STATIC, 0 ,0 ,RMAX_DRAW_TWEENS ,sizeof(DrawTween) ,128}, //40
|
||
|
{M_("drawmesh") ,(void**)&DRAW_MESHES ,MEM_STATIC, 0 ,0 ,RMAX_DRAW_MESHES ,sizeof(DrawMesh) ,128}, //41
|
||
|
#ifdef BIKE
|
||
|
{M_("bike") ,(void**)&BIKE_bike ,MEM_STATIC, 0 ,0 ,BIKE_MAX_BIKES ,sizeof(BIKE_Bike) ,0}, //42
|
||
|
#endif
|
||
|
{M_("barrelsphere") ,(void**)&BARREL_sphere ,MEM_STATIC, 0 ,0 ,BARREL_MAX_SPHERES ,sizeof(BARREL_Sphere) ,0}, //43
|
||
|
{M_("barrels") ,(void**)&BARREL_barrel ,MEM_DYNAMIC,&BARREL_barrel_upto ,0 ,BARREL_MAX_BARRELS ,sizeof(Barrel) ,0}, //44
|
||
|
{M_("plat") ,(void**)&PLAT_plat ,MEM_DYNAMIC,&PLAT_plat_upto ,0 ,RPLAT_MAX_PLATS ,sizeof(Plat) ,2}, //45
|
||
|
{M_("wmove") ,(void**)&WMOVE_face ,MEM_DYNAMIC,&WMOVE_face_upto ,0 ,RWMOVE_MAX_FACES ,sizeof(WMOVE_Face) ,64}, //46
|
||
|
{M_("mav_opt") ,(void**)&MAV_opt ,MEM_DYNAMIC,&MAV_opt_upto ,0 ,MAV_MAX_OPTS ,sizeof(MAV_Opt) ,0}, //47
|
||
|
|
||
|
//{M_("mav height") ,(void**)&MAV_height ,MEM_STATIC, 0 ,0 ,PAP_SIZE_HI*PAP_SIZE_HI ,sizeof(SBYTE) },
|
||
|
|
||
|
{M_("mav_nav") ,(void**)&MAV_nav ,MEM_STATIC, 0 ,0 ,PAP_SIZE_HI*PAP_SIZE_HI ,sizeof(UWORD) ,0}, //48
|
||
|
{M_("road_noads") ,(void**)&ROAD_node ,MEM_DYNAMIC,&ROAD_node_upto ,0 ,ROAD_MAX_NODES ,sizeof(ROAD_Node) ,0}, //49
|
||
|
{M_("balloons") ,(void**)&BALLOON_balloon ,MEM_DYNAMIC,&BALLOON_balloon_upto ,0 ,BALLOON_MAX_BALLOONS ,sizeof(BALLOON_Balloon) ,0}, //50
|
||
|
{M_("tracks") ,(void**)&tracks ,MEM_STATIC, 0 ,0 ,TRACK_BUFFER_LENGTH ,sizeof(Track) ,0}, //51
|
||
|
{M_("roofface4") ,(void**)&roof_faces4 ,MEM_DYNAMIC,0 ,&next_roof_face4 ,MAX_ROOF_FACE4 ,sizeof(struct RoofFace4) ,0}, //52
|
||
|
{M_("fastnav") ,(void**)&COLLIDE_fastnav ,MEM_STATIC, 0 ,0 ,PAP_SIZE_HI*PAP_SIZE_HI>>3 ,sizeof(UBYTE) ,0}, //53
|
||
|
{M_("night_slight") ,(void**)&NIGHT_slight ,MEM_DYNAMIC,&NIGHT_slight_upto ,0 ,NIGHT_MAX_SLIGHTS ,sizeof(NIGHT_Slight) ,0}, //54
|
||
|
{M_("night_smap") ,(void**)&NIGHT_smap ,MEM_STATIC ,0 ,0 ,PAP_SIZE_LO*PAP_SIZE_LO ,sizeof(NIGHT_Smap) ,0}, //55
|
||
|
{M_("night_dlight") ,(void**)&NIGHT_dlight ,MEM_STATIC ,0 ,0 ,NIGHT_MAX_DLIGHTS ,sizeof(NIGHT_Dlight) ,0}, //56
|
||
|
{M_("WARE_ware") ,(void**)&WARE_ware ,MEM_DYNAMIC,0 ,&WARE_ware_upto ,WARE_MAX_WARES ,sizeof(WARE_Ware) ,0}, //57
|
||
|
{M_("WARE_nav") ,(void**)&WARE_nav ,MEM_DYNAMIC,0 ,&WARE_nav_upto ,WARE_MAX_NAVS ,sizeof(UWORD) ,0}, //58
|
||
|
{M_("WARE_height") ,(void**)&WARE_height ,MEM_DYNAMIC,0 ,&WARE_height_upto ,WARE_MAX_HEIGHTS ,sizeof(SBYTE) ,0}, //59
|
||
|
{M_("WARE_rooftex") ,(void**)&WARE_rooftex ,MEM_DYNAMIC,0 ,&WARE_rooftex_upto ,WARE_MAX_ROOFTEXES ,sizeof(UWORD) ,0}, //60
|
||
|
{M_("Trip_Wire") ,(void**)&TRIP_wire ,MEM_DYNAMIC,&TRIP_wire_upto ,0 ,TRIP_MAX_WIRES ,sizeof(TRIP_Wire) ,0}, //61
|
||
|
{M_("Road_edges") ,(void**)&ROAD_edge ,MEM_DYNAMIC,0 ,&ROAD_edge_upto ,ROAD_MAX_EDGES ,sizeof(UBYTE) ,0}, //62
|
||
|
{M_("Thing_heads") ,(void**)&thing_class_head ,MEM_STATIC ,0 ,0 ,CLASS_END ,sizeof(UWORD) ,0}, //63
|
||
|
{M_("psx_remap") ,(void**)&psx_remap ,MEM_STATIC ,0 ,0 ,128 ,sizeof(UWORD) ,0}, //64
|
||
|
{M_("psx_tex_xy") ,(void**)&psx_textures_xy ,MEM_STATIC ,0 ,0 ,200*5 ,sizeof(UWORD) ,0}, //65
|
||
|
{M_("map_beacon") ,(void**)&MAP_beacon ,MEM_STATIC ,0 ,0 ,MAP_MAX_BEACONS ,sizeof(MAP_Beacon) ,0}, //66
|
||
|
// {"anim_mids" ,(void**)&anim_mids ,MEM_STATIC ,0 ,&next_anim_mids ,256 ,sizeof(PrimPoint) },
|
||
|
// cutscene memory
|
||
|
#ifndef BUILD_PSX
|
||
|
{M_("cutscene_data"),(void**)&PLAYCUTS_cutscenes ,MEM_DYNAMIC,0 ,&PLAYCUTS_cutscene_ctr ,MAX_CUTSCENES ,sizeof(CPData) ,0},
|
||
|
{M_("cutscene_trks"),(void**)&PLAYCUTS_tracks ,MEM_DYNAMIC,0 ,&PLAYCUTS_track_ctr ,MAX_CUTSCENE_TRACKS ,sizeof(CPChannel) ,0},
|
||
|
{M_("cutscene_pkts"),(void**)&PLAYCUTS_packets ,MEM_DYNAMIC,0 ,&PLAYCUTS_packet_ctr ,MAX_CUTSCENE_PACKETS ,sizeof(CPPacket) ,0},
|
||
|
{M_("cutscene_text"),(void**)&PLAYCUTS_text_data ,MEM_DYNAMIC,0 ,&PLAYCUTS_text_ctr ,MAX_CUTSCENE_TEXT ,sizeof(CBYTE) ,0},
|
||
|
#endif
|
||
|
{M_("darci normal") ,(void**)&darci_normal ,MEM_DYNAMIC,0 ,&darci_normal_count ,12000 ,sizeof(UWORD) ,0},
|
||
|
{M_("prim info") ,(void**)&prim_info ,MEM_STATIC ,0 ,0 ,256 ,sizeof(PrimInfo) ,0},
|
||
|
|
||
|
{M_("Doors-gates") ,(void**)&DOOR_door ,MEM_STATIC ,0 ,0 ,DOOR_MAX_DOORS ,sizeof(DOOR_Door) ,0},
|
||
|
|
||
|
//
|
||
|
// new ones added by MikeD for footstep surfaces
|
||
|
//
|
||
|
{M_("soundfxmap") ,(void**)&SOUND_FXMapping ,MEM_STATIC, 0 ,0 ,1024 ,sizeof(UBYTE) ,0}, //48
|
||
|
{M_("soundfxgroup") ,(void**)&SOUND_FXGroups ,MEM_STATIC, 0 ,0 ,128*2 ,sizeof(UWORD) ,0}, //48
|
||
|
|
||
|
|
||
|
{0,0,0,0,0,0,0}
|
||
|
// {"" ,(void**) ,1,0 ,& ,MAX_PAINTMEM ,sizeof(struct ) },
|
||
|
|
||
|
|
||
|
};
|
||
|
|
||
|
|
||
|
void init_memory(void)
|
||
|
{
|
||
|
SLONG c0=0;
|
||
|
SLONG mem_size,mem_cumlative=0;
|
||
|
struct MemTable *p_tab;
|
||
|
UBYTE *p_all;
|
||
|
SLONG temp;
|
||
|
|
||
|
|
||
|
|
||
|
// FIXME FUDGE!
|
||
|
#ifdef TARGET_DC
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#ifndef PSX
|
||
|
#ifndef TARGET_DC
|
||
|
save_table[SAVE_TABLE_PEOPLE].Maximum=RMAX_PEOPLE;
|
||
|
save_table[SAVE_TABLE_VEHICLE].Maximum=RMAX_VEHICLES;
|
||
|
save_table[SAVE_TABLE_SPECIAL].Maximum=RMAX_SPECIALS;
|
||
|
save_table[SAVE_TABLE_BAT].Maximum=RBAT_MAX_BATS;
|
||
|
save_table[SAVE_TABLE_DTWEEN].Maximum=RMAX_DRAW_TWEENS;
|
||
|
save_table[SAVE_TABLE_DMESH].Maximum=RMAX_DRAW_MESHES;
|
||
|
|
||
|
extern UBYTE music_max_gain;
|
||
|
|
||
|
// temp= ENV_get_value_number("music_vol", 128, "Audio");
|
||
|
// SATURATE(temp,0,255);
|
||
|
// music_max_gain=temp;
|
||
|
|
||
|
|
||
|
extern SLONG save_psx;
|
||
|
extern SLONG build_psx;
|
||
|
|
||
|
if((save_psx=ENV_get_value_number("psx", 0, "Secret")))
|
||
|
{
|
||
|
// save_psx=1;
|
||
|
build_psx=1;
|
||
|
}
|
||
|
#endif
|
||
|
#endif
|
||
|
while(save_table[c0].Point)
|
||
|
{
|
||
|
void* ptr;
|
||
|
p_tab=&save_table[c0];
|
||
|
mem_size=p_tab->StructSize*p_tab->Maximum;
|
||
|
mem_cumlative+=mem_size;
|
||
|
DebugText(" %s = %d cuml %d \n",p_tab->Name,mem_size,mem_cumlative);
|
||
|
|
||
|
|
||
|
c0++;
|
||
|
}
|
||
|
|
||
|
c0=0;
|
||
|
mem_cumlative+=1024;
|
||
|
|
||
|
if(mem_all)
|
||
|
{
|
||
|
MemFree(mem_all);
|
||
|
mem_all = NULL;
|
||
|
}
|
||
|
|
||
|
|
||
|
#ifndef LAZY_LOADING_MEMORY_ON_DC_PLEASE_BOB
|
||
|
// Not used on DC.
|
||
|
|
||
|
mem_all=MemAlloc(mem_cumlative);
|
||
|
ASSERT(mem_all);
|
||
|
mem_all_size=mem_cumlative;
|
||
|
|
||
|
|
||
|
p_all=(UBYTE*)mem_all;
|
||
|
|
||
|
while(save_table[c0].Point)
|
||
|
{
|
||
|
void* ptr;
|
||
|
p_tab=&save_table[c0];
|
||
|
mem_size=p_tab->StructSize*p_tab->Maximum;
|
||
|
|
||
|
mem_size+=3;
|
||
|
mem_size&=0xfffffffc;
|
||
|
*p_tab->Point=p_all;
|
||
|
p_all+=mem_size;
|
||
|
c0++;
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
|
||
|
anim_mids=(PrimPoint*)MemAlloc(256*sizeof(PrimPoint));
|
||
|
// because furniture isnt saved at the moment, so isnt in the table
|
||
|
the_game.Furnitures=(Furniture*)MemAlloc(sizeof(Furniture)*MAX_FURNITURE);
|
||
|
// {"prim normal" ,(void**)&prim_normal ,1,0 ,&next_prim_point ,MAX_PRIM_POINTS ,sizeof(PrimNormal) },
|
||
|
prim_normal=(PrimNormal*)MemAlloc(sizeof(PrimNormal)*MAX_PRIM_POINTS);
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
#ifndef PSX
|
||
|
void set_darci_normals(void)
|
||
|
{
|
||
|
SLONG count_vertex;
|
||
|
SLONG c0,c1,index;
|
||
|
SLONG sp,ep;
|
||
|
SLONG last_point=0,first_point=0x7fffffff;
|
||
|
SLONG start_object;
|
||
|
for(c0=1;c0<darci_normal_count;c0++)
|
||
|
{
|
||
|
SLONG nx,ny,nz,c;
|
||
|
|
||
|
nx=prim_normal[c0].X;
|
||
|
ny=prim_normal[c0].Y;
|
||
|
nz=prim_normal[c0].Z;
|
||
|
SATURATE(nx,-256,255);
|
||
|
SATURATE(ny,-256,255);
|
||
|
SATURATE(nz,-256,255);
|
||
|
|
||
|
nx>>=4;
|
||
|
nx+=16;
|
||
|
ASSERT(nx>=0 &&nx<=31);
|
||
|
|
||
|
ny>>=4;
|
||
|
ny+=16;
|
||
|
ASSERT(ny>=0 && ny<=31);
|
||
|
|
||
|
nz>>=4;
|
||
|
nz+=16;
|
||
|
ASSERT(nz>=0 && nz<=31);
|
||
|
|
||
|
nx&=31;
|
||
|
ny&=31;
|
||
|
nz&=31;
|
||
|
|
||
|
c=nx<<10;
|
||
|
c|=ny<<5;
|
||
|
c|=nz;
|
||
|
darci_normal[c0]=c;
|
||
|
|
||
|
}
|
||
|
return;
|
||
|
/*
|
||
|
start_object = prim_multi_objects[game_chunk[0].MultiObject[0]].StartObject;
|
||
|
for(c0=0;c0<15;c0++)
|
||
|
{
|
||
|
index = start_object+game_chunk[0].PeopleTypes[0].BodyPart[c0];
|
||
|
|
||
|
sp=prim_objects[index].StartPoint;
|
||
|
ep=prim_objects[index].EndPoint;
|
||
|
|
||
|
if(sp<first_point)
|
||
|
first_point=sp;
|
||
|
if(ep>last_point)
|
||
|
last_point=ep;
|
||
|
|
||
|
|
||
|
}
|
||
|
ASSERT(last_point-first_point>0 &&last_point-first_point<1000);
|
||
|
|
||
|
// darci_normal=(UWORD*)MemAlloc((last_point-first_point+2)*2);
|
||
|
darci_normal[0]=first_point-1;
|
||
|
|
||
|
for(c0=0;c0<15;c0++)
|
||
|
{
|
||
|
index = start_object+game_chunk[0].PeopleTypes[0].BodyPart[c0];
|
||
|
sp=prim_objects[index].StartPoint;
|
||
|
ep=prim_objects[index].EndPoint;
|
||
|
for(c1=sp;c1<ep;c1++)
|
||
|
{
|
||
|
SLONG nx,ny,nz,c;
|
||
|
|
||
|
nx=prim_normal[c1].X;
|
||
|
ny=prim_normal[c1].Y;
|
||
|
nz=prim_normal[c1].Z;
|
||
|
SATURATE(nx,-256,255);
|
||
|
SATURATE(ny,-256,255);
|
||
|
SATURATE(nz,-256,255);
|
||
|
// >>1 =-127 ->127
|
||
|
// >>1 =-63 -> 63
|
||
|
// >>1 =-31 -> 31
|
||
|
// >>1 =-15 -> 15
|
||
|
nx>>=4;
|
||
|
nx+=16;
|
||
|
ASSERT(nx>=0 &&nx<=31);
|
||
|
|
||
|
ny>>=4;
|
||
|
ny+=16;
|
||
|
ASSERT(ny>=0 && ny<=31);
|
||
|
|
||
|
nz>>=4;
|
||
|
nz+=16;
|
||
|
ASSERT(nz>=0 && nz<=31);
|
||
|
|
||
|
nx&=31;
|
||
|
ny&=31;
|
||
|
nz&=31;
|
||
|
|
||
|
c=nx<<10;
|
||
|
c|=ny<<5;
|
||
|
c|=nz;
|
||
|
darci_normal[c1-first_point+1]=c;
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|
||
|
darci_normal_count=last_point-first_point+1;
|
||
|
*/
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#ifndef PSX
|
||
|
void convert_drawtype_to_index(Thing *p_thing,SLONG meshtype)
|
||
|
{
|
||
|
switch(meshtype)
|
||
|
{
|
||
|
case DT_MESH:
|
||
|
if(p_thing->Draw.Mesh)
|
||
|
{
|
||
|
ULONG drawtype;
|
||
|
drawtype=(p_thing->Draw.Mesh-DRAW_MESHES);
|
||
|
p_thing->Draw.Mesh=(DrawMesh*)drawtype;
|
||
|
}
|
||
|
break;
|
||
|
case DT_ROT_MULTI:
|
||
|
case DT_ANIM_PRIM:
|
||
|
case DT_BIKE:
|
||
|
if(p_thing->Draw.Tweened)
|
||
|
{
|
||
|
ULONG drawtype;
|
||
|
SLONG chunk;
|
||
|
|
||
|
switch(p_thing->Class)
|
||
|
{
|
||
|
case CLASS_BIKE:
|
||
|
case CLASS_PERSON:
|
||
|
case CLASS_VEHICLE:
|
||
|
case CLASS_ANIMAL:
|
||
|
chunk=(ULONG)(p_thing->Draw.Tweened->TheChunk-&game_chunk[0]);
|
||
|
ASSERT(chunk>=0);
|
||
|
chunk|=1<<16;
|
||
|
p_thing->Draw.Tweened->TheChunk=(GameKeyFrameChunk*)chunk;
|
||
|
break;
|
||
|
case CLASS_BAT:
|
||
|
case CLASS_ANIM_PRIM:
|
||
|
chunk=(ULONG)(p_thing->Draw.Tweened->TheChunk-&anim_chunk[0]);
|
||
|
ASSERT(chunk>=0);
|
||
|
chunk|=2<<16;
|
||
|
p_thing->Draw.Tweened->TheChunk=(GameKeyFrameChunk*)chunk;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
drawtype=(p_thing->Draw.Tweened-DRAW_TWEENS);
|
||
|
p_thing->Draw.Tweened=(DrawTween*)drawtype;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
void convert_thing_to_index(Thing *p_thing)
|
||
|
{
|
||
|
// ASSERT(THING_NUMBER(p_thing)!=94);
|
||
|
switch(p_thing->DrawType)
|
||
|
{
|
||
|
case DT_MESH:
|
||
|
case DT_CHOPPER:
|
||
|
convert_drawtype_to_index(p_thing,DT_MESH);
|
||
|
break;
|
||
|
case DT_ROT_MULTI:
|
||
|
convert_drawtype_to_index(p_thing,DT_ROT_MULTI);
|
||
|
break;
|
||
|
|
||
|
case DT_ANIM_PRIM:
|
||
|
case DT_BIKE:
|
||
|
convert_drawtype_to_index(p_thing,DT_ANIM_PRIM);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
switch(p_thing->Class)
|
||
|
{
|
||
|
|
||
|
case CLASS_NONE:
|
||
|
break;
|
||
|
case CLASS_PLAYER:
|
||
|
p_thing->Genus.Player->PlayerPerson=(Thing*)THING_NUMBER(p_thing->Genus.Player->PlayerPerson);
|
||
|
p_thing->Genus.Player=(Player*)PLAYER_NUMBER(p_thing->Genus.Player);
|
||
|
|
||
|
break;
|
||
|
case CLASS_CAMERA:
|
||
|
break;
|
||
|
case CLASS_PROJECTILE:
|
||
|
p_thing->Genus.Projectile=(Projectile *)PROJECTILE_NUMBER(p_thing->Genus.Projectile);
|
||
|
break;
|
||
|
case CLASS_BUILDING:
|
||
|
break;
|
||
|
case CLASS_PERSON:
|
||
|
p_thing->Genus.Person=(Person *)PERSON_NUMBER(p_thing->Genus.Person);
|
||
|
|
||
|
break;
|
||
|
case CLASS_ANIMAL:
|
||
|
p_thing->Genus.Animal=(Animal*)ANIMAL_NUMBERb(p_thing->Genus.Animal);
|
||
|
|
||
|
break;
|
||
|
case CLASS_FURNITURE:
|
||
|
p_thing->Genus.Furniture=(Furniture*)FURNITURE_NUMBER(p_thing->Genus.Furniture);
|
||
|
break;
|
||
|
case CLASS_SWITCH:
|
||
|
p_thing->Genus.Switch=(Switch*)SWITCH_NUMBER(p_thing->Genus.Switch);
|
||
|
break;
|
||
|
case CLASS_VEHICLE:
|
||
|
p_thing->Genus.Vehicle=(Vehicle*)VEHICLE_NUMBER(p_thing->Genus.Vehicle);
|
||
|
break;
|
||
|
case CLASS_SPECIAL:
|
||
|
p_thing->Genus.Special=(Special*)SPECIAL_NUMBER(p_thing->Genus.Special);
|
||
|
break;
|
||
|
case CLASS_ANIM_PRIM:
|
||
|
break;
|
||
|
case CLASS_CHOPPER:
|
||
|
p_thing->Genus.Chopper=(Chopper*)CHOPPER_NUMBER(p_thing->Genus.Chopper);
|
||
|
|
||
|
break;
|
||
|
case CLASS_PYRO:
|
||
|
p_thing->Genus.Pyro=(Pyro*)PYRO_NUMBER(p_thing->Genus.Pyro);
|
||
|
break;
|
||
|
case CLASS_TRACK:
|
||
|
if (p_thing->Genus.Track->flags==TRACK_FLAGS_SPLUTTING)
|
||
|
p_thing->Genus.Track->page=POLY_PAGE_BLOODSPLAT;
|
||
|
p_thing->Genus.Track=(Track*)TRACK_NUMBER(p_thing->Genus.Track);
|
||
|
break;
|
||
|
case CLASS_PLAT:
|
||
|
p_thing->Genus.Plat=(Plat*)PLAT_NUMBER(p_thing->Genus.Plat);
|
||
|
|
||
|
break;
|
||
|
case CLASS_BARREL:
|
||
|
p_thing->Genus.Barrel=(Barrel*)BARREL_NUMBER(p_thing->Genus.Barrel);
|
||
|
|
||
|
break;
|
||
|
#ifdef BIKE
|
||
|
case CLASS_BIKE:
|
||
|
p_thing->Genus.Bike=(BIKE_Bike*)BIKE_NUMBER(p_thing->Genus.Bike);
|
||
|
break;
|
||
|
#endif
|
||
|
case CLASS_BAT:
|
||
|
p_thing->Genus.Bat=(Bat*)BAT_NUMBER(p_thing->Genus.Bat);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
ASSERT(0);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
void convert_pointers_to_index(void)
|
||
|
{
|
||
|
SLONG c0,i;
|
||
|
static max_people=0,max_car=0,max_mesh=0,max_tween=0,max_anim=0,max_special=0,max_bat=0;
|
||
|
SLONG count_people=0,count_car=0,count_mesh=0,count_tween=0,count_anim=0,count_special=0,count_bat=0;
|
||
|
SLONG gap=0;
|
||
|
|
||
|
for(c0=0;c0<MAX_THINGS;c0++)
|
||
|
{
|
||
|
convert_thing_to_index(TO_THING(c0));
|
||
|
/*
|
||
|
switch(TO_THING(c0)->Class)
|
||
|
{
|
||
|
case CLASS_PERSON:
|
||
|
count_people++;
|
||
|
break;
|
||
|
case CLASS_VEHICLE:
|
||
|
count_car++;
|
||
|
break;
|
||
|
case CLASS_SPECIAL:
|
||
|
count_special++;
|
||
|
break;
|
||
|
case CLASS_BAT:
|
||
|
count_bat++;
|
||
|
break;
|
||
|
}
|
||
|
switch(TO_THING(c0)->DrawType)
|
||
|
{
|
||
|
case DT_MESH:
|
||
|
case DT_CHOPPER:
|
||
|
count_mesh++;
|
||
|
break;
|
||
|
case DT_ROT_MULTI:
|
||
|
count_tween++;
|
||
|
break;
|
||
|
|
||
|
case DT_ANIM_PRIM:
|
||
|
case DT_BIKE:
|
||
|
count_anim++;
|
||
|
break;
|
||
|
}
|
||
|
*/
|
||
|
}
|
||
|
for (i = 0; i < RMAX_DRAW_MESHES; i++)
|
||
|
{
|
||
|
if (DRAW_MESHES[i].Angle != 0xfafa)
|
||
|
{
|
||
|
if(i>count_mesh)
|
||
|
{
|
||
|
count_mesh=i;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<RMAX_DRAW_TWEENS;c0++)
|
||
|
{
|
||
|
if(!(DRAW_TWEENS[c0].Flags&DT_FLAG_UNUSED))
|
||
|
{
|
||
|
if(c0>count_tween)
|
||
|
count_tween=c0;
|
||
|
}
|
||
|
}
|
||
|
for (i = 0; i < RMAX_VEHICLES; i++)
|
||
|
{
|
||
|
if (TO_VEHICLE(i)->Spring[0].Compression != VEH_NULL)
|
||
|
{
|
||
|
if(i>count_car)
|
||
|
count_car=i;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
for(c0=0;c0<RMAX_PEOPLE;c0++)
|
||
|
{
|
||
|
if(PEOPLE[c0].AnimType!=PERSON_NONE)
|
||
|
{
|
||
|
if(c0>count_people)
|
||
|
count_people=c0;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
for(c0=1;c0<RMAX_SPECIALS;c0++)
|
||
|
{
|
||
|
if(SPECIALS[c0].SpecialType!=SPECIAL_NONE)
|
||
|
{
|
||
|
if(c0>count_special)
|
||
|
count_special=c0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
for (i = 0; i < RBAT_MAX_BATS; i++)
|
||
|
{
|
||
|
if (TO_BAT(i)->type != BAT_TYPE_UNUSED)
|
||
|
{
|
||
|
if(i>count_bat)
|
||
|
count_bat=i;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
save_table[SAVE_TABLE_PEOPLE].Maximum =MIN(save_table[SAVE_TABLE_PEOPLE].Extra+count_people,RMAX_PEOPLE);
|
||
|
save_table[SAVE_TABLE_VEHICLE].Maximum =MIN(save_table[SAVE_TABLE_VEHICLE].Extra+count_car,RMAX_VEHICLES);
|
||
|
save_table[SAVE_TABLE_SPECIAL].Maximum =MIN(save_table[SAVE_TABLE_SPECIAL].Extra+count_special,RMAX_SPECIALS);
|
||
|
save_table[SAVE_TABLE_BAT].Maximum =MIN(save_table[SAVE_TABLE_BAT].Extra+count_bat,RBAT_MAX_BATS);
|
||
|
save_table[SAVE_TABLE_DTWEEN].Maximum =MIN(save_table[SAVE_TABLE_DTWEEN].Extra+count_tween,RMAX_DRAW_TWEENS);
|
||
|
save_table[SAVE_TABLE_DMESH].Maximum =MIN(save_table[SAVE_TABLE_DMESH].Extra+count_mesh,RMAX_DRAW_MESHES);
|
||
|
|
||
|
extern CBYTE ELEV_fname_level[];
|
||
|
if ( level_index==0 )
|
||
|
{
|
||
|
// This is probably Breakout! - in which case, we need the fudge in.
|
||
|
// Make sure you manually step into the fudge code.
|
||
|
if (strstr(ELEV_fname_level, "FTutor"))
|
||
|
{
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
//ASSERT ( strstr ( ELEV_fname_level, "Album1" ) );
|
||
|
//ASSERT ( FALSE );
|
||
|
}
|
||
|
}
|
||
|
if(level_index==20 || level_index==19 || level_index== 26|| level_index== 24 || strstr ( ELEV_fname_level, "Album1" ) )
|
||
|
{
|
||
|
//cop killers or semtex or estate map or stern revenge
|
||
|
|
||
|
save_table[SAVE_TABLE_PEOPLE].Maximum =MIN(save_table[SAVE_TABLE_PEOPLE].Extra+count_people+30,RMAX_PEOPLE);
|
||
|
save_table[SAVE_TABLE_DTWEEN].Maximum =MIN(save_table[SAVE_TABLE_DTWEEN].Extra+count_tween+30,RMAX_DRAW_TWEENS);
|
||
|
save_table[SAVE_TABLE_DMESH].Maximum =MIN(save_table[SAVE_TABLE_DMESH].Extra+count_mesh+30,RMAX_DRAW_MESHES);
|
||
|
}
|
||
|
|
||
|
|
||
|
if(count_special>max_special)
|
||
|
{
|
||
|
max_special=count_special;
|
||
|
DebugText(" MOSTspecialS %d \n",max_special);
|
||
|
}
|
||
|
if(count_bat>max_bat)
|
||
|
{
|
||
|
max_bat=count_bat;
|
||
|
DebugText(" MOSTbatS %d \n",max_bat);
|
||
|
}
|
||
|
if(count_mesh>max_mesh)
|
||
|
{
|
||
|
max_mesh=count_mesh;
|
||
|
DebugText(" MOSTmeshS %d \n",max_mesh);
|
||
|
}
|
||
|
if(count_tween>max_tween)
|
||
|
{
|
||
|
max_tween=count_tween;
|
||
|
DebugText(" MOSTtweenS %d \n",max_tween);
|
||
|
}
|
||
|
if(count_anim>max_anim)
|
||
|
{
|
||
|
max_anim=count_anim;
|
||
|
DebugText(" MOSTanimS %d \n",max_anim);
|
||
|
}
|
||
|
|
||
|
if(count_car>max_car)
|
||
|
{
|
||
|
max_car=count_car;
|
||
|
DebugText(" MOSTCARS %d \n",max_car);
|
||
|
}
|
||
|
if(count_people>max_people)
|
||
|
{
|
||
|
max_people=count_people;
|
||
|
DebugText(" MOSTPEOPLE %d \n",max_people);
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<MAX_PLAYERS;c0++)
|
||
|
{
|
||
|
NET_PERSON(c0)=(Thing*)THING_NUMBER(NET_PERSON(c0));
|
||
|
NET_PLAYER(c0)=(Thing*)THING_NUMBER(NET_PLAYER(c0));
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<EWAY_mess_upto;c0++)
|
||
|
{
|
||
|
EWAY_mess[c0]=(CBYTE*)((SLONG)(EWAY_mess[c0]-EWAY_mess_buffer));
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<PYRO_COUNT;c0++)
|
||
|
{
|
||
|
if(TO_PYRO(c0)->thing)
|
||
|
TO_PYRO(c0)->thing=(Thing*)THING_NUMBER(TO_PYRO(c0)->thing);
|
||
|
|
||
|
if(TO_PYRO(c0)->victim)
|
||
|
TO_PYRO(c0)->victim=(Thing*)THING_NUMBER(TO_PYRO(c0)->victim);
|
||
|
}
|
||
|
|
||
|
#ifndef BUILD_PSX
|
||
|
// cutscene stuff. convert the track pointers first:
|
||
|
for(c0=0;c0<PLAYCUTS_cutscene_ctr;c0++)
|
||
|
{
|
||
|
PLAYCUTS_cutscenes[c0].channels=(CPChannel*)(PLAYCUTS_cutscenes[c0].channels-PLAYCUTS_tracks);
|
||
|
}
|
||
|
for(c0=0;c0<PLAYCUTS_track_ctr;c0++)
|
||
|
{
|
||
|
PLAYCUTS_tracks[c0].packets=(CPPacket*)(PLAYCUTS_tracks[c0].packets-PLAYCUTS_packets);
|
||
|
}
|
||
|
for(c0=0;c0<PLAYCUTS_packet_ctr;c0++)
|
||
|
{
|
||
|
// if (PLAYCUTS_packets[c0].type==PT_TEXT) PLAYCUTS_packets[c0].pos.X-=PLAYCUTS_text_data;
|
||
|
if (PLAYCUTS_packets[c0].type==5) PLAYCUTS_packets[c0].pos.X-=(ULONG)PLAYCUTS_text_data;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
#define STORE_DATA(a) FileWrite(handle,(UBYTE*)&a,sizeof(a));DebugText(" store data %d \n",sizeof(a))
|
||
|
|
||
|
void convert_keyframe_to_index(GameKeyFrame *p,GameKeyFrameElement *p_ele,GameFightCol *p_fight,SLONG count)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
for(c0=0;c0<count;c0++)
|
||
|
{
|
||
|
p[c0].FirstElement=(GameKeyFrameElement *)((SLONG)(p[c0].FirstElement-p_ele));
|
||
|
p[c0].PrevFrame=(GameKeyFrame*)((SLONG)(p[c0].PrevFrame-p));
|
||
|
p[c0].NextFrame=(GameKeyFrame*)((SLONG)(p[c0].NextFrame-p));
|
||
|
p[c0].Fight=(GameFightCol*)((SLONG)(p[c0].Fight-p_fight));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void convert_animlist_to_index(GameKeyFrame **p,GameKeyFrame *p_anim,SLONG count)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
for(c0=0;c0<count;c0++)
|
||
|
{
|
||
|
p[c0]=(GameKeyFrame*)((SLONG)(p[c0]-p_anim));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void convert_fightcol_to_index(GameFightCol *p,GameFightCol *p_fight,SLONG count)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
for(c0=0;c0<count;c0++)
|
||
|
{
|
||
|
p[c0].Next=(GameFightCol*)((SLONG)(p[c0].Next-p_fight));
|
||
|
}
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
void convert_keyframe_to_pointer(GameKeyFrame *p,GameKeyFrameElement *p_ele,GameFightCol *p_fight,SLONG count)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
|
||
|
|
||
|
ASSERT(( ((ULONG)p)&3)==0);
|
||
|
ASSERT(( ((ULONG)p_ele)&3)==0);
|
||
|
ASSERT(( ((ULONG)p_fight)&3)==0);
|
||
|
|
||
|
for(c0=0;c0<count;c0++)
|
||
|
{
|
||
|
if(((SLONG)p[c0].FirstElement)<0)
|
||
|
p[c0].FirstElement=NULL;
|
||
|
else
|
||
|
p[c0].FirstElement=&p_ele[(SLONG)p[c0].FirstElement];
|
||
|
|
||
|
if(((SLONG)p[c0].PrevFrame)<0)
|
||
|
p[c0].PrevFrame=NULL;
|
||
|
else
|
||
|
p[c0].PrevFrame=&p[(SLONG)p[c0].PrevFrame];
|
||
|
|
||
|
if(((SLONG)p[c0].NextFrame)<0)
|
||
|
p[c0].NextFrame=NULL;
|
||
|
else
|
||
|
p[c0].NextFrame=&p[(SLONG)p[c0].NextFrame];
|
||
|
|
||
|
if(((SLONG)p[c0].Fight)<0)
|
||
|
p[c0].Fight=NULL;
|
||
|
else
|
||
|
p[c0].Fight=&p_fight[(SLONG)p[c0].Fight];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void convert_animlist_to_pointer(GameKeyFrame **p,GameKeyFrame *p_anim,SLONG count)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
for(c0=0;c0<count;c0++)
|
||
|
{
|
||
|
p[c0]=&p_anim[(SLONG)p[c0]];
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void convert_fightcol_to_pointer(GameFightCol *p,GameFightCol *p_fight,SLONG count)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
for(c0=0;c0<count;c0++)
|
||
|
{
|
||
|
|
||
|
if(((SLONG)p[c0].Next)<0)
|
||
|
p[c0].Next=0;
|
||
|
else
|
||
|
p[c0].Next=&p_fight[(SLONG)p[c0].Next];
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
#ifndef PSX
|
||
|
|
||
|
void save_whole_anims(MFFileHandle handle)
|
||
|
{
|
||
|
SLONG c0,c1;
|
||
|
SLONG blank=-1;
|
||
|
SLONG check=666;
|
||
|
|
||
|
|
||
|
STORE_DATA(next_game_chunk);
|
||
|
STORE_DATA(next_anim_chunk);
|
||
|
|
||
|
for(c0=0;c0<next_game_chunk;c0++)
|
||
|
{
|
||
|
if(game_chunk[c0].MultiObject[0])
|
||
|
{
|
||
|
struct GameKeyFrameChunk *gc;
|
||
|
gc=&game_chunk[c0];
|
||
|
STORE_DATA(c0); //4
|
||
|
STORE_DATA(gc->MaxPeopleTypes); //2
|
||
|
STORE_DATA(gc->MaxKeyFrames); //2
|
||
|
STORE_DATA(gc->MaxAnimFrames); //2
|
||
|
STORE_DATA(gc->MaxFightCols); //2
|
||
|
STORE_DATA(gc->MaxElements); //4
|
||
|
STORE_DATA(gc->ElementCount); //4
|
||
|
|
||
|
//
|
||
|
// Convert the pointers to indexes
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_index(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_index(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_index(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
//
|
||
|
// now save the data blocks
|
||
|
//
|
||
|
STORE_DATA(check);
|
||
|
for(c1=0;c1<10;c1++)
|
||
|
{
|
||
|
STORE_DATA(gc->MultiObject[c1]);
|
||
|
}
|
||
|
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->PeopleTypes,gc->MaxPeopleTypes*sizeof(struct BodyDef));
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimKeyFrames,gc->MaxKeyFrames*sizeof(GameKeyFrame));
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimList,gc->MaxAnimFrames*sizeof(GameKeyFrame*));
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->TheElements,gc->MaxElements*sizeof(GameKeyFrameElement));
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->FightCols,gc->MaxFightCols*sizeof(GameFightCol));
|
||
|
STORE_DATA(check);
|
||
|
|
||
|
//
|
||
|
// Now convert the indexes back to pointers
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_pointer(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_pointer(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_pointer(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
STORE_DATA(blank);
|
||
|
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<next_anim_chunk;c0++)
|
||
|
{
|
||
|
if(anim_chunk[c0].MultiObject[0])
|
||
|
{
|
||
|
struct GameKeyFrameChunk *gc;
|
||
|
gc=&anim_chunk[c0];
|
||
|
STORE_DATA(c0); //4
|
||
|
STORE_DATA(gc->MaxPeopleTypes); //2
|
||
|
STORE_DATA(gc->MaxKeyFrames); //2
|
||
|
STORE_DATA(gc->MaxAnimFrames); //2
|
||
|
STORE_DATA(gc->MaxFightCols); //2
|
||
|
STORE_DATA(gc->MaxElements); //4
|
||
|
STORE_DATA(gc->ElementCount); //4
|
||
|
|
||
|
//
|
||
|
// Convert the pointers to indexes
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_index(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_index(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_index(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
//
|
||
|
// now save the data blocks
|
||
|
//
|
||
|
for(c1=0;c1<10;c1++)
|
||
|
{
|
||
|
STORE_DATA(gc->MultiObject[c1]);
|
||
|
}
|
||
|
|
||
|
// FileWrite(handle,(UBYTE*)&gc->MultiObject[0],10*sizeof(UWORD));
|
||
|
FileWrite(handle,(UBYTE*)gc->PeopleTypes,gc->MaxPeopleTypes*sizeof(struct BodyDef));
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimKeyFrames,gc->MaxKeyFrames*sizeof(GameKeyFrame));
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimList,gc->MaxAnimFrames*sizeof(GameKeyFrame*));
|
||
|
FileWrite(handle,(UBYTE*)gc->TheElements,gc->MaxElements*sizeof(GameKeyFrameElement));
|
||
|
FileWrite(handle,(UBYTE*)gc->FightCols,gc->MaxFightCols*sizeof(GameFightCol));
|
||
|
|
||
|
//
|
||
|
// Now convert the indexes back to pointers
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_pointer(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_pointer(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_pointer(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
STORE_DATA(blank);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
SLONG find_best_anim_offset_old(SLONG mx,SLONG my,SLONG mz,SLONG bdist)
|
||
|
{
|
||
|
SLONG c0,dist;
|
||
|
|
||
|
bdist=128-bdist;
|
||
|
ASSERT(bdist>0);
|
||
|
|
||
|
for(c0=0;(unsigned)c0<next_anim_mids;c0++)
|
||
|
{
|
||
|
SLONG dx,dy,dz;
|
||
|
dx=anim_mids[c0].X-mx;
|
||
|
dy=anim_mids[c0].Y-my;
|
||
|
dz=anim_mids[c0].Z-mz;
|
||
|
|
||
|
dist=Root(dx*dx+dy*dy+dz*dz);
|
||
|
if(dist<bdist)
|
||
|
return(c0);
|
||
|
}
|
||
|
|
||
|
if(next_anim_mids<256)
|
||
|
{
|
||
|
anim_mids[next_anim_mids].X=mx;
|
||
|
anim_mids[next_anim_mids].Y=my;
|
||
|
anim_mids[next_anim_mids].Z=mz;
|
||
|
next_anim_mids++;
|
||
|
return(next_anim_mids-1);
|
||
|
}
|
||
|
ASSERT(0);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
SLONG find_best_anim_offset(SLONG mx,SLONG my,SLONG mz,SLONG anim,struct GameKeyFrameChunk *gc)
|
||
|
{
|
||
|
SLONG c0,dist,bdist;
|
||
|
|
||
|
|
||
|
// if(anim<1565 || anim>1570)
|
||
|
if(1)
|
||
|
{
|
||
|
for(c0=0;(unsigned)c0<next_anim_mids;c0++)
|
||
|
{
|
||
|
SLONG cx,cy,cz;
|
||
|
SLONG dx,dy,dz;
|
||
|
SLONG ele;
|
||
|
|
||
|
bdist=0;
|
||
|
cx=anim_mids[c0].X;
|
||
|
cy=anim_mids[c0].Y;
|
||
|
cz=anim_mids[c0].Z;
|
||
|
|
||
|
for(ele=0;ele<gc->ElementCount;ele++)
|
||
|
{
|
||
|
dx=gc->AnimKeyFrames[anim].FirstElement[ele].OffsetX+mx-cx;
|
||
|
dy=gc->AnimKeyFrames[anim].FirstElement[ele].OffsetY+my-cy;
|
||
|
dz=gc->AnimKeyFrames[anim].FirstElement[ele].OffsetZ+mz-cz;
|
||
|
dist=Root(dx*dx+dy*dy+dz*dz);
|
||
|
if(dist>bdist)
|
||
|
bdist=dist;
|
||
|
}
|
||
|
if(bdist<128)
|
||
|
return(c0);
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
|
||
|
}
|
||
|
|
||
|
if(next_anim_mids<256)
|
||
|
{
|
||
|
DebugText(" added a new anim_mid %d (%d,%d,%d)\n",next_anim_mids,mx,my,mz);
|
||
|
anim_mids[next_anim_mids].X=mx;
|
||
|
anim_mids[next_anim_mids].Y=my;
|
||
|
anim_mids[next_anim_mids].Z=mz;
|
||
|
next_anim_mids++;
|
||
|
return(next_anim_mids-1);
|
||
|
}
|
||
|
ASSERT(0);
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
|
||
|
extern void convert_to_psx_gke(GameKeyFrameElementComp *to, GameKeyFrameElement *from);
|
||
|
#ifndef ULTRA_COMPRESSED_ANIMATIONS
|
||
|
|
||
|
|
||
|
void fix_psxed_anims(void)
|
||
|
{
|
||
|
SLONG c0,c1,ele,index;
|
||
|
struct GameKeyFrameElementComp *p;
|
||
|
UWORD *bits;
|
||
|
|
||
|
for(c0=0;c0<next_game_chunk;c0++)
|
||
|
{
|
||
|
if(game_chunk[c0].MultiObject[0])
|
||
|
{
|
||
|
struct GameKeyFrameChunk *gc;
|
||
|
|
||
|
gc=&game_chunk[c0];
|
||
|
|
||
|
bits=(UWORD *)MemAlloc(sizeof(UWORD)*gc->MaxElements);
|
||
|
memset((UBYTE*)bits,0,gc->MaxElements*2);
|
||
|
|
||
|
if(c0!=5)
|
||
|
for(c1=0;c1<gc->MaxKeyFrames;c1++)
|
||
|
{
|
||
|
|
||
|
if(gc->AnimKeyFrames[c1].FirstElement)
|
||
|
{
|
||
|
SLONG ele_index;
|
||
|
ele_index=(ULONG)(gc->AnimKeyFrames[c1].FirstElement-gc->TheElements);
|
||
|
|
||
|
//
|
||
|
// don't want to do a keyframe twice
|
||
|
//
|
||
|
if(bits[ele_index])
|
||
|
{
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SLONG bdist=0;
|
||
|
SLONG mx,my,mz;
|
||
|
mx=anim_mids[gc->AnimKeyFrames[c1].XYZIndex].X;
|
||
|
my=anim_mids[gc->AnimKeyFrames[c1].XYZIndex].Y;
|
||
|
mz=anim_mids[gc->AnimKeyFrames[c1].XYZIndex].Z;
|
||
|
|
||
|
for(ele=0;ele<gc->ElementCount;ele++)
|
||
|
{
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX+=mx;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY+=my;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ+=mz;
|
||
|
|
||
|
}
|
||
|
|
||
|
bits[ele_index]=1; //done
|
||
|
}
|
||
|
}
|
||
|
gc->AnimKeyFrames[c1].XYZIndex=0;
|
||
|
}
|
||
|
MemFree(bits);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
next_anim_mids=0;
|
||
|
|
||
|
}
|
||
|
|
||
|
void save_whole_anims_psx(MFFileHandle handle)
|
||
|
{
|
||
|
SLONG c0,c1;
|
||
|
SLONG blank=-1;
|
||
|
SLONG check=666;
|
||
|
struct GameKeyFrameElementComp *p;
|
||
|
UWORD *bits;
|
||
|
ULONG ele_index,ele;
|
||
|
SLONG big_x=0,big_y=0,big_z=0;
|
||
|
|
||
|
next_anim_mids=0;
|
||
|
|
||
|
STORE_DATA(next_game_chunk);
|
||
|
STORE_DATA(next_anim_chunk);
|
||
|
|
||
|
for(c0=0;c0<next_game_chunk;c0++)
|
||
|
{
|
||
|
if(game_chunk[c0].MultiObject[0])
|
||
|
{
|
||
|
struct GameKeyFrameChunk *gc;
|
||
|
|
||
|
gc=&game_chunk[c0];
|
||
|
|
||
|
p=(struct GameKeyFrameElementComp *)MemAlloc(sizeof(struct GameKeyFrameElementComp)*gc->MaxElements);
|
||
|
bits=(UWORD *)MemAlloc(sizeof(UWORD)*gc->MaxElements);
|
||
|
memset((UBYTE*)bits,0,gc->MaxElements*2);
|
||
|
|
||
|
if(c0!=5)
|
||
|
for(c1=0;c1<gc->MaxKeyFrames;c1++)
|
||
|
{
|
||
|
SLONG bx=0,by=0,bz=0;//999999,by=9999999,bz=9999999,ele;
|
||
|
UWORD off_bits=0;
|
||
|
|
||
|
// ASSERT(c1!=1565);
|
||
|
if(gc->AnimKeyFrames[c1].FirstElement)
|
||
|
{
|
||
|
ele_index=(ULONG)(gc->AnimKeyFrames[c1].FirstElement-gc->TheElements);
|
||
|
|
||
|
//
|
||
|
// don't want to do a keyframe twice
|
||
|
//
|
||
|
if(bits[ele_index])
|
||
|
{
|
||
|
gc->AnimKeyFrames[c1].XYZIndex=bits[ele_index]-1;
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
SLONG bdist=0;
|
||
|
for(ele=0;(signed)ele<gc->ElementCount;ele++)
|
||
|
{
|
||
|
|
||
|
//if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX<bx)
|
||
|
bx+=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX);
|
||
|
|
||
|
//if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY<by)
|
||
|
by+=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY);
|
||
|
|
||
|
//if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ<bz)
|
||
|
bz+=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ);
|
||
|
|
||
|
}
|
||
|
bx/=gc->ElementCount;
|
||
|
by/=gc->ElementCount;
|
||
|
bz/=gc->ElementCount;
|
||
|
/*
|
||
|
bx+=128;
|
||
|
by+=128;
|
||
|
bz+=128;
|
||
|
bx&=0xffffff00;
|
||
|
by&=0xffffff00;
|
||
|
bz&=0xffffff00;
|
||
|
*/
|
||
|
|
||
|
for(ele=0;(signed)ele<gc->ElementCount;ele++)
|
||
|
{
|
||
|
SLONG dx,dy,dz,dist;
|
||
|
|
||
|
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX-=bx;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY-=by;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ-=bz;
|
||
|
|
||
|
dx=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX);
|
||
|
dy=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY);
|
||
|
dz=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ);
|
||
|
dist=Root(dx*dx+dy*dy+dz*dz);
|
||
|
|
||
|
if(dist>bdist)
|
||
|
bdist=dist;
|
||
|
|
||
|
|
||
|
if(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX)>abs(big_x))
|
||
|
big_x=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX);
|
||
|
|
||
|
if(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY)>abs(big_y))
|
||
|
big_y=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY);
|
||
|
|
||
|
if(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ)>abs(big_z))
|
||
|
big_z=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// ASSERT(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX>=-128 && gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX<128);
|
||
|
// ASSERT(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY>=-128 && gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY<128);
|
||
|
// ASSERT(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ>=-128 && gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ<128);
|
||
|
|
||
|
}
|
||
|
ASSERT(bdist<128);
|
||
|
ASSERT(abs(big_x)<128);
|
||
|
ASSERT(abs(big_y)<128);
|
||
|
ASSERT(abs(big_z)<128);
|
||
|
|
||
|
{
|
||
|
SLONG dx,dy,dz;
|
||
|
SLONG index;
|
||
|
|
||
|
index=find_best_anim_offset(bx,by,bz,c1,gc);
|
||
|
|
||
|
dx=bx-anim_mids[index].X;
|
||
|
dy=by-anim_mids[index].Y;
|
||
|
dz=bz-anim_mids[index].Z;
|
||
|
|
||
|
for(ele=0;(signed)ele<gc->ElementCount;ele++)
|
||
|
{
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX+=dx;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY+=dy;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ+=dz;
|
||
|
ASSERT(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX)<128);
|
||
|
ASSERT(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY)<128);
|
||
|
ASSERT(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ)<128);
|
||
|
|
||
|
}
|
||
|
gc->AnimKeyFrames[c1].XYZIndex=index;
|
||
|
bits[ele_index]=index+1; //done
|
||
|
|
||
|
}
|
||
|
|
||
|
/*
|
||
|
off_bits=(bx&0x700)>>7;
|
||
|
off_bits|=(bz&0x700)>>4;
|
||
|
off_bits|=(by&0xff00);
|
||
|
bits[ele_index]=off_bits|1;
|
||
|
*/
|
||
|
// bits[ele_index]=1; //done
|
||
|
}
|
||
|
gc->AnimKeyFrames[c1].Flags=(gc->AnimKeyFrames[c1].Flags&1);//|off_bits;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
DebugText(" game chunk %d bigx %d bigy %d bigz %d \n",c0,big_x,big_y,big_z);
|
||
|
|
||
|
big_x=0;
|
||
|
big_y=0;
|
||
|
big_z=0;
|
||
|
|
||
|
|
||
|
|
||
|
for(c1=0;c1<gc->MaxElements;c1++)
|
||
|
{
|
||
|
convert_to_psx_gke(&p[c1],&gc->TheElements[c1]);
|
||
|
}
|
||
|
|
||
|
|
||
|
STORE_DATA(c0); //4
|
||
|
STORE_DATA(gc->MaxPeopleTypes); //2
|
||
|
STORE_DATA(gc->MaxKeyFrames); //2
|
||
|
STORE_DATA(gc->MaxAnimFrames); //2
|
||
|
STORE_DATA(gc->MaxFightCols); //2
|
||
|
STORE_DATA(gc->MaxElements); //4
|
||
|
STORE_DATA(gc->ElementCount); //4
|
||
|
|
||
|
//
|
||
|
// Convert the pointers to indexes
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_index(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_index(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_index(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
//
|
||
|
// now save the data blocks
|
||
|
//
|
||
|
STORE_DATA(check);
|
||
|
for(c1=0;c1<10;c1++)
|
||
|
{
|
||
|
STORE_DATA(gc->MultiObject[c1]);
|
||
|
}
|
||
|
|
||
|
|
||
|
STORE_DATA(check);
|
||
|
DebugText(" peep_types -> %d tot %d\n",gc->MaxPeopleTypes,gc->MaxPeopleTypes*sizeof(struct BodyDef));
|
||
|
DebugText(" keyframes -> %d tot %d\n",gc->MaxKeyFrames,gc->MaxKeyFrames*sizeof(GameKeyFrame));
|
||
|
DebugText(" animlist -> %d tot %d\n",gc->MaxAnimFrames,gc->MaxAnimFrames*sizeof(GameKeyFrame*));
|
||
|
DebugText(" elements -> %d tot %d\n",gc->MaxElements,gc->MaxElements*sizeof(GameKeyFrameElementComp));
|
||
|
DebugText(" fightcols -> %d tot %d\n",gc->MaxFightCols,gc->MaxFightCols*sizeof(GameFightCol));
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
FileWrite(handle,(UBYTE*)gc->PeopleTypes,gc->MaxPeopleTypes*sizeof(struct BodyDef));
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimKeyFrames,gc->MaxKeyFrames*sizeof(GameKeyFrame));
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimList,gc->MaxAnimFrames*sizeof(GameKeyFrame*));
|
||
|
STORE_DATA(check);
|
||
|
// FileWrite(handle,(UBYTE*)gc->TheElements,gc->MaxElements*sizeof(GameKeyFrameElement));
|
||
|
FileWrite(handle,(UBYTE*)p,gc->MaxElements*sizeof(GameKeyFrameElementComp));
|
||
|
STORE_DATA(check);
|
||
|
FileWrite(handle,(UBYTE*)gc->FightCols,gc->MaxFightCols*sizeof(GameFightCol));
|
||
|
STORE_DATA(check);
|
||
|
|
||
|
//
|
||
|
// Now convert the indexes back to pointers
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_pointer(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_pointer(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_pointer(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
MemFree(p);
|
||
|
MemFree(bits);
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
STORE_DATA(blank);
|
||
|
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<next_anim_chunk;c0++)
|
||
|
{
|
||
|
if(anim_chunk[c0].MultiObject[0])
|
||
|
{
|
||
|
struct GameKeyFrameChunk *gc;
|
||
|
UWORD ele_index;
|
||
|
|
||
|
gc=&anim_chunk[c0];
|
||
|
|
||
|
|
||
|
|
||
|
p=(struct GameKeyFrameElementComp *)MemAlloc(sizeof(struct GameKeyFrameElementComp)*gc->MaxElements);
|
||
|
bits=(UWORD *)MemAlloc(sizeof(UWORD)*gc->MaxElements);
|
||
|
memset((UBYTE*)bits,0,gc->MaxElements*2);
|
||
|
|
||
|
/*
|
||
|
for(c1=0;c1<gc->MaxKeyFrames;c1++)
|
||
|
{
|
||
|
SLONG bx=0,by=0,bz=0;//999999,by=9999999,bz=9999999,ele;
|
||
|
UWORD off_bits=0;
|
||
|
if(gc->AnimKeyFrames[c1].FirstElement)
|
||
|
{
|
||
|
ele_index=(ULONG)(gc->AnimKeyFrames[c1].FirstElement-gc->TheElements);
|
||
|
if(bits[ele_index])
|
||
|
{
|
||
|
off_bits=bits[ele_index]&0xfffe;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for(ele=0;ele<gc->ElementCount;ele++)
|
||
|
{
|
||
|
|
||
|
//if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX<bx)
|
||
|
bx+=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX);
|
||
|
|
||
|
//if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY<by)
|
||
|
by+=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY);
|
||
|
|
||
|
//if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ<bz)
|
||
|
bz+=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ);
|
||
|
|
||
|
}
|
||
|
bx/=gc->ElementCount;
|
||
|
by/=gc->ElementCount;
|
||
|
bz/=gc->ElementCount;
|
||
|
|
||
|
bx+=128;
|
||
|
by+=128;
|
||
|
bz+=128;
|
||
|
bx&=0xffffff00;
|
||
|
by&=0xffffff00;
|
||
|
bz&=0xffffff00;
|
||
|
|
||
|
for(ele=0;ele<gc->ElementCount;ele++)
|
||
|
{
|
||
|
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX-=bx;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY-=by;
|
||
|
gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ-=bz;
|
||
|
|
||
|
if(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX)>abs(big_x))
|
||
|
big_x=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX);
|
||
|
|
||
|
if(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY)>abs(big_y))
|
||
|
big_y=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY);
|
||
|
|
||
|
if(abs(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ)>abs(big_z))
|
||
|
big_z=(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ);
|
||
|
|
||
|
|
||
|
// ASSERT(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX>=-128 && gc->AnimKeyFrames[c1].FirstElement[ele].OffsetX<128);
|
||
|
// ASSERT(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY>=-128 && gc->AnimKeyFrames[c1].FirstElement[ele].OffsetY<128);
|
||
|
// ASSERT(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ>=-128 && gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZ<128);
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
off_bits=(bx&0x700)>>7;
|
||
|
off_bits|=(bz&0x700)>>4;
|
||
|
off_bits|=(by&0xff00);
|
||
|
bits[ele_index]=off_bits|1;
|
||
|
}
|
||
|
gc->AnimKeyFrames[c1].Flags=(gc->AnimKeyFrames[c1].Flags&1)|off_bits;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
|
||
|
for(c1=0;c1<gc->MaxElements;c1++)
|
||
|
{
|
||
|
convert_to_psx_gke(&p[c1],&gc->TheElements[c1]);
|
||
|
}
|
||
|
|
||
|
|
||
|
STORE_DATA(c0); //4
|
||
|
STORE_DATA(gc->MaxPeopleTypes); //2
|
||
|
STORE_DATA(gc->MaxKeyFrames); //2
|
||
|
STORE_DATA(gc->MaxAnimFrames); //2
|
||
|
STORE_DATA(gc->MaxFightCols); //2
|
||
|
STORE_DATA(gc->MaxElements); //4
|
||
|
STORE_DATA(gc->ElementCount); //4
|
||
|
|
||
|
//
|
||
|
// Convert the pointers to indexes
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_index(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_index(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_index(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
//
|
||
|
// now save the data blocks
|
||
|
//
|
||
|
for(c1=0;c1<10;c1++)
|
||
|
{
|
||
|
STORE_DATA(gc->MultiObject[c1]);
|
||
|
}
|
||
|
|
||
|
DebugText(" peep_types -> %d tot %d\n",gc->MaxPeopleTypes,gc->MaxPeopleTypes*sizeof(struct BodyDef));
|
||
|
DebugText(" keyframes -> %d tot %d\n",gc->MaxKeyFrames,gc->MaxKeyFrames*sizeof(GameKeyFrame));
|
||
|
DebugText(" animlist -> %d tot %d\n",gc->MaxAnimFrames,gc->MaxAnimFrames*sizeof(GameKeyFrame*));
|
||
|
DebugText(" elements -> %d tot %d\n",gc->MaxElements,gc->MaxElements*sizeof(GameKeyFrameElementComp));
|
||
|
DebugText(" fightcols -> %d tot %d\n",gc->MaxFightCols,gc->MaxFightCols*sizeof(GameFightCol));
|
||
|
|
||
|
// FileWrite(handle,(UBYTE*)&gc->MultiObject[0],10*sizeof(UWORD));
|
||
|
FileWrite(handle,(UBYTE*)gc->PeopleTypes,gc->MaxPeopleTypes*sizeof(struct BodyDef));
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimKeyFrames,gc->MaxKeyFrames*sizeof(GameKeyFrame));
|
||
|
FileWrite(handle,(UBYTE*)gc->AnimList,gc->MaxAnimFrames*sizeof(GameKeyFrame*));
|
||
|
// FileWrite(handle,(UBYTE*)gc->TheElements,gc->MaxElements*sizeof(GameKeyFrameElement));
|
||
|
FileWrite(handle,(UBYTE*)p,gc->MaxElements*sizeof(GameKeyFrameElementComp));
|
||
|
FileWrite(handle,(UBYTE*)gc->FightCols,gc->MaxFightCols*sizeof(GameFightCol));
|
||
|
|
||
|
//
|
||
|
// Now convert the indexes back to pointers
|
||
|
//
|
||
|
|
||
|
convert_keyframe_to_pointer(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_pointer(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_pointer(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
DebugText(" anim chunk %d bigx %d bigy %d bigz %d \n",c0,big_x,big_y,big_z);
|
||
|
|
||
|
big_x=0;
|
||
|
big_y=0;
|
||
|
big_z=0;
|
||
|
MemFree(p);
|
||
|
MemFree(bits);
|
||
|
|
||
|
}
|
||
|
else
|
||
|
STORE_DATA(blank);
|
||
|
|
||
|
}
|
||
|
STORE_DATA(next_anim_mids);
|
||
|
FileWrite(handle,(UBYTE*)anim_mids,next_anim_mids*sizeof(PrimPoint));
|
||
|
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
#define getPSXU(page) (((page)&7)<<5)
|
||
|
#define getPSXV(page) (((page)&0x38)<<2)
|
||
|
|
||
|
//#ifdef PSX
|
||
|
extern UWORD psx_start_page;
|
||
|
//#endif
|
||
|
void fix_psx_face3(struct PrimFace3PSX *p2)
|
||
|
{
|
||
|
//#ifdef PSX
|
||
|
ULONG page;
|
||
|
SLONG x;
|
||
|
SLONG u,v;
|
||
|
|
||
|
page=p2->TexturePage;//|((p2->UV[0][0]&0xc0)<<2)+(8<<6);
|
||
|
p2->TexturePage+=(psx_start_page>>6)<<6;
|
||
|
|
||
|
p2->UV[0][0]&=0x3f;
|
||
|
|
||
|
u=getPSXU(page);
|
||
|
v=getPSXV(page);
|
||
|
|
||
|
for(x=0;x<3;x++)
|
||
|
{
|
||
|
if (p2->UV[x][0]==32) p2->UV[x][0]=31;
|
||
|
p2->UV[x][0]+=u;
|
||
|
if (p2->UV[x][1]==32) p2->UV[x][1]=31;
|
||
|
p2->UV[x][1]+=v;
|
||
|
}
|
||
|
//#endif
|
||
|
}
|
||
|
|
||
|
void fix_psx_face4(struct PrimFace4PSX *p)
|
||
|
{
|
||
|
//#ifdef PSX
|
||
|
ULONG page;
|
||
|
SLONG x;
|
||
|
SLONG u,v;
|
||
|
|
||
|
page=p->TexturePage;
|
||
|
if (!(p->FaceFlags & FACE_FLAG_WALKABLE))
|
||
|
p->TexturePage+=(psx_start_page>>6)<<6;
|
||
|
|
||
|
p->UV[0][0]&=0x3f;
|
||
|
u=getPSXU(page);
|
||
|
v=getPSXV(page);
|
||
|
|
||
|
for(x=0;x<4;x++)
|
||
|
{
|
||
|
if (p->UV[x][0]==32) p->UV[x][0]=31;
|
||
|
p->UV[x][0]+=u;
|
||
|
if (p->UV[x][1]==32) p->UV[x][1]=31;
|
||
|
p->UV[x][1]+=v;
|
||
|
}
|
||
|
//#endif
|
||
|
}
|
||
|
void save_whole_wad(CBYTE *gamename,UBYTE type)
|
||
|
{
|
||
|
|
||
|
// return;
|
||
|
|
||
|
SLONG c0=0;
|
||
|
SLONG *p_slong;
|
||
|
UWORD *p_uword;
|
||
|
UBYTE *p_mem;
|
||
|
SLONG mem_size,mem_cumlative=0;
|
||
|
struct MemTable *ptab;
|
||
|
MFFileHandle handle = FILE_OPEN_ERROR;
|
||
|
SLONG count;
|
||
|
SLONG save_type=0;
|
||
|
SLONG check=666;
|
||
|
UBYTE padding_byte;
|
||
|
UWORD padding_word;
|
||
|
ULONG struct_size;
|
||
|
|
||
|
|
||
|
set_darci_normals();
|
||
|
//
|
||
|
// remove anything that can't survive the reload (transient effects)
|
||
|
//
|
||
|
|
||
|
|
||
|
handle=FileCreate(gamename,1);
|
||
|
if(handle!=FILE_CREATION_ERROR)
|
||
|
{
|
||
|
// get rid of the nasty pointers
|
||
|
// by converting to indexes
|
||
|
convert_pointers_to_index();
|
||
|
DebugText("\n SAVE INGAME \n");
|
||
|
|
||
|
STORE_DATA(save_type);
|
||
|
|
||
|
|
||
|
|
||
|
while(save_table[c0].Point)
|
||
|
{
|
||
|
mem_size=0;
|
||
|
count=0;
|
||
|
// ASSERT(c0!=29);
|
||
|
ptab=&save_table[c0];
|
||
|
switch(ptab->Type)
|
||
|
{
|
||
|
case 2:
|
||
|
mem_size=ptab->Maximum*ptab->StructSize;
|
||
|
count=ptab->Maximum;
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
if(ptab->CountL)
|
||
|
{
|
||
|
count=*ptab->CountL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(ptab->CountW)
|
||
|
count=*ptab->CountW;
|
||
|
else
|
||
|
ASSERT(0);
|
||
|
}
|
||
|
if(ptab->Extra) //redundant but more readable!
|
||
|
count+=ptab->Extra; // we have some extra ones so increase how many we create, this is also saved into the next_blah_blah filed but the loader will subtract this off for next_blah_blah
|
||
|
|
||
|
mem_size=count*ptab->StructSize;
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if(c0==16)
|
||
|
{
|
||
|
struct PrimFace4PSX *block;
|
||
|
SLONG index;
|
||
|
// special PSX primface4
|
||
|
DebugText(" prim face 4 psx = %d was %d\n",count*sizeof(struct PrimFace4PSX),mem_size);
|
||
|
mem_size=count*sizeof(struct PrimFace4PSX);
|
||
|
block=(struct PrimFace4PSX*)MemAlloc(mem_size);
|
||
|
|
||
|
for(index=0;index<*ptab->CountW;index++)
|
||
|
{
|
||
|
SLONG page;
|
||
|
SLONG i,j;
|
||
|
block[index].Points[0]=prim_faces4[index].Points[0];
|
||
|
block[index].Points[1]=prim_faces4[index].Points[1];
|
||
|
block[index].Points[2]=prim_faces4[index].Points[2];
|
||
|
block[index].Points[3]=prim_faces4[index].Points[3];
|
||
|
|
||
|
for(j=0;j<4;j++)
|
||
|
for(i=0;i<2;i++)
|
||
|
{
|
||
|
block[index].UV[j][i]=prim_faces4[index].UV[j][i];
|
||
|
}
|
||
|
block[index].FaceFlags=prim_faces4[index].FaceFlags;
|
||
|
block[index].DrawFlags=prim_faces4[index].DrawFlags;
|
||
|
|
||
|
page = prim_faces4[index].UV[0][0] & 0xc0;
|
||
|
page <<= 2;
|
||
|
page |= prim_faces4[index].TexturePage;
|
||
|
|
||
|
block[index].ThingIndex=prim_faces4[index].ThingIndex;
|
||
|
if (prim_faces4[index].FaceFlags & FACE_FLAG_WALKABLE)
|
||
|
{
|
||
|
block[index].TexturePage=prim_faces4[index].WALKABLE;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
block[index].TexturePage=page;
|
||
|
}
|
||
|
block[index].AltPal=0;
|
||
|
fix_psx_face4(&block[index]);
|
||
|
|
||
|
}
|
||
|
// chunk id
|
||
|
FileWrite(handle,(UBYTE*)&c0,4);
|
||
|
FileWrite(handle,(UBYTE*)&count,4);
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
{
|
||
|
ULONG size=sizeof(struct PrimFace4PSX);
|
||
|
FileWrite(handle,(UBYTE*)&size,4);
|
||
|
}
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4);
|
||
|
if(mem_size&3)
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4-(mem_size&3));
|
||
|
|
||
|
|
||
|
FileWrite(handle,(UBYTE*)block,mem_size);
|
||
|
MemFree(block);
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
if(c0==17)
|
||
|
{
|
||
|
struct PrimFace3PSX *block;
|
||
|
SLONG index;
|
||
|
// special PSX primface4
|
||
|
DebugText(" prim face3 psx = %d was %d\n",count*sizeof(struct PrimFace3PSX),mem_size);
|
||
|
mem_size=count*sizeof(struct PrimFace3PSX);
|
||
|
block=(struct PrimFace3PSX*)MemAlloc(mem_size);
|
||
|
|
||
|
for(index=0;index<*ptab->CountW;index++)
|
||
|
{
|
||
|
SLONG page;
|
||
|
SLONG i,j;
|
||
|
block[index].Points[0]=prim_faces3[index].Points[0];
|
||
|
block[index].Points[1]=prim_faces3[index].Points[1];
|
||
|
block[index].Points[2]=prim_faces3[index].Points[2];
|
||
|
|
||
|
for(j=0;j<3;j++)
|
||
|
for(i=0;i<2;i++)
|
||
|
{
|
||
|
block[index].UV[j][i]=prim_faces3[index].UV[j][i];
|
||
|
}
|
||
|
block[index].FaceFlags=prim_faces3[index].FaceFlags;
|
||
|
block[index].DrawFlags=prim_faces3[index].DrawFlags;
|
||
|
|
||
|
page = prim_faces3[index].UV[0][0] & 0xc0;
|
||
|
page <<= 2;
|
||
|
page |= prim_faces3[index].TexturePage;
|
||
|
|
||
|
block[index].ThingIndex=prim_faces3[index].ThingIndex;
|
||
|
if (prim_faces3[index].FaceFlags & FACE_FLAG_WALKABLE)
|
||
|
{
|
||
|
block[index].TexturePage=prim_faces3[index].WALKABLE;
|
||
|
}
|
||
|
else
|
||
|
block[index].TexturePage=page;
|
||
|
|
||
|
block[index].AltPal=0;
|
||
|
fix_psx_face3(&block[index]);
|
||
|
|
||
|
}
|
||
|
// chunk id
|
||
|
FileWrite(handle,(UBYTE*)&c0,4);
|
||
|
FileWrite(handle,(UBYTE*)&count,4);
|
||
|
{
|
||
|
ULONG size=sizeof(struct PrimFace3PSX);
|
||
|
FileWrite(handle,(UBYTE*)&size,4);
|
||
|
}
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4);
|
||
|
if(mem_size&3)
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4-(mem_size&3));
|
||
|
|
||
|
|
||
|
FileWrite(handle,(UBYTE*)block,mem_size);
|
||
|
MemFree(block);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
p_mem=(UBYTE*)*ptab->Point;
|
||
|
|
||
|
// chunk id
|
||
|
FileWrite(handle,(UBYTE*)&c0,4);
|
||
|
FileWrite(handle,(UBYTE*)&count,4);
|
||
|
struct_size=ptab->StructSize;
|
||
|
FileWrite(handle,(UBYTE*)&struct_size,4);
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4);
|
||
|
if(mem_size&3)
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4-(mem_size&3));
|
||
|
|
||
|
|
||
|
FileWrite(handle,(UBYTE*)p_mem,mem_size);
|
||
|
}
|
||
|
|
||
|
mem_cumlative+=mem_size;
|
||
|
if(ptab->CountL)
|
||
|
DebugText(" %s -> %d tot %d (%d/%d)\n",ptab->Name,mem_size,mem_cumlative,*ptab->CountL,ptab->Maximum);
|
||
|
else
|
||
|
if(ptab->CountW)
|
||
|
DebugText(" %s -> %d tot %d (%d/%d)\n",ptab->Name,mem_size,mem_cumlative,*ptab->CountW,ptab->Maximum);
|
||
|
else
|
||
|
DebugText(" %s -> %d tot %d (%d)\n",ptab->Name,mem_size,mem_cumlative,ptab->Maximum);
|
||
|
|
||
|
c0++;
|
||
|
}
|
||
|
DebugText("\n");
|
||
|
|
||
|
|
||
|
STORE_DATA(PRIMARY_USED);
|
||
|
STORE_DATA(PRIMARY_UNUSED);
|
||
|
STORE_DATA(SECONDARY_USED);
|
||
|
STORE_DATA(SECONDARY_UNUSED);
|
||
|
STORE_DATA(PERSON_COUNT);
|
||
|
STORE_DATA(PERSON_COUNT);
|
||
|
STORE_DATA(ANIMAL_COUNT);
|
||
|
STORE_DATA(CHOPPER_COUNT);
|
||
|
STORE_DATA(PYRO_COUNT);
|
||
|
STORE_DATA(PLAYER_COUNT);
|
||
|
STORE_DATA(PROJECTILE_COUNT);
|
||
|
STORE_DATA(SPECIAL_COUNT);
|
||
|
STORE_DATA(SWITCH_COUNT);
|
||
|
STORE_DATA(PRIMARY_COUNT);
|
||
|
STORE_DATA(SECONDARY_COUNT);
|
||
|
STORE_DATA(GAME_STATE);
|
||
|
STORE_DATA(GAME_TURN);
|
||
|
STORE_DATA(GAME_FLAGS);
|
||
|
STORE_DATA(TEXTURE_set);
|
||
|
STORE_DATA(WMOVE_face_upto);
|
||
|
STORE_DATA(first_walkable_prim_point);
|
||
|
STORE_DATA(number_of_walkable_prim_points);
|
||
|
STORE_DATA(first_walkable_prim_face4);
|
||
|
STORE_DATA(number_of_walkable_prim_faces4);
|
||
|
STORE_DATA(BARREL_sphere_last);
|
||
|
STORE_DATA(track_head);
|
||
|
STORE_DATA(track_tail);
|
||
|
STORE_DATA(track_eob);
|
||
|
STORE_DATA( NIGHT_dlight_free);
|
||
|
STORE_DATA( NIGHT_dlight_used);
|
||
|
|
||
|
|
||
|
STORE_DATA(EWAY_time_accurate);
|
||
|
STORE_DATA(EWAY_time);
|
||
|
STORE_DATA(EWAY_tick);
|
||
|
STORE_DATA(EWAY_cam_active);
|
||
|
STORE_DATA(EWAY_cam_x);
|
||
|
STORE_DATA(EWAY_cam_y);
|
||
|
STORE_DATA(EWAY_cam_z);
|
||
|
STORE_DATA(EWAY_cam_dx);
|
||
|
STORE_DATA(EWAY_cam_dy);
|
||
|
STORE_DATA(EWAY_cam_dz);
|
||
|
STORE_DATA(EWAY_cam_yaw);
|
||
|
STORE_DATA(EWAY_cam_pitch);
|
||
|
STORE_DATA(EWAY_cam_waypoint);
|
||
|
STORE_DATA(EWAY_cam_target);
|
||
|
STORE_DATA(EWAY_cam_delay);
|
||
|
STORE_DATA(EWAY_cam_speed);
|
||
|
STORE_DATA(EWAY_cam_freeze);
|
||
|
STORE_DATA(EWAY_cam_cant_interrupt);
|
||
|
STORE_DATA( NIGHT_amb_d3d_colour);
|
||
|
STORE_DATA( NIGHT_amb_d3d_specular);
|
||
|
STORE_DATA( NIGHT_amb_red);
|
||
|
STORE_DATA( NIGHT_amb_green);
|
||
|
STORE_DATA( NIGHT_amb_blue);
|
||
|
STORE_DATA( NIGHT_amb_norm_x);
|
||
|
STORE_DATA( NIGHT_amb_norm_y);
|
||
|
STORE_DATA( NIGHT_amb_norm_z);
|
||
|
STORE_DATA( NIGHT_flag);
|
||
|
STORE_DATA( NIGHT_lampost_radius);
|
||
|
STORE_DATA( NIGHT_lampost_red);
|
||
|
STORE_DATA( NIGHT_lampost_green);
|
||
|
STORE_DATA( NIGHT_lampost_blue);
|
||
|
STORE_DATA( NIGHT_sky_colour);
|
||
|
STORE_DATA(padding_byte);
|
||
|
STORE_DATA(check);
|
||
|
STORE_DATA(CRIME_RATE);
|
||
|
STORE_DATA(CRIME_RATE_SCORE_MUL);
|
||
|
STORE_DATA(MUSIC_WORLD);
|
||
|
STORE_DATA(BOREDOM_RATE);
|
||
|
STORE_DATA(world_type);
|
||
|
|
||
|
STORE_DATA(EWAY_fake_wander_text_normal_index );
|
||
|
STORE_DATA(EWAY_fake_wander_text_normal_number );
|
||
|
STORE_DATA(EWAY_fake_wander_text_guilty_index );
|
||
|
STORE_DATA(EWAY_fake_wander_text_guilty_number );
|
||
|
STORE_DATA(EWAY_fake_wander_text_annoyed_index );
|
||
|
STORE_DATA(EWAY_fake_wander_text_annoyed_number);
|
||
|
|
||
|
STORE_DATA(GAME_FLAGS);
|
||
|
|
||
|
STORE_DATA(semtex);
|
||
|
STORE_DATA(estate);
|
||
|
STORE_DATA(padding_word);
|
||
|
|
||
|
|
||
|
#ifdef OLD_CAM
|
||
|
|
||
|
CAM_focus=(Thing*)THING_NUMBER(CAM_focus);
|
||
|
STORE_DATA(CAM_focus);
|
||
|
CAM_focus=TO_THING((SLONG)CAM_focus);
|
||
|
#endif
|
||
|
|
||
|
switch(type)
|
||
|
{
|
||
|
case 0:
|
||
|
save_whole_anims(handle);
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
#ifndef ULTRA_COMPRESSED_ANIMATIONS
|
||
|
save_whole_anims_psx(handle);
|
||
|
#endif
|
||
|
break;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
// STORE_DATA(GAME_TIME,sizeof
|
||
|
// STORE_DATA(GAME_SEASON,size
|
||
|
|
||
|
FileClose(handle);
|
||
|
|
||
|
// convert back again
|
||
|
convert_index_to_pointers();
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
void save_whole_game(CBYTE *gamename)
|
||
|
{
|
||
|
SLONG level;
|
||
|
CBYTE name[30];
|
||
|
// return;
|
||
|
extern SLONG save_psx;
|
||
|
|
||
|
#ifndef ULTRA_COMPRESSED_ANIMATIONS
|
||
|
if(save_psx)
|
||
|
{
|
||
|
#if 0
|
||
|
void WMOVE_remove(UBYTE which_class);
|
||
|
WMOVE_remove(CLASS_VEHICLE);
|
||
|
#endif
|
||
|
// save_whole_wad(gamename,0);
|
||
|
|
||
|
//
|
||
|
// creates texture pages for playstation with just the prim/people textures that are used
|
||
|
//
|
||
|
|
||
|
//
|
||
|
// Also adjusts the face3 and face4 texturepage numbers to the new location
|
||
|
//
|
||
|
SLONG build_tims_ingame(CBYTE *name);
|
||
|
|
||
|
level=build_tims_ingame(gamename);
|
||
|
|
||
|
sprintf(name,"c:\\levels\\%d\\%d.nad",level,level);
|
||
|
|
||
|
|
||
|
gamename[strlen(gamename)-3]='n';
|
||
|
save_whole_wad(name,1);
|
||
|
#ifdef TARGET_DC
|
||
|
// Hmmmm.. this has trouble copiling on the DC.
|
||
|
// shouldn't be using it, anyway.
|
||
|
ASSERT(FALSE);
|
||
|
#else
|
||
|
CopyFile(name,gamename,0);
|
||
|
#endif
|
||
|
|
||
|
fix_psxed_anims();
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
extern SLONG person_normal_animate(Thing *p_person);
|
||
|
|
||
|
void convert_drawtype_to_pointer(Thing *p_thing,SLONG meshtype)
|
||
|
{
|
||
|
switch(meshtype)
|
||
|
{
|
||
|
case DT_MESH:
|
||
|
// if(p_thing->Draw.Mesh)
|
||
|
{
|
||
|
DrawMesh *drawtype;
|
||
|
drawtype=TO_DRAW_MESH((ULONG)p_thing->Draw.Mesh);
|
||
|
p_thing->Draw.Mesh=drawtype;
|
||
|
drawtype->Cache=0;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
case DT_ROT_MULTI:
|
||
|
case DT_ANIM_PRIM:
|
||
|
case DT_BIKE:
|
||
|
// if(p_thing->Draw.Tweened)
|
||
|
{
|
||
|
DrawTween *drawtype;
|
||
|
SLONG chunk;
|
||
|
|
||
|
drawtype=TO_DRAW_TWEEN((ULONG)p_thing->Draw.Tweened);
|
||
|
ASSERT((ULONG)(p_thing->Draw.Tweened)<RMAX_DRAW_TWEENS);
|
||
|
p_thing->Draw.Tweened=drawtype;
|
||
|
|
||
|
chunk=(SLONG)drawtype->TheChunk;
|
||
|
switch(chunk>>16)
|
||
|
{
|
||
|
case 1:
|
||
|
drawtype->TheChunk=&game_chunk[chunk&0xffff];
|
||
|
break;
|
||
|
case 2:
|
||
|
drawtype->TheChunk=&anim_chunk[chunk&0xffff];
|
||
|
break;
|
||
|
default:
|
||
|
ASSERT(0);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
switch(p_thing->Class)
|
||
|
{
|
||
|
case CLASS_PERSON:
|
||
|
drawtype->QueuedFrame=0;
|
||
|
drawtype->InterruptFrame=0;
|
||
|
if(p_thing->Genus.Person->PersonType==PERSON_CIV && (drawtype->CurrentAnim>100 && drawtype->CurrentAnim<140)&&drawtype->CurrentAnim!=109)
|
||
|
{
|
||
|
drawtype->CurrentFrame=game_chunk[ANIM_TYPE_CIV].AnimList[drawtype->CurrentAnim];
|
||
|
}
|
||
|
else
|
||
|
if(p_thing->Genus.Person->PersonType==PERSON_COP && (drawtype->CurrentAnim>200 && drawtype->CurrentAnim<220))
|
||
|
{
|
||
|
drawtype->CurrentFrame=game_chunk[ANIM_TYPE_ROPER].AnimList[drawtype->CurrentAnim];
|
||
|
}
|
||
|
else
|
||
|
drawtype->CurrentFrame=global_anim_array[p_thing->Genus.Person->AnimType][drawtype->CurrentAnim];
|
||
|
|
||
|
|
||
|
if(drawtype->CurrentFrame)
|
||
|
drawtype->NextFrame=drawtype->CurrentFrame->NextFrame;
|
||
|
else
|
||
|
drawtype->NextFrame=0;
|
||
|
|
||
|
if(p_thing->State==STATE_DEAD)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
SLONG old_tick;
|
||
|
|
||
|
old_tick=TICK_RATIO;
|
||
|
|
||
|
the_game.TickRatio=1<<TICK_SHIFT;
|
||
|
for(c0=0;c0<40;c0++)
|
||
|
person_normal_animate(p_thing);
|
||
|
|
||
|
the_game.TickRatio=old_tick;
|
||
|
}
|
||
|
break;
|
||
|
case CLASS_BAT:
|
||
|
|
||
|
case CLASS_BIKE:
|
||
|
case CLASS_ANIM_PRIM:
|
||
|
drawtype->QueuedFrame=0;
|
||
|
drawtype->InterruptFrame=0;
|
||
|
|
||
|
// load_anim_prim_object(p_thing->Index); // make sure the anim prim is loaded, wont load it if it's already in
|
||
|
//
|
||
|
//
|
||
|
// bat's dont set up index right
|
||
|
//
|
||
|
drawtype->CurrentFrame = anim_chunk[p_thing->Index].AnimList[drawtype->CurrentAnim];
|
||
|
if(drawtype->CurrentFrame)
|
||
|
drawtype->NextFrame=drawtype->CurrentFrame->NextFrame;
|
||
|
else
|
||
|
drawtype->NextFrame=0;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case CLASS_ANIMAL:
|
||
|
drawtype->QueuedFrame=0;
|
||
|
drawtype->InterruptFrame=0;
|
||
|
drawtype->CurrentFrame = game_chunk[6].AnimList[1];
|
||
|
if(drawtype->CurrentFrame)
|
||
|
drawtype->NextFrame=drawtype->CurrentFrame->NextFrame;
|
||
|
else
|
||
|
drawtype->NextFrame=0;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
ASSERT(0);
|
||
|
drawtype->QueuedFrame=0;
|
||
|
drawtype->InterruptFrame=0;
|
||
|
drawtype->CurrentFrame=0;
|
||
|
drawtype->NextFrame=0;
|
||
|
break;
|
||
|
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// what's left is function pointers
|
||
|
// and
|
||
|
|
||
|
|
||
|
extern void process_hardware_level_input_for_player(Thing *p_thing);
|
||
|
extern void fn_anim_prim_normal(Thing *p_thing);
|
||
|
|
||
|
void convert_thing_to_pointer(Thing *p_thing)
|
||
|
{
|
||
|
|
||
|
switch(p_thing->Class)
|
||
|
{
|
||
|
|
||
|
case CLASS_NONE:
|
||
|
break;
|
||
|
case CLASS_PLAYER:
|
||
|
p_thing->Genus.Player=(Player*)TO_PLAYER((SLONG)p_thing->Genus.Player);
|
||
|
p_thing->Genus.Player->PlayerPerson=(Thing*)TO_THING((SLONG)p_thing->Genus.Player->PlayerPerson);
|
||
|
p_thing->StateFn = process_hardware_level_input_for_player; // Bodge for now
|
||
|
|
||
|
break;
|
||
|
case CLASS_CAMERA:
|
||
|
break;
|
||
|
case CLASS_PROJECTILE:
|
||
|
p_thing->Genus.Projectile=(Projectile *)TO_PROJECTILE((SLONG)p_thing->Genus.Projectile);
|
||
|
break;
|
||
|
case CLASS_BUILDING:
|
||
|
break;
|
||
|
case CLASS_PERSON:
|
||
|
p_thing->Genus.Person=(Person *)TO_PERSON((SLONG)p_thing->Genus.Person);
|
||
|
set_generic_person_state_function(p_thing,p_thing->State);
|
||
|
break;
|
||
|
case CLASS_ANIMAL:
|
||
|
p_thing->Genus.Animal=(Animal*)TO_ANIMAL((SLONG)p_thing->Genus.Animal);
|
||
|
|
||
|
set_state_function(p_thing, p_thing->State);
|
||
|
|
||
|
break;
|
||
|
case CLASS_FURNITURE:
|
||
|
p_thing->Genus.Furniture=(Furniture*)TO_FURNITURE((SLONG)p_thing->Genus.Furniture);
|
||
|
break;
|
||
|
case CLASS_SWITCH:
|
||
|
p_thing->Genus.Switch=(Switch*)TO_SWITCH((SLONG)p_thing->Genus.Switch);
|
||
|
break;
|
||
|
case CLASS_VEHICLE:
|
||
|
p_thing->Genus.Vehicle=(Vehicle*)TO_VEHICLE((SLONG)p_thing->Genus.Vehicle);
|
||
|
set_state_function(p_thing, p_thing->State);
|
||
|
break;
|
||
|
case CLASS_SPECIAL:
|
||
|
p_thing->Genus.Special=(Special*)TO_SPECIAL((SLONG)p_thing->Genus.Special);
|
||
|
void special_normal(Thing *s_thing);
|
||
|
p_thing->StateFn = special_normal;
|
||
|
|
||
|
break;
|
||
|
#ifdef ANIM_PRIM
|
||
|
case CLASS_ANIM_PRIM:
|
||
|
if(p_thing->StateFn)
|
||
|
{
|
||
|
p_thing->StateFn = fn_anim_prim_normal;
|
||
|
|
||
|
}
|
||
|
break;
|
||
|
#endif
|
||
|
case CLASS_CHOPPER:
|
||
|
void CHOPPER_fn_normal(Thing *);
|
||
|
p_thing->Genus.Chopper=(Chopper*)TO_CHOPPER((SLONG)p_thing->Genus.Chopper);
|
||
|
p_thing->StateFn = CHOPPER_fn_normal;
|
||
|
|
||
|
break;
|
||
|
case CLASS_PYRO:
|
||
|
p_thing->Genus.Pyro=(Pyro*)TO_PYRO((SLONG)p_thing->Genus.Pyro);
|
||
|
set_state_function(p_thing, p_thing->State);
|
||
|
break;
|
||
|
case CLASS_TRACK:
|
||
|
p_thing->Genus.Track=(Track*)TO_TRACK((SLONG)p_thing->Genus.Track);
|
||
|
break;
|
||
|
case CLASS_PLAT:
|
||
|
p_thing->Genus.Plat=(Plat*)TO_PLAT((SLONG)p_thing->Genus.Plat);
|
||
|
p_thing->StateFn = PLAT_process;
|
||
|
break;
|
||
|
case CLASS_BARREL:
|
||
|
void BARREL_process_normal(Thing *p_barrel);
|
||
|
p_thing->Genus.Barrel=(Barrel*)TO_BARREL((SLONG)p_thing->Genus.Barrel);
|
||
|
p_thing->StateFn = BARREL_process_normal;
|
||
|
|
||
|
break;
|
||
|
|
||
|
#ifdef BIKE
|
||
|
case CLASS_BIKE:
|
||
|
void BIKE_process_normal(Thing *p_bike);
|
||
|
p_thing->StateFn = BIKE_process_normal;
|
||
|
p_thing->Genus.Bike=(BIKE_Bike*)TO_BIKE((SLONG)p_thing->Genus.Bike);
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
case CLASS_BAT:
|
||
|
p_thing->StateFn = BAT_normal;
|
||
|
p_thing->Genus.Bat=(Bat*)TO_BAT((SLONG)p_thing->Genus.Bat);
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
ASSERT(0);
|
||
|
break;
|
||
|
}
|
||
|
switch(p_thing->DrawType)
|
||
|
{
|
||
|
case DT_MESH:
|
||
|
case DT_CHOPPER:
|
||
|
convert_drawtype_to_pointer(p_thing,DT_MESH);
|
||
|
break;
|
||
|
case DT_ROT_MULTI:
|
||
|
convert_drawtype_to_pointer(p_thing,DT_ROT_MULTI);
|
||
|
break;
|
||
|
case DT_ANIM_PRIM:
|
||
|
case DT_BIKE:
|
||
|
convert_drawtype_to_pointer(p_thing,DT_ANIM_PRIM);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void convert_index_to_pointers(void)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
for(c0=0;c0<MAX_THINGS;c0++)
|
||
|
{
|
||
|
convert_thing_to_pointer(TO_THING(c0));
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<MAX_PLAYERS;c0++)
|
||
|
{
|
||
|
NET_PERSON(c0)=TO_THING((SLONG)NET_PERSON(c0));
|
||
|
NET_PLAYER(c0)=TO_THING((SLONG)NET_PLAYER(c0));
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<EWAY_mess_upto;c0++)
|
||
|
{
|
||
|
EWAY_mess[c0]=(CBYTE*)&EWAY_mess_buffer[(SLONG)EWAY_mess[c0]];
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<MAX_PYROS;c0++)
|
||
|
{
|
||
|
if(TO_PYRO(c0)->thing)
|
||
|
TO_PYRO(c0)->thing=TO_THING((ULONG)TO_PYRO(c0)->thing);
|
||
|
|
||
|
if(TO_PYRO(c0)->victim)
|
||
|
TO_PYRO(c0)->victim=TO_THING((ULONG)TO_PYRO(c0)->victim);
|
||
|
}
|
||
|
#ifndef PSX
|
||
|
// cutscene stuff. convert the track pointers back first:
|
||
|
for(c0=0;c0<PLAYCUTS_cutscene_ctr;c0++)
|
||
|
{
|
||
|
PLAYCUTS_cutscenes[c0].channels=PLAYCUTS_tracks+(SLONG)PLAYCUTS_cutscenes[c0].channels;
|
||
|
}
|
||
|
for(c0=0;c0<PLAYCUTS_track_ctr;c0++)
|
||
|
{
|
||
|
PLAYCUTS_tracks[c0].packets=PLAYCUTS_packets+(SLONG)PLAYCUTS_tracks[c0].packets;
|
||
|
}
|
||
|
for(c0=0;c0<PLAYCUTS_packet_ctr;c0++)
|
||
|
{
|
||
|
// if (PLAYCUTS_packets[c0].type==PT_TEXT) PLAYCUTS_packets[c0].pos.X+=PLAYCUTS_text_data;
|
||
|
if (PLAYCUTS_packets[c0].type==5) PLAYCUTS_packets[c0].pos.X+=(ULONG)PLAYCUTS_text_data;
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void uncache(void)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
void NIGHT_destroy_all_cached_info();
|
||
|
NIGHT_destroy_all_cached_info();
|
||
|
|
||
|
for(c0=0;c0<next_dfacet;c0++)
|
||
|
{
|
||
|
dfacets[c0].Dfcache=0;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#define GET_DATA(d) memcpy((UBYTE*)&d,p_all,sizeof(d));p_all+=sizeof(d)
|
||
|
|
||
|
void load_whole_anims(UBYTE *p_all)
|
||
|
{
|
||
|
SLONG c0,c1;
|
||
|
SLONG dummy;
|
||
|
SLONG check;
|
||
|
|
||
|
|
||
|
GET_DATA(next_game_chunk);
|
||
|
GET_DATA(next_anim_chunk);
|
||
|
|
||
|
for(c0=0;c0<next_game_chunk;c0++)
|
||
|
{
|
||
|
GET_DATA(dummy);
|
||
|
if(dummy>=0)
|
||
|
ASSERT(dummy==c0);
|
||
|
|
||
|
if(dummy==c0)
|
||
|
{
|
||
|
struct GameKeyFrameChunk *gc;
|
||
|
gc=&game_chunk[c0];
|
||
|
GET_DATA(gc->MaxPeopleTypes);
|
||
|
GET_DATA(gc->MaxKeyFrames);
|
||
|
GET_DATA(gc->MaxAnimFrames);
|
||
|
GET_DATA(gc->MaxFightCols);
|
||
|
GET_DATA(gc->MaxElements);
|
||
|
GET_DATA(gc->ElementCount);
|
||
|
|
||
|
GET_DATA(check);
|
||
|
ASSERT(check==666);
|
||
|
|
||
|
for(c1=0;c1<10;c1++)
|
||
|
{
|
||
|
GET_DATA(gc->MultiObject[c1]);
|
||
|
}
|
||
|
|
||
|
GET_DATA(check);
|
||
|
ASSERT(check==666);
|
||
|
gc->PeopleTypes=(struct BodyDef*)p_all;
|
||
|
p_all+=gc->MaxPeopleTypes*sizeof(struct BodyDef);
|
||
|
|
||
|
GET_DATA(check);
|
||
|
ASSERT(check==666);
|
||
|
gc->AnimKeyFrames=(GameKeyFrame*)p_all;
|
||
|
p_all+=gc->MaxKeyFrames*sizeof(GameKeyFrame);
|
||
|
|
||
|
|
||
|
GET_DATA(check);
|
||
|
ASSERT(check==666);
|
||
|
gc->AnimList=(GameKeyFrame**)p_all;
|
||
|
p_all+=gc->MaxAnimFrames*sizeof(GameKeyFrame*);
|
||
|
|
||
|
|
||
|
GET_DATA(check);
|
||
|
ASSERT(check==666);
|
||
|
gc->TheElements=(GameKeyFrameElement*)p_all;
|
||
|
p_all+=gc->MaxElements*sizeof(GameKeyFrameElement);
|
||
|
|
||
|
GET_DATA(check);
|
||
|
ASSERT(check==666);
|
||
|
gc->FightCols=(GameFightCol*)p_all;
|
||
|
p_all+=gc->MaxFightCols*sizeof(GameFightCol);
|
||
|
|
||
|
GET_DATA(check);
|
||
|
ASSERT(check==666);
|
||
|
|
||
|
convert_keyframe_to_pointer(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_pointer(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_pointer(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<next_anim_chunk;c0++)
|
||
|
{
|
||
|
GET_DATA(dummy);
|
||
|
if(dummy>=0)
|
||
|
ASSERT(dummy==c0);
|
||
|
|
||
|
if(dummy==c0)
|
||
|
{
|
||
|
struct GameKeyFrameChunk *gc;
|
||
|
gc=&anim_chunk[c0];
|
||
|
GET_DATA(gc->MaxPeopleTypes);
|
||
|
GET_DATA(gc->MaxKeyFrames);
|
||
|
GET_DATA(gc->MaxAnimFrames);
|
||
|
GET_DATA(gc->MaxFightCols);
|
||
|
GET_DATA(gc->MaxElements);
|
||
|
GET_DATA(gc->ElementCount);
|
||
|
|
||
|
for(c1=0;c1<10;c1++)
|
||
|
{
|
||
|
GET_DATA(gc->MultiObject[c1]);
|
||
|
}
|
||
|
|
||
|
gc->PeopleTypes=(struct BodyDef*)p_all;
|
||
|
p_all+=gc->MaxPeopleTypes*sizeof(struct BodyDef);
|
||
|
|
||
|
gc->AnimKeyFrames=(GameKeyFrame*)p_all;
|
||
|
p_all+=gc->MaxKeyFrames*sizeof(GameKeyFrame);
|
||
|
|
||
|
|
||
|
gc->AnimList=(GameKeyFrame**)p_all;
|
||
|
p_all+=gc->MaxAnimFrames*sizeof(GameKeyFrame*);
|
||
|
|
||
|
gc->TheElements=(GameKeyFrameElement*)p_all;
|
||
|
p_all+=gc->MaxElements*sizeof(GameKeyFrameElement);
|
||
|
|
||
|
gc->FightCols=(GameFightCol*)p_all;
|
||
|
p_all+=gc->MaxFightCols*sizeof(GameFightCol);
|
||
|
|
||
|
convert_keyframe_to_pointer(gc->AnimKeyFrames,gc->TheElements,gc->FightCols,gc->MaxKeyFrames);
|
||
|
convert_animlist_to_pointer(gc->AnimList,gc->AnimKeyFrames,gc->MaxAnimFrames);
|
||
|
convert_fightcol_to_pointer(gc->FightCols,gc->FightCols,gc->MaxFightCols);
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|
||
|
GET_DATA(next_anim_mids);
|
||
|
anim_mids=(PrimPoint *)p_all;
|
||
|
p_all+=next_anim_mids*sizeof(PrimPoint);
|
||
|
|
||
|
}
|
||
|
|
||
|
extern SLONG EWAY_count_up; // The visible count-up timer...
|
||
|
|
||
|
//
|
||
|
// The penalties incurred for the count-up timer.
|
||
|
//
|
||
|
|
||
|
extern UBYTE EWAY_count_up_add_penalties;
|
||
|
extern SWORD EWAY_count_up_num_penalties;
|
||
|
extern UWORD EWAY_count_up_penalty_timer;
|
||
|
|
||
|
void flag_v_faces(void)
|
||
|
{
|
||
|
SLONG c0;
|
||
|
struct PrimFace4 *p4;
|
||
|
struct PrimFace3 *p3;
|
||
|
SLONG vx,vz,wx,wz,ny;
|
||
|
|
||
|
p4=&prim_faces4[0];
|
||
|
for(c0=0;c0<next_prim_face4;c0++)
|
||
|
{
|
||
|
vx=prim_points[p4->Points[1]].X-prim_points[p4->Points[0]].X;
|
||
|
vz=prim_points[p4->Points[1]].Z-prim_points[p4->Points[0]].Z;
|
||
|
|
||
|
wx=prim_points[p4->Points[0]].X-prim_points[p4->Points[2]].X;
|
||
|
wz=prim_points[p4->Points[0]].Z-prim_points[p4->Points[2]].Z;
|
||
|
|
||
|
|
||
|
ny=((vz)*(wx))-(vx*wz)>>8; //perform cross product on vect V & W
|
||
|
|
||
|
if(ny<2)
|
||
|
p4->FaceFlags|=FACE_FLAG_VERTICAL;
|
||
|
|
||
|
p4++;
|
||
|
}
|
||
|
|
||
|
p3=&prim_faces3[0];
|
||
|
for(c0=0;c0<next_prim_face3;c0++)
|
||
|
{
|
||
|
vx=prim_points[p3->Points[1]].X-prim_points[p3->Points[0]].X;
|
||
|
vz=prim_points[p3->Points[1]].Z-prim_points[p3->Points[0]].Z;
|
||
|
|
||
|
wx=prim_points[p3->Points[0]].X-prim_points[p3->Points[2]].X;
|
||
|
wz=prim_points[p3->Points[0]].Z-prim_points[p3->Points[2]].Z;
|
||
|
|
||
|
|
||
|
ny=((vz)*(wx))-(vx*wz)>>8; //perform cross product on vect V & W
|
||
|
|
||
|
if(ny<2)
|
||
|
p3->FaceFlags|=FACE_FLAG_VERTICAL;
|
||
|
|
||
|
p3++;
|
||
|
}
|
||
|
}
|
||
|
#ifndef NEW_LEVELS
|
||
|
UWORD EWAY_timer_bodge[EWAY_MAX_TIMERS];
|
||
|
#endif
|
||
|
|
||
|
void load_whole_game(CBYTE *gamename)
|
||
|
{
|
||
|
// return;
|
||
|
|
||
|
SLONG c0=0,id;
|
||
|
SLONG *p_slong;
|
||
|
UWORD *p_uword;
|
||
|
UBYTE *p_mem,*p_all;
|
||
|
SLONG mem_size;
|
||
|
struct MemTable *ptab;
|
||
|
#ifndef PSX
|
||
|
MFFileHandle handle = FILE_OPEN_ERROR;
|
||
|
#else
|
||
|
SLONG handle;
|
||
|
#endif
|
||
|
SLONG count;
|
||
|
SLONG texture_set_local;
|
||
|
SLONG save_type;
|
||
|
|
||
|
SLONG check;
|
||
|
UBYTE padding_byte;
|
||
|
UWORD padding_word;
|
||
|
|
||
|
SetSeed(1234567);
|
||
|
srand(1234567);
|
||
|
#ifndef NEW_LEVELS
|
||
|
memset((UBYTE*)EWAY_timer_bodge,0,EWAY_MAX_TIMERS*2);
|
||
|
#endif
|
||
|
|
||
|
#ifdef PSX
|
||
|
|
||
|
extern void SetDisplayClear(SLONG clear);
|
||
|
extern void AENG_loading_bar(SLONG percent);
|
||
|
extern void OB_init();
|
||
|
OB_init(); //ob_hydrant now cleared
|
||
|
|
||
|
SetDisplayClear(0);
|
||
|
|
||
|
extern int wad_level;
|
||
|
extern UBYTE roper_pickup;
|
||
|
|
||
|
if(wad_level==21)
|
||
|
{
|
||
|
roper_pickup=2;
|
||
|
}
|
||
|
else
|
||
|
if(wad_level==33)
|
||
|
{
|
||
|
roper_pickup=1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
roper_pickup=0;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Make sure when we go into the game, the draw stuff is set up
|
||
|
//
|
||
|
#if 1
|
||
|
GDisp_SetupBucketMem(&my_heap[8],16384);
|
||
|
#endif
|
||
|
void AENG_flip_init(void);
|
||
|
AENG_flip_init();
|
||
|
#endif
|
||
|
|
||
|
extern UWORD player_dlight;
|
||
|
player_dlight=0;
|
||
|
|
||
|
#ifdef ULTRA_COMPRESSED_ANIMATIONS
|
||
|
gamename[strlen(gamename)-3]='n';
|
||
|
#endif
|
||
|
|
||
|
if(mem_all)
|
||
|
MemFree(mem_all);
|
||
|
|
||
|
#ifndef PSX
|
||
|
handle=FileOpen(gamename);
|
||
|
if(handle==FILE_OPEN_ERROR)
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
mem_size=FileSize(handle);
|
||
|
p_all=(UBYTE*)MemAlloc(mem_size);
|
||
|
ASSERT(p_all);
|
||
|
FileRead(handle,p_all,mem_size);
|
||
|
FileClose(handle);
|
||
|
#else
|
||
|
|
||
|
TEXTURE_choose_set(wad_level);
|
||
|
|
||
|
AENG_loading_bar(20);
|
||
|
|
||
|
#ifndef FS_ISO9660
|
||
|
handle=PCopen(gamename,0,0);
|
||
|
if (handle<0)
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
return;
|
||
|
}
|
||
|
mem_size=PClseek(handle,0,SEEK_END);
|
||
|
PClseek(handle,0,SEEK_SET);
|
||
|
p_all=(UBYTE*)MemAlloc(mem_size);
|
||
|
PCread(handle,p_all,mem_size);
|
||
|
PCclose(handle);
|
||
|
// Calculate how much bucket space is available
|
||
|
#if 1
|
||
|
BUCKET_MEM=(total_mem_size-(mem_size+128))&0xfffffffc;
|
||
|
#endif
|
||
|
|
||
|
AENG_loading_bar(40);
|
||
|
#else
|
||
|
extern char cd_file_buffer[];
|
||
|
|
||
|
CdlFILE cfile;
|
||
|
char *p=gamename;
|
||
|
while(*p)
|
||
|
*p++=toupper(*p);
|
||
|
sprintf(cd_file_buffer,"\\%s;1",gamename);
|
||
|
|
||
|
if (CdSearchFile(&cfile,cd_file_buffer)==0)
|
||
|
{
|
||
|
// printf("Error: Cannot find level file '%s'\n",cd_file_buffer);
|
||
|
}
|
||
|
mem_size=(cfile.size+2047)&0x7ffff800;
|
||
|
p_all=(UBYTE*)MemAlloc(mem_size);
|
||
|
CdReadFile(cd_file_buffer,(ULONG*)p_all,mem_size);
|
||
|
CdReadSync(0,cd_file_buffer);
|
||
|
#if 1
|
||
|
BUCKET_MEM=(total_mem_size-(mem_size+128))&0xfffffffc;
|
||
|
#endif
|
||
|
AENG_loading_bar(40);
|
||
|
|
||
|
#ifdef VERSION_PAL
|
||
|
#if !defined(MIKE)&&!defined(VERSION_DEMO)
|
||
|
if (do_decrypt[wad_level-1])
|
||
|
Decrypt(p_all);
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
mem_all=p_all;
|
||
|
mem_all_size=mem_size;
|
||
|
|
||
|
|
||
|
|
||
|
GET_DATA(save_type);
|
||
|
|
||
|
|
||
|
|
||
|
// printf("Save Type: %d\n",save_type);
|
||
|
while(save_table[c0].Point)
|
||
|
{
|
||
|
SLONG struct_size;
|
||
|
// printf("Loading: %s\n",save_table[c0].Name);
|
||
|
id=*((SLONG*)p_all);
|
||
|
// printf(" id %d ",id);
|
||
|
ASSERT(id==c0);
|
||
|
p_all+=4;
|
||
|
|
||
|
count=*((SLONG*)p_all);
|
||
|
// printf(" count %d",count);
|
||
|
p_all+=4;
|
||
|
|
||
|
struct_size=*((SLONG*)p_all);
|
||
|
p_all+=4;
|
||
|
// printf(" struct size %d shouldbe %d memsize %d\n",struct_size,save_table[c0].StructSize,*(SLONG*)p_all);
|
||
|
ASSERT(struct_size==save_table[c0].StructSize);
|
||
|
|
||
|
mem_size=*((SLONG*)p_all);
|
||
|
p_all+=4;
|
||
|
|
||
|
if(mem_size&3)
|
||
|
p_all+=4-(mem_size&3);
|
||
|
|
||
|
ptab=&save_table[c0];
|
||
|
|
||
|
*ptab->Point=p_all;
|
||
|
|
||
|
switch(ptab->Type)
|
||
|
{
|
||
|
case 2:
|
||
|
if(ptab->Extra)
|
||
|
ptab->Maximum=count;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
if(ptab->Extra)
|
||
|
count-=ptab->Extra;
|
||
|
|
||
|
if(ptab->CountL)
|
||
|
{
|
||
|
*ptab->CountL=count;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(ptab->CountW)
|
||
|
*ptab->CountW=count;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p_all+=mem_size;
|
||
|
|
||
|
c0++;
|
||
|
}
|
||
|
|
||
|
for(c0=0;c0<EWAY_mess_buffer_upto;c0++)
|
||
|
if (EWAY_mess_buffer[c0]==160) EWAY_mess_buffer[c0]=32;
|
||
|
|
||
|
#ifdef PSX
|
||
|
AENG_loading_bar(60);
|
||
|
#endif
|
||
|
|
||
|
GET_DATA(PRIMARY_USED);
|
||
|
GET_DATA(PRIMARY_UNUSED);
|
||
|
GET_DATA(SECONDARY_USED);
|
||
|
GET_DATA(SECONDARY_UNUSED);
|
||
|
GET_DATA(PERSON_COUNT);
|
||
|
GET_DATA(PERSON_COUNT);
|
||
|
GET_DATA(ANIMAL_COUNT);
|
||
|
GET_DATA(CHOPPER_COUNT);
|
||
|
GET_DATA(PYRO_COUNT);
|
||
|
GET_DATA(PLAYER_COUNT);
|
||
|
GET_DATA(PROJECTILE_COUNT);
|
||
|
GET_DATA(SPECIAL_COUNT);
|
||
|
GET_DATA(SWITCH_COUNT);
|
||
|
GET_DATA(PRIMARY_COUNT);
|
||
|
GET_DATA(SECONDARY_COUNT);
|
||
|
GET_DATA(GAME_STATE);
|
||
|
|
||
|
#ifdef TARGET_DC
|
||
|
GAME_STATE &= ~(GS_RECORD|GS_PLAYBACK|GS_EDITOR);
|
||
|
#endif
|
||
|
|
||
|
GET_DATA(GAME_TURN);
|
||
|
GET_DATA(GAME_FLAGS);
|
||
|
GET_DATA(texture_set_local);
|
||
|
GET_DATA(WMOVE_face_upto);
|
||
|
GET_DATA(first_walkable_prim_point);
|
||
|
GET_DATA(number_of_walkable_prim_points);
|
||
|
GET_DATA(first_walkable_prim_face4);
|
||
|
GET_DATA(number_of_walkable_prim_faces4);
|
||
|
GET_DATA(BARREL_sphere_last);
|
||
|
GET_DATA(track_head);
|
||
|
GET_DATA(track_tail);
|
||
|
GET_DATA(track_eob);
|
||
|
GET_DATA( NIGHT_dlight_free);
|
||
|
GET_DATA( NIGHT_dlight_used);
|
||
|
|
||
|
|
||
|
GET_DATA(EWAY_time_accurate);
|
||
|
GET_DATA(EWAY_time);
|
||
|
GET_DATA(EWAY_tick);
|
||
|
GET_DATA(EWAY_cam_active);
|
||
|
GET_DATA(EWAY_cam_x);
|
||
|
GET_DATA(EWAY_cam_y);
|
||
|
GET_DATA(EWAY_cam_z);
|
||
|
GET_DATA(EWAY_cam_dx);
|
||
|
GET_DATA(EWAY_cam_dy);
|
||
|
GET_DATA(EWAY_cam_dz);
|
||
|
GET_DATA(EWAY_cam_yaw);
|
||
|
GET_DATA(EWAY_cam_pitch);
|
||
|
GET_DATA(EWAY_cam_waypoint);
|
||
|
GET_DATA(EWAY_cam_target);
|
||
|
GET_DATA(EWAY_cam_delay);
|
||
|
GET_DATA(EWAY_cam_speed);
|
||
|
GET_DATA(EWAY_cam_freeze);
|
||
|
GET_DATA(EWAY_cam_cant_interrupt);
|
||
|
GET_DATA(NIGHT_amb_d3d_colour);
|
||
|
GET_DATA(NIGHT_amb_d3d_specular);
|
||
|
GET_DATA(NIGHT_amb_red);
|
||
|
GET_DATA(NIGHT_amb_green);
|
||
|
GET_DATA(NIGHT_amb_blue);
|
||
|
GET_DATA(NIGHT_amb_norm_x);
|
||
|
GET_DATA(NIGHT_amb_norm_y);
|
||
|
GET_DATA(NIGHT_amb_norm_z);
|
||
|
GET_DATA(NIGHT_flag);
|
||
|
GET_DATA(NIGHT_lampost_radius);
|
||
|
GET_DATA(NIGHT_lampost_red);
|
||
|
GET_DATA(NIGHT_lampost_green);
|
||
|
GET_DATA(NIGHT_lampost_blue);
|
||
|
GET_DATA(NIGHT_sky_colour);
|
||
|
GET_DATA(padding_byte);
|
||
|
GET_DATA(check);
|
||
|
GET_DATA(CRIME_RATE);
|
||
|
GET_DATA(CRIME_RATE_SCORE_MUL);
|
||
|
GET_DATA(MUSIC_WORLD);
|
||
|
GET_DATA(BOREDOM_RATE);
|
||
|
GET_DATA(world_type);
|
||
|
|
||
|
GET_DATA(EWAY_fake_wander_text_normal_index );
|
||
|
GET_DATA(EWAY_fake_wander_text_normal_number );
|
||
|
GET_DATA(EWAY_fake_wander_text_guilty_index );
|
||
|
GET_DATA(EWAY_fake_wander_text_guilty_number );
|
||
|
GET_DATA(EWAY_fake_wander_text_annoyed_index );
|
||
|
GET_DATA(EWAY_fake_wander_text_annoyed_number);
|
||
|
|
||
|
GET_DATA(GAME_FLAGS);
|
||
|
|
||
|
GET_DATA(semtex);
|
||
|
GET_DATA(estate);
|
||
|
GET_DATA(padding_word);
|
||
|
|
||
|
|
||
|
ASSERT(check==666);
|
||
|
|
||
|
//NIGHT_flag&=~NIGHT_FLAG_DAYTIME;
|
||
|
|
||
|
// This needs to go here, if it doesn't then the later levels will
|
||
|
// automatically fail because the timer will be over the time limit.
|
||
|
|
||
|
EWAY_time_accurate = 0;
|
||
|
EWAY_time = 0;
|
||
|
EWAY_count_up = 0;
|
||
|
|
||
|
//
|
||
|
// The penalties on the count-up timer.
|
||
|
//
|
||
|
|
||
|
EWAY_count_up_add_penalties = 0;
|
||
|
EWAY_count_up_num_penalties = 0;
|
||
|
EWAY_count_up_penalty_timer = 0;
|
||
|
|
||
|
// NIGHT_amb_red*=2;
|
||
|
// NIGHT_amb_green*=2;
|
||
|
// NIGHT_amb_blue*=2;
|
||
|
#ifdef VERSION_USA
|
||
|
SATURATE(NIGHT_amb_red,25,127);
|
||
|
SATURATE(NIGHT_amb_green,25,127);
|
||
|
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
SATURATE(NIGHT_amb_blue,25,127);
|
||
|
|
||
|
|
||
|
#ifdef VERSION_USA
|
||
|
{
|
||
|
SLONG bright;
|
||
|
SATURATE(NIGHT_amb_red,25,127);
|
||
|
SATURATE(NIGHT_amb_green,25,127);
|
||
|
|
||
|
bright=Root(NIGHT_amb_red*NIGHT_amb_red + NIGHT_amb_green*NIGHT_amb_green+NIGHT_amb_blue*NIGHT_amb_blue);
|
||
|
|
||
|
|
||
|
if(bright==0)
|
||
|
bright=1;
|
||
|
#define MIN_BRIGHT 75
|
||
|
if(bright<MIN_BRIGHT)
|
||
|
{
|
||
|
NIGHT_amb_red=(NIGHT_amb_red*MIN_BRIGHT)/bright;
|
||
|
NIGHT_amb_green=(NIGHT_amb_green*MIN_BRIGHT)/bright;
|
||
|
NIGHT_amb_blue=(NIGHT_amb_blue*MIN_BRIGHT)/bright;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
|
||
|
#ifdef OLD_CAM
|
||
|
GET_DATA(CAM_focus);
|
||
|
CAM_focus=TO_THING((SLONG)CAM_focus);
|
||
|
#endif
|
||
|
|
||
|
//
|
||
|
// this needs to be before convert_index_to_pointers (because c_i_t_p needs the anims in place)
|
||
|
//
|
||
|
load_whole_anims(p_all);
|
||
|
|
||
|
#ifdef PSX
|
||
|
AENG_loading_bar(80);
|
||
|
printf("BUCKET_MEM = %d\n",BUCKET_MEM);
|
||
|
#endif
|
||
|
|
||
|
void setup_global_anim_array(void);
|
||
|
setup_global_anim_array();
|
||
|
void init_dead_tween(void);
|
||
|
init_dead_tween();
|
||
|
|
||
|
|
||
|
convert_index_to_pointers();
|
||
|
|
||
|
FC_look_at(0, THING_NUMBER(NET_PERSON(0)));
|
||
|
FC_force_camera_behind(0);
|
||
|
|
||
|
uncache();
|
||
|
|
||
|
// if(texture_set_local!=TEXTURE_set)
|
||
|
{
|
||
|
#ifndef PSX
|
||
|
TEXTURE_choose_set(texture_set_local);
|
||
|
ASSERT(0); // you need a filename for TEXTURE_load_needed()
|
||
|
// TEXTURE_load_needed();
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
extern void PARTICLE_Reset();
|
||
|
PARTICLE_Reset();
|
||
|
|
||
|
extern void POW_init();
|
||
|
POW_init();
|
||
|
|
||
|
extern void PCOM_init(void);
|
||
|
PCOM_init();
|
||
|
|
||
|
#ifdef PSX
|
||
|
void init_punch_kick(void);
|
||
|
init_punch_kick();
|
||
|
|
||
|
#ifndef NEW_LEVELS
|
||
|
EWAY_timer=&EWAY_timer_bodge[0];
|
||
|
#endif
|
||
|
|
||
|
#endif
|
||
|
|
||
|
// calc_prim_info();
|
||
|
VEH_init_vehinfo();
|
||
|
|
||
|
extern void init_noises(void);
|
||
|
extern void init_arrest(void);
|
||
|
init_noises();
|
||
|
init_arrest();
|
||
|
|
||
|
#ifndef PSX
|
||
|
calc_prim_normals();
|
||
|
#else
|
||
|
extern void SetDisplayFade(void);
|
||
|
SetDisplayFade();
|
||
|
#endif
|
||
|
// find_anim_prim_bboxes();
|
||
|
|
||
|
#ifndef PSX
|
||
|
// TEXTURE_fix_prim_textures();
|
||
|
// TEXTURE_fix_texture_styles();
|
||
|
AENG_create_dx_prim_points();
|
||
|
NIGHT_generate_walkable_lighting();
|
||
|
#else
|
||
|
AENG_loading_bar(100);
|
||
|
SetDisplayClear(1);
|
||
|
AENG_create_dx_prim_points();
|
||
|
NIGHT_ambient(NIGHT_amb_red,NIGHT_amb_green,NIGHT_amb_blue,NIGHT_amb_norm_x,NIGHT_amb_norm_y,NIGHT_amb_norm_z);
|
||
|
void init_gangattack(void);
|
||
|
|
||
|
init_gangattack(); //probably should save these
|
||
|
|
||
|
SBYTE global_spang_count;
|
||
|
global_spang_count=0;
|
||
|
|
||
|
|
||
|
extern void Wadmenu_PutStats();
|
||
|
Wadmenu_PutStats();
|
||
|
|
||
|
extern void Wadmenu_PutStats();
|
||
|
Wadmenu_PutStats();
|
||
|
|
||
|
#if 0
|
||
|
|
||
|
extern void AENG_ambient_editor(int store);
|
||
|
AENG_ambient_editor(1);
|
||
|
#endif
|
||
|
|
||
|
{
|
||
|
SLONG c0;
|
||
|
for(c0=0;c0<100;c0++)
|
||
|
{
|
||
|
FC_process();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
|
||
|
flag_v_faces();
|
||
|
|
||
|
#ifdef PSX
|
||
|
if(wad_level==25)
|
||
|
{
|
||
|
|
||
|
TO_THING(193)->Genus.Person->Flags &= ~FLAG_PERSON_USEABLE;
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
#ifndef PSX
|
||
|
#ifndef TARGET_DC
|
||
|
|
||
|
//
|
||
|
// Quick load\save filename.
|
||
|
// The value we save out at the end to make sure we're okay.
|
||
|
//
|
||
|
|
||
|
#define MEMORY_QUICK_FNAME "data\\quicksave.dat"
|
||
|
#define MEMORY_QUICK_CHECK 314159265
|
||
|
|
||
|
|
||
|
SLONG MEMORY_quick_avaliable;
|
||
|
|
||
|
|
||
|
void MEMORY_quick_init()
|
||
|
{
|
||
|
FileDelete(MEMORY_QUICK_FNAME);
|
||
|
|
||
|
MEMORY_quick_avaliable = FALSE;
|
||
|
}
|
||
|
|
||
|
void MEMORY_quick_save()
|
||
|
{
|
||
|
SLONG i;
|
||
|
UBYTE padding_byte;
|
||
|
SLONG check = 666;
|
||
|
SLONG checksum;
|
||
|
|
||
|
FILE *handle = MF_Fopen(MEMORY_QUICK_FNAME, "wb");
|
||
|
|
||
|
if (!handle)
|
||
|
{
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save out a version number.
|
||
|
//
|
||
|
|
||
|
SLONG version = 1;
|
||
|
|
||
|
if (fwrite(&version, sizeof(SLONG), 1, handle) != 1) goto file_error;
|
||
|
|
||
|
//
|
||
|
// Go through the memory table and save all arrays.
|
||
|
//
|
||
|
|
||
|
MemTable *mt;
|
||
|
|
||
|
for (i = 0; save_table[i].Point; i++)
|
||
|
{
|
||
|
mt = &save_table[i];
|
||
|
|
||
|
if (fwrite(mt->Point, mt->StructSize, mt->Maximum, handle) != (unsigned)mt->Maximum) goto file_error;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save out the extra data we might need!
|
||
|
//
|
||
|
|
||
|
#define QSTORE_DATA(x) if (fwrite(&(x), sizeof(x), 1, handle) != 1) goto file_error;
|
||
|
|
||
|
QSTORE_DATA(PRIMARY_USED);
|
||
|
QSTORE_DATA(PRIMARY_UNUSED);
|
||
|
QSTORE_DATA(SECONDARY_USED);
|
||
|
QSTORE_DATA(SECONDARY_UNUSED);
|
||
|
QSTORE_DATA(PERSON_COUNT);
|
||
|
QSTORE_DATA(PERSON_COUNT);
|
||
|
QSTORE_DATA(ANIMAL_COUNT);
|
||
|
QSTORE_DATA(CHOPPER_COUNT);
|
||
|
QSTORE_DATA(PYRO_COUNT);
|
||
|
QSTORE_DATA(PLAYER_COUNT);
|
||
|
QSTORE_DATA(PROJECTILE_COUNT);
|
||
|
QSTORE_DATA(SPECIAL_COUNT);
|
||
|
QSTORE_DATA(SWITCH_COUNT);
|
||
|
QSTORE_DATA(PRIMARY_COUNT);
|
||
|
QSTORE_DATA(SECONDARY_COUNT);
|
||
|
QSTORE_DATA(GAME_STATE);
|
||
|
QSTORE_DATA(GAME_TURN);
|
||
|
QSTORE_DATA(GAME_FLAGS);
|
||
|
QSTORE_DATA(TEXTURE_set);
|
||
|
QSTORE_DATA(WMOVE_face_upto)
|
||
|
QSTORE_DATA(first_walkable_prim_point);
|
||
|
QSTORE_DATA(number_of_walkable_prim_points);
|
||
|
QSTORE_DATA(first_walkable_prim_face4);
|
||
|
QSTORE_DATA(number_of_walkable_prim_faces4);
|
||
|
QSTORE_DATA(BARREL_sphere_last);
|
||
|
QSTORE_DATA(track_head);
|
||
|
QSTORE_DATA(track_tail);
|
||
|
QSTORE_DATA(track_eob);
|
||
|
QSTORE_DATA( NIGHT_dlight_free);
|
||
|
QSTORE_DATA( NIGHT_dlight_used);
|
||
|
|
||
|
QSTORE_DATA(EWAY_time_accurate);
|
||
|
QSTORE_DATA(EWAY_time);
|
||
|
QSTORE_DATA(EWAY_tick);
|
||
|
QSTORE_DATA(EWAY_cam_active);
|
||
|
QSTORE_DATA(EWAY_cam_x);
|
||
|
QSTORE_DATA(EWAY_cam_y);
|
||
|
QSTORE_DATA(EWAY_cam_z);
|
||
|
QSTORE_DATA(EWAY_cam_dx);
|
||
|
QSTORE_DATA(EWAY_cam_dy);
|
||
|
QSTORE_DATA(EWAY_cam_dz);
|
||
|
QSTORE_DATA(EWAY_cam_yaw);
|
||
|
QSTORE_DATA(EWAY_cam_pitch);
|
||
|
QSTORE_DATA(EWAY_cam_waypoint);
|
||
|
QSTORE_DATA(EWAY_cam_target);
|
||
|
QSTORE_DATA(EWAY_cam_delay);
|
||
|
QSTORE_DATA(EWAY_cam_speed);
|
||
|
QSTORE_DATA(EWAY_cam_freeze);
|
||
|
QSTORE_DATA(EWAY_cam_cant_interrupt);
|
||
|
|
||
|
QSTORE_DATA( NIGHT_amb_d3d_colour);
|
||
|
QSTORE_DATA( NIGHT_amb_d3d_specular);
|
||
|
QSTORE_DATA( NIGHT_amb_red);
|
||
|
QSTORE_DATA( NIGHT_amb_green);
|
||
|
QSTORE_DATA( NIGHT_amb_blue);
|
||
|
QSTORE_DATA( NIGHT_amb_norm_x);
|
||
|
QSTORE_DATA( NIGHT_amb_norm_y);
|
||
|
QSTORE_DATA( NIGHT_amb_norm_z);
|
||
|
QSTORE_DATA( NIGHT_flag);
|
||
|
QSTORE_DATA( NIGHT_lampost_radius);
|
||
|
QSTORE_DATA( NIGHT_lampost_red);
|
||
|
QSTORE_DATA( NIGHT_lampost_green);
|
||
|
QSTORE_DATA( NIGHT_lampost_blue);
|
||
|
QSTORE_DATA( NIGHT_sky_colour);
|
||
|
QSTORE_DATA(padding_byte);
|
||
|
QSTORE_DATA(check);
|
||
|
QSTORE_DATA(CRIME_RATE);
|
||
|
QSTORE_DATA(CRIME_RATE_SCORE_MUL);
|
||
|
QSTORE_DATA(MUSIC_WORLD);
|
||
|
QSTORE_DATA(BOREDOM_RATE);
|
||
|
QSTORE_DATA(world_type);
|
||
|
|
||
|
QSTORE_DATA(EWAY_fake_wander_text_normal_index );
|
||
|
QSTORE_DATA(EWAY_fake_wander_text_normal_number );
|
||
|
QSTORE_DATA(EWAY_fake_wander_text_guilty_index );
|
||
|
QSTORE_DATA(EWAY_fake_wander_text_guilty_number );
|
||
|
QSTORE_DATA(EWAY_fake_wander_text_annoyed_index );
|
||
|
QSTORE_DATA(EWAY_fake_wander_text_annoyed_number);
|
||
|
|
||
|
QSTORE_DATA(GAME_FLAGS);
|
||
|
|
||
|
//
|
||
|
// Lighting stuff that isn't saved on the PSX, so it isn't in the save table.
|
||
|
//
|
||
|
|
||
|
if (fwrite( NIGHT_square, sizeof(NIGHT_Square), NIGHT_MAX_SQUARES , handle) != NIGHT_MAX_SQUARES ) goto file_error;
|
||
|
if (fwrite(&NIGHT_square_free, sizeof(NIGHT_square_free), 1 , handle) != 1 ) goto file_error;
|
||
|
if (fwrite( NIGHT_cache, sizeof(UBYTE), PAP_SIZE_LO * PAP_SIZE_LO, handle) != PAP_SIZE_LO * PAP_SIZE_LO) goto file_error;
|
||
|
|
||
|
if (fwrite( NIGHT_dfcache, sizeof(NIGHT_Dfcache), NIGHT_MAX_DFCACHES , handle) != NIGHT_MAX_DFCACHES ) goto file_error;
|
||
|
if (fwrite(&NIGHT_dfcache_used, sizeof(UBYTE), 1 , handle) != 1 ) goto file_error;
|
||
|
if (fwrite(&NIGHT_dfcache_free, sizeof(UBYTE), 1 , handle) != 1 ) goto file_error;
|
||
|
|
||
|
//
|
||
|
// Make sure we're in the right place.
|
||
|
//
|
||
|
|
||
|
checksum = MEMORY_QUICK_CHECK;
|
||
|
|
||
|
QSTORE_DATA(checksum);
|
||
|
|
||
|
MF_Fclose(handle);
|
||
|
|
||
|
MEMORY_quick_avaliable = TRUE;
|
||
|
|
||
|
return;
|
||
|
|
||
|
file_error:;
|
||
|
|
||
|
MF_Fclose(handle);
|
||
|
|
||
|
FileDelete(MEMORY_QUICK_FNAME);
|
||
|
|
||
|
MEMORY_quick_avaliable = FALSE;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
SLONG MEMORY_quick_load_available(void)
|
||
|
{
|
||
|
return MEMORY_quick_avaliable;
|
||
|
}
|
||
|
|
||
|
|
||
|
SLONG MEMORY_quick_load()
|
||
|
{
|
||
|
SLONG i;
|
||
|
UBYTE padding_byte;
|
||
|
SLONG check = 666;
|
||
|
SLONG checksum;
|
||
|
|
||
|
FILE *handle = MF_Fopen(MEMORY_QUICK_FNAME, "rb");
|
||
|
|
||
|
if (!handle)
|
||
|
{
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save out a version number.
|
||
|
//
|
||
|
|
||
|
SLONG version;
|
||
|
|
||
|
if (fread(&version, sizeof(SLONG), 1, handle) != 1) goto file_error;
|
||
|
|
||
|
ASSERT(version == 1);
|
||
|
|
||
|
//
|
||
|
// Go through the memory table and load all arrays.
|
||
|
//
|
||
|
|
||
|
MemTable *mt;
|
||
|
|
||
|
for (i = 0; save_table[i].Point; i++)
|
||
|
{
|
||
|
mt = &save_table[i];
|
||
|
|
||
|
if (fread(mt->Point, mt->StructSize, mt->Maximum, handle) != (unsigned)mt->Maximum) goto file_error;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Save out the extra data we might need!
|
||
|
//
|
||
|
|
||
|
#define QREAD_DATA(x) if (fread(&(x), sizeof(x), 1, handle) != 1) goto file_error;
|
||
|
|
||
|
QREAD_DATA(PRIMARY_USED);
|
||
|
QREAD_DATA(PRIMARY_UNUSED);
|
||
|
QREAD_DATA(SECONDARY_USED);
|
||
|
QREAD_DATA(SECONDARY_UNUSED);
|
||
|
QREAD_DATA(PERSON_COUNT);
|
||
|
QREAD_DATA(PERSON_COUNT);
|
||
|
QREAD_DATA(ANIMAL_COUNT);
|
||
|
QREAD_DATA(CHOPPER_COUNT);
|
||
|
QREAD_DATA(PYRO_COUNT);
|
||
|
QREAD_DATA(PLAYER_COUNT);
|
||
|
QREAD_DATA(PROJECTILE_COUNT);
|
||
|
QREAD_DATA(SPECIAL_COUNT);
|
||
|
QREAD_DATA(SWITCH_COUNT);
|
||
|
QREAD_DATA(PRIMARY_COUNT);
|
||
|
QREAD_DATA(SECONDARY_COUNT);
|
||
|
QREAD_DATA(GAME_STATE);
|
||
|
|
||
|
#ifdef TARGET_DC
|
||
|
GAME_STATE &= ~(GS_RECORD|GS_PLAYBACK|GS_EDITOR);
|
||
|
#endif
|
||
|
|
||
|
QREAD_DATA(GAME_TURN);
|
||
|
QREAD_DATA(GAME_FLAGS);
|
||
|
QREAD_DATA(TEXTURE_set);
|
||
|
QREAD_DATA(WMOVE_face_upto)
|
||
|
QREAD_DATA(first_walkable_prim_point);
|
||
|
QREAD_DATA(number_of_walkable_prim_points);
|
||
|
QREAD_DATA(first_walkable_prim_face4);
|
||
|
QREAD_DATA(number_of_walkable_prim_faces4);
|
||
|
QREAD_DATA(BARREL_sphere_last);
|
||
|
QREAD_DATA(track_head);
|
||
|
QREAD_DATA(track_tail);
|
||
|
QREAD_DATA(track_eob);
|
||
|
QREAD_DATA( NIGHT_dlight_free);
|
||
|
QREAD_DATA( NIGHT_dlight_used);
|
||
|
|
||
|
QREAD_DATA(EWAY_time_accurate);
|
||
|
QREAD_DATA(EWAY_time);
|
||
|
QREAD_DATA(EWAY_tick);
|
||
|
QREAD_DATA(EWAY_cam_active);
|
||
|
QREAD_DATA(EWAY_cam_x);
|
||
|
QREAD_DATA(EWAY_cam_y);
|
||
|
QREAD_DATA(EWAY_cam_z);
|
||
|
QREAD_DATA(EWAY_cam_dx);
|
||
|
QREAD_DATA(EWAY_cam_dy);
|
||
|
QREAD_DATA(EWAY_cam_dz);
|
||
|
QREAD_DATA(EWAY_cam_yaw);
|
||
|
QREAD_DATA(EWAY_cam_pitch);
|
||
|
QREAD_DATA(EWAY_cam_waypoint);
|
||
|
QREAD_DATA(EWAY_cam_target);
|
||
|
QREAD_DATA(EWAY_cam_delay);
|
||
|
QREAD_DATA(EWAY_cam_speed);
|
||
|
QREAD_DATA(EWAY_cam_freeze);
|
||
|
QREAD_DATA(EWAY_cam_cant_interrupt);
|
||
|
QREAD_DATA( NIGHT_amb_d3d_colour);
|
||
|
QREAD_DATA( NIGHT_amb_d3d_specular);
|
||
|
QREAD_DATA( NIGHT_amb_red);
|
||
|
QREAD_DATA( NIGHT_amb_green);
|
||
|
QREAD_DATA( NIGHT_amb_blue);
|
||
|
QREAD_DATA( NIGHT_amb_norm_x);
|
||
|
QREAD_DATA( NIGHT_amb_norm_y);
|
||
|
QREAD_DATA( NIGHT_amb_norm_z);
|
||
|
QREAD_DATA( NIGHT_flag);
|
||
|
QREAD_DATA( NIGHT_lampost_radius);
|
||
|
QREAD_DATA( NIGHT_lampost_red);
|
||
|
QREAD_DATA( NIGHT_lampost_green);
|
||
|
QREAD_DATA( NIGHT_lampost_blue);
|
||
|
QREAD_DATA( NIGHT_sky_colour);
|
||
|
QREAD_DATA(padding_byte);
|
||
|
QREAD_DATA(check);
|
||
|
QREAD_DATA(CRIME_RATE);
|
||
|
QREAD_DATA(CRIME_RATE_SCORE_MUL);
|
||
|
QREAD_DATA(MUSIC_WORLD);
|
||
|
QREAD_DATA(BOREDOM_RATE);
|
||
|
QREAD_DATA(world_type);
|
||
|
|
||
|
QREAD_DATA(EWAY_fake_wander_text_normal_index );
|
||
|
QREAD_DATA(EWAY_fake_wander_text_normal_number );
|
||
|
QREAD_DATA(EWAY_fake_wander_text_guilty_index );
|
||
|
QREAD_DATA(EWAY_fake_wander_text_guilty_number );
|
||
|
QREAD_DATA(EWAY_fake_wander_text_annoyed_index );
|
||
|
QREAD_DATA(EWAY_fake_wander_text_annoyed_number);
|
||
|
|
||
|
QREAD_DATA(GAME_FLAGS);
|
||
|
|
||
|
//
|
||
|
// Lighting stuff that isn't saved on the PSX, so it isn't in the save table.
|
||
|
//
|
||
|
|
||
|
if (fread( NIGHT_square, sizeof(NIGHT_Square), NIGHT_MAX_SQUARES , handle) != NIGHT_MAX_SQUARES ) goto file_error;
|
||
|
if (fread(&NIGHT_square_free, sizeof(NIGHT_square_free), 1 , handle) != 1 ) goto file_error;
|
||
|
if (fread( NIGHT_cache, sizeof(UBYTE), PAP_SIZE_LO * PAP_SIZE_LO, handle) != PAP_SIZE_LO * PAP_SIZE_LO) goto file_error;
|
||
|
|
||
|
if (fread( NIGHT_dfcache, sizeof(NIGHT_Dfcache), NIGHT_MAX_DFCACHES , handle) != NIGHT_MAX_DFCACHES ) goto file_error;
|
||
|
if (fread(&NIGHT_dfcache_used, sizeof(UBYTE), 1 , handle) != 1 ) goto file_error;
|
||
|
if (fread(&NIGHT_dfcache_free, sizeof(UBYTE), 1 , handle) != 1 ) goto file_error;
|
||
|
|
||
|
//
|
||
|
// Make sure we're in the right place.
|
||
|
//
|
||
|
|
||
|
QREAD_DATA(checksum);
|
||
|
|
||
|
if (checksum != MEMORY_QUICK_CHECK)
|
||
|
{
|
||
|
goto file_error;
|
||
|
}
|
||
|
|
||
|
MF_Fclose(handle);
|
||
|
|
||
|
NIGHT_cache_recalc();
|
||
|
NIGHT_dfcache_recalc();
|
||
|
NIGHT_generate_walkable_lighting();
|
||
|
|
||
|
return TRUE;
|
||
|
|
||
|
file_error:;
|
||
|
|
||
|
MF_Fclose(handle);
|
||
|
|
||
|
return FALSE;
|
||
|
}
|
||
|
|
||
|
|
||
|
#endif
|
||
|
#endif
|
||
|
|
||
|
|
||
|
#ifndef TARGET_DC
|
||
|
#if 1 // TEST_DC
|
||
|
|
||
|
//
|
||
|
// Dreamcast load/save games...
|
||
|
//
|
||
|
|
||
|
void save_dreamcast_wad(CBYTE *fname)
|
||
|
{
|
||
|
|
||
|
SLONG c0=0;
|
||
|
SLONG *p_slong;
|
||
|
UWORD *p_uword;
|
||
|
UBYTE *p_mem;
|
||
|
SLONG mem_size,mem_cumlative=0;
|
||
|
struct MemTable *ptab;
|
||
|
MFFileHandle handle = FILE_OPEN_ERROR;
|
||
|
SLONG count;
|
||
|
SLONG save_type=0;
|
||
|
SLONG check=666;
|
||
|
UBYTE padding_byte;
|
||
|
UWORD padding_word;
|
||
|
ULONG struct_size;
|
||
|
|
||
|
//
|
||
|
// The dreamcast doesn't want darci_normals...
|
||
|
//
|
||
|
|
||
|
darci_normal_count = 0;
|
||
|
|
||
|
//
|
||
|
// remove anything that can't survive the reload (transient effects)
|
||
|
//
|
||
|
|
||
|
|
||
|
// Sets up level_index for special fudges.
|
||
|
extern SLONG get_level_no ( CBYTE *name );
|
||
|
get_level_no(fname);
|
||
|
|
||
|
|
||
|
// Add a full pathname.
|
||
|
|
||
|
char cFullName[100] = "c:\\fallen\\";
|
||
|
strcat ( cFullName, fname );
|
||
|
|
||
|
// Change the extension to ".dad"
|
||
|
int iLastChar = strlen ( cFullName );
|
||
|
ASSERT ( cFullName[iLastChar-4] == '.' );
|
||
|
ASSERT ( cFullName[iLastChar-3] == 'u' );
|
||
|
ASSERT ( cFullName[iLastChar-2] == 'c' );
|
||
|
ASSERT ( cFullName[iLastChar-1] == 'm' );
|
||
|
|
||
|
cFullName[iLastChar-3] = 'd';
|
||
|
cFullName[iLastChar-2] = 'a';
|
||
|
cFullName[iLastChar-1] = 'd';
|
||
|
|
||
|
TRACE ( "Writing out level <%s>", cFullName );
|
||
|
|
||
|
handle = FileCreate(cFullName, 1);
|
||
|
|
||
|
if(handle!=FILE_CREATION_ERROR)
|
||
|
{
|
||
|
// get rid of the nasty pointers
|
||
|
// by converting to indexes
|
||
|
|
||
|
convert_pointers_to_index();
|
||
|
|
||
|
DebugText("\n SAVE INGAME \n");
|
||
|
|
||
|
STORE_DATA(save_type);
|
||
|
|
||
|
while(save_table[c0].Point)
|
||
|
{
|
||
|
mem_size=0;
|
||
|
count=0;
|
||
|
// ASSERT(c0!=29);
|
||
|
ptab=&save_table[c0];
|
||
|
switch(ptab->Type)
|
||
|
{
|
||
|
case MEM_STATIC:
|
||
|
mem_size=ptab->Maximum*ptab->StructSize;
|
||
|
count=ptab->Maximum;
|
||
|
break;
|
||
|
|
||
|
case MEM_DYNAMIC:
|
||
|
if(ptab->CountL)
|
||
|
{
|
||
|
count=*ptab->CountL;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(ptab->CountW)
|
||
|
|
||
|
count=*ptab->CountW;
|
||
|
}
|
||
|
if(ptab->Extra) // redundant but more readable!
|
||
|
count+=ptab->Extra; // we have some extra ones so increase how many we create,
|
||
|
// this is also saved into the next_blah_blah filed but the
|
||
|
// loader will subtract this off for next_blah_blah
|
||
|
|
||
|
mem_size=count*ptab->StructSize;
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
ASSERT(0);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
|
||
|
p_mem=(UBYTE*)*ptab->Point;
|
||
|
|
||
|
// chunk id
|
||
|
FileWrite(handle,(UBYTE*)&c0,4);
|
||
|
FileWrite(handle,(UBYTE*)&count,4);
|
||
|
struct_size=ptab->StructSize;
|
||
|
FileWrite(handle,(UBYTE*)&struct_size,4);
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4);
|
||
|
if(mem_size&3)
|
||
|
FileWrite(handle,(UBYTE*)&mem_size,4-(mem_size&3));
|
||
|
|
||
|
FileWrite(handle,(UBYTE*)p_mem,mem_size);
|
||
|
|
||
|
mem_cumlative+=mem_size;
|
||
|
|
||
|
if(ptab->CountL)
|
||
|
DebugText(" %s -> %d tot %d (%d/%d)\n",ptab->Name,mem_size,mem_cumlative,*ptab->CountL,ptab->Maximum);
|
||
|
else
|
||
|
if(ptab->CountW)
|
||
|
DebugText(" %s -> %d tot %d (%d/%d)\n",ptab->Name,mem_size,mem_cumlative,*ptab->CountW,ptab->Maximum);
|
||
|
else
|
||
|
DebugText(" %s -> %d tot %d (%d)\n",ptab->Name,mem_size,mem_cumlative,ptab->Maximum);
|
||
|
|
||
|
c0++;
|
||
|
}
|
||
|
DebugText("\n");
|
||
|
|
||
|
STORE_DATA(PRIMARY_USED);
|
||
|
STORE_DATA(PRIMARY_UNUSED);
|
||
|
STORE_DATA(SECONDARY_USED);
|
||
|
STORE_DATA(SECONDARY_UNUSED);
|
||
|
STORE_DATA(PERSON_COUNT);
|
||
|
STORE_DATA(PERSON_COUNT);
|
||
|
STORE_DATA(ANIMAL_COUNT);
|
||
|
STORE_DATA(CHOPPER_COUNT);
|
||
|
STORE_DATA(PYRO_COUNT);
|
||
|
STORE_DATA(PLAYER_COUNT);
|
||
|
STORE_DATA(PROJECTILE_COUNT);
|
||
|
STORE_DATA(SPECIAL_COUNT);
|
||
|
STORE_DATA(SWITCH_COUNT);
|
||
|
STORE_DATA(PRIMARY_COUNT);
|
||
|
STORE_DATA(SECONDARY_COUNT);
|
||
|
STORE_DATA(GAME_STATE);
|
||
|
STORE_DATA(GAME_TURN);
|
||
|
STORE_DATA(GAME_FLAGS);
|
||
|
STORE_DATA(TEXTURE_set);
|
||
|
STORE_DATA(WMOVE_face_upto);
|
||
|
STORE_DATA(first_walkable_prim_point);
|
||
|
STORE_DATA(number_of_walkable_prim_points);
|
||
|
STORE_DATA(first_walkable_prim_face4);
|
||
|
STORE_DATA(number_of_walkable_prim_faces4);
|
||
|
STORE_DATA(BARREL_sphere_last);
|
||
|
STORE_DATA(track_head);
|
||
|
STORE_DATA(track_tail);
|
||
|
STORE_DATA(track_eob);
|
||
|
STORE_DATA( NIGHT_dlight_free);
|
||
|
STORE_DATA( NIGHT_dlight_used);
|
||
|
|
||
|
|
||
|
STORE_DATA(EWAY_time_accurate);
|
||
|
STORE_DATA(EWAY_time);
|
||
|
STORE_DATA(EWAY_tick);
|
||
|
|
||
|
|
||
|
|
||
|
STORE_DATA(EWAY_cam_active);
|
||
|
STORE_DATA(EWAY_cam_goinactive);
|
||
|
STORE_DATA(EWAY_cam_x); // Big coordinates...
|
||
|
STORE_DATA(EWAY_cam_y);
|
||
|
STORE_DATA(EWAY_cam_z);
|
||
|
STORE_DATA(EWAY_cam_dx);
|
||
|
STORE_DATA(EWAY_cam_dy);
|
||
|
STORE_DATA(EWAY_cam_dz);
|
||
|
STORE_DATA(EWAY_cam_yaw);
|
||
|
STORE_DATA(EWAY_cam_pitch);
|
||
|
STORE_DATA(EWAY_cam_want_yaw);
|
||
|
STORE_DATA(EWAY_cam_want_pitch);
|
||
|
STORE_DATA(EWAY_cam_waypoint);
|
||
|
STORE_DATA(EWAY_cam_target);
|
||
|
STORE_DATA(EWAY_cam_delay);
|
||
|
STORE_DATA(EWAY_cam_speed);
|
||
|
STORE_DATA(EWAY_cam_freeze); // Stop the player moving.
|
||
|
STORE_DATA(EWAY_cam_cant_interrupt);
|
||
|
STORE_DATA(EWAY_cam_thing);
|
||
|
STORE_DATA(EWAY_cam_thing);
|
||
|
STORE_DATA(EWAY_cam_targx);
|
||
|
STORE_DATA(EWAY_cam_targy);
|
||
|
STORE_DATA(EWAY_cam_targz);
|
||
|
STORE_DATA(EWAY_cam_lens); // 16-bit fixed point
|
||
|
STORE_DATA(EWAY_cam_warehouse);
|
||
|
STORE_DATA(EWAY_cam_lock);
|
||
|
STORE_DATA(EWAY_cam_last_yaw);
|
||
|
STORE_DATA(EWAY_cam_last_x);
|
||
|
STORE_DATA(EWAY_cam_last_y);
|
||
|
STORE_DATA(EWAY_cam_last_z);
|
||
|
STORE_DATA(EWAY_cam_skip);
|
||
|
STORE_DATA(EWAY_cam_last_dyaw);
|
||
|
|
||
|
|
||
|
|
||
|
STORE_DATA( NIGHT_amb_d3d_colour);
|
||
|
STORE_DATA( NIGHT_amb_d3d_specular);
|
||
|
STORE_DATA( NIGHT_amb_red);
|
||
|
STORE_DATA( NIGHT_amb_green);
|
||
|
STORE_DATA( NIGHT_amb_blue);
|
||
|
STORE_DATA( NIGHT_amb_norm_x);
|
||
|
STORE_DATA( NIGHT_amb_norm_y);
|
||
|
STORE_DATA( NIGHT_amb_norm_z);
|
||
|
STORE_DATA( NIGHT_flag);
|
||
|
STORE_DATA( NIGHT_lampost_radius);
|
||
|
STORE_DATA( NIGHT_lampost_red);
|
||
|
STORE_DATA( NIGHT_lampost_green);
|
||
|
STORE_DATA( NIGHT_lampost_blue);
|
||
|
STORE_DATA( NIGHT_sky_colour);
|
||
|
STORE_DATA(padding_byte);
|
||
|
STORE_DATA(check);
|
||
|
STORE_DATA(CRIME_RATE);
|
||
|
STORE_DATA(CRIME_RATE_SCORE_MUL);
|
||
|
STORE_DATA(MUSIC_WORLD);
|
||
|
STORE_DATA(BOREDOM_RATE);
|
||
|
STORE_DATA(world_type);
|
||
|
STORE_DATA(TEXTURE_SET);
|
||
|
STORE_DATA(padding_word);
|
||
|
|
||
|
STORE_DATA(EWAY_fake_wander_text_normal_index );
|
||
|
STORE_DATA(EWAY_fake_wander_text_normal_number );
|
||
|
STORE_DATA(EWAY_fake_wander_text_guilty_index );
|
||
|
STORE_DATA(EWAY_fake_wander_text_guilty_number );
|
||
|
STORE_DATA(EWAY_fake_wander_text_annoyed_index );
|
||
|
STORE_DATA(EWAY_fake_wander_text_annoyed_number);
|
||
|
|
||
|
STORE_DATA(GAME_FLAGS);
|
||
|
|
||
|
STORE_DATA(semtex);
|
||
|
STORE_DATA(estate);
|
||
|
STORE_DATA(padding_word);
|
||
|
|
||
|
|
||
|
#ifdef OLD_CAM
|
||
|
|
||
|
CAM_focus=(Thing*)THING_NUMBER(CAM_focus);
|
||
|
STORE_DATA(CAM_focus);
|
||
|
CAM_focus=TO_THING((SLONG)CAM_focus);
|
||
|
#endif
|
||
|
|
||
|
save_whole_anims(handle);
|
||
|
|
||
|
FileClose(handle);
|
||
|
|
||
|
//
|
||
|
// convert back again
|
||
|
//
|
||
|
|
||
|
convert_index_to_pointers();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#endif // TEST_DC
|
||
|
#endif // not TARGET_DC
|
||
|
|
||
|
|
||
|
//#ifdef TARGET_DC
|
||
|
#if TEST_DC
|
||
|
|
||
|
|
||
|
void load_dreamcast_wad(CBYTE *fname)
|
||
|
{
|
||
|
SLONG c0=0,id;
|
||
|
SLONG *p_slong;
|
||
|
UWORD *p_uword;
|
||
|
UBYTE *p_mem,*p_all;
|
||
|
ULONG mem_size;
|
||
|
struct MemTable *ptab;
|
||
|
#ifndef PSX
|
||
|
MFFileHandle handle = FILE_OPEN_ERROR;
|
||
|
#else
|
||
|
SLONG handle;
|
||
|
#endif
|
||
|
SLONG count;
|
||
|
SLONG texture_set_local;
|
||
|
SLONG save_type;
|
||
|
|
||
|
SLONG check;
|
||
|
UBYTE padding_byte;
|
||
|
UWORD padding_word;
|
||
|
|
||
|
SetSeed(1234567);
|
||
|
srand(1234567);
|
||
|
|
||
|
|
||
|
|
||
|
// Clear out all the rendering pages' VBs and IBs.
|
||
|
extern void POLY_ClearAllPages ( void );
|
||
|
POLY_ClearAllPages();
|
||
|
|
||
|
|
||
|
|
||
|
extern UWORD player_dlight;
|
||
|
player_dlight=0;
|
||
|
|
||
|
//
|
||
|
// Load in the wad file into memory.
|
||
|
//
|
||
|
|
||
|
#ifndef LAZY_LOADING_MEMORY_ON_DC_PLEASE_BOB
|
||
|
if(mem_all)
|
||
|
MemFree(mem_all);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
// Add a full pathname.
|
||
|
char cFullName[64] = "";
|
||
|
strcat ( cFullName, fname );
|
||
|
|
||
|
// Change the extension to ".dad"
|
||
|
int iLastChar = strlen ( cFullName );
|
||
|
ASSERT ( cFullName[iLastChar-4] == '.' );
|
||
|
ASSERT ( cFullName[iLastChar-3] == 'u' );
|
||
|
ASSERT ( cFullName[iLastChar-2] == 'c' );
|
||
|
ASSERT ( cFullName[iLastChar-1] == 'm' );
|
||
|
|
||
|
cFullName[iLastChar-3] = 'd';
|
||
|
cFullName[iLastChar-2] = 'a';
|
||
|
cFullName[iLastChar-1] = 'd';
|
||
|
|
||
|
TRACE ( "Reading level <%s>", cFullName );
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//strcpy ( cFullName, "dream.dad" );
|
||
|
|
||
|
handle=FileOpen(cFullName);
|
||
|
if(handle==FILE_OPEN_ERROR)
|
||
|
{
|
||
|
ASSERT(0);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
mem_size=FileSize(handle);
|
||
|
|
||
|
#ifdef LAZY_LOADING_MEMORY_ON_DC_PLEASE_BOB
|
||
|
if ( mem_size > mem_all_size )
|
||
|
{
|
||
|
if ( mem_all != NULL )
|
||
|
{
|
||
|
MemFree ( mem_all );
|
||
|
}
|
||
|
mem_all = MemAlloc ( mem_size );
|
||
|
ASSERT ( mem_all != NULL );
|
||
|
mem_all_size = mem_size;
|
||
|
}
|
||
|
#else
|
||
|
|
||
|
mem_all=(UBYTE*)MemAlloc(mem_size);
|
||
|
mem_all_size=mem_size;
|
||
|
ASSERT(mem_all);
|
||
|
#endif
|
||
|
|
||
|
ASSERT ( mem_all != NULL );
|
||
|
ASSERT ( mem_size <= mem_all_size );
|
||
|
FileRead(handle,mem_all,mem_size);
|
||
|
FileClose(handle);
|
||
|
p_all = (UBYTE *)mem_all;
|
||
|
|
||
|
|
||
|
extern UBYTE loading_screen_active;
|
||
|
loading_screen_active = TRUE;
|
||
|
|
||
|
//
|
||
|
// Assign the data...
|
||
|
//
|
||
|
|
||
|
GET_DATA(save_type);
|
||
|
|
||
|
// printf("Save Type: %d\n",save_type);
|
||
|
while(save_table[c0].Point)
|
||
|
{
|
||
|
SLONG struct_size;
|
||
|
// printf("Loading: %s\n",save_table[c0].Name);
|
||
|
id=*((SLONG*)p_all);
|
||
|
// printf(" id %d ",id);
|
||
|
ASSERT(id==c0);
|
||
|
p_all+=4;
|
||
|
|
||
|
count=*((SLONG*)p_all);
|
||
|
// printf(" count %d",count);
|
||
|
p_all+=4;
|
||
|
|
||
|
struct_size=*((SLONG*)p_all);
|
||
|
p_all+=4;
|
||
|
// printf(" struct size %d shouldbe %d memsize %d\n",struct_size,save_table[c0].StructSize,*(SLONG*)p_all);
|
||
|
ASSERT(struct_size==save_table[c0].StructSize);
|
||
|
|
||
|
mem_size=*((SLONG*)p_all);
|
||
|
p_all+=4;
|
||
|
|
||
|
if(mem_size&3)
|
||
|
p_all+=4-(mem_size&3);
|
||
|
|
||
|
ptab=&save_table[c0];
|
||
|
|
||
|
*ptab->Point=p_all;
|
||
|
|
||
|
switch(ptab->Type)
|
||
|
{
|
||
|
case 2:
|
||
|
if(ptab->Extra)
|
||
|
ptab->Maximum=count;
|
||
|
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
if(ptab->Extra)
|
||
|
count-=ptab->Extra;
|
||
|
|
||
|
if(ptab->CountL)
|
||
|
{
|
||
|
*ptab->CountL=count;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(ptab->CountW)
|
||
|
*ptab->CountW=count;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
p_all+=mem_size;
|
||
|
|
||
|
c0++;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// I wonder what this does!
|
||
|
//
|
||
|
|
||
|
for(c0=0;c0<EWAY_mess_buffer_upto;c0++)
|
||
|
{
|
||
|
if (EWAY_mess_buffer[c0]==160)
|
||
|
{
|
||
|
EWAY_mess_buffer[c0]=32;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
GET_DATA(PRIMARY_USED);
|
||
|
GET_DATA(PRIMARY_UNUSED);
|
||
|
GET_DATA(SECONDARY_USED);
|
||
|
GET_DATA(SECONDARY_UNUSED);
|
||
|
GET_DATA(PERSON_COUNT);
|
||
|
GET_DATA(PERSON_COUNT);
|
||
|
GET_DATA(ANIMAL_COUNT);
|
||
|
GET_DATA(CHOPPER_COUNT);
|
||
|
GET_DATA(PYRO_COUNT);
|
||
|
GET_DATA(PLAYER_COUNT);
|
||
|
GET_DATA(PROJECTILE_COUNT);
|
||
|
GET_DATA(SPECIAL_COUNT);
|
||
|
GET_DATA(SWITCH_COUNT);
|
||
|
GET_DATA(PRIMARY_COUNT);
|
||
|
GET_DATA(SECONDARY_COUNT);
|
||
|
// Don't load this from the WAD!
|
||
|
//GET_DATA(GAME_STATE);
|
||
|
p_all+=sizeof(GAME_STATE);
|
||
|
|
||
|
#ifdef TARGET_DC
|
||
|
GAME_STATE &= ~(GS_RECORD|GS_PLAYBACK|GS_EDITOR);
|
||
|
#endif
|
||
|
|
||
|
GET_DATA(GAME_TURN);
|
||
|
GET_DATA(GAME_FLAGS);
|
||
|
GET_DATA(texture_set_local);
|
||
|
GET_DATA(WMOVE_face_upto);
|
||
|
GET_DATA(first_walkable_prim_point);
|
||
|
GET_DATA(number_of_walkable_prim_points);
|
||
|
GET_DATA(first_walkable_prim_face4);
|
||
|
GET_DATA(number_of_walkable_prim_faces4);
|
||
|
GET_DATA(BARREL_sphere_last);
|
||
|
GET_DATA(track_head);
|
||
|
GET_DATA(track_tail);
|
||
|
GET_DATA(track_eob);
|
||
|
GET_DATA( NIGHT_dlight_free);
|
||
|
GET_DATA( NIGHT_dlight_used);
|
||
|
|
||
|
|
||
|
GET_DATA(EWAY_time_accurate);
|
||
|
GET_DATA(EWAY_time);
|
||
|
GET_DATA(EWAY_tick);
|
||
|
|
||
|
GET_DATA(EWAY_cam_active);
|
||
|
GET_DATA(EWAY_cam_goinactive);
|
||
|
GET_DATA(EWAY_cam_x); // Big coordinates...
|
||
|
GET_DATA(EWAY_cam_y);
|
||
|
GET_DATA(EWAY_cam_z);
|
||
|
GET_DATA(EWAY_cam_dx);
|
||
|
GET_DATA(EWAY_cam_dy);
|
||
|
GET_DATA(EWAY_cam_dz);
|
||
|
GET_DATA(EWAY_cam_yaw);
|
||
|
GET_DATA(EWAY_cam_pitch);
|
||
|
GET_DATA(EWAY_cam_want_yaw);
|
||
|
GET_DATA(EWAY_cam_want_pitch);
|
||
|
GET_DATA(EWAY_cam_waypoint);
|
||
|
GET_DATA(EWAY_cam_target);
|
||
|
GET_DATA(EWAY_cam_delay);
|
||
|
GET_DATA(EWAY_cam_speed);
|
||
|
GET_DATA(EWAY_cam_freeze); // Stop the player moving.
|
||
|
GET_DATA(EWAY_cam_cant_interrupt);
|
||
|
GET_DATA(EWAY_cam_thing);
|
||
|
GET_DATA(EWAY_cam_thing); // Twice because EWAY_cam_thing is a UWORD
|
||
|
GET_DATA(EWAY_cam_targx);
|
||
|
GET_DATA(EWAY_cam_targy);
|
||
|
GET_DATA(EWAY_cam_targz);
|
||
|
GET_DATA(EWAY_cam_lens); // 16-bit fixed point
|
||
|
GET_DATA(EWAY_cam_warehouse);
|
||
|
GET_DATA(EWAY_cam_lock);
|
||
|
GET_DATA(EWAY_cam_last_yaw);
|
||
|
GET_DATA(EWAY_cam_last_x);
|
||
|
GET_DATA(EWAY_cam_last_y);
|
||
|
GET_DATA(EWAY_cam_last_z);
|
||
|
GET_DATA(EWAY_cam_skip);
|
||
|
GET_DATA(EWAY_cam_last_dyaw);
|
||
|
|
||
|
|
||
|
GET_DATA(NIGHT_amb_d3d_colour);
|
||
|
GET_DATA(NIGHT_amb_d3d_specular);
|
||
|
GET_DATA(NIGHT_amb_red);
|
||
|
GET_DATA(NIGHT_amb_green);
|
||
|
GET_DATA(NIGHT_amb_blue);
|
||
|
GET_DATA(NIGHT_amb_norm_x);
|
||
|
GET_DATA(NIGHT_amb_norm_y);
|
||
|
GET_DATA(NIGHT_amb_norm_z);
|
||
|
GET_DATA(NIGHT_flag);
|
||
|
GET_DATA(NIGHT_lampost_radius);
|
||
|
GET_DATA(NIGHT_lampost_red);
|
||
|
GET_DATA(NIGHT_lampost_green);
|
||
|
GET_DATA(NIGHT_lampost_blue);
|
||
|
GET_DATA(NIGHT_sky_colour);
|
||
|
GET_DATA(padding_byte);
|
||
|
GET_DATA(check);
|
||
|
GET_DATA(CRIME_RATE);
|
||
|
GET_DATA(CRIME_RATE_SCORE_MUL);
|
||
|
GET_DATA(MUSIC_WORLD);
|
||
|
GET_DATA(BOREDOM_RATE);
|
||
|
GET_DATA(world_type);
|
||
|
GET_DATA(TEXTURE_SET);
|
||
|
GET_DATA(padding_word);
|
||
|
|
||
|
GET_DATA(EWAY_fake_wander_text_normal_index );
|
||
|
GET_DATA(EWAY_fake_wander_text_normal_number );
|
||
|
GET_DATA(EWAY_fake_wander_text_guilty_index );
|
||
|
GET_DATA(EWAY_fake_wander_text_guilty_number );
|
||
|
GET_DATA(EWAY_fake_wander_text_annoyed_index );
|
||
|
GET_DATA(EWAY_fake_wander_text_annoyed_number);
|
||
|
|
||
|
GET_DATA(GAME_FLAGS);
|
||
|
|
||
|
GET_DATA(semtex);
|
||
|
GET_DATA(estate);
|
||
|
GET_DATA(padding_word);
|
||
|
|
||
|
ASSERT(check==666);
|
||
|
|
||
|
//NIGHT_flag&=~NIGHT_FLAG_DAYTIME;
|
||
|
|
||
|
// This needs to go here, if it doesn't then the later levels will
|
||
|
// automatically fail because the timer will be over the time limit.
|
||
|
|
||
|
EWAY_time_accurate = 0;
|
||
|
EWAY_time = 0;
|
||
|
EWAY_count_up = 0;
|
||
|
|
||
|
//
|
||
|
// The penalties on the count-up timer.
|
||
|
//
|
||
|
|
||
|
EWAY_count_up_add_penalties = 0;
|
||
|
EWAY_count_up_num_penalties = 0;
|
||
|
EWAY_count_up_penalty_timer = 0;
|
||
|
|
||
|
// NIGHT_amb_red*=2;
|
||
|
// NIGHT_amb_green*=2;
|
||
|
// NIGHT_amb_blue*=2;
|
||
|
SATURATE(NIGHT_amb_red,16,127);
|
||
|
SATURATE(NIGHT_amb_green,16,127);
|
||
|
SATURATE(NIGHT_amb_blue,25,127);
|
||
|
|
||
|
|
||
|
//
|
||
|
// this needs to be before convert_index_to_pointers (because c_i_t_p needs the anims in place)
|
||
|
//
|
||
|
load_whole_anims(p_all);
|
||
|
|
||
|
void setup_global_anim_array(void);
|
||
|
setup_global_anim_array();
|
||
|
void init_dead_tween(void);
|
||
|
init_dead_tween();
|
||
|
|
||
|
convert_index_to_pointers();
|
||
|
|
||
|
// Reset camera mode.
|
||
|
extern int g_iPlayerCameraMode;
|
||
|
g_iPlayerCameraMode = 0;
|
||
|
FC_change_camera_type(0,0);
|
||
|
FC_look_at(0, THING_NUMBER(NET_PERSON(0)));
|
||
|
FC_force_camera_behind(0);
|
||
|
|
||
|
uncache();
|
||
|
|
||
|
//
|
||
|
// Pass a NULL filename to TEXTURE_load_needed(). This is okay if
|
||
|
// we aren't using texture clumping.
|
||
|
//
|
||
|
// Er.... no it isn't - I need that name! ATF
|
||
|
//
|
||
|
|
||
|
if ( ( GAME_STATE & GS_REPLAY ) == 0 )
|
||
|
{
|
||
|
TEXTURE_choose_set(texture_set_local);
|
||
|
//TEXTURE_load_needed(NULL);
|
||
|
TEXTURE_load_needed(fname, 0, 256, 900);
|
||
|
}
|
||
|
|
||
|
extern void PARTICLE_Reset();
|
||
|
PARTICLE_Reset();
|
||
|
|
||
|
extern void POW_init();
|
||
|
POW_init();
|
||
|
|
||
|
// calc_prim_info();
|
||
|
VEH_init_vehinfo();
|
||
|
|
||
|
extern void DIRT_init(SLONG,SLONG,SLONG,SLONG,SLONG,SLONG,SLONG);
|
||
|
DIRT_init(100, 3, 3, INFINITY, INFINITY, INFINITY, INFINITY);
|
||
|
|
||
|
extern void init_noises(void);
|
||
|
extern void init_arrest(void);
|
||
|
init_noises();
|
||
|
init_arrest();
|
||
|
void MIST_init();
|
||
|
MIST_init();
|
||
|
extern void PANEL_new_text_init();
|
||
|
PANEL_new_text_init();
|
||
|
SPARK_init();
|
||
|
|
||
|
|
||
|
// Set Darci's powerups.
|
||
|
NET_PLAYER(0)->Genus.Player->Strength =the_game.DarciStrength;
|
||
|
NET_PLAYER(0)->Genus.Player->Constitution=the_game.DarciConstitution;
|
||
|
NET_PLAYER(0)->Genus.Player->Stamina =the_game.DarciStamina;
|
||
|
NET_PLAYER(0)->Genus.Player->Skill =the_game.DarciSkill;
|
||
|
|
||
|
// Clear the cheat status.
|
||
|
extern bool g_bPunishMePleaseICheatedOnThisLevel;
|
||
|
g_bPunishMePleaseICheatedOnThisLevel = FALSE;
|
||
|
|
||
|
calc_prim_normals();
|
||
|
// find_anim_prim_bboxes();
|
||
|
|
||
|
// TEXTURE_fix_prim_textures();
|
||
|
// TEXTURE_fix_texture_styles();
|
||
|
AENG_create_dx_prim_points();
|
||
|
NIGHT_generate_walkable_lighting();
|
||
|
|
||
|
flag_v_faces();
|
||
|
|
||
|
//
|
||
|
// Stop it getting too dark, bloody artists!
|
||
|
//
|
||
|
void init_gangattack(void);
|
||
|
|
||
|
init_gangattack(); //probably should save these
|
||
|
|
||
|
extern SBYTE global_spang_count;
|
||
|
global_spang_count=0;
|
||
|
|
||
|
|
||
|
extern UBYTE EWAY_conv_active;
|
||
|
EWAY_conv_active=0; //fixes semtex restart crash during cut scene
|
||
|
|
||
|
#ifdef TARGET_DC
|
||
|
// Reactivates mist.
|
||
|
extern void EWAY_reactivate_waypoints_that_arent_in_the_dad_file ( void );
|
||
|
EWAY_reactivate_waypoints_that_arent_in_the_dad_file ();
|
||
|
#endif
|
||
|
|
||
|
loading_screen_active = FALSE;
|
||
|
|
||
|
}
|
||
|
|
||
|
#endif // TARGET_DC
|