From 97d8594f28e0f6cfb1aaa994a5e60099286d49bd Mon Sep 17 00:00:00 2001 From: Ivan Baravy Date: Mon, 17 Feb 2020 02:52:40 +0000 Subject: [PATCH] Add Newton fractal demo. Accepts @ss parameter to run as a screen saver. Written in UASM by 0CorErr. Translated to FASM by dunkaist. git-svn-id: svn://kolibrios.org@7723 a494cfbc-eb01-0410-851d-a64ba20cac60 --- programs/demos/newton_fractal/Tupfile.lua | 4 + programs/demos/newton_fractal/newfract.asm | 379 +++++++++++++++++++++ 2 files changed, 383 insertions(+) create mode 100644 programs/demos/newton_fractal/Tupfile.lua create mode 100644 programs/demos/newton_fractal/newfract.asm diff --git a/programs/demos/newton_fractal/Tupfile.lua b/programs/demos/newton_fractal/Tupfile.lua new file mode 100644 index 0000000000..decfa7850e --- /dev/null +++ b/programs/demos/newton_fractal/Tupfile.lua @@ -0,0 +1,4 @@ +if tup.getconfig("NO_FASM") ~= "" then return end +HELPERDIR = (tup.getconfig("HELPERDIR") == "") and "../.." or tup.getconfig("HELPERDIR") +tup.include(HELPERDIR .. "/use_fasm.lua") +tup.rule("newfract.asm", FASM .. " %f %o " .. tup.getconfig("KPACK_CMD"), "newfract") diff --git a/programs/demos/newton_fractal/newfract.asm b/programs/demos/newton_fractal/newfract.asm new file mode 100644 index 0000000000..0933b33a7d --- /dev/null +++ b/programs/demos/newton_fractal/newfract.asm @@ -0,0 +1,379 @@ +; +; Newton fractal demo +; +; Written in UASM by 0CorErr +; Translated to FASM by dunkaist +; + +use32 + org 0 + db 'MENUET01' + dd 0x01,start,i_end,e_end,e_end,params,0 + +include 'proc32.inc' +include 'macros.inc' + +WS_DRAW_NOTHING = 0x0100_0000 +WS_SKINNED_FIXED = 0x0400_0000 +WS_BACKGROUND_NOREDRAW = 0x4000_0000 +WS_COORD_CLIENT = 0x2000_0000 +WS_CAPTION = 0x1000_0000 + +CS_MOVABLE = 0 + +WINDOW_STATE_ROLLED_UP = 4 + +WINDOW_BORDER_SIZE = 5 + +;COUNT = 16 +COUNT = 100 + +struct TSize + SizeY dw ? + SizeX dw ? +ends + +struct TBox + X dd ? + Y dd ? + SizeX dd ? + SizeY dd ? +ends + +struct Complex + X dd ? + Y dd ? +ends + + +proc get_newton_fractal uses ebx edi, _width, _height +locals + Pow2_Z_X dd ? + Pow2_D_X dd ? + Pow2_T_Y dd ? + Pow2_T_X dd ? + P dd ? + N dd ? + YMax dd ? + XMax dd ? + Y dd ? + X dd ? + D Complex + T Complex + Z Complex + Buf dd ? + ImgH dd ? + ImgW dd ? +endl + mov eax, [_width] + mov [ImgW], eax + shr eax, 1 + mov [XMax], eax + + mov eax, [_height] + mov [ImgH], eax + shr eax, 1 + mov [YMax], eax + + mov eax, [ImgH] + dec eax + imul eax, [ImgW] + mov [line_shift], eax + + ; allocate buffer for image + mov ecx, [ImgW] + imul ecx, [ImgH] + mcall 68, 12, + mov [Buf], eax + + mov edi, [Buf] + mov eax, [YMax] + neg eax + mov [Y], eax +.next_line: + mov eax, [XMax] + neg eax + mov [X], eax +.next_pixel: + mov [N], 0 + fild [X] + fdiv [Float_250] + fstp [Z.X] + fild [Y] + fdiv [Float_250] + fstp [Z.Y] + mov eax, [Z.X] + mov ecx, [Z.Y] + mov [D.X], eax + mov [D.Y], ecx +@@: + fld [Z.X] + fmul st0, st0 + fstp [Pow2_Z_X] + fld [Z.Y] + fmul st0, st0 + fadd [Pow2_Z_X] + fcomp [Max] + fnstsw ax +;.Break .If !(ah & 1) ; >= Max + test ah, 1 + jz @f + fld [D.X] + fmul st0, st0 + fstp [Pow2_D_X] + fld [D.Y] + fmul st0, st0 + fadd [Pow2_D_X] + fcomp [Min] + fnstsw ax +;.Break .If ah & 1 ; <= Min + test ah, 1 + jnz @f + mov eax, [Z.X] + mov ecx, [Z.Y] + mov [T.X], eax + mov [T.Y], ecx + + fld [T.X] + fmul st0, st0 ; Pow2_T_X = T.X * T.X + fstp [Pow2_T_X] + + fld [T.Y] + fmul st0, st0 + fst [Pow2_T_Y] ; Pow2_T_Y = T.Y * T.Y + fadd [Pow2_T_X] + fmul st0, st0 + fstp [P] ; P = (Pow2_T_X + Pow2_T_Y) * (Pow2_T_X + Pow2_T_Y) + + fld [Pow2_T_X] + fsub [Pow2_T_Y] + fld [Float_3] + fmul [P] + fxch st1 + fdivrp ; Z.X = (Pow2_T_X - Pow2_T_Y) / (3 * P) + 2 * T.X / 3 + fld [Float_2] + fmul [T.X] + fdiv [Float_3] + fxch st1 + faddp + fstp [Z.X] + + fld [P] + fsub [T.X] + fdiv [P] + fmul [T.Y] ; Z.Y = (P - T.X) / P * 2 * T.Y / 3 + fmul [Float_2] + fdiv [Float_3] + fstp [Z.Y] + + fld [T.X] + fsub [Z.X] + fabs + fstp [D.X] + + fld [T.Y] + fsub [Z.Y] + fabs + fstp [D.Y] + + inc [N] + cmp [N], COUNT + jbe @b +@@: + mov eax, [N] + mov ecx, palette_colors + xor edx, edx + div ecx + + ; Set next pixel + mov [edi], dl + mov eax, [line_shift] + mov [edi+eax], dl + inc edi + mov eax, [X] + inc eax + mov [X], eax + cmp eax, [XMax] + jnz .next_pixel + + mov eax, [ImgW] + add eax, eax + sub [line_shift], eax + mov eax, [Y] + inc eax + mov [Y], eax + cmp eax, 0 + jle .next_line +.done: + mov eax, [Buf] + ret +endp + + +start: + mcall 68, 11 + cmp dword[params], '@ss' + setz [screensaver] + jnz .windowed + ; fullscreen + mcall 14 + movzx ecx, ax + shr eax, 16 + mov [Window.SizeX], eax + mov [Window.SizeY], ecx + xor [window_style], WS_SKINNED_FIXED + WS_DRAW_NOTHING + mov [window_border_size], 0 + mov [skin_height], 0 + + mov edi, transparent_cursor + xor eax, eax + mov ecx, 32*32 + rep stosd + mcall 37, 4, transparent_cursor, 2 + mov ecx, eax + mcall 37, 5 + + mov ebx, EVM_REDRAW + EVM_KEY + EVM_BUTTON + EVM_MOUSE + jmp .common +.windowed: + mcall 48, 4 + mov [skin_height], eax + bt eax, 0 + sbb [Window.SizeY], 0 + mcall 14 + movzx ecx, ax + shr eax, 16 + sub eax, [Window.SizeX] + sub ecx, [Window.SizeY] + shr eax, 1 + shr ecx, 1 + mov [Window.X], eax + mov [Window.Y], ecx + + mov ebx, EVM_REDRAW + EVM_KEY + EVM_BUTTON +.common: + mcall 40 + + mov ebx, [Window.SizeX] + inc ebx + sub ebx, [window_border_size] + sub ebx, [window_border_size] + mov ecx, [Window.SizeY] + inc ecx + sub ecx, [skin_height] + sub ecx, [window_border_size] + stdcall get_newton_fractal, ebx, ecx + mov [image], eax + +.still: +; mcall 11 +; dec eax +; jz .redraw +; jns .exit +; mcall 5, 10 + mcall 10 + dec eax + jnz .exit +.redraw: + mcall 12, 1 + mcall 0, <[Window.X],[Window.SizeX]>, <[Window.Y],[Window.SizeY]>, [window_style], 0, window_title + mcall 9, proc_info, -1 + test [proc_info.wnd_state], WINDOW_STATE_ROLLED_UP + jnz .no_draw + inc [proc_info.client_box.width] + inc [proc_info.client_box.height] + mcall 65, [image], <[proc_info.client_box.width],[proc_info.client_box.height]>, 0, 8, palette, 0 +; call rotate_palette +.no_draw: + mcall 12, 2 + jmp .still +.exit: + mcall -1 + + +proc rotate_palette + mov esi, palette + mov edi, esi + mov ecx, palette_colors +.next_color: + mov ebx, 2 + lodsd +.next_channel: + cmp [palette_rotate_direction+ebx], 1 + jnz .down +.up: + add al, 1 + jnc .ok + btc word[palette_rotate_direction+ebx], 0 + sub al, 1 +.down: + sub al, 1 + jnc .ok + btc word[palette_rotate_direction+ebx], 0 + add al, 2 +.ok: + ror eax, 8 + dec ebx + jns .next_channel + ror eax, 8 + stosd + dec ecx + jnz .next_color + ret +endp + +palette: + dd 0x00C5037D, 0x006D398B, 0x00454E99, 0x002A71AF, \ + 0x000696BB, 0x00008F5A, 0x008DBB25, 0x00F3E500, \ + 0x00FCC609, 0x00F28E1C, 0x00E96220, 0x00E32322 +palette_colors = ($-palette)/4 + +; dd 0x00C21460, 0x008601AF, 0x004424D6, 0x000247FE, \ +; 0x00347C98, 0x0066B032, 0x00B2D732, 0x00FEFE33, \ +; 0x00FCCC1A, 0x00FB9902, 0x00FC600A, 0x00FE2712 + +; dd 0x00C21460, 0x008601AF, 0x004424D6, 0x00347C98, \ +; 0x0066B032, 0x00B2D732, 0x00FCCC1A, 0x00FB9902, \ +; 0x00FC600A + +; dd 0x00C21460, 0x004424D6, 0x00347C98, 0x0066B032, \ +; 0x00B2D732, 0x00FEFE33, 0x00FCCC1A, 0x00FC600A, \ +; 0x00FE2712 + +; dd 0x00FE2712, 0x00FC600A, 0x00FCCC1A, 0x00FEFE33, \ +; 0x00B2D732, 0x0066B032, 0x00347C98, 0x004424D6, \ +; 0x00C21460 + +; dd 0x00347C98, 0x004424D6, 0x00C21460, 0x00FE2712, \ +; 0x00FC600A, 0x00FCCC1A, 0x00FEFE33, 0x00B2D732, \ +; 0x0066B032 + +Float_250 dd 250.0 +Float_3 dd 3.0 +Float_2 dd 2.0 + +;Max dd 10000.0 +;Min dd 0.0001 +Max dd 10000000.0 +Min dd 0.0000001 + +Window TBox 0, 0, 320*3+1, 240*3+1 +window_style dd WS_SKINNED_FIXED + WS_COORD_CLIENT + WS_CAPTION + \ + WS_BACKGROUND_NOREDRAW +window_border_size dd WINDOW_BORDER_SIZE +image dd 0 +line_shift dd 0 +;palette_rotate_direction db 1, 0, 1, 0 +window_title db "Newton fractal",0 + +i_end: +align 4 +proc_info process_information + +transparent_cursor rd 32*32 +skin_height dd ? +screensaver db ? +params rb 0x400 +align 4 +rb 0x200 +e_end: