News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Flicker

Started by Farabi, June 17, 2005, 01:50:07 PM

Previous topic - Next topic

Farabi

I use double buffer but still it flicker. Can it posible because bitblt is slow? I did saw about set thread priority function or something, can it maybe solve the problem?

What is the function name? Set thread priority? I forgot. Last time I use that function my computer smells like burn. But im not sure.

[attachment deleted by admin]
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

MichaelW

I think the problem is what used to be called "tearing". It is normally caused by the buffer update and screen refresh being out of sync. This page explains the problem and demonstrates a method of avoiding it, without having your code waste time in a polling loop. If you manage to create an ASM version of this code, I would be interested in seeing it. I saved the link so I could experiment with it, but I have never found the time to do so:

http://www.codeproject.com/gdi/tearingfreedrawing.asp

MSDN: SetPriorityClass

eschew obfuscation

Farabi

Sure. After I finish the problem I will send the source. And also what function do you suggest for this? WaitForVerticalRetrace? But it is not available on GDI function.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

MichaelW

#3
This demonstrates a minimal solution that I think should work for most systems.

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    include \masm32\include\masm32rt.inc
    include \masm32\include\ddraw.inc
    includelib \masm32\lib\ddraw.lib

    DD_OK EQU 0

    DDO_GetScanLine EQU 64
   
    DDERR_INVALIDPARAMS EQU E_INVALIDARG
    DDERR_UNSUPPORTED   EQU E_NOTIMPL
    DDERR_INVALIDOBJECT EQU ((1 shl 31) or (876h shl 16) or ( 130 ))
    DDERR_VERTICALBLANKINPROGRESS EQU ((1 shl 31)or(876h shl 16)or(537))

    DDGetScanLine PROTO scanLine:DWORD
    WaitForVerticalBlank PROTO

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
    .data
        lpdd_1      dd 0
        scanLine    dd 0
        maxScanLine dd 0
        vbStart     dd 0
        vbEnd       dd 0
        temp        dd 0
    .code
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
start:
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

    ; ------------------------------------
    ; Create a default DirectDraw object.
    ; ------------------------------------
    invoke DirectDrawCreate,NULL,ADDR lpdd_1,NULL
    .IF (eax)
        print "DirectDrawCreate failed",13,10
        jmp   fini
    .ENDIF

    ; -----------------------------------------------------------
    ; Make sure DDGetScanLine doesn't have any obvious problems.
    ; -----------------------------------------------------------
    invoke DDGetScanLine, ADDR scanLine
    .IF (eax != DD_OK)
        SWITCH (eax)
          CASE DDERR_INVALIDPARAMS
            print "DDERR_INVALIDPARAMS",13,10
          CASE DDERR_UNSUPPORTED
            print "DDERR_UNSUPPORTED",13,10
          CASE DDERR_INVALIDOBJECT
            print "DDERR_INVALIDOBJECT",13,10
        ENDSW
        jmp   fini
    .ENDIF

    ; ---------------------------------------------------
    ; Set HIGH_PRIORITY_CLASS to miminize interruptions.
    ; ---------------------------------------------------
    invoke GetCurrentProcess
    invoke SetPriorityClass, eax, HIGH_PRIORITY_CLASS

    ; ----------------------------------------------------
    ; Determine the maximum scan line, which will be the
    ; value of the scan line counter at the bottom of the
    ; top border, immediately above the first visible
    ; scan line (scan line 0).
    ; ----------------------------------------------------
    mov   ebx, 100000
    .WHILE (ebx)
        invoke DDGetScanLine, ADDR scanLine
        .IF (eax == DD_OK)
            mov   eax, scanLine
            .IF (eax > maxScanLine)
                mov   maxScanLine, eax
            .ENDIF
        .ENDIF
        dec   ebx
    .ENDW
    print "maximum scan line = "
    print ustr$(maxScanLine),13,10

    ; ----------------------------------------
    ; Determine the scan lines where vertical
    ; blank starts and ends.
    ; ----------------------------------------
    invoke DDGetScanLine, ADDR scanLine
    .WHILE (scanLine)
        invoke DDGetScanLine, ADDR scanLine
    .ENDW
    .WHILE (TRUE)
        invoke DDGetScanLine, ADDR scanLine
        .IF (eax != DDERR_VERTICALBLANKINPROGRESS)
            m2m   vbStart, scanLine
            inc   vbStart
        .ELSE
            .WHILE (eax == DDERR_VERTICALBLANKINPROGRESS)
                invoke DDGetScanLine, ADDR scanLine
            .ENDW
            m2m   vbEnd, scanLine
            .BREAK
        .ENDIF
    .ENDW
    print "vertical blank start = "
    print ustr$(vbStart),13,10
    print "vertical blank end = "
    print ustr$(vbEnd),13,10

    ; ----------------------------------------
    ; Determine the approximate refresh rate.
    ; ----------------------------------------
    invoke GetTickCount
    mov   ebx, eax
    .WHILE (eax == ebx)
        invoke GetTickCount
    .ENDW
    mov   temp, eax
    mov   ebx, 200
    .WHILE (ebx)
        invoke WaitForVerticalBlank
        dec   ebx
    .ENDW
    invoke GetTickCount
    sub   eax, temp
    mov   temp, eax
    fld8  200000.0
    fild  temp
    fdiv
    fistp temp
    print chr$("approximate refresh rate = ")
    print ustr$(temp),'Hz',13,10

    invoke GetCurrentProcess
    invoke SetPriorityClass, eax, NORMAL_PRIORITY_CLASS

  fini:   

    mov   eax, input(13,10,"Press enter to exit...")
    exit

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

