; funky tunnel by whizzter/woorlic ; compiles with nasm.. (nasm tunnel.asm -o tunnel.com) ; source included! ; originating somewhere else in a comfile would be kinda hazardous org 100h ; sinetable used for the twirling sinetab equ 64010 ; misc temp operands tt1 equ 64570 tt2 equ 64575 ; misc tunnel position values aa1 equ 64590 aa2 equ 64591 aa3 equ 64592 aa4 equ 64593 ; this segment should be free ; (a com program uses all memory from PSP->0a000, so as long as you have ; over 150k of mem free this should work) mov ah,080h mov ds,ax ; the 'ol videomem mov ah,0a0h mov es,ax ; setting mode13 mov ax,13h int 10h ; clear the copro before creating sinetable and setting the palette finit mov cx,256 mov di,sinetab fldz mov dx,3c8h xor ax,ax out dx,al inc dx sinpal_loop: fld st0 fsin fimul word [cs:fme] fiadd word [cs:fme] fistp dword [di] fadd dword [cs:fadda] mov al,ah shr al,2 out dx,al out dx,al xor al,al out dx,al inc ah inc di loop sinpal_loop ; create the LUT for the tunnel ; lut setup: ; 320x100 with ; 2 bytes.. first = angle(0>_x>_255), second = Z of tunnel ; this tunnel uses polar cords.. ; so the precalc is simply ; beware of pseudo code..! :) ; angle=atan(x/y) ; distZ=3000/sqrt(x^2 + y^2) ; you might be wondering how the Z stuff works.. ; if you remember the old projection formula ; u=x/z where u is screen X and x and z is the 3D coords ; if we rewrite this we get that ; z=x/u ; so 3000 is the radius of our tunnel, u is in our case the distance from the ; center of the screen and then Z is resolved mov cx,32000 mov bx,320 xor di,di tunnel_precalc: mov ax,cx add ax,319 xor dx,dx div bx sub dx,160 sub ax,50 mov [tt1],ax mov [tt2],dx fild word [tt1] fild word [tt2] fpatan fmul dword [cs:fma] fistp word [di] inc di fild word [tt1] fimul word [tt1] fild word [tt2] fimul word [tt2] faddp st1 fsqrt fidivr word [cs:fp] fistp word [di] inc di loop tunnel_precalc main: add byte[aa4],2 dec byte[aa3] inc byte[aa1] inc byte[aa2] mov di,0 call dotun call dotun ; check the last pressed key in al,60h dec al ; scancode for ESC = 1.. 1-1 = 0 .. if this is true then exit jnz main ; set mode 3(text) mov ax,3 int 10h ; and exit ret ; painting code.. ; distorts the angle depending on the sinetable and the distance.. dotun: mov cx,32000 mov si,0 inner: xor bh,bh mov bl,[si+1] add bl,[aa3] mov al,[bx+sinetab] mov bl,[si+1] add bl,[aa4] add al,[bx+sinetab] mov bl,[si] add bl,al add bl,[aa2] and bl,0f0h mov al,bl inc si mov bl,[si] add bl,[aa1] inc si and bl,0f0h xor al,bl stosb loop inner ret fp dw 3000 fme dw 30 fadda dd 0.024543692 fma dd 40.74366543 ; eh.. last note.. the doc and com filesizes were luck, this wasn't ; tunnel.com - 255 bytes, tunnel.doc - 512 bytes , tunnel.asm 2999 bytes