www.pudn.com > ctm.zip > CTM.ASM
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
;
; Totally Crap Linear Texture Mapping Routines !!!
;
; by Mandrill (mpersano@yahoo.com) - send me an E-Mail now !!!
;
; warning: the code below sucks very much, and i know it. actually
; the whole thing was done at my workplace, while my boss was looking
; the other way - thank god i no longer work there ... it really looks
; like shit because of the "linear" texture mapping, there is no
; perspective correction. you can do what you want with it, i don't care -
; and, if you do use them, please don't credit me, i don't to be associated
; with such crap. as they say, use at your own risk.
;
; against this code:
; (1) crap code
; (2) slow, no optimizing
; (3) no proper clipping
; (4) low precision
; (5) lots of floating point (sucks)
; (6) almost no comments
;
; pro this code:
; (1) free (about nothing else ...)
;
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
.model small
.stack 200h
.data
numcoords equ 8 ; a cube has 8 vertexes ...
numfaces equ 6 ; ... and 6 faces
cube equ 73 ; the cube size
FrameBufferSeg dw ?
alfa dd 0.2 ; sorry, angles in floating point ...
beta dd 0.4
gama dd 0.6
coord dw ?
xcoord dd ?
ycoord dd ?
zcoord dd ?
sin_alfa dw ?
cos_alfa dw ?
sin_beta dw ?
cos_beta dw ?
sin_gama dw ?
cos_gama dw ?
xinclow dw ?
xinchigh dw ?
text_u1 dw ?
text_v1 dw ?
text_u2 dw ?
text_v2 dw ?
uinclow dw ?
uinchigh dw ?
u1 dw ?
u2 dw ?
vinclow dw ?
vinchigh dw ?
v1 dw ?
v2 dw ?
ka1 dd 0.015
ka2 dd 0.025
ka3 dd 0.012
k32768 dd 32767.0
slope dw 200*8 dup (?)
coords label word
dw -cube, -cube, -cube
dw cube, -cube, -cube
dw cube, -cube, cube
dw -cube, -cube, cube
dw -cube, cube, -cube
dw cube, cube, -cube
dw cube, cube, cube
dw -cube, cube, cube
faces label word
dw 2, 1, 5, 6
dw 4, 7, 6, 5
dw 6, 7, 3, 2
dw 0, 4, 5, 1
dw 0, 1, 2, 3
dw 0, 3, 7, 4
poly2d label word
dw 8*8 dup (0)
.code
.386
mov ax, @data
mov ds, ax
mov ax, ss
add ax, 20h
mov FrameBufferSeg, ax ; frame buffer segment
add ax, 64 * (1024 / 16)
mov fs, ax ; texture segment in fs
mov ax, 13h
int 10h
call mandel ; calculates texture
finit
xor dx, dx
@wait4esc:
fld alfa ; calculates angle
fadd ka1 ; must be replaced by pre-calc table ...
fstp alfa
fld beta ; calculates angle
fadd ka2 ; must be replaced by pre-calc table ...
fstp beta
fld gama ; calculates angle
fadd ka3 ; must be replaced by pre-calc table ...
fstp gama
fld alfa
fsincos
fmul k32768
fistp cos_alfa
fmul k32768
fistp sin_alfa ; sin and cos of angles in 1.15 fixed point format
fld beta
fsincos
fmul k32768
fistp cos_beta
fmul k32768
fistp sin_beta
fld gama
fsincos
fmul k32768
fistp cos_gama
fmul k32768
fistp sin_gama
call RotateCoords
mov ax, numfaces
mov coord, ax
call CleanBuffer
@face:
mov di, coord
dec di
shl di, 3
add di, offset faces
; FaceShown - checks if you can see the face
; (back-face culling)
mov si, [di]
shl si, 3
movsx ecx, word ptr poly2d[si]
mov si, [di+2]
shl si, 3
movsx ebx, word ptr poly2d[si]
sub ecx, ebx
mov si, [di+6]
shl si, 3
movsx eax, word ptr poly2d[si+2]
mov si, [di+2]
shl si, 3
movsx ebx, word ptr poly2d[si+2]
sub eax, ebx
imul ecx ; ecx = a
mov ecx, eax
mov si, [di]
shl si, 3
movsx ebp, word ptr poly2d[si+2]
mov si, [di+2]
shl si, 3
movsx ebx, word ptr poly2d[si+2]
sub ebp, ebx
mov si, [di+6]
shl si, 3
movsx eax, word ptr poly2d[si]
mov si, [di+2]
shl si, 3
movsx ebx, word ptr poly2d[si]
sub eax, ebx
imul ebp ; ecx = a
sub ecx, eax
jge @notshown
; shows face
push di
call ClearSlope
pop di
mov ax, [di]
mov bx, [di + 2]
mov word ptr text_u1, 0
mov word ptr text_v1, 0
mov word ptr text_u2, 0
mov word ptr text_v2, 255
call CalcSlope
mov ax, [di + 2]
mov bx, [di + 4]
mov word ptr text_u1, 0
mov word ptr text_v1, 255
mov word ptr text_u2, 255
mov word ptr text_v2, 255
call CalcSlope
mov ax, [di + 4]
mov bx, [di + 6]
mov word ptr text_u1, 255
mov word ptr text_v1, 255
mov word ptr text_u2, 255
mov word ptr text_v2, 0
call CalcSlope
mov ax, [di + 6]
mov bx, [di]
mov text_u1, 255
mov text_v1, 0
mov text_u2, 0
mov text_v2, 0
call CalcSlope
mov dx, coord
add dl, 50
call FillShape
@notshown:
dec coord
jne @face
call CopyBuffer
in al, 60h ; checks [esc]
cmp al, 1
je @finis
cmp al, 2
jne @wait4esc
call initcolors
jmp @wait4esc
@finis:
mov ax, 3 ; back to dos
int 10h
mov ax, 4c00h
int 21h
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;
; CleanBuffer - cleans frame buffer
;
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
CleanBuffer proc
mov ax, FrameBufferSeg
mov es, ax
xor eax, eax
xor di, di
mov cx, 16000
rep stosd
ret
CleanBuffer endp
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;
; CopyBuffer - copies frame buffer to screen
;
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
CopyBuffer proc
mov ax, 0a000h
mov es, ax
mov ax, FrameBufferSeg
mov ds, ax
xor di, di
xor si, si
mov cx, 16000
rep movsd
mov ax, @data
mov ds, ax ; restore ds
ret
CopyBuffer endp
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;
; RotateCoords
;
; in: sin_alfa, cos_alfa, sin_beta, cos_beta, sin_gama, cos_gama
; in 1:15 fixed-point format (*32768)
;
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
RotateCoords proc
mov si, offset coords
mov di, offset poly2d
mov bp, numcoords
@rc:
; gira ao redor de z
movsx ebx, cos_alfa
movsx eax, word ptr [si]
imul ebx
shl eax, 1 ; 16:16
mov ebx, eax
movsx ecx, sin_alfa
movsx eax, word ptr [si+2]
imul ecx
shl eax, 1 ; 16:16
sub eax, ebx
mov xcoord, eax
movsx ebx, sin_alfa
movsx eax, word ptr [si]
imul ebx
shl eax, 1 ; 16:16
mov ebx, eax
movsx ecx, cos_alfa
movsx eax, word ptr [si+2]
imul ecx
shl eax, 1
add eax, ebx
mov ycoord, eax
; gira ao redor de y
movsx ebx, cos_beta
mov eax, xcoord
push eax
imul ebx
shrd eax, edx, 15
mov ebx, eax
movsx ecx, sin_beta
movsx eax, word ptr [si+4]
imul ecx
shl eax, 1
sub eax, ebx
mov xcoord, eax
movsx ebx, sin_beta
pop eax ; eax = xcoord
imul ebx
shrd eax, edx, 15
mov ebx, eax
movsx ecx, cos_beta
movsx eax, word ptr [si+4]
imul ecx
shl eax, 1
add eax, ebx
mov zcoord, eax
; gira ao redor de x
movsx ebx, cos_gama
mov eax, ycoord
push eax
imul ebx
shrd eax, edx, 15
mov ebx, eax
movsx ecx, sin_gama
mov eax, zcoord
imul ecx
shrd eax, edx, 15
sub eax, ebx
mov ycoord, eax
movsx ebx, sin_gama
pop eax ; eax = ycoord
imul ebx
shrd eax, edx, 15
mov ebx, eax
movsx ecx, cos_gama
mov eax, zcoord
imul ecx
shrd eax, edx, 15
add eax, ebx
mov zcoord, eax
; perspective transform
mov ax, word ptr xcoord + 2
xchg ah, al
xor al, al ; ax *= 256
cwd
mov bx, word ptr zcoord + 2
add bx, 256
idiv bx
add ax, 160
mov [di], ax
mov ax, word ptr ycoord + 2
xchg ah, al
xor al, al ; ax *= 256
cwd
mov bx, word ptr zcoord + 2
add bx, 256
idiv bx
add ax, 100
mov [di+2], ax
add di, 8
add si, 6
dec bp
je @fim_rc
jmp @rc
@fim_rc:
ret
RotateCoords endp
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;
; CalcSlope
;
; ax = l1
; bx = l2
;
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
zcount dw ?
x1 dw ?
y1 dw ?
x2 dw ?
y2 dw ?
proc CalcSlope
push di
mov di, ax
shl di, 3
add di, offset poly2d
mov si, bx
shl si, 3
add si, offset poly2d
mov ax, [di+2] ; [di + 2] = y1
mov cx, [si+2] ; [si + 2] = y2
cmp ax, cx
jle @cs1
xchg ax, cx
xchg si, di
mov bx, text_u1
xchg bx, text_u2
mov text_u1, bx
mov bx, text_v1
xchg bx, text_v2
mov text_v1, bx
@cs1: ; di -> l1, si -> l2
sub cx, ax ; cx = counter
jz @zero
mov ax, [di+2]
cmp ax, 199
jge @zero
mov y1, ax
mov ax, [si+2]
cmp ax, 1
jle @zero
mov y2, ax
movsx ecx, cx
mov ax, [di]
mov x1, ax
mov ax, [si]
mov x2, ax
sub ax, x1
movsx eax, ax
shl eax, 16
cdq
idiv ecx
mov dword ptr xinclow, eax
mov ax, text_u2
sub ax, text_u1
shl eax, 16
cdq
idiv ecx
mov dword ptr uinclow, eax
mov ax, text_v2
sub ax, text_v1
shl eax, 16
cdq
idiv ecx
mov dword ptr vinclow, eax
mov ax, y1
cmp ax, 0
jge @noclip2
; x2 - x1 x - x1
;--------- = ---------
; y2 - y1 y - y1
; x = (y-y1)*(x2-x1)/(y2-y1) + x1
mov ax, y1
neg ax
mov dx, x2
sub dx, x1
imul dx
mov bx, y2
sub bx, y1
idiv bx
add x1, ax
mov ax, y1
neg ax
mov dx, text_u2
sub dx, text_u1
imul dx
mov bx, y2
sub bx, y1
idiv bx
add text_u1, ax
mov ax, y1
neg ax
mov dx, text_v2
sub dx, text_v1
imul dx
mov bx, y2
sub bx, y1
idiv bx
add text_v1, ax
xor ax, ax
mov y1, ax
mov cx, y2
sub cx, y1
@noclip2:
mov ax, y2
cmp ax, 200
jl @noclip1
mov cx, 199
sub cx, y1
@noclip1:
mov zcount, cx
mov si, y1
shl si, 3
add si, offset slope
xor eax, eax
mov ax, x1 ; eax ok
xor ebx, ebx
mov bl, byte ptr text_u1
mov bh, byte ptr text_v1 ; ebx ok
mov cx, vinclow
shl ecx, 16
mov cx, uinchigh ; ecx ok
mov bp, uinclow
shl ebp, 16
mov bp, xinchigh
xor edx, edx
mov dx, vinchigh
mov di, xinclow
shl edi, 16
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿
; ³UPPER 16BIT ³ LOWER 16BIT ³
; ÚÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´
; ³ REG ³ HI WORD ³ HI BYTE ³ LOW BYTE ³
; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ´
; ³ EAX ³ U-LOW ³ X ³
; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´
; ³ EBX ³ V-LOW ³ V ³ U ³
; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ´
; ³ ECX ³ V-INC-LOW ³ U-INC ³
; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´
; ³ EDX ³ X-LOW ³ -- ³ V-INC ³
; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄ´
; ³ EBP ³ U-INC-LOW ³ X-INC ³
; ÃÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÅÄÄÄÄÄÄÄÄÄÄÄÄÂÄÄÄÄÄÄÄÄÄÄÄÄ´
; ³ EDI ³ X-INC-LOW ³ -- ³ -- ³
; ÀÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÁÄÄÄÄÄÄÄÄÄÄÄÄÙ
@inner_loop:
add edx, edi
adc eax, ebp
adc ebx, ecx
adc bh, dl
cmp word ptr [si], 8000h
jne @skp
mov [si], ax
mov [si+4], bx
@skp:
mov [si+2], ax
mov [si+6], bx
add si, 8
dec zcount
jne @inner_loop
@zero:
pop di
ret
CalcSlope endp
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;
; ClearSlope - clear slope-table
;
; i/o: nothing
; destroys es !
;
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
ClearSlope proc
mov cx, 200
mov ax, @data
mov es, ax
mov di, offset slope
@clsl:
mov eax, 80008000h
stosd
xor eax, eax
stosd
loop @clsl
ret
ClearSlope endp
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
;
; FillShape - fills horizontal spans
;
; in: dl = color of the polygon
;
; °°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
FillShape proc
mov ax, FrameBufferSeg
mov es, ax
xor bp, bp
mov si, offset slope
mov zcount, 200
@loop:
cmp word ptr [si], 8000h
jz @skip1 ; no hline to draw
mov ax, [si]
mov cx, [si+2]
xor bx, bx
cmp ax, cx
jle @skip2
xchg ax, cx
mov bx, [si+6] ; redo this !
shr bx, 8
xor bh, bh
mov v1, bx
mov bx, [si+4]
shr bx, 8
xor bh, bh
mov v2, bx
mov bx, [si+6] ; redo this !
xor bh, bh
mov u1, bx
mov bx, [si+4]
xor bh, bh
mov u2, bx
jmp @skip3
@skip2:
mov bx, [si+4]
shr bx, 8
xor bh, bh
mov v1, bx
mov bx, [si+6]
shr bx, 8
xor bh, bh
mov v2, bx
mov bx, [si+4]
xor bh, bh
mov u1, bx
mov bx, [si+6]
xor bh, bh
mov u2, bx
@skip3:
mov di, bp
add di, ax
sub cx, ax
jz @skip1
movsx ecx, cx
push bp
push si
mov ax, u2
sub ax, u1
shl eax, 16
cdq
idiv ecx
mov dword ptr uinclow, eax
mov ax, v2
sub ax, v1
shl eax, 16
cdq
idiv ecx
mov dword ptr vinclow, eax
xor si, si
mov bp, uinclow
mov dx, vinclow
shl edx, 16
mov dx, uinchigh
mov ah, byte ptr vinchigh
xor ebx, ebx
mov bl, byte ptr u1
mov bh, byte ptr v1
; this is it: the INNER LOOP !!!
; lots of fun, try to figure out what's in each register
@fs:
add si, bp
adc ebx, edx
adc bh, ah
mov al, fs:[bx]
stosb
loop @fs
@skip_il:
pop si
pop bp
@skip1:
add si, 8
add bp, 320
dec zcount
jne @loop
ret
FillShape endp
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
proc initcolors
mov si, offset poly2d
mov cx, 8
@ic:
call rand
;shr al, 4
mov [si+4], al
call rand
; shr al, 4
mov [si+6], al
add si, 8
loop @ic
ret
initcolors endp
MULTIPLIER equ 015a4e35h
INCREMENT equ 1
Seed dd 1
;
; pseudo-random number generator (number in ax) - ripped from Borland
;
proc rand
; Seed = MULTIPLIER * Seed + INCREMENT;
mov eax, Seed
mov ebx, MULTIPLIER
imul ebx
add eax, INCREMENT
mov Seed, eax
; return((int)(Seed >> 16) & 0x7fff);
shr eax, 16
and ax, 7fffh
ret
rand endp
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
;
; Crappy Mandelbrot Set Generator
;
;²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²²
; int
x dw 0
y dw 0
dummy dw ?
; float
xl dd ?
yl dd ?
px dd ?
py dd ?
npx dd ?
npy dd ?
deltax dd 0.012
deltay dd 0.012
k1 dd -2.00
k2 dd -1.50
i dw ?
j dw ?
step_xl dw 1
step_yl dw 1
mandel proc
mov ax, 0a000h
mov es, ax
; xl = -2!
fld dword ptr [k1]
fstp dword ptr [xl]
; FOR x = 0 TO 200
xor ax, ax
mov [x], ax
next_x:
; yl = -1.5
fld dword ptr [k2]
fstp dword ptr [yl]
; xl = xl + (3 / 200)
fld dword ptr [xl]
fadd dword ptr [deltax]
fstp dword ptr [xl]
; FOR y = 0 TO 200
xor ax, ax
mov [y], ax
mov di, [x]
next_y:
; yl = yl + (3 / 200)
fld dword ptr [yl]
fadd dword ptr [deltay]
fstp dword ptr [yl]
; px = xl
mov eax, [xl]
mov [px], eax
; py = yl
mov eax, [yl]
mov [py], eax
; i% = 0
xor ax, ax
mov [i], ax
my_while:
; WHILE (((px * px + py * py) < 4) AND (i% < 128))
fld dword ptr [px]
fmul st, st
fld dword ptr [py]
fmul st, st
fadd
fistp word ptr [dummy]
mov ax, [dummy]
cmp ax, 4
jg my_wend
mov ax, [i]
cmp ax, 64
je my_wend
; npx = (px * px - py * py) + xl
fld dword ptr [px]
fmul st, st
fld dword ptr [py]
fmul st, st
fsub
fadd dword ptr [xl]
fstp dword ptr [npx]
; npy = (2! * px * py) + yl
fld dword ptr [px]
fmul dword ptr [py]
fadd st, st
fadd dword ptr [yl]
fstp dword ptr [npy]
; px = npx
mov eax, [npx]
mov [px], eax
; py = npy
mov eax, [npy]
mov [py], eax
; i% = i% + 1
inc [i]
; WEND
jmp my_while
my_wend:
; PSET (x, y), i% + 32
mov al, byte ptr [i]
cmp al, 64
jne mw0
xor al, al
jmp mw1
mw0:
add al, 32
mw1:
mov fs:[di], al
mov es:[di], al
add di, 256
; IF (i% = 128) THEN PSET (x, y), 0
mov ax, [y]
inc ax
mov [y], ax
cmp ax, 256
jne next_y
; NEXT y
mov ax, [x]
inc ax
mov [x], ax
cmp ax, 256
jne next_x
; NEXT x
inkey:
ret
mandel endp
end