DDGetScanLine proc lpScanLine:DWORD

    push  lpScanLine
    push  lpdd_1
    mov   eax, lpdd_1
    mov   eax, [eax]
    call  DWORD PTR[eax+DDO_GetScanLine]
    ret

DDGetScanLine endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««

WaitForVerticalBlank proc

    LOCAL localScanLine:DWORD

    invoke DDGetScanLine, ADDR localScanLine
    ; -------------------------------
    ; Wait until not vertical blank.
    ; -------------------------------
    .WHILE (eax == DDERR_VERTICALBLANKINPROGRESS)
        invoke DDGetScanLine, ADDR localScanLine
    .ENDW
    ; ---------------------------
    ; Wait until vertical blank.
    ; ---------------------------
    .WHILE (eax != DDERR_VERTICALBLANKINPROGRESS)
        invoke DDGetScanLine, ADDR localScanLine
    .ENDW   

    ret

WaitForVerticalBlank endp

; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
end start

eschew obfuscation

Farabi

Hai. Please test this, I heard it was crashes. Is this crashes on your computer?

http://www.geocities.com/realvampire2001/Contoh_program.zip
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Mark Jones

Both work fine for me on AMD XP SP2. :)
"To deny our impulses... foolish; to revel in them, chaos." MCJ 2003.08

brixton

Both crash for me, Win2k  :eek
If you love somebody, set them free.
If they return, they were always yours. If they don't, they never were..

MichaelW

Both work OK for me: P3, Windows 2000 SP4, default version of DirectX (8.1), default drivers for Matrox G200.


eschew obfuscation

brixton

Oops, my bad, didn't extract the sound!  :lol

Both work fine now  :U
If you love somebody, set them free.
If they return, they were always yours. If they don't, they never were..

Farabi

Thank you very much for testing it. I will upload the source soon.

Brixton:
So in Win2k if the music did not extracted it crash. Thanks for let me know about it.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

brixton

Quote from: Farabi on June 20, 2005, 12:11:41 AMBrixton:
So in Win2k if the music did not extracted it crash. Thanks for let me know about it.
Yes.  They both crashed at slightly different stages though.  :eek
If you love somebody, set them free.
If they return, they were always yours. If they don't, they never were..

Farabi

About the source I cannot post it. The size is above 256 Kbytes.
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Farabi

Here is the old source. Its disneat I hope you can understand it. Its free for you to modify or recreate it for commercial or non commercial purpose.

[attachment deleted by admin]
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

Farabi

Here is a screen shot



I cannot send the code rigth now because it still under development. It still big.

Here is the very basic function to made a circle. Unfortunately FPU is very slow. Im still find another way to make it fast and this is what I know to make it fast.

*Note: The clock information on this code is wrong*

If this code

push eax
fld dword ptr[esp]
pop eax
fimul delta
fistp r_cos

replaced with this code

; xor edx,edx
; mov ecx,delta
; mul ecx
; mov ecx,1000
; div ecx
; mov eax,r_cos

I can save time until 15 times on 1.7 GHz celeron machine. I tried it but it crashed. I dont know what causing it. When I debug it with ollydbg, it stop at this function.


GetSin proc uses esi deg:dword ; 3 Clock cycle

mov esi,SCTbl ; 1 Clock cycle
mov ecx,deg ; 1 Clock cycle
mov eax,dword ptr[esi+ecx*4] ; 1 Clock cycle

ret
GetSin endp


Ecx register on GetSin procedure point to a wrong place and reported access violation. Maybe someone here understand and can solve this?


