mirror of
https://github.com/UberGames/MD3View.git
synced 2024-11-09 23:01:57 +00:00
332 lines
8.9 KiB
C++
Executable file
332 lines
8.9 KiB
C++
Executable file
/*
|
|
Copyright (C) 2010 Matthew Baranowski, Sander van Rossen & Raven software.
|
|
|
|
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 3 of the License, 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, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
// Some useful text display routines for text within OpenGL window panes..
|
|
//
|
|
// Uses charset from Beeb micro
|
|
//
|
|
#include "system.h"
|
|
#include "ndictionary.h" // needed so I can include "md3view.h"
|
|
#include "md3gl.h"
|
|
#include "DiskIO.h"
|
|
#include "md3view.h" // needed so I can access mdview struct
|
|
#include "text.h"
|
|
|
|
int g_iScreenWidth = 0;
|
|
int g_iScreenHeight = 0;
|
|
|
|
bool gbTextInhibit = false;
|
|
|
|
|
|
// internal protos...
|
|
//
|
|
void Text_EnsureCreated(void);
|
|
|
|
|
|
BYTE byChars[]=
|
|
{
|
|
0,0,0,0,0,0,0,0
|
|
,24,24,24,24,24,0,24,0
|
|
,108,108,108,0,0,0,0,0
|
|
,108,108,-2,108,-2,108,108,0
|
|
,12,63,104,62,11,126,24,0
|
|
,96,102,12,24,48,102,6,0
|
|
,56,108,108,56,109,102,59,0
|
|
,12,24,48,0,0,0,0,0
|
|
,12,24,48,48,48,24,12,0
|
|
,48,24,12,12,12,24,48,0
|
|
,0,24,126,60,126,24,0,0
|
|
,0,24,24,126,24,24,0,0
|
|
,0,0,0,0,0,12,12,48
|
|
,0,0,0,126,0,0,0,0
|
|
,0,0,0,0,0,0,24,24
|
|
,0,6,12,24,48,96,0,0
|
|
,60,102,110,126,118,102,60,0
|
|
,24,56,24,24,24,24,126,0
|
|
,60,102,6,12,24,48,126,0
|
|
,60,102,6,28,6,102,60,0
|
|
,12,28,60,108,126,12,12,0
|
|
,126,96,124,6,6,102,60,0
|
|
,28,48,96,124,102,102,60,0
|
|
,126,6,12,24,48,48,48,0
|
|
,60,102,102,60,102,102,60,0
|
|
,60,102,102,62,6,12,56,0
|
|
,0,0,24,24,0,24,24,0
|
|
,0,0,24,24,0,24,24,48
|
|
,12,24,48,96,48,24,12,0
|
|
,0,0,126,0,126,0,0,0
|
|
,48,24,12,6,12,24,48,0
|
|
,60,102,12,24,24,0,24,0
|
|
,60,102,110,106,110,96,60,0
|
|
,60,102,102,126,102,102,102,0
|
|
,124,102,102,124,102,102,124,0
|
|
,60,102,96,96,96,102,60,0
|
|
,120,108,102,102,102,108,120,0
|
|
,126,96,96,124,96,96,126,0
|
|
,126,96,96,124,96,96,96,0
|
|
,60,102,96,110,102,102,60,0
|
|
,102,102,102,126,102,102,102,0
|
|
,126,24,24,24,24,24,126,0
|
|
,62,12,12,12,12,108,56,0
|
|
,102,108,120,112,120,108,102,0
|
|
,96,96,96,96,96,96,126,0
|
|
,99,119,127,107,107,99,99,0
|
|
,102,102,118,126,110,102,102,0
|
|
,60,102,102,102,102,102,60,0
|
|
,124,102,102,124,96,96,96,0
|
|
,60,102,102,102,106,108,54,0
|
|
,124,102,102,124,108,102,102,0
|
|
,60,102,96,60,6,102,60,0
|
|
,126,24,24,24,24,24,24,0
|
|
,102,102,102,102,102,102,60,0
|
|
,102,102,102,102,102,60,24,0
|
|
,99,99,107,107,127,119,99,0
|
|
,102,102,60,24,60,102,102,0
|
|
,102,102,102,60,24,24,24,0
|
|
,126,6,12,24,48,96,126,0
|
|
,124,96,96,96,96,96,124,0
|
|
,0,96,48,24,12,6,0,0
|
|
,62,6,6,6,6,6,62,0
|
|
,24,60,102,66,0,0,0,0
|
|
,0,0,0,0,0,0,0,-1
|
|
,28,54,48,124,48,48,126,0
|
|
,0,0,60,6,62,102,62,0
|
|
,96,96,124,102,102,102,124,0
|
|
,0,0,60,102,96,102,60,0
|
|
,6,6,6,62,102,102,62,0
|
|
,0,0,60,102,126,96,60,0
|
|
,28,48,48,124,48,48,48,0
|
|
,0,0,62,102,102,62,6,60
|
|
,96,96,124,102,102,102,102,0
|
|
,24,0,56,24,24,24,60,0
|
|
,24,0,56,24,24,24,24,112
|
|
,96,96,102,108,120,108,102,0
|
|
,56,24,24,24,24,24,60,0
|
|
,0,0,54,127,107,99,99,0
|
|
,0,0,124,102,102,102,102,0
|
|
,0,0,60,102,102,102,60,0
|
|
,0,0,124,102,102,124,96,96
|
|
,0,0,62,102,102,62,6,7
|
|
,0,0,108,118,96,96,96,0
|
|
,0,0,62,96,60,6,124,0
|
|
,48,48,124,48,48,48,28,0
|
|
,0,0,102,102,102,102,62,0
|
|
,0,0,102,102,102,60,24,0
|
|
,0,0,99,99,107,127,54,0
|
|
,0,0,102,60,24,60,102,0
|
|
,0,0,102,102,102,62,6,60
|
|
,0,0,126,12,24,48,126,0
|
|
,12,24,24,112,24,24,12,0
|
|
,24,24,24,0,24,24,24,0
|
|
,48,24,24,14,24,24,48,0
|
|
,49,107,70,0,0,0,0,0
|
|
,126,195,219,211,211,219,195,126
|
|
};
|
|
|
|
GLuint gFontOffset;
|
|
BOOL bTextCreated=FALSE;
|
|
#define TOTALFONTENTRIES 128 // enough for all 7-bit ascii range
|
|
|
|
// This should be called once at program start, but only after OpenGL is up and running (and in context)...
|
|
//
|
|
// (Actually it's now called every time you print a string, but the bool check protects it)
|
|
//
|
|
void Text_EnsureCreated(void)
|
|
{
|
|
static bool bFlipped = FALSE;
|
|
|
|
if (!bTextCreated)
|
|
{
|
|
if (!bFlipped)
|
|
{
|
|
// first stage is to flip all the char defs top to bottom to match OpenGL format...
|
|
//
|
|
for (int i=0; i<sizeof(byChars); i+=TEXT_DEPTH)
|
|
{
|
|
// each char...
|
|
//
|
|
for (int j=0; j<4; j++)
|
|
{
|
|
byte b = byChars[i+j];
|
|
byChars[i+j] = byChars[i+(7-j)];
|
|
byChars[i+(7-j)] = b;
|
|
}// for (int j=0; j<4; j++)
|
|
}// for (int i=0; i<sizeof(byChars); i+=TEXT_DEPTH)
|
|
bFlipped = TRUE;
|
|
}// if (!bFlipped)
|
|
|
|
// make a raster Font for OpenGL...
|
|
//
|
|
glPixelStorei(GL_UNPACK_ALIGNMENT,1);
|
|
// gFontOffset = TEXT_CALLLIST;
|
|
gFontOffset = glGenLists(TOTALFONTENTRIES);
|
|
|
|
|
|
for (int i=0; i<sizeof(byChars)/TEXT_DEPTH; i++)
|
|
{
|
|
glNewList(gFontOffset + ' '+i,GL_COMPILE);
|
|
glBitmap(TEXT_WIDTH, TEXT_DEPTH,0.0,0.0,TEXT_WIDTH,0.0,&byChars[i*TEXT_DEPTH]);
|
|
glEndList();
|
|
}
|
|
bTextCreated=TRUE;
|
|
}// if (!bTextCreated)
|
|
|
|
}// void Text_EnsureCreated(void)
|
|
|
|
|
|
|
|
|
|
// Called at end of program from scModels_Destroy() since this program doesn't appear to have
|
|
// much in the way of begin/end points to attach things to...
|
|
//
|
|
// OpenGL should still be active at this point for giving back lists, but if it isn't then I suspect
|
|
// it doesn't matter 100% since we'll be dropping back to Windows anyway which will (hopefully) free up everything.
|
|
//
|
|
void Text_Destroy(void)
|
|
{
|
|
if (bTextCreated)
|
|
{
|
|
glDeleteLists(gFontOffset,TOTALFONTENTRIES);
|
|
bTextCreated = FALSE;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Displays a text string at a 3d world point...
|
|
//
|
|
void Text_Display(LPCSTR psString, Vec3 v3DPos, byte r, byte g, byte b)
|
|
{
|
|
if (!gbTextInhibit)
|
|
{
|
|
// it appears I have to do this in MD3View or paint messages keep getting back here even after SysOnDestroy()...
|
|
//
|
|
if (!mdview.done)
|
|
{
|
|
int iStrlen = strlen(psString);
|
|
|
|
Text_EnsureCreated();
|
|
|
|
if (iStrlen)
|
|
{
|
|
glPushAttrib(GL_LIGHTING_BIT | GL_LIST_BIT | GL_ENABLE_BIT);
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glColor3ub(r,g,b);
|
|
glRasterPos3f(v3DPos[0],v3DPos[1],v3DPos[2]);
|
|
glListBase(gFontOffset);
|
|
glCallLists(iStrlen,GL_UNSIGNED_BYTE,(GLubyte *) psString);
|
|
glPopAttrib();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Displays text at a 2d screen coord. 0,0 is top left corner, add TEXT_DEPTH per Y to go down a line
|
|
//
|
|
// Note new param 'bResizeStringIfNecessary', this is so that if a string goes off the left hand edge of the window
|
|
// it will now (instead of just not printing the entire string like OpenGL would normally do) move the print pos up
|
|
// a char each time until it fits. It may take more time to do so only set the bool true if really needed.
|
|
//
|
|
// return value is a convenient xpos for next xpos along after this strlen...
|
|
//
|
|
int Text_DisplayFlat(LPCSTR psString, int x, int y, byte r, byte g, byte b, bool bResizeStringIfNecessary /* = false */)
|
|
{
|
|
int iRetVal = x;
|
|
|
|
if (!gbTextInhibit) // this will also mean the non-existant cursor isn't moved on by the retval, but that shouldn't matter under this circumstance
|
|
{
|
|
// it appears I have to do this in MD3View or paint messages keep getting back here even after SysOnDestroy()...
|
|
//
|
|
if (!mdview.done)
|
|
{
|
|
int iStrlen = strlen(psString);
|
|
GLboolean bRasterValid;
|
|
|
|
Text_EnsureCreated();
|
|
|
|
// (source indenting only to help with gl stack status)
|
|
|
|
if (iStrlen)
|
|
{
|
|
glPushAttrib(GL_LIGHTING_BIT | GL_LIST_BIT | GL_TRANSFORM_BIT | GL_ENABLE_BIT);
|
|
{
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPushMatrix();
|
|
{
|
|
glLoadIdentity();
|
|
|
|
gluOrtho2D(0.0,(GLfloat) g_iScreenWidth, 0.0, (GLfloat) g_iScreenHeight);
|
|
glMatrixMode(GL_MODELVIEW);
|
|
glPushMatrix();
|
|
{
|
|
glLoadIdentity();
|
|
|
|
glDisable(GL_TEXTURE_2D);
|
|
glDisable(GL_LIGHTING);
|
|
|
|
glColor3ub(r,g,b);
|
|
// glRasterPos2i(x,y); // from bottom left
|
|
|
|
// pre-dec to counter pre-inc coming up...
|
|
//
|
|
x-=TEXT_WIDTH;
|
|
iStrlen+=1;
|
|
psString--;
|
|
|
|
do
|
|
{
|
|
x+=TEXT_WIDTH;
|
|
iStrlen-=1;
|
|
psString++;
|
|
//
|
|
glRasterPos2i(x,(g_iScreenHeight-y)-TEXT_DEPTH);
|
|
glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID,&bRasterValid);
|
|
}
|
|
while ( bResizeStringIfNecessary && !bRasterValid && iStrlen);
|
|
|
|
if (iStrlen) // because it may have all been clipped off the left
|
|
{
|
|
glListBase(gFontOffset);
|
|
glCallLists(iStrlen,GL_UNSIGNED_BYTE,(GLubyte *) psString);
|
|
iRetVal += iStrlen*TEXT_WIDTH;
|
|
}
|
|
}
|
|
glPopMatrix(); // GL_MODELVIEW
|
|
}
|
|
glMatrixMode(GL_PROJECTION);
|
|
glPopMatrix();
|
|
//
|
|
}
|
|
glPopAttrib();
|
|
}
|
|
}
|
|
}
|
|
|
|
return iRetVal;
|
|
}
|
|
|
|
|
|
////////////////////////////// eof /////////////////////////////////
|
|
|