Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
/*
** Oricutron
** Copyright (C) 2009-2014 Peter Gordon
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the GNU General Public License
** as published by the Free Software Foundation, version 2
** of the License.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
**
** OpenGL rendering
*/
#ifdef __OPENGL_AVAILABLE__
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "system.h"
#ifdef WIN32
#include <windows.h>
#endif
#ifndef __APPLE__
#include <GL/gl.h>
#else
#include <OpenGL/gl.h>
#endif
#if SDL_MAJOR_VERSION == 1
# ifdef __SPECIFY_SDL_DIR__
# include <SDL/SDL_endian.h>
# else
# include <SDL_endian.h>
# endif
#else /* SDL_MAJOR_VERSION == 1 */
# ifdef __SPECIFY_SDL_DIR__
# include <SDL2/SDL_endian.h>
# else
# include <SDL_endian.h>
# endif
#endif
#include "6502.h"
#include "via.h"
#include "8912.h"
#include "disk.h"
#include "gui.h"
#include "monitor.h"
#include "6551.h"
#include "machine.h"
#include "render_gl.h"
#include "ula.h"
#define TEX_VIDEO (0)
#define TEX_SCANLINES (1)
#define TEX_STATUS (2)
#define TEX_POPUP (3)
#define TEX_TZ (TEX_POPUP+1)
#define TEX_TZ_LAST ((NUM_TZ+TEX_TZ)-1)
#define TEX_GIMG (TEX_TZ_LAST+1)
#define TEX_GIMG_LAST ((NUM_GIMG+TEX_GIMG)-1)
#define NUM_TEXTURES (TEX_GIMG_LAST+1)
extern SDL_bool refreshstatus;
struct texture
{
int w, h;
float tw, th;
Uint8 *buf;
};
static SDL_bool dodeltex = SDL_FALSE;
static GLuint tex[NUM_TEXTURES];
static struct texture tx[NUM_TEXTURES];
static struct SDL_Surface *screen;
static Uint32 gpal[NUM_GUI_COLS];
static float clrcol[3];
extern unsigned char sgpal[];
extern SDL_bool fullscreen;
extern struct textzone *tz[NUM_TZ];
extern Uint8 oricpalette[];
extern struct guiimg gimgs[NUM_GIMG];
// Our "lovely" hand-coded font
extern unsigned char thefont[];
// Print a char onto a textzone texture
// i = texture number
// x,y = location
// ch = which char to draw
// fcol = foreground colour
// bcol = background colour
// solidfont = use background colour
static void printchar( int i, int x, int y, unsigned char ch, Uint32 fcol, Uint32 bcol, SDL_bool solidfont )
{
int px, py, c;
unsigned char *fptr;
struct texture *ptx = &tx[i];
Uint32 *ptr;
if( ch > 127 ) return;
ptr = (Uint32 *)&ptx->buf[(y*ptx->w+x)*4];
fptr = &thefont[ch*12];
for( py=0; py<12; py++ )
{
for( c=0x80, px=0; px<8; px++, c>>=1 )
{
if( (*fptr)&c )
{
*(ptr++) = fcol;
} else {
if( solidfont )
*(ptr++) = bcol;
else
ptr++;
}
}
ptr += ptx->w-8;
fptr++;
}
}
static void update_textzone_texture( struct machine *oric, int i )
{
int x, y, px, py, o;
if( !tz[i] ) return;
if( !tz[i]->modified ) return;
if( !tx[i+TEX_TZ].buf ) return;
o = 0;
for( y=0, py=0; y<tz[i]->h; y++, py+=12 )
{
for( x=0, px=0; x<tz[i]->w; x++, o++, px+=8 )
printchar( i+TEX_TZ, px, py, tz[i]->tx[o], gpal[tz[i]->fc[o]], gpal[tz[i]->bc[o]], SDL_TRUE );
}
glBindTexture( GL_TEXTURE_2D, tex[i+TEX_TZ] );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[i+TEX_TZ].w, tx[i+TEX_TZ].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i+TEX_TZ].buf );
tz[i]->modified = SDL_FALSE;
}
static void update_video_texture( struct machine *oric )
{
int x, y, o, c;
Uint8 *sptr;
o = 0;
sptr = oric->scr;
for( y=0; y<224; y++ )
{
if (!oric->vid_dirty[y])
{
sptr += 240;
o += tx[TEX_VIDEO].w*4;
continue;
}
for( x=0; x<240; x++ )
{
c = *(sptr++) * 3;
tx[TEX_VIDEO].buf[o++] = oricpalette[c++];
tx[TEX_VIDEO].buf[o++] = oricpalette[c++];
tx[TEX_VIDEO].buf[o++] = oricpalette[c++];
tx[TEX_VIDEO].buf[o++] = 0xff;
}
// Repeat the right and bottom borders to prevent linear interpolation to
// garbage at the edges (GL_CLAMP takes care of the left and top)
tx[TEX_VIDEO].buf[o++] = oricpalette[c-3];
tx[TEX_VIDEO].buf[o++] = oricpalette[c-2];
tx[TEX_VIDEO].buf[o++] = oricpalette[c-1];
tx[TEX_VIDEO].buf[o++] = 0xff;
o += (tx[TEX_VIDEO].w-241) * 4;
oric->vid_dirty[y] = SDL_FALSE;
}
sptr -= 240;
for( x=0; x<240; x++ )
{
c = *(sptr++) * 3;
tx[TEX_VIDEO].buf[o++] = oricpalette[c++];
tx[TEX_VIDEO].buf[o++] = oricpalette[c++];
tx[TEX_VIDEO].buf[o++] = oricpalette[c++];
tx[TEX_VIDEO].buf[o++] = 0xff;
}
// Repeat the right and bottom borders to prevent linear interpolation to
// garbage at the edges (GL_CLAMP takes care of the left and top)
tx[TEX_VIDEO].buf[o++] = oricpalette[c-3];
tx[TEX_VIDEO].buf[o++] = oricpalette[c-2];
tx[TEX_VIDEO].buf[o++] = oricpalette[c-1];
tx[TEX_VIDEO].buf[o++] = 0xff;
glBindTexture( GL_TEXTURE_2D, tex[TEX_VIDEO] );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_VIDEO].w, tx[TEX_VIDEO].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_VIDEO].buf );
}
void render_begin_gl( struct machine *oric )
{
int i;
refreshstatus = SDL_TRUE;
update_video_texture( oric );
for( i=0; i<NUM_TZ; i++ )
update_textzone_texture( oric, i );
if( oric->newpopupstr )
{
memset( tx[TEX_POPUP].buf, 0, tx[TEX_POPUP].w*tx[TEX_POPUP].h*4 );
for( i=0; oric->popupstr[i]; i++ )
printchar( TEX_POPUP, i*8, 0, oric->popupstr[i], gpal[1], gpal[0], SDL_TRUE );
glBindTexture( GL_TEXTURE_2D, tex[TEX_POPUP] );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_POPUP].w, tx[TEX_POPUP].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_POPUP].buf );
oric->newpopupstr = SDL_FALSE;
}
if( oric->newstatusstr )
{
memset( tx[TEX_STATUS].buf, 0, tx[TEX_STATUS].w*tx[TEX_STATUS].h*4 );
for( i=0; oric->statusstr[i]; i++ )
printchar( TEX_STATUS, i*8, 0, oric->statusstr[i], gpal[1], gpal[0], SDL_FALSE );
glBindTexture( GL_TEXTURE_2D, tex[TEX_STATUS] );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_STATUS].w, tx[TEX_STATUS].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_STATUS].buf );
}
glClearColor(clrcol[0], clrcol[1], clrcol[2], 1.0f);
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
}
void render_end_gl( struct machine *oric )
{
if( oric->emu_mode == EM_RUNNING )
{
if( oric->popupstr[0] )
{
glBindTexture( GL_TEXTURE_2D, tex[TEX_POPUP] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 320.0f, 0.0f, 0.0f );
glTexCoord2f( 320.0f/512.0f, 0.0f ); glVertex3f( 640.0f, 0.0f, 0.0f );
glTexCoord2f( 320.0f/512.0f, 12.0f/32.0f ); glVertex3f( 640.0f, 12.0f, 0.0f );
glTexCoord2f( 0.0f, 12.0f/32.0f ); glVertex3f( 320.0f, 12.0f, 0.0f );
glEnd();
}
if( oric->statusstr[0] )
{
glBindTexture( GL_TEXTURE_2D, tex[TEX_STATUS] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 466.0f, 0.0f );
glTexCoord2f( 320.0f/512.0f, 0.0f ); glVertex3f( 320.0f, 466.0f, 0.0f );
glTexCoord2f( 320.0f/512.0f, 12.0f/32.0f ); glVertex3f( 320.0f, 478.0f, 0.0f );
glTexCoord2f( 0.0f, 12.0f/32.0f ); glVertex3f( 0.0f, 478.0f, 0.0f );
glEnd();
}
}
SDL_COMPAT_GL_SwapBuffers();
}
static unsigned int rounduppow2( unsigned int x )
{
x--;
x |= x >> 1;
x |= x >> 2;
x |= x >> 4;
x |= x >> 8;
x |= x >> 16;
x++;
return x;
}
void render_textzone_alloc_gl( struct machine *oric, int i )
{
render_textzone_free_gl( oric, i );
if( !tz[i] ) return;
#ifdef __amigaos4__
// seems to be a bug in OS4 SDL or GL that reallocating the texture
// a different size causes problems :-/ Or it might just be me being
// stupid, but i can't see how at this time. Anyway; say hello to mr.
// ugly workaround
tx[i+TEX_TZ].w = 512;
tx[i+TEX_TZ].h = 512;
#else
tx[i+TEX_TZ].w = rounduppow2( tz[i]->w * 8 );
tx[i+TEX_TZ].h = rounduppow2( tz[i]->h * 12 );
#endif
tx[i+TEX_TZ].buf = malloc( tx[i+TEX_TZ].w*tx[i+TEX_TZ].h*4 );
if( !tx[i+TEX_TZ].buf )
{
tx[i+TEX_TZ].w = 0;
tx[i+TEX_TZ].h = 0;
return;
}
tx[i+TEX_TZ].tw = ((float)(tz[i]->w*8)) / ((float)tx[i+TEX_TZ].w);
tx[i+TEX_TZ].th = ((float)(tz[i]->h*12)) / ((float)tx[i+TEX_TZ].h);
glBindTexture( GL_TEXTURE_2D, tex[i+TEX_TZ] );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[i+TEX_TZ].w, tx[i+TEX_TZ].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i+TEX_TZ].buf );
tz[i]->modified = SDL_TRUE;
}
void render_textzone_free_gl( struct machine *oric, int i )
{
if( tx[i+TEX_TZ].buf )
{
free( tx[i+TEX_TZ].buf );
tx[i+TEX_TZ].buf = NULL;
}
tx[i+TEX_TZ].w = 0;
tx[i+TEX_TZ].h = 0;
}
void render_textzone_gl( struct machine *oric, int i )
{
if( !tz[i] ) return;
if( !tx[i+TEX_TZ].buf ) return;
glBindTexture( GL_TEXTURE_2D, tex[i+TEX_TZ] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( tz[i]->x, tz[i]->y, 0.0f );
glTexCoord2f( tx[i+TEX_TZ].tw, 0.0f ); glVertex3f( tz[i]->x+tz[i]->w*8, tz[i]->y, 0.0f );
glTexCoord2f( tx[i+TEX_TZ].tw, tx[i+TEX_TZ].th ); glVertex3f( tz[i]->x+tz[i]->w*8, tz[i]->y+tz[i]->h*12, 0.0f );
glTexCoord2f( 0.0f, tx[i+TEX_TZ].th ); glVertex3f( tz[i]->x, tz[i]->y+tz[i]->h*12, 0.0f );
glEnd();
}
void render_clear_area_gl( int x, int y, int w, int h )
{
}
void render_gimg_gl( int i, Sint32 xp, Sint32 yp )
{
glBindTexture( GL_TEXTURE_2D, tex[i+TEX_GIMG] );
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( xp, yp, 0.0f );
glTexCoord2f( tx[i+TEX_GIMG].tw, 0.0f ); glVertex3f( xp+gimgs[i].w, yp, 0.0f );
glTexCoord2f( tx[i+TEX_GIMG].tw, tx[i+TEX_GIMG].th ); glVertex3f( xp+gimgs[i].w, yp+gimgs[i].h, 0.0f );
glTexCoord2f( 0.0f, tx[i+TEX_GIMG].th ); glVertex3f( xp, yp+gimgs[i].h, 0.0f );
glEnd();
}
void render_gimgpart_gl( int i, Sint32 xp, Sint32 yp, Sint32 ox, Sint32 oy, Sint32 w, Sint32 h )
{
float texl, text, texr, texb;
texl = ((float)ox)/((float)tx[i+TEX_GIMG].w);
text = ((float)oy)/((float)tx[i+TEX_GIMG].h);
texr = ((float)ox+w)/((float)tx[i+TEX_GIMG].w);
texb = ((float)oy+h)/((float)tx[i+TEX_GIMG].h);
glBindTexture( GL_TEXTURE_2D, tex[i+TEX_GIMG] );
glBegin( GL_QUADS );
glTexCoord2f( texl, text ); glVertex3f( xp, yp, 0.0f );
glTexCoord2f( texr, text ); glVertex3f( xp+w, yp, 0.0f );
glTexCoord2f( texr, texb ); glVertex3f( xp+w, yp+h, 0.0f );
glTexCoord2f( texl, texb ); glVertex3f( xp, yp+h, 0.0f );
glEnd();
}
void render_video_gl( struct machine *oric, SDL_bool doublesize )
{
float l, r, t, b;
int y;
glBindTexture( GL_TEXTURE_2D, tex[TEX_VIDEO] );
if( doublesize )
{
if( oric->hstretch )
{
l = 0.0f;
r = 640.f;
t = 14.0f;
b = 462.0f;
} else {
l = 320.0f-240.0f;
r = 320.0f+240.0f;
if( oric->aratio && oric->vid_freq )
{
t = 14.0f + (448.0f-448.0f*(260.0f/308.0f))/2;
b = 462.0f - (448.0f-448.0f*(260.0f/308.0f))/2;
}
else
{
t = 14.0f;
b = 462.0f;
}
}
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( l, t, 0.0f );
glTexCoord2f( 240.0f/256.0f, 0.0f ); glVertex3f( r, t, 0.0f );
glTexCoord2f( 240.0f/256.0f, 224.0f/256.0f ); glVertex3f( r, b, 0.0f );
glTexCoord2f( 0.0f, 224.0f/256.0f ); glVertex3f( l, b, 0.0f );
glEnd();
if( oric->palghost )
{
float offs = (oric->hstretch) ? 3.2f : 2.2f;
glColor4ub( 255, 255, 255, 64 );
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( l+offs, t, 0.0f );
glTexCoord2f( 240.0f/256.0f, 0.0f ); glVertex3f( r+offs, t, 0.0f );
glTexCoord2f( 240.0f/256.0f, 224.0f/256.0f ); glVertex3f( r+offs, b, 0.0f );
glTexCoord2f( 0.0f, 224.0f/256.0f ); glVertex3f( l+offs, b, 0.0f );
glEnd();
glColor4ub( 255, 255, 255, 255 );
}
if( !oric->scanlines ) return;
glBindTexture( GL_TEXTURE_2D, tex[TEX_SCANLINES] );
glBegin( GL_QUADS );
for( y=14; y<224*2+14; y+=32 )
{
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( l, y, 0.0f );
glTexCoord2f( 1.0f, 0.0f ); glVertex3f( r, y, 0.0f );
glTexCoord2f( 1.0f, 1.0f ); glVertex3f( r, y+32, 0.0f );
glTexCoord2f( 0.0f, 1.0f ); glVertex3f( l, y+32, 0.0f );
}
glEnd();
return;
}
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f ); glVertex3f( 0.0f, 4.0f, 0.0f );
glTexCoord2f( 240.0f/256.0f, 0.0f ); glVertex3f( 240.0f, 4.0f, 0.0f );
glTexCoord2f( 240.0f/256.0f, 224.0f/256.0f ); glVertex3f( 240.0f, 228.0f, 0.0f );
glTexCoord2f( 0.0f, 224.0f/256.0f ); glVertex3f( 0.0f, 228.0f, 0.0f );
glEnd();
}
void preinit_render_gl( struct machine *oric )
{
Sint32 i;
screen = NULL;
dodeltex = SDL_FALSE;
for( i=0; i<NUM_TEXTURES; i++ )
{
tx[i].w = 0;
tx[i].h = 0;
tx[i].buf = NULL;
}
}
SDL_bool render_togglefullscreen_gl( struct machine *oric )
{
#if defined(__amigaos4__) || defined(__linux__)
// Use SDL_WM_ToggleFullScreen on systems where it is supported
if( SDL_COMPAT_WM_ToggleFullScreen( screen ) )
{
fullscreen = !fullscreen;
return SDL_TRUE;
}
return SDL_FALSE;
#else
oric->shut_render( oric );
fullscreen = !fullscreen;
if( oric->init_render( oric ) ) return SDL_TRUE;
set_render_mode( oric, RENDERMODE_NULL );
oric->emu_mode = EM_PLEASEQUIT;
return SDL_FALSE;
#endif
}
static SDL_bool go_go_gadget_texture( int i, int w, int h, int blendtype, SDL_bool callteximg2d )
{
tx[i].w = w;
tx[i].h = h;
tx[i].buf = malloc( w*h*4 );
if( !tx[i].buf ) return SDL_FALSE;
memset( tx[i].buf, 0, w*h*4 );
glBindTexture( GL_TEXTURE_2D, tex[i] );
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_MAG_FILTER, blendtype );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, blendtype );
if( callteximg2d )glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i].buf );
return SDL_TRUE;
}
SDL_bool init_render_gl( struct machine *oric )
{
int depth, i, x, y;
int BitsPerPixel = SDL_COMPAT_GetBitsPerPixel();
depth = 32;
if( BitsPerPixel )
depth = BitsPerPixel;
if (oric->show_keyboard) {
screen = SDL_COMPAT_SetVideoMode( 640, 480+240, depth, fullscreen ? SDL_COMPAT_OPENGL|SDL_COMPAT_FULLSCREEN : SDL_COMPAT_OPENGL );
} else {
screen = SDL_COMPAT_SetVideoMode( 640, 480, depth, fullscreen ? SDL_COMPAT_OPENGL|SDL_COMPAT_FULLSCREEN : SDL_COMPAT_OPENGL );
}
if( !screen )
{
printf( "SDL video failed\n" );
return SDL_FALSE;
}
glMatrixMode( GL_PROJECTION );
if (oric->show_keyboard) {
glOrtho( 0.0f, 640.0f, 480.0f+240.0f, 0.0f, 0.0f, 1.0f );
} else {
glOrtho( 0.0f, 640.0f, 480.0f, 0.0f, 0.0f, 1.0f );
}
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
glDisable( GL_DEPTH_TEST );
glColor4ub( 255, 255, 255, 255 );
glGenTextures( NUM_TEXTURES, tex );
dodeltex = SDL_TRUE;
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glEnable( GL_TEXTURE_2D );
glEnable( GL_BLEND );
// Allocate texture buffers
if( !go_go_gadget_texture( TEX_VIDEO, 256, 256, GL_LINEAR, SDL_TRUE ) ) return SDL_FALSE;
if( !go_go_gadget_texture( TEX_SCANLINES, 32, 32, GL_NEAREST, SDL_FALSE ) ) return SDL_FALSE;
if( !go_go_gadget_texture( TEX_STATUS, 512, 32, GL_NEAREST, SDL_TRUE ) ) return SDL_FALSE;
if( !go_go_gadget_texture( TEX_POPUP, 512, 32, GL_NEAREST, SDL_TRUE ) ) return SDL_FALSE;
for( y=0; y<32; y++ )
{
for( x=0; x<32*4; )
{
tx[TEX_SCANLINES].buf[y*32*4+x++] = 0x00;
tx[TEX_SCANLINES].buf[y*32*4+x++] = 0x00;
tx[TEX_SCANLINES].buf[y*32*4+x++] = 0x00;
tx[TEX_SCANLINES].buf[y*32*4+x++] = (y&1) ? 0x30 : 0x00;
}
}
glBindTexture( GL_TEXTURE_2D, tex[TEX_SCANLINES] );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[TEX_SCANLINES].w, tx[TEX_SCANLINES].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[TEX_SCANLINES].buf );
for( i=0; i<NUM_GIMG; i++ )
{
if( !go_go_gadget_texture( i+TEX_GIMG, rounduppow2( gimgs[i].w ), rounduppow2( gimgs[i].h ), GL_NEAREST, SDL_FALSE ) ) return SDL_FALSE;
tx[i+TEX_GIMG].tw = ((float)gimgs[i].w) / ((float)tx[i+TEX_GIMG].w);
tx[i+TEX_GIMG].th = ((float)gimgs[i].h) / ((float)tx[i+TEX_GIMG].h);
for( y=0; y<gimgs[i].h; y++ )
{
for( x=0; x<gimgs[i].w; x++ )
{
tx[i+TEX_GIMG].buf[(y*tx[i+TEX_GIMG].w+x)*4 ] = gimgs[i].buf[(y*gimgs[i].w+x)*3];
tx[i+TEX_GIMG].buf[(y*tx[i+TEX_GIMG].w+x)*4+1] = gimgs[i].buf[(y*gimgs[i].w+x)*3+1];
tx[i+TEX_GIMG].buf[(y*tx[i+TEX_GIMG].w+x)*4+2] = gimgs[i].buf[(y*gimgs[i].w+x)*3+2];
tx[i+TEX_GIMG].buf[(y*tx[i+TEX_GIMG].w+x)*4+3] = 0xff;
}
}
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, tx[i+TEX_GIMG].w, tx[i+TEX_GIMG].h, 0, GL_RGBA, GL_UNSIGNED_BYTE, tx[i+TEX_GIMG].buf );
}
// Get the GUI palette
for( i=0; i<NUM_GUI_COLS; i++ )
{
gpal[i] = (sgpal[i*3]<<24)|(sgpal[i*3+1]<<16)|(sgpal[i*3+2]<<8)|0xff;
gpal[i] = _BE32( gpal[i] );
}
for( i=0; i<NUM_TZ; i++ )
render_textzone_alloc_gl( oric, i );
SDL_COMPAT_WM_SetCaption( APP_NAME_FULL, APP_NAME_FULL );
clrcol[0] = ((float)sgpal[0*3+0])/255.0f;
clrcol[1] = ((float)sgpal[0*3+1])/255.0f;
clrcol[2] = ((float)sgpal[0*3+2])/255.0f;
ula_set_dirty( oric );
return SDL_TRUE;
}
void shut_render_gl( struct machine *oric )
{
int i;
if( dodeltex )
{
glDeleteTextures( NUM_TEXTURES, tex );
dodeltex = SDL_FALSE;
}
for( i=0; i<NUM_TEXTURES; i++ )
{
if( tx[i].buf ) free( tx[i].buf );
tx[i].buf = NULL;
tx[i].w = 0;
tx[i].h = 0;
}
}
#endif //__OPENGL_AVAILABLE__