]> icculus.org git repositories - theoddone33/hheretic.git/blob - base/p_tick.c
Optimized blit functions.
[theoddone33/hheretic.git] / base / p_tick.c
1
2 // P_tick.c
3
4 #include "doomdef.h"
5 #include "p_local.h"
6
7 int leveltime;
8 int TimerGame;
9
10 /*
11 ====================
12 =
13 = P_ArchivePlayers
14 =
15 ====================
16 */
17
18 void P_ArchivePlayers(void)
19 {
20         int i;
21         int j;
22         player_t dest;
23
24         for(i = 0; i < MAXPLAYERS; i++)
25         {
26                 if(!playeringame[i])
27                 {
28                         continue;
29                 }
30                 memcpy(&dest, &players[i], sizeof(player_t));
31                 for(j = 0; j < NUMPSPRITES; j++)
32                 {
33                         if(dest.psprites[j].state)
34                         {
35                                 dest.psprites[j].state =
36                                         (state_t *)(dest.psprites[j].state-states);
37                         }
38                 }
39                 SV_Write(&dest, sizeof(player_t));
40         }
41 }
42
43 /*
44 ====================
45 =
46 = P_UnArchivePlayers
47 =
48 ====================
49 */
50
51 void P_UnArchivePlayers (void)
52 {
53         int             i,j;
54
55         for (i=0 ; i<MAXPLAYERS ; i++)
56         {
57                 if (!playeringame[i])
58                         continue;
59                 memcpy (&players[i],save_p, sizeof(player_t));
60                 save_p += sizeof(player_t);
61                 players[i].mo = NULL;           // will be set when unarc thinker
62                 players[i].message = NULL;
63                 players[i].attacker = NULL;
64                 for (j=0 ; j<NUMPSPRITES ; j++)
65                         if (players[i]. psprites[j].state)
66                                 players[i]. psprites[j].state 
67                                 = &states[ (int)players[i].psprites[j].state ];
68         }
69 }
70
71 //=============================================================================
72
73
74 /*
75 ====================
76 =
77 = P_ArchiveWorld
78 =
79 ====================
80 */
81
82 void P_ArchiveWorld(void)
83 {
84         int i, j;
85         sector_t *sec;
86         line_t *li;
87         side_t *si;
88
89         // Sectors
90         for(i = 0, sec = sectors; i < numsectors; i++, sec++)
91         {
92                 SV_WriteWord(sec->floorheight>>FRACBITS);
93                 SV_WriteWord(sec->ceilingheight>>FRACBITS);
94                 SV_WriteWord(sec->floorpic);
95                 SV_WriteWord(sec->ceilingpic);
96                 SV_WriteWord(sec->lightlevel);
97                 SV_WriteWord(sec->special); // needed?
98                 SV_WriteWord(sec->tag); // needed?
99         }
100
101         // Lines
102         for(i = 0, li = lines; i < numlines; i++, li++)
103         {
104                 SV_WriteWord(li->flags);
105                 SV_WriteWord(li->special);
106                 SV_WriteWord(li->tag);
107                 for(j = 0; j < 2; j++)
108                 {
109                         if(li->sidenum[j] == -1)
110                         {
111                                 continue;
112                         }
113                         si = &sides[li->sidenum[j]];
114                         SV_WriteWord(si->textureoffset>>FRACBITS);
115                         SV_WriteWord(si->rowoffset>>FRACBITS);
116                         SV_WriteWord(si->toptexture);
117                         SV_WriteWord(si->bottomtexture);
118                         SV_WriteWord(si->midtexture);
119                 }
120         }
121 }
122
123 /*
124 ====================
125 =
126 = P_UnArchiveWorld
127 =
128 ====================
129 */
130
131 void P_UnArchiveWorld (void)
132 {
133         int                     i,j;
134         sector_t        *sec;
135         line_t          *li;
136         side_t          *si;
137         short           *get;
138         
139         get = (short *)save_p;
140                 
141 //
142 // do sectors
143 //
144         for (i=0, sec = sectors ; i<numsectors ; i++,sec++)
145         {
146                 sec->floorheight = *get++ << FRACBITS;
147                 sec->ceilingheight = *get++ << FRACBITS;
148                 sec->floorpic = *get++;
149                 sec->ceilingpic = *get++;
150                 sec->lightlevel = *get++;
151                 sec->special = *get++;  // needed?
152                 sec->tag = *get++;              // needed?
153                 sec->specialdata = 0;
154                 sec->soundtarget = 0;
155         }       
156
157 //
158 // do lines
159 //
160         for (i=0, li = lines ; i<numlines ; i++,li++)
161         {
162                 li->flags = *get++;
163                 li->special = *get++;
164                 li->tag = *get++;
165                 for (j=0 ; j<2 ; j++)
166                 {
167                         if (li->sidenum[j] == -1)
168                                 continue;
169                         si = &sides[li->sidenum[j]];
170                         si->textureoffset = *get++ << FRACBITS;
171                         si->rowoffset = *get++ << FRACBITS;
172                         si->toptexture = *get++;
173                         si->bottomtexture = *get++;
174                         si->midtexture = *get++;
175                 }
176         }
177                 
178         save_p = (byte *)get;   
179 }
180
181 //=============================================================================
182
183 typedef enum
184 {
185         tc_end,
186         tc_mobj
187 } thinkerclass_t;
188
189 /*
190 ====================
191 =
192 = P_ArchiveThinkers
193 =
194 ====================
195 */
196
197 void P_ArchiveThinkers(void)
198 {
199         thinker_t *th;
200         mobj_t mobj;
201
202         for(th = thinkercap.next; th != &thinkercap; th = th->next)
203         {
204                 if(th->function == P_MobjThinker)
205                 {
206                         SV_WriteByte(tc_mobj);
207                         memcpy(&mobj, th, sizeof(mobj_t));
208                         mobj.state = (state_t *)(mobj.state-states);
209                         if(mobj.player)
210                         {
211                                 mobj.player = (player_t *)((mobj.player-players)+1);
212                         }
213                         SV_Write(&mobj, sizeof(mobj_t));
214                         continue;
215                 }
216                 //I_Error("P_ArchiveThinkers: Unknown thinker function");
217         }
218
219         // Add a terminating marker
220         SV_WriteByte(tc_end);
221 }
222
223 /*
224 ====================
225 =
226 = P_UnArchiveThinkers
227 =
228 ====================
229 */
230
231 void P_UnArchiveThinkers (void)
232 {
233         byte            tclass;
234         thinker_t       *currentthinker, *next;
235         mobj_t          *mobj;
236         
237 //
238 // remove all the current thinkers
239 //
240         currentthinker = thinkercap.next;
241         while (currentthinker != &thinkercap)
242         {
243                 next = currentthinker->next;
244                 if (currentthinker->function == P_MobjThinker)
245                         P_RemoveMobj ((mobj_t *)currentthinker);
246                 else
247                         Z_Free (currentthinker);
248                 currentthinker = next;
249         }
250         P_InitThinkers ();
251         
252 // read in saved thinkers
253         while (1)
254         {
255                 tclass = *save_p++;
256                 switch (tclass)
257                 {
258                 case tc_end:
259                         return;                 // end of list
260                         
261                 case tc_mobj:
262                         mobj = Z_Malloc (sizeof(*mobj), PU_LEVEL, NULL);
263                         memcpy (mobj, save_p, sizeof(*mobj));
264                         save_p += sizeof(*mobj);
265                         mobj->state = &states[(int)mobj->state];
266                         mobj->target = NULL;
267                         if (mobj->player)
268                         {
269                                 mobj->player = &players[(int)mobj->player-1];
270                                 mobj->player->mo = mobj;
271                         }
272                         P_SetThingPosition (mobj);
273                         mobj->info = &mobjinfo[mobj->type];
274                         mobj->floorz = mobj->subsector->sector->floorheight;
275                         mobj->ceilingz = mobj->subsector->sector->ceilingheight;
276                         mobj->thinker.function = P_MobjThinker;
277                         P_AddThinker (&mobj->thinker);
278                         break;
279                         
280                 default:
281                         I_Error ("Unknown tclass %i in savegame",tclass);
282                 }
283         
284         }
285
286 }
287
288 //=============================================================================
289
290
291 /*
292 ====================
293 =
294 = P_ArchiveSpecials
295 =
296 ====================
297 */
298 enum
299 {
300         tc_ceiling,
301         tc_door,
302         tc_floor,
303         tc_plat,
304         tc_flash,
305         tc_strobe,
306         tc_glow,
307         tc_endspecials
308 } specials_e;   
309
310 void P_ArchiveSpecials(void)
311 {
312 /*
313 T_MoveCeiling, (ceiling_t: sector_t * swizzle), - active list
314 T_VerticalDoor, (vldoor_t: sector_t * swizzle),
315 T_MoveFloor, (floormove_t: sector_t * swizzle),
316 T_LightFlash, (lightflash_t: sector_t * swizzle),
317 T_StrobeFlash, (strobe_t: sector_t *),
318 T_Glow, (glow_t: sector_t *),
319 T_PlatRaise, (plat_t: sector_t *), - active list
320 */
321
322         thinker_t *th;
323         ceiling_t ceiling;
324         vldoor_t door;
325         floormove_t floor;
326         plat_t plat;
327         lightflash_t flash;
328         strobe_t strobe;
329         glow_t glow;
330
331         for(th = thinkercap.next; th != &thinkercap; th = th->next)
332         {
333                 if(th->function == T_MoveCeiling)
334                 {
335                         SV_WriteByte(tc_ceiling);
336                         memcpy(&ceiling, th, sizeof(ceiling_t));
337                         ceiling.sector = (sector_t *)(ceiling.sector-sectors);
338                         SV_Write(&ceiling, sizeof(ceiling_t));
339                         continue;
340                 }
341                 if(th->function == T_VerticalDoor)
342                 {
343                         SV_WriteByte(tc_door);
344                         memcpy(&door, th, sizeof(vldoor_t));
345                         door.sector = (sector_t *)(door.sector-sectors);
346                         SV_Write(&door, sizeof(vldoor_t));
347                         continue;
348                 }
349                 if(th->function == T_MoveFloor)
350                 {
351                         SV_WriteByte(tc_floor);
352                         memcpy(&floor, th, sizeof(floormove_t));
353                         floor.sector = (sector_t *)(floor.sector-sectors);
354                         SV_Write(&floor, sizeof(floormove_t));
355                         continue;
356                 }
357                 if(th->function == T_PlatRaise)
358                 {
359                         SV_WriteByte(tc_plat);
360                         memcpy(&plat, th, sizeof(plat_t));
361                         plat.sector = (sector_t *)(plat.sector-sectors);
362                         SV_Write(&plat, sizeof(plat_t));
363                         continue;
364                 }
365                 if(th->function == T_LightFlash)
366                 {
367                         SV_WriteByte(tc_flash);
368                         memcpy(&flash, th, sizeof(lightflash_t));
369                         flash.sector = (sector_t *)(flash.sector-sectors);
370                         SV_Write(&flash, sizeof(lightflash_t));
371                         continue;
372                 }
373                 if(th->function == T_StrobeFlash)
374                 {
375                         SV_WriteByte(tc_strobe);
376                         memcpy(&strobe, th, sizeof(strobe_t));
377                         strobe.sector = (sector_t *)(strobe.sector-sectors);
378                         SV_Write(&strobe, sizeof(strobe_t));
379                         continue;
380                 }
381                 if(th->function == T_Glow)
382                 {
383                         SV_WriteByte(tc_glow);
384                         memcpy(&glow, th, sizeof(glow_t));
385                         glow.sector = (sector_t *)(glow.sector-sectors);
386                         SV_Write(&glow, sizeof(glow_t));
387                         continue;
388                 }
389         }
390         // Add a terminating marker
391         SV_WriteByte(tc_endspecials);
392 }
393
394 /*
395 ====================
396 =
397 = P_UnArchiveSpecials
398 =
399 ====================
400 */
401
402 void P_UnArchiveSpecials (void)
403 {
404         byte            tclass;
405         ceiling_t       *ceiling;
406         vldoor_t        *door;
407         floormove_t     *floor;
408         plat_t          *plat;
409         lightflash_t *flash;
410         strobe_t        *strobe;
411         glow_t          *glow;
412         
413         
414 // read in saved thinkers
415         while (1)
416         {
417                 tclass = *save_p++;
418                 switch (tclass)
419                 {
420                         case tc_endspecials:
421                                 return;                 // end of list
422                         
423                         case tc_ceiling:
424                                 ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVEL, NULL);
425                                 memcpy (ceiling, save_p, sizeof(*ceiling));
426                                 save_p += sizeof(*ceiling);
427                                 ceiling->sector = &sectors[(int)ceiling->sector];
428                                 ceiling->sector->specialdata = T_MoveCeiling;
429                                 if (ceiling->thinker.function)
430                                         ceiling->thinker.function = T_MoveCeiling;
431                                 P_AddThinker (&ceiling->thinker);
432                                 P_AddActiveCeiling(ceiling);
433                                 break;
434
435                         case tc_door:
436                                 door = Z_Malloc (sizeof(*door), PU_LEVEL, NULL);
437                                 memcpy (door, save_p, sizeof(*door));
438                                 save_p += sizeof(*door);
439                                 door->sector = &sectors[(int)door->sector];
440                                 door->sector->specialdata = door;
441                                 door->thinker.function = T_VerticalDoor;
442                                 P_AddThinker (&door->thinker);
443                                 break;
444
445                         case tc_floor:
446                                 floor = Z_Malloc (sizeof(*floor), PU_LEVEL, NULL);
447                                 memcpy (floor, save_p, sizeof(*floor));
448                                 save_p += sizeof(*floor);
449                                 floor->sector = &sectors[(int)floor->sector];
450                                 floor->sector->specialdata = T_MoveFloor;
451                                 floor->thinker.function = T_MoveFloor;
452                                 P_AddThinker (&floor->thinker);
453                                 break;
454                                 
455                         case tc_plat:
456                                 plat = Z_Malloc (sizeof(*plat), PU_LEVEL, NULL);
457                                 memcpy (plat, save_p, sizeof(*plat));
458                                 save_p += sizeof(*plat);
459                                 plat->sector = &sectors[(int)plat->sector];
460                                 plat->sector->specialdata = T_PlatRaise;
461                                 if (plat->thinker.function)
462                                         plat->thinker.function = T_PlatRaise;
463                                 P_AddThinker (&plat->thinker);
464                                 P_AddActivePlat(plat);
465                                 break;
466                                 
467                         case tc_flash:
468                                 flash = Z_Malloc (sizeof(*flash), PU_LEVEL, NULL);
469                                 memcpy (flash, save_p, sizeof(*flash));
470                                 save_p += sizeof(*flash);
471                                 flash->sector = &sectors[(int)flash->sector];
472                                 flash->thinker.function = T_LightFlash;
473                                 P_AddThinker (&flash->thinker);
474                                 break;
475                                 
476                         case tc_strobe:
477                                 strobe = Z_Malloc (sizeof(*strobe), PU_LEVEL, NULL);
478                                 memcpy (strobe, save_p, sizeof(*strobe));
479                                 save_p += sizeof(*strobe);
480                                 strobe->sector = &sectors[(int)strobe->sector];
481                                 strobe->thinker.function = T_StrobeFlash;
482                                 P_AddThinker (&strobe->thinker);
483                                 break;
484                                 
485                         case tc_glow:
486                                 glow = Z_Malloc (sizeof(*glow), PU_LEVEL, NULL);
487                                 memcpy (glow, save_p, sizeof(*glow));
488                                 save_p += sizeof(*glow);
489                                 glow->sector = &sectors[(int)glow->sector];
490                                 glow->thinker.function = T_Glow;
491                                 P_AddThinker (&glow->thinker);
492                                 break;
493                                 
494                         default:
495                                 I_Error ("P_UnarchiveSpecials:Unknown tclass %i "
496                                                         "in savegame",tclass);
497                 }
498         
499         }
500
501 }
502
503
504
505 /*
506 ===============================================================================
507
508                                                                 THINKERS
509
510 All thinkers should be allocated by Z_Malloc so they can be operated on uniformly.  The actual
511 structures will vary in size, but the first element must be thinker_t.
512
513 ===============================================================================
514 */
515
516 thinker_t       thinkercap;     // both the head and tail of the thinker list
517
518 /*
519 ===============
520 =
521 = P_InitThinkers
522 =
523 ===============
524 */
525
526 void P_InitThinkers (void)
527 {
528         thinkercap.prev = thinkercap.next  = &thinkercap;
529 }
530
531
532 /*
533 ===============
534 =
535 = P_AddThinker
536 =
537 = Adds a new thinker at the end of the list
538 =
539 ===============
540 */
541
542 void P_AddThinker (thinker_t *thinker)
543 {
544         thinkercap.prev->next = thinker;
545         thinker->next = &thinkercap;
546         thinker->prev = thinkercap.prev;
547         thinkercap.prev = thinker;
548 }
549
550 /*
551 ===============
552 =
553 = P_RemoveThinker
554 =
555 = Deallocation is lazy -- it will not actually be freed until its
556 = thinking turn comes up
557 =
558 ===============
559 */
560
561 void P_RemoveThinker (thinker_t *thinker)
562 {
563         thinker->function = (think_t)-1;
564 }
565
566 /*
567 ===============
568 =
569 = P_AllocateThinker
570 =
571 = Allocates memory and adds a new thinker at the end of the list
572 =
573 ===============
574 */
575
576 void P_AllocateThinker (thinker_t *thinker)
577 {
578 }
579
580
581 /*
582 ===============
583 =
584 = P_RunThinkers
585 =
586 ===============
587 */
588
589 void P_RunThinkers (void)
590 {
591         thinker_t       *currentthinker;
592
593         currentthinker = thinkercap.next;
594         while (currentthinker != &thinkercap)
595         {
596                 if (currentthinker->function == (think_t)-1)
597                 {       // time to remove it
598                         currentthinker->next->prev = currentthinker->prev;
599                         currentthinker->prev->next = currentthinker->next;
600                         Z_Free (currentthinker);
601                 }
602                 else
603                 {
604                         if (currentthinker->function)
605                                 currentthinker->function (currentthinker);
606                 }
607                 currentthinker = currentthinker->next;
608         }
609 }
610
611 //----------------------------------------------------------------------------
612 //
613 // PROC P_Ticker
614 //
615 //----------------------------------------------------------------------------
616
617 void P_Ticker(void)
618 {
619         int i;
620
621         if(paused)
622         {
623                 return;
624         }
625         for(i = 0; i < MAXPLAYERS; i++)
626         {
627                 if(playeringame[i])
628                 {
629                         P_PlayerThink(&players[i]);
630                 }
631         }
632         if(TimerGame)
633         {
634                 if(!--TimerGame)
635                 {
636                         G_ExitLevel();
637                 }
638         }
639         P_RunThinkers();
640         P_UpdateSpecials();
641         P_AmbientSound();
642         leveltime++;
643 }