Weed

 


Вернулся к старой задаче(кто знает, сколько  у меня задумок?) и решил собрать старую программу XPL0 под названием weed:

\Weed.xpl       15-Jan-2009
\Plots the "Weed" function
include c:\cxpl\codesi; \intrinsic routine declarations
define  S = 100.,       \size of plotted image (scale factor)
        N = 32000.,     \number of points plotted
        Pi2 = 3.14159265*2.;
integer X, Y;           \graphic coordinates (pixels)
real    A, D;           \angle and distance (polar coordinates)
begin
SetVid($12);            \set 640x480 graphics with 16 colors
A:= 0.;                 \for A:= 0 to Pi2 do...
repeat
 D:= (1.+Sin(A)) * (1.+.9*Cos(8.*A)) * (1.+.1*Cos(24.*A)) * (.9+.05*Cos(200.*A));
 X:= Fix(D*Cos(A)*S);   \convert polar to rectangular coordinates
 Y:= Fix(D*Sin(A)*S);
 Point(X+320, 400-Y, 2\green\);
 A:= A + Pi2/N;
until A >= Pi2;
X:= ChIn(1);            \wait for a keystroke
SetVid($03);            \restore normal text mode
end;

получился .com файл размером в 17Кб, и изучение в дизассемблере вызывает уныние. Решил потренировать навыки с FPU и переписать на ассемблере. Вот только код нужно переписать(PureBasic):

If InitSprite() And OpenWindow(0,0,0,640,480,"Weed",#PB_Window_SystemMenu) And OpenWindowedScreen(WindowID(0),0,0,640,480,0,0,0) 
  StartDrawing(ScreenOutput())
  
  ;AA.f=0
  For A=0 To 32000
    AA.f=A*#PI/16000
 D.f= ( 1+Sin(AA) ) * ( 1+0.9*Cos(8*AA) ) * ( 1+0.1*Cos(24*AA) ) * (0.9+0.05*Cos(200*AA));
 X.f= Int(D*Cos(AA)*100);   \convert polar to rectangular coordinates
 Y.f= Int(D*Sin(AA)*100);
 Box (x+320,400-y,1,1,$FF000)
 ;AA=AA+2*#PI/32000
  Next A
        StopDrawing() 
        FlipBuffers() 
  Repeat 
  Until WindowEvent()=#PB_Event_CloseWindow 
EndIf
; IDE Options = PureBasic 5.30 (Windows - x86)
; CursorPosition = 5

Сегодня утром засел за код - хороший способ проснуться. Сделал всего две ошибки, после чего программа заработала.  Pouet. Вангую, что получу свиней, т.к. получилась интра 150 байт, но:

1. вряд ли выйдет 128б - не вижу способов сокращения кода.

2. Музыку я не могу втиснуть.

Все файлы тут.

Дополнение: сократили до 128 байт(HellMood)


org 100h
use16
mov al,12h
int 10h
mov ch,32000/256-1
wlp:
push cx
;   AA.f=A*#PI/16000
mov word [bp+si],cx
fldpi
fidiv word [byte bx+si-256+c1]
fimul word[bp+si]
fst dword [bp+si] ;AA
; D:= (1+Sin(A)) * (1+0.9*Cos(8*A)) * (1+0.1*Cos(24*A)) * (0.9+0.05*Cos(200*A));
FSIN
FLD1
FADDP ;ST(1) = ST(0) + ST(1),
;(1+0.9*Cos(8*A))
fld dword [bp+si]
fimul word [byte bx+si-256+c2]
fcos
fmul dword [byte bx+si-256+c3-2]
fld1
faddp
FMULP ;ST(1) = ST(0) * ST(1)
;(1+0.1*Cos(24*A))
fld dword [bp+si]
fimul word [byte bx+si-256+c6]
fcos
fmul dword [byte bx+si-256+c7-2]
fld1
faddp
FMULP
;(0.9+0.05*Cos(200*A))
fld dword [bp+si]
fimul word [byte bx+si-256+c4]
fcos
fmul dword [byte bx+si-256+c5-2]
fld dword [byte bx+si-256+c3-2]
faddp
fmulp
fimul word [byte bx+si-256+c8]
fstp dword [bp+si+4];D*S
; X:= Fix(D*Cos(A)*S); \convert polar to rectangular coordinates
; Y:= Fix(D*Sin(A)*S);
fld dword [bp+si]
fsincos
fmul dword [bp+si+4]
fistp word[bp+si] ;X
mov cx,320
add cx,[bp+si]
fmul dword [bp+si+4]
fistp word[bp+si] ;Y
mov dx,400
sub dx,word [bp+si]
; Point(X+320, 400-Y, 2\green\);
; Expects: AH 0cH
;    AL color number (+80H means XOR with current value)
;    BH video page (0-based)
;    CX graphics column
;    DX graphics row
; mov ax,0c12h
mov ah,0x0c
; xor bh,bh
int 10h
pop cx
; in al,60h
; dec al
; je exp
loop wlp
ret
c1: dw 16000
c2: dw 8
; c3: dd 0.9
c3: dw 0x3f66
c4: dw 200
; c5: dd 0.05
c5: dw 0x3d4c
c6: dw 24
; c7: dd 0.1
c7: dw 0x3dcc
c8: dw 100


Комментарии