Subversion Repositories Kolibri OS

Compare Revisions

Ignore whitespace Rev 209 → Rev 272

/programs/demos/free3d04/trunk/free3d04.asm
9,7 → 9,7
; Willow - greatly srinked code size by using GIF texture and FPU to calculate sine table
;
; !!!! Don't use GIF.INC in your apps - it's modified for FREE3D !!!!
 
TEX_SIZE equ 64*64*4
ceil = sinus+16*1024
wall = ceil+TEX_SIZE*1
22,9 → 22,9
APP_MEM equ 0x200000
 
use32
 
org 0x0
 
db 'MENUET01' ; 8 byte id
dd 0x01 ; header version
dd START ; start of code
32,11 → 32,11
dd APP_MEM;0x300000 ; memory for app
dd APP_MEM;0x300000 ; esp
dd 0x0 , 0x0 ; I_Param , I_Icon
include 'lang.inc'
include 'lang.inc'
include 'macros.inc'
COLOR_ORDER equ OTHER
COLOR_ORDER equ OTHER
include 'gif.inc'
 
START: ; start of execution
mov esi,textures
mov edi,ceil
45,8 → 45,8
mov esi,sinus
mov ecx,360*10
fninit
fld [sindegree]
.sinlp:
fld [sindegree]
.sinlp:
fst st1
fsin
fmul [sindiv]
56,7 → 56,7
loop .sinlp
call draw_window ; at first, draw the window
call draw_stuff
 
gamestart:
; ******* MOUSE CHECK *******
; mov eax,37 ; check mouse (use mouse over window to navigate)
67,12 → 67,12
mov eax,37
mov ebx,1 ; check mouseposition
int 0x40
 
mov ebx,eax
shr eax,16
and eax,0x0000FFFF ; mousex
and ebx,0x0000FFFF ; mousey
 
cmp eax,5 ; mouse out of window ?
jb check_refresh ; it will prevent an app-crash
cmp ebx,22
81,7 → 81,7
jg check_refresh
cmp ebx,501
jg check_refresh
 
cmp eax,315 ; navigating?
jb m_left
cmp eax,325 ;
93,12 → 93,12
jg s_down
; ******* END OF MOUSE CHECK *******
check_refresh:
 
; mov eax,23 ; wait for system event with 10 ms timeout
; mov ebx,1 ; thats max 100 FPS
mov eax,11 ; ask no wait for full speed
int 0x40
 
cmp eax,1 ; window redraw request ?
je red2
cmp eax,2 ; key in buffer ?
105,32 → 105,32
je key2
cmp eax,3 ; button in buffer ?
je button2
 
mov edi,[mouseya] ; check flag if a refresh has to be done
cmp edi,1
jne gamestart
mov [mouseya],dword 0
call draw_stuff
 
 
jmp gamestart
 
; END OF MAINLOOP
 
red2: ; redraw
call draw_window
call draw_stuff
jmp gamestart
 
key2: ; key
mov eax,2
int 0x40
cmp al,1
je gamestart ; keybuffer empty
 
cmp ah,27 ; esc=End App
je finish
 
cmp ah,178 ; up
je s_up
cmp ah,177 ; down
139,24 → 139,26
je s_left
cmp ah,179 ; right
je s_right
 
jmp gamestart ; was any other key
 
 
s_up: ; walk forward (key or mouse)
mov eax,[vpx]
mov ebx,[vpy]
 
 
mov ecx,[vheading]
imul ecx,4
add ecx,sinus
; imul ecx,4
; add ecx,sinus
lea ecx, [sinus+ecx*4]
mov edi,[ecx]
 
mov edx,[vheading]
imul edx,4
add edx,sinus
add edx,3600
; imul edx,4
; add edx,sinus
; add edx,3600
lea edx, [sinus+3600+edx*4]
cmp edx,eosinus ;cosinus taken from (sinus plus 900) mod 3600
jb ok200
sub edx,14400
164,7 → 166,7
mov esi,[edx]
; sal esi,1 ; edit walking speed here
; sal edi,1
 
