; Moving cube geometry shares the existing 320x240 logical game canvas. .data cubeCorners3D dd -32768,-32768,-32768, 32768,-32768,-32768 dd 32768,32768,-32768, -32768,32768,-32768 dd -32768,-32768,32768, 32768,-32768,32768 dd 32768,32768,32768, -32768,32768,32768 cubeFaces3D db 0,1,2,3, 4,7,6,5, 0,3,7,4 db 1,5,6,2, 0,4,5,1, 3,2,6,7 cubeTop3D dd 3,1,1,1,1,3 cubeRight3D dd 2,3,2,2,3,2 cubeColors3D dd 00FAF1DFh,00C9C1B0h,00D1C5AEh dd 00DFD3BDh,00FFF9EAh,00B5AA98h cubePips3D dd 32768,32768, 16384,16384, 49152,49152 dd 49152,16384, 16384,49152, 16384,32768, 49152,32768 cubeX3D dd 0 cubeY3D dd 0 cubeScale3D dd 36 cubeSinX3D dd 0 cubeCosX3D dd 65536 cubeSinY3D dd 0 cubeCosY3D dd 65536 cubeSinZ3D dd 0 cubeCosZ3D dd 65536 cubeVertices3D dd 16 dup(0) cubeFaceValues3D dd 6 dup(0) cubeQuad3D dd 8 dup(0) .code ; Fill clockwise triangles. Edges are incremented per pixel, avoiding divisions. DrawTriangle3D PROC uses ebx esi edi x1:DWORD,y1:DWORD,x2:DWORD,y2:DWORD,x3:DWORD,y3:DWORD,tint:DWORD local lowX:DWORD,highX:DWORD,lowY:DWORD,highY:DWORD local dx0:DWORD,dy0:DWORD,dx1:DWORD,dy1:DWORD,dx2:DWORD,dy2:DWORD local row0:DWORD,row1:DWORD,row2:DWORD,e0:DWORD,e1:DWORD,e2:DWORD local py:DWORD,px:DWORD mov eax, x2 sub eax, x1 mov dx0, eax mov edx, y2 sub edx, y1 mov dy0, edx mov ebx, x3 sub ebx, x1 imul ebx, edx mov ecx, y3 sub ecx, y1 imul eax, ecx sub eax, ebx cmp eax, 0 jle triangle_done mov eax, x3 sub eax, x2 mov dx1, eax mov eax, y3 sub eax, y2 mov dy1, eax mov eax, x1 sub eax, x3 mov dx2, eax mov eax, y1 sub eax, y3 mov dy2, eax mov eax, x1 mov ebx, eax cmp eax, x2 jle @F mov eax, x2 @@: cmp eax, x3 jle @F mov eax, x3 @@: cmp eax, 0 jge @F xor eax, eax @@: mov lowX, eax cmp ebx, x2 jge @F mov ebx, x2 @@: cmp ebx, x3 jge @F mov ebx, x3 @@: cmp ebx, 319 jle @F mov ebx, 319 @@: mov highX, ebx mov eax, y1 mov ebx, eax cmp eax, y2 jle @F mov eax, y2 @@: cmp eax, y3 jle @F mov eax, y3 @@: cmp eax, 0 jge @F xor eax, eax @@: mov lowY, eax cmp ebx, y2 jge @F mov ebx, y2 @@: cmp ebx, y3 jge @F mov ebx, y3 @@: cmp ebx, 239 jle @F mov ebx, 239 @@: mov highY, ebx mov eax, lowY sub eax, y1 imul eax, dx0 mov edx, lowX sub edx, x1 imul edx, dy0 sub eax, edx mov row0, eax mov eax, lowY sub eax, y2 imul eax, dx1 mov edx, lowX sub edx, x2 imul edx, dy1 sub eax, edx mov row1, eax mov eax, lowY sub eax, y3 imul eax, dx2 mov edx, lowX sub edx, x3 imul edx, dy2 sub eax, edx mov row2, eax mov eax, lowY mov py, eax triangle_row: mov eax, py cmp eax, highY jg triangle_done mov eax, row0 mov e0, eax mov eax, row1 mov e1, eax mov eax, row2 mov e2, eax mov eax, lowX mov px, eax triangle_pixel: mov eax, px cmp eax, highX jg triangle_next_row mov eax, e0 or eax, e1 or eax, e2 js triangle_next_pixel mov edi, py imul edi, SCREEN_W * 2 mov eax, px shl eax, 1 add edi, eax mov eax, tint mov screenBuffer[edi*4], eax mov screenBuffer[edi*4+4], eax mov screenBuffer[edi*4+SCREEN_W*4], eax mov screenBuffer[edi*4+SCREEN_W*4+4], eax triangle_next_pixel: mov eax, dy0 sub e0, eax mov eax, dy1 sub e1, eax mov eax, dy2 sub e2, eax inc px jmp triangle_pixel triangle_next_row: mov eax, dx0 add row0, eax mov eax, dx1 add row1, eax mov eax, dx2 add row2, eax inc py jmp triangle_row triangle_done: ret DrawTriangle3D ENDP ; Local 16.16 coordinates -> yaw, pitch, roll -> screen coordinates. ProjectCubePoint3D PROC uses ebx esi edi nx:DWORD,ny:DWORD,nz:DWORD local rx:DWORD,ry:DWORD,rz:DWORD mov eax, nx imul cubeCosY3D shrd eax, edx, 16 mov ebx, eax mov eax, nz imul cubeSinY3D shrd eax, edx, 16 add eax, ebx mov rx, eax mov eax, nz imul cubeCosY3D shrd eax, edx, 16 mov ebx, eax mov eax, nx imul cubeSinY3D shrd eax, edx, 16 sub ebx, eax mov rz, ebx mov eax, ny imul cubeCosX3D shrd eax, edx, 16 mov ebx, eax mov eax, rz imul cubeSinX3D shrd eax, edx, 16 sub ebx, eax mov ry, ebx mov eax, rx imul cubeCosZ3D shrd eax, edx, 16 mov ebx, eax mov eax, ry imul cubeSinZ3D shrd eax, edx, 16 sub ebx, eax imul ebx, cubeScale3D sar ebx, 16 add ebx, cubeX3D mov eax, rx imul cubeSinZ3D shrd eax, edx, 16 mov esi, eax mov eax, ry imul cubeCosZ3D shrd eax, edx, 16 add eax, esi imul eax, cubeScale3D sar eax, 16 add eax, cubeY3D mov edx, eax mov eax, ebx ret ProjectCubePoint3D ENDP DrawCubePip3D PROC uses ebx esi u:DWORD,v:DWORD,pipRadius:DWORD mov eax, cubeQuad3D[8] sub eax, cubeQuad3D imul u shrd eax, edx, 16 mov ebx, eax mov eax, cubeQuad3D[24] sub eax, cubeQuad3D imul v shrd eax, edx, 16 add ebx, eax add ebx, cubeQuad3D mov eax, cubeQuad3D[12] sub eax, cubeQuad3D[4] imul u shrd eax, edx, 16 mov esi, eax mov eax, cubeQuad3D[28] sub eax, cubeQuad3D[4] imul v shrd eax, edx, 16 add esi, eax add esi, cubeQuad3D[4] invoke DrawCircle, ebx, esi, pipRadius, 00A31D25h ret DrawCubePip3D ENDP DrawTumblingDie3D PROC uses ebx esi edi centerX:DWORD,centerY:DWORD,pitch:DWORD,yaw:DWORD,roll:DWORD,value:DWORD local face:DWORD,pip:DWORD,pipRadius:DWORD,area:DWORD mov eax, centerX mov cubeX3D, eax mov eax, centerY mov cubeY3D, eax mov eax, pitch and eax, 511 mov edx, tableSin[eax*4] mov cubeSinX3D, edx mov edx, tableCos[eax*4] mov cubeCosX3D, edx mov eax, yaw and eax, 511 mov edx, tableSin[eax*4] mov cubeSinY3D, edx mov edx, tableCos[eax*4] mov cubeCosY3D, edx mov eax, roll and eax, 511 mov edx, tableSin[eax*4] mov cubeSinZ3D, edx mov edx, tableCos[eax*4] mov cubeCosZ3D, edx mov eax, value mov cubeFaceValues3D, eax mov edx, 7 sub edx, eax mov cubeFaceValues3D[4], edx dec eax mov edx, cubeRight3D[eax*4] mov cubeFaceValues3D[12], edx mov ecx, 7 sub ecx, edx mov cubeFaceValues3D[8], ecx mov edx, cubeTop3D[eax*4] mov cubeFaceValues3D[16], edx mov ecx, 7 sub ecx, edx mov cubeFaceValues3D[20], ecx xor esi, esi cube_project_loop: imul edi, esi, 12 invoke ProjectCubePoint3D, cubeCorners3D[edi], cubeCorners3D[edi+4], cubeCorners3D[edi+8] mov cubeVertices3D[esi*8], eax mov cubeVertices3D[esi*8+4], edx inc esi cmp esi, 8 jb cube_project_loop mov face, 0 cube_face_loop: mov esi, face xor edi, edi cube_load_quad: movzx eax, cubeFaces3D[esi*4+edi] mov ebx, cubeVertices3D[eax*8] mov cubeQuad3D[edi*8], ebx mov ebx, cubeVertices3D[eax*8+4] mov cubeQuad3D[edi*8+4], ebx inc edi cmp edi, 4 jb cube_load_quad mov eax, cubeQuad3D[8] sub eax, cubeQuad3D mov edx, cubeQuad3D[28] sub edx, cubeQuad3D[4] imul eax, edx mov ebx, cubeQuad3D[24] sub ebx, cubeQuad3D mov edx, cubeQuad3D[12] sub edx, cubeQuad3D[4] imul ebx, edx sub eax, ebx mov area, eax cmp eax, 0 jle cube_next_face mov ebx, cubeColors3D[esi*4] invoke DrawTriangle3D, cubeQuad3D, cubeQuad3D[4], cubeQuad3D[8], cubeQuad3D[12], cubeQuad3D[16], cubeQuad3D[20], ebx invoke DrawTriangle3D, cubeQuad3D, cubeQuad3D[4], cubeQuad3D[16], cubeQuad3D[20], cubeQuad3D[24], cubeQuad3D[28], ebx cmp area, 70 jl cube_next_face mov pipRadius, 1 cmp area, 450 jl @F mov pipRadius, 2 @@: mov ebx, cubeFaceValues3D[esi*4] test ebx, 1 jz cube_corner_pips invoke DrawCubePip3D, 32768, 32768, pipRadius cube_corner_pips: cmp ebx, 2 jl cube_next_face invoke DrawCubePip3D, 16384, 16384, pipRadius invoke DrawCubePip3D, 49152, 49152, pipRadius cmp ebx, 4 jl cube_next_face invoke DrawCubePip3D, 49152, 16384, pipRadius invoke DrawCubePip3D, 16384, 49152, pipRadius cmp ebx, 6 jl cube_next_face invoke DrawCubePip3D, 16384, 32768, pipRadius invoke DrawCubePip3D, 49152, 32768, pipRadius cube_next_face: inc face cmp face, 6 jb cube_face_loop ret DrawTumblingDie3D ENDP RenderDiceThrow3D PROC uses ebx esi edi local t:DWORD,ground:DWORD,lift:DWORD,pitch:DWORD,yaw:DWORD,roll:DWORD local cx1:DWORD,cx2:DWORD,cy:DWORD mov t, 1600 cmp dice3d_state, 1 jne throw_pose mov eax, dice3d_timer mov t, eax throw_pose: mov eax, t imul eax, 59 xor edx, edx mov ecx, 1600 div ecx mov ebx, 155 sub ebx, eax mov ground, ebx mov lift, 0 mov eax, t cmp eax, 500 jae throw_bounce2 mov edx, 500 sub edx, eax imul eax, edx imul eax, 160 xor edx, edx mov ecx, 250000 div ecx mov lift, eax jmp throw_position throw_bounce2: cmp eax, 950 jae throw_bounce3 sub eax, 500 mov edx, 450 sub edx, eax imul eax, edx imul eax, 56 xor edx, edx mov ecx, 202500 div ecx mov lift, eax jmp throw_position throw_bounce3: cmp eax, 1300 jae throw_position sub eax, 950 mov edx, 350 sub edx, eax imul eax, edx imul eax, 24 xor edx, edx mov ecx, 122500 div ecx mov lift, eax throw_position: mov eax, ground sub eax, lift mov cy, eax mov eax, t imul eax, 12 xor edx, edx mov ecx, 1600 div ecx mov ebx, 146 sub ebx, eax mov cx1, ebx add eax, 174 mov cx2, eax mov eax, 1600 sub eax, t mov esi, eax imul eax, 3 shr eax, 2 add eax, 40 mov pitch, eax mov eax, esi imul eax, 3 xor edx, edx mov ecx, 5 div ecx add eax, 44 mov yaw, eax mov eax, esi imul eax, esi shl eax, 1 xor edx, edx mov ecx, 1600 div ecx mov roll, eax mov eax, cx1 sub eax, 16 mov edx, ground add edx, 18 invoke DrawBox, eax, edx, 33, 3, 00082011h mov eax, cx2 sub eax, 16 mov edx, ground add edx, 18 invoke DrawBox, eax, edx, 33, 3, 00082011h invoke DrawTumblingDie3D, cx1, cy, pitch, yaw, roll, dice3d_val1 mov eax, roll neg eax mov edx, cy cmp dice3d_state, 1 jne @F sub edx, 3 @@: invoke DrawTumblingDie3D, cx2, edx, pitch, yaw, eax, dice3d_val2 ret RenderDiceThrow3D ENDP