Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
101 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

Minor Enhancements

The program in this example was made to be the simplest possible. In order to do so, a few minor enhancements were cut out. These extra procedures are used in the examples included with the kit, as well as in many example programs floating around the internet. In order for you to better understand more advanced programs, I will include these additions in the entire code posting below. The extra features will appear in bold, along with all the code from above. A short explanation of each will be given after the code posting.

#include<ps2gs.h>

int g_fd_gs;

ps2_gs_gparam  *g_gp;
ps2_gs_dbuff    g_db;
ps2_gs_finish   g_finish;

int acquire();
int release();

int main()
{
  int frame;
  int odev;
  int r = 0, g = 0, b = 255;

  g_gp = ps2_gs_get_gparam();
  acquire();
  ps2_gs_vc_graphicsmode();

  ps2_gs_set_dbuff(&g_db, PS2_GS_PSMCT32, g_gp->width,
    g_gp->height, PS2_GS_ZGREATER, PS2_GS_PSMZ24,1);
  
  ps2_gs_start_display(0);

  ps2_gs_vc_enablevcswitch(acquire, release);
  
  for(frame = 0;frame < 200 ;frame++)
  {
    ps2_gs_vc_lock();

    odev = !ps2_gs_sync_v(0);
        
    ps2_gs_set_half_offset((frame & 1) ? &g_db.draw1 :
                           &g_db.draw0, odev)

    ps2_gs_swap_dbuff(&g_db,frame);

    *(__u64*)&g_db.clear0.rgbaq =
      PS2_GS_SETREG_RGBAQ(r,g,b,0,0);
    *(__u64*)&g_db.clear1.rgbaq =
      PS2_GS_SETREG_RGBAQ(r,g,b,0,0);

    ps2_gs_put_drawenv((frame & 1) ? &g_db.giftag1 :
                       &g_db.giftag0);
    ps2_gs_set_finish(&g_finish);
    ps2_gs_wait_finish(&g_finish);
    
    ps2_gs_vc_unlock();
  }
  release();
  return 0;
}

int acquire()
{
  g_fd_gs = ps2_gs_open(-1);

  if(g_fd_gs < 0)
    return PS2_GS_VC_ACQ_FAILURE;

  ps2_gs_reset(0, PS2_GS_NOINTERLACE, PS2_GS_NTSC,
               PS2_GS_FIELD, PS2_GS_640x480, PS2_GS_60Hz);

  return PS2_GS_VC_ACQ_SUCCESS;
}

int release()
{
  if(g_fd_gs >= 0)
  {
    ps2_gs_close();
    g_fd_gs = -1;
  }

  return PS2_GS_VC_REL_SUCCESS;
}

The additions to the code do only two things. The first is enabling support for the virtual console, the second is a trick to make the resolution look doubled in interlaced mode. Virtual consoles are, well, virtual consoles. When you start up your ps2 with Linux, you can press Ctrl + Alt + F1 through Ctrl + Alt + F6 to switch in between virtual consoles. If you write your code without the addition of ps2_gs_vc_enablevcswitch the user cannot switch between virtual consoles. Ps2_gs_vc_lock locks the virtual console to the current one while settings are made and the screen is drawn, then ps2_gs_vc_unlock releases it so it can be switched again. Also, virtual consoles can have a text mode and a graphics mode. Since we are doing graphics, ps2_gs_vc_graphicsmode is used to set the virtual console to graphics mode.

Odev receives the opposite of the return value from ps2_gs_sync_v. In interlace mode ps2_gs_sync_v returns 0 for an even field or 1 for an odd field. Then the opposite of that is passed to ps2_gs_set_half_offset. If when it gets to set offset it is a 0, nothing happens; if it is a 1, the image is shifted half a pixel. Doing this makes the resolution look to be doubled. The drawing environments from the double buffer are also alternately passed to ps2_gs_set_half_offset so that the may be offset.

Please note that the above additions are not required in order to program ps2 games. Using half offset will probably be the most important later, but using the virtual console simply isn't important when it comes to just PS2 programming.


Contents
  Page 1
  Page 2

  Printable version
  Discuss this article

The Series
  Part 1: Initialization
  Part 2: Drawing Primitives