]> git.lizzy.rs Git - plan9front.git/blob - sys/src/games/doom/p_saveg.c
games/doom: fix the french problem, remove debug prints
[plan9front.git] / sys / src / games / doom / p_saveg.c
1 // Emacs style mode select   -*- C++ -*- 
2 //-----------------------------------------------------------------------------
3 //
4 // $Id:$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
11 //
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
16 //
17 // $Log:$
18 //
19 // DESCRIPTION:
20 //      Archiving: SaveGame I/O.
21 //
22 //-----------------------------------------------------------------------------
23
24 static const char
25 rcsid[] = "$Id: p_tick.c,v 1.4 1997/02/03 16:47:55 b1 Exp $";
26
27 #include "i_system.h"
28 #include "z_zone.h"
29 #include "p_local.h"
30
31 // State.
32 #include "doomstat.h"
33 #include "r_state.h"
34
35 byte*           save_p;
36
37
38 // Pads save_p to a 4-byte boundary
39 //  so that the load/save works on SGI&Gecko.
40 #define PADSAVEP()      save_p += (4 - ((int) save_p & 3)) & 3
41
42
43
44 //
45 // P_ArchivePlayers
46 //
47 void P_ArchivePlayers (void)
48 {
49     int         i;
50     int         j;
51     player_t*   dest;
52                 
53     for (i=0 ; i<MAXPLAYERS ; i++)
54     {
55         if (!playeringame[i])
56             continue;
57         
58         PADSAVEP();
59
60         dest = (player_t *)save_p;
61         memcpy (dest,&players[i],sizeof(player_t));
62         save_p += sizeof(player_t);
63         for (j=0 ; j<NUMPSPRITES ; j++)
64         {
65             if (dest->psprites[j].state)
66             {
67                 dest->psprites[j].state 
68                     = (state_t *)(dest->psprites[j].state-states);
69             }
70         }
71     }
72 }
73
74
75
76 //
77 // P_UnArchivePlayers
78 //
79 void P_UnArchivePlayers (void)
80 {
81     int         i;
82     int         j;
83         
84     for (i=0 ; i<MAXPLAYERS ; i++)
85     {
86         if (!playeringame[i])
87             continue;
88         
89         PADSAVEP();
90
91         memcpy (&players[i],save_p, sizeof(player_t));
92         save_p += sizeof(player_t);
93         
94         // will be set when unarc thinker
95         players[i].mo = NULL;   
96         players[i].message = NULL;
97         players[i].attacker = NULL;
98
99         for (j=0 ; j<NUMPSPRITES ; j++)
100         {
101             if (players[i]. psprites[j].state)
102             {
103                 players[i]. psprites[j].state 
104                     = &states[ (int)players[i].psprites[j].state ];
105             }
106         }
107     }
108 }
109
110
111 //
112 // P_ArchiveWorld
113 //
114 void P_ArchiveWorld (void)
115 {
116     int                 i;
117     int                 j;
118     sector_t*           sec;
119     line_t*             li;
120     side_t*             si;
121     short*              put;
122         
123     put = (short *)save_p;
124     
125     // do sectors
126     for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
127     {
128         *put++ = sec->floorheight >> FRACBITS;
129         *put++ = sec->ceilingheight >> FRACBITS;
130         *put++ = sec->floorpic;
131         *put++ = sec->ceilingpic;
132         *put++ = sec->lightlevel;
133         *put++ = sec->special;          // needed?
134         *put++ = sec->tag;              // needed?
135     }
136
137     
138     // do lines
139     for (i=0, li = lines ; i<numlines ; i++,li++)
140     {
141         *put++ = li->flags;
142         *put++ = li->special;
143         *put++ = li->tag;
144         for (j=0 ; j<2 ; j++)
145         {
146             if (li->sidenum[j] == -1)
147                 continue;
148             
149             si = &sides[li->sidenum[j]];
150
151             *put++ = si->textureoffset >> FRACBITS;
152             *put++ = si->rowoffset >> FRACBITS;
153             *put++ = si->toptexture;
154             *put++ = si->bottomtexture;
155             *put++ = si->midtexture;    
156         }
157     }
158         
159     save_p = (byte *)put;
160 }
161
162
163
164 //
165 // P_UnArchiveWorld
166 //
167 void P_UnArchiveWorld (void)
168 {
169     int                 i;
170     int                 j;
171     sector_t*           sec;
172     line_t*             li;
173     side_t*             si;
174     short*              get;
175         
176     get = (short *)save_p;
177     
178     // do sectors
179     for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
180     {
181         sec->floorheight = *get++ << FRACBITS;
182         sec->ceilingheight = *get++ << FRACBITS;
183         sec->floorpic = *get++;
184         sec->ceilingpic = *get++;
185         sec->lightlevel = *get++;
186         sec->special = *get++;          // needed?
187         sec->tag = *get++;              // needed?
188         sec->specialdata = 0;
189         sec->soundtarget = 0;
190     }
191     
192     // do lines
193     for (i=0, li = lines ; i<numlines ; i++,li++)
194     {
195         li->flags = *get++;
196         li->special = *get++;
197         li->tag = *get++;
198         for (j=0 ; j<2 ; j++)
199         {
200             if (li->sidenum[j] == -1)
201                 continue;
202             si = &sides[li->sidenum[j]];
203             si->textureoffset = *get++ << FRACBITS;
204             si->rowoffset = *get++ << FRACBITS;
205             si->toptexture = *get++;
206             si->bottomtexture = *get++;
207             si->midtexture = *get++;
208         }
209     }
210     save_p = (byte *)get;       
211 }
212
213
214
215
216
217 //
218 // Thinkers
219 //
220 typedef enum
221 {
222     tc_end,
223     tc_mobj
224
225 } thinkerclass_t;
226
227
228
229 //
230 // P_ArchiveThinkers
231 //
232 void P_ArchiveThinkers (void)
233 {
234     thinker_t*          th;
235     mobj_t*             mobj;
236         
237     // save off the current thinkers
238     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
239     {
240         if (th->function == P_MobjThinker)
241         {
242             *save_p++ = tc_mobj;
243             PADSAVEP();
244             mobj = (mobj_t *)save_p;
245             memcpy (mobj, th, sizeof(*mobj));
246             save_p += sizeof(*mobj);
247             mobj->state = (state_t *)(mobj->state - states);
248             
249             if (mobj->player)
250                 mobj->player = (player_t *)((mobj->player-players) + 1);
251             continue;
252         }
253                 
254         // I_Error ("P_ArchiveThinkers: Unknown thinker function");
255     }
256
257     // add a terminating marker
258     *save_p++ = (byte)tc_end;   
259 }
260
261
262
263 //
264 // P_UnArchiveThinkers
265 //
266 void P_UnArchiveThinkers (void)
267 {
268     byte                tclass;
269     thinker_t*          currentthinker;
270     thinker_t*          next;
271     mobj_t*             mobj;
272     
273     // remove all the current thinkers
274     currentthinker = thinkercap.next;
275     while (currentthinker != &thinkercap)
276     {
277         next = currentthinker->next;
278         
279         if (currentthinker->function == P_MobjThinker)
280             P_RemoveMobj ((mobj_t *)currentthinker);
281         else
282             Z_Free (currentthinker);
283
284         currentthinker = next;
285     }
286     P_InitThinkers ();
287         
288     // read in saved thinkers
289     while (1)
290     {
291         tclass = *save_p++;
292         switch (tclass)
293         {
294           case tc_end:
295             return;     // end of list
296                         
297           case tc_mobj:
298             PADSAVEP();
299             mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
300             memcpy (mobj, save_p, sizeof(*mobj));
301             save_p += sizeof(*mobj);
302             mobj->state = &states[(int)mobj->state];
303             mobj->target = NULL;
304             if (mobj->player)
305             {
306                 mobj->player = &players[(int)mobj->player-1];
307                 mobj->player->mo = mobj;
308             }
309             P_SetThingPosition (mobj);
310             mobj->info = &mobjinfo[mobj->type];
311             mobj->floorz = mobj->subsector->sector->floorheight;
312             mobj->ceilingz = mobj->subsector->sector->ceilingheight;
313             mobj->thinker.function = P_MobjThinker;
314             P_AddThinker (&mobj->thinker);
315             break;
316                         
317           default:
318             I_Error ("Unknown tclass %i in savegame",tclass);
319         }
320         
321     }
322
323 }
324
325
326 //
327 // P_ArchiveSpecials
328 //
329 enum
330 {
331     tc_ceiling,
332     tc_door,
333     tc_floor,
334     tc_plat,
335     tc_flash,
336     tc_strobe,
337     tc_glow,
338     tc_endspecials
339
340 } specials_e;   
341
342
343
344 //
345 // Things to handle:
346 //
347 // T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
348 // T_VerticalDoor, (vldoor_t: sector_t * swizzle),
349 // T_MoveFloor, (floormove_t: sector_t * swizzle),
350 // T_LightFlash, (lightflash_t: sector_t * swizzle),
351 // T_StrobeFlash, (strobe_t: sector_t *),
352 // T_Glow, (glow_t: sector_t *),
353 // T_PlatRaise, (plat_t: sector_t *), - active list
354 //
355 void P_ArchiveSpecials (void)
356 {
357     thinker_t*          th;
358     ceiling_t*          ceiling;
359     vldoor_t*           door;
360     floormove_t*        floor;
361     plat_t*             plat;
362     lightflash_t*       flash;
363     strobe_t*           strobe;
364     glow_t*             glow;
365     int                 i;
366         
367     // save off the current thinkers
368     for (th = thinkercap.next ; th != &thinkercap ; th=th->next)
369     {
370         if (th->function == NULL)
371         {
372             for (i = 0; i < MAXCEILINGS;i++)
373                 if (activeceilings[i] == (ceiling_t *)th)
374                     break;
375             
376             if (i<MAXCEILINGS)
377             {
378                 *save_p++ = tc_ceiling;
379                 PADSAVEP();
380                 ceiling = (ceiling_t *)save_p;
381                 memcpy (ceiling, th, sizeof(*ceiling));
382                 save_p += sizeof(*ceiling);
383                 ceiling->sector = (sector_t *)(ceiling->sector - sectors);
384             }
385             continue;
386         }
387                         
388         if (th->function == T_MoveCeiling)
389         {
390             *save_p++ = tc_ceiling;
391             PADSAVEP();
392             ceiling = (ceiling_t *)save_p;
393             memcpy (ceiling, th, sizeof(*ceiling));
394             save_p += sizeof(*ceiling);
395             ceiling->sector = (sector_t *)(ceiling->sector - sectors);
396             continue;
397         }
398                         
399         if (th->function == T_VerticalDoor)
400         {
401             *save_p++ = tc_door;
402             PADSAVEP();
403             door = (vldoor_t *)save_p;
404             memcpy (door, th, sizeof(*door));
405             save_p += sizeof(*door);
406             door->sector = (sector_t *)(door->sector - sectors);
407             continue;
408         }
409                         
410         if (th->function == T_MoveFloor)
411         {
412             *save_p++ = tc_floor;
413             PADSAVEP();
414             floor = (floormove_t *)save_p;
415             memcpy (floor, th, sizeof(*floor));
416             save_p += sizeof(*floor);
417             floor->sector = (sector_t *)(floor->sector - sectors);
418             continue;
419         }
420                         
421         if (th->function == T_PlatRaise)
422         {
423             *save_p++ = tc_plat;
424             PADSAVEP();
425             plat = (plat_t *)save_p;
426             memcpy (plat, th, sizeof(*plat));
427             save_p += sizeof(*plat);
428             plat->sector = (sector_t *)(plat->sector - sectors);
429             continue;
430         }
431                         
432         if (th->function == T_LightFlash)
433         {
434             *save_p++ = tc_flash;
435             PADSAVEP();
436             flash = (lightflash_t *)save_p;
437             memcpy (flash, th, sizeof(*flash));
438             save_p += sizeof(*flash);
439             flash->sector = (sector_t *)(flash->sector - sectors);
440             continue;
441         }
442                         
443         if (th->function == T_StrobeFlash)
444         {
445             *save_p++ = tc_strobe;
446             PADSAVEP();
447             strobe = (strobe_t *)save_p;
448             memcpy (strobe, th, sizeof(*strobe));
449             save_p += sizeof(*strobe);
450             strobe->sector = (sector_t *)(strobe->sector - sectors);
451             continue;
452         }
453                         
454         if (th->function == T_Glow)
455         {
456             *save_p++ = tc_glow;
457             PADSAVEP();
458             glow = (glow_t *)save_p;
459             memcpy (glow, th, sizeof(*glow));
460             save_p += sizeof(*glow);
461             glow->sector = (sector_t *)(glow->sector - sectors);
462             continue;
463         }
464     }
465         
466     // add a terminating marker
467     *save_p++ = tc_endspecials; 
468
469 }
470
471
472 //
473 // P_UnArchiveSpecials
474 //
475 void P_UnArchiveSpecials (void)
476 {
477     byte                tclass;
478     ceiling_t*          ceiling;
479     vldoor_t*           door;
480     floormove_t*        floor;
481     plat_t*             plat;
482     lightflash_t*       flash;
483     strobe_t*           strobe;
484     glow_t*             glow;
485         
486         
487     // read in saved thinkers
488     while (1)
489     {
490         tclass = *save_p++;
491         switch (tclass)
492         {
493           case tc_endspecials:
494             return;     // end of list
495                         
496           case tc_ceiling:
497             PADSAVEP();
498             ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL);
499             memcpy (ceiling, save_p, sizeof(*ceiling));
500             save_p += sizeof(*ceiling);
501             ceiling->sector = &sectors[(int)ceiling->sector];
502             ceiling->sector->specialdata = ceiling;
503
504             if (ceiling->thinker.function)
505                 ceiling->thinker.function = T_MoveCeiling;
506
507             P_AddThinker (&ceiling->thinker);
508             P_AddActiveCeiling(ceiling);
509             break;
510                                 
511           case tc_door:
512             PADSAVEP();
513             door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL);
514             memcpy (door, save_p, sizeof(*door));
515             save_p += sizeof(*door);
516             door->sector = &sectors[(int)door->sector];
517             door->sector->specialdata = door;
518             door->thinker.function = T_VerticalDoor;
519             P_AddThinker (&door->thinker);
520             break;
521                                 
522           case tc_floor:
523             PADSAVEP();
524             floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
525             memcpy (floor, save_p, sizeof(*floor));
526             save_p += sizeof(*floor);
527             floor->sector = &sectors[(int)floor->sector];
528             floor->sector->specialdata = floor;
529             floor->thinker.function = T_MoveFloor;
530             P_AddThinker (&floor->thinker);
531             break;
532                                 
533           case tc_plat:
534             PADSAVEP();
535             plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
536             memcpy (plat, save_p, sizeof(*plat));
537             save_p += sizeof(*plat);
538             plat->sector = &sectors[(int)plat->sector];
539             plat->sector->specialdata = plat;
540
541             if (plat->thinker.function)
542                 plat->thinker.function = T_PlatRaise;
543
544             P_AddThinker (&plat->thinker);
545             P_AddActivePlat(plat);
546             break;
547                                 
548           case tc_flash:
549             PADSAVEP();
550             flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
551             memcpy (flash, save_p, sizeof(*flash));
552             save_p += sizeof(*flash);
553             flash->sector = &sectors[(int)flash->sector];
554             flash->thinker.function = T_LightFlash;
555             P_AddThinker (&flash->thinker);
556             break;
557                                 
558           case tc_strobe:
559             PADSAVEP();
560             strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
561             memcpy (strobe, save_p, sizeof(*strobe));
562             save_p += sizeof(*strobe);
563             strobe->sector = &sectors[(int)strobe->sector];
564             strobe->thinker.function = T_StrobeFlash;
565             P_AddThinker (&strobe->thinker);
566             break;
567                                 
568           case tc_glow:
569             PADSAVEP();
570             glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
571             memcpy (glow, save_p, sizeof(*glow));
572             save_p += sizeof(*glow);
573             glow->sector = &sectors[(int)glow->sector];
574             glow->thinker.function = T_Glow;
575             P_AddThinker (&glow->thinker);
576             break;
577                                 
578           default:
579             I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
580                      "in savegame",tclass);
581         }
582         
583     }
584
585 }
586