Mercurial > sdl-ios-xcode
diff src/video/xbios/SDL_xbios.c @ 978:3b1ba22f5a28
Add support for OpenGL on Atari using OSMesa, the offscreen rendering driver from Mesa
author | Patrice Mandin <patmandin@gmail.com> |
---|---|
date | Wed, 17 Nov 2004 23:13:15 +0000 |
parents | 15a7d0c44e73 |
children | c9d1ade1fb0b |
line wrap: on
line diff
--- a/src/video/xbios/SDL_xbios.c Mon Nov 15 23:34:56 2004 +0000 +++ b/src/video/xbios/SDL_xbios.c Wed Nov 17 23:13:15 2004 +0000 @@ -37,6 +37,10 @@ #include <sys/stat.h> #include <unistd.h> +#ifdef HAVE_OPENGL +#include <GL/osmesa.h> +#endif + /* Mint includes */ #include <mint/cookie.h> #include <mint/osbind.h> @@ -74,6 +78,15 @@ static void XBIOS_FreeHWSurface(_THIS, SDL_Surface *surface); static void XBIOS_UpdateRects(_THIS, int numrects, SDL_Rect *rects); +#ifdef HAVE_OPENGL +/* OpenGL functions */ +static int XBIOS_GL_LoadLibrary(_THIS, const char *path); +static void *XBIOS_GL_GetProcAddress(_THIS, const char *proc); +static int XBIOS_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value); +static int XBIOS_GL_MakeCurrent(_THIS); +static void XBIOS_GL_SwapBuffers(_THIS); +#endif + /* List of video modes */ /* ST modes */ @@ -93,21 +106,21 @@ static int xbiosnummodes_f30rvb=16; static xbiosmode_t xbiosmodelist_f30rvb[]={ {BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,SDL_FALSE}, + {BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE}, + {BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE}, + {BPS16|VERTFLAG,320,400,16,SDL_FALSE}, {BPS16|COL80|OVERSCAN,768,240,16,SDL_FALSE}, - {BPS16|COL80|VERTFLAG,640,400,16,SDL_FALSE}, + {BPS16|OVERSCAN,384,240,16,SDL_FALSE}, {BPS16|COL80,640,200,16,SDL_FALSE}, - {BPS16|OVERSCAN|VERTFLAG,384,480,16,SDL_FALSE}, - {BPS16|OVERSCAN,384,240,16,SDL_FALSE}, - {BPS16|VERTFLAG,320,400,16,SDL_FALSE}, {BPS16,320,200,16,SDL_FALSE}, {BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,SDL_FALSE}, + {BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE}, + {BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE}, + {BPS8|VERTFLAG,320,400,8,SDL_FALSE}, {BPS8|COL80|OVERSCAN,768,240,8,SDL_FALSE}, - {BPS8|COL80|VERTFLAG,640,400,8,SDL_FALSE}, + {BPS8|OVERSCAN,384,240,8,SDL_FALSE}, {BPS8|COL80,640,200,8,SDL_FALSE}, - {BPS8|OVERSCAN|VERTFLAG,384,480,8,SDL_FALSE}, - {BPS8|OVERSCAN,384,240,8,SDL_FALSE}, - {BPS8|VERTFLAG,320,400,8,SDL_FALSE}, {BPS8,320,200,8,SDL_FALSE} }; @@ -118,8 +131,8 @@ {BPS16|VERTFLAG,320,240,16,SDL_FALSE}, {BPS8|COL80,640,480,8,SDL_FALSE}, + {BPS8,320,480,8,SDL_FALSE}, {BPS8|COL80|VERTFLAG,640,240,8,SDL_FALSE}, - {BPS8,320,480,8,SDL_FALSE}, {BPS8|VERTFLAG,320,240,8,SDL_FALSE} }; @@ -206,6 +219,15 @@ device->FlipHWSurface = XBIOS_FlipHWSurface; device->FreeHWSurface = XBIOS_FreeHWSurface; +#ifdef HAVE_OPENGL + /* OpenGL functions */ + device->GL_LoadLibrary = XBIOS_GL_LoadLibrary; + device->GL_GetProcAddress = XBIOS_GL_GetProcAddress; + device->GL_GetAttribute = XBIOS_GL_GetAttribute; + device->GL_MakeCurrent = XBIOS_GL_MakeCurrent; + device->GL_SwapBuffers = XBIOS_GL_SwapBuffers; +#endif + /* Events */ device->InitOSKeymap = Atari_InitOSKeymap; device->PumpEvents = Atari_PumpEvents; @@ -393,6 +415,10 @@ /* Init chunky to planar routine */ SDL_Atari_C2pConvert = SDL_Atari_C2pConvert8; +#ifdef HAVE_OPENGL + this->gl_config.driver_loaded = 1; +#endif + /* We're done! */ return(0); } @@ -412,6 +438,14 @@ { int i; +#ifdef HAVE_OPENGL + /* Shutdown OpenGL context */ + if (XBIOS_ctx) { + OSMesaDestroyContext(XBIOS_ctx); + XBIOS_ctx = NULL; + } +#endif + for (i=0;i<2;i++) { if (XBIOS_screensmem[i]!=NULL) { Mfree(XBIOS_screensmem[i]); @@ -503,6 +537,14 @@ XBIOS_screens[0]=(void *) (( (long) XBIOS_screensmem[0]+256) & 0xFFFFFF00UL); +#ifdef HAVE_OPENGL + if (flags & SDL_OPENGL) { + if (this->gl_config.double_buffer) { + flags |= SDL_DOUBLEBUF; + } + } +#endif + /* Double buffer ? */ if (flags & SDL_DOUBLEBUF) { XBIOS_screensmem[1] = Atari_SysMalloc(new_screen_size, MX_STRAM); @@ -525,7 +567,6 @@ return(NULL); } - current->flags = modeflags; current->w = XBIOS_width = width; current->h = XBIOS_height = height; current->pitch = (width * new_depth)>>3; @@ -540,6 +581,33 @@ XBIOS_fbnum = 0; +#ifdef HAVE_OPENGL + if (flags & SDL_OPENGL) { + GLenum format; + + /* Init OpenGL context using OSMesa */ + if (new_depth == 8) { + format = OSMESA_COLOR_INDEX; + } else { + format = OSMESA_RGB_565; + } + + XBIOS_ctx = OSMesaCreateContextExt( format, this->gl_config.depth_size, + this->gl_config.stencil_size, this->gl_config.accum_red_size + + this->gl_config.accum_green_size + this->gl_config.accum_blue_size + + this->gl_config.accum_alpha_size, NULL ); + if (!XBIOS_ctx) { + XBIOS_FreeBuffers(this); + SDL_SetError("OSMesaCreateContext failed"); + return(NULL); + } + + modeflags |= SDL_OPENGL; + } +#endif + + current->flags = modeflags; + /* Now set the video mode */ #ifndef DEBUG_VIDEO_XBIOS Setscreen(-1,XBIOS_screens[0],-1); @@ -698,13 +766,6 @@ destscr += destx; /* Convert chunky to planar screen */ -#ifdef DEBUG_VIDEO_XBIOS - printf("C2p:\n"); - printf(" Source: Adr=0x%08x, Pitch=%d\n", surface->pixels, surface->pitch); - printf(" Dest: Adr=0x%08x, Pitch=%d\n", destscr, XBIOS_pitch); - printf(" Size: %dx%d, dblline=%d\n", surface->w, surface->h, XBIOS_doubleline); - fflush(stdout); -#endif SDL_Atari_C2pConvert( surface->pixels, destscr, @@ -835,3 +896,113 @@ this->screen->pixels = NULL; } + +#ifdef HAVE_OPENGL + +/* OpenGL functions */ +static int XBIOS_GL_LoadLibrary(_THIS, const char *path) +{ + /* Library is always opened */ + this->gl_config.driver_loaded = 1; + + return 0; +} + +static void *XBIOS_GL_GetProcAddress(_THIS, const char *proc) +{ + void *func = NULL; + + if (XBIOS_ctx != NULL) { + func = OSMesaGetProcAddress(proc); + } + + return func; +} + +static int XBIOS_GL_GetAttribute(_THIS, SDL_GLattr attrib, int* value) +{ + GLenum mesa_attrib; + SDL_Surface *surface; + + if (XBIOS_ctx == NULL) { + return -1; + } + + switch(attrib) { + case SDL_GL_RED_SIZE: + mesa_attrib = GL_RED_BITS; + break; + case SDL_GL_GREEN_SIZE: + mesa_attrib = GL_GREEN_BITS; + break; + case SDL_GL_BLUE_SIZE: + mesa_attrib = GL_BLUE_BITS; + break; + case SDL_GL_ALPHA_SIZE: + mesa_attrib = GL_ALPHA_BITS; + break; + case SDL_GL_DOUBLEBUFFER: + surface = this->screen; + *value = ((surface->flags & SDL_DOUBLEBUF)==SDL_DOUBLEBUF); + return 0; + case SDL_GL_DEPTH_SIZE: + mesa_attrib = GL_DEPTH_BITS; + break; + case SDL_GL_STENCIL_SIZE: + mesa_attrib = GL_STENCIL_BITS; + break; + case SDL_GL_ACCUM_RED_SIZE: + mesa_attrib = GL_ACCUM_RED_BITS; + break; + case SDL_GL_ACCUM_GREEN_SIZE: + mesa_attrib = GL_ACCUM_GREEN_BITS; + break; + case SDL_GL_ACCUM_BLUE_SIZE: + mesa_attrib = GL_ACCUM_BLUE_BITS; + break; + case SDL_GL_ACCUM_ALPHA_SIZE: + mesa_attrib = GL_ACCUM_ALPHA_BITS; + break; + default : + return -1; + } + + glGetIntegerv(mesa_attrib, value); + return 0; +} + +static int XBIOS_GL_MakeCurrent(_THIS) +{ + SDL_Surface *surface; + GLenum type; + + if (XBIOS_ctx == NULL) { + return -1; + } + + surface = this->screen; + if ((surface->format->BitsPerPixel) == 8) { + type = GL_UNSIGNED_BYTE; + } else { + type = GL_UNSIGNED_SHORT_5_6_5; + } + + if (!OSMesaMakeCurrent(XBIOS_ctx, surface->pixels, type, surface->w, surface->h)) { + SDL_SetError("Can not make OpenGL context current"); + return -1; + } + + return 0; +} + +static void XBIOS_GL_SwapBuffers(_THIS) +{ + if (XBIOS_ctx == NULL) { + return; + } + + XBIOS_FlipHWSurface(this, this->screen); + XBIOS_GL_MakeCurrent(this); +} + +#endif