add eax,edi ; newPx
add ebx,esi ; newPy
mov edi,eax ; newPx / ffff
173,8 → 175,9
sar esi,16
mov ecx,esi
sal ecx,5 ; equal *32
add ecx,edi
add ecx,grid
; add ecx,edi
; add ecx,grid
lea ecx, [grid+ecx+edi]
cmp [ecx],byte 0 ; collision check
jne cannotwalk0
mov [vpx],eax
182,29 → 185,31
mov [mouseya],dword 1 ; set refresh flag
cannotwalk0:
jmp check_refresh
 
s_down: ; walk backward
mov eax,[vpx]
mov ebx,[vpy]
 
mov ecx,[vheading]
imul ecx,4
add ecx,sinus
; imul ecx,4
; add ecx,sinus
lea ecx, [sinus+ecx*4]
mov edi,[ecx]
 
mov edx,[vheading]
imul edx,4
add edx,sinus
add edx,3600
; imul edx,4
; add edx,sinus
; add edx,3600
lea edx, [sinus+3600+edx*4]
cmp edx,eosinus ;cosinus taken from (sinus plus 900) mod 3600
jb ok201
sub edx,14400
ok201:
 
mov esi,[edx]
; sal esi,1 ; edit walking speed here
; sal edi,1
 
sub eax,edi ; newPx
sub ebx,esi ; newPy
mov edi,eax ; newPx / ffff
213,8 → 218,9
sar esi,16
mov ecx,esi
sal ecx,5
add ecx,edi
add ecx,grid
; add ecx,edi
; add ecx,grid
lea ecx, [grid+ecx+edi]
cmp [ecx],byte 0
jne cannotwalk1
mov [vpx],eax
222,7 → 228,7
mov [mouseya],dword 1
cannotwalk1:
jmp check_refresh
 
s_left: ; turn left (key)
mov edi,[vheading] ; heading
add edi,50
233,7 → 239,7
mov [vheading],edi
mov [mouseya],dword 1
jmp check_refresh
 
s_right: ; turn right
mov edi,[vheading]
sub edi,50
244,7 → 250,7
mov [vheading],edi
mov [mouseya],dword 1
jmp check_refresh
 
m_left: ; turn left (mouse)
mov edi,[vheading] ; heading
mov ecx,315
258,7 → 264,7
mov [vheading],edi
mov [mouseya],dword 1
jmp continue ; allow both: walk and rotate
 
m_right: ; turn right
mov edi,[vheading]
sub eax,325
271,32 → 277,32
mov [vheading],edi
mov [mouseya],dword 1
jmp continue
 
 
 
button2: ; button
mov eax,17 ; get id
int 0x40
cmp ah,1 ; button id=1 ?
jne gamestart
 
; eo GAME mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm
finish:
mov eax,-1 ; close this program
int 0x40
 
 
; *********************************************
; ******* WINDOW DEFINITIONS AND DRAW ********
; *********************************************
 
 
draw_window:
 
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,1 ; 1, start of draw
int 0x40
 
; DRAW WINDOW
mov eax,0 ; function 0 : define and draw window
mov ebx,50*65536+649 ; [x start] *65536 + [x size]
305,7 → 311,7
mov esi,0x80777777 ; color of grab bar RRGGBB,8->color gl
mov edi,0x00777777 ; color of frames RRGGBB
int 0x40
 
; WINDOW LABEL
mov eax,4 ; function 4 : write text to window
mov ebx,8*65536+8 ; [x start] *65536 + [y start]
313,7 → 319,7
mov edx,labelt ; pointer to text beginning
mov esi,labellen-labelt ; text length
int 0x40
 
; CLOSE BUTTON
mov eax,8 ; function 8 : define and draw button
mov ebx,(649-19)*65536+12 ; [x start] *65536 + [x size]
321,20 → 327,20
mov edx,1 ; button id
mov esi,0x777777 ; button color RRGGBB
int 0x40
 
 
mov eax,12 ; function 12:tell os about windowdraw
mov ebx,2 ; 2, end of draw
int 0x40
 
ret
 
; *********************************************
; ******* COMPUTE 3D-VIEW ********
; *********************************************
draw_stuff:
 
 
mov [step1],dword 1
;mov [step64],dword 64
mov esi,[vheading]
361,42 → 367,44
jb ok2
sub edx,3600
ok2:
 
; get stepx and stepy
mov ecx,edx
imul ecx,4
add ecx,sinus ; pointer to stepx
; mov ecx,edx
; imul ecx,4
; add ecx,sinus ; pointer to stepx
lea ecx, [sinus+edx*4]
mov esi,[ecx]
sar esi,4 ; accuracy
mov [vstepx],esi ; store stepx
mov esi,edx
imul esi,4
add esi,sinus ; pointer to stepy
add esi,3600
 
; mov esi,edx
; imul esi,4
; add esi,sinus ; pointer to stepy
; add esi,3600
lea esi, [sinus+3600+edx*4]
cmp esi,eosinus ;cosinus taken from ((sinus plus 900) mod 3600)
jb ok202
sub esi,14400
ok202:
 
mov ecx,[esi]
sar ecx,4
mov [vstepy],ecx ; store stepy
 
 
mov eax,[vpx] ; get Camera Position
mov ebx,[vpy]
mov [vxx],eax ; init caster position
mov [vyy],ebx
 
mov edi,0 ; init L (number of raycsting-steps)
mov [step1],dword 1 ; init Caster stepwidth for L
 
; raycast a pixel column.................................
raycast:
add edi,[step1] ; count caster steps
;jmp nodouble ; use this to prevent blinking/wobbling textures: much slower!
 
cmp edi,32
je double
cmp edi,512
404,26 → 412,26
cmp edi,1024
je double
jmp nodouble
 
double:
mov edx,[step1]
sal edx,1
mov [step1],edx
 
mov edx,[vstepx]
sal edx,1
mov [vstepx],edx
 
mov edx,[vstepy]
sal edx,1
mov [vstepy],edx
 
nodouble:
 
mov eax,32000 ; 3600 ; determine Floors Height based on distance
mov edx,0
mov ebx,edi
 
div ebx
mov esi,eax
mov [vdd],esi
430,7 → 438,7
mov edx,260
sub edx,esi
mov [vh],edx
 
cmp edx,22
jb no_nu_pixel
cmp edx,259
437,42 → 445,47
jg no_nu_pixel ; draw only new pixels
cmp edx,[h_old]
je no_nu_pixel
 
mov eax,[vxx] ; calc floor pixel
mov ebx,[vyy]
 
and eax,0x0000FFFF
and ebx,0x0000FFFF
 
shr eax,10
shr ebx,10 ; pixel coords inside Texture x,y 64*64
mov [xfrac],eax
mov [yfrac],ebx
 
 
 
; plot floor pixel !!!!
mov [vl],edi ; save L
mov [ytemp],esi ; remember L bzw. H
 
mov edi,[yfrac] ; get pixel color of this floor pixel
sal edi,8
mov esi,[xfrac]
sal esi,2
add edi,esi
add edi,wall ; in fact its floor, just using the wall texture :)
; add edi,esi
; add edi,wall ; in fact its floor, just using the wall texture :)
lea edi, [wall+edi+esi]
 
mov edx,[edi]
mov [remesi],esi
 
;**** calculate pixel adress:****
mov esi,[ytemp]
add esi,240
imul esi,1920
add esi,[vx1]
add esi,[vx1]
add esi,[vx1]
add esi,0x80000
; add esi,[vx1]
; add esi,[vx1]
; add esi,[vx1]
; add esi,0x80000
mov eax, [vx1]
lea eax, [eax+eax*2]
lea esi, [0x80000+eax+esi]
 
