flat assembler
Message board for the users of flat assembler.

Index > Windows > how to animate an abject like circle or ellipse?!

Author
Thread Post new topic Reply to topic
dave_30



Joined: 15 Dec 2012
Posts: 14
dave_30 11 Jan 2013, 18:17
is there any way to animate an object let's say a pixel like circle or ellipse?
Post 11 Jan 2013, 18:17
View user's profile Send private message Reply with quote
HaHaAnonymous



Joined: 02 Dec 2012
Posts: 1178
Location: Unknown
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
Post 11 Jan 2013, 18:18
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20304
Location: In your JS exploiting you and your system
revolution 11 Jan 2013, 18:29
Animation is mostly just redrawing the objects in a different place for each frame. And remember to clear away the old copy else you'll get multiple copies in different places and it might look bad.
Post 11 Jan 2013, 18:29
View user's profile Send private message Visit poster's website Reply with quote
dave_30



Joined: 15 Dec 2012
Posts: 14
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!
Post 11 Jan 2013, 19:20
View user's profile Send private message Reply with quote
AsmGuru62



Joined: 28 Jan 2004
Posts: 1619
Location: Toronto, Canada
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.
Post 11 Jan 2013, 20:23
View user's profile Send private message Send e-mail Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20304
Location: In your JS exploiting you and your system
revolution 11 Jan 2013, 21:33
AsmGuru62 wrote:
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.
Well that is one way. But as to it being the best will be dependant upon the exact requirements and situation.
Post 11 Jan 2013, 21:33
View user's profile Send private message Visit poster's website Reply with quote
baldr



Joined: 19 Mar 2008
Posts: 1651
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.
Post 11 Jan 2013, 21:56
View user's profile Send private message Reply with quote
dave_30



Joined: 15 Dec 2012
Posts: 14
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?


Description:
Download
Filename: devil-game.rar
Filesize: 162.82 KB
Downloaded: 178 Time(s)

Post 12 Jan 2013, 08:18
View user's profile Send private message Reply with quote
Madis731



Joined: 25 Sep 2003
Posts: 2139
Location: Estonia
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.
Post 18 Jan 2013, 13:53
View user's profile Send private message Visit poster's website Yahoo Messenger MSN Messenger Reply with quote
Spool



Joined: 08 Jan 2013
Posts: 151
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
Post 18 Jan 2013, 20:57
View user's profile Send private message Reply with quote
tthsqe



Joined: 20 May 2009
Posts: 767
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 ?
    
Post 18 Jan 2013, 23:22
View user's profile Send private message Reply with quote
dave_30



Joined: 15 Dec 2012
Posts: 14
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  
    


Description:
Download
Filename: devil-game.rar
Filesize: 223.59 KB
Downloaded: 187 Time(s)

Post 19 Jan 2013, 20:54
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.