Главная »
Асм » Трехмерный вращающийся куб в DosBox
§ DosBox
Красиво этот кубик работает только в DosBOX, где можно отрегулировать скорость вращения путем уменьшения или увеличения циклов.

§ Алгоритм
Фрейм
- Рисование треугольника
- Копирование фрейма в видеопамять
- Удаление треугольника
- Добавление вращений по осям
Куб
- Считывание и рисование 6 граней
Грань
- Получение номера 4 точек
- Получение (x,y,z) точек и выполнение вращения
- Проекция (x,y,z) -> (px,py)
- Проверка на фронтальную сторону грани
- Рисование 4 линии
§ Код на FASM
org 100h
call scr13
call clear
cycle: mov [box.cl], byte 10
call drawcube
call copyscr
mov [box.cl], byte 0
call drawcube
add word [box.rx], 1
add word [box.ry], 2
add word [box.rz], 1
jmp cycle
drawcube:
mov si, a_face
.next: mov cx, 4
mov di, point
@@: lodsb
call proj
mov [di+0], ax
mov [di+2], bx
add di, 4
loop @b
mov di, point.a
mov ax, [di+4+2]
sub ax, [di+0+2]
mov bx, [di+8+0]
sub bx, [di+0+0]
imul bx, ax
mov ax, [di+4+0]
sub ax, [di+0+0]
mov cx, [di+8+2]
sub cx, [di+0+2]
imul ax, cx
cmp bx, ax
jle .skip
push si
mov si, point.a
mov di, point.b
.rpt: mov ax, [si+0]
mov bx, [si+2]
mov cx, [di+0]
mov dx, [di+2]
mov bp, [box.cl]
call line
add si, 4
add di, 4
cmp si, point.d + 4
je .end
cmp si, point.d
jne .rpt
mov di, point.a
jmp .rpt
.end: pop si
.skip: cmp si, a_face + (4*6)
jne .next
ret
proj: push cx
movzx ebx, al
movsx ecx, byte [a_vtx + 3*ebx + 2]
movsx eax, byte [a_vtx + 3*ebx + 1]
movsx ebx, byte [a_vtx + 3*ebx + 0]
shl ax, 8
shl bx, 8
shl cx, 8
xchg eax, ecx
mov dx, [box.ry]
call rotate
xchg eax, ecx
mov dx, [box.rz]
call rotate
xchg ebx, ecx
mov dx, [box.rx]
call rotate
xchg ebx, ecx
add ebx, [cam.x]
add eax, [cam.y]
add ecx, [cam.z]
imul eax, 200
imul ebx, 200
cdq
idiv ecx
xchg eax, ebx
cdq
idiv ecx
add ax, 160
sub bx, 100
neg bx
pop cx
ret
rotate: mov [.x], ax
mov [.y], bx
mov [.r], dx
fild word [.r]
fld dword [.f360]
fdivp st1,st0
fsincos
fild word [.y]
fild word [.x]
fmul st0,st2
fxch st1
fmul st0,st3
fsubp st1,st0
fistp dword [.t]
mov eax, [.t]
fild word [.x]
fild word [.y]
fmulp st2,st0
fmulp st2,st0
faddp st1,st0
fistp dword [.t]
mov ebx, [.t]
ret
.f360: dd 100.0
.x: dw 0
.y: dw 0
.t: dd 0
.r: dw 0
scr13: mov ax, 0013h
int 10h
ret
loadvb: mov ax, cs
add ax, 1000h
mov es, ax
ret
clear: call loadvb
xor di, di
xor eax, eax
mov cx, 16000
rep stosd
ret
copyscr:
push ds es
xor si, si
xor di, di
call loadvb
push es
mov ax, $A000
mov es, ax
pop ds
mov cx, 16000
rep movsd
pop es ds
ret
line: push si di
mov si, 1
mov di, 1
mov [.x2], cx
mov [.y2], dx
sub cx, ax
jge @f
neg cx
neg si
@@: sub dx, bx
jge @f
neg dx
neg di
@@: mov [.sx], si
mov [.sy], di
mov [.dx], cx
mov [.dy], dx
mov si, cx
sub si, dx
mov dx, bp
.ps: cmp ax, 320
jnb @f
cmp bx, 200
jnb @f
imul di, bx, 320
add di, ax
mov [es: di], dl
@@: cmp ax, [.x2]
jne @f
cmp bx, [.y2]
jne @f
pop di si
ret
@@: mov cx, si
add cx, cx
cmp cx, [.dx]
jg @f
add si, [.dx]
add bx, [.sy]
@@: add cx, [.dy]
jle .ps
sub si, [.dy]
add ax, [.sx]
jmp .ps
.sx: dw 0
.sy: dw 0
.dx: dw 0
.dy: dw 0
.x2: dw 0
.y2: dw 0
box:
.cl: db 14
.rx: dw 0
.ry: dw 0
.rz: dw 0
a_vtx: db -1, 1, 1
db 1, 1, 1
db 1,-1, 1
db -1,-1, 1
db -1, 1,-1
db 1, 1,-1
db 1,-1,-1
db -1,-1,-1
a_face: db 0,1,2,3
db 1,5,6,2
db 5,4,7,6
db 4,0,3,7
db 6,7,3,2
db 4,5,1,0
cam:
.x: dd 0
.y: dd 0
.z: dd 1200
point:
.a: dw ?, ?
.b: dw ?, ?
.c: dw ?, ?
.d: dw ?, ?