OSDN Git Service

got 8086 port of wolf3d to work and sod to work
[proj16/16.git] / 16 / WOLFSRC / WL_DR_A.ASM
1         IDEAL\r
2         MODEL   MEDIUM,C\r
3         P286\r
4 \r
5 SCREENSEG       =       0a000h\r
6 \r
7 FINEANGLES      =       3600\r
8 DEG90           =       900\r
9 DEG180          =       1800\r
10 DEG270          =       2700\r
11 DEG360          =       3600\r
12 \r
13 OP_JLE          =       07eh\r
14 OP_JGE          =       07dh\r
15 \r
16 EXTRN   finetangent:DWORD       ; far array, starts at offset 0\r
17 \r
18 EXTRN   HitHorizWall:FAR\r
19 EXTRN   HitVertWall:FAR\r
20 EXTRN   HitHorizDoor:FAR\r
21 EXTRN   HitVertDoor:FAR\r
22 EXTRN   HitHorizPWall:FAR\r
23 EXTRN   HitVertPWall:FAR\r
24 \r
25 \r
26 DATASEG\r
27 \r
28 EXTRN   viewwidth:WORD\r
29 \r
30 EXTRN   tilemap:BYTE\r
31 EXTRN   spotvis:BYTE\r
32 EXTRN   pixelangle:WORD\r
33 \r
34 \r
35 EXTRN   midangle:WORD\r
36 EXTRN   angle:WORD\r
37 \r
38 EXTRN   focaltx:WORD\r
39 EXTRN   focalty:WORD\r
40 EXTRN   viewtx:WORD\r
41 EXTRN   viewty:WORD\r
42 EXTRN   viewx:DWORD\r
43 EXTRN   viewy:DWORD\r
44 \r
45 EXTRN   xpartialup:WORD\r
46 EXTRN   ypartialup:WORD\r
47 EXTRN   xpartialdown:WORD\r
48 EXTRN   ypartialdown:WORD\r
49 \r
50 EXTRN   tilehit:WORD\r
51 EXTRN   pixx:WORD\r
52 EXTRN   wallheight:WORD                 ; array of VIEWWIDTH entries\r
53 \r
54 EXTRN   xtile:WORD\r
55 EXTRN   ytile:WORD\r
56 EXTRN   xtilestep:WORD\r
57 EXTRN   ytilestep:WORD\r
58 EXTRN   xintercept:DWORD\r
59 EXTRN   yintercept:DWORD\r
60 EXTRN   xstep:DWORD\r
61 EXTRN   ystep:DWORD\r
62 \r
63 EXTRN   doorposition:WORD               ; table of door position values\r
64 \r
65 \r
66 EXTRN   pwallpos:WORD                   ; amound a pushable wall has been moved\r
67 \r
68 CODESEG\r
69 \r
70 ;-------------------\r
71 ;\r
72 ; xpartialbyystep\r
73 ;\r
74 ; multiplies long [ystep] (possibly negative), by word [xpartial] (in BX)\r
75 ;\r
76 ; returns dx:ax\r
77 ; trashes bx,cx,di\r
78 ;\r
79 ;-------------------\r
80 \r
81 PROC xpartialbyystep NEAR\r
82 ;\r
83 ; setup\r
84 ;\r
85         mov     ax,[WORD ystep]\r
86         mov     cx,[WORD ystep+2]\r
87         or      cx,cx               ; is ystep negatice?\r
88         jns     @@multpos\r
89 ;\r
90 ; multiply negative cx:ax by bx\r
91 ;\r
92         neg     cx\r
93         neg     ax\r
94         sbb     cx,0\r
95 \r
96         mul     bx                                      ; fraction*fraction\r
97         mov     di,dx                           ; di is low word of result\r
98         mov     ax,cx                           ;\r
99         mul     bx                                      ; units*fraction\r
100         add     ax,di\r
101         adc     dx,0\r
102 \r
103         neg     dx\r
104         neg     ax\r
105         sbb     dx,0\r
106         ret\r
107 ;\r
108 ; multiply positive cx:ax by bx\r
109 ;\r
110 EVEN\r
111 @@multpos:\r
112         mul     bx                                      ; fraction*fraction\r
113         mov     di,dx                           ; di is low word of result\r
114         mov     ax,cx                           ;\r
115         mul     bx                                      ; units*fraction\r
116         add     ax,di\r
117         adc     dx,0\r
118 \r
119         ret\r
120 \r
121 ENDP\r
122 \r
123 \r
124 \r
125 ;-------------------\r
126 ;\r
127 ; ypartialbyxstep\r
128 ;\r
129 ; multiplies long [xstep] (possibly negative), by word [ypartial] (in BP)\r
130 ;\r
131 ; returns dx:ax\r
132 ; trashes cx,di,bp\r
133 ;\r
134 ;-------------------\r
135 \r
136 PROC ypartialbyxstep NEAR\r
137 ;\r
138 ; setup\r
139 ;\r
140         mov     ax,[WORD xstep]\r
141         mov     cx,[WORD xstep+2]\r
142         or      cx,cx               ; is ystep negatice?\r
143         jns     @@multpos\r
144 ;\r
145 ; multiply negative cx:ax by bx\r
146 ;\r
147         neg     cx\r
148         neg     ax\r
149         sbb     cx,0\r
150 \r
151         mul     bp                                      ; fraction*fraction\r
152         mov     di,dx                           ; di is low word of result\r
153         mov     ax,cx                           ;\r
154         mul     bp                                      ; units*fraction\r
155         add     ax,di\r
156         adc     dx,0\r
157 \r
158         neg     dx\r
159         neg     ax\r
160         sbb     dx,0\r
161         ret\r
162 ;\r
163 ; multiply positive cx:ax by bx\r
164 ;\r
165 EVEN\r
166 @@multpos:\r
167         mul     bp                                      ; fraction*fraction\r
168         mov     di,dx                           ; di is low word of result\r
169         mov     ax,cx                           ;\r
170         mul     bp                                      ; units*fraction\r
171         add     ax,di\r
172         adc     dx,0\r
173         ret\r
174 \r
175 ENDP\r
176 \r
177 \r
178 ;============================\r
179 ;\r
180 ; AsmRefresh\r
181 ;\r
182 ;\r
183 ;============================\r
184 \r
185 PROC    AsmRefresh\r
186 PUBLIC  AsmRefresh\r
187 \r
188         push    si\r
189         push    di\r
190         push    bp\r
191 \r
192         mov     [pixx],0\r
193 ;---------------------------------------------------------------------------\r
194 ;\r
195 ; Setup to trace a ray through pixx view pixel\r
196 ;\r
197 ; CX : angle of the ray through pixx\r
198 ; ES : points to segment of finetangent array for this block of code\r
199 ;\r
200 ; Upon entrance to initialize block\r
201 ;\r
202 ; BX : xpartial\r
203 ; BP : ypartial\r
204 ;\r
205 ;---------------------------------------------------------------------------\r
206         EVEN\r
207 pixxloop:\r
208         mov     ax,SEG finetangent\r
209         mov     es,ax\r
210         mov     cx,[midangle]                   ; center of view area\r
211         mov     bx,[pixx]\r
212         shl     bx,1\r
213         add     cx,[pixelangle+bx]              ; delta for this pixel\r
214         cmp     cx,0\r
215         jge     not0\r
216 ;----------\r
217 ;\r
218 ; -90 - -1 degree arc\r
219 ;\r
220 ;----------\r
221         add     cx,FINEANGLES                   ; -90 is the same as 270\r
222         jmp     entry360\r
223 \r
224 not0:\r
225         cmp     cx,DEG90\r
226         jge     not90\r
227 ;----------\r
228 ;\r
229 ; 0-89 degree arc\r
230 ;\r
231 ;----------\r
232 entry90:\r
233         mov     [xtilestep],1                   ; xtilestep = 1\r
234         mov     [ytilestep],-1                  ; ytilestep = -1\r
235         mov     [BYTE cs:horizop],OP_JGE        ; patch a jge in\r
236         mov     [BYTE cs:vertop],OP_JLE         ; patch a jle in\r
237         mov     bx,DEG90-1\r
238         sub     bx,cx\r
239         ;begin 8086 hack\r
240         ;shl    bx,2\r
241         shl bx,1\r
242         shl bx,1\r
243         ;end 8086 hack\r
244         mov     ax,[es:bx]\r
245         mov     dx,[es:bx+2]\r
246         mov     [WORD xstep],ax\r
247         mov     [WORD xstep+2],dx               ; xstep = finetangent[DEG90-1-angle]\r
248         mov     bx,cx\r
249         ;begin 8086 hack\r
250         ;shl    bx,2\r
251         shl bx,1\r
252         shl bx,1\r
253         ;end 8086 hack\r
254         mov     ax,[es:bx]\r
255         mov     dx,[es:bx+2]\r
256         neg     dx\r
257         neg     ax\r
258         sbb     dx,0\r
259         mov     [WORD ystep],ax\r
260         mov     [WORD ystep+2],dx               ; ystep = -finetangent[angle]\r
261 \r
262         mov     bx,[xpartialup]                 ; xpartial = xpartialup\r
263         mov     bp,[ypartialdown]               ; ypartial = ypartialdown\r
264         jmp     initvars\r
265 \r
266 not90:\r
267         cmp     cx,DEG180\r
268         jge     not180\r
269 ;----------\r
270 ;\r
271 ; 90-179 degree arc\r
272 ;\r
273 ;----------\r
274         mov     ax,-1\r
275         mov     [xtilestep],ax                  ; xtilestep = -1\r
276         mov     [ytilestep],ax                  ; ytilestep = -1\r
277         mov     [BYTE cs:horizop],OP_JLE        ; patch a jle in\r
278         mov     [BYTE cs:vertop],OP_JLE         ; patch a jle in\r
279 \r
280         mov     bx,cx\r
281         ;begin 8086 hack\r
282         ;shl    bx,2\r
283         shl bx,1\r
284         shl bx,1\r
285         ;end 8086 hack\r
286         mov     ax,[es:bx-DEG90*4]\r
287         mov     dx,[es:bx+2-DEG90*4]\r
288         neg     dx\r
289         neg     ax\r
290         sbb     dx,0\r
291         mov     [WORD xstep],ax\r
292         mov     [WORD xstep+2],dx               ; xstep = -finetangent[angle-DEG90]\r
293         mov     bx,DEG180-1\r
294         sub     bx,cx\r
295         ;begin 8086 hack\r
296         ;shl    bx,2\r
297         shl bx,1\r
298         shl bx,1\r
299         ;end 8086 hack\r
300         mov     ax,[es:bx]\r
301         mov     dx,[es:bx+2]\r
302         neg     dx\r
303         neg     ax\r
304         sbb     dx,0\r
305         mov     [WORD ystep],ax\r
306         mov     [WORD ystep+2],dx               ; ystep = -finetangent[DEG180-1-angle]\r
307 \r
308         mov     bx,[xpartialdown]               ; xpartial = xpartialdown\r
309         mov     bp,[ypartialdown]               ; ypartial = ypartialdown\r
310         jmp     initvars\r
311 \r
312 not180:\r
313         cmp     cx,DEG270\r
314         jge     not270\r
315 ;----------\r
316 ;\r
317 ; 180-269 degree arc\r
318 ;\r
319 ;----------\r
320         mov     [xtilestep],-1                  ; xtilestep = -1\r
321         mov     [ytilestep],1                   ; ytilestep = 1\r
322         mov     [BYTE cs:horizop],OP_JLE        ; patch a jle in\r
323         mov     [BYTE cs:vertop],OP_JGE         ; patch a jge in\r
324 \r
325         mov     bx,DEG270-1\r
326         sub     bx,cx\r
327         ;begin 8086 hack\r
328         ;shl    bx,2\r
329         shl bx,1\r
330         shl bx,1\r
331         ;end 8086 hack\r
332         mov     ax,[es:bx]\r
333         mov     dx,[es:bx+2]\r
334         neg     dx\r
335         neg     ax\r
336         sbb     dx,0\r
337         mov     [WORD xstep],ax\r
338         mov     [WORD xstep+2],dx               ; xstep = -finetangent[DEG270-1-angle]\r
339         mov     bx,cx\r
340         ;begin 8086 hack\r
341         ;shl    bx,2\r
342         shl bx,1\r
343         shl bx,1\r
344         ;end 8086 hack\r
345         mov     ax,[es:bx-DEG180*4]\r
346         mov     dx,[es:bx+2-DEG180*4]\r
347         mov     [WORD ystep],ax\r
348         mov     [WORD ystep+2],dx               ; ystep = finetangent[angle-DEG180]\r
349 \r
350         mov     bx,[xpartialdown]               ; xpartial = xpartialdown\r
351         mov     bp,[ypartialup]                 ; ypartial = ypartialup\r
352         jmp     initvars\r
353 \r
354 \r
355 not270:\r
356         cmp     cx,DEG360\r
357         jge     not360\r
358 ;----------\r
359 ;\r
360 ; 270-359 degree arc\r
361 ;\r
362 ;----------\r
363 entry360:\r
364         mov     ax,1\r
365         mov     [xtilestep],ax                  ; xtilestep = 1\r
366         mov     [ytilestep],ax                  ; ytilestep = 1\r
367         mov     [BYTE cs:horizop],OP_JGE        ; patch a jge in\r
368         mov     [BYTE cs:vertop],OP_JGE         ; patch a jge in\r
369 \r
370         mov     bx,cx\r
371         ;begin 8086 hack\r
372         ;shl    bx,2\r
373         shl bx,1\r
374         shl bx,1\r
375         ;end 8086 hack\r
376         mov     ax,[es:bx-DEG270*4]\r
377         mov     dx,[es:bx+2-DEG270*4]\r
378         mov     [WORD xstep],ax\r
379         mov     [WORD xstep+2],dx               ; xstep = finetangent[angle-DEG270]\r
380         mov     bx,DEG360-1\r
381         sub     bx,cx\r
382         ;begin 8086 hack\r
383         ;shl    bx,2\r
384         shl bx,1\r
385         shl bx,1\r
386         ;end 8086 hack\r
387         mov     ax,[es:bx]\r
388         mov     dx,[es:bx+2]\r
389         mov     [WORD ystep],ax\r
390         mov     [WORD ystep+2],dx               ; ystep = finetangent[DEG360-1-angle]\r
391 \r
392         mov     bx,[xpartialup]                 ; xpartial = xpartialup\r
393         mov     bp,[ypartialup]                 ; ypartial = ypartialup\r
394         jmp     initvars\r
395 \r
396 \r
397 not360:\r
398 ;----------\r
399 ;\r
400 ; 360-449 degree arc\r
401 ;\r
402 ;----------\r
403         sub     cx,FINEANGLES                   ; -449 is the same as 89\r
404         jmp     entry90\r
405 \r
406 ;---------------------------------------------------------------------------\r
407 ;\r
408 ; initialise variables for intersection testing\r
409 ;\r
410 ;---------------------------------------------------------------------------\r
411 initvars:\r
412         call    NEAR xpartialbyystep    ; xpartial is in BX\r
413         add     ax,[WORD viewy]\r
414         adc     dx,[WORD viewy+2]\r
415         mov     [WORD yintercept],ax\r
416         mov     [WORD yintercept+2],dx\r
417 \r
418         mov     si,[focaltx]\r
419         add     si,[xtilestep]\r
420         mov     [xtile],si                                      ; xtile = focaltx+xtilestep\r
421         ;begin 8086 hack\r
422         ;shl    si,6\r
423         push cx\r
424         mov cl,6\r
425         shl si,cl\r
426         pop cx\r
427         ;end 8086 hack\r
428         add     si,dx                                           ; xspot = (xtile<<6) + yinttile\r
429 \r
430 \r
431         call    NEAR ypartialbyxstep    ; ypartial is in BP\r
432         add     ax,[WORD viewx]\r
433         adc     dx,[WORD viewx+2]\r
434         mov     [WORD xintercept],ax\r
435         mov     cx,dx\r
436 \r
437         mov     bx,[focalty]\r
438         add     bx,[ytilestep]\r
439         mov     bp,bx                                           ; ytile = focalty+ytilestep\r
440         mov     di,dx\r
441         ;begin 8086 hack\r
442         ;shl    di,6\r
443         push cx\r
444         mov cl,6\r
445         shl di,cl\r
446         pop cx\r
447         ;end 8086 hack\r
448         add     di,bx                                           ; yspot = (xinttile<<6) + ytile\r
449 \r
450         mov     bx,[xtile]\r
451         mov     dx,[WORD yintercept+2]\r
452         mov     ax,SCREENSEG\r
453         mov     es,ax                                           ; faster than mov es,[screenseg]\r
454 \r
455 \r
456 ;---------------------------------------------------------------------------\r
457 ;\r
458 ; trace along this angle until we hit a wall\r
459 ;\r
460 ; CORE LOOP!\r
461 ;\r
462 ; All variables are killed when a wall is hit\r
463 ;\r
464 ; AX : scratch\r
465 ; BX : xtile\r
466 ; CX : high word of xintercept\r
467 ; DX : high word of yintercept\r
468 ; SI : xspot (yinttile<<6)+xtile (index into tilemap and spotvis)\r
469 ; DI : yspot (xinttile<<6)+ytile (index into tilemap and spotvis)\r
470 ; BP : ytile\r
471 ; ES : screenseg\r
472 ;\r
473 ;---------------------------------------------------------------------------\r
474 \r
475 ;-----------\r
476 ;\r
477 ; check intersections with vertical walls\r
478 ;\r
479 ;-----------\r
480 \r
481         EVEN\r
482 vertcheck:\r
483         cmp     dx,bp\r
484 vertop:                                                         ; 0x7e = jle (ytilestep==-1)\r
485         jle     horizentry                                      ; 0x7d = jge (ytilestep==1)\r
486 vertentry:\r
487         test [BYTE tilemap+si],0ffh             ; tilehit = *((byte *)tilemap+xspot);\r
488         jnz     hitvert\r
489 passvert:\r
490         mov     [BYTE spotvis+si],1                     ; *((byte *)spotvis+xspot) = true;\r
491         add     bx,[xtilestep]                          ; xtile+=xtilestep\r
492         mov     ax,[WORD ystep]\r
493         add     [WORD yintercept],ax            ; yintercept += ystep\r
494         adc     dx,[WORD ystep+2]\r
495         mov     si,bx\r
496         ;begin 8086 hack\r
497         ;shl    si,6\r
498         push cx\r
499         mov cl,6\r
500         shl si,cl\r
501         pop cx\r
502         ;end 8086 hack\r
503         add     si,dx                                           ; xspot = (xtile<<6)+yinttile\r
504         jmp     vertcheck\r
505 \r
506         EVEN\r
507 hitvert:\r
508         mov     al,[BYTE tilemap+si]            ; tilehit = *((byte *)tilemap+xspot);\r
509         mov     [BYTE tilehit],al\r
510         or      al,al                                           ; set flags\r
511         jns     notvertdoor\r
512         jmp     vertdoor\r
513 notvertdoor:\r
514         mov     [WORD xintercept],0\r
515         mov     [WORD xintercept+2],bx\r
516         mov     [xtile],bx\r
517         mov     [WORD yintercept+2],dx\r
518         mov     [ytile],dx\r
519         call FAR HitVertWall\r
520         jmp nextpix\r
521 \r
522 \r
523 ;-----------\r
524 ;\r
525 ; check intersections with horizontal walls\r
526 ;\r
527 ;-----------\r
528         EVEN\r
529 horizcheck:\r
530         cmp     cx,bx\r
531 horizop:                                                        ; 0x7e = jle (xtilestep==-1)\r
532         jle     vertentry                                       ; 0x7d = jge (xtilestep==1)\r
533 horizentry:\r
534         test [BYTE tilemap+di],0ffh             ; tilehit = *((byte *)tilemap+yspot);\r
535         jnz     hithoriz\r
536 passhoriz:\r
537         mov     [BYTE spotvis+di],1                     ; *((byte *)spotvis+yspot) = true;\r
538         add     bp,[ytilestep]                          ; ytile+=ytilestep\r
539         mov     ax,[WORD xstep]\r
540         add     [WORD xintercept],ax            ; xintercept += xstep\r
541         adc     cx,[WORD xstep+2]\r
542         mov     di,cx\r
543         ;begin 8086 hack\r
544         ;shl    di,6\r
545         push cx\r
546         mov cl,6\r
547         shl di,cl\r
548         pop cx\r
549         ;end 8086 hack\r
550         add     di,bp                                           ; yspot = (xinttile<<6)+ytile\r
551         jmp     horizcheck\r
552 \r
553         EVEN\r
554 hithoriz:\r
555         mov     al,[BYTE tilemap+di]            ; tilehit = *((byte *)tilemap+yspot);\r
556         mov     [BYTE tilehit],al\r
557         or      al,al                                           ; set flags\r
558         js      horizdoor\r
559         mov     [WORD xintercept+2],cx\r
560         mov     [xtile],cx\r
561         mov     [WORD yintercept],0\r
562         mov     [WORD yintercept+2],bp\r
563         mov     [ytile],bp\r
564         call FAR HitHorizWall\r
565         jmp nextpix\r
566 \r
567 ;---------------------------------------------------------------------------\r
568 ;\r
569 ; next pixel over\r
570 ;\r
571 ;---------------------------------------------------------------------------\r
572 \r
573 nextpix:\r
574         mov     ax,[pixx]\r
575         inc     ax\r
576         mov     [pixx],ax\r
577         cmp     ax,[viewwidth]\r
578         jge     done\r
579         jmp     pixxloop\r
580 done:\r
581         pop     bp\r
582         pop     di\r
583         pop     si\r
584         retf\r
585 \r
586 ;===========================================================================\r
587 \r
588 ;=============\r
589 ;\r
590 ; hit a special horizontal wall, so find which coordinate a door would be\r
591 ; intersected at, and check to see if the door is open past that point\r
592 ;\r
593 ;=============\r
594 horizdoor:\r
595         mov     [xtile],bx                                      ; save off live register variables\r
596         mov     [WORD yintercept+2],dx\r
597 \r
598         test al,040h                                    ; both high bits set == pushable wall\r
599         jnz     horizpushwall\r
600 \r
601         mov     bx,ax\r
602         and     bx,7fh                                          ; strip high bit\r
603         shl     bx,1                        ; index into word width door table\r
604 \r
605         mov     ax,[WORD xstep]\r
606         mov     dx,[WORD xstep+2]\r
607         sar     dx,1\r
608         rcr ax,1                                                ; half a step gets to door position\r
609 \r
610         add     ax,[WORD xintercept]            ; add half step to current intercept pos\r
611         adc     dx,cx                                           ; CX hold high word of xintercept\r
612 \r
613         cmp     cx,dx                                           ; is it still in the same tile?\r
614         je      hithmid\r
615 ;\r
616 ; midpoint is outside tile, so it hit the side of the wall before a door\r
617 ;\r
618 continuehoriz:\r
619         mov     bx,[xtile]                                      ; reload register variables\r
620         mov     dx,[WORD yintercept+2]\r
621         jmp     passhoriz                                       ; continue tracing\r
622 ;\r
623 ; the trace hit the door plane at pixel position AX, see if the door is\r
624 ; closed that much\r
625 ;\r
626 hithmid:\r
627         cmp     ax,[doorposition+bx]            ; position of leading edge of door\r
628         jb      continuehoriz\r
629 ;\r
630 ; draw the door\r
631 ;\r
632         mov     [WORD xintercept],ax            ; save pixel intercept position\r
633         mov     [WORD xintercept+2],cx\r
634 \r
635         mov     [WORD yintercept],8000h         ; intercept in middle of tile\r
636         mov     [WORD yintercept+2],bp\r
637 \r
638         call    FAR HitHorizDoor\r
639         jmp     nextpix\r
640 \r
641 ;============\r
642 ;\r
643 ; hit a sliding horizontal wall\r
644 ;\r
645 ;============\r
646 \r
647 horizpushwall:\r
648         mov     ax,[WORD xstep+2]                       ; multiply xstep by pwallmove (0-63)\r
649         mul     [pwallpos]\r
650         mov     bx,ax\r
651         mov     ax,[WORD xstep]\r
652         mul     [pwallpos]\r
653         add     dx,bx\r
654 \r
655         sar     dx,1                                            ; then divide by 64 to accomplish a\r
656         rcr ax,1                                                ; fixed point multiplication\r
657         sar     dx,1\r
658         rcr ax,1\r
659         sar     dx,1\r
660         rcr ax,1\r
661         sar     dx,1\r
662         rcr ax,1\r
663         sar     dx,1\r
664         rcr ax,1\r
665         sar     dx,1\r
666         rcr ax,1\r
667 \r
668         add     ax,[WORD xintercept]            ; add partial step to current intercept\r
669         adc     dx,cx                                           ; CX hold high word of xintercept\r
670 \r
671         cmp     cx,dx                                           ; is it still in the same tile?\r
672         jne     continuehoriz                           ; no, it hit the side\r
673 \r
674 ;\r
675 ; draw the pushable wall at the new height\r
676 ;\r
677         mov     [WORD xintercept],ax            ; save pixel intercept position\r
678         mov     [WORD xintercept+2],dx\r
679 \r
680         mov     [WORD yintercept+2],bp\r
681         mov     [WORD yintercept],0\r
682 \r
683         call    FAR HitHorizPWall\r
684         jmp     nextpix\r
685 \r
686 \r
687 \r
688 ;===========================================================================\r
689 \r
690 ;=============\r
691 ;\r
692 ; hit a special vertical wall, so find which coordinate a door would be\r
693 ; intersected at, and check to see if the door is open past that point\r
694 ;\r
695 ;=============\r
696 vertdoor:\r
697         mov     [xtile],bx                                      ; save off live register variables\r
698         mov     [WORD yintercept+2],dx\r
699 \r
700         test al,040h                                    ; both high bits set == pushable wall\r
701         jnz     vertpushwall\r
702 \r
703         mov     bx,ax\r
704         and     bx,7fh                                          ; strip high bit\r
705         shl     bx,1                        ; index into word width doorposition\r
706 \r
707         mov     ax,[WORD ystep]\r
708         mov     dx,[WORD ystep+2]\r
709         sar     dx,1\r
710         rcr ax,1                                                ; half a step gets to door position\r
711 \r
712         add     ax,[WORD yintercept]            ; add half step to current intercept pos\r
713         adc     dx,[WORD yintercept+2]\r
714 \r
715         cmp     [WORD yintercept+2],dx          ; is it still in the same tile?\r
716         je      hitvmid\r
717 ;\r
718 ; midpoint is outside tile, so it hit the side of the wall before a door\r
719 ;\r
720 continuevert:\r
721         mov     bx,[xtile]                                      ; reload register variables\r
722         mov     dx,[WORD yintercept+2]\r
723         jmp     passvert                                        ; continue tracing\r
724 ;\r
725 ; the trace hit the door plane at pixel position AX, see if the door is\r
726 ; closed that much\r
727 ;\r
728 hitvmid:\r
729         cmp     ax,[doorposition+bx]            ; position of leading edge of door\r
730         jb      continuevert\r
731 ;\r
732 ; draw the door\r
733 ;\r
734         mov     [WORD yintercept],ax            ; save pixel intercept position\r
735         mov     [WORD xintercept],8000h         ; intercept in middle of tile\r
736         mov     ax,[xtile]\r
737         mov     [WORD xintercept+2],ax\r
738 \r
739         call    FAR HitVertDoor\r
740         jmp     nextpix\r
741 \r
742 ;============\r
743 ;\r
744 ; hit a sliding vertical wall\r
745 ;\r
746 ;============\r
747 \r
748 vertpushwall:\r
749         mov     ax,[WORD ystep+2]                       ; multiply ystep by pwallmove (0-63)\r
750         mul     [pwallpos]\r
751         mov     bx,ax\r
752         mov     ax,[WORD ystep]\r
753         mul     [pwallpos]\r
754         add     dx,bx\r
755 \r
756         sar     dx,1                                            ; then divide by 64 to accomplish a\r
757         rcr ax,1                                                ; fixed point multiplication\r
758         sar     dx,1\r
759         rcr ax,1\r
760         sar     dx,1\r
761         rcr ax,1\r
762         sar     dx,1\r
763         rcr ax,1\r
764         sar     dx,1\r
765         rcr ax,1\r
766         sar     dx,1\r
767         rcr ax,1\r
768 \r
769         add     ax,[WORD yintercept]            ; add partial step to current intercept\r
770         adc     dx,[WORD yintercept+2]\r
771 \r
772         cmp     [WORD yintercept+2],dx          ; is it still in the same tile?\r
773         jne     continuevert                            ; no, it hit the side\r
774 \r
775 ;\r
776 ; draw the pushable wall at the new height\r
777 ;\r
778         mov     [WORD yintercept],ax            ; save pixel intercept position\r
779         mov     [WORD yintercept+2],dx\r
780 \r
781         mov     bx,[xtile]\r
782         mov     [WORD xintercept+2],bx\r
783         mov     [WORD xintercept],0\r
784 \r
785         call    FAR HitVertPWall\r
786         jmp     nextpix\r
787 \r
788 \r
789 \r
790 ENDP\r
791 \r
792 \r
793 END\r
794 \r
795 \r