cmp esi,0x80000+1920*480
jg foff0
cmp esi,0x80000
479,33 → 492,33
jb foff0
; now we have the adress of the floor-pixel color in edi
; and the adress of the pixel in the image in esi
 
mov edx,[edi]
;******************** custom distance DARKEN Floor
 
mov eax,[vdd]
 
; jmp nodark0 ; use this to deactivate darkening floor (a bit faster)
 
cmp eax,80
jg nodark0
; split rgb
 
mov [blue],edx
and [blue],dword 255
 
shr edx,8
mov [green],edx
and [green],dword 255
 
shr edx,8
mov [red],edx
and [red],dword 255
 
mov eax,81 ; darkness parameter
sub eax,[vdd]
sal eax,1
 
; reduce rgb
sub [red],eax
cmp [red], dword 0
512,13 → 525,13
jg notblack10
mov [red],dword 0
notblack10:
 
sub [green],eax
cmp [green],dword 0
jg notblack20
mov [green],dword 0
notblack20:
 
mov edx,[blue]
sub [blue],eax
cmp [blue],dword 0
525,71 → 538,73
jg notblack30
mov [blue],dword 0
notblack30:
 
shl dword [red],16 ; reassemble rgb
shl dword [green],8
mov edx,[red]
or edx,[green]
or edx,[blue]
 
nodark0:
; eo custom darken floor
 
 
mov eax,edx
mov [esi],eax ; actually draw the floor pixel
 
; paint "forgotten" pixels
 
mov edx,[lasty]
sub edx,1920
cmp esi,edx
je foff0
mov [esi+1920],eax
 
sub edx,1920
cmp esi,edx
je foff0
mov [edx+1920],eax
 
sub edx,1920
cmp esi,edx
je foff0
mov [edx+1920],eax
 
foff0:
mov [lasty],esi
;**** end of draw floor pixel ****
 
mov esi,[remesi]
mov edi,[vl] ; restore L
 
no_nu_pixel:
 
 
mov esi,[vh]
mov [h_old],esi
 
mov eax,[vxx]
mov ebx,[vyy]
 
add eax,[vstepx] ; casting...
add ebx,[vstepy]
 
mov [vxx],eax
mov [vyy],ebx
 
sar eax,16
sar ebx,16
 
mov [vpxi],eax ; casters position in Map Grid
mov [vpyi],ebx
 
mov edx,ebx
; imul edx,32
shl edx,5
add edx,grid
add edx,eax
; add edx,grid
; add edx,eax
lea edx, [grid+edx+eax]
 
cmp [edx],byte 0 ; raycaster reached a wall? (0=no)
jne getout
cmp edi,10000 ; limit view range
598,44 → 613,48
getout:
mov eax,[edx] ; store Grid Wall Value for Texture Selection
mov [vk],eax
 
call blur ; deactivate this (blurs the near floor) : a bit faster
 
; simply copy floor to ceil pixel column here
;jmp nocopy ; use this for test purposes
 
pusha
mov eax,0x80000+1920*240
mov ebx,0x80000+1920*240
 
copyfloor:
sub eax,1920
add ebx,1920
mov ecx,0
add ecx,[vx1]
add ecx,[vx1]
add ecx,[vx1]
mov edx,ecx
 
; mov ecx,0
; add ecx,[vx1]
; add ecx,[vx1]
; add ecx,[vx1]
mov ecx, [vx1]
lea ecx, [ecx+ecx*2]
 
; mov edx,ecx
; add ecx,eax
; add edx,ebx
lea edx, [ecx+ebx]
add ecx,eax
add edx,ebx
 
mov esi,[edx]
mov [ecx],esi
 
cmp eax,0x80000
jg copyfloor
 
popa
; *** end of copy floor to ceil
;nocopy:
;__________________________________________________________________________
 
 
; draw this pixelrows wall
mov [vl],edi
 
mov edi,260
sub edi,[vdd]
cmp edi,0
643,111 → 662,112
xor edi,edi
ok3:
mov [vbottom],edi ; end wall ceil (or window top)
 
mov esi,262
add esi,[vdd] ; start wall floor
 
xor edi,edi
 
; somethin is wrong with xfrac,so recalc...
 
mov eax,[vxx]
and eax,0x0000FFFF
shr eax,10
mov [xfrac],eax
 
mov eax,[vyy]
and eax,0x0000FFFF
shr eax,10
mov [yfrac],eax
 
pixelrow:
 
; find each pixels color:
 
add edi,64
sub esi,1
cmp esi, 502 ; dont calc offscreen-pixels
jg speedup
 
xor edx,edx
mov eax, edi
mov ebx,[vdd]
add ebx,[vdd]
; add ebx,[vdd]
add ebx, ebx
div ebx
and eax,63
mov [ytemp],eax ; get y of texture for wall
 
mov eax,[xfrac]
add eax,[yfrac]
 
and eax,63
mov [xtemp],eax ; get x of texture for wall
 
; now prepare to plot that wall-pixel...
mov [remedi],edi
 
mov edi,[ytemp]
sal edi,8
mov edx,[xtemp]
sal edx,2
add edi,edx
 
mov eax,[vk] ; determine which texture should be used
and eax,255
 
cmp eax,1
jne checkmore1
add edi,ceil
jmp foundtex
checkmore1:
 
cmp eax,2
jne checkmore2
add edi,wall
jmp foundtex
checkmore2:
 
cmp eax,3
jne checkmore3
add edi,wall2
jmp foundtex
checkmore3:
 
cmp eax,4
jne checkmore4
add edi,wall3
jmp foundtex
checkmore4:
 
cmp eax,5
jne checkmore5
add edi,wall4
jmp foundtex
checkmore5:
 
cmp eax,6
jne checkmore6
add edi,wall5
jmp foundtex
checkmore6:
 
cmp eax,7
jne checkmore7
add edi,wall6
jmp foundtex
checkmore7:
 
cmp eax,8
jne checkmore8
add edi,wall7
jmp foundtex
checkmore8:
 
foundtex:
 
mov edx,[edi] ; get pixel color inside texture
 
; ***pseudoshade south-west
jmp east ; activate this for southwest pseudoshade : a bit slower + blink-bug
mov edi,[yfrac]
758,18 → 778,22
shr edx,1
mov [pseudo],dword 1
east:
 
call dark_distance ; deactivate wall distance darkening: a bit faster
 
; ******* DRAW WALL PIXEL *******
mov eax,esi
sub eax,22
; sub eax,22
lea eax, [esi-22]
imul eax,1920
add eax,[vx1]
add eax,[vx1]
add eax,[vx1]
add eax,0x80000
; add eax,[vx1]
; add eax,[vx1]
; add eax,[vx1]
; add eax,0x80000
mov ebx, [vx1]
lea ebx, [ebx+ebx*2]
lea eax, [eax+0x80000+ebx]
 
cmp eax,0x80000+1920*480
jg dont_draw
cmp eax,0x80000
781,12 → 805,12
speedup:
cmp esi,[vbottom] ; end of this column?
jg pixelrow
 
mov edi,[vl] ; restoring
mov eax,[vx1] ; inc X1
add eax,1
mov [vx1],eax
 
;*** NEXT A ***
mov esi,[va]
sub esi,1
795,8 → 819,8
jg for_a
;*** EO NEXT A ***
;---------------------------------------------------------------------------
 
 
; **** put image !!!!!****
; ***********************
mov eax,7
804,21 → 828,25
mov ecx,640*65536+480
mov edx,5*65536+20
int 0x40
 
ret
 
blur:
 
pusha
mov eax,0x080000+360*1920
 
