summaryrefslogtreecommitdiff
path: root/apps/plugins/sdl/progs/wolf3d/wl_act1.c
diff options
context:
space:
mode:
authorFranklin Wei <git@fwei.tk>2019-07-07 22:00:20 -0400
committerFranklin Wei <git@fwei.tk>2019-07-09 11:20:55 -0400
commit3f59fc8b771625aca9c3aefe03cf1038d8461963 (patch)
treee0623a323613baa0b0993411b38bcaed144b27ed /apps/plugins/sdl/progs/wolf3d/wl_act1.c
parent439a0d1d91fa040d261fc39b87278bc9f5391dcc (diff)
downloadrockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.tar.gz
rockbox-3f59fc8b771625aca9c3aefe03cf1038d8461963.zip
Wolfenstein 3-D!
This is a port of Wolf4SDL, which is derived from the original id software source release. The port runs on top of the SDL plugin runtime and is loaded as an overlay. Licensing of the game code is not an issue, as discussed below (essentially, the Debian project treats Wolf4SDL as GPLv2, with an email from John Carmack backing it up): http://forums.rockbox.org/index.php?topic=52872 Included is a copy of MAME's Yamaha OPL sound chip emulator (fmopl_gpl.c). This file was not part of the original Wolf4SDL source (which includes a non-GPL'd version), but was rather rebased from from a later MAME source which had been relicensed to GPLv2. Change-Id: I64c2ba035e0be7e2f49252f40640641416613439
Diffstat (limited to 'apps/plugins/sdl/progs/wolf3d/wl_act1.c')
-rw-r--r--apps/plugins/sdl/progs/wolf3d/wl_act1.c859
1 files changed, 859 insertions, 0 deletions
diff --git a/apps/plugins/sdl/progs/wolf3d/wl_act1.c b/apps/plugins/sdl/progs/wolf3d/wl_act1.c
new file mode 100644
index 0000000000..e9553c97c5
--- /dev/null
+++ b/apps/plugins/sdl/progs/wolf3d/wl_act1.c
@@ -0,0 +1,859 @@
1// WL_ACT1.C
2
3#include "wl_def.h"
4#pragma hdrstop
5
6/*
7=============================================================================
8
9 STATICS
10
11=============================================================================
12*/
13
14
15statobj_t statobjlist[MAXSTATS];
16statobj_t *laststatobj;
17
18
19struct
20{
21 short picnum;
22 wl_stat_t type;
23 uint32_t specialFlags; // they are ORed to the statobj_t flags
24} statinfo[] =
25{
26 {SPR_STAT_0}, // puddle spr1v
27 {SPR_STAT_1,block}, // Green Barrel "
28 {SPR_STAT_2,block}, // Table/chairs "
29 {SPR_STAT_3,block,FL_FULLBRIGHT}, // Floor lamp "
30 {SPR_STAT_4,none,FL_FULLBRIGHT}, // Chandelier "
31 {SPR_STAT_5,block}, // Hanged man "
32 {SPR_STAT_6,bo_alpo}, // Bad food "
33 {SPR_STAT_7,block}, // Red pillar "
34 //
35 // NEW PAGE
36 //
37 {SPR_STAT_8,block}, // Tree spr2v
38 {SPR_STAT_9}, // Skeleton flat "
39 {SPR_STAT_10,block}, // Sink " (SOD:gibs)
40 {SPR_STAT_11,block}, // Potted plant "
41 {SPR_STAT_12,block}, // Urn "
42 {SPR_STAT_13,block}, // Bare table "
43 {SPR_STAT_14,none,FL_FULLBRIGHT}, // Ceiling light "
44 #ifndef SPEAR
45 {SPR_STAT_15}, // Kitchen stuff "
46 #else
47 {SPR_STAT_15,block}, // Gibs!
48 #endif
49 //
50 // NEW PAGE
51 //
52 {SPR_STAT_16,block}, // suit of armor spr3v
53 {SPR_STAT_17,block}, // Hanging cage "
54 {SPR_STAT_18,block}, // SkeletoninCage "
55 {SPR_STAT_19}, // Skeleton relax "
56 {SPR_STAT_20,bo_key1}, // Key 1 "
57 {SPR_STAT_21,bo_key2}, // Key 2 "
58 {SPR_STAT_22,block}, // stuff (SOD:gibs)
59 {SPR_STAT_23}, // stuff
60 //
61 // NEW PAGE
62 //
63 {SPR_STAT_24,bo_food}, // Good food spr4v
64 {SPR_STAT_25,bo_firstaid}, // First aid "
65 {SPR_STAT_26,bo_clip}, // Clip "
66 {SPR_STAT_27,bo_machinegun}, // Machine gun "
67 {SPR_STAT_28,bo_chaingun}, // Gatling gun "
68 {SPR_STAT_29,bo_cross}, // Cross "
69 {SPR_STAT_30,bo_chalice}, // Chalice "
70 {SPR_STAT_31,bo_bible}, // Bible "
71 //
72 // NEW PAGE
73 //
74 {SPR_STAT_32,bo_crown}, // crown spr5v
75 {SPR_STAT_33,bo_fullheal,FL_FULLBRIGHT},// one up "
76 {SPR_STAT_34,bo_gibs}, // gibs "
77 {SPR_STAT_35,block}, // barrel "
78 {SPR_STAT_36,block}, // well "
79 {SPR_STAT_37,block}, // Empty well "
80 {SPR_STAT_38,bo_gibs}, // Gibs 2 "
81 {SPR_STAT_39,block}, // flag "
82 //
83 // NEW PAGE
84 //
85 #ifndef SPEAR
86 {SPR_STAT_40,block}, // Call Apogee spr7v
87 #else
88 {SPR_STAT_40}, // Red light
89 #endif
90 //
91 // NEW PAGE
92 //
93 {SPR_STAT_41}, // junk "
94 {SPR_STAT_42}, // junk "
95 {SPR_STAT_43}, // junk "
96 #ifndef SPEAR
97 {SPR_STAT_44}, // pots "
98 #else
99 {SPR_STAT_44,block}, // Gibs!
100 #endif
101 {SPR_STAT_45,block}, // stove " (SOD:gibs)
102 {SPR_STAT_46,block}, // spears " (SOD:gibs)
103 {SPR_STAT_47}, // vines "
104 //
105 // NEW PAGE
106 //
107 #ifdef SPEAR
108 {SPR_STAT_48,block}, // marble pillar
109 {SPR_STAT_49,bo_25clip}, // bonus 25 clip
110 {SPR_STAT_50,block}, // truck
111 {SPR_STAT_51,bo_spear}, // SPEAR OF DESTINY!
112 #endif
113
114 {SPR_STAT_26,bo_clip2}, // Clip "
115#ifdef USE_DIR3DSPR
116 // These are just two examples showing the new way of using dir 3d sprites.
117 // You can find the allowed values in the objflag_t enum in wl_def.h.
118 {SPR_STAT_47,none,FL_DIR_VERT_MID},
119 {SPR_STAT_47,block,FL_DIR_HORIZ_MID},
120#endif
121 {-1} // terminator
122};
123
124/*
125===============
126=
127= InitStaticList
128=
129===============
130*/
131
132void InitStaticList (void)
133{
134 laststatobj = &statobjlist[0];
135}
136
137
138
139/*
140===============
141=
142= SpawnStatic
143=
144===============
145*/
146
147void SpawnStatic (int tilex, int tiley, int type)
148{
149 laststatobj->shapenum = statinfo[type].picnum;
150 laststatobj->tilex = tilex;
151 laststatobj->tiley = tiley;
152 laststatobj->visspot = &spotvis[tilex][tiley];
153
154 switch (statinfo[type].type)
155 {
156 case block:
157 actorat[tilex][tiley] = (objtype *) 64; // consider it a blocking tile
158 case none:
159 laststatobj->flags = 0;
160 break;
161
162 case bo_cross:
163 case bo_chalice:
164 case bo_bible:
165 case bo_crown:
166 case bo_fullheal:
167 if (!loadedgame)
168 gamestate.treasuretotal++;
169
170 case bo_firstaid:
171 case bo_key1:
172 case bo_key2:
173 case bo_key3:
174 case bo_key4:
175 case bo_clip:
176 case bo_25clip:
177 case bo_machinegun:
178 case bo_chaingun:
179 case bo_food:
180 case bo_alpo:
181 case bo_gibs:
182 case bo_spear:
183 laststatobj->flags = FL_BONUS;
184 laststatobj->itemnumber = statinfo[type].type;
185 break;
186 }
187
188 laststatobj->flags |= statinfo[type].specialFlags;
189
190 laststatobj++;
191
192 if (laststatobj == &statobjlist[MAXSTATS])
193 Quit ("Too many static objects!\n");
194}
195
196
197/*
198===============
199=
200= PlaceItemType
201=
202= Called during game play to drop actors' items. It finds the proper
203= item number based on the item type (bo_???). If there are no free item
204= spots, nothing is done.
205=
206===============
207*/
208
209void PlaceItemType (int itemtype, int tilex, int tiley)
210{
211 int type;
212 statobj_t *spot;
213
214 //
215 // find the item number
216 //
217 for (type=0; ; type++)
218 {
219 if (statinfo[type].picnum == -1) // end of list
220 Quit ("PlaceItemType: couldn't find type!");
221 if (statinfo[type].type == itemtype)
222 break;
223 }
224
225 //
226 // find a spot in statobjlist to put it in
227 //
228 for (spot=&statobjlist[0]; ; spot++)
229 {
230 if (spot==laststatobj)
231 {
232 if (spot == &statobjlist[MAXSTATS])
233 return; // no free spots
234 laststatobj++; // space at end
235 break;
236 }
237
238 if (spot->shapenum == -1) // -1 is a free spot
239 break;
240 }
241 //
242 // place it
243 //
244 spot->shapenum = statinfo[type].picnum;
245 spot->tilex = tilex;
246 spot->tiley = tiley;
247 spot->visspot = &spotvis[tilex][tiley];
248 spot->flags = FL_BONUS | statinfo[type].specialFlags;
249 spot->itemnumber = statinfo[type].type;
250}
251
252
253
254/*
255=============================================================================
256
257 DOORS
258
259doorobjlist[] holds most of the information for the doors
260
261doorposition[] holds the amount the door is open, ranging from 0 to 0xffff
262 this is directly accessed by AsmRefresh during rendering
263
264The number of doors is limited to 64 because a spot in tilemap holds the
265 door number in the low 6 bits, with the high bit meaning a door center
266 and bit 6 meaning a door side tile
267
268Open doors conect two areas, so sounds will travel between them and sight
269 will be checked when the player is in a connected area.
270
271Areaconnect is incremented/decremented by each door. If >0 they connect
272
273Every time a door opens or closes the areabyplayer matrix gets recalculated.
274 An area is true if it connects with the player's current spor.
275
276=============================================================================
277*/
278
279#define DOORWIDTH 0x7800
280#define OPENTICS 300
281
282doorobj_t doorobjlist[MAXDOORS],*lastdoorobj;
283short doornum;
284
285word doorposition[MAXDOORS]; // leading edge of door 0=closed
286 // 0xffff = fully open
287
288byte areaconnect[NUMAREAS][NUMAREAS];
289
290boolean areabyplayer[NUMAREAS];
291
292
293/*
294==============
295=
296= ConnectAreas
297=
298= Scans outward from playerarea, marking all connected areas
299=
300==============
301*/
302
303void RecursiveConnect (int areanumber)
304{
305 int i;
306
307 for (i=0;i<NUMAREAS;i++)
308 {
309 if (areaconnect[areanumber][i] && !areabyplayer[i])
310 {
311 areabyplayer[i] = true;
312 RecursiveConnect (i);
313 }
314 }
315}
316
317
318void ConnectAreas (void)
319{
320 memset (areabyplayer,0,sizeof(areabyplayer));
321 areabyplayer[player->areanumber] = true;
322 RecursiveConnect (player->areanumber);
323}
324
325
326void InitAreas (void)
327{
328 memset (areabyplayer,0,sizeof(areabyplayer));
329 if (player->areanumber < NUMAREAS)
330 areabyplayer[player->areanumber] = true;
331}
332
333
334
335/*
336===============
337=
338= InitDoorList
339=
340===============
341*/
342
343void InitDoorList (void)
344{
345 memset (areabyplayer,0,sizeof(areabyplayer));
346 memset (areaconnect,0,sizeof(areaconnect));
347
348 lastdoorobj = &doorobjlist[0];
349 doornum = 0;
350}
351
352
353/*
354===============
355=
356= SpawnDoor
357=
358===============
359*/
360
361void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
362{
363 word *map;
364
365 if (doornum==MAXDOORS)
366 Quit ("64+ doors on level!");
367
368 doorposition[doornum] = 0; // doors start out fully closed
369 lastdoorobj->tilex = tilex;
370 lastdoorobj->tiley = tiley;
371 lastdoorobj->vertical = vertical;
372 lastdoorobj->lock = lock;
373 lastdoorobj->action = dr_closed;
374
375 actorat[tilex][tiley] = (objtype *)(uintptr_t)(doornum | 0x80); // consider it a solid wall
376
377 //
378 // make the door tile a special tile, and mark the adjacent tiles
379 // for door sides
380 //
381 tilemap[tilex][tiley] = doornum | 0x80;
382 map = mapsegs[0] + (tiley<<mapshift) +tilex;
383 if (vertical)
384 {
385 *map = *(map-1); // set area number
386 tilemap[tilex][tiley-1] |= 0x40;
387 tilemap[tilex][tiley+1] |= 0x40;
388 }
389 else
390 {
391 *map = *(map-mapwidth); // set area number
392 tilemap[tilex-1][tiley] |= 0x40;
393 tilemap[tilex+1][tiley] |= 0x40;
394 }
395
396 doornum++;
397 lastdoorobj++;
398}
399
400//===========================================================================
401
402/*
403=====================
404=
405= OpenDoor
406=
407=====================
408*/
409
410void OpenDoor (int door)
411{
412 if (doorobjlist[door].action == dr_open)
413 doorobjlist[door].ticcount = 0; // reset open time
414 else
415 doorobjlist[door].action = dr_opening; // start it opening
416}
417
418
419/*
420=====================
421=
422= CloseDoor
423=
424=====================
425*/
426
427void CloseDoor (int door)
428{
429 int tilex,tiley,area;
430 objtype *check;
431
432 //
433 // don't close on anything solid
434 //
435 tilex = doorobjlist[door].tilex;
436 tiley = doorobjlist[door].tiley;
437
438 if (actorat[tilex][tiley])
439 return;
440
441 if (player->tilex == tilex && player->tiley == tiley)
442 return;
443
444 if (doorobjlist[door].vertical)
445 {
446 if ( player->tiley == tiley )
447 {
448 if ( ((player->x+MINDIST) >>TILESHIFT) == tilex )
449 return;
450 if ( ((player->x-MINDIST) >>TILESHIFT) == tilex )
451 return;
452 }
453 check = actorat[tilex-1][tiley];
454 if (ISPOINTER(check) && ((check->x+MINDIST) >> TILESHIFT) == tilex )
455 return;
456 check = actorat[tilex+1][tiley];
457 if (ISPOINTER(check) && ((check->x-MINDIST) >> TILESHIFT) == tilex )
458 return;
459 }
460 else if (!doorobjlist[door].vertical)
461 {
462 if (player->tilex == tilex)
463 {
464 if ( ((player->y+MINDIST) >>TILESHIFT) == tiley )
465 return;
466 if ( ((player->y-MINDIST) >>TILESHIFT) == tiley )
467 return;
468 }
469 check = actorat[tilex][tiley-1];
470 if (ISPOINTER(check) && ((check->y+MINDIST) >> TILESHIFT) == tiley )
471 return;
472 check = actorat[tilex][tiley+1];
473 if (ISPOINTER(check) && ((check->y-MINDIST) >> TILESHIFT) == tiley )
474 return;
475 }
476
477
478 //
479 // play door sound if in a connected area
480 //
481 area = *(mapsegs[0] + (doorobjlist[door].tiley<<mapshift)
482 +doorobjlist[door].tilex)-AREATILE;
483 if (areabyplayer[area])
484 {
485 PlaySoundLocTile(CLOSEDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley); // JAB
486 }
487
488 doorobjlist[door].action = dr_closing;
489 //
490 // make the door space solid
491 //
492 actorat[tilex][tiley] = (objtype *)(uintptr_t)(door | 0x80);
493}
494
495
496
497/*
498=====================
499=
500= OperateDoor
501=
502= The player wants to change the door's direction
503=
504=====================
505*/
506
507void OperateDoor (int door)
508{
509 int lock;
510
511 lock = doorobjlist[door].lock;
512 if (lock >= dr_lock1 && lock <= dr_lock4)
513 {
514 if ( ! (gamestate.keys & (1 << (lock-dr_lock1) ) ) )
515 {
516 SD_PlaySound (NOWAYSND); // locked
517 return;
518 }
519 }
520
521 switch (doorobjlist[door].action)
522 {
523 case dr_closed:
524 case dr_closing:
525 OpenDoor (door);
526 break;
527 case dr_open:
528 case dr_opening:
529 CloseDoor (door);
530 break;
531 }
532}
533
534
535//===========================================================================
536
537/*
538===============
539=
540= DoorOpen
541=
542= Close the door after three seconds
543=
544===============
545*/
546
547void DoorOpen (int door)
548{
549 if ( (doorobjlist[door].ticcount += (short) tics) >= OPENTICS)
550 CloseDoor (door);
551}
552
553
554
555/*
556===============
557=
558= DoorOpening
559=
560===============
561*/
562
563void DoorOpening (int door)
564{
565 unsigned area1,area2;
566 word *map;
567 int32_t position;
568
569 position = doorposition[door];
570 if (!position)
571 {
572 //
573 // door is just starting to open, so connect the areas
574 //
575 map = mapsegs[0] + (doorobjlist[door].tiley<<mapshift)
576 +doorobjlist[door].tilex;
577
578 if (doorobjlist[door].vertical)
579 {
580 area1 = *(map+1);
581 area2 = *(map-1);
582 }
583 else
584 {
585 area1 = *(map-mapwidth);
586 area2 = *(map+mapwidth);
587 }
588 area1 -= AREATILE;
589 area2 -= AREATILE;
590
591 if (area1 < NUMAREAS && area2 < NUMAREAS)
592 {
593 areaconnect[area1][area2]++;
594 areaconnect[area2][area1]++;
595
596 if (player->areanumber < NUMAREAS)
597 ConnectAreas ();
598
599 if (areabyplayer[area1])
600 PlaySoundLocTile(OPENDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley); // JAB
601 }
602 }
603
604 //
605 // slide the door by an adaptive amount
606 //
607 position += tics<<10;
608 if (position >= 0xffff)
609 {
610 //
611 // door is all the way open
612 //
613 position = 0xffff;
614 doorobjlist[door].ticcount = 0;
615 doorobjlist[door].action = dr_open;
616 actorat[doorobjlist[door].tilex][doorobjlist[door].tiley] = 0;
617 }
618
619 doorposition[door] = (word) position;
620}
621
622
623/*
624===============
625=
626= DoorClosing
627=
628===============
629*/
630
631void DoorClosing (int door)
632{
633 unsigned area1,area2;
634 word *map;
635 int32_t position;
636 int tilex,tiley;
637
638 tilex = doorobjlist[door].tilex;
639 tiley = doorobjlist[door].tiley;
640
641 if ( ((int)(uintptr_t)actorat[tilex][tiley] != (door | 0x80))
642 || (player->tilex == tilex && player->tiley == tiley) )
643 { // something got inside the door
644 OpenDoor (door);
645 return;
646 };
647
648 position = doorposition[door];
649
650 //
651 // slide the door by an adaptive amount
652 //
653 position -= tics<<10;
654 if (position <= 0)
655 {
656 //
657 // door is closed all the way, so disconnect the areas
658 //
659 position = 0;
660
661 doorobjlist[door].action = dr_closed;
662
663 map = mapsegs[0] + (doorobjlist[door].tiley<<mapshift) + doorobjlist[door].tilex;
664
665 if (doorobjlist[door].vertical)
666 {
667 area1 = *(map+1);
668 area2 = *(map-1);
669 }
670 else
671 {
672 area1 = *(map-mapwidth);
673 area2 = *(map+mapwidth);
674 }
675 area1 -= AREATILE;
676 area2 -= AREATILE;
677
678 if (area1 < NUMAREAS && area2 < NUMAREAS)
679 {
680 areaconnect[area1][area2]--;
681 areaconnect[area2][area1]--;
682
683 if (player->areanumber < NUMAREAS)
684 ConnectAreas ();
685 }
686 }
687
688 doorposition[door] = (word) position;
689}
690
691
692
693
694/*
695=====================
696=
697= MoveDoors
698=
699= Called from PlayLoop
700=
701=====================
702*/
703
704void MoveDoors (void)
705{
706 int door;
707
708 if (gamestate.victoryflag) // don't move door during victory sequence
709 return;
710
711 for (door = 0; door < doornum; door++)
712 {
713 switch (doorobjlist[door].action)
714 {
715 case dr_open:
716 DoorOpen (door);
717 break;
718
719 case dr_opening:
720 DoorOpening(door);
721 break;
722
723 case dr_closing:
724 DoorClosing(door);
725 break;
726 }
727 }
728}
729
730
731/*
732=============================================================================
733
734 PUSHABLE WALLS
735
736=============================================================================
737*/
738
739word pwallstate;
740word pwallpos; // amount a pushable wall has been moved (0-63)
741word pwallx,pwally;
742byte pwalldir,pwalltile;
743int dirs[4][2]={{0,-1},{1,0},{0,1},{-1,0}};
744
745/*
746===============
747=
748= PushWall
749=
750===============
751*/
752
753void PushWall (int checkx, int checky, int dir)
754{
755 int oldtile, dx, dy;
756
757 if (pwallstate)
758 return;
759
760 oldtile = tilemap[checkx][checky];
761 if (!oldtile)
762 return;
763
764 dx = dirs[dir][0];
765 dy = dirs[dir][1];
766
767 if (actorat[checkx+dx][checky+dy])
768 {
769 SD_PlaySound (NOWAYSND);
770 return;
771 }
772 actorat[checkx+dx][checky+dy] = (objtype *)(uintptr_t) (tilemap[checkx+dx][checky+dy] = oldtile);
773
774 gamestate.secretcount++;
775 pwallx = checkx;
776 pwally = checky;
777 pwalldir = dir;
778 pwallstate = 1;
779 pwallpos = 0;
780 pwalltile = tilemap[pwallx][pwally];
781 tilemap[pwallx][pwally] = 64;
782 tilemap[pwallx+dx][pwally+dy] = 64;
783 *(mapsegs[1]+(pwally<<mapshift)+pwallx) = 0; // remove P tile info
784 *(mapsegs[0]+(pwally<<mapshift)+pwallx) = *(mapsegs[0]+(player->tiley<<mapshift)+player->tilex); // set correct floorcode (BrotherTank's fix)
785
786 SD_PlaySound (PUSHWALLSND);
787}
788
789
790
791/*
792=================
793=
794= MovePWalls
795=
796=================
797*/
798
799void MovePWalls (void)
800{
801 int oldblock,oldtile;
802
803 if (!pwallstate)
804 return;
805
806 oldblock = pwallstate/128;
807
808 pwallstate += (word)tics;
809
810 if (pwallstate/128 != oldblock)
811 {
812 // block crossed into a new block
813 oldtile = pwalltile;
814
815 //
816 // the tile can now be walked into
817 //
818 tilemap[pwallx][pwally] = 0;
819 actorat[pwallx][pwally] = 0;
820 *(mapsegs[0]+(pwally<<mapshift)+pwallx) = player->areanumber+AREATILE;
821
822 int dx=dirs[pwalldir][0], dy=dirs[pwalldir][1];
823 //
824 // see if it should be pushed farther
825 //
826 if (pwallstate>=256) // only move two tiles fix
827 {
828 //
829 // the block has been pushed two tiles
830 //
831 pwallstate = 0;
832 tilemap[pwallx+dx][pwally+dy] = oldtile;
833 return;
834 }
835 else
836 {
837 int xl,yl,xh,yh;
838 xl = (player->x-PLAYERSIZE) >> TILESHIFT;
839 yl = (player->y-PLAYERSIZE) >> TILESHIFT;
840 xh = (player->x+PLAYERSIZE) >> TILESHIFT;
841 yh = (player->y+PLAYERSIZE) >> TILESHIFT;
842
843 pwallx += dx;
844 pwally += dy;
845
846 if (actorat[pwallx+dx][pwally+dy]
847 || xl<=pwallx+dx && pwallx+dx<=xh && yl<=pwally+dy && pwally+dy<=yh)
848 {
849 pwallstate = 0;
850 tilemap[pwallx][pwally] = oldtile;
851 return;
852 }
853 actorat[pwallx+dx][pwally+dy] = (objtype *)(uintptr_t) (tilemap[pwallx+dx][pwally+dy] = oldtile);
854 tilemap[pwallx+dx][pwally+dy] = 64;
855 }
856 }
857
858 pwallpos = (pwallstate/2)&63;
859}