#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 #include #include #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>=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(splast_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>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;c0Class) { 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;c0count_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;c0count_people) count_people=c0; } } for(c0=1;c0count_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;c0thing) 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;c0MaxPeopleTypes); //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;c0MaxPeopleTypes); //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)c01570) if(1) { for(c0=0;(unsigned)c0ElementCount;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;c0MaxElements); memset((UBYTE*)bits,0,gc->MaxElements*2); if(c0!=5) for(c1=0;c1MaxKeyFrames;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;eleElementCount;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;c0MaxElements); bits=(UWORD *)MemAlloc(sizeof(UWORD)*gc->MaxElements); memset((UBYTE*)bits,0,gc->MaxElements*2); if(c0!=5) for(c1=0;c1MaxKeyFrames;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)eleElementCount;ele++) { //if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetXAnimKeyFrames[c1].FirstElement[ele].OffsetX); //if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetYAnimKeyFrames[c1].FirstElement[ele].OffsetY); //if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZAnimKeyFrames[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)eleElementCount;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)eleElementCount;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;c1MaxElements;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;c0MaxElements); bits=(UWORD *)MemAlloc(sizeof(UWORD)*gc->MaxElements); memset((UBYTE*)bits,0,gc->MaxElements*2); /* for(c1=0;c1MaxKeyFrames;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;eleElementCount;ele++) { //if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetXAnimKeyFrames[c1].FirstElement[ele].OffsetX); //if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetYAnimKeyFrames[c1].FirstElement[ele].OffsetY); //if(gc->AnimKeyFrames[c1].FirstElement[ele].OffsetZAnimKeyFrames[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;eleElementCount;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;c1MaxElements;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)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<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;c0thing) 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=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=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;c0Points[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;c0Points[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;c0Genus.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;c0Genus.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