From 4d3a628089b1d30a7ff4b417d08e9c639efa2297 Mon Sep 17 00:00:00 2001 From: DJRobX Date: Tue, 13 Nov 2007 12:12:57 +0000 Subject: [PATCH] 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. --- VBA.vcproj | 28 +++++ src/hq3x32.cpp | 35 ++++++ src/simpleFilter.cpp | 214 +++++++++++++++++------------------ src/win32/OpenGL.cpp | 245 +++++++++++++++++++++++------------------ src/win32/VBA.cpp | 20 +++- src/win32/glfont.c | 154 ++++++++++++++++++++++++++ src/win32/glfont.h | 63 +++++++++++ src/win32/gzglfont.h | 257 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 794 insertions(+), 222 deletions(-) create mode 100644 src/win32/glfont.c create mode 100644 src/win32/glfont.h create mode 100644 src/win32/gzglfont.h diff --git a/VBA.vcproj b/VBA.vcproj index ef1ffa89..27f43c0a 100644 --- a/VBA.vcproj +++ b/VBA.vcproj @@ -1113,6 +1113,34 @@ RelativePath=".\src\win32\GDIDisplay.cpp" > + + + + + + + + + + + diff --git a/src/hq3x32.cpp b/src/hq3x32.cpp index 492225b1..bb2f0380 100644 --- a/src/hq3x32.cpp +++ b/src/hq3x32.cpp @@ -66,6 +66,7 @@ int InitLUTs(void) } int hq3xinited=0; +extern int realsystemRedShift, realsystemBlueShift; void hq3x32(unsigned char * pIn, unsigned int srcPitch, unsigned char *, @@ -80,6 +81,23 @@ void hq3x32(unsigned char * pIn, unsigned int srcPitch, hq3xinited=1; } 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> 16 | + (*p & 0x0000FF) << 16 | + (*p & 0x00FF00); + p++; + } + p += offset; + } + } } void hq3x16(unsigned char * pIn, unsigned int srcPitch, @@ -122,4 +140,21 @@ void hq4x32(unsigned char * pIn, unsigned int srcPitch, hq3xinited=1; } 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> 16 | + (*p & 0x0000FF) << 16 | + (*p & 0x00FF00); + p++; + } + p += offset; + } + } } diff --git a/src/simpleFilter.cpp b/src/simpleFilter.cpp index 15e0e78c..7c8b68e2 100644 --- a/src/simpleFilter.cpp +++ b/src/simpleFilter.cpp @@ -1,110 +1,110 @@ -// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. -// Copyright (C) 1999-2003 Forgotten -// Copyright (C) 2005 Forgotten and the VBA development team - -// 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; either version 2, or(at your option) -// any later version. -// -// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "System.h" - -void Simple2x16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, - u8 *dstPtr, u32 dstPitch, int width, int height) -{ - u8 *nextLine, *finish; - - nextLine = dstPtr + dstPitch; - - do { - u32 *bP = (u32 *) srcPtr; - u32 *dP = (u32 *) dstPtr; - u32 *nL = (u32 *) nextLine; - u32 currentPixel; - - finish = (u8 *) bP + ((width+2) << 1); - currentPixel = *bP++; - - do { -#ifdef WORDS_BIGENDIAN - u32 color = currentPixel >> 16; -#else - u32 color = currentPixel & 0xffff; -#endif - - color = color | (color << 16); - - *(dP) = color; - *(nL) = color; - -#ifdef WORDS_BIGENDIAN - color = currentPixel & 0xffff; -#else - color = currentPixel >> 16; -#endif - color = color| (color << 16); - *(dP + 1) = color; - *(nL + 1) = color; - - currentPixel = *bP++; - - dP += 2; - nL += 2; - } while ((u8 *) bP < finish); - - srcPtr += srcPitch; - dstPtr += dstPitch << 1; - nextLine += dstPitch << 1; - } - while (--height); -} - -void Simple2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, - u8 *dstPtr, u32 dstPitch, int width, int height) -{ - u8 *nextLine, *finish; - - nextLine = dstPtr + dstPitch; - - do { - u32 *bP = (u32 *) srcPtr; - u32 *dP = (u32 *) dstPtr; - u32 *nL = (u32 *) nextLine; - u32 currentPixel; - - finish = (u8 *) bP + ((width+1) << 2); - currentPixel = *bP++; - - do { - u32 color = currentPixel; - - *(dP) = color; - *(dP+1) = color; - *(nL) = color; - *(nL + 1) = color; - - currentPixel = *bP++; - - dP += 2; - nL += 2; - } while ((u8 *) bP < finish); - - srcPtr += srcPitch; - dstPtr += dstPitch << 1; - nextLine += dstPitch << 1; - } - while (--height); -} - +// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. +// Copyright (C) 1999-2003 Forgotten +// Copyright (C) 2005 Forgotten and the VBA development team + +// 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; either version 2, or(at your option) +// any later version. +// +// 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "System.h" + +void Simple2x16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, + u8 *dstPtr, u32 dstPitch, int width, int height) +{ + u8 *nextLine, *finish; + + nextLine = dstPtr + dstPitch; + + do { + u32 *bP = (u32 *) srcPtr; + u32 *dP = (u32 *) dstPtr; + u32 *nL = (u32 *) nextLine; + u32 currentPixel; + + finish = (u8 *) bP + ((width+2) << 1); + currentPixel = *bP++; + + do { +#ifdef WORDS_BIGENDIAN + u32 color = currentPixel >> 16; +#else + u32 color = currentPixel & 0xffff; +#endif + + color = color | (color << 16); + + *(dP) = color; + *(nL) = color; + +#ifdef WORDS_BIGENDIAN + color = currentPixel & 0xffff; +#else + color = currentPixel >> 16; +#endif + color = color| (color << 16); + *(dP + 1) = color; + *(nL + 1) = color; + + currentPixel = *bP++; + + dP += 2; + nL += 2; + } while ((u8 *) bP < finish); + + srcPtr += srcPitch; + dstPtr += dstPitch << 1; + nextLine += dstPitch << 1; + } + while (--height); +} + +void Simple2x32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, + u8 *dstPtr, u32 dstPitch, int width, int height) +{ + u8 *nextLine, *finish; + + nextLine = dstPtr + dstPitch; + + do { + u32 *bP = (u32 *) srcPtr; + u32 *dP = (u32 *) dstPtr; + u32 *nL = (u32 *) nextLine; + u32 currentPixel; + + finish = (u8 *) bP + ((width+1) << 2); + currentPixel = *bP++; + + do { + u32 color = currentPixel; + + *(dP) = color; + *(dP+1) = color; + *(nL) = color; + *(nL + 1) = color; + + currentPixel = *bP++; + + dP += 2; + nL += 2; + } while ((u8 *) bP < finish); + + srcPtr += srcPitch; + dstPtr += dstPitch << 1; + nextLine += dstPitch << 1; + } + while (--height); +} + void Simple3x16(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height) diff --git a/src/win32/OpenGL.cpp b/src/win32/OpenGL.cpp index 70058095..33d8a65d 100644 --- a/src/win32/OpenGL.cpp +++ b/src/win32/OpenGL.cpp @@ -27,8 +27,10 @@ #include "../Text.h" #include "../Util.h" #include "../gb/gbGlobals.h" +#include "..\memgzio.h" #include +#include "glFont.h" // OpenGL #include // main include file @@ -57,7 +59,7 @@ extern bool detectMMX(); class OpenGLDisplay : public IDisplay { private: HDC hDC; - HGLRC hglrc; + HGLRC hRC; GLuint texture; int width; int height; @@ -65,18 +67,22 @@ private: u8 *filterData; RECT destRect; bool failed; + GLFONT font; void initializeMatrices( int w, int h ); bool initializeTexture( int w, int h ); void updateFiltering( int value ); void setVSync( int interval = 1 ); void calculateDestRect( int w, int h ); + void initializeFont(); public: OpenGLDisplay(); virtual ~OpenGLDisplay(); virtual DISPLAY_TYPE getType() { return OPENGL; }; + virtual void EnableOpenGL(); + virtual void DisableOpenGL(); virtual bool initialize(); virtual void cleanup(); virtual void render(); @@ -88,17 +94,51 @@ public: 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() { hDC = NULL; - hglrc = NULL; + hRC = NULL; texture = 0; width = 0; height = 0; size = 0.0f; - filterData = (u8 *)malloc(4*4*256*240); 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() { if(texture != 0) { glDeleteTextures(1, &texture); texture = 0; } - - if(hglrc != NULL) { - wglDeleteContext(hglrc); - wglMakeCurrent(NULL, NULL); - hglrc = NULL; - } - - if(hDC != NULL) { - ReleaseDC(*theApp.m_pMainWnd, hDC); - hDC = NULL; - } - + DisableOpenGL(); if(filterData) { free(filterData); filterData = NULL; } - width = 0; height = 0; size = 0.0f; @@ -209,7 +269,7 @@ bool OpenGLDisplay::initialize() theApp.dest.right = theApp.surfaceSizeX; theApp.dest.bottom = theApp.surfaceSizeY; - DWORD style = WS_POPUP | WS_VISIBLE; + DWORD style = WS_POPUPWINDOW | WS_VISIBLE; DWORD styleEx = 0; if( theApp.videoOption <= VIDEO_4X ) @@ -253,77 +313,22 @@ bool OpenGLDisplay::initialize() } theApp.updateMenuBar(); - theApp.adjustDestRect(); - theApp.mode320Available = FALSE; theApp.mode640Available = FALSE; theApp.mode800Available = FALSE; + theApp.mode1024Available = FALSE; + theApp.mode1280Available = FALSE; - CDC *dc = pWnd->GetDC(); - HDC hDC = dc->GetSafeHdc(); - - 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 + EnableOpenGL(); + initializeFont(); glPushAttrib( GL_ENABLE_BIT ); glDisable( GL_DEPTH_TEST ); glDisable( GL_CULL_FACE ); glEnable( GL_TEXTURE_2D ); + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + initializeMatrices( theApp.surfaceSizeX, theApp.surfaceSizeY ); @@ -359,6 +364,7 @@ bool OpenGLDisplay::initialize() void OpenGLDisplay::clear() { + glClearColor(0.0,0.0,0.0,1.0); glClear( GL_COLOR_BUFFER_BIT ); } @@ -375,7 +381,8 @@ void OpenGLDisplay::render() { clear(); - int pitch = theApp.filterWidth * 4 + 4; + + int pitch = theApp.filterWidth * (systemColorDepth>>3) + 4; u8 *data = pix + ( theApp.sizeX + 1 ) * 4; // apply pixel filter @@ -386,46 +393,46 @@ void OpenGLDisplay::render() pitch, (u8*)theApp.delta, (u8*)filterData, - theApp.filterWidth * 4 * 2, + width * 4 , theApp.filterWidth, theApp.filterHeight); } // Texturemap complete texture to surface // so we have free scaling and antialiasing - int mult; + if( theApp.filterFunction ) { - glPixelStorei( GL_UNPACK_ROW_LENGTH, theApp.sizeX << 1 ); - mult = 2; + glPixelStorei( GL_UNPACK_ROW_LENGTH, width); } else { glPixelStorei( GL_UNPACK_ROW_LENGTH, theApp.sizeX + 1 ); - mult = 1; } - - glTexSubImage2D( + + glTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, - mult * theApp.sizeX, - mult * theApp.sizeY, + width, + height, GL_RGBA, GL_UNSIGNED_BYTE, data ); + + if( theApp.glType == 0 ) { glBegin( GL_TRIANGLE_STRIP ); glTexCoord2f( 0.0f, 0.0f ); glVertex3i( 0, 0, 0 ); - glTexCoord2f( (float)(mult * theApp.sizeX) / size, 0.0f ); + glTexCoord2f( (float)(width) / size, 0.0f ); glVertex3i( theApp.surfaceSizeX, 0, 0 ); - glTexCoord2f( 0.0f, (float)(mult * theApp.sizeY) / size ); + glTexCoord2f( 0.0f, (float)(height) / size ); 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 ); glEnd(); @@ -435,46 +442,62 @@ void OpenGLDisplay::render() glTexCoord2f( 0.0f, 0.0f ); glVertex3i( 0, 0, 0 ); - glTexCoord2f( (float)(mult * theApp.sizeX) / size, 0.0f ); + glTexCoord2f( (float)(width) / size, 0.0f ); 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 ); - glTexCoord2f( 0.0f, (float)(mult * theApp.sizeY) / size ); + glTexCoord2f( 0.0f, (float)(height) / size ); glVertex3i( 0, theApp.surfaceSizeY, 0 ); 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 - dc->SetBkMode( theApp.showSpeedTransparent ? TRANSPARENT : OPAQUE ); - if( theApp.showSpeed && ( theApp.videoOption > VIDEO_4X ) ) { + if( theApp.showSpeed ) { // && ( theApp.videoOption > VIDEO_4X ) ) { char buffer[30]; if( theApp.showSpeed == 1 ) { sprintf( buffer, "%3d%%", systemSpeed ); } else { sprintf( buffer, "%3d%%(%d, %d fps)", systemSpeed, systemFrameSkip, theApp.showRenderedFrames ); } - dc->SetTextColor( RGB(0x00, 0x00, 0xFF) ); - dc->TextOut( 10, 20, buffer ); + glFontBegin(&font); + 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( ( ( GetTickCount() - theApp.screenMessageTime ) < 3000 ) && !theApp.disableStatusMessage ) { - dc->SetTextColor( RGB(0xFF, 0x00, 0x00) ); - dc->TextOut( 10, theApp.surfaceSizeY - 20, theApp.screenMessageBuffer ); + glFontBegin(&font); + 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 { 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; return false; } + if (filterData) + free(filterData); + filterData = (u8 *)malloc(4*w*h); + } return true; diff --git a/src/win32/VBA.cpp b/src/win32/VBA.cpp index 82d852e3..372fdb35 100644 --- a/src/win32/VBA.cpp +++ b/src/win32/VBA.cpp @@ -145,6 +145,10 @@ int systemRedShift = 0; int systemBlueShift = 0; int systemGreenShift = 0; int systemColorDepth = 16; +int realsystemRedShift = 0; +int realsystemBlueShift = 0; +int realsystemGreenShift = 0; +int realsystemColorDepth = 16; int systemVerbose = 0; int systemDebug = 0; int systemSaveUpdateCounter = SYSTEM_SAVE_NOT_UPDATED; @@ -675,10 +679,10 @@ void VBA::updateFilter() if ( b16to32Video ) { b16to32Video = false; - systemColorDepth = 32; - systemRedShift = 19; - systemGreenShift = 11; - systemBlueShift = 3; + systemColorDepth = realsystemColorDepth; + systemRedShift = realsystemRedShift; + systemGreenShift = realsystemGreenShift; + systemBlueShift = realsystemBlueShift; utilUpdateSystemColorMaps(); } // END hacky ugly code @@ -859,11 +863,15 @@ void VBA::updateFilter() if( display ) display->changeRenderSize(rect.right, rect.bottom); - if (b16to32Video) - { + if (b16to32Video && systemColorDepth!=16) + { + realsystemColorDepth = systemColorDepth; systemColorDepth = 16; + realsystemRedShift = systemRedShift; systemRedShift = 11; + realsystemGreenShift = systemGreenShift; systemGreenShift = 6; + realsystemBlueShift = systemBlueShift; systemBlueShift = 0; utilUpdateSystemColorMaps(); } diff --git a/src/win32/glfont.c b/src/win32/glfont.c new file mode 100644 index 00000000..3220ec41 --- /dev/null +++ b/src/win32/glfont.c @@ -0,0 +1,154 @@ +//********************************************************* +//GLFONT.CPP -- glFont routines +//Copyright (c) 1998 Brad Fish +//See glFont.txt for terms of use +//November 10, 1998 +//********************************************************* + +#include +#include +#include +#include +#include +#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 + + + diff --git a/src/win32/glfont.h b/src/win32/glfont.h new file mode 100644 index 00000000..21df1f30 --- /dev/null +++ b/src/win32/glfont.h @@ -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 + diff --git a/src/win32/gzglfont.h b/src/win32/gzglfont.h new file mode 100644 index 00000000..618065f6 --- /dev/null +++ b/src/win32/gzglfont.h @@ -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' + }; \ No newline at end of file