1933 lines
52 KiB
C
1933 lines
52 KiB
C
/*
|
|
** Insert new header here
|
|
**
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdarg.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <assert.h>
|
|
#include <time.h>
|
|
#include <math.h>
|
|
|
|
#include <glide.h>
|
|
|
|
#ifdef __MWERKS__
|
|
#include <sioux.h>
|
|
#endif
|
|
|
|
#ifdef __DJGPP__
|
|
#include <crt0.h>
|
|
int crt0_startup_flags = _CRT0_FLAG_NONMOVE_SBRK;
|
|
#endif
|
|
|
|
#include "tlib.h"
|
|
|
|
static FxBool okToRender = FXTRUE;
|
|
static FxBool fullScreen = FXTRUE;
|
|
static void *state = NULL;
|
|
static void *vlstate = NULL;
|
|
|
|
FxBool
|
|
tlOkToRender()
|
|
{
|
|
return okToRender;
|
|
} /* tlOkToRender */
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function:tlGetOpt
|
|
Date: 2/26
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Incrementally search an argument list for matches.
|
|
Arguments:
|
|
argc - first argument to main
|
|
argv - second argument to main
|
|
tags - string of non-whitespace characters to be search for in the
|
|
argument string
|
|
match - pointer to storage for matched character
|
|
remArgs - pointer to storage for remaining arglist after any match
|
|
Return:
|
|
1 if matched
|
|
0 if no more arguments
|
|
-1 if unrecognized
|
|
-------------------------------------------------------------------*/
|
|
int tlGetOpt( int argc, char *argv[],
|
|
const char *tags, char *match,
|
|
char **remArgs[] ){
|
|
static int firstCall;
|
|
static int lastArg;
|
|
|
|
int rv = 0;
|
|
|
|
if ( !firstCall ) {
|
|
lastArg = 1;
|
|
firstCall = 1;
|
|
|
|
|
|
#if __MWERKS__
|
|
SIOUXSettings.standalone = true;
|
|
SIOUXSettings.setupmenus = false;
|
|
SIOUXSettings.autocloseonquit = true;
|
|
SIOUXSettings.asktosaveonclose = false;
|
|
#endif
|
|
}
|
|
|
|
while( (lastArg<argc) && (*argv[lastArg] != '-') ) lastArg++;
|
|
|
|
if ( lastArg < argc ) {
|
|
unsigned tag;
|
|
for( tag = 0; tag < strlen( tags ); tag++ ) {
|
|
if ( *(argv[lastArg]+1) == tags[tag] ) {
|
|
*match = tags[tag];
|
|
*remArgs = &argv[++lastArg];
|
|
rv = 2;
|
|
break;
|
|
}
|
|
}
|
|
rv--;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlGetResolution
|
|
Date: 2/25
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Get the integer representing the provided resolution and return the
|
|
necessary floats for screen scaling.
|
|
Arguments:
|
|
identifier - string identifying resolution of the form XRSxYRS
|
|
width - pointer to float storage for width
|
|
height - pointer to float storage for height
|
|
Return:
|
|
int
|
|
-------------------------------------------------------------------*/
|
|
|
|
typedef struct {
|
|
const char *id;
|
|
int res;
|
|
float width;
|
|
float height;
|
|
} ResToRes;
|
|
|
|
static ResToRes resTable[] = {
|
|
{ "320x200", GR_RESOLUTION_320x200, 320.0f, 200.0f }, /* 0x0 */
|
|
{ "320x240", GR_RESOLUTION_320x240, 320.0f, 240.0f }, /* 0x1 */
|
|
{ "400x256", GR_RESOLUTION_400x256, 400.0f, 256.0f }, /* 0x2 */
|
|
{ "512x384", GR_RESOLUTION_512x384, 512.0f, 384.0f }, /* 0x3 */
|
|
{ "640x200", GR_RESOLUTION_640x200, 640.0f, 200.0f }, /* 0x4 */
|
|
{ "640x350", GR_RESOLUTION_640x350, 640.0f, 350.0f }, /* 0x5 */
|
|
{ "640x400", GR_RESOLUTION_640x400, 640.0f, 400.0f }, /* 0x6 */
|
|
{ "640x480", GR_RESOLUTION_640x480, 640.0f, 480.0f }, /* 0x7 */
|
|
{ "800x600", GR_RESOLUTION_800x600, 800.0f, 600.0f }, /* 0x8 */
|
|
{ "960x720", GR_RESOLUTION_960x720, 960.0f, 720.0f }, /* 0x9 */
|
|
{ "856x480", GR_RESOLUTION_856x480, 856.0f, 480.0f }, /* 0xA */
|
|
{ "512x256", GR_RESOLUTION_512x256, 512.0f, 256.0f }, /* 0xB */
|
|
{ "1024x768", GR_RESOLUTION_1024x768, 1024.0f, 768.0f }, /* 0xC */
|
|
{ "1280x1024", GR_RESOLUTION_1280x1024, 1280.0f, 1024.0f }, /* 0xD */
|
|
{ "1600x1200", GR_RESOLUTION_1600x1200, 1600.0f, 1200.0f }, /* 0xE */
|
|
{ "400x300", GR_RESOLUTION_400x300, 400.0f, 300.0f } /* 0xF */
|
|
};
|
|
|
|
static long resTableSize = sizeof( resTable ) / sizeof( ResToRes );
|
|
|
|
void
|
|
tlGetDimsByConst(const int resConst, float *w, float *h)
|
|
{
|
|
int match;
|
|
|
|
for( match = 0; match < resTableSize; match++ ) {
|
|
if ( resTable[match].res == resConst ){
|
|
*w = resTable[match].width;
|
|
*h = resTable[match].height;
|
|
return;
|
|
}
|
|
}
|
|
#ifdef __WIN32__
|
|
{
|
|
extern void getWindowSize(float *width, float *height);
|
|
getWindowSize(w, h);
|
|
}
|
|
#endif
|
|
} /* tlGetDimsByConst */
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlGetReslutionConstant
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Returns the glide constant for a command line resolution argument
|
|
Arguments:
|
|
identifier - command line resolution arg.
|
|
width - storage for floating point screen width
|
|
height - storaget for floating piont screen height
|
|
Return:
|
|
GrResolution_t matching resolution argument
|
|
-------------------------------------------------------------------*/
|
|
static int Res = GR_RESOLUTION_640x480;
|
|
int
|
|
tlGetResolutionConstant( const char *identifier, float *width,
|
|
float *height )
|
|
{
|
|
int match;
|
|
|
|
for( match = 0; match < resTableSize; match++ ) {
|
|
if ( !strcmp( identifier, resTable[match].id ) ) {
|
|
Res = resTable[match].res;
|
|
*width = resTable[match].width;
|
|
*height = resTable[match].height;
|
|
fullScreen = FXTRUE;
|
|
return Res;
|
|
}
|
|
}
|
|
#ifdef __WIN32__
|
|
{
|
|
extern void getWindowSize(float *width, float *height);
|
|
|
|
fullScreen = FXFALSE;
|
|
getWindowSize(width, height);
|
|
}
|
|
#endif
|
|
return Res = GR_RESOLUTION_NONE;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlGetResolutionString
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: Test LIbrary
|
|
Description:
|
|
Returns a string value for a given resolution constant
|
|
Arguments:
|
|
res - resolution constant
|
|
Return:
|
|
string representing resolution
|
|
-------------------------------------------------------------------*/
|
|
const char *tlGetResolutionString( int res ) {
|
|
int match;
|
|
const char *str = "unknown";
|
|
|
|
for( match = 0; match < resTableSize; match++ ) {
|
|
if ( resTable[match].res == res ) {
|
|
str = resTable[match].id;
|
|
break;
|
|
}
|
|
}
|
|
return str;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlGetResolutionList
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: TestLibrary
|
|
Description:
|
|
Return a list of all supported resolutions
|
|
Arguments:
|
|
none
|
|
Return:
|
|
const char * to resolution list
|
|
-------------------------------------------------------------------*/
|
|
const char *tlGetResolutionList( void ) {
|
|
char *list = calloc( sizeof( char ), 256 );
|
|
int member;
|
|
strcat( list, resTable[0].id );
|
|
for( member = 1; member < resTableSize; member++ ) {
|
|
strcat( list, " | " );
|
|
strcat( list, resTable[member].id );
|
|
}
|
|
return list;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlVertexLayout
|
|
Date: 1/26/98
|
|
Implementor(s): atai
|
|
Library: Test Library
|
|
Description:
|
|
Set up default tlVertexLayout
|
|
Arguments:
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlVertexLayout( void ) {
|
|
grVertexLayout(GR_PARAM_XY, GR_VERTEX_X_OFFSET << 2, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_RGB, GR_VERTEX_R_OFFSET << 2, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_A, GR_VERTEX_A_OFFSET << 2, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_Z, GR_VERTEX_OOZ_OFFSET << 2, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_Q0, GR_VERTEX_OOW_TMU0_OFFSET << 2, GR_PARAM_DISABLE);
|
|
grVertexLayout(GR_PARAM_ST1, GR_VERTEX_SOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE);
|
|
grVertexLayout(GR_PARAM_Q1, GR_VERTEX_OOW_TMU1_OFFSET << 2, GR_PARAM_DISABLE);
|
|
return;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlVoodooType
|
|
Date: 6/02/98
|
|
Implementor(s): atai
|
|
Library: Test Library
|
|
Description:
|
|
return platform type
|
|
Arguments:
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
int tlVoodooType( void ) {
|
|
const char *vstr;
|
|
int vtype = TL_VOODOO_UNDEF;
|
|
|
|
vstr = grGetString(GR_HARDWARE);
|
|
if (!strcmp(vstr, "Voodoo2"))
|
|
vtype = TL_VOODOO2;
|
|
else if (!strcmp(vstr, "Voodoo Banshee"))
|
|
vtype = TL_VOODOOBANSHEE;
|
|
else if (!strcmp(vstr, "Voodoo Graphics"))
|
|
vtype = TL_VOODOO;
|
|
else if (!strcmp(vstr, "Voodoo Rush"))
|
|
vtype = TL_VOODOORUSH;
|
|
return vtype;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlSetScreen
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Set up screen scaling
|
|
Arguments:
|
|
width - width of screen
|
|
height - height of screen
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
static float scrXScale;
|
|
static float scrYScale;
|
|
|
|
void tlSetScreen( float width, float height ) {
|
|
scrXScale = width;
|
|
scrYScale = height;
|
|
return;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlScaleX
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: Test Lib
|
|
Description:
|
|
Scale X coordinates from normalized device coordinates [ 0.0, 1.0 )
|
|
to Screen Coordinates [ 0.0, WidthOfScreenInPixels )
|
|
Arguments:
|
|
coord - x coordinate to scale
|
|
Return:
|
|
scaled x coordinate
|
|
-------------------------------------------------------------------*/
|
|
float tlScaleX( float coord ) {
|
|
return coord * scrXScale;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlScaleY
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: Test Lib
|
|
Description:
|
|
Scale Y coordinates from normalized device coordinates [ 0.0, 1.0 )
|
|
to Screen Coordinates [ 0.0, HeightOfScreenInPixels )
|
|
Arguments:
|
|
coord - y coordinate to scale
|
|
Return:
|
|
scaled y coordinate
|
|
-------------------------------------------------------------------*/
|
|
float tlScaleY( float coord ) {
|
|
return coord *scrYScale;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlSetConsole
|
|
Date:
|
|
Implementor(s):
|
|
Library:
|
|
Description:
|
|
Arguments:
|
|
Return:
|
|
-------------------------------------------------------------------*/
|
|
static unsigned char fontTable[128][2];
|
|
static GrTexInfo fontInfo;
|
|
static unsigned long fontAddress;
|
|
static const char fontString[] = "ABCDEFGHIJKLMN"
|
|
"OPQRSTUVWXYZ01"
|
|
"23456789.,;:*-"
|
|
"+/_()<>|[]{}! ";
|
|
|
|
static const int fontWidth = 9*2;
|
|
static const int fontHeight = 12*2;
|
|
static const int charsPerLine = 14;
|
|
|
|
static int fontInitialized;
|
|
|
|
#if 0 /* not used */
|
|
static void grabTex( FxU32 addr, void *storage );
|
|
static void putTex( FxU32 addr, void *storage );
|
|
#endif
|
|
static void consoleScroll( void );
|
|
static void drawChar( char character, float x, float y, float w, float h );
|
|
|
|
#include "tldata.inc"
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlSetConsole
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Initialize Console for printing. The console will scroll text
|
|
60 column text in the window described by minx, miny, maxx, maxy.
|
|
Arguments:
|
|
minX, minY - upper left corner of console
|
|
maxX, maxY - lower right corner of console
|
|
rows - rows of text to display
|
|
columns - columns to display before scroll
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
static char *consoleGrid;
|
|
static int consoleRows;
|
|
static int consoleColumns;
|
|
static int consoleX;
|
|
static int consoleY;
|
|
static int consoleColor;
|
|
static float consoleOriginX;
|
|
static float consoleOriginY;
|
|
static float consoleCharWidth;
|
|
static float consoleCharHeight;
|
|
|
|
void tlConSet( float minX, float minY,
|
|
float maxX, float maxY,
|
|
int columns, int rows,
|
|
int color ) {
|
|
int entry;
|
|
char xCoord;
|
|
char yCoord;
|
|
|
|
if (state == NULL) {
|
|
FxI32 state_size;
|
|
grGet(GR_GLIDE_STATE_SIZE, 4, &state_size);
|
|
state = malloc(state_size);
|
|
}
|
|
if (vlstate == NULL) {
|
|
FxI32 state_size;
|
|
grGet(GR_GLIDE_VERTEXLAYOUT_SIZE, 4, &state_size);
|
|
vlstate = malloc(state_size);
|
|
}
|
|
|
|
fontInfo.smallLodLog2 = GR_LOD_LOG2_128;
|
|
fontInfo.largeLodLog2 = GR_LOD_LOG2_128;
|
|
fontInfo.aspectRatioLog2 = GR_ASPECT_LOG2_2x1;
|
|
fontInfo.format = GR_TEXFMT_ALPHA_8;
|
|
fontInfo.data = &fontData[0];
|
|
|
|
if ( getenv( "FX_GLIDE_NO_FONT" ) ) {
|
|
fontInitialized = 0;
|
|
return;
|
|
}
|
|
|
|
for( entry = 1; entry < 128; entry++ ) {
|
|
char *hit = strchr( fontString, entry );
|
|
if ( hit ) {
|
|
int offset = hit - fontString;
|
|
|
|
xCoord = ( offset % charsPerLine ) * fontWidth;
|
|
yCoord = ( offset / charsPerLine ) * fontHeight;
|
|
|
|
fontTable[entry][0] = xCoord;
|
|
fontTable[entry][1] = yCoord;
|
|
}
|
|
}
|
|
|
|
if ( consoleGrid ) free( consoleGrid );
|
|
|
|
consoleGrid = calloc( sizeof( char ), rows * columns );
|
|
memset( consoleGrid, 32, rows*columns );
|
|
consoleRows = rows;
|
|
consoleColumns = columns;
|
|
consoleX = consoleY = 0;
|
|
|
|
consoleColor = color;
|
|
consoleOriginX = minX;
|
|
consoleOriginY = minY;
|
|
consoleCharWidth = ( (maxX - minX)/(float)columns );
|
|
consoleCharHeight = ( (maxY - minY)/(float)rows );
|
|
|
|
fontAddress = grTexMaxAddress( 0 ) -
|
|
grTexCalcMemRequired( fontInfo.smallLodLog2, fontInfo.largeLodLog2,
|
|
fontInfo.aspectRatioLog2, fontInfo.format );
|
|
|
|
fontInitialized = 1;
|
|
|
|
return;
|
|
};
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlConOutput
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Output a printf style string to the console
|
|
Arguments:
|
|
fmt - format string
|
|
... - other args
|
|
Return:
|
|
int - number of chars printed
|
|
-------------------------------------------------------------------*/
|
|
int tlConOutput( const char *fmt, ... ) {
|
|
int rv = 0;
|
|
va_list argptr;
|
|
|
|
if( fontInitialized ) {
|
|
static char buffer[1024];
|
|
const char *c;
|
|
char* temp;
|
|
|
|
va_start( argptr, fmt );
|
|
rv = vsprintf( buffer, fmt, argptr );
|
|
va_end( argptr );
|
|
|
|
temp = buffer;
|
|
while(*temp != '\0') {
|
|
if (*temp >= 'a' && *temp <= 'z')
|
|
*temp -= ('a'-'A');
|
|
temp++;
|
|
}
|
|
|
|
c = buffer;
|
|
|
|
/* update console grid */
|
|
|
|
while( *c ) {
|
|
switch( *c ) {
|
|
case '\n':
|
|
consoleY++;
|
|
case '\r':
|
|
consoleX = 0;
|
|
if ( consoleY >= consoleRows ) {
|
|
consoleY = consoleRows - 1;
|
|
consoleScroll();
|
|
}
|
|
break;
|
|
default:
|
|
if ( consoleX >= consoleColumns ) {
|
|
consoleX = 0;
|
|
consoleY++;
|
|
if ( consoleY >= consoleRows ) {
|
|
consoleY = consoleRows - 1;
|
|
consoleScroll();
|
|
}
|
|
}
|
|
consoleGrid[(consoleY*consoleColumns)+consoleX]=*c;
|
|
consoleX++;
|
|
break;
|
|
}
|
|
c++;
|
|
}
|
|
}
|
|
|
|
return rv;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlConClear
|
|
Date: 3/1
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Clear the console
|
|
Arguments:
|
|
none
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlConClear() {
|
|
memset( consoleGrid, 32, consoleRows*consoleColumns );
|
|
consoleX = consoleY = 0;
|
|
return;
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlConRender
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: test library
|
|
Description:
|
|
Render the console
|
|
Arguments:
|
|
none
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlConRender( void ) {
|
|
if( fontInitialized ) {
|
|
int x, y;
|
|
|
|
grGlideGetState( state );
|
|
grGlideGetVertexLayout( vlstate );
|
|
|
|
grVertexLayout(GR_PARAM_XY, 0, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_Q, GR_VERTEX_OOW_OFFSET << 2, GR_PARAM_ENABLE);
|
|
grVertexLayout(GR_PARAM_ST0, GR_VERTEX_SOW_TMU0_OFFSET << 2, GR_PARAM_ENABLE);
|
|
|
|
grCoordinateSpace(GR_WINDOW_COORDS);
|
|
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
|
|
GR_COMBINE_FACTOR_LOCAL,
|
|
GR_COMBINE_LOCAL_CONSTANT,
|
|
GR_COMBINE_OTHER_TEXTURE,
|
|
FXFALSE );
|
|
grAlphaCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
|
|
GR_COMBINE_FACTOR_ONE,
|
|
GR_COMBINE_LOCAL_NONE,
|
|
GR_COMBINE_OTHER_TEXTURE,
|
|
FXFALSE );
|
|
grTexCombine( GR_TMU0,
|
|
GR_COMBINE_FUNCTION_LOCAL,
|
|
GR_COMBINE_FACTOR_NONE,
|
|
GR_COMBINE_FUNCTION_LOCAL,
|
|
GR_COMBINE_FACTOR_NONE,
|
|
FXFALSE,
|
|
FXFALSE );
|
|
grAlphaBlendFunction( GR_BLEND_SRC_ALPHA, GR_BLEND_ONE_MINUS_SRC_ALPHA,
|
|
GR_BLEND_ONE, GR_BLEND_ZERO );
|
|
grAlphaTestFunction( GR_CMP_ALWAYS );
|
|
grTexFilterMode( GR_TMU0,
|
|
GR_TEXTUREFILTER_BILINEAR,
|
|
GR_TEXTUREFILTER_BILINEAR );
|
|
grTexMipMapMode( GR_TMU0,
|
|
GR_MIPMAP_DISABLE,
|
|
FXFALSE );
|
|
grTexMultibase(GR_TMU0, FXFALSE);
|
|
grDepthBufferFunction( GR_CMP_ALWAYS );
|
|
grAlphaTestReferenceValue( 0x1 );
|
|
grSstOrigin( GR_ORIGIN_UPPER_LEFT );
|
|
grCullMode( GR_CULL_DISABLE );
|
|
grTexDownloadMipMap( 0, fontAddress, GR_MIPMAPLEVELMASK_BOTH,
|
|
&fontInfo );
|
|
grTexSource( 0, fontAddress,
|
|
GR_MIPMAPLEVELMASK_BOTH, &fontInfo );
|
|
grClipWindow( (int)tlScaleX(0.0f),(int)tlScaleY(0.0f),
|
|
(int)tlScaleX(1.0f),(int)tlScaleY(1.0f) );
|
|
|
|
for( y = 0; y < consoleRows; y++ ) {
|
|
float charX = consoleOriginX;
|
|
float charY = consoleOriginY+(consoleCharHeight*y);
|
|
for( x = 0; x < consoleColumns; x++ ) {
|
|
drawChar( consoleGrid[(y*consoleColumns)+x],
|
|
charX, charY,
|
|
consoleCharWidth,
|
|
consoleCharHeight );
|
|
charX += consoleCharWidth;
|
|
}
|
|
}
|
|
|
|
grGlideSetState(state);
|
|
grGlideSetVertexLayout( vlstate );
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlSleep
|
|
Date: 3/1
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Block for a number of seconds
|
|
Arguments:
|
|
seconds - number of seconds before function returns
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlSleep( int seconds ) {
|
|
time_t time0 = time( 0 );
|
|
while( (time(0)-time0) < seconds );
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlIdentity
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Return an identity matrix
|
|
Arguments:
|
|
none
|
|
Return:
|
|
const pointer to identity matrix
|
|
-------------------------------------------------------------------*/
|
|
static TlMatrix currentMatrix;
|
|
|
|
#define DEGREE (.01745328f)
|
|
|
|
const float *tlIdentity( void ) {
|
|
static TlMatrix m;
|
|
m[0][0] = 1.0f, m[0][1] = 0.0f, m[0][2] = 0.0f, m[0][3] = 0.0f;
|
|
m[1][0] = 0.0f, m[1][1] = 1.0f, m[1][2] = 0.0f, m[1][3] = 0.0f;
|
|
m[2][0] = 0.0f, m[2][1] = 0.0f, m[2][2] = 1.0f, m[2][3] = 0.0f;
|
|
m[3][0] = 0.0f, m[3][1] = 0.0f, m[3][2] = 0.0f, m[3][3] = 1.0f;
|
|
return &m[0][0];
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlXRotation
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Generate a rotation about the x axis
|
|
Arguments:
|
|
degrees - number of degrees to rotate
|
|
Return:
|
|
const point to rotation matrix
|
|
-------------------------------------------------------------------*/
|
|
const float *tlXRotation( float degrees ) {
|
|
static TlMatrix m;
|
|
float c = (float)cos( degrees * DEGREE );
|
|
float s = (float)sin( degrees * DEGREE );
|
|
m[0][0] = 1.0f, m[0][1] = 0.0f, m[0][2] = 0.0f, m[0][3] = 0.0f;
|
|
m[1][0] = 0.0f, m[1][1] = c, m[1][2] = s, m[1][3] = 0.0f;
|
|
m[2][0] = 0.0f, m[2][1] = -s, m[2][2] = c, m[2][3] = 0.0f;
|
|
m[3][0] = 0.0f, m[3][1] = 0.0f, m[3][2] = 0.0f, m[3][3] = 1.0f;
|
|
return &m[0][0];
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlYRotation
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Generate a rotation about the y axis
|
|
Arguments:
|
|
degrees - number of degrees to rotate
|
|
Return:
|
|
const point to rotation matrix
|
|
-------------------------------------------------------------------*/
|
|
const float *tlYRotation( float degrees ) {
|
|
static TlMatrix m;
|
|
float c = (float)cos( degrees * DEGREE );
|
|
float s = (float)sin( degrees * DEGREE );
|
|
m[0][0] = c, m[0][1] = 0.0f, m[0][2] = -s, m[0][3] = 0.0f;
|
|
m[1][0] = 0.0f, m[1][1] = 1.0f, m[1][2] = 0.0f, m[1][3] = 0.0f;
|
|
m[2][0] = s, m[2][1] = 0.0f, m[2][2] = c, m[2][3] = 0.0f;
|
|
m[3][0] = 0.0f, m[3][1] = 0.0f, m[3][2] = 0.0f, m[3][3] = 1.0f;
|
|
return &m[0][0];
|
|
}
|
|
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlZRotation
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Generate about the z axis
|
|
Arguments:
|
|
degrees - number of degrees to rotate
|
|
Return:
|
|
const point to rotation matrix
|
|
-------------------------------------------------------------------*/
|
|
const float *tlZRotation( float degrees ) {
|
|
static TlMatrix m;
|
|
float c = (float)cos( degrees * DEGREE );
|
|
float s = (float)sin( degrees * DEGREE );
|
|
m[0][0] = c, m[0][1] = s, m[0][2] = 0.0f, m[0][3] = 0.0f;
|
|
m[1][0] = -s, m[1][1] = c, m[1][2] = 0.0f, m[1][3] = 0.0f;
|
|
m[2][0] = 0.0f, m[2][1] = 0.0f, m[2][2] = 1.0f, m[2][3] = 0.0f;
|
|
m[3][0] = 0.0f, m[3][1] = 0.0f, m[3][2] = 0.0f, m[3][3] = 1.0f;
|
|
return &m[0][0];
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlTranslation
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Generate a translation matrix
|
|
Arguments:
|
|
x, y, z - offsets to translate origin
|
|
Return:
|
|
const point to translation matrix
|
|
-------------------------------------------------------------------*/
|
|
const float *tlTranslation( float x, float y, float z ) {
|
|
static TlMatrix m;
|
|
m[0][0] = 1.0f, m[0][1] = 0.0f, m[0][2] = 0.0f, m[0][3] = 0.0f;
|
|
m[1][0] = 0.0f, m[1][1] = 1.0f, m[1][2] = 0.0f, m[1][3] = 0.0f;
|
|
m[2][0] = 0.0f, m[2][1] = 0.0f, m[2][2] = 1.0f, m[2][3] = 0.0f;
|
|
m[3][0] = x, m[3][1] = y, m[3][2] = z, m[3][3] = 1.0f;
|
|
return &m[0][0];
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlSetMatrix
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Set the current matrix. This matrix translates the object into
|
|
View space from local coordiantes during calls to transformVertices
|
|
All spaces are considered to by -1.0->1.0 normalized.
|
|
Arguments:
|
|
m - pointer to matrix
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlSetMatrix( const float *m ) {
|
|
memcpy( currentMatrix, m, sizeof( TlMatrix ) );
|
|
return;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlMultMatrix
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Multiply the current matrix by the provided matrix
|
|
Arguments:
|
|
matrix to post-cat to the current matrix
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlMultMatrix( const float *m ) {
|
|
TlMatrix result;
|
|
TlMatrix mat;
|
|
int i, j;
|
|
|
|
memcpy( mat, m, sizeof( TlMatrix ) );
|
|
|
|
for( j = 0; j < 4; j++ ) {
|
|
for( i = 0; i < 4; i++ ) {
|
|
result[j][i] =
|
|
currentMatrix[j][0] * mat[0][i] +
|
|
currentMatrix[j][1] * mat[1][i] +
|
|
currentMatrix[j][2] * mat[2][i] +
|
|
currentMatrix[j][3] * mat[3][i];
|
|
}
|
|
}
|
|
memcpy( currentMatrix, result, sizeof( TlMatrix ) );
|
|
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlTransformVertices
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
Transform a list of vertices from model space into view space
|
|
Arguments:
|
|
dstVerts - memory to store transformed vertices
|
|
srcVerts - array of vertices to be transformed
|
|
length - number of vertices to transform
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlTransformVertices( TlVertex3D *dstVerts, TlVertex3D *srcVerts, unsigned length ) {
|
|
TlVertex3D tmp, v;
|
|
TlMatrix m;
|
|
unsigned i;
|
|
|
|
memcpy( m, currentMatrix, sizeof( TlMatrix ) );
|
|
for( i = 0; i < length; i++ ) {
|
|
v = srcVerts[i];
|
|
tmp = v;
|
|
tmp.x = v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0];
|
|
tmp.y = v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1];
|
|
tmp.z = v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2];
|
|
tmp.w = v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3];
|
|
dstVerts[i] = tmp;
|
|
}
|
|
return;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlProjectVertices
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Library
|
|
Description:
|
|
perspective project a set of vertices into normalized 2D space (0,1)
|
|
Arguments:
|
|
dstVerts - memory to store projected vertices
|
|
srcVerts - array of vertices to be transformed
|
|
length - number of vertices to transform
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
#define VP_OFFSET 1.0f
|
|
#define VP_SCALE 0.5f
|
|
|
|
void tlProjectVertices( TlVertex3D *dstVerts, TlVertex3D *srcVerts, unsigned length ) {
|
|
TlVertex3D tmp, v;
|
|
TlMatrix m;
|
|
unsigned i;
|
|
|
|
/* simplified perspective proj matrix assume unit clip volume */
|
|
m[0][0] = 1.0f, m[0][1] = 0.0f, m[0][2] = 0.0f, m[0][3] = 0.0f;
|
|
m[1][0] = 0.0f, m[1][1] = 1.0f, m[1][2] = 0.0f, m[1][3] = 0.0f;
|
|
m[2][0] = 0.0f, m[2][1] = 0.0f, m[2][2] = 1.0f, m[2][3] = 1.0f;
|
|
m[3][0] = 0.0f, m[3][1] = 0.0f, m[3][2] = 0.0f, m[3][3] = 0.0f;
|
|
|
|
for( i = 0; i < length; i++ ) {
|
|
v = srcVerts[i];
|
|
tmp = v;
|
|
tmp.x = v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0];
|
|
tmp.y = v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1];
|
|
tmp.z = v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2];
|
|
tmp.w = v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3];
|
|
tmp.x /= tmp.w, tmp.y /= tmp.w, tmp.z /= tmp.w;
|
|
tmp.x += VP_OFFSET, tmp.x *= VP_SCALE;
|
|
tmp.y += VP_OFFSET, tmp.y *= VP_SCALE;
|
|
dstVerts[i] = tmp;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlCProjectVertices
|
|
Date: 06-Feb-98
|
|
Implementor(s): atai
|
|
Library: Test Library
|
|
Description:
|
|
perspective project a set of vertices only.
|
|
Arguments:
|
|
dstVerts - memory to store projected vertices
|
|
srcVerts - array of vertices to be transformed
|
|
length - number of vertices to transform
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
void tlCProjectVertices( TlVertex3D *dstVerts, TlVertex3D *srcVerts, unsigned length ) {
|
|
TlVertex3D tmp, v;
|
|
TlMatrix m;
|
|
unsigned i;
|
|
|
|
/* simplified perspective proj matrix assume unit clip volume */
|
|
m[0][0] = 1.0f, m[0][1] = 0.0f, m[0][2] = 0.0f, m[0][3] = 0.0f;
|
|
m[1][0] = 0.0f, m[1][1] = 1.0f, m[1][2] = 0.0f, m[1][3] = 0.0f;
|
|
m[2][0] = 0.0f, m[2][1] = 0.0f, m[2][2] = 1.0f, m[2][3] = 1.0f;
|
|
m[3][0] = 0.0f, m[3][1] = 0.0f, m[3][2] = 0.0f, m[3][3] = 0.0f;
|
|
|
|
for( i = 0; i < length; i++ ) {
|
|
v = srcVerts[i];
|
|
tmp = v;
|
|
tmp.x = v.x * m[0][0] + v.y * m[1][0] + v.z * m[2][0] + v.w * m[3][0];
|
|
tmp.y = v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1] + v.w * m[3][1];
|
|
tmp.z = v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2] + v.w * m[3][2];
|
|
tmp.w = v.x * m[0][3] + v.y * m[1][3] + v.z * m[2][3] + v.w * m[3][3];
|
|
dstVerts[i] = tmp;
|
|
}
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlLoadTexture
|
|
Date: 3/3
|
|
Implementor(s): jdt
|
|
Library: Test Libarary
|
|
Description:
|
|
Load Texture
|
|
|
|
This example loads textures from a .3df file. 3DF files
|
|
containe pre-computed mipmaps data along with any
|
|
necessary supplementary information, for example
|
|
palettes, ncc-tables, level-of-detail description,
|
|
aspect ratio or format
|
|
|
|
The gu3dfGetInfo and gu3dfLoad APIs load A 3DF file
|
|
into Gu3DfInfo structure from a file on disk. Data
|
|
can then be extracted from the gu3DfInfo structure
|
|
to initialize a GrTexInfo structure used in the
|
|
glide texturing routines. Also note that texture table
|
|
( either NCC or Palette ) management is left up to the
|
|
application programmer.
|
|
Arguments:
|
|
filename - name of .3df file on disk
|
|
info - Pointer to GrTexInfo
|
|
tableType - pointer to tabletype
|
|
table - pointer to table data
|
|
Return:
|
|
0 - fail
|
|
1 - pass
|
|
-------------------------------------------------------------------*/
|
|
static GrTexTable_t texTableType( GrTextureFormat_t format );
|
|
|
|
int tlLoadTexture( const char *filename,
|
|
GrTexInfo *info,
|
|
GrTexTable_t *tableType,
|
|
void *table ) {
|
|
Gu3dfInfo tdfInfo;
|
|
int rv = 0;
|
|
|
|
assert( filename );
|
|
assert( info );
|
|
assert( tableType );
|
|
assert( table );
|
|
if ( gu3dfGetInfo( filename, &tdfInfo ) ) {
|
|
tdfInfo.data = malloc( tdfInfo.mem_required );
|
|
assert( tdfInfo.data );
|
|
if ( gu3dfLoad( filename, &tdfInfo ) ) {
|
|
info->smallLodLog2 = tdfInfo.header.small_lod;
|
|
info->largeLodLog2 = tdfInfo.header.large_lod;
|
|
info->aspectRatioLog2 = tdfInfo.header.aspect_ratio;
|
|
info->format = tdfInfo.header.format;
|
|
info->data = tdfInfo.data;
|
|
*tableType = texTableType( info->format );
|
|
switch( *tableType ) {
|
|
case GR_TEXTABLE_NCC0:
|
|
case GR_TEXTABLE_NCC1:
|
|
case GR_TEXTABLE_PALETTE:
|
|
memcpy( table, &(tdfInfo.table), sizeof( TlTextureTable ) );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
rv = 1;
|
|
}
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
|
|
|
|
/*--------------------------------------------------------------------
|
|
Static Helpers
|
|
--------------------------------------------------------------------*/
|
|
|
|
static void consoleScroll( void ) {
|
|
memmove( consoleGrid,
|
|
consoleGrid + consoleColumns,
|
|
(consoleRows-1)*consoleColumns );
|
|
memset( consoleGrid+(consoleRows-1)*consoleColumns,
|
|
32,
|
|
consoleColumns );
|
|
}
|
|
|
|
static void drawChar( char character, float x, float y, float w, float h ) {
|
|
GrVertex a, b, c, d;
|
|
/* a---b
|
|
|\ |
|
|
| \ |
|
|
| \|
|
|
c---d */
|
|
|
|
if ( character == 32 ) return;
|
|
|
|
a.oow = b.oow = c.oow = d.oow = 1.0f;
|
|
|
|
a.x = c.x = tlScaleX(x);
|
|
a.y = b.y = tlScaleY(y);
|
|
d.x = b.x = tlScaleX(x+w);
|
|
d.y = c.y = tlScaleY(y+h);
|
|
|
|
grConstantColorValue( consoleColor );
|
|
|
|
a.tmuvtx[0].sow = c.tmuvtx[0].sow =
|
|
(float)fontTable[(unsigned char)character][0];
|
|
a.tmuvtx[0].tow = b.tmuvtx[0].tow =
|
|
(float)fontTable[(unsigned char)character][1];
|
|
d.tmuvtx[0].sow = b.tmuvtx[0].sow =
|
|
a.tmuvtx[0].sow + (float)fontWidth;
|
|
d.tmuvtx[0].tow = c.tmuvtx[0].tow =
|
|
a.tmuvtx[0].tow + (float)fontHeight;
|
|
|
|
grDrawTriangle( &a, &d, &c );
|
|
grDrawTriangle( &a, &b, &d );
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
|
|
#if 0 /* not used */
|
|
static void readRegion( void *data,
|
|
int x, int y,
|
|
int w, int h );
|
|
static void writeRegion( void *data,
|
|
int x, int y,
|
|
int w, int h );
|
|
|
|
|
|
static void putTex( FxU32 addr, void *storage ) {
|
|
GrTexInfo texInfo;
|
|
|
|
texInfo.smallLodLog2 = GR_LOD_LOG2_256;
|
|
texInfo.largeLodLog2 = GR_LOD_LOG2_256;
|
|
texInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
|
texInfo.format = GR_TEXFMT_RGB_565;
|
|
texInfo.data = storage;
|
|
|
|
grTexDownloadMipMap( 0, addr, GR_MIPMAPLEVELMASK_BOTH, &fontInfo );
|
|
}
|
|
|
|
|
|
static void grabTex( FxU32 addr, void *storage ) {
|
|
static FxU16 tmpSpace[256][256];
|
|
GrTexInfo texInfo;
|
|
GrVertex a, b, c, d;
|
|
|
|
grGlideGetState( state );
|
|
grDitherMode( GR_DITHER_DISABLE );
|
|
grColorMask( FXTRUE, FXFALSE );
|
|
grSstOrigin( GR_ORIGIN_UPPER_LEFT );
|
|
grCullMode( GR_CULL_DISABLE );
|
|
|
|
/* Grab Upper Left 256*256 of frame buffer */
|
|
readRegion( tmpSpace, 0, 0, 256, 256 );
|
|
|
|
/* Grab First 256x256 MM in Texture Ram */
|
|
texInfo.smallLodLog2 = GR_LOD_LOG2_256;
|
|
texInfo.largeLodLog2 = GR_LOD_LOG2_256;
|
|
texInfo.aspectRatioLog2 = GR_ASPECT_LOG2_1x1;
|
|
texInfo.format = GR_TEXFMT_RGB_565;
|
|
texInfo.data = 0;
|
|
grTexMipMapMode( 0, GR_MIPMAP_DISABLE, FXFALSE );
|
|
grTexFilterMode( 0,
|
|
GR_TEXTUREFILTER_POINT_SAMPLED,
|
|
GR_TEXTUREFILTER_POINT_SAMPLED );
|
|
grTexCombine( 0,
|
|
GR_COMBINE_FUNCTION_LOCAL,
|
|
GR_COMBINE_FACTOR_NONE,
|
|
GR_COMBINE_FUNCTION_LOCAL,
|
|
GR_COMBINE_FACTOR_NONE,
|
|
FXFALSE,
|
|
FXFALSE );
|
|
grColorCombine( GR_COMBINE_FUNCTION_SCALE_OTHER,
|
|
GR_COMBINE_FACTOR_ONE,
|
|
GR_COMBINE_LOCAL_NONE,
|
|
GR_COMBINE_OTHER_TEXTURE,
|
|
FXFALSE );
|
|
grTexSource( 0, addr, GR_MIPMAPLEVELMASK_BOTH, &texInfo );
|
|
grAlphaBlendFunction( GR_BLEND_ONE, GR_BLEND_ZERO,
|
|
GR_BLEND_ONE, GR_BLEND_ZERO);
|
|
grDepthBufferFunction( GR_DEPTHBUFFER_DISABLE );
|
|
grAlphaTestFunction( GR_CMP_ALWAYS );
|
|
grFogMode( GR_FOG_DISABLE );
|
|
grCullMode( GR_CULL_DISABLE );
|
|
grChromakeyMode( GR_CHROMAKEY_DISABLE );
|
|
/*-------------------
|
|
A---B
|
|
| \ |
|
|
C---D
|
|
-------------------*/
|
|
a.oow = a.tmuvtx[0].oow = 1.0f;
|
|
b = c = d = a;
|
|
a.x = c.x = a.y = b.y = 0.5f;
|
|
b.x = d.x = c.y = d.y = 255.6f;
|
|
a.tmuvtx[0].sow = c.tmuvtx[0].sow = a.tmuvtx[0].tow = b.tmuvtx[0].tow =
|
|
0.5f;
|
|
b.tmuvtx[0].sow = d.tmuvtx[0].sow = c.tmuvtx[0].tow = d.tmuvtx[0].tow =
|
|
0.5f;
|
|
grDrawTriangle( &a, &d, &c );
|
|
grDrawTriangle( &a, &b, &d );
|
|
readRegion( storage, 0, 0, 256, 256 );
|
|
|
|
/* Restore The Upper Left Hand of Frame Buffer */
|
|
writeRegion( tmpSpace, 0, 0, 256, 256 );
|
|
grGlideSetState( state );
|
|
return;
|
|
}
|
|
|
|
static void readRegion( void *data,
|
|
int sx, int sy,
|
|
int w, int h ) {
|
|
int x; int y;
|
|
GrLfbInfo_t info;
|
|
|
|
info.size = sizeof( info );
|
|
|
|
assert( grLfbLock( GR_LFB_READ_ONLY,
|
|
GR_BUFFER_BACKBUFFER,
|
|
GR_LFBWRITEMODE_ANY,
|
|
GR_ORIGIN_UPPER_LEFT,
|
|
FXFALSE,
|
|
&info ) );
|
|
|
|
for( y = 0; y < h; y++ ) {
|
|
unsigned short *dst = ((unsigned short *)data+
|
|
(w*y));
|
|
unsigned short *src = (unsigned short*)(((char*)info.lfbPtr)
|
|
+(info.strideInBytes*(sy+y))
|
|
+(sx<<1));
|
|
for( x = 0; x < w; x++ ) {
|
|
*dst++ = *src++;
|
|
}
|
|
}
|
|
|
|
|
|
assert( grLfbUnlock( GR_LFB_READ_ONLY, GR_BUFFER_BACKBUFFER ) );
|
|
return;
|
|
}
|
|
static void writeRegion( void *data,
|
|
int sx, int sy,
|
|
int w, int h ) {
|
|
int x; int y;
|
|
GrLfbInfo_t info;
|
|
|
|
info.size = sizeof( info );
|
|
|
|
assert( grLfbLock( GR_LFB_WRITE_ONLY,
|
|
GR_BUFFER_BACKBUFFER,
|
|
GR_LFBWRITEMODE_ANY,
|
|
GR_ORIGIN_UPPER_LEFT,
|
|
FXFALSE,
|
|
&info ) );
|
|
|
|
for( y = 0; y < h; y++ ) {
|
|
unsigned short *src = ((unsigned short *)data+
|
|
(w*y));
|
|
unsigned short *dst = (unsigned short*)(((char*)info.lfbPtr)
|
|
+(info.strideInBytes*(sy+y))
|
|
+(sx<<1));
|
|
for( x = 0; x < w; x++ ) {
|
|
*dst++ = *src++;
|
|
}
|
|
}
|
|
|
|
assert( grLfbUnlock( GR_LFB_WRITE_ONLY, GR_BUFFER_BACKBUFFER ) );
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
|
|
static GrTexTable_t texTableType( GrTextureFormat_t format ) {
|
|
GrTexTable_t rv = (GrTexTable_t)NO_TABLE;
|
|
switch( format ) {
|
|
case GR_TEXFMT_YIQ_422:
|
|
case GR_TEXFMT_AYIQ_8422:
|
|
rv = GR_TEXTABLE_NCC0;
|
|
break;
|
|
case GR_TEXFMT_P_8:
|
|
case GR_TEXFMT_AP_88:
|
|
rv = GR_TEXTABLE_PALETTE;
|
|
break;
|
|
}
|
|
return rv;
|
|
}
|
|
|
|
/*
|
|
* SimpleRleDecode
|
|
* simple rle decoder
|
|
* Arguments:
|
|
* width : width of the image
|
|
* height : height of the image
|
|
* pixelsize : 1-4
|
|
* *mem : compressed data
|
|
* *buff : uncompressed data
|
|
* Return:
|
|
* TRUE if decode sucessful. otherwise FALSE
|
|
* The simple rle file file format
|
|
* width: 2 bytes
|
|
* height: 2 bytes
|
|
* compression type: 1 byte (0: literal data, 1: rle)
|
|
* depth: 1 byte (16 for sst1)
|
|
* image data
|
|
* 1st byte: control byte. msb = 1 indicate a run, msb = 0 indicate a literal string
|
|
* bit 7-0 is counter. it is zero based.
|
|
* next depth/8 bytes: pixel data
|
|
*/
|
|
FxBool
|
|
SimpleRleDecode
|
|
(
|
|
FxU16 width,
|
|
FxU16 height,
|
|
FxU8 pixelsize,
|
|
FxU8 *mem,
|
|
FxU8 *buff
|
|
)
|
|
{
|
|
FxU32 count = width * height;
|
|
FxU8 run, lit;
|
|
|
|
while (count) {
|
|
if (*mem & 0x80) {
|
|
run = *mem & 0x7f;
|
|
run++;
|
|
mem++;
|
|
if (count < run)
|
|
return FXFALSE;
|
|
count -= run;
|
|
while (run) {
|
|
memcpy(buff, mem, pixelsize);
|
|
run--;
|
|
buff+=pixelsize;
|
|
}
|
|
mem+=pixelsize;
|
|
}
|
|
else {
|
|
lit = *mem;
|
|
lit++;
|
|
mem++;
|
|
if (count < lit)
|
|
return FXFALSE;
|
|
count -= lit;
|
|
while (lit) {
|
|
memcpy(buff, mem, pixelsize);
|
|
lit--;
|
|
buff+=pixelsize;
|
|
mem+=pixelsize;
|
|
}
|
|
}
|
|
}
|
|
return FXTRUE;
|
|
}
|
|
|
|
/*
|
|
* WritePixel
|
|
* write rle run/literal strings
|
|
* Arguments:
|
|
* flag: TRUE if it is a run. otherwise it is a string
|
|
* count: number of run/literal (0 based)
|
|
* *buff: output area
|
|
* *tmp: source area
|
|
* pixelsize: pixel size (1-4)
|
|
* Return:
|
|
* none
|
|
*/
|
|
static void
|
|
WritePixel
|
|
(
|
|
FxBool flag,
|
|
FxU8 count,
|
|
FxU8 *buff,
|
|
FxU8 *tmp,
|
|
FxU8 pixelsize
|
|
)
|
|
{
|
|
FxU8 val;
|
|
FxU32 i;
|
|
|
|
if (flag) {
|
|
val = 0x80 | count;
|
|
count = 0;
|
|
}
|
|
else
|
|
val = count;
|
|
|
|
*buff = val;
|
|
buff++;
|
|
for (i = 0; i <= count; i++) {
|
|
memcpy(buff, tmp, pixelsize);
|
|
buff+=pixelsize;
|
|
tmp+=4;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* SimpleRleEncode
|
|
* simple rle encoder
|
|
* Arguments:
|
|
* pixelcount : number of pixels
|
|
* pixelsize : 1-4
|
|
* *mem : source image
|
|
* *buff : compressed data
|
|
* Return:
|
|
* none
|
|
*/
|
|
static FxU32
|
|
SimpleRleEncode
|
|
(
|
|
FxU32 pixelcount, /* number of pixels */
|
|
FxU8 pixelsize, /* size of pixel (in bytes) 1-4 */
|
|
FxU8 *mem, /* src image */
|
|
FxU8 *buff /* compressed data */
|
|
)
|
|
{
|
|
FxU8 *src = buff;
|
|
FxU8 run = 0, lit = 0;
|
|
FxU32 tmp[130];
|
|
FxU32 pval = 0, cval = 0;
|
|
FxU32 i;
|
|
FxU32 tt;
|
|
FxBool flag = FXFALSE;
|
|
|
|
/* determine run or literal */
|
|
mem+=pixelsize;
|
|
|
|
for (i = 1; i < pixelcount; i++) {
|
|
if (i > 300000)
|
|
tt = 1;
|
|
memcpy(&pval, mem-pixelsize, pixelsize);
|
|
memcpy(&cval, mem, pixelsize);
|
|
if (cval == pval) {
|
|
flag = FXFALSE;
|
|
if (lit) {
|
|
WritePixel(FXFALSE, (FxU8)(lit - 1), buff, (FxU8 *)&tmp[0], pixelsize);
|
|
buff += (1 + pixelsize * lit);
|
|
lit = 0;
|
|
}
|
|
run++;
|
|
if (run == 128) {
|
|
WritePixel(FXTRUE, (FxU8)(run - 1), buff, (FxU8 *)&tmp[0], pixelsize);
|
|
buff += (1 + pixelsize);
|
|
run -= 128;
|
|
}
|
|
memcpy(&tmp[0], mem, pixelsize);
|
|
}
|
|
else {
|
|
flag = FXTRUE;
|
|
if (run) {
|
|
WritePixel(FXTRUE, run, buff, (FxU8 *)&tmp[0], pixelsize);
|
|
buff += (1 + pixelsize);
|
|
run = 0;
|
|
}
|
|
else {
|
|
if (lit == 128) {
|
|
WritePixel(FXFALSE, (FxU8)(lit - 1), buff, (FxU8 *)&tmp[0], pixelsize);
|
|
buff += (1 + pixelsize * lit);
|
|
lit -= 128;
|
|
}
|
|
memcpy(&tmp[lit], mem-pixelsize, pixelsize);
|
|
lit++;
|
|
}
|
|
}
|
|
mem+=pixelsize;
|
|
}
|
|
/* last pixel */
|
|
if (flag) {
|
|
if (lit == 128) {
|
|
WritePixel(FXFALSE, (FxU8)(lit - 1), buff, (FxU8 *)&tmp[0], pixelsize);
|
|
buff += (1 + pixelsize * lit);
|
|
lit -= 128;
|
|
}
|
|
memcpy(&tmp[lit], mem-pixelsize, pixelsize);
|
|
WritePixel(FXFALSE, (FxU8)lit, buff, (FxU8 *)&tmp[0], pixelsize);
|
|
lit++;
|
|
buff += (1 + pixelsize * lit);
|
|
lit = 0;
|
|
}
|
|
else if (run) {
|
|
WritePixel(FXTRUE, run, buff, (FxU8 *)&tmp[0], pixelsize);
|
|
buff += (1 + pixelsize);
|
|
run = 0;
|
|
}
|
|
|
|
return( (FxU32) (buff - src));
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlScreenDump
|
|
Date: 6/6/97
|
|
Implementor(s):
|
|
Library: test library
|
|
Description:
|
|
dump the lfb data
|
|
Arguments:
|
|
filename - filename
|
|
width - width for frame buffer
|
|
height - height for frame buffer
|
|
Return:
|
|
none
|
|
-------------------------------------------------------------------*/
|
|
FxBool
|
|
tlScreenDump
|
|
(
|
|
const char *filename,
|
|
FxU16 width,
|
|
FxU16 height
|
|
)
|
|
{
|
|
FILE *fp;
|
|
FxU16 *pixel, *region;
|
|
FxU8 *buff;
|
|
FxU32 count, signature;
|
|
FxU8 type, depth;
|
|
|
|
fp = fopen(filename, "wb");
|
|
if (fp == NULL)
|
|
return(FXFALSE);
|
|
|
|
region = malloc(width * height * sizeof(FxU16));
|
|
buff = malloc(width * height * sizeof(FxU16) * 2);
|
|
grLfbReadRegion( GR_BUFFER_FRONTBUFFER,
|
|
0, 0, width, height,
|
|
width*2, region );
|
|
|
|
pixel = (FxU16 *)region;
|
|
|
|
count = SimpleRleEncode( (FxU32)width * (FxU32)height, 2, (FxU8 *)region, (FxU8 *)buff);
|
|
|
|
/* header of the file */
|
|
type = LFB_DATA_RLE;
|
|
depth = 16;
|
|
signature = IMAGE_SRLE;
|
|
fwrite(&signature, sizeof(FxU32), 1, fp);
|
|
fwrite(&width, sizeof(FxU16), 1, fp);
|
|
fwrite(&height, sizeof(FxU16), 1, fp);
|
|
fwrite(&depth, sizeof(FxU8), 1, fp);
|
|
fwrite(&type, sizeof(FxU8), 1, fp);
|
|
|
|
/* LFB data */
|
|
fwrite(buff, count, 1, fp);
|
|
|
|
free(buff);
|
|
free(region);
|
|
fclose(fp);
|
|
|
|
return FXTRUE;
|
|
}
|
|
|
|
#ifdef __linux__
|
|
#include <linutil.h>
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlKbHit
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: test library
|
|
Description:
|
|
Returns true if there are pending characters in the input queue
|
|
Arguments:
|
|
none
|
|
Return:
|
|
nonzero if keys in queue
|
|
-------------------------------------------------------------------*/
|
|
int tlKbHit( void ) {
|
|
return lin_kbhit();
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlGetCH
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: test library
|
|
Description:
|
|
Returns character from top of input fifo, blocks if fifo is empty
|
|
Arguments:
|
|
none
|
|
Return:
|
|
character
|
|
-------------------------------------------------------------------*/
|
|
char tlGetCH( void ) {
|
|
return lin_getch();
|
|
}
|
|
|
|
FxBool
|
|
tlErrorMessage(const char *err) {
|
|
fprintf(stderr, "%s", err);
|
|
return FXTRUE;
|
|
} /* tlErrorMessage */
|
|
|
|
FxU32
|
|
tlGethWnd(void)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
#else
|
|
#ifdef __DOS32__
|
|
/*-------------------------------------------------------------------
|
|
Function: tlKbHit
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: test library
|
|
Description:
|
|
Returns true if there are pending characters in the input queue
|
|
Arguments:
|
|
none
|
|
Return:
|
|
nonzero if keys in queue
|
|
-------------------------------------------------------------------*/
|
|
int tlKbHit( void ) {
|
|
#if macintosh
|
|
return (tlGetCH() != 0);
|
|
#else
|
|
return kbhit();
|
|
#endif
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlGetCH
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: test library
|
|
Description:
|
|
Returns character from top of input fifo, blocks if fifo is empty
|
|
Arguments:
|
|
none
|
|
Return:
|
|
character
|
|
-------------------------------------------------------------------*/
|
|
char tlGetCH( void ) {
|
|
#if macintosh
|
|
static char lastKey = '\0';
|
|
char retVal = 0;
|
|
|
|
if (lastKey != '\0') {
|
|
retVal = lastKey;
|
|
lastKey = '\0';
|
|
} else {
|
|
Point curMouse;
|
|
GrafPtr oldPort;
|
|
WindowPtr consoleWindow = FrontWindow();
|
|
|
|
GetPort(&oldPort);
|
|
SetPort(consoleWindow);
|
|
|
|
GetMouse(&curMouse);
|
|
if ((curMouse.h >= 0) &&
|
|
(curMouse.v >= 0) &&
|
|
(curMouse.h <= consoleWindow->portRect.right) &&
|
|
(curMouse.v <= consoleWindow->portRect.bottom)) {
|
|
|
|
EventRecord tempEvent;
|
|
|
|
if (WaitNextEvent(keyDownMask | keyUpMask, &tempEvent, 100, NULL)) {
|
|
switch(tempEvent.what) {
|
|
case keyDown:
|
|
case keyUp:
|
|
case autoKey:
|
|
retVal =
|
|
lastKey = (char)(tempEvent.message & 0xFF);
|
|
|
|
default:
|
|
SIOUXHandleOneEvent(&tempEvent);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetPort(oldPort);
|
|
}
|
|
|
|
return retVal;
|
|
#else
|
|
return getch();
|
|
#endif
|
|
}
|
|
|
|
FxBool
|
|
tlErrorMessage(const char *err) {
|
|
fprintf(stderr, "%s", err);
|
|
return FXTRUE;
|
|
} /* tlErrorMessage */
|
|
|
|
FxU32
|
|
tlGethWnd(void)
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
#elif __WIN32__
|
|
|
|
|
|
/* This segment simulates main() for Windows, creates a window, etc. */
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#include <windows.h>
|
|
|
|
/* Forward declarations */
|
|
HWND hWndMain;
|
|
|
|
/*
|
|
* MainWndproc
|
|
*
|
|
* Callback for all Windows messages
|
|
*/
|
|
static int qhead = 0;
|
|
static int qtail = 0;
|
|
static int queue[256] = {0};
|
|
|
|
LRESULT WINAPI
|
|
MainWndproc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam )
|
|
{
|
|
PAINTSTRUCT ps;
|
|
HDC hdc;
|
|
|
|
switch( message )
|
|
{
|
|
case WM_SETCURSOR:
|
|
if (Res != GR_RESOLUTION_NONE) {
|
|
SetCursor(NULL);
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case WM_CREATE:
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
hdc = BeginPaint( hWnd, &ps );
|
|
EndPaint( hWnd, &ps );
|
|
return 1;
|
|
|
|
case WM_CLOSE:
|
|
queue[qhead++] = 'q'; qhead &= 255;
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
break;
|
|
|
|
case WM_MOVE:
|
|
break;
|
|
|
|
case WM_DISPLAYCHANGE:
|
|
case WM_SIZE:
|
|
okToRender = FXTRUE;
|
|
break;
|
|
|
|
case WM_CHAR:
|
|
if ((int)wParam & ~0x7f) break;/* not ascii */
|
|
#if 0
|
|
printf("Posting keystroke %.02x\n", wParam);
|
|
fflush(stdout);
|
|
#endif
|
|
/* queue[qhead++] = tolower(wParam); */
|
|
queue[qhead++] = wParam;
|
|
qhead &= 255;
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
return DefWindowProc(hWnd, message, wParam, lParam);
|
|
|
|
} /* MainWndproc */
|
|
|
|
/*
|
|
* initApplication
|
|
*
|
|
* Do that Windows initialization stuff...
|
|
*/
|
|
static BOOL
|
|
initApplication( HANDLE hInstance )
|
|
{
|
|
WNDCLASS wc;
|
|
BOOL rc;
|
|
|
|
wc.style = CS_DBLCLKS;
|
|
wc.lpfnWndProc = MainWndproc;
|
|
wc.cbClsExtra = 0;
|
|
wc.cbWndExtra = 0;
|
|
wc.hInstance = hInstance;
|
|
wc.hIcon = LoadIcon( NULL, IDI_APPLICATION); /* generic icon */
|
|
wc.hCursor = LoadCursor( NULL, IDC_ARROW );
|
|
wc.hbrBackground = GetStockObject( BLACK_BRUSH );
|
|
wc.lpszMenuName = NULL;
|
|
wc.lpszClassName = "WinGlideClass";
|
|
rc = RegisterClass( &wc );
|
|
if( !rc ) {
|
|
return FALSE;
|
|
}
|
|
|
|
hWndMain =
|
|
CreateWindowEx(
|
|
#if 0
|
|
WS_EX_APPWINDOW gives you regular borders?
|
|
WS_EX_TOPMOST Works as advertised.
|
|
#endif
|
|
WS_EX_APPWINDOW,
|
|
"WinGlideClass",
|
|
"Glide Test",
|
|
WS_OVERLAPPED |
|
|
WS_CAPTION |
|
|
WS_THICKFRAME |
|
|
WS_MAXIMIZEBOX |
|
|
WS_MINIMIZEBOX |
|
|
WS_VISIBLE | /* so we don't have to call ShowWindow */
|
|
WS_POPUP | /* non-app window */
|
|
WS_SYSMENU, /* so we get an icon in the tray */
|
|
CW_USEDEFAULT,
|
|
CW_USEDEFAULT,
|
|
0x110, /* GetSystemMetrics(SM_CXSCREEN), */
|
|
0x120, /* GetSystemMetrics(SM_CYSCREEN), */
|
|
NULL,
|
|
NULL,
|
|
hInstance,
|
|
NULL
|
|
);
|
|
|
|
if( !hWndMain ) {
|
|
return FALSE;
|
|
}
|
|
|
|
SetCursor(NULL);
|
|
|
|
ShowWindow( hWndMain, SW_NORMAL);
|
|
UpdateWindow( hWndMain );
|
|
|
|
return TRUE;
|
|
|
|
} /* initApplication */
|
|
|
|
/*
|
|
* main
|
|
*/
|
|
#undef main
|
|
|
|
int
|
|
main( int argc, char **argv)
|
|
{
|
|
extern int mainT(int argc, char **argv);
|
|
|
|
if( !initApplication( GetModuleHandle(NULL)) )
|
|
return FALSE;
|
|
|
|
{
|
|
/*
|
|
* Since printfs go into the bit bucket on Win32,
|
|
* put up a message in the window.
|
|
*/
|
|
HDC hDC = GetDC(hWndMain);
|
|
char *message = "Press any Key to continue!";
|
|
RECT rect;
|
|
|
|
GetClientRect(hWndMain, &rect);
|
|
SetTextColor(hDC, RGB(0, 255, 255));
|
|
SetBkColor(hDC, RGB(0, 0, 0));
|
|
SetTextAlign(hDC, TA_CENTER);
|
|
ExtTextOut(hDC, rect.right/2, rect.bottom/2, ETO_OPAQUE, &rect,
|
|
message, strlen(message), NULL);
|
|
ReleaseDC(hWndMain, hDC);
|
|
GdiFlush();
|
|
}
|
|
/* call the renamed test main proc */
|
|
mainT(argc,argv);
|
|
printf("Exiting main()\n");
|
|
fflush(stdout);
|
|
|
|
DestroyWindow(hWndMain);
|
|
return 0;
|
|
} /* WinMain */
|
|
|
|
FxBool
|
|
tlErrorMessage(const char *err)
|
|
{
|
|
/* make the cursor visible */
|
|
SetCursor(LoadCursor( NULL, IDC_ARROW ));
|
|
|
|
/*
|
|
** warn user if there is one
|
|
*/
|
|
printf("Error %s..\n", err);
|
|
fflush(stdout);
|
|
|
|
MessageBox( hWndMain, err, "ERROR", MB_OK );
|
|
return FALSE;
|
|
} /* tlErrorMessage */
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlKbHit
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: test library
|
|
Description:
|
|
Returns true if there are pending characters in the input queue
|
|
Arguments:
|
|
none
|
|
Return:
|
|
nonzero if keys in queue
|
|
-------------------------------------------------------------------*/
|
|
int
|
|
tlKbHit( void )
|
|
{
|
|
MSG msg;
|
|
|
|
if (qhead != qtail) {
|
|
return 1;
|
|
}
|
|
|
|
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg); /* this might change qhead */
|
|
if (qhead != qtail) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
/*-------------------------------------------------------------------
|
|
Function: tlGetCH
|
|
Date: 2/28
|
|
Implementor(s): jdt
|
|
Library: test library
|
|
Description:
|
|
Returns character from top of input fifo, blocks if fifo is empty
|
|
Arguments:
|
|
none
|
|
Return:
|
|
character
|
|
-------------------------------------------------------------------*/
|
|
char
|
|
tlGetCH( void )
|
|
{
|
|
MSG msg;
|
|
char rv;
|
|
|
|
if (qtail != qhead) {
|
|
rv = queue[qtail++];
|
|
qtail &= 255;
|
|
return rv;
|
|
}
|
|
|
|
while (GetMessage( &msg, NULL, 0, 0 )) {
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
|
|
if (qtail != qhead) {
|
|
rv = queue[qtail++];
|
|
qtail &= 255;
|
|
return rv;
|
|
}
|
|
}
|
|
|
|
/* Should never get here!! */
|
|
/* printf("Bad exit..\n"); */
|
|
/* fflush(stdout); */
|
|
return -1;
|
|
}
|
|
|
|
void
|
|
tlExit()
|
|
{
|
|
PostMessage( hWndMain, WM_CLOSE, 0, 0 );
|
|
}
|
|
|
|
|
|
void
|
|
getWindowSize(float *width, float *height)
|
|
{
|
|
RECT rect;
|
|
|
|
if (fullScreen) {
|
|
GetWindowRect(hWndMain, &rect);
|
|
*width = (float) (rect.right-rect.left);
|
|
*height = (float) (rect.bottom-rect.top);
|
|
}
|
|
else {
|
|
GetClientRect(hWndMain, &rect);
|
|
*width = (float) (rect.right-rect.left);
|
|
*height = (float) (rect.bottom-rect.top);
|
|
}
|
|
}
|
|
|
|
FxU32
|
|
tlGethWnd(void)
|
|
{
|
|
return (FxU32)hWndMain;
|
|
}
|
|
|
|
#endif /* __DOS32__ */
|
|
#endif /* __linux__ */
|