Page 1 of 2 12 LastLast
Results 1 to 10 of 14

Thread: Question about timers

  1. #1
    Administrator James's Avatar
    Join Date
    May 2010
    Location
    on the intraweb
    Posts
    3,180

    Default Question about timers

    I'm trying to put in a timer into my pong application. It will be a count down timer that will be displayed above the scores at the top of the screen. When the timer reaches 0:00 the game advances to the next level and the timer is reset.

    The problem I am running in to is that I have tried a dozen different timers and I can't seem to figure out how to make a timer run in its own thread without effecting the parent window "hWnd". I have created a new static control that will have the time printed on there, but when I put a timer on there it effects the game play (slowing everything down significantly almost to a unplayable state).

    I have tried do while loops, while loops, for loops, settimer() queryprocess timers, the time_t structure and maybe a few other methods I'm forgetting, but they all effect the game for some reason.

    Heres some code:

    The function is being called from WinMain(). Should I be calling it from somewhere else possibly?
    PHP Code:
    void CALLBACK TimerProc(HWND hwndUINT uMsgUINT idEventDWORD dwTime
    {
        
    RECT rc;
        
    GetClientRect(hWnd, &rc);
        
    int width 100;
        
    int height 50;
        
    char szBuffer[50];
        
    int counter 0;

        
    j--;
        
    //printf("Cool!\n");
        
    _stprintf_s(szBuffer,"Test: %i"counter);
        
    myTimer CreateWindowEx(0"STATIC"szBufferWS_CHILD WS_VISIBLE, ((rc.right rc.left 50) / 2), 0widthheighthWnd, (HMENU)IDS_MYTIMERhInstNULL);
        
        
    ShowWindow(myTimerSW_SHOW);
        
    UpdateWindow(myTimer);
        
    counter ++;
    }


    void drawTimer()
    {
        
    RECT rc;
        
    GetClientRect(hWnd, &rc);
        
    int width 100;
        
    int height 50;
        
    char szBuffer[50];
        
    UINT id;
        
    int counter 0;
        
    MSG msg;
        
        
    id SetTimer(myTimer03000, (TIMERPROCTimerProc);

        while(
    j
        {
            
    GetMessage(&msgNULL00);
            
    DispatchMessage(&msg);
        }
        
    KillTimer(NULLid);

        
    /*
        do
        {
            _stprintf_s(szBuffer,"Test: %i", i);
            myTimer = CreateWindowEx(0, "STATIC", szBuffer, WS_CHILD | WS_VISIBLE, ((rc.right - rc.left - 50) / 2), 0, width, height, hWnd, (HMENU)IDS_MYTIMER, hInst, NULL);
        
            ShowWindow(myTimer, SW_SHOW);
            UpdateWindow(myTimer);
            counter ++;

        }while(counter <= (5));
        */

    /*
        time_t today;
        struct tm *tm;
        today = time(0);
        tm = localtime(&today);
        tm->tm_sec = 5;
        tm->tm_hour = 0;
        tm->tm_min = 0;
        int total = 5;
        mktime(tm);


            _stprintf_s(szBuffer,"Time: %02d:%02d %i", tm->tm_min, tm->tm_sec, total);
            myTimer = CreateWindowEx(0, "STATIC", szBuffer, WS_CHILD | WS_VISIBLE, ((rc.right - rc.left - 50) / 2), 0, width, height, hWnd, (HMENU)IDS_MYTIMER, hInst, NULL);
        
            ShowWindow(myTimer, SW_SHOW);
            UpdateWindow(myTimer);
            total = (tm->tm_sec) - 1;
    */


  2. #2
    Banned
    Join Date
    May 2010
    Location
    fuck off?
    Posts
    1,145

    Default

    first you need to set a specific timer loop for your FPS count, so google QueryPerformanceCounter




    use peekmessage instead of getmessage , to speed your game up a lot.

  3. #3
    Administrator James's Avatar
    Join Date
    May 2010
    Location
    on the intraweb
    Posts
    3,180

    Default

    Hmm, maybe I'm not clear sorry.
    The only reason the game is running slow is because of this 2nd timer. The only reason I have a 2nd timer is for a countdown, I'm not sure of any other accurate way of doing a timer without affecting the gameplay. I don't want to speed up or slow down the game. I want 1 timer to control the game, and the only other timer I want is a visual timer that tells the player how many more minutes\seconds are left in the game. I just can't seem to figure out a way of doing that without effecting the game speed.

    I tried your suggestions, and still no dice.

    PHP Code:
    void StartCounter()
    {
        
    char szBuffer[1024];

        
    LARGE_INTEGER li;
        if(!
    QueryPerformanceFrequency(&li))
        {
            
    _stprintf_s(szBuffer,"QueryPerformanceFrequency failed!"NULL);
            
    SetWindowText(myTimerszBuffer);
        }

        
    PCFreq double(li.QuadPart)/1000.0;

        
    QueryPerformanceCounter(&li);
        
    CounterStart li.QuadPart;
    }
    double GetCounter()
    {
        
    LARGE_INTEGER li;
        
    QueryPerformanceCounter(&li);
        return 
    double(li.QuadPart-CounterStart)/PCFreq;
    }

    void drawTimer()
    {
        
    RECT rc;
        
    GetClientRect(hWnd, &rc);
        
    int width 100;
        
    int height 50;
        
    char szBuffer[1024];
        
    MSG msg;

        
    StartCounter();
        
    _stprintf_s(szBuffer,"Counter: %Lg"GetCounter());

        
    myTimer CreateWindowEx(0"STATIC"szBufferWS_CHILD WS_VISIBLE, ((rc.right rc.left 50) / 2), 0widthheighthWnd, (HMENU)IDS_MYTIMERhInstNULL);
        
        
    ShowWindow(myTimerSW_SHOW);
        
    UpdateWindow(myTimer);


  4. #4
    Banned
    Join Date
    May 2010
    Location
    fuck off?
    Posts
    1,145

    Default

    I think you miss understand

    QueryPerformanceCounter is for an accurate game loop, i dont even see a game loop now, and peekmessage to not slow it down.


    then you should be safe making a timer, if u have a non accurate game loop, it will run at different speeds on different computers, which is why it runs different for people on modtheater

    and then with an accurate timed game loop, u dont even need a mutex or second process running a timer loop with a call back, which just fires windows events.


    u can just use the clock and get the time ur app started, and test it ever second or so....?

    clock_t initial = clock();
    //do stuff here
    clock_t current = clock();
    float difference = (current - initial) / 1000.0f;//1000 millis = 1 second
    Last edited by Elgan; December 29th, 2011 at 10:26 AM.

  5. #5
    Über Prodigy & Developer Razo[R]apiD's Avatar
    Join Date
    May 2010
    Location
    Poland, Lublin
    Posts
    3,257

    Default

    Create a thread and do your timer there, it won't affect the game or it shouldn't.

  6. #6
    Banned
    Join Date
    May 2010
    Location
    fuck off?
    Posts
    1,145

    Default

    yes you can do that but btw you should also still setup a proper game loop

  7. #7
    Administrator James's Avatar
    Join Date
    May 2010
    Location
    on the intraweb
    Posts
    3,180

    Default

    I don't understand what you mean by game loop elg?

    Not sure if you saw my source, but I have the main window created in WinMain() then the looping is done in wndProc() via message handling.
    SO events like wm_Create, wm_Paint, wm_timers etc etc all do what they need. As far as I know this is the correct way of doing the looping. Could you show me an example of what you're referring to?

  8. #8
    Banned
    Join Date
    May 2010
    Location
    fuck off?
    Posts
    1,145

    Default

    not looked at your source but above it looks awkward.


    game loop is like the winapi one ebut somtimes u may want to use peekmessage, depends how ur loop is, and if u want ur game to have a set fps or tick count or such so that its speed is constant

  9. #9
    Administrator James's Avatar
    Join Date
    May 2010
    Location
    on the intraweb
    Posts
    3,180

    Default

    I have a bunch of custom functions that are running simultaneously and are executed based on the msg being sent. Everything works fine but the timer.
    @ RR, I did what you said, I'll give this a go and see what happens. Thanks!

    EDIT:
    Alright I think I did what RR suggested, and now I'm trying a simple function called test(), and it's not working... WTF... This shouldn't be so hard. haha.

    Here is what I did:

    PHP Code:
    void test(HWND hWndT)
    {
        
    char szBuffer[1024];
        
    int counter 0;

        for(
    int i 06++)
        {
            
    wait(1);
            
    _stprintf_s(szBuffer"Counter:"NULL);
            
    SetWindowText(myTimerszBuffer);
            
    UpdateWindow(myTimer);
            
    counter++;
        }
    }
    LRESULT CALLBACK WndProcTimer(HWND hWndTimerUINT messageWPARAM wParamLPARAM lParam)
    {
        
    PAINTSTRUCT ps;
        
    HDC hdc;
        
    RECT rc = {0};

        switch (
    message)
        {
            case 
    WM_ERASEBKGND:
            {
                return 
    TRUE;
            }
            break;

            case 
    WM_PAINT:
            {
                
    hdc BeginPaint(myTimer, &ps);            

                
    // TODO: Add any drawing code here...
                
    GetClientRect(myTimer, &rc); 
                
    AdjustWindowRectEx(&rcWS_OVERLAPPED WS_CAPTION WS_SYSMENUFALSENULL); 
                
    test(hWndTimer);
                
    ReleaseDC(myTimerhdc);

                
    EndPaint(myTimer, &ps);
            }
            break;

            case 
    WM_CREATE:
            {
                
    test(hWndTimer);
                
    SetTimermyTimerNULLUSER_TIMER_MINIMUMNULL );
            }
            break;

            case 
    WM_TIMER:
            {
                
    test(hWndTimer);
                
    GetClientRectmyTimer, &rc );
                
    InvalidateRectmyTimer, &rcTRUE );
            }
            break;

            default:
                return 
    DefWindowProc(myTimermessagewParamlParam);
        }
        return 
    0;
    }
    int APIENTRY drawTimerHINSTANCE hInstanceHINSTANCE hPrevInstanceLPSTR lpCmdLineint nCmdShow )
    {
        
    char szWindowClass[] = "myTimer";
        
    MSG msg;
        
    RECT rc;
        
    GetClientRect(hWnd, &rc);
        
    int width 100;
        
    int height 50;

        
    WNDCLASSEX wcex        = {0};
        
    wcex.cbSize            sizeof(WNDCLASSEX);
        
    wcex.style          CS_HREDRAW CS_VREDRAW;
        
    wcex.lpfnWndProc    WndProcTimer;
        
    wcex.hInstance      hInstance;
        
    wcex.hCursor        LoadCursorNULLIDC_ARROW );
        
    wcex.hbrBackground    = (HBRUSH)GetStockObject(BLACK_BRUSH);
        
    wcex.lpszClassName  szWindowClass;
        
    wcex.hIcon            LoadIcon(NULLIDI_APPLICATION);
        
    wcex.hIconSm        LoadIcon(NULLIDI_APPLICATION);
        
    RegisterClassEx( &wcex );

                
        
    //Main Application Window
        
    myTimer CreateWindowEx(0"STATIC"""WS_CHILD WS_VISIBLE, ((rc.right rc.left width) / 2), 0widthheighthWnd, (HMENU)IDS_MYTIMERhInstNULL);
        
        
    // Do stuff here


        //End

        
    if(!myTimer)
        {
            return 
    FALSE;
        }

        
    //Activate our Main Window
        
    ShowWindow(myTimernCmdShow);
        
    UpdateWindow(myTimer);

        
    //while(GetMessage(&msg, NULL, 0, 0))
        
    while(PeekMessage( &msgmyTimer00PM_REMOVE ))
        {
            
    TranslateMessage( &msg );
            
    DispatchMessage( &msg );
        }

        return (int) 
    msg.wParam;

    And I'm calling drawTimer() from the WinMain function like this:
    PHP Code:
    drawTimer(hInstancehPrevInstancelpCmdLinenCmdShow); 
    I know it's calling it correctly, because if I don't apply a transparent brush then I can see the static box that I created, but I can't seem to print text to it and I should be able to.
    I'm calling test() from WM_Create and WM_TIMER and neither work...

  10. #10
    Über Prodigy & Developer Razo[R]apiD's Avatar
    Join Date
    May 2010
    Location
    Poland, Lublin
    Posts
    3,257

    Default

    I was talking about using:

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    and SetTimer in that thread, but I don't if this will be any good for you.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •