You are not logged in.

#1 2008-07-13 13:34:17

brice05
Member

Timer function ?

hi! i'm trying to code a small game for the wii but i can't find a timer function, such as the sdl_get_ticks() function in the sdl library for windows.
for example, how can i move a rectangle of 1pixel every ten milliseconds ?
(i tried to use time.h with the clock() function but it didn't work)
thanks for the help.

Offline

 

#2 2008-07-13 22:56:58

Crayon
Bad Mother Fucker

Re: Timer function ?

I think you need to do something with usleep().

Offline

 

#3 2008-07-14 16:46:07

brice05
Member

Re: Timer function ?

thanks, but if usleep() works as the sleep() function on windows, the program will be stopped, and that's not what i was looking for. i'm trying to do something like this:

Code:

while (1)
    {
        /* Move the sprite of 1px every 10milliseconds
        actualTime = SDL_GetTicks();
        if (actualTime - previousTime > 10)
        {
            posSprite.x++;
            previousTime = actualTime; 
        }
        
        Showthesprite();
    }

Here the sprite is moving without affecting the rest of the program(contrary to the usleep() function).
Otherwise i would probably need to use threads?
but i don't know how this works, as i never used them before.

Offline

 

#4 2008-07-14 18:41:51

Crayon
Bad Mother Fucker

Re: Timer function ?

In lwip/sys.h there seems to have function for that, but I think they are not implemented.

Code:

/* For a totally minimal and standalone system, we provide null
   definitions of the sys_ functions. */
#include "arch/sys_arch.h"

struct sys_timeout {u8_t dummy;};

#define sys_init()
#define sys_timeout(m,h,a)
#define sys_untimeout(m,a)
#define sys_sem_new(c) c
#define sys_sem_signal(s)
#define sys_sem_wait(s)
#define sys_sem_free(s)
#define sys_mbox_new() 0
#define sys_mbox_fetch(m,d)
#define sys_mbox_post(m,d)
#define sys_mbox_free(m)

#define sys_thread_new(t,a,p)

Offline

 

#5 2008-07-14 18:56:31

RedShade
Member

Re: Timer function ?

Unless there is some way to change it, the highest speed you can get is 0.016 seconds per frame, 60 fps on an interlaced NTSC, all other speeds being slower (down to 0.04 seconds per frame on Standard Progressive PAL). So if you really care that much about the timing and such, you'd need your get tick count and to calculate the change per frame in terms of (velocity * time difference), the

Code:

if (actualTime - previousTime > 10){...}

would always be true

Looking at the libogc source, it uses long gettime(void); to check about button presses (if the end-start times are more than 100). We might have a header with that in it. There is also int gettick();, but I don't know how exactly that works since it is only u16.

Last edited by RedShade (2008-07-14 19:58:59)

Offline

 

#6 2008-07-15 19:46:25

brice05
Member

Re: Timer function ?

oh, the loop runs at the same speed as the framerate ?
so if the program is running on an ntsc screen, and the sprite increments itself of four pixels at each loop, it would move of (60 * 4) = 240px per second ?
so we don't need to use timing function in that case ? (if the aim is only to move the sprite)
when you code a homebrew app for the wii, how do you make a rectangle move for example ?
i was looking at a checkboard animation example and i realised that the coder only incremented of 4 the x&y at each loop to move the square around the screen, in this case the speed wouldn't be the same if played on an NTSC/PAL screen ?:

Code:

/****************************************************************************
* pflip.c
*
* libogc example for 2D video page flipping without tearing.
* Shows a checkerboard and bouncing square.
****************************************************************************/
#include <gccore.h>
#include <ogcsys.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/*** 2D Video Globals ***/
GXRModeObj *vmode;        /*** Graphics Mode Object ***/
u32 *xfb[2] = { NULL, NULL };    /*** Framebuffers ***/
int whichfb = 0;        /*** Frame buffer toggle ***/

/****************************************************************************
* CvtRGB
*
* This function simply returns two RGB pixels as one Y1CbY2Cr.
*****************************************************************************/
u32
CvtRGB (u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2)
{
  int y1, cb1, cr1, y2, cb2, cr2, cb, cr;

  y1 = (299 * r1 + 587 * g1 + 114 * b1) / 1000;
  cb1 = (-16874 * r1 - 33126 * g1 + 50000 * b1 + 12800000) / 100000;
  cr1 = (50000 * r1 - 41869 * g1 - 8131 * b1 + 12800000) / 100000;

  y2 = (299 * r2 + 587 * g2 + 114 * b2) / 1000;
  cb2 = (-16874 * r2 - 33126 * g2 + 50000 * b2 + 12800000) / 100000;
  cr2 = (50000 * r2 - 41869 * g2 - 8131 * b2 + 12800000) / 100000;

  cb = (cb1 + cb2) >> 1;
  cr = (cr1 + cr2) >> 1;

  return (y1 << 24) | (cb << 16) | (y2 << 8) | cr;
}

/****************************************************************************
* Initialise Video
*
* Before doing anything in libogc, it's recommended to configure a video
* output.
****************************************************************************/
static void
Initialise (void)
{
  VIDEO_Init ();        /*** ALWAYS CALL FIRST IN ANY LIBOGC PROJECT!
                     Not only does it initialise the video 
                     subsystem, but also sets up the ogc os
                ***/

  PAD_Init ();            /*** Initialise pads for input ***/

    /*** Try to match the current video display mode
         using the higher resolution interlaced.
    
         So NTSC/MPAL gives a display area of 640x480
         PAL display area is 640x528
    ***/
  switch (VIDEO_GetCurrentTvMode ())
    {
    case VI_NTSC:
      vmode = &TVNtsc480IntDf;
      break;

    case VI_PAL:
      vmode = &TVPal528IntDf;
      break;

    case VI_MPAL:
      vmode = &TVMpal480IntDf;
      break;

    default:
      vmode = &TVNtsc480IntDf;
      break;
    }

    /*** Let libogc configure the mode ***/
  VIDEO_Configure (vmode);

    /*** Now configure the framebuffer. 
         Really a framebuffer is just a chunk of memory
         to hold the display line by line.
    ***/

  xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));
    /*** I prefer also to have a second buffer for double-buffering.
         This is not needed for the console demo.
    ***/
  xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode));

    /*** Define a console ***/
  console_init (xfb[0], 20, 64, vmode->fbWidth, vmode->xfbHeight,
        vmode->fbWidth * 2);

    /*** Clear framebuffer to black ***/
  VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK);
  VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK);

    /*** Set the framebuffer to be displayed at next VBlank ***/
  VIDEO_SetNextFramebuffer (xfb[0]);

    /*** Get the PAD status updated by libogc ***/
  VIDEO_SetPostRetraceCallback (PAD_ScanPads);
  VIDEO_SetBlack (0);

    /*** Update the video for next vblank ***/
  VIDEO_Flush ();

  VIDEO_WaitVSync ();        /*** Wait for VBL ***/
  if (vmode->viTVMode & VI_NON_INTERLACE)
    VIDEO_WaitVSync ();

}

