pouët.net

Go to bottom

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
Go to top