Phase1 proc uses esi ; 28.8 Kbyte needed
LOCAL deg,sin,cos,tan:dword


invoke GlobalAlloc,LMEM_DISCARDABLE,28800+14400 + 16*10000 +768
invoke GlobalLock,eax
mov SCTbl,eax


mov esi,eax ; 1 Clock cycle
xor ecx,ecx ; 1 Clock cycle
mov deg,ecx ; 1 Clock cycle

mov edx,3600 ; 1 Clock cycle
shl edx,2 ; 2 Clock cycle


@@:
finit ; 17 Clock cycle
pushad
invoke Deg2Rad,deg ; 104 Clock cycle
popad
fsincos ; 365 Clock cycle
fstp sin ; 8 Clock cycle
fstp cos ; 8 Clock cycle

; push 1000
; fimul dword ptr[esp]
; fistp sin
; pop eax
; push 1000
; fimul dword ptr[esp]
; fistp cos
; pop eax

mov eax,sin ; 1 Clock cycle
mov dword ptr[esi],eax ; 1 Clock cycle
mov eax,cos ; 1 Clock cycle
mov dword ptr[esi+edx],eax ; 1 Clock cycle

add deg,1 ; 3 Clock cycle
add esi,4 ; 1 Clock cycle
add ecx,4 ; 1 Clock cycle
cmp deg,3600 ; 2 Clock cycle
jl @b ; 3 Clock cycle
; 513 Clock cycle Each loop
; 1846800 Clock cycle total loop
; 1846806 Clock cycle
mov esi,SCTbl
add esi,28800
;Tan
mov edx,3600 ; 1 Clock cycle
shl edx,2 ; 2 Clock cycle

xor ecx,ecx
mov deg,ecx

@@:
finit ; 17 Clock cycle
pushad
invoke Deg2Rad,deg ; 104 Clock cycle
popad
fptan ; 273 Clock cycle
fstp tan
; push 1000
; fimul dword ptr[esp]
; fistp tan
; pop eax
;
push tan
pop [esi]
add deg,1 ; 3 Clock cycle
add esi,4 ; 1 Clock cycle
add ecx,4 ; 1 Clock cycle
cmp deg,3600 ; 2 Clock cycle
jl @b ; 3 Clock cycle


mov esi,SCTbl
add esi,28800+14400
mov Line_Table,esi
mov eax,16*10000
mov nLLimit,eax
mov nLPtr,0

add esi,eax
mov SCR_TBL,esi

mov ecx,768
xor eax,eax
xor edx,edx
@@:
mov [esi+edx*4],eax
add eax,1024
dec ecx
jnz @b

ret
Phase1 endp


UMGetPosRound proc uses esi delta:dword,deg:dword ; 138 Clock cycle
LOCAL r_sin,r_cos:dword


cmp deg,3600
jl @f
sub deg,3600
@@:
invoke GetSin,deg
push eax
fld dword ptr[esp]
pop eax
fimul delta
fistp r_sin

; xor edx,edx
; mov ecx,delta
; mul ecx
; mov ecx,1000
; div ecx
; mov eax,r_sin

invoke GetCos,deg
push eax
fld dword ptr[esp]
pop eax
fimul delta
fistp r_cos

; xor edx,edx
; mov ecx,delta
; mul ecx
; mov ecx,1000
; div ecx
; mov eax,r_cos

mov edx,r_sin
mov eax,r_cos


ret
UMGetPosRound endp

GetSin proc uses esi deg:dword ; 3 Clock cycle

mov esi,SCTbl ; 1 Clock cycle
mov ecx,deg ; 1 Clock cycle
mov eax,dword ptr[esi+ecx*4] ; 1 Clock cycle

ret
GetSin endp

GetCos proc uses esi deg:dword ; 4 Clock cycle

mov esi,SCTbl ; 1 Clock cycle
add esi,14400 ; 1 Clock cycle
mov ecx,deg ; 1 Clock cycle
mov eax,dword ptr[esi+ecx*4] ; 1 Clock cycle

ret
GetCos endp

GetTan proc uses esi deg:dword ; 4 Clock cycle

mov esi,SCTbl ; 1 Clock cycle
add esi,28800 ; 1 Clock cycle
mov ecx,deg ; 1 Clock cycle
mov eax,dword ptr[esi+ecx*4] ; 1 Clock cycle

ret
GetTan endp




[attachment deleted by admin]
Those who had universe knowledges can control the world by a micro processor.
http://www.wix.com/farabio/firstpage

"Etos siperi elegi"

daydreamer

why not use bresenhams circlealgo instead?