; ; 3D ТЕКСТУРИРОВАНЫЙ ДВИЖОК 3D TEXTURED ENGINE ; АВТОР: Павлюшин Евгений AUTOR: Pavlushin Evgeni ; ; Компилируется с помощью FASM ассемблера для MenuetOS ; Compile with FASM assembler for MenuetOS ; ; 20.11.04 Fast point calc & triangle draw ; Little matrix no (trangle massive) ; Fast triangle, del triangle out of screen ; 16.12.04 Fast triangle with MMX ; 20.12.04 Out triangle fatal bug's deleted, "black zones" deleted ; Matrix move support ; 24.12.04 Fast keyboard scanning ; Z-ground level map work ; Texture draw correction deleted "black zones" ; 04.01.05 Moveing texture ; 05.01.05 Water dynamic texture ; 06.01.05 Texture pack (many textures in one file) ; 07.01.05 Z-sorting ; 08.01.05 Triangle good clipping calculating (speed up) ; 4 byte Z-sorting, more dynamic of water ; 09.01.05 Texture map from 256 color bmp file ; Pixel Z-buffer, good speed! ; 21.01.05 Models buffer add. ; 25.01.05 Models buffer update, Add 2 new models. ; 29.01.05 Dynamic model array ; 01.02.05 1 picture MipMap calculation ; 04.02.05 All picture MipMap calculation, proc speed up. ; Simple Triangel MipMap chose. ; 05.02.05 Normal Triangel MipMap chose. ; 12.02.05 Best QUALITY of Textured TRIANGEL! ; 13.02.05 add new models. All camera axis calculating ; 16.02.05 Simple model turning ; 17.02.05 Advanced model turning, model tmpoints massive deleted ; New map size 128, add new models. ; 25.02.05 Left side clipping bug deleted ; 26.02.05 Optimization of textured line algorythm ; 24.04.05 Test pixel z-buffer it's work. Use new textri algorythm ; 30.04.05 Fast Y-clipping use32 SCREEN_X equ 800 ;320 ;Screen size easy change SCREEN_Y equ 600 ;200 DSCREEN_X equ SCREEN_X-1 ;320 ;For triangle clipping DSCREEN_Y equ SCREEN_Y-1 ;200 MATRIX_XSIZE equ 64;32;64;100 ;Ground matrix size MATRIX_YSIZE equ 64;32;64;100 SECTOR_SIZE equ 100 ;Size of matrix sector MAP_XSIZE equ 128 ;Rezolution of map file MAP_YSIZE equ 128 org 0x0 db 'MENUET01' ; 8 байт интдефикатор dd 0x01 ; версия заголовка dd START ; адресс начала кода dd I_END ; размер программы dd I_END+(SCREEN_X*SCREEN_Y*3+50000) ; размер памяти для прогграммы dd I_END+(SCREEN_X*SCREEN_Y*3+10000) ; esp dd 0x0 , 0x0 ; I_Param , I_Icon include 'lang.inc' include '..\..\..\macros.inc' include 'ascgl.inc' include 'ascl.inc' START: ; начало приложения ; Draw window at first call draw_window ; Decoding groud texture and ground level map gif_hash_offset = gif_hash_area ;texture's giftoimg texpack_gif,texpack_img-8 ;ground level map giftoimg gif_file_area5,glm_img_area ;get 8bitmap from 256 colors bmp file mov ebp,128;64 mov esi,0x043a+128*128-4;64*64-4 sub esi,128;64 mov edi,0 mov ecx,128;64 texmap_unp: mov al,[bmp_texmap+esi] mov [img_area+edi],al inc esi inc edi dec ecx jnz texmap_unp mov ecx,128;64 sub esi,256;128 dec ebp jnz texmap_unp ;Unpack textures mov esi,texpack_img mov edi,texture_img mov edx,16 mov ecx,16 tpuckloop: pushad call unpuck popad add esi,32*3 add edi,4095 dec ecx jnz tpuckloop add esi,31*32*16*3 mov ecx,16 dec edx jnz tpuckloop ; ; Unpuck one texture procendure ; jmp skip_unpuck unpuck: mov ecx,32 mov edx,32 tunploop: mov ax,[esi] mov [edi],ax mov al,[esi+2] mov [edi+2],al add esi,3 add edi,3 dec ecx jnz tunploop mov ecx,32 add esi,(32*16*3)-(32*3) dec edx jnz tunploop ret skip_unpuck: ;calculating all mipmaps mov esi,texture_img mov ecx,256 ;quantity of textures mmaploop: mov ebp,32 ;max mipmap texture pusha call texgen popa add esi,4095 ;next mipmap block dec ecx jnz mmaploop jmp skip_texgen ;******************************** ; MIPMAP TEXTURE GENERATION ; ; in put: ; esi - offset to texture ; ebp - mipmap max size (32 for this sample) ;******************************** texgen: push esi mov eax,ebp imul eax,ebp imul eax,3 add eax,esi mov edi,eax mov eax,ebp shr eax,1 mov dh,al mov dl,al mov cl,dl mov ecx,ebp mov eax,ebp shl eax,1 add ecx,eax miploop: ; Red xor bx,bx ;for add xor ax,ax ;for add mov al,[esi+0] add bx,ax mov al,[esi+3+0] add bx,ax mov al,[esi+ecx+0] add bx,ax mov al,[esi+ecx+3+0] add bx,ax shr bx,2 ;/4 mov [edi+0],bl ;Green xor bx,bx ;for add xor ax,ax ;for add mov al,[esi+1] add bx,ax mov al,[esi+3+1] add bx,ax mov al,[esi+ecx+1] add bx,ax mov al,[esi+ecx+3+1] add bx,ax shr bx,2 ;/4 mov [edi+1],bl ;Blue xor bx,bx ;for add xor ax,ax ;for add mov al,[esi+2] add bx,ax mov al,[esi+3+2] add bx,ax mov al,[esi+ecx+2] add bx,ax mov al,[esi+ecx+3+2] add bx,ax shr bx,2 ;/4 mov [edi+2],bl add esi,6 add edi,3 dec dl jnz miploop mov ax,bp shr ax,1 mov dl,al add esi,ecx dec dh jnz miploop pop esi mov eax,ebp imul eax,ebp imul eax,3 add esi,eax shr ebp,1 cmp ebp,1 jne texgen ret skip_texgen: ;Copy dynamic water texture ; ???????????? mov ecx,32*32*3 mov esi,texture_img+4095 ;32*32*3 mov edi,texture_limg cld rep movsb ; init sine wave for dynamic water texture finit mov edi,sinwave mov ecx,32;256 isv_loop: fld [angle] fld st fsin fmul [mul_wave] fistp word [edi] fadd [d_angle] fstp [angle] add edi,2 dec ecx jnz isv_loop ;Initalize keyboard mov eax,66 mov ebx,1 mov ecx,1 mcall mov eax,26 mov ebx,2 mov ecx,1 mov edx,keymap+100 mcall ;Build triangle matrix mov esi,points mov eax,-(MATRIX_XSIZE/2)*SECTOR_SIZE mov ebx,-(MATRIX_YSIZE/2)*SECTOR_SIZE mov ebp,img_area+8 loomat: mov [esi],eax ;x-set mov [esi+4],ebx ;y-set mov [esi+8],ecx ;z-set add ebp,3 add esi,4*3 add eax,SECTOR_SIZE cmp eax,((MATRIX_YSIZE/2)+1)*SECTOR_SIZE jnge loomat mov eax,-(MATRIX_YSIZE/2)*SECTOR_SIZE add ebx,SECTOR_SIZE cmp ebx,((MATRIX_XSIZE/2)+1)*SECTOR_SIZE jnge loomat ; Create z-ground good algorythm not already yet (64x64 map) mov esi,glm_img_area+8 mov edi,ground_level_map loox: ; draw_courner_points mov eax,[esi] call get_z ; mov [edi],eax mov eax,[esi+((MATRIX_XSIZE-1)*4)] call get_z ; mov [edi+((MATRIX_XSIZE)*4)],eax mov eax,[esi+(((MATRIX_XSIZE)*(MATRIX_YSIZE-1)+1)*4)] call get_z ; mov [edi+(((MATRIX_XSIZE+1)*(MATRIX_YSIZE)-0)*4)],eax mov eax,[esi+(((MATRIX_XSIZE)*(MATRIX_YSIZE)-1)*4)] call get_z ; mov [edi+(((MATRIX_XSIZE+1)*(MATRIX_YSIZE+1)-1)*4)],eax jmp skip_gz get_z: xor ebx,ebx xor ecx,ecx mov bl,al add ecx,ebx mov bl,ah add ecx,ebx shr eax,16 mov bl,al add ecx,ebx mov eax,ecx xor edx,edx mov ebx,3 cdq div ebx neg eax ret skip_gz: ; z-ground livel facking method (65x65 map) mov esi,glm_img_area+8 mov edi,ground_level_map mov ebp,(MAP_XSIZE+1)*(MAP_YSIZE+1) looglm: mov eax,[esi] ; and eax,0x000000ff call get_z mov [edi],eax add esi,3 add edi,1 dec ebp jnz looglm ;Fill model massive mov ecx,[model_mas_start] imul ecx,8 add ecx,4 mov esi,model_mas_start mov edi,model_mas cld rep movsd jmp skip_moddata model_mas_start: dd 12 ;quantity of models dd 0,0,-150,0,0,0,0,bunker dd 60,-250,-190,0,0,64,0,tank dd 0,180,-150,0,0,0,0,cannon dd 0,480,-150,0,0,0,0,outpost dd 260,60,-150,0,0,0,0,bunker dd 60,260,-150,0,0,0,0,outpost dd 210,410,-150,0,0,0,0,cannon dd 160,260,-150,0,0,0,0,tree dd 100,-360,-150,0,0,192,0,gqfa dd 10,580,-150,0,0,0,0,repear dd 460,160,-100,0,0,0,0,red_flag dd 60,360,-170,0,0,40,0,cannon skip_moddata: ;Main loop still: ; основной цикл mov eax,11 ; проверка состояния окна mcall cmp eax,1 ; окно сдвинули его нужно перерисовать je red cmp eax,2 ; нажата клавиша на клавиатуре je key cmp eax,3 ; нажата кнопка в окне je button ; delay 10 ; cmp [autorot],0 ;frize no fps show when autorot off ; je still cycle: call clrscr ; clear screen buffer call clrzbuf ; clear z-buffer call render_scene ; calculating scene call dispimg ; show buffer fps_show_frequency=0 fps 10,10,cl_White,cl_Black ;turn model on z-axis inc dword [model_mas+4*6] and dword [model_mas+4*6],011111111b ; Sin wave dynamic texture for water ; jmp ndt xor edi,edi mov dx,32 mov bp,word [sin_pos] dp_ver: mov cx,32 ;320 mov si,word [sin_pos] dp_hor: and ebp,0000ffffh mov ax,word [sinwave+ebp] add ax,cx and ax,31 and esi,0000ffffh mov bx,word [sinwave+esi] add bx,dx and bx,31 shl bx,5 add bx,ax push bx imul bx,3 and ebx,0000ffffh mov ax,[texture_limg+ebx] mov [texture_img2+edi],ax mov al,[texture_limg+ebx+2] mov [texture_img2+edi+2],al pop bx add edi,3 add si,2 and si,63;511 dec cx jnz dp_hor add bp,2 and bp,63;511 dec dx jnz dp_ver ; update sine position for next frame add word [sin_pos],2 and word [sin_pos],63;511 ;Move water texture jmp ndt mov esi,texture_limg mov ecx,32*32-1 loodt: mov al,byte [esi] mov bl,byte [esi+1] mov dl,byte [esi+2] mov ah,byte [esi+3] mov bh,byte [esi+4] mov dh,byte [esi+5] mov byte [esi],ah mov byte [esi+1],bh mov byte [esi+2],dh mov byte [esi+3],al mov byte [esi+4],bl mov byte [esi+5],dl add esi,3 dec ecx jnz loodt ndt: ;Creat mipmap pack for dynamic texture mov ebp,32 mov esi,texture_img+4095 call texgen mov eax,4 ; function 4 : write text to window mov ebx,8*65536+8 ; [x start] *65536 + [y start] mov ecx,0x0000ff00 ; font 1 & color ( 0xF0RRGGBB ) mov edx,keymap ; pointer to text beginning mov esi,100 ; text length mcall add edx,100 add ebx,10 mov esi,60 ; text length mov ecx,0x00dddddd ; font 1 & color ( 0xF0RRGGBB ) mcall mov edx,usemap mov esi,60 ; text length mov ecx,0x0000ff00 mcall jmp rx ;01234567890123456789012345678901234567890123456789 usemap db ' E wer u [] asd zxc ' db ' ' rx: cmp byte [keymap+1],0 je n_esc jmp exit n_esc: cmp byte [keymap+22],0 je n_u mov [Xangle],0 mov [Yangle],0 mov [Zangle],0 n_u: ; t,y - mipmap cntrol cmp byte [keymap+20],0 je n_t inc [mipzoom] n_t: cmp byte [keymap+21],0 je n_y dec [mipzoom] n_y: cmp byte [keymap+23],0 je n_i mov byte [keymap+23],0 ; reset key cmp [mipmapwork],1 je i_1 i_0: mov [mipmapwork],1 jmp n_i i_1: mov [mipmapwork],0 n_i: cmp byte [keymap+26],0 je n_lsk add [Xcam],1 n_lsk: cmp byte [keymap+27],0 je n_rsk sub [Xcam],1 n_rsk: cmp byte [keymap+18],0 je n_e add [Yangle],1 n_e: cmp byte [keymap+45],0 je n_x sub [Yangle],1 n_x: cmp byte [keymap+31],0 je n_s add [Xangle],1 n_s: cmp byte [keymap+32],0 je n_d sub [Xangle],1 n_d: cmp byte [keymap+44],0 je n_z add [Zangle],1 n_z: cmp byte [keymap+46],0 je n_c sub [Zangle],1 n_c: cmp byte [keymap+17],0 je n_w add [Zcam],25 ;250 n_w: cmp byte [keymap+19],0 je n_r sub [Zcam],25 ;250 n_r: cmp byte [keymap+75],0 je n_lk add [Zcamangle],1 and [Zcamangle],011111111b n_lk: cmp byte [keymap+77],0 je n_rk sub [Zcamangle],1 and [Zcamangle],011111111b n_rk: cmp byte [keymap+79],0 je n_num1 add [Xcamangle],1 and [Xcamangle],011111111b n_num1: cmp byte [keymap+81],0 je n_num3 sub [Xcamangle],1 and [Xcamangle],011111111b n_num3: cmp byte [keymap+71],0 je n_num7 add [Ycamangle],1 and [Ycamangle],011111111b n_num7: cmp byte [keymap+73],0 je n_num9 sub [Ycamangle],1 and [Ycamangle],011111111b n_num9: cmp byte [keymap+30],0 je n_a mov byte [keymap+30],0 ; reset key cmp [autorot],1 je a_1 a_0: mov [autorot],1 jmp n_a a_1: mov [autorot],0 n_a: ; for camera ; mov ebx,[Xcamangle] ; call GetSinCos ; mov [Xcamsin],eax ; mov [Xcamcos],ebx ; mov ebx,[Ycamangle] ; call GetSinCos ; mov [Ycamsin],eax ; mov [Ycamcos],ebx mov ebx,[Zcamangle] call GetSinCos mov [Zcamsin],eax mov [Zcamcos],ebx mov eax,[Zcamsin] mov ebx,[Zcamcos] ; mov ecx,[Xcamsin] ; mov edx,[Xcamcos] ; mov esi,[Ycamsin] ; mov edi,[Ycamcos] sar eax,4 sar ebx,4 ; sar ecx,4 ; sar edx,4 ; sar esi,4 ; sar edi,4 cmp byte [keymap+72],0 je n_uk sub [Xcam],eax sub [Ycam],ebx ; sub [Zcam],ecx ; sub [Ycam],edx ; sub [Xcam],esi ; add [Zcam],edi n_uk: cmp byte [keymap+80],0 je n_dk add [Xcam],eax add [Ycam],ebx ; add [Zcam],ecx ; add [Ycam],edx ; add [Xcam],esi ; sub [Zcam],edi n_dk: xor ebp,ebp move_test: cmp [Xcam],-SECTOR_SIZE/2 jnl ok1 add [Xcam],SECTOR_SIZE dec [Xmap] jmp move_test ok1: cmp [Xcam],SECTOR_SIZE/2 jng ok2 sub [Xcam],SECTOR_SIZE inc [Xmap] jmp ok1 ok2: cmp [Ycam],-SECTOR_SIZE/2 jnl ok3 add [Ycam],SECTOR_SIZE dec [Ymap] jmp ok2 ok3: cmp [Ycam],SECTOR_SIZE/2 jng ok4 sub [Ycam],SECTOR_SIZE inc [Ymap] jmp ok3 ok4: and [Xangle],011111111b and [Yangle],011111111b and [Zangle],011111111b jmp still red: ; redraw call draw_window jmp still key: ; key mov eax,2 ; just read it and ignore mcall shr eax,8 and eax,0xff mov ah,al mov ebx,0 mov bl,ah cmp bl,224 je noisa ; ignore Ext code cmp bl,170 je noisa ; ignore Key Up code cmp bl,128 ja isa mov [keymap+ebx],byte 'X' ; set press marker to key id jmp noisa isa: sub bl,128 mov [keymap+ebx],byte 0 ; reset key marker noisa: jmp n_a jmp still ; cycle button: ; button mov eax,17 ; get id mcall cmp ah,1 jz exit jmp cycle exit: or eax,-1 mcall ; ********************************************* ; ******* WINDOW DEFINITIONS AND DRAW ******** ; ********************************************* draw_window: mov eax,12 ; function 12:tell os about windowdraw mov ebx,1 ; 1, start of draw mcall ; DRAW WINDOW mov eax,0 ; function 0 : define and draw window mov ebx,0*65536+SCREEN_X-1 ; [x start] *65536 + [x size] mov ecx,0*65536+SCREEN_Y-1 ; [y start] *65536 + [y size] mov edx,0x03ffffff ; color of work area RRGGBB,8->color gl mov esi,0x005080d0 ; color of grab bar RRGGBB,8->color gl mov edi,0x005080d0 ; color of frames RRGGBB mcall ; WINDOW LABEL mov eax,4 ; function 4 : write text to window mov ebx,8*65536+8 ; [x start] *65536 + [y start] mov ecx,0x10ddeeff ; font 1 & color ( 0xF0RRGGBB ) mov edx,labelt ; pointer to text beginning mov esi,labellen-labelt ; text length mcall mov eax,12 mov ebx,2 mcall ret dispimg: mov eax,7 mov ebx,I_END ;zbuffer mov ecx,SCREEN_X*65536+SCREEN_Y xor edx,edx ;0*65536+0 mcall ; ret mov eax,8 mov ebx,(SCREEN_X-30)*65536+20 mov ecx,10*65536+20 mov edx,1 mov esi,0x0000aa00 mcall ret clrscr: ; clear screen buffer ; cld ; mov edi,I_END ; xor eax,eax ; mov ecx,SCREEN_X*SCREEN_Y*3/4 ; rep stosd ; ret ; clear screen buffer with MMX technology +1,5 fps mov edi,I_END mov ecx,SCREEN_X*SCREEN_Y*3/32 xor eax,eax movd mm0,eax movd mm1,eax movd mm2,eax movd mm3,eax csloo: movq qword [edi],mm0 movq qword [edi+8],mm1 movq qword [edi+16],mm2 movq qword [edi+24],mm3 add edi,32 dec ecx jnz csloo ret clrzbuf: ; clear zbuf cld mov edi,zbuffer mov eax,-1 mov ecx,SCREEN_X*SCREEN_Y*3/4 rep stosd ret ; mov [@@atx1],dword 0xffffffff ; mov [@@aty1],dword 0xffffffff ; movq mm0,qword [@@atx1] ; movq mm1,qword [@@atx1] ; movq mm2,qword [@@atx1] ; movq mm3,qword [@@atx1] ;czbloo: ; movq qword [edi],mm0 ; movq qword [edi+8],mm1 ; movq qword [edi+16],mm2 ; movq qword [edi+24],mm3 ; add edi,32 ; dec ecx ; jnz czbloo ret @@atx1: dd 0 @@aty1: dd 0 ;=========================================================================== ; ; 3D-system example. Use the following formulas to rotate a point: ; ; Rotate around x-axis ; Y = Y * COS(xang) - Z * SIN(xang) / 256 ; Z = Y * SIN(xang) + Z * COS(xang) / 256 ; ; Rotate around y-axis ; X = X * COS(yang) - Z * SIN(yang) / 256 ; Z = X * SIN(yang) + Z * COS(yang) / 256 ; ; Rotate around z-axis ; X = X * COS(zang) - Y * SIN(zang) / 256 ; Y = X * SIN(zang) + Y * COS(zang) / 256 ; ; Divide by 256 coz we have multiplyd our sin values with 256 too. ; This example isn't too fast right now but it'll work just fine. ; ;=========================================================================== ;*************************************************************************** ; \\\ MAIN 3D LOOP /// ; ****************** render_scene: ;******************** ; Turn matrix points ;******************** cmp [autorot],0 je no_autorot call UpdateAngles ; Calculate new angles no_autorot: call SetRotation ; Find sine & cosine of those angles mov edi,tpoints mov esi,points mov [mapoff],-1 ;-1 at start mov ebp,[Ymap] imul ebp,MAP_XSIZE+1 mov eax,[Xmap] add ebp,eax mov ecx,(MATRIX_XSIZE+1)*(MATRIX_YSIZE+1) ShowLoop: push ecx push esi mov eax,[esi] sub eax,[Xcam] mov [X],eax mov eax,[esi+4] sub eax,[Ycam] mov [Y],eax mov eax,[ebp+ground_level_map] ;color and eax,0x000000ff sub eax,[Zcam] mov [Z],eax push ebp push edi call TranslatePoint ; Rotates the point using above formulas pop edi mov [edi],ebp ;x mov [edi+4],eax ;y mov eax,[Z] ;z add eax,[Zoff] mov [edi+8],eax pop ebp pop esi pop ecx add esi,4*3 ;next in point add edi,4*3 ;next out point inc [mapoff] cmp [mapoff],MATRIX_XSIZE+1 jne no_shift_glm mov [mapoff],dword 0 add ebp,(MAP_XSIZE-MATRIX_XSIZE) no_shift_glm: add ebp,1 dec ecx jnz ShowLoop ; Show, how many polygons on screen. outcount [massize],50,10,cl_White,8*65536 ;***************** ; out triangles ;***************** mov [mapoff],-1 ;-1 at start mov [massize],0 ;restet triangle massive counter mov ebp,[Ymap] imul ebp,MAP_XSIZE;64;3*64 ;MAP_XSIZE mov eax,[Xmap] add ebp,eax mov edi,tpoints mov ecx,MATRIX_YSIZE ;64 lootpy: push ecx mov ecx,MATRIX_XSIZE ;64 lootpx: ;draw four angle (two triangles) Z_MAX = 10 ;maximal z range for triangles ; get texture offset at start inc [mapoff] cmp [mapoff],MATRIX_XSIZE jne no_shift mov [mapoff],dword 0 add ebp,(MAP_XSIZE-MATRIX_XSIZE) no_shift: xor eax,eax mov al,[ebp+img_area];+8] inc ebp imul eax,4095;32*32*3 add eax,texture_img mov ebx,eax ;first triangle mov eax,[edi+8] ;z1 cmp eax,Z_MAX jl no_add1 mov [@@tz1],eax mov eax,[edi+8+12] ;z2 cmp eax,Z_MAX jl no_add1 mov [@@tz2],eax mov eax,[edi+8+(4*3*(MATRIX_XSIZE+2))] ;z3 cmp eax,Z_MAX jl no_add1 mov [@@tz3],eax cmp dword [edi],SCREEN_X ja p11 cmp dword [edi+4],SCREEN_Y jna yes_add1 p11: cmp dword [edi+12],SCREEN_X ja p12 cmp dword [edi+4+12],SCREEN_Y jna yes_add1 p12: cmp dword [edi+(4*3*(MATRIX_XSIZE+2))],SCREEN_X ja p13 cmp dword [edi+4+(4*3*(MATRIX_XSIZE+2))],SCREEN_Y jna yes_add1 p13: jmp no_add1 yes_add1: movq mm0,qword [edi] ;x1 movq mm1,qword [edi+12] ;x2 movq mm2,qword [edi+(4*3*(MATRIX_XSIZE+2))] ;x3 movq qword [@@tx1],mm0 movq qword [@@tx2],mm1 movq qword [@@tx3],mm2 mov eax,ebx;+1 shl 31;[ebp] mov [@@tex_off],eax ;0x0000ff00 inc [massize] pushad mov [@@tex_x1],0 mov [@@tex_y1],0 mov [@@tex_x3],(32 shl 16) -1;128 mov [@@tex_y3],(32 shl 16) -1;128 mov [@@tex_x2],0 mov [@@tex_y2],(32 shl 16) -1;128 call textured_triangle popad no_add1: ;second triangle mov eax,[edi+8] ;z1 cmp eax,Z_MAX jl no_add2 mov [@@tz1],eax mov eax,[edi+8+(4*3*(MATRIX_XSIZE+1))] ;z2 cmp eax,Z_MAX jl no_add2 mov [@@tz2],eax mov eax,[edi+8+(4*3*(MATRIX_XSIZE+2))] ;z3 cmp eax,Z_MAX jl no_add2 mov [@@tz3],eax cmp dword [edi],SCREEN_X ja p21 cmp dword [edi+4],SCREEN_Y jna yes_add2 p21: cmp dword [edi+(4*3*(MATRIX_XSIZE+1))],SCREEN_X ja p22 cmp dword [edi+4+(4*3*(MATRIX_XSIZE+1))],SCREEN_Y jna yes_add2 p22: cmp dword [edi+(4*3*(MATRIX_XSIZE+2))],SCREEN_X ja p23 cmp dword [edi+4+(4*3*(MATRIX_XSIZE+2))],SCREEN_Y jna yes_add2 p23: jmp no_add2 yes_add2: movq mm0,qword [edi] ;x1 movq mm1,qword [edi+(4*3*(MATRIX_XSIZE+1))] ;x2 movq mm2,qword [edi+(4*3*(MATRIX_XSIZE+2))] ;x3 movq qword [@@tx1],mm0 movq qword [@@tx2],mm1 movq qword [@@tx3],mm2 mov eax,ebx mov [@@tex_off],eax ;0x0000ff00 inc [massize] ; add esi,4*10 pushad mov [@@tex_x1],0 mov [@@tex_y1],0 mov [@@tex_x3],(32 shl 16) -1;128 mov [@@tex_y3],(32 shl 16) -1;128 mov [@@tex_x2],(32 shl 16) -1 mov [@@tex_y2],0 call textured_triangle popad no_add2: add edi,4*3 ;next triangle dec ecx jnz lootpx add edi,4*3 ;next string pop ecx dec ecx jnz lootpy ;********************************** ;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;********************************** ; For good models quality -5% speed ; call clrzbuf jmp skip_modmas mmcnt dd 0 ;counter of model read number modeloff dd 0 ;offset of model structure modelmoff dd 0 ;offset in model mas modeltmpoff dd 0 ;tmpoints offset ; massive of models ; format: X,Y,Z coordoinats,offset to model structure skip_modmas: ; Rendering models on map mov eax,[model_mas] mov [mmcnt],eax ModelRenderLoop: mov ebx,[mmcnt] dec ebx imul ebx,4*8 add ebx,model_mas+4 mov ebp,ebx ;edi=model offset X,Y,Z,Xturn,Yturn,Zturn,zero,modeloff mov ebx,[ebp+4*3];[Xangle] ; Grab angle call GetSinCos ; Get the sine&cosine mov [Xsin],eax ; Save sin mov [Xcos],ebx ; Save cos mov ebx,[ebp+4*4];[Yangle] call GetSinCos mov [Ysin],eax mov [Ycos],ebx mov ebx,[ebp+4*5];[Zangle] call GetSinCos mov [Zsin],eax mov [Zcos],ebx mov ebx,[mmcnt] imul ebx,4*8 add ebx,model_mas+4-4 mov eax,[ebx] mov [modeloff],eax sub ebx,4*7;3 mov [modelmoff],ebx mov edi,modelpoints mov esi,eax ;bunker+8 add esi,8 mov ecx,[eax] ;[bunker] ;MODEL_POINTS TurnModelLoop: push ecx push esi mov eax,[esi] mov [X],eax mov eax,[esi+4] mov [Y],eax mov eax,[esi+8] mov [Z],eax push ebp push edi ;RotatePoint mov esi,[Y] mov ebx,[Xcos] mov edi,[Z] mov ecx,[Xsin] call math mov [Y],esi mov [Z],edi mov esi,[X] mov ebx,[Ycos] mov ecx,[Ysin] call math mov [X],esi mov [Z],edi mov ebx,[Zcos] mov edi,[Y] mov ecx,[Zsin] call math mov [X],esi mov [Y],edi pop edi mov eax,[X] mov [edi],eax mov eax,[Y] mov [edi+4],eax mov eax,[Z] ;z ; add eax,[Zoff] mov [edi+8],eax pop ebp pop esi pop ecx add esi,4*3 ;next in point add edi,4*3 ;next out point dec ecx jnz TurnModelLoop modxxx: ;Turn model off map call SetRotation mov ebx,[mmcnt] imul ebx,4*8 add ebx,model_mas+4-4 mov eax,[ebx] mov [modeloff],eax sub ebx,4*7;3 mov [modelmoff],ebx mov edi,modelpoints mov ecx,[eax] ;[bunker] ;MODEL_POINTS ShowModelLoop: push ecx mov eax,[edi] ;esi] mov ebx,[modelmoff] sub eax,[ebx] ;[Xmod] sub eax,[Xcam] mov ebx,[Xmap] imul ebx,SECTOR_SIZE sub eax,ebx mov [X],eax mov eax,[edi+4] ;esi+4] mov ebx,[modelmoff] sub eax,[ebx+4] ;[Ymod] sub eax,[Ycam] mov ebx,[Ymap] imul ebx,SECTOR_SIZE sub eax,ebx mov [Y],eax mov eax,[edi+8];esi+8] mov ebx,[modelmoff] sub eax,[ebx+8] ;[Zmod] sub eax,[Zcam] mov [Z],eax push ebp push edi call TranslatePoint ; Rotates the point using above formulas pop edi mov [edi],ebp ;x mov [edi+4],eax ;y mov eax,[Z] ;z add eax,[Zoff] mov [edi+8],eax pop ebp pop ecx add edi,4*3 ;next out point dec ecx jnz ShowModelLoop ; add [model_mas+8],dword 3 mov esi,[massize] imul esi,4*10 mov eax,[modeloff] mov ecx,[eax+4] ;MODEL_TRIANGELS ;calc tmpoints offset mov edi,modelpoints mov [modeltmpoff],edi ;calc postlink offset mov edi,[eax] imul edi,3*4;*2 ;X,Y,Z (3) points dd format (4) 2 masives (2) add edi,eax add edi,8 ;skip dd points, dd triangels msloo: mov ebx,[edi] imul ebx,4*3 add ebx,[modeltmpoff] ;tmpoints mov eax,[ebx] mov [@@tx1],eax mov eax,[ebx+4] mov [@@ty1],eax mov eax,[ebx+8] mov [@@tz1],eax mov ebx,[edi+4] imul ebx,4*3 add ebx,[modeltmpoff] ;tmpoints mov eax,[ebx] mov [@@tx2],eax mov eax,[ebx+4] mov [@@ty2],eax mov eax,[ebx+8] mov [@@tz2],eax mov ebx,[edi+8] imul ebx,4*3 add ebx,[modeltmpoff] ;tmpoints mov eax,[ebx] mov [@@tx3],eax mov eax,[ebx+4] mov [@@ty3],eax mov eax,[ebx+8] mov [@@tz3],eax cmp dword [@@tz1],Z_MAX jl no_add cmp dword [@@tz2],Z_MAX jl no_add cmp dword [@@tz3],Z_MAX jl no_add cmp dword [@@tx1],SCREEN_X ja pm1 cmp dword [@@ty1],SCREEN_Y jna yes_madd pm1: cmp dword [@@tx2],SCREEN_X ja pm2 cmp dword [@@ty2],SCREEN_Y jna yes_madd pm2: cmp dword [@@tx3],SCREEN_X ja pm3 cmp dword [@@ty3],SCREEN_Y jna yes_madd pm3: jmp no_add yes_madd: mov ebx,[edi+12] dec ebx js ttex mov eax,1 shl 31 jmp posit ttex: add ebx,2 mov eax,0 neg ebx posit: imul ebx,4095;32*32*3 add ebx,texture_img mov [@@tex_off],ebx pushad mov [@@tex_x1],0 mov [@@tex_y1],0 mov [@@tex_x3],(32 shl 16) -1;128 mov [@@tex_y3],(32 shl 16) -1;128 cmp eax,0 je nez mov [@@tex_x2],0 mov [@@tex_y2],(32 shl 16) -1 jmp isz nez: mov [@@tex_x2],(32 shl 16) -1 mov [@@tex_y2],0 isz: call textured_triangle popad ; mov [esi+8+24+4],eax ; add esi,4*10 inc [massize] no_add: add edi,4*4; *9 dec ecx jnz msloo dec [mmcnt] jnz ModelRenderLoop jmp skip_mdata bunker: dd 8 ;model points dd 10 ;model triagels ;mpoints: dd -105,-105,0, -105,105,0, 105,105,0, 105,-105,0 dd -70,-70,-50, -70,70,-50, 70,70,-50, 70,-70,-50 ; 4-------7 Points structure ; |\0---3/| ; | | | | ; | | | | ; |/1---2\| ; 5-------6 ;pointslink: ;dd 0,1,2, -3, 0,3,2, 3 ;far side dd 4,0,1, -5, 4,5,1, 5 ;left side dd 6,2,3, -5, 6,7,3, 5 ;right side dd 4,0,3, -5, 4,7,3, 5 ;up side dd 5,1,2, -5, 5,6,2, 5 ;down side dd 4,5,6, -6, 4,7,6, 6 ;far side ;model 2 outpost outpost: dd 8 ;model points dd 10 ;model triagels ;mpoints: dd -45,-45,0, -45,45,0, 45,45,0, 45,-45,0 dd -30,-30,-20, -30,30,-20, 30,30,-20, 30,-30,-20 ;pointslink: ;dd 0,1,2, -3, 0,3,2, 3 ;far side dd 4,0,1, -8, 4,5,1, 8 ;left side dd 6,2,3, -8, 6,7,3, 8 ;right side dd 4,0,3, -8, 4,7,3, 8 ;up side dd 5,1,2, -8, 5,6,2, 8 ;down side dd 4,5,6, -7, 4,7,6, 7 ;near side ;model 3 cannon cannon: dd 12 ;model points dd 12 ;model triagels ;mpoints: dd -10,-20,0, -10,20,0, 10,20,0, 10,-20,0 dd -10,-10,-15, -10,10,-15, 10,10,-15, 10,-10,-15 dd -2,15,-8, 2,15,-8, -2,45,-8, 2,45,-8 ;pointslink: ;dd 0,1,2, -3, 0,3,2, 3 ;far side dd 4,0,1, -10, 4,5,1, 10 ;left side dd 6,2,3, -10, 6,7,3, 10 ;right side dd 4,0,3, -10, 4,7,3, 10 ;up side dd 5,1,2, -10, 5,6,2, 10 ;down side dd 4,5,6, -11, 4,7,6, 11 ;near side dd 8,9,10,-10, 9,10,11,10 ;cannon 1 ;model 4 red flag red_flag: dd 12 ;model points dd 6*2 ;model triagels ;mpoints: dd -1,-1,0, -1,1,0, 1,1,0, 1,-1,0 dd -1,-1,-30, -1,1,-30, 1,1,-30, 1,-1,-30 dd 1,1,-30, 10,1,-30, 10,1,-20, 1,1,-20 ;pointslink: dd 4,0,1, -10, 4,5,1, 15 ;left side dd 6,2,3, -10, 6,7,3, 15 ;right side dd 4,0,3, -10, 4,7,3, 15 ;up side dd 5,1,2, -10, 5,6,2, 15 ;down side dd 4,5,6, -10, 4,7,6, 15 ;near side dd 8,11,10,-49, 8,9,10,49 ;flag repear: dd 8 ;model points dd 10 ;model triagels ;mpoints: dd -45,-45,0, -45,45,0, 45,45,0, 45,-45,0 dd -30,-30,-20, -30,30,-20, 30,30,-20, 30,-30,-20 ;pointslink: dd 4,0,1, -5, 4,5,1, 5 ;left side dd 6,2,3, -5, 6,7,3, 5 ;right side dd 4,0,3, -5, 4,7,3, 5 ;up side dd 5,1,2, -5, 5,6,2, 5 ;down side dd 4,5,6, -3, 4,7,6, 3 ;far side ;model 5 tree (elka) tree: dd 16 ;model points dd 8*2 ;model triagels ;mpoints: dd -2,-2,0, -2,2,0, 2,2,0, 2,-2,0 dd -1,-1,-8, -1,1,-8, 1,1,-8, 1,-1,-8 dd -10,-10,-8, -10,10,-8, 10,10,-8, 10,-10,-8 dd -1,-1,-40, -1,1,-40, 1,1,-40, 1,-1,-40 ;pointslink: dd 4,0,1, -16, 4,5,1, 16 ;left side dd 6,2,3, -16, 6,7,3, 16 ;right side dd 4,0,3, -16, 4,7,3, 16 ;up side dd 5,1,2, -16, 5,6,2, 16 ;down side dd 12,8,9, -14, 12,13,9, 14 ;left side dd 14,10,11, -14, 14,15,11, 14 ;right side dd 12,8,11, -14, 12,15,11, 14 ;up side dd 13,9,10, -14, 13,14,10, 14 ;down side ;model tank tank: dd 20 ;model points dd 12+10 ;model triagels ;mpoints: dd -10,-20,-10, -10,20,-10, 10,20,-10, 10,-20,-10 dd -10,-10,-20, -10,10,-20, 10,10,-20, 10,-10,-20 dd -2,15,-15, 2,15,-15, -2,45,-15, 2,45,-15 dd -20,-20,0, -20,20,0, 20,20,0, 20,-20,0 dd -20,-30,-10, -20,30,-10, 20,30,-10, 20,-30,-10 ;pointslink: ;dd 0,1,2, -3, 0,3,2, 3 ;far side dd 4,0,1, -10, 4,5,1, 10 ;left side dd 6,2,3, -10, 6,7,3, 10 ;right side dd 4,0,3, -10, 4,7,3, 10 ;up side dd 5,1,2, -10, 5,6,2, 10 ;down side dd 4,5,6, -11, 4,7,6, 11 ;near side dd 8,9,10,-10, 9,10,11,10 ;cannon 1 dd 16,12,13, -11, 16,17,13, 11 ;left side dd 18,14,15, -11, 18,19,15, 11 ;right side dd 16,12,15, -11, 16,19,15, 11 ;up side dd 17,13,14, -11, 17,18,14, 11 ;down side dd 16,17,18, -11, 16,19,18, 11 ;near side ;Test model gqfa: ;Good quality four angle dd 5 ;model points dd 4 ;model triagels ;mpoints: ;dd -45,-145,0, -45,145,0, 45,45,0, 45,-45,0 dd -0,-105,0, -0,105,0, 45,45,0, 45,-45,0 dd 30,0,0 ;pointslink: dd 1,4,0, 50 ;left side dd 1,4,2, 51 ;right side dd 3,4,2, -50 ;up side dd 3,4,0, -51 ;down side skip_mdata: ;*************** ; Add new models ;*************** ; jmp no_addmodel random 20,eax sub eax,10 imul eax,SECTOR_SIZE add eax,SECTOR_SIZE/2 mov [temp1],eax random 20,eax sub eax,10 imul eax,SECTOR_SIZE add eax,SECTOR_SIZE/2 mov [temp2],eax mov eax,dword [model_mas] cmp eax,40;00 jae no_addmodel imul eax,4*8; add eax,4+model_mas inc dword [model_mas] mov ebx,[temp1] mov [eax],ebx mov ebx,[temp2] mov [eax+4],ebx mov [eax+8],dword -170 mov ebx,0 mov [eax+12],ebx mov [eax+16],ebx mov [eax+20],ebx mov ebx,tree;red_flag mov [eax+28],ebx jmp skip_mdata ;use for auto filling at start no_addmodel: ret UpdateAngles: ; Calculates new x,y,z angles ; to autorotate around mov eax,[Xangle] ; Load current angles mov ebx,[Yangle] mov ecx,[Zangle] add eax,[DeltaX] ; Add velocity and eax,011111111b ; Range from 0..255 mov [Xangle],eax ; Update X add ebx,[DeltaY] ; Add velocity and ebx,011111111b ; Range from 0..255 mov [Yangle],ebx ; Update Y add ecx,[DeltaZ] ; Add velocity and ecx,011111111b ; Range from 0..255 mov [Zangle],ecx ; Update Z ret GetSinCos: ; Needed : bx=angle (0..255) ; Returns: ax=Sin bx=Cos push ebx ; Save angle (use as pointer) shl ebx,2 ; Grab a word so bx=bx*2 mov eax,[SinCos + ebx] ; Get sine pop ebx ; Restore pointer into bx push eax ; Save sine on stack add ebx,64 ; Add 64 to get cosine and ebx,11111111b ; Range from 0..255 shl ebx,2 ; *2 coz it's a word mov eax,[SinCos + ebx] ; Get cosine mov ebx,eax ; Save it bx=Cos pop eax ; Restore ax=Sin ret ; Get sin & cos of x,y,z angle SetRotation: mov ebx,[Xangle] ; Grab angle call GetSinCos ; Get the sine&cosine mov [Xsin],eax ; Save sin mov [Xcos],ebx ; Save cos mov ebx,[Yangle] call GetSinCos mov [Ysin],eax mov [Ycos],ebx mov ebx,[Zangle] call GetSinCos mov [Zsin],eax mov [Zcos],ebx ; for camera mov ebx,[Xcamangle] call GetSinCos mov [Xcamsin],eax mov [Xcamcos],ebx mov ebx,[Ycamangle] call GetSinCos mov [Ycamsin],eax mov [Ycamcos],ebx mov ebx,[Zcamangle] call GetSinCos mov [Zcamsin],eax mov [Zcamcos],ebx ret TranslatePoint: ; Rotates the point around x,y,z ; Gets original x,y,z values ; This can be done elsewhere mov esi,[X] mov edi,[Y] mov ebx,[Zcamcos] mov ecx,[Zcamsin] call math mov [X],esi mov [Y],edi mov esi,[Y] mov edi,[Z] mov ebx,[Xcamcos] mov ecx,[Xcamsin] call math mov [Y],esi mov [Z],edi mov esi,[X] mov edi,[Z] mov ebx,[Ycamcos] mov ecx,[Ycamsin] call math mov [X],esi mov [Z],edi mov esi,[Y] mov ebx,[Xcos] mov edi,[Z] mov ecx,[Xsin] call math mov [Y],esi mov [Z],edi mov esi,[X] mov ebx,[Ycos] mov ecx,[Ysin] call math mov [X],esi mov [Z],edi mov ebx,[Zcos] mov edi,[Y] mov ecx,[Zsin] call math ;************* ; ShowPoint ;************* ; Calculates screenposition and ; plots the point on the screen mov eax,[Xoff] ; Xoff*X / Z+Zoff = screen x mov ecx,esi imul ecx mov ebx,[Z] add ebx,[Zoff] ; Distance cmp ebx,0 je notout idiv ebx add eax,[Mx] ; Center on screen mov ebp,eax ;ebp =Xp mov eax,[Yoff] ; Yoff*Y / Z+Zoff = screen y mov ecx,edi imul ecx cmp ebx,0 je notout idiv ebx ;eax =Yp add eax,[My] ; Center on screen notout: ret math: mov eax,esi imul ebx ; ax = X * Cos(zang) mov ebp,eax mov eax,edi imul ecx ; ax = Y * Sin(zang) sub ebp,eax ; bp = X * Cos(zang) - Y * Sin(zang) sar ebp,8 ; bp = X * Cos(zang) - Y * Sin(zang) / 256 mov eax,esi mov esi,ebp imul ecx ; ax = X * Sin(zang) mov ebp,eax mov eax,edi imul ebx ; ax = Y * Cos(zang) add ebp,eax ; bp = X * SIN(zang) + Y * COS(zang) sar ebp,8 ; bp = X * SIN(zang) + Y * COS(zang) / 256 mov edi,ebp ret SinCos: dd 0,6,13,19,25,31,38,44,50,56 dd 62,68,74,80,86,92,98,104,109,115 dd 121,126,132,137,142,147,152,157,162,167 dd 172,177,181,185,190,194,198,202,206,209 dd 213,216,220,223,226,229,231,234,237,239 dd 241,243,245,247,248,250,251,252,253,254 dd 255,255,256,256,256,256,256,255,255,254 dd 253,252,251,250,248,247,245,243,241,239 dd 237,234,231,229,226,223,220,216,213,209 dd 206,202,198,194,190,185,181,177,172,167 dd 162,157,152,147,142,137,132,126,121,115 dd 109,104,98,92,86,80,74,68,62,56 dd 50,44,38,31,25,19,13,6,0,-6 dd -13,-19,-25,-31,-38,-44,-50,-56,-62,-68 dd -74,-80,-86,-92,-98,-104,-109,-115,-121,-126 dd -132,-137,-142,-147,-152,-157,-162,-167,-172,-177 dd -181,-185,-190,-194,-198,-202,-206,-209,-213,-216 dd -220,-223,-226,-229,-231,-234,-237,-239,-241,-243 dd -245,-247,-248,-250,-251,-252,-253,-254,-255,-255 dd -256,-256,-256,-256,-256,-255,-255,-254,-253,-252 dd -251,-250,-248,-247,-245,-243,-241,-239,-237,-234 dd -231,-229,-226,-223,-220,-216,-213,-209,-206,-202 dd -198,-194,-190,-185,-181,-177,-172,-167,-162,-157 dd -152,-147,-142,-137,-132,-126,-121,-115,-109,-104 dd -98,-92,-86,-80,-74,-68,-62,-56,-50,-44 dd -38,-31,-25,-19,-13,-6 mipzoom dd 0 mipmapwork dd 0 temp1 dd 0 temp2 dd 0 ; 4.24.2005 Textured triangle algorythm ; created by Pavlushin Evgeni waptap[at]mail.ru ; on base tex3 from Mikolaj Felix mfelix@polbox.com align 512 @@tx1 dd 0 ;equ [bp+4] @@ty1 dd 0 ;equ [bp+6] align 512 @@tx2 dd 0 ;equ [bp+8] @@ty2 dd 0 ;equ [bp+10] align 512 @@tx3 dd 0 ;equ [bp+12] @@ty3 dd 0 ;equ [bp+14] @@tz1 dd 0 @@tz2 dd 0 @@tz3 dd 0 @@z_dy12 dd 0 @@z_dy13 dd 0 @@z_dy23 dd 0 @@tex_off dd 0 ;equ [bp+16] @@tex_x1 dd 0 ;equ [bp+18] @@tex_y1 dd 0 ;equ [bp+20] @@tex_x2 dd 0 ;equ [bp+22] @@tex_y2 dd 0 ;equ [bp+24] @@tex_x3 dd 0 ;equ [bp+26] @@tex_y3 dd 0 ;equ [bp+28] @@dx12 dd 0 ;equ [bp-2] @@dx13 dd 0 ;equ [bp-4] @@dx23 dd 0 ;equ [bp-6] @@tex_dx12 dd 0 ;equ [bp-8] @@tex_dy12 dd 0 ;equ [bp-10] @@tex_dx13 dd 0 ;equ [bp-12] @@tex_dy13 dd 0 ;equ [bp-14] @@tex_dx23 dd 0 ;equ [bp-16] @@tex_dy23 dd 0 ;equ [bp-18] @@scan_x1 dd 0 @@scan_y1 dd 0 @@scan_x2 dd 0 @@scan_y2 dd 0 @@scan_z1 dd 0 @@scan_z2 dd 0 SHIFT=16 textured_triangle: mov eax,[@@ty1] cmp eax,[@@ty3] jle tt_check1 xchg eax,[@@ty3] mov [@@ty1],eax mov eax,[@@tx1] xchg eax,[@@tx3] mov [@@tx1],eax mov eax,[@@tz1] xchg eax,[@@tz3] mov [@@tz1],eax mov eax,[@@tex_y1] xchg eax,[@@tex_y3] mov [@@tex_y1],eax mov eax,[@@tex_x1] xchg eax,[@@tex_x3] mov [@@tex_x1],eax tt_check1: mov eax,[@@ty2] cmp eax,[@@ty3] jle tt_check2 xchg eax,[@@ty3] mov [@@ty2],eax mov eax,[@@tx2] xchg eax,[@@tx3] mov [@@tx2],eax mov eax,[@@tz2] xchg eax,[@@tz3] mov [@@tz2],eax mov eax,[@@tex_y2] xchg eax,[@@tex_y3] mov [@@tex_y2],eax mov eax,[@@tex_x2] xchg eax,[@@tex_x3] mov [@@tex_x2],eax tt_check2: mov eax,[@@ty1] cmp eax,[@@ty2] jle tt_check3 xchg eax,[@@ty2] mov [@@ty1],eax mov eax,[@@tx1] xchg eax,[@@tx2] mov [@@tx1],eax mov eax,[@@tz1] xchg eax,[@@tz2] mov [@@tz1],eax mov eax,[@@tex_y1] xchg eax,[@@tex_y2] mov [@@tex_y1],eax mov eax,[@@tex_x1] xchg eax,[@@tex_x2] mov [@@tex_x1],eax tt_check3: mov ebx,[@@ty2] sub ebx,[@@ty1] jnz tt_dx12_make mov [@@dx12],0 mov [@@tex_dx12],0 mov [@@tex_dy12],0 mov [@@z_dy12],0 jmp tt_dx12_done tt_dx12_make: mov eax,[@@tx2] sub eax,[@@tx1] shl eax,SHIFT cdq idiv ebx mov [@@dx12],eax ; dx12 = (x2-x1)/(y2-y1) mov eax,[@@tex_x2] sub eax,[@@tex_x1] cdq idiv ebx mov [@@tex_dx12],eax ; tex_dx12 = (tex_x2-tex_x1)/(y2-y1) mov eax,[@@tex_y2] sub eax,[@@tex_y1] cdq idiv ebx mov [@@tex_dy12],eax ; tex_dy12 = (tex_y2-tex_y1)/(y2-y1) mov eax,[@@tz2] sub eax,[@@tz1] shl eax,SHIFT cdq idiv ebx mov [@@z_dy12],eax tt_dx12_done: mov ebx,[@@ty3] sub ebx,[@@ty1] jnz tt_dx13_make mov [@@dx13],0 mov [@@tex_dx13],0 mov [@@tex_dy13],0 mov [@@z_dy13],0 jmp tt_dx13_done tt_dx13_make: mov eax,[@@tx3] sub eax,[@@tx1] shl eax,SHIFT cdq idiv ebx mov [@@dx13],eax ; dx13 = (x3-x1)/(y3-y1) mov eax,[@@tex_x3] sub eax,[@@tex_x1] cdq idiv ebx mov [@@tex_dx13],eax ; tex_dx13 = (tex_x3-tex_x1)/(y3-y1) mov eax,[@@tex_y3] sub eax,[@@tex_y1] cdq idiv ebx mov [@@tex_dy13],eax ; tex_dy13 = (tex_y3-tex_x1)/(y3-y1) mov eax,[@@tz3] sub eax,[@@tz1] shl eax,SHIFT cdq idiv ebx mov [@@z_dy13],eax tt_dx13_done: mov ebx,[@@ty3] sub ebx,[@@ty2] jnz tt_dx23_make mov [@@dx23],0 mov [@@tex_dx23],0 mov [@@tex_dy23],0 mov [@@z_dy23],0 jmp tt_dx23_done tt_dx23_make: mov eax,[@@tx3] sub eax,[@@tx2] shl eax,SHIFT cdq idiv ebx mov [@@dx23],eax ; dx23 = (x3-x2)/(y3-y2) mov eax,[@@tex_x3] sub eax,[@@tex_x2] cdq idiv ebx mov [@@tex_dx23],eax ; tex_dx23 = (tex_x3-tex_x2)/(y3-y2) mov eax,[@@tex_y3] sub eax,[@@tex_y2] cdq idiv ebx mov [@@tex_dy23],eax ; tex_dy23 = (tex_y3-tex_y2)/(y3-y2) mov eax,[@@tz3] sub eax,[@@tz2] shl eax,SHIFT cdq idiv ebx mov [@@z_dy23],eax tt_dx23_done: mov eax,[@@tx1] shl eax,SHIFT mov ebx,eax mov ecx,[@@ty1] mov edx,[@@tz1] shl edx,SHIFT mov [@@scan_z1],edx mov [@@scan_z2],edx mov edx,[@@tex_x1] mov [@@scan_x1],edx mov [@@scan_x2],edx mov edx,[@@tex_y1] mov [@@scan_y1],edx mov [@@scan_y2],edx ; **************** mov edx,[@@ty1] ;skip equals cmp [@@ty2],edx je tt_loop1_end mov ebp,[@@ty1] cmp ebp,0 jg no_up_clip neg ebp mov edx,[@@ty2] cmp edx,0 jg no_sbx neg edx sub ebp,edx no_sbx: mov edx,[@@tex_dx13] imul edx,ebp add [@@scan_x1],edx mov edx,[@@tex_dx12] imul edx,ebp add [@@scan_x2],edx mov edx,[@@tex_dy13] imul edx,ebp add [@@scan_y1],edx mov edx,[@@tex_dy12] imul edx,ebp add [@@scan_y2],edx mov edx,[@@z_dy13] imul edx,ebp add [@@scan_z1],edx mov edx,[@@z_dy12] imul edx,ebp add [@@scan_z2],edx mov edx,[@@dx13] imul edx,ebp add eax,edx mov edx,[@@dx12] imul edx,ebp add ebx,edx add ecx,ebp no_up_clip: cmp [@@ty2],0 jl tt_loop1_end tt_loop1: cmp ecx,SCREEN_Y jge tt_loop2_end pushad mov edx,[@@scan_y2] mov [@@tex_ly2],edx ;push dx mov edx,[@@scan_x2] mov [@@tex_lx2],edx ;push dx mov edx,[@@scan_y1] mov [@@tex_ly1],edx ;push dx mov edx,[@@scan_x1] mov [@@tex_lx1],edx ;push dx mov edx,[@@scan_z1] mov [@@lz1],edx mov edx,[@@scan_z2] mov [@@lz2],edx mov [@@ly],ecx ;push cx mov edx,ebx sar edx,SHIFT mov [@@lx2],edx ;push dx mov edx,eax sar edx,SHIFT mov [@@lx1],edx ; push dx call textured_horizontal_line popad mov edx,[@@tex_dx13] add [@@scan_x1],edx mov edx,[@@tex_dx12] add [@@scan_x2],edx mov edx,[@@tex_dy13] add [@@scan_y1],edx mov edx,[@@tex_dy12] add [@@scan_y2],edx mov edx,[@@z_dy13] add [@@scan_z1],edx mov edx,[@@z_dy12] add [@@scan_z2],edx add eax,[@@dx13] add ebx,[@@dx12] inc ecx cmp ecx,[@@ty2] jl tt_loop1 tt_loop1_end: mov ebx,[@@tx2] shl ebx,SHIFT mov ecx,[@@ty2] mov edx,[@@tz2] shl edx,SHIFT mov [@@scan_z2],edx mov edx,[@@tex_x2] mov [@@scan_x2],edx mov edx,[@@tex_y2] mov [@@scan_y2],edx mov ebp,[@@ty2] cmp ebp,0 jg no_down_clip neg ebp dec ebp mov edx,[@@tex_dx13] imul edx,ebp add [@@scan_x1],edx mov edx,[@@tex_dx23] imul edx,ebp add [@@scan_x2],edx mov edx,[@@tex_dy13] imul edx,ebp add [@@scan_y1],edx mov edx,[@@tex_dy23] imul edx,ebp add [@@scan_y2],edx mov edx,[@@z_dy13] imul edx,ebp add [@@scan_z1],edx mov edx,[@@z_dy23] imul edx,ebp add [@@scan_z2],edx mov edx,[@@dx13] imul edx,ebp add eax,edx mov edx,[@@dx23] imul edx,ebp add ebx,edx add ecx,ebp no_down_clip: tt_loop2: cmp ecx,SCREEN_Y jge tt_loop2_end pushad mov edx,[@@scan_y2] mov [@@tex_ly2],edx ;push dx mov edx,[@@scan_x2] mov [@@tex_lx2],edx ;push dx mov edx,[@@scan_y1] mov [@@tex_ly1],edx ;push dx mov edx,[@@scan_x1] mov [@@tex_lx1],edx ;push dx mov edx,[@@scan_z1] mov [@@lz1],edx mov edx,[@@scan_z2] mov [@@lz2],edx mov [@@ly],ecx ;push cx mov edx,ebx sar edx,SHIFT mov [@@lx2],edx ;push dx mov edx,eax sar edx,SHIFT mov [@@lx1],edx ; push dx call textured_horizontal_line popad mov edx,[@@tex_dx13] add [@@scan_x1],edx mov edx,[@@tex_dx23] add [@@scan_x2],edx mov edx,[@@tex_dy13] add [@@scan_y1],edx mov edx,[@@tex_dy23] add [@@scan_y2],edx mov edx,[@@z_dy13] add [@@scan_z1],edx mov edx,[@@z_dy23] add [@@scan_z2],edx add eax,[@@dx13] add ebx,[@@dx23] inc ecx cmp ecx,[@@ty3] jl tt_loop2 tt_loop2_end: ret align 512 @@lx1 dd 0 align 512 @@lx2 dd 0 align 512 @@ly dd 0 @@lz1 dd 0 @@lz2 dd 0 @@z_dx dd 0 align 512 @@tex_loff dd 0 ;equ [bp+10] @@tex_lx1 dd 0 ;equ [bp+12] @@tex_ly1 dd 0 ;equ [bp+14] @@tex_lx2 dd 0 ;equ [bp+16] @@tex_ly2 dd 0 ;equ [bp+18] align 512 @@tex_ldx dd 0 ;equ [bp-2] @@tex_ldy dd 0 ;equ [bp-4] align 1024 textured_horizontal_line: mov eax,[@@lx1] cmp eax,[@@lx2] je thl_quit jl thl_ok xchg eax,[@@lx2] mov [@@lx1],eax mov eax,[@@lz1] xchg eax,[@@lz2] mov [@@lz1],eax mov eax,[@@tex_lx1] xchg eax,[@@tex_lx2] mov [@@tex_lx1],eax mov eax,[@@tex_ly1] xchg eax,[@@tex_ly2] mov [@@tex_ly1],eax thl_ok: cmp [@@lx2],0 jle thl_quit mov eax,SCREEN_X cmp [@@lx1],eax jge thl_quit mov ecx,[@@lx2] sub ecx,[@@lx1] ; Uneversal method mov edi,[@@ly] mov eax,SCREEN_X ;di = ly*320+lx1 imul edi add eax,[@@lx1] imul eax,3 mov edi,eax add edi,I_END ;Right side clipping mov eax,SCREEN_X cmp [@@lx2],eax jnge x1ok mov edx,SCREEN_X dec edx sub edx,[@@lx1] cmp edx,0 jle thl_quit mov ecx,edx x1ok: ;Left side clipping cmp [@@lx1],0 jg x2ok mov ecx,[@@lx2] ;cmp lx2 screen x if above cut (for future) mov edi,[@@ly] mov eax,SCREEN_X imul edi,eax imul edi,3 add edi,I_END x2ok: mov ebx,[@@lx2] sub ebx,[@@lx1] mov eax,[@@tex_lx2] sub eax,[@@tex_lx1] cdq idiv ebx mov [@@tex_ldx],eax ; tex_dx = (tex_x2-tex_x1)/(x2-x1) mov eax,[@@tex_ly2] sub eax,[@@tex_ly1] cdq idiv ebx mov [@@tex_ldy],eax ; tex_dy = (tex_y2-tex_y1)/(x2-x1) mov eax,[@@lz2] sub eax,[@@lz1] cdq idiv ebx mov [@@z_dx],eax ; tex_dx = (tex_x2-tex_x1)/(x2-x1) ; Left clipping post correction cmp [@@lx1],0 jg no_lcpc mov eax,[@@lx1] neg eax mov ebp,[@@tex_ldx] imul ebp,eax add [@@tex_lx1],ebp mov ebp,[@@tex_ldy] imul ebp,eax add [@@tex_ly1],ebp mov ebp,[@@z_dx] imul ebp,eax add [@@lz1],ebp no_lcpc: inc ecx ;for equal correction mov edx,[@@tex_lx1] mov ebx,[@@tex_ly1] mov esi,[@@lz1] thl_loop: mov ebp,esi shr ebp,SHIFT mov eax,dword [edi-I_END+zbuffer] cmp ax,bp jb no_set mov [edi-I_END+zbuffer],bp mov eax,edx ; and eax,0x0fff0000 ror ebx,16 mov ax,bx ror ebx,16 shl ax,11 ; 8 for 256*256, 9 for 128*128 ... shr eax,11 lea eax,[eax*2+eax] ; equ imul eax,3 add eax,[@@tex_off] mov ebp,eax mov ax,word [ebp] mov [edi],ax mov al,byte [ebp+2] mov [edi+2],al no_set: add edi,3 add esi,[@@z_dx] add edx,[@@tex_ldx] add ebx,[@@tex_ldy] dec ecx jnz thl_loop thl_quit: ret @@rgb dd 0 @@rgbax dw 0 @@rgbbl db 0 ; === DATA === d_angle dd 0.19634954 ;pi/16 angle dd 0.0 mul_wave dd 1.5 sin_pos dw 0 sinwave rw 256 Xmap dd 0 Ymap dd 0 mapoff dd 0 Xcam dd 0 Ycam dd 0 Zcam dd -400 Xcamangle dd 0 Ycamangle dd 0 Zcamangle dd 0 Xcamsin dd 0 Xcamcos dd 0 Ycamsin dd 0 Ycamcos dd 0 Zcamsin dd 0 Zcamcos dd 0 X dd ? ; X,Y,Z variable for formula Y dd ? Z dd ? Xp dd ? Yp dd ? Xangle dd 0 ; Angle to rotate around x Yangle dd 0 Zangle dd 0 DeltaX dd 1 ; x,y,z rotation angle DeltaY dd 1 DeltaZ dd 1 Xoff dd 256 ; x-cord Yoff dd 256 ; y-cord Zoff dd 0;800 ; Distance from viewer Xsin dd ? ; Sine and cosine of angle to rotate around Xcos dd ? Ysin dd ? Ycos dd ? Zsin dd ? Zcos dd ? Mx dd SCREEN_X/2 ; Center of the screen My dd SCREEN_Y/2 autorot db 0 ;Auto rotation flag massize dd 0 ;Size of triangle massive id dd 0 temp dd 0 ; DATA AREA labelt: db '3D TEXTURED ENGINE' labellen: ;Texture pusck 32*32 256 texpack_gif: file 'texpack.gif' rb 50 ;Ground texture bmp_texmap: file 'texmap.bmp' rb 50 ; Ground livel map gif_file_area5: file 'map.gif' ;level map rb 50 rb 8 texture_limg: rb 4095 texture_img: rb 4095 texture_img2: rb 4095 rb (4095)*16*16 img_area: rb 128*128*3+8 glm_img_area: rb (MAP_XSIZE+1)*(MAP_YSIZE+1)*3+8 rb 8 texpack_img: rb 512*512*3+8 keymap: rb 1000 model_mas: rb 4+8*100 ; Hash area for decoding GIF gif_hash_area: rd 4096+1 MAX_MODEL_POINTS = 100 modelpoints: rb MAX_MODEL_POINTS*3*4 ; Matrix points massive points: ; Massive of turn matrix points tpoints=points+((MATRIX_XSIZE+1)*(MATRIX_YSIZE+1)*3*4) ; Ground level map massive ground_level_map=tpoints+((MATRIX_XSIZE+1)*(MATRIX_YSIZE+1)*3*4) ; zbuffer zbuffer=ground_level_map+((MAP_XSIZE+1)*(MAP_YSIZE+1)*4) I_END=zbuffer+(SCREEN_X*SCREEN_Y)*3