copyfloor2:
add eax,1920
mov ebx,eax
add ebx,[vx1]
add ebx,[vx1]
add ebx,[vx1]
; mov ebx,eax
; add ebx,[vx1]
; add ebx,[vx1]
; add ebx,[vx1]
mov ebx,[vx1]
lea ebx, [ebx+ebx*2]
add ebx, eax
 
 
mov ecx,[ebx-15]
and ecx,0x00FEFEFE
shr ecx,1
828,68 → 856,68
add edx,ecx
and edx,0x00FEFEFE
shr edx,1
 
mov ecx,[ebx-9]
and ecx,0x00FEFEFE
shr ecx,1
add edx,ecx
 
and edx,0x00FEFEFE
shr edx,1
 
mov ecx,[ebx-6]
and ecx,0x00FEFEFE
shr ecx,1
add edx,ecx
 
and edx,0x00FEFEFE
shr edx,1
 
mov ecx,[ebx-3]
and ecx,0x00FEFEFE
shr ecx,1
add edx,ecx
 
and edx,0x00FEFEFE
shr edx,1
 
mov ecx,[ebx]
and ecx,0x00FEFEFE
shr ecx,1
add edx,ecx
 
mov [ebx],edx
 
cmp eax,0x80000+478*1920
jb copyfloor2
 
popa
 
ret
 
 
 
; ******* Darken by Distance *******
dark_distance:
 
; color must be in edx, wall height in [vdd]
 
mov eax,[vdd]
cmp eax,50
jg nodark
; split rgb
 
mov [blue],edx
and [blue],dword 255
 
shr edx,8
mov [green],edx
and [green],dword 255
 
shr edx,8
mov [red],edx
and [red],dword 255
 
mov eax,51 ; darkness parameter
sub eax,[vdd]
cmp [pseudo],dword 1
896,7 → 924,7
je isdarkside
sal eax,2
isdarkside:
 
; reduce rgb
sub [red],eax
cmp [red], dword 0
903,13 → 931,13
jg notblack10b
mov [red],dword 0
notblack10b:
 
sub [green],eax
cmp [green],dword 0
jg notblack20b
mov [green],dword 0
notblack20b:
 
mov edx,[blue]
sub [blue],eax
cmp [blue],dword 0
916,7 → 944,7
jg notblack30b
mov [blue],dword 0
notblack30b:
 
shl dword [red],16 ; reassemble rgb
shl dword [green],8
mov edx,[red]
923,14 → 951,14
or edx,[green]
or edx,[blue]
mov eax,edx
 
nodark:
 
ret
 
 
; DATA AREA
 
;ceil=ceil
;wall=wall floor
;2 corner stone
939,7 → 967,7
;5 greek mosaic
;6 old street stones
;7 maya wall
 
grid: ; 32*32 Blocks, Map: 0 = Air, 1 to 8 = Wall
db 2,1,2,1,2,1,2,1,2,1,2,1,1,1,1,1,1,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
db 1,0,0,0,1,0,0,0,0,0,0,3,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,8,8
973,23 → 1001,24
db 5,0,0,0,0,0,0,5,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,4,4,4,4,4,0,0,1
db 1,4,1,4,1,4,1,4,1,4,1,3,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1
db 2,1,2,1,2,1,2,1,2,1,2,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
 
vpx:
dd 0x0001FFFF ; initial player position * 0xFFFF
vpy:
dd 0x0001FFFF
 
labelt:
db 'FISHEYE RAYCASTING ENGINE ETC. FREE3D'
 
labellen:
sindegree dd 0.0
sininc dd 0.0017453292519943295769236907684886
sindiv dd 6553.5
sindiv dd 6553.5
textures:
file 'texture.gif'
I_END:
 
align 4
 
col1:
dd ?;-
; misc raycaster vars:
1033,7 → 1062,7
dd ?;-
wtolong:
dw ?,?;-,?;-
 
xtemp:
dd ?;-
ytemp:
1074,6 → 1103,7
dd ?;-
lasty:
dd ?;-
sinus rd 360*10
 
I_END:
sinus rd 360*10
eosinus: