; Amaze : 128-byte intro with castle wolfenstein raycasting (fasm 1.70.03/WinXP 5.1.2600) ; credit : olivier.poudade.free.fr 2013 aka baudsurfer ; credit : inspired by Justin Frankel^Nullsoft's 256-byte intro gaycast (www.1014.org/code) ; greets : Adok, Frag, lordKelvin, Pirx, Rudi, sensenstahl, y0bi ; shouts : dark bit factory forum users (www.dbfinteractive.com) BONUSFLOOR=0 ; set this flag to 1 to draw floor (adds extra 10 bytes) org 100h ; start binary at psp+256 fldz ; fpu in : undefined / fpu out : (st0=0) fldz ; fpu in : (st0=0) / fpu out : (st0=0.0) (st1=0.0) lds ax,[bx] ; ds=ff9fh=a000h-16 ax=20cdh bx=assumed 0 frame: fiadd word [cs:7] ; advance value from previous frave / psp+7h=1dfeh fld st0 ; fpu in : (st0=0.0) (st1=0.0) / fpu out : (st0=st1) (st1=0.0) (st2=0.0) fld1 ; fpu in : (st0=st1) (st1=0.0) (st2=0.0) / fpu out : (st0=1.0) (st1=st2) (st2=0.0) (st3=0.0) mov bp,320 ; set bp to SCREEN_W faddp st3,st0 ; fpu in : (st0=1.0) (st1=st2) (st2=0.0) (st3=0.0) / fpu out : (st0=st1) (st1=0.0) (st2=0.0) / popped st0+st3 mov ax,13h ; vga chaine mode 320x256x8 / best effort to plug it closest to plotting int 10h ; vga video bios api also used as clear screen function / best effort to plug it closest to plotting xloop: mov byte [si+3],3bh ; was mov word [si+2],3b44h / 3b44h=15172b from /was fadd dword [cs:ADJ_VA] with ADJ_VA dd 994352038 fadd dword [si] ; st0=viewing angle adjust fld st0 ; fpu in : (st0=st1) (st1=0.0) (st2=0.0) / fpu out : (st0=st1) (st1=st2) (st2=0.0) (st3=0.0) fsincos ; fpu in : (st0=st1) (st1=st2) (st2=0.0) (st3=0.0) / fpu out : (cos(st0=st1)) (sin(st0=st1)) (st2=st3) (st3=0.0) (st4=0.0) mov cx,07e0h ; 07e0h=2016b=32*63 size of maze mov dx,cx ; dx=saved 32*63 cst for later use fld st4 ; st4=st0 fld st5 ; st5=st0 raycast: fadd st0,st3 ; fpu in : st0 st1 st2 st3 st0 st0 / fpu out: st0+st3 st1 st2 st3 st4 st5 fist dword [si] ; [si] = st0+st3 / si isa previous lower column ender-don't care fxch ; in : st0+st3 st1 st2 st3 st4 st5 out: st1 st0+st3 st2 st3 st4 st5 fadd st0,st2 ; in : st1 st0+st3 st2 st3 st4 st5 out: st1+st2 st0+st3 st2 st3 st4 mov bx,[si] ; mov bh,[si+1] fist dword [si] ; si=st1+st2 fxch ; in : st1+st2 st0+st3 st2 st3 st4 out: st0+st3 st1+st2 st2 st3 st4 mov bl,[si+1] ; lsbyte of maze position test byte [gs:bx],4 ; test if map wall flag present as arbitrary bitflag in 1kb bios ivt space jnz rayhit ; if so bail out casting loop loop raycast ; else continue raycast rayhit: sub dx,cx ; dx now holds column height for floor (200-100-lower wall height) mov cx,4 ; disregard scratchpad top 16 bytes of fpu stack fpupop16:fstp st0 ; disregard scratchpad top 16 bytes of fpu stack loop fpupop16 ; disregard scratchpad top 16 bytes of fpu stack xchg cx,dx ; after : dx=0, cx=divisor mov ah,3bh ; discreet scale / ah=3bh=>ax=3a98h=15000b div cx ; cx=distance / ax=result, dx=remainder xchg ax,cx ; ax=distance, cx=result (wall height/2) lea di,[bp+32015] ; middle of *this column (width*height/2) with ff9fh fixup / di=[32335;32015] mov si,di ; src and dst index are same middle of *this column at start mov dx,100 ; dx=max height of wall/2 cmp cx,dx ; clipping test jc texture ; no clipping needed mov cl,99 ; clipping texture: if BONUSFLOOR ; bonus floor sub dx,cx ; dx=(max column height-wall height)/2 end if ; bonus floor yloop: mov ax,cx ; xor texture : get height as distance xor ax,si ; xor texture : perform unique number xor texture aaa ; normalize pixel color palette index to [0,15] adc al,16 ; shift pixel color palette index to vga gray gradient [16,31] mov [di],al ; plot upper vertical pixel sub di,320 ; get next upper vertical pixel floor: mov [si],al ; plot lower vertical pixel add si,320 ; get next lower vertical pixel if BONUSFLOOR ; bonus floor jcxz floor2 ; re-use for floor below (skip loop if cx=0) end if ; bonus floor loop yloop ; repeat until all pixels of *this column wall processed if BONUSFLOOR ; bonus floor mov al,23 ; discreet uniform grey color value floor2: dec dx ; decrement *this column floor index jnz floor ; repeat until all pixels of *this column floor processed end if ; bonus floor dec bp ; decrement screen column index jnz xloop ; repeat until all columns [319,0] of this screen processed fstp st0 ; disregard scratchpad top 4 bytes of fpu stack jmp frame ; process next frame / sorry no space left for esc key exit test