From 0cb93396cfbbffafc181a214e6af3ec9d14be8aa Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 13 Jan 2007 06:40:41 +0000 Subject: [PATCH] free3d04 1) fixed I_END 2)small arithmetic optimization git-svn-id: svn://kolibrios.org@272 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/demos/free3d04/trunk/free3d04.asm | 516 +++++++++++---------- 1 file changed, 273 insertions(+), 243 deletions(-) diff --git a/programs/demos/free3d04/trunk/free3d04.asm b/programs/demos/free3d04/trunk/free3d04.asm index f23e2ef7d5..00dffb6291 100644 --- a/programs/demos/free3d04/trunk/free3d04.asm +++ b/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 @@ wall7 = ceil+TEX_SIZE*7 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 @@ use32 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 @@ START: ; start of execution mov esi,sinus mov ecx,360*10 fninit - fld [sindegree] - .sinlp: + fld [sindegree] + .sinlp: fst st1 fsin fmul [sindiv] @@ -56,7 +56,7 @@ START: ; start of execution 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 @@ gamestart: 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 @@ gamestart: jg check_refresh cmp ebx,501 jg check_refresh - + cmp eax,315 ; navigating? jb m_left cmp eax,325 ; @@ -93,44 +93,44 @@ continue: 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 ? 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 @@ key2: ; key 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 @@ s_up: ; walk forward (key or mouse) 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 @@ s_up: ; walk forward (key or mouse) 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 @@ s_up: ; walk forward (key or mouse) 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 @@ s_down: ; walk backward 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 @@ s_down: ; walk backward mov [mouseya],dword 1 cannotwalk1: jmp check_refresh - + s_left: ; turn left (key) mov edi,[vheading] ; heading add edi,50 @@ -233,7 +239,7 @@ s_left: ; turn left (key) mov [vheading],edi mov [mouseya],dword 1 jmp check_refresh - + s_right: ; turn right mov edi,[vheading] sub edi,50 @@ -244,7 +250,7 @@ s_right: ; turn right 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 @@ m_left: ; turn left (mouse) 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 @@ m_right: ; turn right 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 @@ draw_window: 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 @@ draw_window: 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 @@ draw_window: 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 @@ ok1: 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,192 +412,199 @@ raycast: 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 mov edx,260 sub edx,esi mov [vh],edx - + cmp edx,22 jb no_nu_pixel cmp edx,259 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 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 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 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 @@ no_nu_pixel: 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 @@ copyfloor: 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 @@ jmp east ; activate this for southwest pseudoshade : a bit slower + blink-bug 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 @@ dont_draw: 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 @@ speedup: jg for_a ;*** EO NEXT A *** ;--------------------------------------------------------------------------- - - + + ; **** put image !!!!!**** ; *********************** mov eax,7 @@ -804,21 +828,25 @@ speedup: 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,109 +856,109 @@ copyfloor2: 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 je isdarkside sal eax,2 isdarkside: - + ; reduce rgb sub [red],eax cmp [red], dword 0 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 jg notblack30b mov [blue],dword 0 notblack30b: - + shl dword [red],16 ; reassemble rgb shl dword [green],8 mov edx,[red] 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 @@ nodark: ;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 1,0,0,0,1,0,0,5,0,0,0,3,0,0,0,0,6,1,5,1,0,1,0,4,4,0,0,0,4,4,0,1 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 @@ vpyi: dd ?;- wtolong: dw ?,?;-,?;- - + xtemp: dd ?;- ytemp: @@ -1074,6 +1103,7 @@ step64: dd ?;- lasty: dd ?;- - -sinus rd 360*10 + +I_END: +sinus rd 360*10 eosinus: