
; 256bytes demos archive Baze氏作のtubeを移植
; オリジナル入手先 http://www.256b.com

; 目標 1024bytes…
; 何も書いてないのに 次リリースの予定に入ってるなんて ひげぽん非道いや

	bits	32

SYSPRINT		equ		0x0001			; テキスト表示
LEMMINGS		equ		0x0002			; レミングス
GETVRAMINFO		equ		0x0011			; VRAM取得

%if 0
SCREEN_W		equ		160
SCREEN_H		equ		160
%else
SCREEN_W		equ		240
SCREEN_H		equ		240
%endif

		struc	tube_t
.fpuwork	resd	1
.angle		resd	1
.step		resd	1
.yalign		resd	1
.vram		resd	1
.bpp		resd	1
.vramw		resd	1
.vramh		resd	1
.targw		resd	1
.r240		resd	1
.r128ppi	resd	1
.anglestep	resd	1
.size
		endstruc

screen		equ		0xc0000000
palettes	equ		(screen + (SCREEN_W * SCREEN_H))
texture		equ		(palettes + (0x100 * 4))
dataend		equ		(texture + 0x10000)

section .text

%ifdef BUILD_ON_LINUX
	global	user_start
user_start:
%else
	global	_user_start
_user_start:
%endif
				sub		esp, byte (tube_t.size)

				; VRAM取得
				xor		ebx, ebx
				mov		bl, GETVRAMINFO
				lea		esi, [esp + tube_t.vram]
				int		0x80
				mov		ebp, [esp + tube_t.bpp]
				mov		esi, errvrammsg
				cmp		ebp, byte 16
				jb		short .lemmings

				; FPUチェック
				add		esi, byte (errfpumsg - errvrammsg)
				fninit
				fnstcw	word [esp]
				cmp		word [esp], 0x37f
				je		short .main

				; プロセス終了
.lemmings:		xor		ebx, ebx
				mov		bl, SYSPRINT
				int		0x80
				xor		ebx, ebx
				mov		bl, LEMMINGS
				int		0x80

				; めいん〜
.main:			cld

				; パレット作成
makepalettes:	mov		edi, palettes
				xor		ecx, ecx
.lp1:			mov		eax, ecx
				imul	eax
				shr		eax, 7
				mov		ah, cl
				rcl		eax, 9
				stosd
				inc		ecx
				cmp		ecx, byte 0x7f
				jbe		short .lp1
				dec		ecx
				xor		eax, eax
.lp2:			imul	eax, ecx, 0x000201
				stosd
				dec		ecx
				jns		short .lp2
				inc		ecx

				; テクスチャ作成 (乱数が面倒なんでオリジナルから借りて来る)
maketexture:
			;	mov		edi, texture
.lp1:			mov		[edi + ecx], cl
				inc		ecx
				or		cx, cx
				jne		short .lp1
				mov		dl, 0xc9
				xor		eax, eax
.lp2:			lea		esi, [ecx + 255]
				movzx	esi, si
				movzx	ebx, cx
				add		eax, ecx
				rol		ax, cl
				mov		dh, al
				sar		dh, 5
				adc		dl, dh
				adc		dl, [edi + esi]
				shr		dl, 1
				mov		[edi + ebx], dl
				not		bh
				mov		[edi + ebx], dl
				loop	.lp2

				mov		ebx, esp

				; rdataコピー
				mov		esi, const_tbl
				lea		edi, [ebx + tube_t.targw]
				mov		cl, 4
				rep movsd

				; yalign計算
				shr		ebp, 3
				mov		eax, [ebx + tube_t.vramw]
				sub		eax, [ebx + tube_t.targw]
				imul	ebp
				mov		[ebx + tube_t.yalign], eax


				; 計算〜
updatescreen:	mov		esi, [ebx + tube_t.step]
				add		byte [ebx + tube_t.step + 1], 8
				mov		ecx, screen
				fld		dword [ebx + tube_t.angle]
				fadd	dword [ebx + tube_t.anglestep]
				fst		dword [ebx + tube_t.angle]
				fsincos
				mov		edi, -(SCREEN_H / 2)
