OpenGL update phase 1. Window-based rendering working better.

Properly accepts various input filter sizes
Hq3x code modified to rearrange output for RGB instead of BGR
New code to draw text directly in OpenGL instead of using
GDI.
This commit is contained in:
DJRobX 2007-11-13 12:12:57 +00:00
parent a7d094cf60
commit 4d3a628089
8 changed files with 794 additions and 222 deletions

View File

@ -1113,6 +1113,34 @@
RelativePath=".\src\win32\GDIDisplay.cpp" RelativePath=".\src\win32\GDIDisplay.cpp"
> >
</File> </File>
<File
RelativePath=".\src\win32\glfont.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Optimized|Win32"
>
<Tool
Name="VCCLCompilerTool"
CompileAs="1"
/>
</FileConfiguration>
</File>
<File <File
RelativePath=".\src\win32\OpenGL.cpp" RelativePath=".\src\win32\OpenGL.cpp"
> >

View File

@ -66,6 +66,7 @@ int InitLUTs(void)
} }
int hq3xinited=0; int hq3xinited=0;
extern int realsystemRedShift, realsystemBlueShift;
void hq3x32(unsigned char * pIn, unsigned int srcPitch, void hq3x32(unsigned char * pIn, unsigned int srcPitch,
unsigned char *, unsigned char *,
@ -80,6 +81,23 @@ void hq3x32(unsigned char * pIn, unsigned int srcPitch,
hq3xinited=1; hq3xinited=1;
} }
hq3x_32( pIn, pOut, Xres, Yres, dstPitch, srcPitch - (Xres *2) ); hq3x_32( pIn, pOut, Xres, Yres, dstPitch, srcPitch - (Xres *2) );
if (realsystemRedShift == 3)
{ // damn you opengl...
int offset = (dstPitch - (Xres *12)) / 4;
unsigned int *p = (unsigned int *)pOut;
Yres *= 3;
while(Yres--)
{
for(int i=0;i<Xres*3;i++)
{
*p = (*p & 0xFF0000) >> 16 |
(*p & 0x0000FF) << 16 |
(*p & 0x00FF00);
p++;
}
p += offset;
}
}
} }
void hq3x16(unsigned char * pIn, unsigned int srcPitch, void hq3x16(unsigned char * pIn, unsigned int srcPitch,
@ -122,4 +140,21 @@ void hq4x32(unsigned char * pIn, unsigned int srcPitch,
hq3xinited=1; hq3xinited=1;
} }
hq4x_32( pIn, pOut, Xres, Yres, dstPitch, srcPitch - (Xres *2)); hq4x_32( pIn, pOut, Xres, Yres, dstPitch, srcPitch - (Xres *2));
if (realsystemRedShift == 3)
{ // damn you opengl...
int offset = (dstPitch - (Xres *16)) / 4;
unsigned int *p = (unsigned int *)pOut;
Yres *= 4;
while(Yres--)
{
for(int i=0;i<Xres*4;i++)
{
*p = (*p & 0xFF0000) >> 16 |
(*p & 0x0000FF) << 16 |
(*p & 0x00FF00);
p++;
}
p += offset;
}
}
} }

View File

@ -1,110 +1,110 @@
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. // VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
// Copyright (C) 1999-2003 Forgotten // Copyright (C) 1999-2003 Forgotten
// Copyright (C) 2005 Forgotten and the VBA development team // Copyright (C) 2005 Forgotten and the VBA development team
// This program is free software; you can redistribute it and/or modify // 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 // it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2, or(at your option) // the Free Software Foundation; either version 2, or(at your option)
// any later version. // any later version.
// //
// This program is distributed in the hope that it will be useful, // This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of // but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. // GNU General Public License for more details.
// //
// You should have received a copy of the GNU General Public License // You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software Foundation, // along with this program; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "System.h" #include "System.h"
void Simple2x16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, void Simple2x16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height) u8 *dstPtr, u32 dstPitch, int width, int height)
{ {
u8 *nextLine, *finish; u8 *nextLine, *finish;
nextLine = dstPtr + dstPitch; nextLine = dstPtr + dstPitch;
do { do {
u32 *bP = (u32 *) srcPtr; u32 *bP = (u32 *) srcPtr;
u32 *dP = (u32 *) dstPtr; u32 *dP = (u32 *) dstPtr;
u32 *nL = (u32 *) nextLine; u32 *nL = (u32 *) nextLine;
u32 currentPixel; u32 currentPixel;
finish = (u8 *) bP + ((width+2) << 1); finish = (u8 *) bP + ((width+2) << 1);
currentPixel = *bP++; currentPixel = *bP++;
do { do {
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
u32 color = currentPixel >> 16; u32 color = currentPixel >> 16;
#else #else
u32 color = currentPixel & 0xffff; u32 color = currentPixel & 0xffff;
#endif #endif
color = color | (color << 16); color = color | (color << 16);
*(dP) = color; *(dP) = color;
*(nL) = color; *(nL) = color;
#ifdef WORDS_BIGENDIAN #ifdef WORDS_BIGENDIAN
color = currentPixel & 0xffff; color = currentPixel & 0xffff;
#else #else
color = currentPixel >> 16; color = currentPixel >> 16;
#endif #endif
color = color| (color << 16); color = color| (color << 16);
*(dP + 1) = color; *(dP + 1) = color;
*(nL + 1) = color; *(nL + 1) = color;
currentPixel = *bP++; currentPixel = *bP++;
dP += 2; dP += 2;
nL += 2; nL += 2;
} while ((u8 *) bP < finish); } while ((u8 *) bP < finish);
srcPtr += srcPitch; srcPtr += srcPitch;
dstPtr += dstPitch << 1; dstPtr += dstPitch << 1;
nextLine += dstPitch << 1; nextLine += dstPitch << 1;
} }
while (--height); while (--height);
} }
void Simple2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, void Simple2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height) u8 *dstPtr, u32 dstPitch, int width, int height)
{ {
u8 *nextLine, *finish; u8 *nextLine, *finish;
nextLine = dstPtr + dstPitch; nextLine = dstPtr + dstPitch;
do { do {
u32 *bP = (u32 *) srcPtr; u32 *bP = (u32 *) srcPtr;
u32 *dP = (u32 *) dstPtr; u32 *dP = (u32 *) dstPtr;
u32 *nL = (u32 *) nextLine; u32 *nL = (u32 *) nextLine;
u32 currentPixel; u32 currentPixel;
finish = (u8 *) bP + ((width+1) << 2); finish = (u8 *) bP + ((width+1) << 2);
currentPixel = *bP++; currentPixel = *bP++;
do { do {
u32 color = currentPixel; u32 color = currentPixel;
*(dP) = color; *(dP) = color;
*(dP+1) = color; *(dP+1) = color;
*(nL) = color; *(nL) = color;
*(nL + 1) = color; *(nL + 1) = color;
currentPixel = *bP++; currentPixel = *bP++;
dP += 2; dP += 2;
nL += 2; nL += 2;
} while ((u8 *) bP < finish); } while ((u8 *) bP < finish);
srcPtr += srcPitch; srcPtr += srcPitch;
dstPtr += dstPitch << 1; dstPtr += dstPitch << 1;
nextLine += dstPitch << 1; nextLine += dstPitch << 1;
} }
while (--height); while (--height);
} }
void Simple3x16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, void Simple3x16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */,
u8 *dstPtr, u32 dstPitch, int width, int height) u8 *dstPtr, u32 dstPitch, int width, int height)

View File

