A kocka by Abaddon [web]
; A kocka (The Cube)
; 256byte intro for Experience 2025
; handcrafted x86 code by TomCat/Abaddon
ZOOM EQU 5*20
BGCOLOR EQU 0E0H
ORG 256
MOV FS,AX ; FS:BIOS variables
PUSH 0A000H
DB '@TC' ; my signo & my favorite instruction
POP SI ; SI:-4
MOV AL,13H ; 320x200 video mode
INT 10H
POP ES ; ES:screen buffer
pixel:
SUB DH,100 ; DH:Py
SUB DL,128 ; DL:Px
PUSH DX
SALC
XOR DL,AL ; DL:ABS(Px)
MOV CL,BGCOLOR ; background color
MOV BP,texture+4 ; half spaces data
background:
MOV AL,ZOOM
MUL BYTE [BP+SI]
INC BP
XCHG BX,AX
MOV AL,16
MUL BYTE [BP+SI]
IMUL DH
ADD BX,AX
MOV AL,[BP+SI]
INC BP
AND AL,0F0H
IMUL DL
ADD BX,AX
JNS .1 ; dont want to paint this half plane
MOV CL,[BP+SI] ; CL:new color
.1:
INC BP
JPE background ; loop x7 (next data)
CMP [SI],CH ; background color?
JNS .2
TEST CL,CL ; right half of the screen?
JS .2
ADD CL,24 ; otherwise make it brighter
.2:
POP DX
FILD DWORD [BP+SI] ; BIGP
FILD QWORD [BP+SI] ; BIGN BIGP
MOV BX,32*256 ; BX:buffer of normal vectors
PUSHA ; DI SI BP SP BX DX CX AX
plane: ; Respect to LBi for PolyRoll
CMP [BX+SI+3],CH ; sign check for Nz
;JZ next ; who cares zero divison?
FLD DWORD [BP+80] ; cos
FIMUL WORD [BP+SI] ; cos*CUBE
FIADD WORD [SI-5] ; Px R max min
FMUL DWORD [BX+4] ; Px*Nx R max min
FILD WORD [SI-4] ; Py Px*Nx max min
FMUL DWORD [BX] ; Py*Ny Px*Nx max min
FADDP ; Py*Ny+Px*Nx max min
FISUBR WORD [BP+SI] ; R-Px*Nx-Py*Ny max min
FDIV DWORD [BX+SI] ; (R-Px*Nx-Py*Ny)/Nz max min
JL front-2 ; we need to run some data for short jumps :)
back:
FUCOMI ST0,ST2 ; Pz max min
FCMOVNB ST0,ST2 ; min max min
FSTP ST2 ; max min
next:
ADD BL,BH
JNZ plane ; loop x8 (next plane) but only 6 different
FUCOMIP ST0,ST1 ; min
FSTP ST0 ; -
JC hit
MOV [SI],CL ; AL on stack <- texture color
hit:
POPA
STOSB
MOV AX,0CCCDH
MUL DI ; DH:y DL:x
frame:
JC pixel ; Respect to gopher for REMNANTS
;+-+-+-+-+-+-+-+-+-
MOV AX,0010101000010101B; 6 normals encoded
;xyzxyzxyzxyzxyzxyz
rotate:
MOV CL,3
.1:
FLD1 ; 1...
SHL AX,1
JC .2
FSUB ST0,ST0 ; 0...
.2:
TEST BL,BH ; alternate the sign
JZ .3
FCHS ; -1/0...
.3:
LOOP .1 ; loop x3 (next coord)
axis:
NEG SI
twice: ; Respect to Rrrola for Pyrit
FLD ST1 ; NX NZ NX NY
FILD DWORD [FS:046CH] ; time
FIMUL WORD [BP-front+SPEED]; angle=time*SPEED
JNS angleok
FCOS ; nonlinear rotation
FADD ST0,ST0 ; 2a NX NZ NX NY
FST DWORD [BP+80]
angleok:
FSINCOS ; cos sin NX NZ NX NY
FMULP ST4,ST0 ; sin NX sinNZ cosNX cosNZ NY
FMULP ST1,ST0 ; sinNX sinNZ cosNX cosNZ NY
CMC
JNC twice ; loop x2
FADDP ST3,ST0 ; sinNZ cosNX sinNX+cosNZ NY
FSUBP ST1,ST0 ; cosNX-sinNZ sinNX+cosNZ NY
FSTP DWORD [BX+SI] ; sin*NX+cosNZ NY
JNS axis ; loop x2 (next axis)
FSTP DWORD [BX] ; -
SUB BL,-32
JC rotate ; loop x8 (next plane) but only 6 different
DEC WORD [BP+SI]
IN AL,60H
DAS
JC frame ; Respect to Digimind for Burning Match
RETN
SPEED DW -88
texture:
; data structure of half spaces
; byte1: distance from the origo
; byte2: direction by digits x/y incremets
; byte3: new color
DB 0,00FH,68
DB 6,00FH,BGCOLOR
DB 8,0D1H,44
DB 23,0D1H,74H
DB 24,0D1H,BGCOLOR
DB 12,001H,BGCOLOR
DB 12,00FH,BGCOLOR
MAXCOLOR:;DD 15.45
CUBE DW 50*256,4176H
front:
NOP ; we need the right parity for the dataloop
FADD ST0,ST0 ; perspective correction
FUCOMI ST0,ST1 ; Pz max min
FCMOVB ST0,ST1 ; max max min
FSTP ST1 ; max min
JNA .1
FLD1 ; 1
FSUB DWORD [BX+SI] ; 1-Nz
FMUL DWORD [BP+SI] ; MAXCOLOR*(1-Nz)
FISTP WORD [SI] ; AL on stack <- object color
.1:
JMP next
[ back to the prod ]