flat assembler
Message board for the users of flat assembler.
Index
> Windows > how to animate an abject like circle or ellipse?! |
Author |
|
dave_30 11 Jan 2013, 18:17
is there any way to animate an object let's say a pixel like circle or ellipse?
|
|||
11 Jan 2013, 18:17 |
|
HaHaAnonymous 11 Jan 2013, 18:18
[ Post removed by author. ]
Last edited by HaHaAnonymous on 28 Feb 2015, 22:02; edited 1 time in total |
|||
11 Jan 2013, 18:18 |
|
dave_30 11 Jan 2013, 19:20
the problem is i'm suck at this stuff and i can't come up with an algorithm to make this work!
|
|||
11 Jan 2013, 19:20 |
|
AsmGuru62 11 Jan 2013, 20:23
Best way is to draw the whole frame in memory, erase background and all.
And then dump it onto screen. Do it in a loop, changing the object(s) coordinates. |
|||
11 Jan 2013, 20:23 |
|
revolution 11 Jan 2013, 21:33
AsmGuru62 wrote: Best way is to draw the whole frame in memory, erase background and all. |
|||
11 Jan 2013, 21:33 |
|
baldr 11 Jan 2013, 21:56
AsmGuru62, backbuffer is good for serious screen updating. revolution's right, for small deltas (like in a platformer/scroller) bitblit to the updated area is much more appreciable.
|
|||
11 Jan 2013, 21:56 |
|
dave_30 12 Jan 2013, 08:18
guys i tried circle algorithm to create the cirle animation for each dot but this is what i came up with which isn't what i want.
http://board.flatassembler.net/files/devil_game_830.rar i want each pixel to be animated in circle shape. btw,here is the function that draws the stars: Code: proc DrawStars local radius dd ? local counter dd ? pushad xor ebx,ebx mov ecx,ebx mov esi,ebx mov [counter],ebx .repeat inc ebx .if [InitStars]=0 stdcall RandomNum,0,ScreenWidth mov [fire_dusts.x+ecx],eax stdcall RandomNum,0,ScreenHeight mov [fire_dusts.y+ecx],eax stdcall RandomNum,1,2 mov [fire_dusts.speedy+ecx],eax stdcall RandomNum,1,3 mov [fire_dusts.speedx+ecx],eax stdcall RandomNum,1,0ffh mov [fire_dusts.alpha+ecx],eax .if ebx = StarCount mov [InitStars],1 .endif .else mov [radius],1 fild [counter] fsin fimul [radius] fiadd [fire_dusts.x+ecx] fistp [fire_dusts.x+ecx] fild [counter] fcos fimul [radius] fiadd [fire_dusts.y+ecx] fistp [fire_dusts.y+ecx] .if [fire_dusts.x+ecx] > ScreenWidth mov [fire_dusts.x+ecx] ,0 .endif .if [fire_dusts.x+ecx] <= 0 mov [fire_dusts.x+ecx] ,ScreenWidth .endif .if [fire_dusts.y+ecx] > ScreenHeight mov [fire_dusts.y+ecx] ,0 .endif .if [fire_dusts.y+ecx] <= 0 mov [fire_dusts.y+ecx] ,ScreenHeight .endif stdcall PutPixel,[fire_dusts.x+ecx],[fire_dusts.y+ecx],0ffffffh,0 .endif inc [counter] add ecx,StarStrcutS .until ebx = StarCount popad ret endp what i'm doing wrong here?
|
|||||||||||
12 Jan 2013, 08:18 |
|
Madis731 18 Jan 2013, 13:53
Your radius seems to be too small. Just 1 px! And try to divide counter by at leas 100 before sin() because integers 1...4 would plot like this:
http://www.wolframalpha.com/input/?i=plot+%7Bsin%281%29%2Ccos%281%29%7D%2C%7Bsin%282%29%2Ccos%282%29%7D%2C%7Bsin%283%29%2Ccos%283%29%7D%2C%7Bsin%284%29%2Ccos%284%29%7D and you wouldn't want that. If you get it working, then its probably good idea to switch over to Bresenham's circle http://en.wikipedia.org/wiki/Midpoint_circle_algorithm Because now your wasting more than 200 clocks per pixel fsincos is a very expensive instruction. |
|||
18 Jan 2013, 13:53 |
|
Spool 18 Jan 2013, 20:57
[ Post removed by author. ]
Last edited by Spool on 17 Mar 2013, 04:23; edited 1 time in total |
|||
18 Jan 2013, 20:57 |
|
tthsqe 18 Jan 2013, 23:22
I like the following way to draw stuff. It works by estimating the distance from a point to the curve defined by f(x,y)=0. In this case, I am plotting x^2+a y^2-1 = 0 and animating a.
Code: format PE GUI 5.0 entry Start include 'win32axp.inc' DIB_RGB_COLORS = 0 section '.code' code readable executable align 16 SquaredDistanceEstimate: ; plotting F(x,y)=0 ; given x at xmm0 and y at xmm1 (double precision), this should return F(x,y)^2/(gradF(x,y).gradF(x,y)) in xmm0 (single precision) ; for F(x,y) = x^2+a y^2-1, this is (x^2+a y^2-1)^2/((2x)^2+(2a y)^2) mulsd xmm0,xmm0 mulsd xmm1,xmm1 mulsd xmm1,[a] movsd xmm2,xmm1 mulsd xmm2,[a] addsd xmm1,xmm0 addsd xmm2,xmm0 subsd xmm1,[.const_1] mulsd xmm1,xmm1 mulsd xmm2,[.const_4] cvtsd2ss xmm0,xmm1 cvtsd2ss xmm1,xmm2 rcpss xmm1,xmm1 mulss xmm0,xmm1 ret align 8 .const_1: dq 1.0 .const_4: dq 4.0 align 16 ConvertToGrey: ; given # at xmm0, convert to color in eax ; min(255,1.5*255/(1+#)) mov eax,3*128 mov ecx,255 cvtsi2ss xmm1,eax rcpss xmm0,xmm0 mulss xmm1,xmm0 cvtss2si eax,xmm1 cmp eax,ecx cmova eax,ecx mov ecx,0x00010101 imul ecx ret ; these are the size of the plotted region and the width of the line align 8 scale dq 2.0 width dq 1.0 DrawBitmap: push ebp mov ebp,esp sub esp,8*8 virtual at ebp-8*8 xmin dq ? xmax dq ? xstep dq ? ymin dq ? ymax dq ? ystep dq ? fac dd ? end virtual ; a = 2 + sin(t/500) invoke GetTickCount mov dword[esp-4],eax fild dword[esp-4] mov dword[esp-4],500 fild dword[esp-4] fdivp st1,st0 fsin fld1 fadd st1,st0 faddp st1,st0 fstp qword[a] ; find the window fild [Bitmap.x] fild [Bitmap.y] fdivp st1,st0 fsqrt fld [scale] fld st0 fmul st0,st2 fst [xmax] fchs fstp [xmin] fdivrp st1,st0 fst [ymax] fchs fstp [ymin] ; find the pixel fac fild [Bitmap.x] fild [Bitmap.y] fmulp st1,st0 fld [xmax] fld [xmin] fsubp st1,st0 fld [ymax] fld [ymin] fsubp st1,st0 fmulp st1,st0 fld [width] fmulp st1,st0 fdivp st1,st0 fstp [fac] ; find xstep and ystep fld [xmax] fld [xmin] fsubp st1,st0 fild [Bitmap.x] fdivp st1,st0 fstp [xstep] fld [ymax] fld [ymin] fsubp st1,st0 fild [Bitmap.y] fdivp st1,st0 fstp [ystep] ; fill the bitmap mov ebx,[ppvBits] mov esi,[Bitmap.y] .l1: mov edi,[Bitmap.x] .l2: movsd xmm0,[xmax] movsd xmm1,[ymax] cvtsi2sd xmm2,edi cvtsi2sd xmm3,esi mulsd xmm2,[xstep] mulsd xmm3,[ystep] subsd xmm0,xmm2 ; x subsd xmm1,xmm3 ; y call SquaredDistanceEstimate mulss xmm0,[fac] call ConvertToGrey mov [ebx],eax add ebx,4 sub edi,1 jnz .l2 sub esi,1 jnz .l1 mov esp,ebp pop ebp ret ;;;;;;;;;;;;;;;;;;;; this is all standard stuff to open the window ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Start: invoke GetModuleHandle,0 mov [wc.hInstance],eax mov [hInstance],eax invoke LoadIcon,0,IDI_APPLICATION mov [wc.hIcon],eax invoke LoadCursor,0,IDC_ARROW mov [wc.hCursor],eax invoke RegisterClass,wc test eax,eax jz Error invoke CreateWindowEx,0,MainWindowClass,MainWindowTitle,WS_VISIBLE+WS_OVERLAPPEDWINDOW,100,100,600,600,NULL,NULL,[wc.hInstance],NULL mov [hMainWindow],eax test eax,eax jz Error .MsgLoop: invoke PeekMessage,msg,NULL,0,0,PM_REMOVE cmp [msg.message],WM_QUIT je .EndLoop invoke TranslateMessage,msg invoke DispatchMessage,msg add byte[PaintTimer],8 jnz .MsgLoop call Paint invoke Sleep,20 jmp .MsgLoop .EndLoop: invoke ExitProcess,[msg.wParam] Error: invoke MessageBox,NULL,_error,NULL,MB_ICONERROR+MB_OK invoke ExitProcess,0 proc WindowProc hwnd,wmsg,wparam,lparam push esi edi ebx cmp [wmsg],WM_CREATE je .wmcreate cmp [wmsg],WM_PAINT je .wmpaint cmp [wmsg],WM_SIZE je .wmsize cmp [wmsg],WM_DESTROY je .wm_destroy .defwndproc: invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam] jmp .return .wmcreate: .wmsize: invoke GetClientRect,[hwnd],rect mov eax,[rect.right] test eax,eax jz .returnz mov eax,[rect.right] mov ecx,[rect.bottom] mov [Bitmap.x],eax mov [Bitmap.y],ecx mov ecx,[hBitmap] test ecx,ecx jz .wmpaint_newbm jmp .wmpaint_redobm .wmpaint: invoke GetClientRect,[hMainWindow],rect mov eax,[rect.right] mov ecx,[hBitmap] test eax,eax jz .returnz test ecx,ecx jz .wmpaint_newbm .wmpaint_ok: call Paint jmp .returnz .wmpaint_redobm: invoke DeleteObject,[hBitmap] .wmpaint_newbm: mov [bmiheader.biSize],sizeof.BITMAPINFOHEADER mov eax,[Bitmap.x] mov [bmiheader.biWidth],eax mov eax,[Bitmap.y] neg eax mov [bmiheader.biHeight],eax mov [bmiheader.biPlanes],1 mov [bmiheader.biBitCount],32 mov [bmiheader.biCompression],BI_RGB mov eax,[Bitmap.x] imul eax,[Bitmap.y] lea eax,[4*eax+16] mov [bmiheader.biSizeImage],eax mov [bmiheader.biXPelsPerMeter],0 mov [bmiheader.biYPelsPerMeter],0 mov [bmiheader.biClrUsed],0 mov [bmiheader.biClrImportant],0 invoke CreateDIBSection,0,bmiheader,DIB_RGB_COLORS,ppvBits,0,0 mov [hBitmap],eax jmp .wmpaint_ok .wm_destroy: invoke PostQuitMessage,0 .returnz: xor eax,eax .return: pop ebx edi esi ret endp Paint: cmp [hBitmap],0 je .Done invoke InvalidateRect,[hMainWindow],rect,FALSE invoke BeginPaint,[hMainWindow],ps mov [hdc],eax invoke CreateCompatibleDC,eax test eax,eax jz Error mov [hMemDC],eax call DrawBitmap invoke SelectObject,[hMemDC],[hBitmap] invoke BitBlt,[hdc],0,0,[rect.right],[rect.bottom],[hMemDC],0,0,SRCCOPY invoke DeleteDC,[hMemDC] invoke EndPaint,[hMainWindow],ps .Done: ret section '.idata' import data readable writeable library kernel32,'KERNEL32.DLL',\ user32,'USER32.DLL',\ gdi32,'GDI32.DLL' include 'api\kernel32.inc' include 'api\user32.inc' include 'api\gdi32.inc' section '.data' data readable writeable align 4 wc WNDCLASS 0,WindowProc,0,0,NULL,NULL,NULL,COLOR_BTNFACE+1,NULL,MainWindowClass align 1 MainWindowTitle db 'plot', 0 MainWindowClass db 'plot32', 0 _error TCHAR 'Startup failed.',0 align 8 a dq 2.0 align 4 hMainWindow dd ? hStatusWindow dd ? hMainMenu dd ? hInstance dd ? ppvBits dd ? hMemDC dd ? hdc dd ? hBitmap dd ? Bitmap.x dd ? Bitmap.y dd ? TickCount dd ? bmiheader BITMAPINFOHEADER ps PAINTSTRUCT rc RECT rect RECT msg MSG align 1 PaintTimer db ? |
|||
18 Jan 2013, 23:22 |
|
dave_30 19 Jan 2013, 20:54
thx for the help guys.
i just been able to make it and here is the application. but there is a problem.i can't slow down the moving speed of pixels and even if i change the values of the radius and delta still nothing happens and even gets worse and i feel like pixels doesn't moves smooth and animation doesn't looks good and pixels does freezes at some point. how i can fix this? here is the new proc: Code: proc DrawDusts pushad xor ebx,ebx mov ecx,ebx mov edx,[fire_dustva] .repeat inc ebx fld [fire_dusts.anglex+ecx] fadd [fire_dusts.deltax+ecx] fst [fire_dusts.anglex+ecx] fcos fmul [fire_dusts.radiusx+ecx] frndint fiadd [fire_dusts.x+ecx] fistp [fire_dusts.x+ecx] fld [fire_dusts.angley+ecx] fadd [fire_dusts.deltay+ecx] fst [fire_dusts.angley+ecx] fsin fmul [fire_dusts.radiusy+ecx] frndint fiadd [fire_dusts.y+ecx] fistp [fire_dusts.y+ecx] fild [fire_dusts.y+ecx] fisub [fire_dusts.speedy+ecx] fistp [fire_dusts.y+ecx] .if [fire_dusts.x+ecx] > ScreenWidth mov [fire_dusts.x+ecx] ,0 .endif .if [fire_dusts.x+ecx] <= 0 mov [fire_dusts.x+ecx] ,ScreenWidth .endif .if [fire_dusts.y+ecx] > ScreenHeight mov [fire_dusts.y+ecx] ,0 .endif .if [fire_dusts.y+ecx] <= 0 mov [fire_dusts.y+ecx] ,ScreenHeight .endif stdcall PutPixel,[fire_dusts.x+ecx] ,[fire_dusts.y+ecx],0xe8430d,[fire_dusts.alpha+ecx] add ecx,sizeof.fire_dust .until ebx = DustCount popad ret endp and here is the proc which initializes the pixels: Code: proc InitDusts pushad invoke HeapAlloc,[App.ProcessHeap],HEAP_ZERO_MEMORY,sizeof.fire_dust*DustCount mov [fire_dustva],eax mov ebx,eax invoke HeapLock,[App.ProcessHeap] mov edx,ebx xor ebx,ebx mov ecx,ebx .repeat inc ebx stdcall RandomNum,0,ScreenWidth mov [fire_dusts.x+ecx],eax stdcall RandomNum,0,ScreenHeight mov [fire_dusts.y+ecx],eax stdcall RandomNum,1,255 mov [fire_dusts.alpha+ecx],eax stdcall RndFloatNum,0.7,1.5 mov [fire_dusts.radiusx+ecx],eax stdcall RndFloatNum,0.7,1.5 mov [fire_dusts.radiusy+ecx],eax stdcall RndFloatNum,0.04,0.07 mov [fire_dusts.deltax+ecx],eax stdcall RndFloatNum,0.04,0.07 mov [fire_dusts.deltay+ecx],eax stdcall RandomNum,1,3 mov [fire_dusts.speedx+ecx],eax stdcall RandomNum,1,3 mov [fire_dusts.speedy+ecx],eax add ecx,sizeof.fire_dust .until ebx = DustCount popad ret endp cos of the animation i had to create random float number generator. Code: proc RandomNum val1:DWORD,val2:DWORD pushad inc [val2] .repeat rdtsc xor eax,edx xor edx,edx idiv [val2] .if dword [val1] > edx add edx,[val1] .endif .if byte [flag] = 0 mov byte [flag],1 .else cmp edx,[OldVal] jne done .until edx <> [OldVal] done: .endif mov [OldVal],edx popad mov eax,[OldVal] ret endp proc RndFloatNum val1:DWORD,val2:DWORD .repeat stdcall RandomNum,0,999999999 push eax fld dword [val2] fadd [val1] fild dword [esp] fprem fstp dword [esp] fstp st0 mov eax,[esp] add esp,4 .if eax < [val1] mov eax,[val1] .elseif eax > [val2] mov eax,[val2] .endif .if byte [flag] = 1 mov byte [flag],2 .else cmp eax,[OldValF] jne sk .until eax <> [OldValF] sk: .endif mov [OldValF],eax ret endp
|
|||||||||||
19 Jan 2013, 20:54 |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.