@ -27,8 +27,10 @@
#include "../Text.h" #include "../Text.h"
#include "../Util.h" #include "../Util.h"
#include "../gb/gbGlobals.h" #include "../gb/gbGlobals.h"
#include "..\memgzio.h"
#include <cmath> #include <cmath>
#include "glFont.h"
// OpenGL // OpenGL
#include <gl/GL.h> // main include file #include <gl/GL.h> // main include file
@ -57,7 +59,7 @@ extern bool detectMMX();
class OpenGLDisplay : public IDisplay { class OpenGLDisplay : public IDisplay {
private: private:
HDC hDC; HDC hDC;
HGLRC hglrc; HGLRC hRC;
GLuint texture; GLuint texture;
int width; int width;
int height; int height;
@ -65,18 +67,22 @@ private:
u8 *filterData; u8 *filterData;
RECT destRect; RECT destRect;
bool failed; bool failed;
GLFONT font;
void initializeMatrices( int w, int h ); void initializeMatrices( int w, int h );
bool initializeTexture( int w, int h ); bool initializeTexture( int w, int h );
void updateFiltering( int value ); void updateFiltering( int value );
void setVSync( int interval = 1 ); void setVSync( int interval = 1 );
void calculateDestRect( int w, int h ); void calculateDestRect( int w, int h );
void initializeFont();
public: public:
OpenGLDisplay(); OpenGLDisplay();
virtual ~OpenGLDisplay(); virtual ~OpenGLDisplay();
virtual DISPLAY_TYPE getType() { return OPENGL; }; virtual DISPLAY_TYPE getType() { return OPENGL; };
virtual void EnableOpenGL();
virtual void DisableOpenGL();
virtual bool initialize(); virtual bool initialize();
virtual void cleanup(); virtual void cleanup();
virtual void render(); virtual void render();
@ -88,17 +94,51 @@ public:
virtual int selectFullScreenMode( GUID ** ); virtual int selectFullScreenMode( GUID ** );
}; };
#include "gzglfont.h"
void OpenGLDisplay::initializeFont()
{
int ret;
z_stream strm;
char *buf = (char *)malloc(GZGLFONT_SIZE);
/* allocate inflate state */
strm.zalloc = Z_NULL;
strm.zfree = Z_NULL;
strm.opaque = Z_NULL;
strm.avail_in = 0;
strm.next_in = Z_NULL;
ret = inflateInit2(&strm, 16+MAX_WBITS);
if (ret != Z_OK)
return;
strm.avail_in = sizeof(gzglfont);
strm.next_in = gzglfont;
strm.avail_out = GZGLFONT_SIZE;
strm.next_out = (Bytef *)buf;
ret = inflate(&strm, Z_NO_FLUSH);
if (ret==Z_STREAM_END)
{
glGenTextures( 1, &texture );
glFontCreate(&font, (char *)buf, texture);
texture=0;
}
free(buf);
(void)inflateEnd(&strm);
}
OpenGLDisplay::OpenGLDisplay() OpenGLDisplay::OpenGLDisplay()
{ {
hDC = NULL; hDC = NULL;
hglrc = NULL; hRC = NULL;
texture = 0; texture = 0;
width = 0; width = 0;
height = 0; height = 0;
size = 0.0f; size = 0.0f;
filterData = (u8 *)malloc(4*4*256*240);
failed = false; failed = false;
filterData = NULL;
} }
@ -108,29 +148,49 @@ OpenGLDisplay::~OpenGLDisplay()
} }
void OpenGLDisplay::EnableOpenGL()
{
PIXELFORMATDESCRIPTOR pfd;
int format;
// get the device context (DC)
hDC = GetDC( theApp.m_pMainWnd->GetSafeHwnd() );
// set the pixel format for the DC
ZeroMemory( &pfd, sizeof( pfd ) );
pfd.nSize = sizeof( pfd );
pfd.nVersion = 1;
pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
pfd.iPixelType = PFD_TYPE_RGBA;
pfd.cColorBits = 24;
pfd.cDepthBits = 16;
pfd.iLayerType = PFD_MAIN_PLANE;
format = ChoosePixelFormat( hDC, &pfd );
SetPixelFormat( hDC, format, &pfd );
// create and enable the render context (RC)
hRC = wglCreateContext( hDC );
wglMakeCurrent( hDC, hRC );
}
void OpenGLDisplay::DisableOpenGL()
{
wglMakeCurrent( NULL, NULL );
wglDeleteContext( hRC );
ReleaseDC( theApp.m_pMainWnd->GetSafeHwnd(), hDC );
}
void OpenGLDisplay::cleanup() void OpenGLDisplay::cleanup()
{ {
if(texture != 0) { if(texture != 0) {
glDeleteTextures(1, &texture); glDeleteTextures(1, &texture);
texture = 0; texture = 0;
} }
DisableOpenGL();
if(hglrc != NULL) {
wglDeleteContext(hglrc);
wglMakeCurrent(NULL, NULL);
hglrc = NULL;
}
if(hDC != NULL) {
ReleaseDC(*theApp.m_pMainWnd, hDC);
hDC = NULL;
}
if(filterData) { if(filterData) {
free(filterData); free(filterData);
filterData = NULL; filterData = NULL;
} }
width = 0; width = 0;
height = 0; height = 0;
size = 0.0f; size = 0.0f;
@ -209,7 +269,7 @@ bool OpenGLDisplay::initialize()
theApp.dest.right = theApp.surfaceSizeX; theApp.dest.right = theApp.surfaceSizeX;
theApp.dest.bottom = theApp.surfaceSizeY; theApp.dest.bottom = theApp.surfaceSizeY;
DWORD style = WS_POPUP | WS_VISIBLE; DWORD style = WS_POPUPWINDOW | WS_VISIBLE;
DWORD styleEx = 0; DWORD styleEx = 0;
if( theApp.videoOption <= VIDEO_4X ) if( theApp.videoOption <= VIDEO_4X )
@ -253,77 +313,22 @@ bool OpenGLDisplay::initialize()
} }
theApp.updateMenuBar(); theApp.updateMenuBar();
theApp.adjustDestRect(); theApp.adjustDestRect();
theApp.mode320Available = FALSE; theApp.mode320Available = FALSE;
theApp.mode640Available = FALSE; theApp.mode640Available = FALSE;
theApp.mode800Available = FALSE; theApp.mode800Available = FALSE;
theApp.mode1024Available = FALSE;
theApp.mode1280Available = FALSE;
CDC *dc = pWnd->GetDC(); EnableOpenGL();
HDC hDC = dc->GetSafeHdc(); initializeFont();
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR),
1, // version number
PFD_DRAW_TO_WINDOW | // support window
PFD_SUPPORT_OPENGL | // support OpenGL
PFD_DOUBLEBUFFER, // double buffered
PFD_TYPE_RGBA, // RGBA type
24, // 24-bit color depth
0, 0, 0, 0, 0, 0, // color bits ignored
0, // no alpha buffer
0, // shift bit ignored
0, // no accumulation buffer
0, 0, 0, 0, // accum bits ignored
32, // 32-bit z-buffer
0, // no stencil buffer
0, // no auxiliary buffer
PFD_MAIN_PLANE, // main layer
0, // reserved
0, 0, 0 // layer masks ignored
};
int iPixelFormat;
if( !(iPixelFormat = ChoosePixelFormat( hDC, &pfd )) ) {
winlog( "Failed ChoosePixelFormat\n" );
return false;
}
// obtain detailed information about
// the device context's first pixel format
if( !( DescribePixelFormat(
hDC,
iPixelFormat,
sizeof(PIXELFORMATDESCRIPTOR),
&pfd ) ) )
{
winlog( "Failed DescribePixelFormat\n" );
return false;
}
if( !SetPixelFormat( hDC, iPixelFormat, &pfd ) ) {
winlog( "Failed SetPixelFormat\n" );
return false;
}
if( !( hglrc = wglCreateContext( hDC ) ) ) {
winlog( "Failed wglCreateContext\n" );
return false;
}
if( !wglMakeCurrent(hDC, hglrc) ) {
winlog( "Failed wglMakeCurrent\n" );
return false;
}
pWnd->ReleaseDC( dc );
// setup 2D gl environment
glPushAttrib( GL_ENABLE_BIT ); glPushAttrib( GL_ENABLE_BIT );
glDisable( GL_DEPTH_TEST ); glDisable( GL_DEPTH_TEST );
glDisable( GL_CULL_FACE ); glDisable( GL_CULL_FACE );
glEnable( GL_TEXTURE_2D ); glEnable( GL_TEXTURE_2D );
glEnable(GL_BLEND);
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
initializeMatrices( theApp.surfaceSizeX, theApp.surfaceSizeY ); initializeMatrices( theApp.surfaceSizeX, theApp.surfaceSizeY );
@ -359,6 +364,7 @@ bool OpenGLDisplay::initialize()
void OpenGLDisplay::clear() void OpenGLDisplay::clear()
{ {
glClearColor(0.0,0.0,0.0,1.0);
glClear( GL_COLOR_BUFFER_BIT ); glClear( GL_COLOR_BUFFER_BIT );
} }
@ -375,7 +381,8 @@ void OpenGLDisplay::render()
{ {
clear(); clear();
int pitch = theApp.filterWidth * 4 + 4;
int pitch = theApp.filterWidth * (systemColorDepth>>3) + 4;
u8 *data = pix + ( theApp.sizeX + 1 ) * 4; u8 *data = pix + ( theApp.sizeX + 1 ) * 4;
// apply pixel filter // apply pixel filter
@ -386,46 +393,46 @@ void OpenGLDisplay::render()
pitch, pitch,
(u8*)theApp.delta, (u8*)theApp.delta,
(u8*)filterData, (u8*)filterData,
theApp.filterWidth * 4 * 2, width * 4 ,
theApp.filterWidth, theApp.filterWidth,
theApp.filterHeight); theApp.filterHeight);
} }
// Texturemap complete texture to surface // Texturemap complete texture to surface
// so we have free scaling and antialiasing // so we have free scaling and antialiasing
int mult;
if( theApp.filterFunction ) { if( theApp.filterFunction ) {
glPixelStorei( GL_UNPACK_ROW_LENGTH, theApp.sizeX << 1 ); glPixelStorei( GL_UNPACK_ROW_LENGTH, width);
mult = 2;
} else { } else {
glPixelStorei( GL_UNPACK_ROW_LENGTH, theApp.sizeX + 1 ); glPixelStorei( GL_UNPACK_ROW_LENGTH, theApp.sizeX + 1 );
mult = 1;
} }
glTexSubImage2D( glTexSubImage2D(
GL_TEXTURE_2D, GL_TEXTURE_2D,
0, 0,
0, 0,
0, 0,
mult * theApp.sizeX, width,
mult * theApp.sizeY, height,
GL_RGBA, GL_RGBA,
GL_UNSIGNED_BYTE, GL_UNSIGNED_BYTE,
data ); data );
if( theApp.glType == 0 ) { if( theApp.glType == 0 ) {
glBegin( GL_TRIANGLE_STRIP ); glBegin( GL_TRIANGLE_STRIP );
glTexCoord2f( 0.0f, 0.0f ); glTexCoord2f( 0.0f, 0.0f );
glVertex3i( 0, 0, 0 ); glVertex3i( 0, 0, 0 );
glTexCoord2f( (float)(mult * theApp.sizeX) / size, 0.0f ); glTexCoord2f( (float)(width) / size, 0.0f );
glVertex3i( theApp.surfaceSizeX, 0, 0 ); glVertex3i( theApp.surfaceSizeX, 0, 0 );
glTexCoord2f( 0.0f, (float)(mult * theApp.sizeY) / size ); glTexCoord2f( 0.0f, (float)(height) / size );
glVertex3i( 0, theApp.surfaceSizeY, 0 ); glVertex3i( 0, theApp.surfaceSizeY, 0 );
glTexCoord2f( (float)(mult * theApp.sizeX) / size, (float)(mult * theApp.sizeY) / size ); glTexCoord2f( (float)(width) / size, (float)(height) / size );
glVertex3i( theApp.surfaceSizeX, theApp.surfaceSizeY, 0 ); glVertex3i( theApp.surfaceSizeX, theApp.surfaceSizeY, 0 );
glEnd(); glEnd();
@ -435,46 +442,62 @@ void OpenGLDisplay::render()
glTexCoord2f( 0.0f, 0.0f ); glTexCoord2f( 0.0f, 0.0f );
glVertex3i( 0, 0, 0 ); glVertex3i( 0, 0, 0 );
glTexCoord2f( (float)(mult * theApp.sizeX) / size, 0.0f ); glTexCoord2f( (float)(width) / size, 0.0f );
glVertex3i( theApp.surfaceSizeX, 0, 0 ); glVertex3i( theApp.surfaceSizeX, 0, 0 );
glTexCoord2f( (float)(mult * theApp.sizeX) / size, (float)(mult * theApp.sizeY) / size ); glTexCoord2f( (float)(width) / size, (float)(height) / size );
glVertex3i( theApp.surfaceSizeX, theApp.surfaceSizeY, 0 ); glVertex3i( theApp.surfaceSizeX, theApp.surfaceSizeY, 0 );
glTexCoord2f( 0.0f, (float)(mult * theApp.sizeY) / size ); glTexCoord2f( 0.0f, (float)(height) / size );
glVertex3i( 0, theApp.surfaceSizeY, 0 ); glVertex3i( 0, theApp.surfaceSizeY, 0 );
glEnd(); glEnd();
} }
CDC *dc = theApp.m_pMainWnd->GetDC();
SwapBuffers( dc->GetSafeHdc() );
// since OpenGL draws on the back buffer,
// we have to swap it to the front buffer to see it
// draw informations with GDI on the front buffer if( theApp.showSpeed ) { // && ( theApp.videoOption > VIDEO_4X ) ) {
dc->SetBkMode( theApp.showSpeedTransparent ? TRANSPARENT : OPAQUE );
if( theApp.showSpeed && ( theApp.videoOption > VIDEO_4X ) ) {
char buffer[30]; char buffer[30];
if( theApp.showSpeed == 1 ) { if( theApp.showSpeed == 1 ) {
sprintf( buffer, "%3d%%", systemSpeed ); sprintf( buffer, "%3d%%", systemSpeed );
} else { } else {
sprintf( buffer, "%3d%%(%d, %d fps)", systemSpeed, systemFrameSkip, theApp.showRenderedFrames ); sprintf( buffer, "%3d%%(%d, %d fps)", systemSpeed, systemFrameSkip, theApp.showRenderedFrames );
} }
dc->SetTextColor( RGB(0x00, 0x00, 0xFF) ); glFontBegin(&font);
dc->TextOut( 10, 20, buffer ); glPushMatrix();
float fontscale = (float)theApp.surfaceSizeX / 100.0;
glScalef(fontscale, fontscale, fontscale);
glColor4f(1.0f, 0.25f, 0.25f, 1.0f);
glFontTextOut(buffer, (theApp.surfaceSizeX-(strlen(buffer)*11))/(fontscale*2), (theApp.surfaceSizeY-20)/fontscale, 0);
glPopMatrix();
glFontEnd();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBindTexture( GL_TEXTURE_2D, texture );
} }
if( theApp.screenMessage ) { if( theApp.screenMessage ) {
if( ( ( GetTickCount() - theApp.screenMessageTime ) < 3000 ) && !theApp.disableStatusMessage ) { if( ( ( GetTickCount() - theApp.screenMessageTime ) < 3000 ) && !theApp.disableStatusMessage ) {
dc->SetTextColor( RGB(0xFF, 0x00, 0x00) ); glFontBegin(&font);
dc->TextOut( 10, theApp.surfaceSizeY - 20, theApp.screenMessageBuffer ); glPushMatrix();
float fontscale = (float)theApp.surfaceSizeX / 100.0;
glScalef(fontscale, fontscale, fontscale);
glColor4f(1.0f, 0.25f, 0.25f, 1.0f);
glFontTextOut((char *)((const char *)theApp.screenMessageBuffer), (theApp.surfaceSizeX-(theApp.screenMessageBuffer.GetLength()*11))/(fontscale*2), (theApp.surfaceSizeY-40)/fontscale, 0);
glPopMatrix();
glFontEnd();
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
glBindTexture( GL_TEXTURE_2D, texture );
} else { } else {
theApp.screenMessage = false; theApp.screenMessage = false;
} }
} }
theApp.m_pMainWnd->ReleaseDC( dc );
glFlush();
SwapBuffers( hDC );
// since OpenGL draws on the back buffer,
// we have to swap it to the front buffer to see it
// draw informations with GDI on the front buffer
} }
@ -602,6 +625,10 @@ bool OpenGLDisplay::changeRenderSize( int w, int h )
failed = true; failed = true;
return false; return false;
} }
if (filterData)
free(filterData);
filterData = (u8 *)malloc(4*w*h);
} }
return true; return true;

View File

@ -145,6 +145,10 @@ int systemRedShift = 0;
int systemBlueShift = 0; int systemBlueShift = 0;
int systemGreenShift = 0; int systemGreenShift = 0;
int systemColorDepth = 16; int systemColorDepth = 16;
int realsystemRedShift = 0;
int realsystemBlueShift = 0;
int realsystemGreenShift = 0;
int realsystemColorDepth = 16;
int systemVerbose = 0; int systemVerbose = 0;
int systemDebug = 0; int systemDebug = 0;
int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED;
@ -675,10 +679,10 @@ void VBA::updateFilter()
if ( b16to32Video ) if ( b16to32Video )
{ {
b16to32Video = false; b16to32Video = false;
systemColorDepth = 32; systemColorDepth = realsystemColorDepth;
systemRedShift = 19; systemRedShift = realsystemRedShift;
systemGreenShift = 11; systemGreenShift = realsystemGreenShift;
systemBlueShift = 3; systemBlueShift = realsystemBlueShift;
utilUpdateSystemColorMaps(); utilUpdateSystemColorMaps();
} }
// END hacky ugly code // END hacky ugly code
@ -859,11 +863,15 @@ void VBA::updateFilter()
if( display ) if( display )
display->changeRenderSize(rect.right, rect.bottom); display->changeRenderSize(rect.right, rect.bottom);
if (b16to32Video) if (b16to32Video && systemColorDepth!=16)
{ {
realsystemColorDepth = systemColorDepth;
systemColorDepth = 16; systemColorDepth = 16;
realsystemRedShift = systemRedShift;
systemRedShift = 11; systemRedShift = 11;
realsystemGreenShift = systemGreenShift;
systemGreenShift = 6; systemGreenShift = 6;
realsystemBlueShift = systemBlueShift;
systemBlueShift = 0; systemBlueShift = 0;
utilUpdateSystemColorMaps(); utilUpdateSystemColorMaps();
} }

154
src/win32/glfont.c Normal file
View File

@ -0,0 +1,154 @@
//*********************************************************
//GLFONT.CPP -- glFont routines
//Copyright (c) 1998 Brad Fish
//See glFont.txt for terms of use
//November 10, 1998
//*********************************************************
#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <gl\gl.h>
#include "glfont.h"
//*********************************************************
//Variables
//*********************************************************
//Current font
GLFONT *glFont;
//*********************************************************
//Functions
//*********************************************************
int glFontCreate (GLFONT *Font, char *Buffer, int Tex)
{
char *TexBytes;
int Num;
//Read glFont structure
memcpy(Font, Buffer, sizeof(GLFONT));
Buffer+=sizeof(GLFONT);
//Save texture number
Font->Tex = Tex;
//Get number of characters
Num = Font->IntEnd - Font->IntStart + 1;
//Allocate memory for characters
if ((Font->Char = (GLFONTCHAR *)malloc(
sizeof(GLFONTCHAR) * Num)) == NULL)
return FALSE;
//Read glFont characters
memcpy(Font->Char, Buffer, sizeof(GLFONTCHAR)*Num);
Buffer+=sizeof(GLFONTCHAR)*Num;
//Get texture size
Num = Font->TexWidth * Font->TexHeight * 2;
//Allocate memory for texture data
if ((TexBytes = (char *)malloc(Num)) == NULL)
return FALSE;
//Read texture data
memcpy(TexBytes, Buffer, sizeof(char)*Num);
Buffer+=sizeof(char)*Num;
//Set texture attributes
glBindTexture(GL_TEXTURE_2D, Font->Tex);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,
GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,
GL_CLAMP);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_LINEAR);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,
GL_MODULATE);
//Create texture
glTexImage2D(GL_TEXTURE_2D, 0, 2, Font->TexWidth,
Font->TexHeight, 0, GL_LUMINANCE_ALPHA,
GL_UNSIGNED_BYTE, (void *)TexBytes);
//Clean up
free(TexBytes);
//Return pointer to new font
return TRUE;
}
//*********************************************************
void glFontDestroy (GLFONT *Font)
{
//Free character memory
free(Font->Char);
}
//*********************************************************
void glFontBegin (GLFONT *Font)
{
//Save pointer to font structure
if (Font->Char != NULL)
glFont = Font;
else
glFont = NULL;
//Bind to font texture
glBindTexture(GL_TEXTURE_2D, Font->Tex);
}
//*********************************************************
void glFontEnd (void)
{
//Font no longer current
glFont = NULL;
}
//*********************************************************
void glFontTextOut (char *String, float x, float y,
float z)
{
int Length, i;
GLFONTCHAR *Char;
//Return if we don't have a valid glFont
if (glFont == NULL)
return;
//Get length of string
Length = strlen(String);
//Begin rendering quads
glBegin(GL_QUADS);
//Loop through characters
for (i = 0; i < Length; i++)
{
//Get pointer to glFont character
Char = &glFont->Char[(int)String[i] -
glFont->IntStart];
//Specify vertices and texture coordinates
glTexCoord2f(Char->tx1, Char->ty1);
glVertex3f(x, y - Char->dy, z);
glTexCoord2f(Char->tx1, Char->ty2);
glVertex3f(x, y, z);
glTexCoord2f(Char->tx2, Char->ty2);
glVertex3f(x + Char->dx, y, z);
glTexCoord2f(Char->tx2, Char->ty1);
glVertex3f(x + Char->dx, y - Char->dy, z);
//Move to next character
x += Char->dx;
}
//Stop rendering quads
glEnd();
}
//*********************************************************
//End of file

63
src/win32/glfont.h Normal file
View File