.lp2:			mov		ebp, -(SCREEN_W / 2)
.lp1:			mov		[ebx], ebp
				fild	dword [ebx]
				mov		[ebx], edi
				fild	dword [ebx]
				fld		st0				; y
				fmul	st0, st3
				fld		st2				; x
				fmul	st0, st5
				fsubp	st1, st0
				fxch	st0, st2
				fmul	st0, st3
				fxch	st0, st1
				fmul	st0, st4
				faddp	st1, st0
				fld		dword [ebx + tube_t.r240]
%if 1
				fld		st1				; y
				fmul	st0, st4
				fld		st1				; z
				fmul	st0, st6
				fsubp	st1, st0
				fxch	st0, st1
				fmul	st0, st4
				fxch	st0, st2
				fmul	st0, st5
				faddp	st2, st0
%endif
				fld		st2
				fmul	st0, st0
				fld		st2
				fmul	st0, st0
				faddp	st1, st0
				fsqrt
				fdivp	st1, st0
				fxch	st0, st2
				fpatan
				fmul	dword [ebx + tube_t.r128ppi]
				fistp	dword [ebx]
				mov		dl, [ebx]
				fmul	dword [ebx + tube_t.r128ppi]
				fistp	dword [ebx]
				mov		dh, [ebx]
				lea		eax, [esi + edx]
				add		al, ah
				and		al, 64
				mov		ah, 8
				je		short .store
				shl		edx, 2
				lea		eax, [esi + edx]
				sub		al, ah
				mov		ah, 16
				jns		short .store
				add		edx, edx
				mov		ah, 48
.store:			mov		al, byte [ecx]
				sar		al, 2
				sub		al, ah
				lea		edx, [esi + edx]
				movzx	edx, dx
				add		al, [texture + edx]
				mov		[ecx], al
				inc		ecx
				inc		ebp
				cmp		ebp, byte (SCREEN_W / 2)
				jl		near .lp1
				inc		edi
				cmp		edi, byte (SCREEN_H / 2)
				jl		near .lp2
				fstp	st0
				fstp	st0


				; VRAM描画〜
vramdraw:		mov		edx, [ebx + tube_t.vram]
;				mov		ecx, palettes
				mov		esi, screen
				push	dword updatescreen
				mov		edi, SCREEN_H
				cmp		[ebx + tube_t.bpp], byte 24
				je		short vramdraw24
				cmp		[ebx + tube_t.bpp], byte 16
				je		short vramdraw16

vramdraw32:
.lp2:			mov		ebp, [ebx + tube_t.targw]
.lp1:			movzx	eax, byte [esi]
				inc		esi
				mov		eax, [ecx + eax * 4]
				mov		[edx], eax
				add		edx, byte 4
				dec		ebp
				jne		short .lp1
				add		edx, [ebx + tube_t.yalign]
				dec		edi
				jne		short .lp2
				ret

vramdraw24:
.lp2:			mov		ebp, [ebx + tube_t.targw]
.lp1:			movzx	eax, byte [esi]
				inc		esi
				mov		eax, [ecx + eax * 4]
				mov		[edx], ax
				shr		eax, 16
				add		edx, byte 3
				mov		[edx-1], al
				dec		ebp
				jne		short .lp1
				add		edx, [ebx + tube_t.yalign]
				dec		edi
				jne		short .lp2
				ret

vramdraw16:
.lp2:			mov		ebp, [ebx + tube_t.targw]
.lp1:			movzx	eax, byte [esi]
				inc		esi
				mov		eax, [ecx + eax * 4]
				ror		eax, 8
				shr		ah, 3
				shr		ax, 2
				rol		eax, 5
				mov		[edx], ax
				add		edx, byte 2
				dec		ebp
				jne		short .lp1
				add		edx, [ebx + tube_t.yalign]
				dec		edi
				jne		short .lp2
				ret

errvrammsg		db	'Require 16/24/32bpp.', 10, 0
errfpumsg		db	'Require FPU.', 10, 0

				align	4
const_tbl		dd		SCREEN_W
				dd		240.							; Zのデフォルト
				dd		40.743665431525205956834		; 128 / PI
				dd		0.05							; てきとー回転θ

const_term:

	ends

