From 1d22e16f3ce315828ed66b13dd793463160d0c19 Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Fri, 25 Oct 2019 11:37:58 +0100 Subject: [PATCH 1/1] Copy source and binaries from download into git. --- README | 1 + pyrit.asm | 244 ++++++++++++++++++++++++++++++++++++++++++++ pyrit.com | Bin 0 -> 256 bytes pyrit.png | Bin 0 -> 5177 bytes pyrit_dosbox_compatible.com | Bin 0 -> 261 bytes pyrit_vsync.com | Bin 0 -> 271 bytes 6 files changed, 245 insertions(+) create mode 100644 README create mode 100644 pyrit.asm create mode 100644 pyrit.com create mode 100644 pyrit.png create mode 100644 pyrit_dosbox_compatible.com create mode 100644 pyrit_vsync.com diff --git a/README b/README new file mode 100644 index 0000000..1a5d493 --- /dev/null +++ b/README @@ -0,0 +1 @@ +https://www.pouet.net/prod.php?which=78045 diff --git a/pyrit.asm b/pyrit.asm new file mode 100644 index 0000000..50c49b4 --- /dev/null +++ b/pyrit.asm @@ -0,0 +1,244 @@ +; Pyrit + +; a 256-byte intro by Rrrola + +; greets to everyone who's computer is too fast :) + +; This is loosely based on my intro 'Gem' (shown on Demobit), +; but the code is much better. + +; Vector3: X right, Y down, Z forward. +; On the FP stack it looks like {Y X Z} (Y is often used in comparisons). +; In memory it looks like {Z X Y}, which saves a displacement byte. +; (u'v) is the dot product: ux*vx + uy*vy + uz*vz. + +org 100h ; assume al=0 bx=0 sp=di=-2 si=0100h bp=09??h + +;Set video mode and earth+sky palette + dec di ; u16[100h] = -20401, u16[10Ch] = -30515 + mov al,13h + dec di ; initial pixel_adr@di = -4 + +P:shr cl,1 ; B@cl = 0..8..31,31..0 + + int 10h ; set video mode / color: bx=index dh=R ch=G cl=B + + movsx cx,bl ; 0..127,128..255 (palette index) + xor ch,cl ; 0..127,127..0 + mov cl,ch + mov ax,cx + mul ax ; R@dh = 0..16..63,63..16..0 + + shr cx,1 ; G@ch = 0..63,63..0 + + inc bl ; keep default color 0 + js Q ; R@dh = 0..63,63..16..0 + xchg cl,dh ; B@cl = 0..16..63,63..0 +Q:mov ax,1010h + jnz P ;bx=0 cx=0 + + +;Each frame: Generate normals to p0..p11=[bp+200h,300h,...]. +M:mov ax,0x4731 ; highest 9 bits: float32 exponent 1/256 (for T) + ; lower byte = 2*number of rotations+1 + ; lowest 4 bits must be 0x1 for 'test cl,al' + mov dx,0xA000-10-20-20-4 + mov es,dx ; dx:bx = YX:XX = 0x9fca:0 + pusha ; adr: -18 -16 -14 -12 -10 -8 -6 -4 -2 + ; stack: di si bp sp bx dx cx ax 0 + ; data: -4 100 9?? -2 0 9fca {T/256} + mov cx,12 +G:add bp,si ; i@cx = 12...1; bp points to p[12-i]; carry=0 + pusha + +;Generate 12 planes with unit normals. + +; fld1 ; platonic dodecahedron: exact is atan((1+sqrt5)/2)=1.017rad + fld dword[di-2] ;|t=T/256: morphing shape: cube, platonic12, rhombic12 + + fsincos + + fldz ;|a=0 b c (a*a+b*b+c*c = 1) +; fldlg2 ;irregular shape + +N:test cl,al ;=1 ;|a b c + jnz K + fchs +K:fstp st3 ;|b c +-a (scramble so that all 12 planes are generated) + loop N ;cl=0 ;|z x y + +;Do a bunch of slow rotations. z x y -> cx-sy cy+sx z + +R:fstp st3 ;|x y z +Z:fld st1 ;|y x y z ;|x sy x cy z + fld dword[di-2] ;|t=T/256 + fsincos ;|c=cos(t) s=sin(t) y x y z ;|c s x sy x cy z + fmulp st4 ;|s y x cy z ;|s x sy cx cy z + fmulp ;|sy x cy z ;|sx sy cx cy z + add al,0x7F ; loop 2x +BIG equ $-1 ;=28799 (anything higher and you'll get overflow glitches) + jo Z + faddp st3 ;|sy cx cy+sx z + fsubp ;|new.z=cx-sy .x=cy+sx .y=z + jc R ; loop 24x + +S:fstp dword[bp+si] ;[bp+100]=.z [bp+104]=.x [bp+108]=.y + sub si,di + jpo S + + popa + loop G +C:popa ;=16993, background color multiplier + +; the visible pixels are A0000..AF9FF, I want X=0 Y=0 in the center +;Each pixel: cx=T dx:bx=YX:XX(init=9fca:0) di=adr(init=-4) +X:inc dx ; part of "dx:bx += 0x0000CCCD" +X2: + stosb + + pusha ; adr: -18 -16 -14 -12 -10 -8 -6 -4 -2 + fninit ; stack: di si bp sp bx dx cx ax 0 + mov bx,es ; s16: pixadr 100 9?? -2 ..X..Y T result + mov di,-4 ;di = address of pushed ax + +;Compute ray direction. + fild word[byte BIG+si-100h] ; store 28799 as a double, read as two floats +C2 equ $-2 ;=20036, foreground color multiplier + fst qword[bx] ; t_front@float[bx] = 0, t_back@float[bx+4] = 6.879 + fild word[di+4-9] + fild word[di+4-8] ;|y=Y x=X z=BIG + +;Intersect the pyrite. + call GEM + popa ; color -> pushed ax +; mov al,dl ; show only palette + +;; Faster, but lower quality: draw each pixel twice. +; stosb +; add bx,0xCCCD; dx:bx = YXX += 0000CCCD +; adc dx,0 + + add bx,0xCCCD; dx:bx = YXX += 0000CCCD + jnc X2 + jnz X ; do 65536 pixels + + in al,60h + dec ax ; ah=0 (checkboard uses positive color indices) + loopnz M ; T-- +; ret ; fallthrough + +GEM: +;Hit the pyrite. + xchg ax,cx ; ax = T + +; Faster (+4 or +8 bytes): test the shape only in the center of the screen + add dh,dh + jo B + add dl,dl + jo B + +;Ray-plane intersection. +;Find the front plane with maximum t and back plane with minimum t. +; tf@[bx], tb@[bx+4] ray parameter t +; pf@[bx+si], pb@[bx+4+si] pointer to plane + mov cx,12 ; i@cx = 12...1 +I:add bp,si ; bp points to p[i] + fldlg2 ;|pd=0.301 y x z + fadd dword[bp+si] ;|N=pd-(ro'p[i]) y x z ; ro = 0 0 -1 + + push si ; Dot product: +D:fld dword[bp+si] ;|p[i].z ... + fmul st4 ;|rd.z*p[i].z ... + sub si,di ; 100 104 108 + jpo D ;|(rd*p[i]).y .x .z N rd.y .x .z + pop si + faddp + faddp ;|D=(rd'p[i]) N y x z + +;If we hit the plane from the front (D<0), update tf. Otherwise update tb. + push bx + fst dword[bp+di]; -> p[i].dot_rd (will be read later) + test [bp+di+2],sp ; sf=1 if we're in front of the plane + js FRONT + sub bx,di ; bx = address of tf?tb +FRONT: ; D<0: if tf*D < N { tf=N/D; pf=current; } maximalize tf + fld st0 ; D>=0: if tb*D < N { tb=N/D; pb=current; } minimalize tb + fmul dword[bx] ;|(tf?tb)*D D N y x z + +;;DosBOX-compatible FPU comparison, +5 bytes (+3 but we need ax) +; push ax +; fcomp st2 ;|D N y x z +; fnstsw ax +; sahf ; cf = (tf?tb)*D < N +; pop ax +; jc NEXT + + fcomip st2 + jc NEXT + +;another alternative, +6 bytes +; fsub st2 +; fstp dword[bp-8] +; test [bp-6],sp ; sf=1 if <0 +; js NEXT + + + fdivr st1 ;|t=N/D N y x z + fst dword[bx] ; -> tf?tb + mov [bx+si],bp ; pf?pb = current +NEXT: + fcompp + pop bx ;|y x z + + mov dx,[bx+6] + cmp dx,[bx+2] ; if tf>tb { no_hit: early exit } + jng B ;si=100 ;|y x z + + loop I + +;Reflect: reflect(i,n) = i - 2*n*(i'n) + mov bx,[bx+si] ; pf +Y:fld dword[bx+di] ;|(rd'pf) rd.y .x .z ; reads pf->dot_rd + fmul dword[bx+si] ;|(rd'pf)*pf.z rd.y .x .z + fadd st0 ;|2*(rd'pf)*pf.z rd.y .x .z + fsubr st3 ;|R.z=rd.z-2*(rd'pf)*pf.z rd.y .x .z + sub si,di ;100 104 108 + jpo Y ;si=10C ;|(R=i-2*n(i'n)).y R.x R.z rd.y .x .z + +;Environment map: chessboard below, sky gradient above. +B: +; Subtle highlight on the pyrite. + fld st0 + fimul word[byte C+si-100h] ; 16993 (background) or 20036 (pyrit) + fistp dword[di] ;|y x z + sar dword[di],22 ; if y>=-0.5 { chessboard } else { sky } + js E ; the sky is just y (= y^2 after gamma) + +; Everything the same brightness. (-6 bytes) +; fist word[di] ;|y x z +; sar word[di],8 ; if y>=-0.5 { chessboard } else { sky } +; js E ; the sky is just y (= y^2 after gamma) + +; Dark background version. +; fist word[di] ;|y x z +; shld cx,si,16-3 +; xor cl,9 ; hit?8:9 - make the background darker +; sar word[di],cl ; if y>=-0.5 { chessboard } else { sky } +; js E ; the sky is just y (= y^2 after gamma) + + fidivr word[si] ;|C/y x z (C = hit?-30515:-20401) + fmul st1,st0 + fmul st2 ;|u=z*C/y v=x*C/y z + + fistp dword[bp+di] + sub al,[bp+di+1] + fistp dword[bp+di] + xor al,[bp+di+1] ; xortex@ax = (T-u) XOR v + +; aam -32-24 ; more interesting floor texture + and al,9<<3 + add al,10<<3 ; tex = (xortex AND 0b1001) + 10 [10|11|18|19] + mul byte[di] + mov [di],ah ; pushed al = tex*y + +E:ret diff --git a/pyrit.com b/pyrit.com new file mode 100644 index 0000000000000000000000000000000000000000..30e5210f034a3682265f655112237fed5ea2b637 GIT binary patch literal 256 zcmV+b0ssC_uoF+v>CF%izRNJpi0O&Q_u$d#{=;|zhR(PU5Ow6ZF-N+}pN_&{xeNdS z^i*+v4`!+u6a{MgH0Q-pt;~1b=Yx-oxJMa_QL`DgJx*!kHPi74LLTZ>l)J68gJ z5aP#+7}){X2-v{b>nZ+w^x44POkmp`X2Crcco^P1+{xI=+Z!rF0oxlgLjfd61W@)R Gh$X{Jg^@S_ literal 0 HcmV?d00001 diff --git a/pyrit.png b/pyrit.png new file mode 100644 index 0000000000000000000000000000000000000000..c996d8cef844165c824353116980d227d454bfb0 GIT binary patch literal 5177 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 literal 0 HcmV?d00001 diff --git a/pyrit_dosbox_compatible.com b/pyrit_dosbox_compatible.com new file mode 100644 index 0000000000000000000000000000000000000000..2a2e0a1612de4cef5d0e4d1a47391c1fbcc2bc2b GIT binary patch literal 261 zcmV+g0s8(=uoF+v>CF%izRNJpi0O&Q_u$d#{=;|zhR(PU5Ow6ZF-N+}pN_&{xeNdS z^i*+v4`!+u6a{MgH0Q-pt;~1b=Yx-oxJMa_QL`DgJx*eh}iqix}Af*a+Cb*y}0&d-U1B-b`TI9cIBj7I+xmJlx6H%G(<%Ljl_xGD86* LNCZ&!C5R=%R9=)L literal 0 HcmV?d00001 diff --git a/pyrit_vsync.com b/pyrit_vsync.com new file mode 100644 index 0000000000000000000000000000000000000000..363ac03166e02c39d68021e5eb0e79b280b43df9 GIT binary patch literal 271 zcmV+q0r37$uoF+v>CF%izRNJpi0O&Q_u$d#{=;|zhR(PU5Ow6ZF-N+}pN_&{xeNdS z^i*+v4`!+u6a{MgH0Q-pt;~1b=Yx-oxJMa_QL`DgJxU{^*#X!H*udE9DgJx(*}&dRVA~yL!95mu7~VYG$=J%< V8!AHq+Z!@N0VGHSQ1&H=CByaAn2G=Z literal 0 HcmV?d00001 -- 1.8.3.1