/****************************************************************************
* Main
*
* Create a checkerboard, and flip it
****************************************************************************/
int
main ()
{
  u32 *checkerboard;
  u32 colour1, colour2, colswap;
  int rows, cols;
  int height;
  int i, j, t, v;
  int pos = 0;
  int startx, starty;
  int directionx, directiony;

    /*** Start libOGC ***/
  Initialise ();

    /*** Allocate a buffer to hold the checkerboard ***/
  height = vmode->xfbHeight + 64;
  checkerboard = (u32 *) malloc ((704 * height * 2));
  colour1 = CvtRGB (0x00, 0x00, 0x80, 0x00, 0x00, 0x80);
  colour2 = CvtRGB (0x00, 0x00, 0xe0, 0x00, 0x00, 0xe0);

  for (i = 0; i < height; i += 32)
    {
        /*** Draw a line ***/
      colswap = colour1;
      colour1 = colour2;
      colour2 = colswap;

      for (v = 0; v < 32; v++)
    {
      for (t = 0; t < 11; t++)
        {
          for (j = 0; j < 16; j++)
        checkerboard[pos++] = colour1;

          for (j = 0; j < 16; j++)
        checkerboard[pos++] = colour2;
        }

    }
    }

  pos = 0;
  colour1 = CvtRGB (0xff, 0xff, 0xff, 0xff, 0xff, 0xff);
  startx = starty = directionx = directiony = 0;

  for (;;)
    {
        /*** Flip to off screen xfb ***/
      whichfb ^= 1;

        /*** Draw checkerboard ***/
      t = 0;
      v = 0;
      for (j = 0; j < vmode->xfbHeight; j++)
    {
      memcpy (&xfb[whichfb][v], &checkerboard[pos + t], 1280);
      t += 352;
      v += 320;
    }

        /*** Draw Bouncing Square ***/
      if (directionx)
    startx -= 4;
      else
    startx += 4;

      if (directiony)
    starty -= 2;
      else
    starty += 2;

      if (startx >= 576)
    directionx = 1;

      if (starty >= (vmode->xfbHeight - 64))
    directiony = 1;

      if (startx < 0)
    {
      startx = 0;
      directionx = 0;
    }

      if (starty < 0)
    {
      starty = 0;
      directiony = 0;
    }

      v = (starty * 320) + (startx >> 1);

      for (rows = 0; rows < 64; rows++)
    {
      for (cols = 0; cols < 32; cols++)
        xfb[whichfb][v + cols] = colour1;

      v += 320;
    }

        /*** Set this as next frame to display ***/
      VIDEO_SetNextFramebuffer (xfb[whichfb]);
      VIDEO_Flush ();
      VIDEO_WaitVSync ();

        /*** Move the checkerboard along ***/
      pos += 353;
      if (pos == ((352 * 64) + 64))
    pos = 0;
    }

  return 0;
}

crayon: i just discovered what was a thread and saw another post of yours on wiibrew http://forum.wiibrew.org/viewtopic.php?f=19&p=3940. perhaps this would be the solution as it would only block the function which calculates the x and y coordinates, and not the rest of the program.

Last edited by brice05 (2008-07-15 19:53:41)

Offline

 

#7 2008-07-15 21:14:38

RedShade
Member

Re: Timer function ?

You would want to keep graphic loops at the same speed as the frame rate, but might want to have threads if you are doing other communication, like with a USB external or network so that you can have the data transfer happening all the time. It depends on how much calculation you need to do per frame.

I have at least heard once the comment that since PAL screens are a different size, they have more screen to draw, but the decrease in frame rate allows you extra time to fill in the extra space :-P. With most stuff people are doing, I don't think they will be that strained for resources if they aren't too  sloppy.

If you want to, you could just check once about what frame rate you are running at and then never need to deal with a clock for animation purposes again. You can't animate your pictures in-between frame draws (well, shouldn't because no one would see it). If the graphics do start to lag due to heavy animation, the buffer will cause a skip and catch up again, which causes the lag effect that you see on some systems, you don't need to worry about doing that yourself (well, avoid it if at all possible anyway tongue)

Offline

 

#8 2008-07-16 00:06:04

brice05
Member

Re: Timer function ?

ok, thanks for the help, i'll adapt it to the framerate then.

Offline

 

Board footer

Powered by FluxBB