Gp2x Minimal Library [by Rlyeh]


ks5202

Still Fresh
Joined
Nov 14, 2005
Messages
16
/*
GP2X minimal library by rlyeh, 2005.
Thanks to Squidge and Robster! :)
*/

#include <fcntl.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>
#include <linux/fb.h>


int memdev;
u16 *memdd;


void gp2x_reg_init(void)
{
memdev = open("/dev/mem", O_RDWR);
memdd=(u16 *)mmap(0, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
}

#define gp2x_reg_read(addr) memdd[addr >> 1]

#define gp2x_reg_write(addr, data) memdd[addr >> 1]=data


/*
GP2X Video library w/ double buffering by rlyeh, 2005.
Thanks to Squidge and Robster for the help! :)
*/

u16 *gp2x_screen[2], *screen;
u32 gp2x_screenc=0,fbdev[2],smem_start[2];

void gp2x_video_flip (void)
{
u32 nBufferAddress=smem_start[gp2x_screenc];

screen=gp2x_screen[gp2x_screenc^=1];

gp2x_reg_write (0x290E, (unsigned short)(nBufferAddress & 0xffff));
gp2x_reg_write (0x2910, (unsigned short)(nBufferAddress >> 16));
gp2x_reg_write (0x2912, (unsigned short)(nBufferAddress & 0xffff));
gp2x_reg_write (0x2914, (unsigned short)(nBufferAddress >> 16));
}

void gp2x_video_init (void)
{
struct fb_fix_screeninfo fixed_info;

fbdev[0]=open("/dev/fb0", O_RDWR);
fbdev[1]=open("/dev/fb1", O_RDWR);

ioctl (fbdev[0], FBIOGET_FSCREENINFO, &fixed_info);
smem_start[0]=fixed_info.smem_start;
gp2x_screen[0]=(u16 *)mmap(0, 320*240*sizeof(u16), PROT_WRITE, MAP_SHARED, fbdev[0], 0);

ioctl (fbdev[1], FBIOGET_FSCREENINFO, &fixed_info);
smem_start[1]=fixed_info.smem_start;
gp2x_screen[1]=(u16 *)mmap(0, 320*240*sizeof(u16), PROT_WRITE, MAP_SHARED, fbdev[1], 0);

gp2x_video_flip();
gp2x_video_flip();
}



/*
GP2x joystick library by rlyeh, 2005.
Thanks to Squidge for his previous work! :)
*/

#define GP2X_UP (0x01)
#define GP2X_LEFT (0x04)
#define GP2X_DOWN (0x10)
#define GP2X_RIGHT (0x40)
#define GP2X_START (1<<8)
#define GP2X_SELECT (1<<9)
#define GP2X_L (1<<10)
#define GP2X_R (1<<11)
#define GP2X_A (1<<12)
#define GP2X_B (1<<13)
#define GP2X_X (1<<14)
#define GP2X_Y (1<<15)
#define GP2X_VOLM (1<<22)
#define GP2X_VOLP (1<<23)
#define GP2X_PUSH (1<<27)

u32 gp2x_joystick_read(void)
{
u32 value=(gp2x_reg_read(0x1198) & 0x00FF);

if(value==0xFD) value=0xFA;
if(value==0xF7) value=0xEB;
if(value==0xDF) value=0xAF;
if(value==0x7F) value=0xBE;

return ~((gp2x_reg_read(0x1184) & 0xFF00) | value | (gp2x_reg_read(0x1186) << 16));
}




/*
GP2x soundring buffer library by rlyeh, 2005.
*/

#define SOUND_DEVICE_BUFFSIZE (44100/60)
int sound_fd=0;
u32 sound_numsamples, sound_samplesize;
s16 sound_fd_buffer[SOUND_DEVICE_BUFFSIZE*4];

u32 gp2x_sound_init(u32 rate, u32 bits, u32 stereo)
{
int tmp;

if ( sound_fd ) { close(sound_fd); sound_fd=0; }

/* Open sound device */
if ( (sound_fd = open( "/dev/dsp", O_WRONLY )) < 0 )
return (sound_fd = 0);

/* Setting signed 16-bit format */
tmp = (bits == 16 ? AFMT_S16_LE : AFMT_U8);
if ( ioctl(sound_fd, SNDCTL_DSP_SETFMT, &tmp) < 0 )
{ close(sound_fd); return (sound_fd = 0); }

/* Setting stereo mode */
tmp = stereo;
if ( ioctl(sound_fd, SNDCTL_DSP_STEREO, &tmp) < 0 )
{ close(sound_fd); return (sound_fd = 0); }

/* Setting sample rate */
tmp = rate;
if ( ioctl(sound_fd, SNDCTL_DSP_SPEED, &tmp) < 0 )
{ close(sound_fd); return (sound_fd = 0); }

sound_numsamples=SOUND_DEVICE_BUFFSIZE/(44100/rate);
sound_samplesize=sound_numsamples << (stereo + (bits==16));

/* Successful */
return 1;
}


void gp2x_sound_deinit(void)
{
if ( sound_fd ) close(sound_fd);
}


void gp2x_sound_play(void)
{
if( sound_fd )
{
sound_frame(NULL, &sound_fd_buffer[0], sound_numsamples);
write( sound_fd, &sound_fd_buffer[0], sound_samplesize);
}
}








/*
GP2X misc options by rlyeh, 2005.
*/


void gp2x_backtomenu(void)
{
chdir("/usr/gp2x");
execl("gp2xmenu",NULL);
}


void gp2x_deinit(void)
{
//SDL_Quit(); //I use it for timers

gp2x_sound_deinit();
close(memdev);

close(fbdev[0]);
close(fbdev[1]);
}

void gp2x_init(u32 rate, u32 bits, u32 stereo)
{
gp2x_reg_init();

gp2x_sound_init(rate, bits, stereo);
gp2x_video_init();

//SDL_Init(0); //I use it for timers
}



/*

EXAMPLE
=======

now supply your own function for 16 bits, stereo:

void sound_frame(void *blah, void *bufferg, int samples)
{
signed short *buffer=(signed short *)bufferg;
while(samples--)
{
*buffer++=0; //Left channel
*buffer++=0; //Right channel
}
}

or for 8 bits, mono:

void sound_frame(void *blah, void *bufferg, int samples)
{
unsigned char *buffer=(unsigned char *)bufferg;
while(samples--)
{
*buffer++=0; //Central channel
}
}


and done...

int main(int argc, char *argv[])
{
gp2x_init(44100,16,1);

while(1)
{
screen[160+120*320]=0xFFFF; //pixel is RGB:565
gp2x_video_flip();
}

gp2x_deinit();

}

*/
---------------------------------------
copyed in http://www.emulnation.info/retrodev/
 
Very cool. So, I've done a bit of SDL before; anything I should be aware of if I'm testing on a PC? I see you're doing dev at 320x240; are there any additional video modes? (I heard that you can get 720x??? from the TV-out.)
 
Before this gets lost in the forums, could you add it to the wiki?

http://wiki.gp2x.org.

Just register and you can edit and add new pages.
 
great ! thanks.

i'm going to restructure the wiki a bit when i have time.

making a comprehensive list of "sdk's", the different ways of how to get started, etc etc
 
great ! thanks.

i'm going to restructure the wiki a bit when i have time.

making a comprehensive list of "sdk's", the different ways of how to get started, etc etc
I've got a C++ 16.16 fixed-point math library from back in the day that I've recently cleaned up, and I'm planning on releasing as soon as I've tested it on the gp2x (should be arriving this weekend :D). The license will probably be zlib. As a teaser, here's part of the header file:

Code:
  // functions
  friend char *fixtoa(const Fix& f, char *buffer);
  friend Fix floor(const Fix& f);
  friend Fix ceil(const Fix& f);
  friend Fix round(const Fix& f);
  friend Fix abs(const Fix& f);
  friend int sgn(const Fix& f);
  friend Fix scalb(const Fix& f,long exp);  // returns x * 2^exp
  friend Fix sin(const Fix& a);
  friend Fix cos(const Fix& a);
  friend Fix tan(const Fix& a);
  friend Fix asin(const Fix& f);
  friend Fix acos(const Fix& f);
  friend Fix atan(const Fix& f);
  friend Fix atan2(const Fix& y,const Fix& x);  // returns atan(y/x)
  friend Fix exp(const Fix& f);
  friend Fix log(const Fix& f);
  friend Fix sqrt(const Fix& f);
 
Last edited by a moderator:
Back
Top