diff --git a/Makefile b/Makefile index a534afc..6b395b7 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ INSTALL=/usr/bin/install -c cabrio: main.o ogl.o sdl.o config.o bg.o menu.o game_sel.o \ game.o font.o hint.o genre.o platform.o submenu.o \ - sound.o event.o key.o control.o setup.o + sound.o event.o key.o control.o setup.o sdl_ogl.o $(CC) -o $@ $(LDFLAGS) $^ .c.o: %.c diff --git a/bg.c b/bg.c index d0419b8..7c9dfb2 100644 --- a/bg.c +++ b/bg.c @@ -1,4 +1,5 @@ #include "bg.h" +#include "sdl_ogl.h" #include "sdl.h" #include "ogl.h" @@ -13,15 +14,14 @@ void bg_clear( void ) { bg_texture = bg_clear_texture; } -int bg_init( void ) { - SDL_Surface *bg = sdl_load_image( BG_DEFAULT ); - if( bg == NULL ) { - fprintf( stderr, "Warning: couldn't load default background image '%s'\n", BG_DEFAULT ); - bg_clear_texture = 0; +int bg_init( void ) { + int x,y; + bg_clear_texture = sdl_create_texture( BG_DEFAULT, &x, &y ); + if( bg_clear_texture == 0 ) { + fprintf( stderr, "Warning: couldn't create default background texture from '%s'\n", BG_DEFAULT ); return -1; } - ogl_create_texture( bg, &bg_clear_texture ); - SDL_FreeSurface( bg ); + bg_clear(); return 0; } @@ -43,20 +43,18 @@ int bg_resume( void ) { int bg_set( const char *filename ) { if( filename && *filename ) { - SDL_Surface *bg = sdl_load_image( filename ); - if( bg == NULL ) { + int x,y; + if( bg_texture != bg_clear_texture ) { + ogl_free_texture( &bg_texture ); + } + bg_texture = sdl_create_texture( filename, &x, &y ); + if( bg_texture == 0 ) { fprintf( stderr, "Warning: couldn't load background image '%s'\n", filename ); - bg_texture = 0; return -1; } - if( bg_texture != bg_clear_texture ) { - glDeleteTextures( 1, &bg_texture ); - } - ogl_create_texture( bg, &bg_texture ); - SDL_FreeSurface( bg ); } else { - bg_texture = bg_clear_texture; + bg_clear(); } return 0; } diff --git a/config.c b/config.c index 8f334a7..91e9e85 100644 --- a/config.c +++ b/config.c @@ -684,14 +684,14 @@ int config_new( void ) { const int num_params = 4; const char *params[] = { "-nowindow", "-skip_gameinfo", "-switchres", "-joystick" }; const int keys[] = { - -1, /* Place holder */ - SDLK_UP, /* EVENT_UP == 1 */ - SDLK_DOWN, /* EVENT_DOWN */ - SDLK_LEFT, /* EVENT_LEFT */ - SDLK_RIGHT, /* EVENT_RIGHT */ - SDLK_RETURN, /* EVENT_SELECT */ - SDLK_BACKSPACE, /* EVENT_BACK */ - SDLK_ESCAPE /* EVENT_QUIT */ + -1, /* Place holder */ + key_id("up"), /* EVENT_UP == 1 */ + key_id("down"), /* EVENT_DOWN */ + key_id("left"), /* EVENT_LEFT */ + key_id("right"), /* EVENT_RIGHT */ + key_id("return"), /* EVENT_SELECT */ + key_id("backspace"), /* EVENT_BACK */ + key_id("escape") /* EVENT_QUIT */ }; emulator->id = 0; diff --git a/control.c b/control.c index 0ce41a5..bbde2f0 100644 --- a/control.c +++ b/control.c @@ -109,24 +109,3 @@ const char *axis_dir_name( int axis_dir ) { return ""; } -int hat_dir_value( int direction ) { - switch( direction ) { - case SDL_HAT_UP: - return DIR_UP; - break; - case SDL_HAT_DOWN: - return DIR_DOWN; - break; - case SDL_HAT_LEFT: - return DIR_LEFT; - break; - case SDL_HAT_RIGHT: - return DIR_RIGHT; - break; - default: - fprintf( stderr, "Warning: Bogus hat direction %d\n", direction ); - break; - } - return 0; -} - diff --git a/event.c b/event.c index b45366d..bf53e02 100644 --- a/event.c +++ b/event.c @@ -2,6 +2,7 @@ #include "config.h" #include "event.h" #include "sdl.h" +#include #define MAX_JOYSTICKS 8 @@ -37,14 +38,14 @@ int event_init( void ) { events[i].control_type = config->iface.controls[i].control_type; events[i].control_id = config->iface.controls[i].control_id; events[i].value = config->iface.controls[i].value; - printf("%s: %s%d %s%d = %d\n", + /* printf("%s: %s%d %s%d = %d\n", event_name(i), device_name(events[i].device_type), events[i].device_id, control_name(events[i].control_type), events[i].control_id, events[i].value - ); + ); */ } return 0; @@ -119,7 +120,7 @@ int event_poll( void ) { else if ( sdl_event.type == SDL_JOYHATMOTION && sdl_event.jhat.which == events[i].device_id && events[i].control_type == CTRL_HAT - && hat_dir_value( sdl_event.jhat.hat ) == events[i].control_id + && sdl_hat_dir_value( sdl_event.jhat.hat ) == events[i].control_id && sdl_event.jhat.value == events[i].value ) { event = i; } @@ -210,7 +211,7 @@ int event_probe( int timeout, struct event *event ) { event->device_id = sdl_event.jhat.which; event->control_type = CTRL_HAT; event->control_id = sdl_event.jhat.hat; - event->value = hat_dir_value( sdl_event.jhat.value ); + event->value = sdl_hat_dir_value( sdl_event.jhat.value ); return 1; case SDL_JOYBALLMOTION: event->device_type = DEV_JOYSTICK; diff --git a/font.c b/font.c index c1e577f..1a63d3b 100644 --- a/font.c +++ b/font.c @@ -4,6 +4,7 @@ #include "font.h" #include "sdl.h" #include "ogl.h" +#include "sdl_ogl.h" static TTF_Font *font = NULL; static SDL_Color col = { 255, 255, 255 }; diff --git a/game.c b/game.c index b3008a9..72afce0 100644 --- a/game.c +++ b/game.c @@ -1,8 +1,10 @@ +#include #include "game.h" #include "config.h" #include "genre.h" #include "platform.h" #include "ogl.h" +#include "sdl_ogl.h" struct game *game_start = NULL; struct game *game_filter_start = NULL; @@ -48,31 +50,28 @@ void game_list_free( void ) { } int game_load_texture( struct game *game ) { - SDL_Surface *s = sdl_load_image( game->logo_image ); - if( s == NULL ) { + int x, y; + game->texture = sdl_create_texture( game->logo_image, &x, &y ); + if( game->texture == 0 ) { return -1; } else { - if( ogl_create_texture( s, &(game->texture) ) != -1 ) { - int x = s->w; - int y = s->h; - if( x > y ) { - /* Landscape */ - if( x > IMAGE_MAX_WIDTH ) { - y = (int)(float)y/((float)x/IMAGE_MAX_WIDTH); - x = IMAGE_MAX_WIDTH; - } + if( x > y ) { + /* Landscape */ + if( x > IMAGE_MAX_WIDTH ) { + y = (int)(float)y/((float)x/IMAGE_MAX_WIDTH); + x = IMAGE_MAX_WIDTH; } - else { - /* Portrait (or square) */ - if( y > IMAGE_MAX_HEIGHT ) { - x = (int)(float)x/((float)y/IMAGE_MAX_HEIGHT); - y = IMAGE_MAX_HEIGHT; - } + } + else { + /* Portrait (or square) */ + if( y > IMAGE_MAX_HEIGHT ) { + x = (int)(float)x/((float)y/IMAGE_MAX_HEIGHT); + y = IMAGE_MAX_HEIGHT; } - game->image_width = x; - game->image_height = y; } + game->image_width = x; + game->image_height = y; } return 0; } diff --git a/game_sel.c b/game_sel.c index e48fde5..ea89b3e 100644 --- a/game_sel.c +++ b/game_sel.c @@ -1,3 +1,5 @@ +#include +#include #include "game_sel.h" #include "bg.h" #include "math.h" diff --git a/hint.c b/hint.c index ea1708f..02d70e5 100644 --- a/hint.c +++ b/hint.c @@ -1,6 +1,7 @@ #include "hint.h" #include "sdl.h" #include "font.h" +#include "sdl_ogl.h" #define ORIENT_LEFT 0 #define ORIENT_RIGHT 1 @@ -19,9 +20,10 @@ struct font_message *text_select_message = 0; struct font_message *text_back_message = 0; int hint_init( void ) { - arrow_texture = sdl_create_texture( DATA_DIR "/pixmaps/arrow.png" ); - back_texture = sdl_create_texture( DATA_DIR "/pixmaps/button_blue.png" ); - select_texture = sdl_create_texture( DATA_DIR "/pixmaps/button_red.png" ); + int x,y; + arrow_texture = sdl_create_texture( DATA_DIR "/pixmaps/arrow.png", &x, &y ); + back_texture = sdl_create_texture( DATA_DIR "/pixmaps/button_blue.png", &x, &y ); + select_texture = sdl_create_texture( DATA_DIR "/pixmaps/button_red.png", &x, &y ); text_select_message = font_message_create( "Select" ); text_back_message = font_message_create( "Back" ); return 0; diff --git a/include/control.h b/include/control.h index 18fbbea..3705d89 100644 --- a/include/control.h +++ b/include/control.h @@ -38,7 +38,6 @@ int direction_id( char *name ); int axis_dir_value( char *name ); const char *axis_dir_name( int axis_dir ); -int hat_dir_value( int direction ); #endif diff --git a/include/font.h b/include/font.h index 7384684..1255f21 100644 --- a/include/font.h +++ b/include/font.h @@ -15,7 +15,6 @@ int font_resume( void ); void font_free( void ); void font_message_free( struct font_message *m ); struct font_message *font_message_create( const char *text ); -SDL_Surface *font_render( const char *text ); #endif diff --git a/include/ogl.h b/include/ogl.h index d862801..566d3c5 100644 --- a/include/ogl.h +++ b/include/ogl.h @@ -1,16 +1,14 @@ #ifndef _OGL_H_ #define _OGL_H_ 1 -#include "sdl.h" -#include #include +#include "sdl.h" #define X 0 #define Y 1 #define Z 2 -int ogl_init( void ); -int ogl_create_texture( SDL_Surface *surface, GLuint *texture ); +int ogl_init( void ); void ogl_free_texture( GLuint *t ); void ogl_clear( void ); void ogl_flush( void ); diff --git a/include/sdl.h b/include/sdl.h index d621426..dcd1765 100644 --- a/include/sdl.h +++ b/include/sdl.h @@ -2,19 +2,13 @@ #define _SDL_H_ 1 #include -#include -#include -#include -#include -#include -#include int sdl_init( void ); void sdl_free( void ); -SDL_Surface *sdl_load_image( const char *filename ); -GLuint sdl_create_texture( const char *filename ); void sdl_frame_delay( void ); +void sdl_clear( void ); void sdl_swap( void ); +int sdl_hat_dir_value( int direction ); #endif diff --git a/include/sdl_ogl.h b/include/sdl_ogl.h new file mode 100644 index 0000000..62a5109 --- /dev/null +++ b/include/sdl_ogl.h @@ -0,0 +1,11 @@ +#ifndef _SDL_OGL_H_ +#define _SDL_OGL_H_ 1 + +#include +#include + +int ogl_create_texture( SDL_Surface *surface, GLuint *texture ); +GLuint sdl_create_texture( const char *filename, int *x, int *y ); + +#endif + diff --git a/key.c b/key.c index 7257056..27f37bb 100644 --- a/key.c +++ b/key.c @@ -1,5 +1,5 @@ #include "key.h" -#include "sdl.h" +#include /* Big list o' key names. These are just the SDLK_* macros with their prefix chopped off. */ static const char *key_name_backspace = "backspace"; diff --git a/main.c b/main.c index f10d3ae..d28f663 100644 --- a/main.c +++ b/main.c @@ -3,7 +3,6 @@ #include #include "sdl.h" -#include "ogl.h" #include "font.h" #include "config.h" #include "genre.h" @@ -107,9 +106,6 @@ int main( int argc, char *arvg[] ) { if( sdl_init() != 0 ) return -1; - if( ogl_init() != 0 ) - return -1; - if( event_init() != 0 ) return -1; @@ -147,7 +143,7 @@ int main( int argc, char *arvg[] ) { bg_init(); while( !quit ) { - ogl_clear(); + sdl_clear(); bg_draw(); hint_draw( menu_level ); menu_draw(); @@ -262,8 +258,6 @@ int main( int argc, char *arvg[] ) { run( to_run ); if( sdl_init() != 0 ) return -1; - if( ogl_init() != 0 ) - return -1; resume_all(); to_run = NULL; } diff --git a/menu.c b/menu.c index ad548cb..aa0e9fb 100644 --- a/menu.c +++ b/menu.c @@ -1,4 +1,6 @@ +#include #include "sdl.h" +#include "sdl_ogl.h" #include "menu.h" #include "font.h" @@ -29,7 +31,8 @@ int menu_selected( void ) { } int menu_load_texture( void ) { - menu_texture = sdl_create_texture( DATA_DIR "/pixmaps/menu_item.png" ); + int x,y; + menu_texture = sdl_create_texture( DATA_DIR "/pixmaps/menu_item.png", &x ,&y ); if( menu_texture == 0 ) { fprintf( stderr, "Warning: Couldn't create texture for menu items\n" ); return -1; diff --git a/ogl.c b/ogl.c index d6d0967..42a40ea 100644 --- a/ogl.c +++ b/ogl.c @@ -1,9 +1,8 @@ +#include +#include #include "ogl.h" #include "config.h" -#define TEXTURE_MAX_WIDTH 512 -#define TEXTURE_MAX_HEIGHT 256 - int ogl_init( void ) { const struct config *config = config_get(); @@ -37,93 +36,6 @@ int ogl_init( void ) { } } -unsigned int next_power_of_two( unsigned int x ) { - int i = 0; - if( x == 0 ) return 1; - for( i = 0; x > 0 ; i++, x>>=1 ); - return 1<w; - unsigned int y = surface->h; - SDL_Surface *resized = NULL; - - if( (surface->w & (surface->w-1)) != 0 ) - x = next_power_of_two( surface->w ); - while( x > TEXTURE_MAX_WIDTH ) - x>>=1; - - if( (surface->h & (surface->h-1)) != 0 ) - y = next_power_of_two( surface->w ); - while( y > TEXTURE_MAX_HEIGHT ) - y>>=1; - - if( x != surface->w || y != surface->h ) { - SDL_Surface *tmp = zoomSurface( surface, (double)x/(double)surface->w, (double)y/(double)surface->h, 0 ); - resized = SDL_DisplayFormatAlpha( tmp ); - SDL_FreeSurface( tmp ); - } - return resized; -} - -int ogl_create_texture( SDL_Surface* surface, GLuint *texture ) { - SDL_Surface *new = NULL; - SDL_Surface *work = NULL; - GLint bpp; - GLenum format = 0; - GLenum error = GL_NO_ERROR; - - if( surface == NULL ) { - fprintf(stderr, "Error: Can't create texture from NULL surface.\n" ); - return -1; - } - new = resize( surface ); - work = new ? new : surface; - - /* determine image format */ - bpp = work->format->BytesPerPixel; - switch( bpp ) { - case 4: - if (work->format->Rmask == 0x000000ff) - format = GL_RGBA; - else - format = GL_BGRA; - break; - case 3: - if (work->format->Rmask == 0x000000ff) - format = GL_RGB; - else - format = GL_BGR; - break; - default: - fprintf(stderr, "Error: image is not true colour (%d bpp).\n", bpp ); - if( work != surface ) - SDL_FreeSurface( work ); - return -1; - break; - } - - glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glGenTextures( 1, texture ); - glBindTexture( GL_TEXTURE_2D, *texture ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexImage2D( GL_TEXTURE_2D, 0, bpp, work->w, work->h, 0, format, GL_UNSIGNED_BYTE, work->pixels ); - - if( work != surface ) - SDL_FreeSurface( work ); - - error = glGetError(); - if( error != GL_NO_ERROR ) { - fprintf(stderr, "Error: couldn't create texture: %s.\n", gluErrorString(error) ); - return -1; - } - return 0; -} - void ogl_free_texture( GLuint *t ) { if( t && *t ) { glDeleteTextures( 1, t ); @@ -138,3 +50,4 @@ void ogl_clear( void ) { void ogl_flush( void ) { glFlush(); } + diff --git a/sdl.c b/sdl.c index 3d46b31..175be80 100644 --- a/sdl.c +++ b/sdl.c @@ -1,10 +1,13 @@ #include -#include -#include #include "config.h" #include "sdl.h" #include "ogl.h" +#include "sdl_ogl.h" +#include +#include +#include +#include static SDL_Surface *screen = NULL; @@ -32,6 +35,10 @@ int sdl_init( void ) { SDL_initFramerate( &manager ); SDL_setFramerate( &manager, 60 ); SDL_WM_SetCaption( title, NULL ); + + if( ogl_init() != 0 ) + return -1; + return 0; } @@ -39,37 +46,36 @@ void sdl_free( void ) { SDL_Quit(); } -SDL_Surface *sdl_load_image( const char *filename ) { - SDL_Surface* load = NULL; - SDL_Surface* conv = NULL; - - load = IMG_Load( filename ); - if( load != NULL ) { - conv = SDL_DisplayFormatAlpha( load ); - SDL_FreeSurface( load ); - } - else { - fprintf(stderr, "Error: Unable to load image '%s': %s\n", filename, SDL_GetError()); - } - return conv; -} - -GLuint sdl_create_texture( const char *filename ) { - GLuint t = 0; - SDL_Surface *s = sdl_load_image( filename ); - if( s ) { - ogl_create_texture( s, &t ); - SDL_FreeSurface( s ); - } - return t; -} - void sdl_frame_delay( void ) { SDL_framerateDelay( &manager ); } +void sdl_clear( void ) { + ogl_clear(); +} + void sdl_swap( void ) { SDL_GL_SwapBuffers(); } +int sdl_hat_dir_value( int direction ) { + switch( direction ) { + case SDL_HAT_UP: + return DIR_UP; + break; + case SDL_HAT_DOWN: + return DIR_DOWN; + break; + case SDL_HAT_LEFT: + return DIR_LEFT; + break; + case SDL_HAT_RIGHT: + return DIR_RIGHT; + break; + default: + fprintf( stderr, "Warning: Bogus hat direction %d\n", direction ); + break; + } + return 0; +} diff --git a/sdl_ogl.c b/sdl_ogl.c new file mode 100644 index 0000000..b83e8ce --- /dev/null +++ b/sdl_ogl.c @@ -0,0 +1,123 @@ +#include +#include +#include +#include "sdl.h" +#include "sdl_ogl.h" + +#define TEXTURE_MAX_WIDTH 512 +#define TEXTURE_MAX_HEIGHT 256 + +unsigned int next_power_of_two( unsigned int x ) { + int i = 0; + if( x == 0 ) return 1; + for( i = 0; x > 0 ; i++, x>>=1 ); + return 1<w; + unsigned int y = surface->h; + SDL_Surface *resized = NULL; + + if( (surface->w & (surface->w-1)) != 0 ) + x = next_power_of_two( surface->w ); + while( x > TEXTURE_MAX_WIDTH ) + x>>=1; + + if( (surface->h & (surface->h-1)) != 0 ) + y = next_power_of_two( surface->w ); + while( y > TEXTURE_MAX_HEIGHT ) + y>>=1; + + if( x != surface->w || y != surface->h ) { + SDL_Surface *tmp = zoomSurface( surface, (double)x/(double)surface->w, (double)y/(double)surface->h, 0 ); + resized = SDL_DisplayFormatAlpha( tmp ); + SDL_FreeSurface( tmp ); + } + return resized; +} + +int ogl_create_texture( SDL_Surface* surface, GLuint *texture ) { + SDL_Surface *new = NULL; + SDL_Surface *work = NULL; + GLint bpp; + GLenum format = 0; + GLenum error = GL_NO_ERROR; + + if( surface == NULL ) { + fprintf(stderr, "Error: Can't create texture from NULL surface.\n" ); + return -1; + } + new = resize( surface ); + work = new ? new : surface; + + /* determine image format */ + bpp = work->format->BytesPerPixel; + switch( bpp ) { + case 4: + if (work->format->Rmask == 0x000000ff) + format = GL_RGBA; + else + format = GL_BGRA; + break; + case 3: + if (work->format->Rmask == 0x000000ff) + format = GL_RGB; + else + format = GL_BGR; + break; + default: + fprintf(stderr, "Error: image is not true colour (%d bpp).\n", bpp ); + if( work != surface ) + SDL_FreeSurface( work ); + return -1; + break; + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glGenTextures( 1, texture ); + glBindTexture( GL_TEXTURE_2D, *texture ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexImage2D( GL_TEXTURE_2D, 0, bpp, work->w, work->h, 0, format, GL_UNSIGNED_BYTE, work->pixels ); + + if( work != surface ) + SDL_FreeSurface( work ); + + error = glGetError(); + if( error != GL_NO_ERROR ) { + fprintf(stderr, "Error: couldn't create texture: %s.\n", gluErrorString(error) ); + return -1; + } + return 0; +} + +GLuint sdl_create_texture( const char *filename, int *x, int *y ) { + GLuint t = 0; + SDL_Surface *s = sdl_load_image( filename ); + if( s ) { + ogl_create_texture( s, &t ); + *x = s->w; + *y = s->h; + SDL_FreeSurface( s ); + } + return t; +} + diff --git a/submenu.c b/submenu.c index 971a6d4..4e69672 100644 --- a/submenu.c +++ b/submenu.c @@ -1,6 +1,7 @@ #include "submenu.h" #include "ogl.h" #include "sdl.h" +#include "sdl_ogl.h" #include "font.h" #include "game.h" #include "genre.h" @@ -27,7 +28,8 @@ int submenu_items( void ) { } int submenu_load_texture( void ) { - texture = sdl_create_texture( DATA_DIR "/pixmaps/submenu_item.png" ); + int x,y; + texture = sdl_create_texture( DATA_DIR "/pixmaps/submenu_item.png", &x, &y ); if( texture == 0 ) { fprintf( stderr, "Warning: Couldn't create texture for submenu items\n" ); return -1;