@ -0,0 +1,63 @@
//*********************************************************
//GLFONT.H -- Header for GLFONT.CPP
//Copyright (c) 1998 Brad Fish
//See glFont.txt for terms of use
//November 10, 1998
//*********************************************************
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
//*********************************************************
//Structures
//*********************************************************
//glFont character structure
typedef struct
{
float dx, dy;
float tx1, ty1;
float tx2, ty2;
} GLFONTCHAR;
//glFont structure
typedef struct
{
int Tex;
int TexWidth, TexHeight;
int IntStart, IntEnd;
GLFONTCHAR *Char;
} GLFONT;
//*********************************************************
//Function Declarations
//*********************************************************
#ifdef __cplusplus
extern "C" {
#endif
//Creates a glFont
int glFontCreate(GLFONT *Font, char *Buffer, int Tex);
//Deletes a glFont
void glFontDestroy (GLFONT *Font);
//Needs to be called before text output
void glFontBegin (GLFONT *Font);
//Needs to be called after text output
void glFontEnd (void);
//Draws text with a glFont
void glFontTextOut (char *String, float x, float y,
float z);
//*********************************************************
#ifdef __cplusplus
}
#endif
//End of file

257
src/win32/gzglfont.h Normal file
View File

@ -0,0 +1,257 @@
#define GZGLFONT_SIZE 35096
unsigned char gzglfont[]=
{
'\x1F', '\x8B', '\x08', '\x08', '\x72', '\x0F', '\x39', '\x47',
'\x00', '\x0B', '\x76', '\x65', '\x72', '\x64', '\x61', '\x6E',
'\x61', '\x00', '\xED', '\x97', '\xBF', '\x6B', '\x5C', '\x47',
'\x10', '\xC7', '\x2F', '\x21', '\x04', '\x27', '\x90', '\x20',
'\x82', '\x08', '\x21', '\x08', '\x21', '\x82', '\x62', '\x5C',
'\x19', '\x21', '\x8C', '\xAB', '\xDC', '\x7B', '\x42', '\x11',
'\x21', '\x0E', '\xC6', '\x1C', '\xAA', '\x0E', '\x05', '\x82',
'\x30', '\x42', '\xA8', '\x88', '\x85', '\x50', '\x11', '\x4C',
'\x9A', '\xB8', '\x70', '\x91', '\xC2', '\x85', '\x50', '\x95',
'\xC2', '\x85', '\x0A', '\x15', '\x29', '\x55', '\x08', '\xBB',
'\x49', '\xE1', '\x22', '\x4D', '\x7A', '\x17', '\x02', '\xBB',
'\x50', '\xE1', '\x22', '\x85', '\x0A', '\xFD', '\x01', '\x81',
'\xCB', '\xED', '\x7B', '\x73', '\x7E', '\xBB', '\xB3', '\x33',
'\xB3', '\xF3', '\x7E', '\xDC', '\xE9', '\x7C', '\xB7', '\x03',
'\xB2', '\xDF', '\x7D', '\x6E', '\xDE', '\xCE', '\x7C', '\x67',
'\x67', '\x7F', '\x5C', '\xAB', '\xD5', '\x6A', '\x3D', '\x82',
'\xBF', '\x85', '\xFE', '\xDF', '\x6F', '\xFD', '\xBF', '\x87',
'\x9F', '\x7C', '\xFB', '\xDE', '\xD7', '\x77', '\x3E', '\x4B',
'\xFB', '\x8F', '\x2B', '\xAD', '\xC2', '\xDA', '\xAD', '\xD6',
'\x79', '\x7B', '\xF7', '\xD5', '\x6D', '\xE0', '\x0B', '\xED',
'\x1C', '\x1F', '\x65', '\xBC', '\x3F', '\x02', '\xF0', '\x13',
'\xE0', '\x33', '\x49', '\xEE', '\xFF', '\x0C', '\xF8', '\x17',
'\x49', '\xCE', '\x77', '\x32', '\x7E', '\xE7', '\xF0', '\x18',
'\xF8', '\x1E', '\xF0', '\xA7', '\x19', '\x3F', '\x5C', '\xFC',
'\x68', '\xA5', '\xD7', '\xEB', '\xF5', '\xBF', '\x3B', '\x02',
'\xFE', '\x1A', '\x8D', '\x73', '\x0E', '\xFC', '\x83', '\xD4',
'\xF0', '\x22', '\xCF', '\x0F', '\xD3', '\x9C', '\x7F', '\x9A',
'\xBA', '\xF9', '\xCC', '\x00', '\x9F', '\x47', '\x7C', '\x01',
'\xF8', '\xCD', '\xD4', '\xCD', '\x67', '\x09', '\xF8', '\x6A',
'\xEA', '\xC6', '\x5D', '\x03', '\xDE', '\x45', '\x71', '\x37',
'\x80', '\xDF', '\xCF', '\xF8', '\xF3', '\x07', '\x3F', '\x02',
'\xDF', '\x02', '\xBE', '\x87', '\xFC', '\xF7', '\x81', '\xFF',
'\x0A', '\xFC', '\xD0', '\xAA', '\xF3', '\xA5', '\xC9', '\xAF',
'\x6D', '\x6A', '\x54', '\xE4', '\x73', '\xD0', '\xCE', '\xB9',
'\xA9', '\xA7', '\xCD', '\x4D', '\x3D', '\x0D', '\xDF', '\x44',
'\x7C', '\x07', '\xF8', '\x1F', '\x88', '\x3F', '\x05', '\xFE',
'\x02', '\xF1', '\xBF', '\x81', '\xFF', '\x8B', '\xF8', '\x05',
'\xF0', '\x6B', '\xA9', '\xCB', '\x3F', '\x4E', '\x73', '\x3E',
'\x87', '\xF8', '\x3C', '\xF0', '\x25', '\xC4', '\x97', '\x81',
'\xAF', '\x21', '\xFE', '\x1D', '\xF0', '\x6E', '\xC6', '\x8B',
'\xBE', '\xDA', '\x00', '\xBE', '\x85', '\xF8', '\x36', '\xF0',
'\x3D', '\xE0', '\xCF', '\xAC', '\xBA', '\x99', '\x1E', '\x32',
'\x7D', '\x78', '\x62', '\x71', '\xD3', '\x87', '\x86', '\xDF',
'\x48', '\x5C', '\xBE', '\x94', '\xE4', '\xFC', '\x51', '\xC6',
'\x8B', '\x7E', '\x78', '\x0C', '\xFC', '\x28', '\xE3', '\xCF',
'\x1F', '\xBC', '\x02', '\x7E', '\x0C', '\xFC', '\x65', '\xC6',
'\x8B', '\xFC', '\xCF', '\x80', '\xFF', '\x87', '\x78', '\x2B',
'\xCD', '\xB9', '\x99', '\x6F', '\x9B', '\xCF', '\x02', '\xBF',
'\x9E', '\xBA', '\xF9', '\xDC', '\x00', '\xFE', '\x4D', '\xC6',
'\x8B', '\x7E', '\x48', '\x80', '\xDF', '\x43', '\xBC', '\x03',
'\x7C', '\x13', '\x8D', '\x73', '\x1F', '\xF8', '\x2F', '\x88',
'\x1B', '\x3B', '\x85', '\xFA', '\x5C', '\x24', '\x45', '\x7F',
'\x9A', '\xFA', '\x18', '\x7E', '\x2D', '\xC9', '\xE7', '\xFA',
'\xED', '\x7A', '\x49', '\x72', '\xFE', '\x7D', '\xC6', '\x8B',
'\xFC', '\x3B', '\xC0', '\x9F', '\x64', '\xBC', '\xC8', '\xE7',
'\x00', '\xF8', '\x49', '\xC6', '\x0F', '\x17', '\xFF', '\x01',
'\x7E', '\x0A', '\xFC', '\x3C', '\xE3', '\x45', '\x3E', '\x6F',
'\x80', '\x9B', '\xF5', '\x6A', '\xFB', '\x9B', '\x3E', '\x33',
'\x7C', '\x3E', '\x75', '\xE3', '\x2E', '\x00', '\x5F', '\x46',
'\xFE', '\xB7', '\x80', '\xFF', '\x80', '\xFC', '\xEF', '\x02',
'\xFF', '\x09', '\xF1', '\x4D', '\xE0', '\xFB', '\xA9', '\x9B',
'\x7F', '\xB6', '\xEE', '\x92', '\x7C', '\xDD', '\xCD', '\xA6',
'\x45', '\x9E', '\xD9', '\xBA', '\x4B', '\xF2', '\x75', '\x36',
'\x9B', '\x5A', '\xF9', '\x24', '\x39', '\xDF', '\x49', '\xF2',
'\x39', '\xCD', '\xC6', '\x58', '\xC9', '\x6B', '\x7F', '\x09',
'\x75', '\xB0', '\xFD', '\x4F', '\x81', '\x9F', '\x25', '\xEE',
'\xF8', '\xAF', '\x81', '\xBF', '\x9F', '\x1A', '\x5E', '\xE4',
'\x63', '\xF6', '\xB5', '\x4B', '\x18', '\x7B', '\x36', '\x2D',
'\xE6', '\xEB', '\x73', '\xE0', '\x5F', '\x21', '\xFF', '\x45',
'\xE0', '\xB7', '\x90', '\xFF', '\x6D', '\xE0', '\xAB', '\xA9',
'\x1B', '\x77', '\x0D', '\x78', '\x37', '\x75', '\xF3', '\xDC',
'\x00', '\xFE', '\x33', '\xE2', '\xC6', '\x4C', '\x6C', '\x53',
'\x8F', '\x65', '\x2B', '\xAE', '\xE9', '\x27', '\xC3', '\x67',
'\x12', '\x97', '\x9B', '\x7A', '\x19', '\xDE', '\x85', '\x39',
'\x1B', '\xF4', '\xD5', '\x26', '\xF0', '\x27', '\xC8', '\xFF',
'\x00', '\xF8', '\x09', '\xE2', '\xA7', '\xC0', '\x5F', '\x66',
'\xBC', '\xD8', '\x07', '\xCE', '\x80', '\x5F', '\x20', '\xFF',
'\x4B', '\xE0', '\xA6', '\x8F', '\x6C', '\x6E', '\xF6', '\x2B',
'\xC3', '\xBF', '\x04', '\x3E', '\xD8', '\x87', '\xE7', '\x80',
'\x2F', '\xA6', '\xEE', '\xF8', '\xD7', '\x81', '\x2F', '\xA1',
'\x71', '\x96', '\x81', '\xAF', '\xA2', '\x71', '\xD6', '\x80',
'\xDF', '\xCD', '\x78', '\xB1', '\x6F', '\xDC', '\x03', '\xBE',
'\x8D', '\xC6', '\xD9', '\x01', '\xFE', '\x10', '\x71', '\x63',
'\x66', '\x0E', '\x4D', '\x1F', '\x76', '\xEC', '\xFA', '\xB4',
'\x73', '\x6E', '\xD6', '\xA9', '\xCD', '\x67', '\x60', '\xCE',
'\x3B', '\x19', '\x2F', '\xE6', '\xBD', '\x0B', '\xFC', '\x71',
'\x92', '\xEF', '\x15', '\x83', '\xFA', '\xFF', '\x0E', '\xFC',
'\x38', '\xE3', '\x85', '\xDE', '\x3F', '\x81', '\xFF', '\x85',
'\xC6', '\x7F', '\x01', '\xFC', '\x1C', '\xF1', '\x37', '\xC0',
'\x4D', '\xDF', '\x76', '\x2C', '\xBD', '\xA6', '\x6F', '\x0D',
'\x9F', '\x4B', '\x5D', '\xFF', '\x79', '\xE0', '\x37', '\x11',
'\x5F', '\x02', '\xBE', '\x92', '\xBA', '\x79', '\xAE', '\x02',
'\xEF', '\x64', '\x7F', '\x45', '\x1F', '\xAE', '\x03', '\xDF',
'\x4A', '\x5D', '\xBD', '\xDB', '\xC0', '\xF7', '\x91', '\xBF',
'\xB1', '\x75', '\xE8', '\xDB', '\x5D', '\xAB', '\xFF', '\x4D',
'\xDF', '\x1A', '\x6E', '\xD6', '\xF1', '\xAE', '\x95', '\xBF',
'\x39', '\x27', '\xD6', '\xA1', '\x6E', '\xBB', '\x69', '\x2B',
'\x5A', '\x34', '\xC2', '\xFA', '\x77', '\xD3', '\xDE', '\xE0',
'\xDF', '\xB0', '\x6F', '\x53', '\xF1', '\x34', '\x9F', '\x9A',
'\x8B', '\x29', '\xE5', '\x40', '\xEB', '\xCF', '\x3F', '\xE1',
'\xD8', '\xFE', '\x67', '\x77', '\x24', '\x2A', '\x0E', '\xF5',
'\x0E', '\xF5', '\x4C', '\x91', '\x3C', '\xB3', '\xE6', '\x6B',
'\x50', '\x45', '\x7F', '\xEF', '\xAD', '\x71', '\x6F', '\xD2',
'\x5A', '\xFC', '\x91', '\xF5', '\xFA', '\xE9', '\x0A', '\xD6',
'\xAF', '\x87', '\xDC', '\xED', '\x3D', '\xC7', '\xEC', '\x37',
'\xDC', '\xAA', '\xB8', '\xFA', '\xE8', '\xD9', '\x97', '\x62',
'\xD1', '\xDF', '\xF8', '\x2B', '\x62', '\xDC', '\xF4', '\xBB',
'\xA3', '\xD8', '\xFA', '\xE5', '\xFE', '\xD0', '\x65', '\x81',
'\x57', '\x14', '\xD5', '\xFF', '\xC3', '\xD5', '\x2F', '\x77',
'\x3F', '\xAD', '\xCF', '\x7E', '\x72', '\x3D', '\x06', '\x63',
'\x71', '\xFD', '\x11', '\xA2', '\xD4', '\x7A', '\xC0', '\x99',
'\xF8', '\xDF', '\x4B', '\xEA', '\x64', '\xFD', '\x5C', '\x04',
'\xAE', '\x02', '\xF6', '\xBA', '\xC0', '\xFB', '\x81', '\x5B',
'\x1F', '\x5D', '\x16', '\xE1', '\xEC', '\x87', '\x73', '\x26',
'\xD8', '\xF1', '\xB9', '\x0A', '\x73', '\xFD', '\x2C', '\xE9',
'\xE7', '\x15', '\x5D', '\x9D', '\x7E', '\x39', '\x06', '\xB5',
'\x9F', '\xB9', '\x6B', '\x9C', '\xCE', '\x86', '\xD3', '\x5F',
'\x4E', '\x69', '\x15', '\xFD', '\xE5', '\x2A', '\x5C', '\x45',
'\x3F', '\x75', '\xFE', '\xF9', '\xD9', '\x70', '\x6B', '\x46',
'\xAF', '\x55', '\xA3', '\x5E', '\x33', '\x4E', '\x9D', '\xD1',
'\xA4', '\x38', '\x4D', '\x8E', '\x36', '\x7C', '\xFD', '\x4D',
'\x5B', '\xF3', '\x51', '\xFC', '\x7E', '\xA9', '\x36', '\x4A',
'\x53', '\xF9', '\x44', '\x8B', '\x36', '\xE9', '\x36', '\xAA',
'\xDD', '\x62', '\x5C', '\xCD', '\xBF', '\xC1', '\x85', '\xF7',
'\x61', '\xCA', '\x4F', '\x3A', '\x11', '\x43', '\x37', '\x47',
'\xFF', '\xA6', '\xDA', '\xEB', '\x51', '\x7E', '\xE5', '\xE2',
'\x6A', '\x0C', '\x8F', '\x4E', '\x53', '\x6E', '\x5F', '\x96',
'\x9F', '\xEC', '\xF7', '\xE9', '\x88', '\x12', '\x2B', '\x1B',
'\xAD', '\xFE', '\x59', '\x29', '\x6B', '\x08', '\xBD', '\x4D',
'\x33', '\xFF', '\xB6', '\x13', '\xEE', '\xAE', '\x32', '\xF9',
'\x85', '\x2A', '\x11', '\xAA', '\xCA', '\xD5', '\xE8', '\xE7',
'\x7B', '\xBD', '\x6C', '\x7E', '\xF5', '\xF4', '\x87', '\xFB',
'\x5A', '\x1A', '\x85', '\xEE', '\x74', '\xAC', '\x3E', '\xFC',
'\xB6', '\x3E', '\x2E', '\x5D', '\x3B', '\x29', '\x47', '\xD9',
'\xEA', '\xE8', '\x0F', '\xF7', '\x84', '\xF6', '\xF7', '\x8E',
'\x36', '\x2E', '\x3F', '\xC3', '\x5C', '\xF7', '\xC8', '\xC6',
'\x47', '\x0B', '\xEB', '\xE7', '\xA3', '\xB9', '\xA3', '\x68',
'\x3A', '\x9B', '\x8B', '\xAB', '\xCF', '\x4F', '\xCE', '\x88',
'\xB3', '\xEA', '\xFA', '\xA5', '\x7A', '\xC8', '\xB5', '\x92',
'\x55', '\x57', '\xD7', '\x4F', '\xC7', '\xD0', '\xEF', '\xAD',
'\x05', '\xC1', '\xB3', '\xE5', '\xCF', '\x21', '\x3D', '\xAF',
'\x9A', '\x99', '\x0E', '\xC7', '\x90', '\xB2', '\x93', '\xDF',
'\xA5', '\xDF', '\xE4', '\xF5', '\x97', '\xEF', '\x97', '\x77',
'\xD1', '\xA2', '\xFE', '\xAB', '\xCE', '\x20', '\x5A', '\xB4',
'\x68', '\x93', '\x69', '\xD4', '\x79', '\x27', '\x9D', '\x82',
'\xA1', '\x33', '\x8F', '\x7A', '\x9F', '\x3A', '\x6B', '\x43',
'\xA7', '\x72', '\x38', '\x0A', '\x8E', '\x19', '\xD2', '\xC9',
'\x53', '\xEE', '\xB4', '\xC5', '\x31', '\xB9', '\x53', '\x9A',
'\x3B', '\xBB', '\xCB', '\xFE', '\xAE', '\xE1', '\x6A', '\x2E',
'\x6B', '\xD0', '\x9E', '\x83', '\xBA', '\x73', '\x74', '\xF0',
'\x6B', '\x2F', '\x67', '\xBE', '\x2E', '\x4A', '\x41', '\xE8',
'\xB6', '\x42', '\x7F', '\xAF', '\xD1', '\x1F', '\x56', '\xC6',
'\x77', '\x1F', '\xD7', '\x99', '\x72', '\x76', '\x58', '\x27',
'\xCE', '\x7C', '\x9C', '\xF4', '\xEB', '\xE6', '\x5D', '\x7E',
'\x0B', '\x7F', '\x2A', '\xAB', '\x1F', '\xD7', '\xB9', '\x9C',
'\x7E', '\xF7', '\x6D', '\x9A', '\x68', '\x95', '\x68', '\xAD',
'\x59', '\xFD', '\xFC', '\x13', '\x1D', '\xA3', '\xDA', '\xFC',
'\xD3', '\xDD', '\xCC', '\xBF', '\xE3', '\xCF', '\x0B', '\x9F',
'\x9D', '\xFB', '\x3D', '\xA7', '\x9F', '\x1A', '\x75', '\x74',
'\xFA', '\xE5', '\xDC', '\x75', '\x7D', '\xA0', '\xAB', '\x9F',
'\xBD', '\xFF', '\xE9', '\xE7', '\x9A', '\xF3', '\xD4', '\xF9',
'\x49', '\x19', '\xEA', '\xD7', '\x02', '\xFF', '\x9D', '\xF4',
'\xBD', '\xAF', '\x9F', '\x3B', '\x29', '\x69', '\x35', '\x54',
'\x9F', '\x51', '\xB5', '\xF3', '\xFD', '\xA4', '\x7E', '\xA2',
'\x46', '\xD3', '\xCD', '\x72', '\x13', '\x36', '\xDA', '\x68',
'\xD1', '\xA2', '\x45', '\x8B', '\x16', '\xAD', '\xAC', '\xF1',
'\xE7', '\x33', '\x75', '\x46', '\x51', '\x7E', '\xFE', '\x38',
'\x14', '\xE1', '\x3C', '\xE9', '\xD3', '\x8C', '\x62', '\xF4',
'\xF9', '\x18', '\xF6', '\x95', '\x4F', '\x3E', '\x5A', '\xBF',
'\xAC', '\x67', '\xF0', '\x14', '\xF6', '\x77', '\x2B', '\xE8',
'\x3F', '\xFB', '\x77', '\x63', '\x7E', '\xDC', '\x6A', '\x94',
'\x8E', '\xD5', '\x84', '\x7E', '\x6E', '\x7E', '\xC3', '\xFA',
'\xE5', '\xFB', '\x5D', '\x58', '\x49', '\x75', '\x5F', '\xDF',
'\xAA', '\xEA', '\xA7', '\xFA', '\x11', '\xFB', '\x17', '\x95',
'\xC2', '\x8A', '\x47', '\xAB', '\x5F', '\xBE', '\xF3', '\xBA',
'\xA6', '\xD7', '\xCF', '\x7D', '\xAB', '\xD1', '\x6F', '\xAF',
'\xA1', '\x66', '\xF5', '\xFB', '\x73', '\x43', '\x31', '\x3A',
'\xEF', '\xE6', '\xE7', '\x9F', '\xDA', '\x2B', '\xF0', '\x2A',
'\x2A', '\xAF', '\x49', '\xAE', '\x15', '\xAD', '\x94', '\xAB',
'\x40', '\x55', '\xFD', '\x9A', '\xF5', '\xDF', '\x94', '\x7E',
'\x29', '\xE7', '\xD0', '\xBE', '\x2C', '\x65', '\x88', '\x69',
'\x39', '\xFD', '\x61', '\x7F', '\xEE', '\x6D', '\x9B', '\xE9',
'\xF7', '\x74', '\x39', '\x17', '\x8E', '\xEA', '\x47', '\xE2',
'\x3A', '\x5C', '\xEA', '\x3F', '\xBA', '\x4F', '\xDD', '\x95',
'\xCD', '\x67', '\x44', '\xCD', '\x24', '\xEE', '\x53', '\x3A',
'\xEB', '\xB0', '\x2F', '\x95', '\x19', '\x35', '\xCE', '\xBB',
'\x6C', '\x93', '\xA8', '\xA9', '\x9C', '\x4D', '\xEA', '\xCC',
'\x46', '\x8B', '\x36', '\xCD', '\xE6', '\xAE', '\x6B', '\xFA',
'\x2C', '\x6E', '\x62', '\xDD', '\xF7', '\x90', '\xE1', '\x68',
'\xDC', '\x49', '\x57', '\xFF', '\x49', '\xBE', '\xE3', '\x69',
'\xCE', '\x40', '\x4C', '\xAB', '\xD7', '\x43', '\x7B', '\x8A',
'\x36', '\xF9', '\x24', '\xE7', '\xAF', '\xD1', '\xE6', '\x67',
'\x5D', '\xB5', '\x02', '\xC3', '\xD1', '\x2F', '\xDF', '\x93',
'\xE9', '\x9E', '\xA6', '\x33', '\x0A', '\xEB', '\xE7', '\x47',
'\xD5', '\x98', '\x46', '\xBF', '\x4E', '\x0D', '\x95', '\xB7',
'\x6E', '\xED', '\xCA', '\x1D', '\x2F', '\xEB', '\x97', '\x2A',
'\xA7', '\xB1', '\xBA', '\xFA', '\x0B', '\x45', '\x1A', '\xFD',
'\xE5', '\x7E', '\xD3', '\x94', '\x21', '\x55', '\xAD', '\xBE',
'\xFE', '\xFC', '\xB9', '\xBA', '\xFE', '\xF0', '\x7C', '\x5F',
'\xBD', '\x7E', '\xA9', '\x9B', '\xE9', '\x6F', '\xE9', '\x9E',
'\xA8', '\xA6', '\xBF', '\xC9', '\xFD', '\x5E', '\x1E', '\xB9',
'\xBC', '\xFE', '\xD0', '\x38', '\xA1', '\xCC', '\x75', '\x73',
'\x3B', '\x2A', '\xFD', '\xD4', '\x79', '\x6C', '\x73', '\xFE',
'\xDD', '\x3A', '\xFA', '\xDD', '\x78', '\xA3', '\xD5', '\x3F',
'\x7E', '\x46', '\x6B', '\xE3', '\xFB', '\x74', '\xD2', '\x8C',
'\xEA', '\x3E', '\xEA', '\xC6', '\x18', '\x1E', '\x81', '\xEE',
'\xE4', '\x68', '\xD1', '\xA2', '\xE5', '\xA6', '\x59', '\x1B',
'\xFA', '\xF5', '\xA3', '\x59', '\x95', '\xDA', '\x37', '\xE9',
'\xB3', '\x45', '\x77', '\x5A', '\x96', '\xB1', '\xF0', '\xFB',
'\xCD', '\xE8', '\x0F', '\xD7', '\x86', '\x27', '\xC3', '\xD4',
'\x1F', '\xB6', '\xAB', '\xD1', '\xAF', '\xF5', '\x6B', '\x5E',
'\x3F', '\x3E', '\x33', '\xA8', '\x53', '\x24', '\xEC', '\xE3',
'\xDF', '\x69', '\xCA', '\x7C', '\xF6', '\xCF', '\x3B', '\x97',
'\x52', '\x1D', '\x91', '\x3F', '\xF9', '\x1E', '\xB4', '\x02',
'\x4D', '\x15', '\x34', '\x31', '\x65', '\x0F', '\xBA', '\x73',
'\xAB', '\xFA', '\x53', '\xBF', '\x2A', '\xFC', '\x3A', '\xD9',
'\xFF', '\x73', '\xA3', '\x87', '\x94', '\x6B', '\x6B', '\x5E',
'\x4F', '\x4F', '\x35', '\xFD', '\x6E', '\x74', '\x7E', '\x8C',
'\x6A', '\xFA', '\xCB', '\xE6', '\xC6', '\x7B', '\xD0', '\x55',
'\x9C', '\x1E', '\xFD', '\xF4', '\xB8', '\xF5', '\xF5', '\x87',
'\xCE', '\x86', '\x51', '\xEA', '\x0F', '\x45', '\x1C', '\x78',
'\x34', '\xAB', '\x5F', '\xDA', '\xFF', '\xEA', '\xEA', '\xD7',
'\xEC', '\xCD', '\x7E', '\x1F', '\xFA', '\x3E', '\xD4', '\x67',
'\x39', '\x46', '\x19', '\xFD', '\x1A', '\x95', '\x55', '\xF5',
'\x8F', '\xCE', '\xB4', '\xF9', '\x8C', '\x5B', '\xDE', '\xF5',
'\xCD', '\xEF', '\x28', '\xD9', '\x73', '\xF8', '\x19', '\x45',
'\x8B', '\x16', '\x6D', '\x32', '\x8C', '\x3A', '\xAD', '\x46',
'\x19', '\x7B', '\x54', '\xB1', '\xB4', '\x19', '\x44', '\xFD',
'\x5C', '\x4E', '\xE1', '\x7B', '\x0C', '\x77', '\x57', '\xF1',
'\xEF', '\x47', '\xBE', '\xAF', '\xE6', '\x26', '\x52', '\xC7',
'\x97', '\xCF', '\x57', '\xA7', '\xBF', '\x89', '\x98', '\x78',
'\x6C', '\x5C', '\xCD', '\xE1', '\xEA', '\xA7', '\xF4', '\x8D',
'\x42', '\x3F', '\x3F', '\x76', '\x73', '\xFA', '\xF9', '\x3B',
'\x34', '\x9F', '\x01', '\xEE', '\x85', '\xE1', '\xEB', '\xC7',
'\x31', '\x43', '\xF9', '\xD2', '\x9A', '\x06', '\x7E', '\x9A',
'\xEA', '\xFA', '\x1E', '\x52', '\x37', '\x0C', '\x5F', '\x3F',
'\xFF', '\xAD', '\x46', '\xBF', '\xAD', '\x80', '\xFE', '\x26',
'\x4C', '\x42', '\x6A', '\xC7', '\x5F', '\xBF', '\xF4', '\x1C',
'\xEE', '\x9E', '\xAA', '\xFA', '\xEB', '\xEC', '\xFF', '\xB2',
'\x9E', '\x32', '\xFB', '\x73', '\x19', '\xFD', '\x5C', '\xF4',
'\x6A', '\xFB', '\x9F', '\x6F', '\x72', '\xA5', '\x74', '\x63',
'\x0C', '\xD7', '\xC2', '\x79', '\x4C', '\xB2', '\x7E', '\x5D',
'\x16', '\xE1', '\x8E', '\x88', '\x16', '\x2D', '\x1A', '\x77',
'\x5F', '\x9A', '\x2E', '\x9B', '\xF6', '\x0A', '\x44', '\xFD',
'\x51', '\x3F', '\xF7', '\x79', '\x3A', '\x2A', '\xE3', '\xDE',
'\x58', '\x8B', '\x7F', '\xA7', '\x43', '\x3F', '\xBE', '\x2B',
'\xD9', '\xFF', '\x4F', '\xAF', '\xFE', '\xE9', '\xD9', '\x17',
'\xA6', '\x45', '\x27', '\x67', '\x51', '\xFF', '\xF4', '\xEA',
'\x8F', '\xF7', '\xDF', '\x68', '\xD1', '\xA2', '\x45', '\x8B',
'\x16', '\x2D', '\x5A', '\xB4', '\xE9', '\xB1', '\xFF', '\x01',
'\xF1', '\xAA', '\xBA', '\x4E', '\x18', '\x89', '\x00', '\x00'
};