diff --git a/src/Makefile-gp2x b/src/Makefile-gp2x new file mode 100644 index 0000000..e943db6 --- /dev/null +++ b/src/Makefile-gp2x @@ -0,0 +1,22 @@ +all: alien + +CC=arm-open2x-linux-gcc +SDL_CFLAGS = `sdl-config --cflags` +SDL_LIBS = `sdl-config --libs` +CFLAGS=-DNDEBUG -Wall $(SDL_CFLAGS) -DGP2X -O2 -pipe -march=armv4t -mtune=arm920t -ftree-vectorize -ffast-math -fsingle-precision-constant +OBJS=\ + client.o common.o vm.o sprites.o decode.o animation.o \ + rooms.o render.o main.o music.o debug.o lzss.o \ + sound.o screen.o scale2x.o scale3x.o game2bin.o cd_iso.o \ + scale800x480.o + +LIBS=-s -L`sdl-config --prefix`/lib/mixer-ogg -lSDL_mixer $(SDL_LIBS) -lvorbisidec -lvorbisfile -lm -larmmem -static + +alien: $(OBJS) + $(CC) -o $@ $(OBJS) $(LIBS) + +.c.o: + $(CC) $(CFLAGS) -c $< -o $@ + +clean: + @rm $(OBJS) diff --git a/src/main.c b/src/main.c index 5cb4874..4e63aa4 100644 --- a/src/main.c +++ b/src/main.c @@ -23,6 +23,15 @@ #include #include #include +#if defined(GP2X) + #include + #include + #include + #include + #if (SDL_MAJOR_VERSION > 1 || SDL_MAJOR_VERSION == 1 && (SDL_MINOR_VERSION > 2 || SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 9 ) ) + #include + #endif +#endif #include "client.h" #include "vm.h" @@ -137,14 +146,116 @@ static void atexit_callback(void) SDL_Quit(); } +#if defined(GP2X) +static int InitialVolume; + +// Set new GP2X mixer level, 0-100 +static void Set_GP2X_Volume (int newvol) +{ + int soundDev, vol; + + if ((newvol >= 0) && (newvol <= 100)) + { + soundDev = open("/dev/mixer", O_RDWR); + if (soundDev != -1) + { + vol = ((newvol << 8) | newvol); + ioctl(soundDev, SOUND_MIXER_WRITE_PCM, &vol); + close(soundDev); + } + } +} + +// Returns 0-100, current mixer volume, -1 on error. +static int Get_GP2X_Volume (void) +{ + int soundDev, vol; + + vol = -1; + soundDev = open("/dev/mixer", O_RDONLY); + if (soundDev != -1) + { + ioctl(soundDev, SOUND_MIXER_READ_PCM, &vol); + close(soundDev); + if (vol != -1) + { + //just return one channel , not both channels, they're hopefully the same anyways + return (vol & 0xFF); + } + } + + return vol; +} + +static void Set_Initial_GP2X_Volume (void) +{ + Set_GP2X_Volume(InitialVolume); +} + +static void Change_HW_Audio_Volume (int amount) +{ + int current_volume; + + current_volume = Get_GP2X_Volume(); + + if (current_volume == -1) current_volume = 68; + + if ((amount > 1) && current_volume < 12) + { + amount = 1; + } + else if ((amount < -1) && current_volume <= 12) + { + amount = -1; + } + + current_volume += amount; + + if (current_volume > 100) + { + current_volume = 100; + } + else if (current_volume < 0) + { + current_volume = 0; + } + Set_GP2X_Volume(current_volume); +} +#endif + static int initialize() { +#if defined(GP2X) + InitialVolume = Get_GP2X_Volume(); + atexit(Set_Initial_GP2X_Volume); +#endif + SDL_Init(SDL_INIT_VIDEO|SDL_INIT_CDROM|SDL_INIT_AUDIO); atexit(atexit_callback); +#if defined(GP2X) + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK)<0) + { + panic("failed to initialize SDL joystick subsystem"); + } + SDL_JoystickOpen(0); +#if defined(SDL_GP2X__H) + if (SDL_GP2X_MouseType() == GP2X_MOUSE_TOUCHSCREEN) + { + SDL_GP2X_TouchpadMouseMotionEvents(0); + SDL_GP2X_TouchpadMouseButtonEvents(0); + } +#endif +#endif + if (cls.nosound == 0) { - if (Mix_OpenAudio(44100, AUDIO_S16, 2, 4096) < 0) +#if defined(GP2X) +#define MIX_BUFFER_SIZE 1024 +#else +#define MIX_BUFFER_SIZE 4096 +#endif + if (Mix_OpenAudio(44100, AUDIO_S16, 2, MIX_BUFFER_SIZE) < 0) { panic("Mix_OpenAudio failed\n"); } @@ -173,6 +284,10 @@ static int initialize() panic("failed to create video surface"); } +#if defined(GP2X) + Set_Initial_GP2X_Volume(); +#endif + return 0; } @@ -642,6 +757,127 @@ void check_events() } break; +#if defined(GP2X) +// GP2X buttons +#define GP2X_BUTTON_UP (0) +#define GP2X_BUTTON_DOWN (4) +#define GP2X_BUTTON_LEFT (2) +#define GP2X_BUTTON_RIGHT (6) +#define GP2X_BUTTON_UPLEFT (1) +#define GP2X_BUTTON_UPRIGHT (7) +#define GP2X_BUTTON_DOWNLEFT (3) +#define GP2X_BUTTON_DOWNRIGHT (5) +#define GP2X_BUTTON_CLICK (18) +#define GP2X_BUTTON_A (12) +#define GP2X_BUTTON_B (13) +#define GP2X_BUTTON_X (14) +#define GP2X_BUTTON_Y (15) +#define GP2X_BUTTON_L (10) +#define GP2X_BUTTON_R (11) +#define GP2X_BUTTON_START (8) +#define GP2X_BUTTON_SELECT (9) +#define GP2X_BUTTON_VOLUP (16) +#define GP2X_BUTTON_VOLDOWN (17) + + case SDL_JOYBUTTONUP: + switch(event.jbutton.button) + { + case GP2X_BUTTON_RIGHT: + key_right = 0; + break; + + case GP2X_BUTTON_LEFT: + key_left = 0; + break; + + case GP2X_BUTTON_UP: + key_up = 0; + break; + + case GP2X_BUTTON_DOWN: + key_down = 0; + break; + + case GP2X_BUTTON_X: + key_a = 0; + break; + + case GP2X_BUTTON_B: + key_b = 0; + break; + + case GP2X_BUTTON_A: + key_c = 0; + break; + + default: + /* keep -Wall happy */ + break; + } + break; + + case SDL_JOYBUTTONDOWN: + switch(event.jbutton.button) + { + case GP2X_BUTTON_SELECT: + cls.quit = 1; + break; + + case GP2X_BUTTON_RIGHT: + key_right = 1; + break; + + case GP2X_BUTTON_LEFT: + key_left = 1; + break; + + case GP2X_BUTTON_UP: + key_up = 1; + break; + + case GP2X_BUTTON_DOWN: + key_down = 1; + break; + + case GP2X_BUTTON_X: + key_a = 1; + break; + + case GP2X_BUTTON_B: + key_b = 1; + break; + + case GP2X_BUTTON_A: + key_c = 1; + break; + + case GP2X_BUTTON_L: + quicksave(); + break; + + case GP2X_BUTTON_R: + quickload(); + break; + + case GP2X_BUTTON_START: + toggle_scaling(); + break; + + case GP2X_BUTTON_VOLUP: + Change_HW_Audio_Volume(4); + break; + + case GP2X_BUTTON_VOLDOWN: + Change_HW_Audio_Volume(-4); + break; + + default: + /* keep -Wall happy */ + break; + } + break; +#endif + case SDL_QUIT: leave_game(); break; diff --git a/src/music.c b/src/music.c index 766968e..1a9ff72 100644 --- a/src/music.c +++ b/src/music.c @@ -91,6 +91,7 @@ static void play_music_track_mp3(int track, int loop) { sprintf(filename, ISO_PREFIX "%02d.ogg", track + 1); } +#if !defined(GP2X) // if ogg file doesn't exist use mp3 if (access(filename, R_OK)) { @@ -103,6 +104,7 @@ static void play_music_track_mp3(int track, int loop) sprintf(filename, ISO_PREFIX "%02d.mp3", track + 1); } } +#endif LOG(("playing mp3 %s\n", filename)); current_track = Mix_LoadMUS(filename); diff --git a/src/render.c b/src/render.c index 4345fde..de44ef7 100644 --- a/src/render.c +++ b/src/render.c @@ -21,6 +21,11 @@ #include "debug.h" #include "render.h" #include "game2bin.h" +#if defined(GP2X) + #if (SDL_MAJOR_VERSION > 1 || SDL_MAJOR_VERSION == 1 && (SDL_MINOR_VERSION > 2 || SDL_MINOR_VERSION == 2 && SDL_PATCHLEVEL >= 9 ) ) + #include + #endif +#endif #include "client.h" #include "scale2x.h" @@ -29,6 +34,10 @@ static int fullscreen = 0; static int scroll_reg = 0; +#if defined(GP2X) +static int tvout = 0; +static int originalsize = 0; +#endif extern int fullscreen_flag; extern SDL_Surface *screen; @@ -105,6 +114,223 @@ void render1x(char *src) } } +#if defined(GP2X) +static void normal320x240_line(Uint8 *dstpix, int dstpitch, char *src, int dstheight) +{ + int x, y; + unsigned char wide[320]; + unsigned char *widep; + unsigned int delta, num_pixels; + + delta = (1 << 24) / 19; // = (320-304) / 304 + widep = wide; + + num_pixels = 1 << 23; // = 0.5 + for (x=0; x<304; x++) + { + num_pixels += delta; + if (num_pixels & (1 << 24)) + { + num_pixels -= (1 << 24); + *widep++ = *src; + } + *widep++ = *src++; + } + + for (y=0; y= 0) + { + if (scroll_reg != 0) + { + normal320x240_line((Uint8*)screen->pixels, screen->pitch, src, scroll_reg+((scroll_reg+2)>>2)); + } + scale320x240(((Uint8*)screen->pixels) + (scroll_reg+((scroll_reg+2)>>2))*screen->pitch, screen->pitch, (Uint8 *)src, 192-scroll_reg); + } + else + { + scale320x240((Uint8*)screen->pixels, screen->pitch, ((Uint8 *)src) - 304*scroll_reg, 192+scroll_reg); + normal320x240_line(((Uint8*)screen->pixels) + (240-(((2-scroll_reg)>>2)-scroll_reg))*screen->pitch, screen->pitch, src + 304*191, ((2-scroll_reg)>>2)-scroll_reg); + } +} + +void toggle_scaling(void) +{ + if (tvout) return; + + originalsize = 1 ^ originalsize; +#if defined(SDL_GP2X__H) + if (originalsize) + { + SDL_GP2X_MiniDisplay(8, 24); + } + else + { + SDL_GP2X_MiniDisplay(0, 0); + } +#endif + { + SDL_Rect rect; + + // clear screen + rect.x = 0; + rect.y = 0; + rect.w = screen->w; + rect.h = screen->h; + SDL_FillRect(screen, &rect, 0); + SDL_Flip(screen); + SDL_FillRect(screen, &rect, 0); + SDL_Flip(screen); + } +} +#endif + static void normal2x_line(Uint8 *dstpix, int dstpitch, char *src, int height) { int x, y; @@ -346,6 +572,20 @@ void render(char *src) SDL_SetColors(screen, palette, 0, 256); } +#if defined(GP2X) + if (!tvout) + { + if (originalsize) + { + render1x(src); + } + else + { + render320x240_scaled(src); + } + } + else +#endif switch(cls.scale) { case 1: @@ -449,8 +689,11 @@ void toggle_fullscreen() return; } +#if defined(GP2X) + if (fullscreen) return; +#endif + fullscreen = 1 ^ fullscreen; - SDL_FreeSurface(screen); screen = 0; if (fullscreen == 0) @@ -475,6 +718,17 @@ void toggle_fullscreen() #if defined(PANDORA) w = 304*cls.scale; h = 192*cls.scale; +#elif defined(GP2X) + if (tvout) + { + w = 320*cls.scale; + h = 200*cls.scale; + } + else + { + w = 320; + h = 240; + } #else w = 320*cls.scale; h = 200*cls.scale; @@ -498,6 +752,14 @@ void toggle_fullscreen() int render_create_surface() { +#if defined(GP2X) && defined(SDL_GP2X__H) + SDL_Rect size; + + SDL_GP2X_GetPhysicalScreenSize(&size); + + tvout = (size.w == 320)?0:1; +#endif + if (cls.pandora && (cls.scale == 3)) { screen = SDL_SetVideoMode(800, 480, 8, SDL_SWSURFACE); diff --git a/src/render.h b/src/render.h index 97306a1..a3f3a90 100644 --- a/src/render.h +++ b/src/render.h @@ -16,4 +16,8 @@ void toggle_fullscreen(); int get_current_palette(); +#if defined(GP2X) +void toggle_scaling(void); +#endif + #endif