- update ssggraph(Ivan's patch)

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@6782 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: 64b92b6152838e585aa6cd000eacc32077f255bb
Former-commit-id: 73962abe9f78b18a7812697bf331cb2443f5fb1b
This commit is contained in:
torcs-ng 2019-11-24 14:26:37 +00:00
parent bdbfd8f389
commit bf61d9cbfb
3 changed files with 545 additions and 529 deletions

View file

@ -72,6 +72,20 @@ static const char* AEnvShadowKeys[] =
static const int NEnvShadowFullCoverRainIndex = 5; // Index in AEnvShadowKeys
static const int NEnvShadowNightIndex = 6; // Index in AEnvShadowKeys
static const int EnvShadowIndices[] =
{
0, // TR_CLOUDS_NONE
0, // TR_CLOUDS_CIRRUS
1, // TR_CLOUDS_FEW
3, // TR_CLOUDS_MANY
2, // TR_CLOUDS_CUMULUS
2, // TR_CLOUDS_SCARCE
2, // TR_CLOUDS_BROKEN
4 // TR_CLOUDS_FULL
};
static const int NEnvShadowIndices = sizeof(EnvShadowIndices) / sizeof(int);
// Some exported global variables.
ssgStateSelector* grEnvSelector = 0;
cgrMultiTexState* grEnvState = 0;
@ -830,8 +844,8 @@ grLoadBackground()
nEnvShadowIndex = NEnvShadowNightIndex;
else if (grTrack->local.rain > 0) // Rain => full cloud cover.
nEnvShadowIndex = NEnvShadowFullCoverRainIndex;
else
nEnvShadowIndex = grTrack->local.clouds;
else if (grTrack->local.clouds < NEnvShadowIndices)
nEnvShadowIndex = EnvShadowIndices[ grTrack->local.clouds ];
}
if (nEnvShadowIndex >= 0)
{
@ -930,7 +944,7 @@ grPreDrawSky(tSituation* s, float fogStart, float fogEnd, class cGrCamera *cam)
{
//static const double m_log01 = -log( 0.01 );
//static const double sqrt_m_log01 = sqrt( m_log01 );
GLbitfield clear_mask;
GLbitfield clear_mask = 0;
if (grSkyDomeDistance )
{

View file

@ -17,9 +17,9 @@
***************************************************************************/
/*
This classes/methods are used to handle texture compression and
textures which are shared among multiple objects. In the long term
they should obsolete parts of grutil.cpp.
This classes/methods are used to handle texture compression and
textures which are shared among multiple objects. In the long term
they should obsolete parts of grutil.cpp.
*/
#include <glfeatures.h> // GfglFeatures
@ -31,37 +31,37 @@
int doMipMap(const char *tfname, int mipmap)
{
char *buf = strdup(tfname);
char *buf = strdup(tfname);
// find the filename extension.
char *s = strrchr(buf, '.');
if (s) {
*s = 0;
}
// find the filename extension.
char *s = strrchr(buf, '.');
if (s) {
*s = 0;
}
// search for the texture parameters.
s = strrchr(buf, '_');
// search for the texture parameters.
s = strrchr(buf, '_');
// 1) no mipmap for "*_n".
if (s && s[1] == 'n') {
mipmap = FALSE;
}
// 1) no mipmap for "*_n".
if (s && s[1] == 'n') {
mipmap = FALSE;
}
// 1) no mipmap for "*shadow*".
if (mipmap) {
// Check the shadow.
s = strrchr((char *)tfname, '/');
if (!s) {
s = (char*)tfname;
} else {
s++;
}
if (strstr(s, "shadow")) {
mipmap = FALSE;
}
}
free(buf);
return mipmap;
// 1) no mipmap for "*shadow*".
if (mipmap) {
// Check the shadow.
s = strrchr((char *)tfname, '/');
if (!s) {
s = (char*)tfname;
} else {
s++;
}
if (strstr(s, "shadow")) {
mipmap = FALSE;
}
}
free(buf);
return mipmap;
}
// cgrStateFactory class ========================================================
@ -71,41 +71,41 @@ cgrStateFactory* grStateFactory = new cgrStateFactory;
cgrSimpleState* cgrStateFactory::getSimpleState()
{
return new cgrSimpleState();
return new cgrSimpleState();
}
cgrMultiTexState* cgrStateFactory::getMultiTexState(cgrMultiTexState::tfnTexScheme fnTexScheme)
{
return new cgrMultiTexState(fnTexScheme);
return new cgrMultiTexState(fnTexScheme);
}
// SGI loader==================================================================
/*
The latter parts are derived from plib (plib.sf.net) and have this license:
The latter parts are derived from plib (plib.sf.net) and have this license:
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
PLIB - A Suite of Portable Game Libraries
Copyright (C) 1998,2002 Steve Baker
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library 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
Library General Public License for more details.
This library 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
For further information visit http://plib.sourceforge.net
For further information visit http://plib.sourceforge.net
*/
/*
Modifications:
Copyright (c) 2005 Bernhard Wymann
Modifications:
Copyright (c) 2005 Bernhard Wymann
*/
@ -114,293 +114,293 @@ cgrMultiTexState* cgrStateFactory::getMultiTexState(cgrMultiTexState::tfnTexSche
// SGI texture loading function.
bool grLoadSGI(const char *fname, ssgTextureInfo* info)
{
cgrSGIHeader *sgihdr = new cgrSGIHeader(fname, info);
bool returnval = sgihdr->loadSGI_bool;
delete sgihdr;
return returnval;
cgrSGIHeader *sgihdr = new cgrSGIHeader(fname, info);
bool returnval = sgihdr->loadSGI_bool;
delete sgihdr;
return returnval;
}
// Register customized loader in plib.
void grRegisterCustomSGILoader(void)
{
ssgAddTextureFormat(".rgb", grLoadSGI);
ssgAddTextureFormat(".rgba", grLoadSGI);
ssgAddTextureFormat(".int", grLoadSGI);
ssgAddTextureFormat(".inta", grLoadSGI);
ssgAddTextureFormat(".bw", grLoadSGI);
ssgAddTextureFormat(".png", grLoadPngTexture);
ssgAddTextureFormat(".jpg", grLoadJpegTexture);
ssgAddTextureFormat(".rgb", grLoadSGI);
ssgAddTextureFormat(".rgba", grLoadSGI);
ssgAddTextureFormat(".int", grLoadSGI);
ssgAddTextureFormat(".inta", grLoadSGI);
ssgAddTextureFormat(".bw", grLoadSGI);
ssgAddTextureFormat(".png", grLoadPngTexture);
ssgAddTextureFormat(".jpg", grLoadJpegTexture);
}
cgrSGIHeader::cgrSGIHeader(const char *fname, ssgTextureInfo* info)
{
cgrSGIHeader *sgihdr = this;
cgrSGIHeader *sgihdr = this;
start = NULL;
leng = NULL;
start = NULL;
leng = NULL;
bool success = openFile(fname);
bool success = openFile(fname);
int mipmap = doMipMap(fname, TRUE);
int mipmap = doMipMap(fname, TRUE);
if (!success) {
loadSGI_bool = false;
return;
}
if (!success) {
loadSGI_bool = false;
return;
}
GLubyte *image = (GLubyte*)malloc( sizeof(GLubyte) * sgihdr->xsize*sgihdr->ysize*sgihdr->zsize );
GLubyte *ptr = image;
GLubyte *image = (GLubyte*)malloc( sizeof(GLubyte) * sgihdr->xsize*sgihdr->ysize*sgihdr->zsize );
GLubyte *ptr = image;
unsigned char *rbuf = new unsigned char[sgihdr->xsize];
unsigned char *gbuf = (sgihdr->zsize>1) ? new unsigned char[sgihdr->xsize] : 0 ;
unsigned char *bbuf = (sgihdr->zsize>2) ? new unsigned char[sgihdr->xsize] : 0 ;
unsigned char *abuf = (sgihdr->zsize>3) ? new unsigned char[sgihdr->xsize] : 0 ;
unsigned char *rbuf = new unsigned char[sgihdr->xsize];
unsigned char *gbuf = (sgihdr->zsize>1) ? new unsigned char[sgihdr->xsize] : 0 ;
unsigned char *bbuf = (sgihdr->zsize>2) ? new unsigned char[sgihdr->xsize] : 0 ;
unsigned char *abuf = (sgihdr->zsize>3) ? new unsigned char[sgihdr->xsize] : 0 ;
for (int y = 0 ; y < sgihdr->ysize ; y++) {
int x ;
for (int y = 0 ; y < sgihdr->ysize ; y++) {
int x ;
switch (sgihdr->zsize) {
case 1:
sgihdr->getRow(rbuf, y, 0);
for (x = 0; x < sgihdr->xsize; x++) {
*ptr++ = rbuf[x];
}
break;
switch (sgihdr->zsize) {
case 1:
sgihdr->getRow(rbuf, y, 0);
for (x = 0; x < sgihdr->xsize; x++) {
*ptr++ = rbuf[x];
}
break;
case 2:
sgihdr->getRow (rbuf, y, 0);
sgihdr->getRow (gbuf, y, 1);
case 2:
sgihdr->getRow (rbuf, y, 0);
sgihdr->getRow (gbuf, y, 1);
for (x = 0; x < sgihdr->xsize; x++) {
*ptr++ = rbuf[x];
*ptr++ = gbuf[x];
}
break;
for (x = 0; x < sgihdr->xsize; x++) {
*ptr++ = rbuf[x];
*ptr++ = gbuf[x];
}
break;
case 3:
sgihdr->getRow(rbuf, y, 0);
sgihdr->getRow(gbuf, y, 1);
sgihdr->getRow(bbuf, y, 2);
case 3:
sgihdr->getRow(rbuf, y, 0);
sgihdr->getRow(gbuf, y, 1);
sgihdr->getRow(bbuf, y, 2);
for (x = 0; x < sgihdr->xsize; x++) {
*ptr++ = rbuf[x];
*ptr++ = gbuf[x];
*ptr++ = bbuf[x];
}
break;
for (x = 0; x < sgihdr->xsize; x++) {
*ptr++ = rbuf[x];
*ptr++ = gbuf[x];
*ptr++ = bbuf[x];
}
break;
case 4:
sgihdr->getRow(rbuf, y, 0);
sgihdr->getRow(gbuf, y, 1);
sgihdr->getRow(bbuf, y, 2);
sgihdr->getRow(abuf, y, 3);
case 4:
sgihdr->getRow(rbuf, y, 0);
sgihdr->getRow(gbuf, y, 1);
sgihdr->getRow(bbuf, y, 2);
sgihdr->getRow(abuf, y, 3);
for (x = 0; x < sgihdr->xsize; x++ ) {
*ptr++ = rbuf[x];
*ptr++ = gbuf[x];
*ptr++ = bbuf[x];
*ptr++ = abuf[x];
}
break;
}
}
for (x = 0; x < sgihdr->xsize; x++ ) {
*ptr++ = rbuf[x];
*ptr++ = gbuf[x];
*ptr++ = bbuf[x];
*ptr++ = abuf[x];
}
break;
}
}
fclose(image_fd);
image_fd = NULL ;
delete [] rbuf;
delete [] gbuf;
delete [] bbuf;
delete [] abuf;
fclose(image_fd);
image_fd = NULL ;
delete [] rbuf;
delete [] gbuf;
delete [] bbuf;
delete [] abuf;
if (info) {
info->width = sgihdr->xsize;
info->height = sgihdr->ysize;
info->depth = sgihdr->zsize;
info->alpha = (sgihdr->zsize == 2 || sgihdr->zsize == 4);
}
if (info) {
info->width = sgihdr->xsize;
info->height = sgihdr->ysize;
info->depth = sgihdr->zsize;
info->alpha = (sgihdr->zsize == 2 || sgihdr->zsize == 4);
}
loadSGI_bool = grMakeMipMaps(image, sgihdr->xsize, sgihdr->ysize, sgihdr->zsize, mipmap);
loadSGI_bool = grMakeMipMaps(image, sgihdr->xsize, sgihdr->ysize, sgihdr->zsize, mipmap);
}
bool grMakeMipMaps (GLubyte *image, int xsize, int ysize, int zsize, int mipmap)
{
if (!((xsize & (xsize-1))==0) || !((ysize & (ysize-1))==0)) {
ulSetError ( UL_WARNING, "Map is not a power-of-two in size!" ) ;
return false ;
}
if (!((xsize & (xsize-1))==0) || !((ysize & (ysize-1))==0)) {
ulSetError ( UL_WARNING, "Map is not a power-of-two in size!" ) ;
return false ;
}
GLubyte *texels[20]; // One element per level of MIPmap.
GLubyte *texels[20]; // One element per level of MIPmap.
for (int l = 0; l < 20; l++) {
texels [l] = NULL;
}
for (int l = 0; l < 20; l++) {
texels [l] = NULL;
}
texels[0] = image;
texels[0] = image;
int lev;
int lev;
for (lev = 0 ;((xsize >> (lev+1)) != 0 || (ysize >> (lev+1)) != 0); lev++) {
// Suffix '1' is the higher level map, suffix '2' is the lower level.
int l1 = lev;
int l2 = lev+1;
int w1 = xsize >> l1;
int h1 = ysize >> l1;
int w2 = xsize >> l2;
int h2 = ysize >> l2;
for (lev = 0 ;((xsize >> (lev+1)) != 0 || (ysize >> (lev+1)) != 0); lev++) {
// Suffix '1' is the higher level map, suffix '2' is the lower level.
int l1 = lev;
int l2 = lev+1;
int w1 = xsize >> l1;
int h1 = ysize >> l1;
int w2 = xsize >> l2;
int h2 = ysize >> l2;
if (w1 <= 0) {
w1 = 1;
}
if (h1 <= 0) {
h1 = 1;
}
if (w2 <= 0) {
w2 = 1;
}
if (h2 <= 0) {
h2 = 1;
}
if (w1 <= 0) {
w1 = 1;
}
if (h1 <= 0) {
h1 = 1;
}
if (w2 <= 0) {
w2 = 1;
}
if (h2 <= 0) {
h2 = 1;
}
texels[l2] = (GLubyte*)malloc( sizeof(GLubyte) * w2*h2*zsize );
texels[l2] = (GLubyte*)malloc( sizeof(GLubyte) * w2*h2*zsize );
for (int x2 = 0; x2 < w2; x2++) {
for (int y2 = 0; y2 < h2; y2++) {
for (int c = 0; c < zsize; c++) {
int x1 = x2 + x2;
int x1_1 = (x1 + 1) % w1;
int y1 = y2 + y2;
int y1_1 = (y1 + 1) % h1;
int t1 = texels[l1][(y1*w1 + x1)*zsize + c];
int t2 = texels[l1][(y1_1*w1 + x1)*zsize + c];
int t3 = texels[l1][(y1*w1 + x1_1)*zsize + c];
int t4 = texels[l1][(y1_1*w1 + x1_1)*zsize + c];
for (int x2 = 0; x2 < w2; x2++) {
for (int y2 = 0; y2 < h2; y2++) {
for (int c = 0; c < zsize; c++) {
int x1 = x2 + x2;
int x1_1 = (x1 + 1) % w1;
int y1 = y2 + y2;
int y1_1 = (y1 + 1) % h1;
int t1 = texels[l1][(y1*w1 + x1)*zsize + c];
int t2 = texels[l1][(y1_1*w1 + x1)*zsize + c];
int t3 = texels[l1][(y1*w1 + x1_1)*zsize + c];
int t4 = texels[l1][(y1_1*w1 + x1_1)*zsize + c];
if (c == 3) { // Alpha.
int a = t1;
if (t2 > a) {
a = t2;
}
if (t3 > a) {
a = t3;
}
if (t4 > a) {
a = t4;
}
texels[l2][(y2*w2 + x2)*zsize + c] = a;
} else {
texels[l2][(y2*w2 + x2)*zsize + c] = ( t1 + t2 + t3 + t4 )/4;
}
}
}
}
}
if (c == 3) { // Alpha.
int a = t1;
if (t2 > a) {
a = t2;
}
if (t3 > a) {
a = t3;
}
if (t4 > a) {
a = t4;
}
texels[l2][(y2*w2 + x2)*zsize + c] = a;
} else {
texels[l2][(y2*w2 + x2)*zsize + c] = ( t1 + t2 + t3 + t4 )/4;
}
}
}
}
}
texels[lev + 1] = NULL;
texels[lev + 1] = NULL;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST);
int map_level = 0;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST);
int map_level = 0;
GLint ww;
GLint ww;
GLint textureTargetFormat;
if (GfglFeatures::self().isSelected(GfglFeatures::TextureCompression)) {
//GfTrace("COMPRESSOR: ");
GLint textureTargetFormat;
if (GfglFeatures::self().isSelected(GfglFeatures::TextureCompression)) {
//GfTrace("COMPRESSOR: ");
switch (zsize) {
case 1:
textureTargetFormat = GL_COMPRESSED_LUMINANCE_ARB;
//GfTrace("GL_COMPRESSED_LUMINANCE_ARB\n");
break;
case 2:
textureTargetFormat = GL_COMPRESSED_LUMINANCE_ALPHA_ARB;
//GfTrace("GL_COMPRESSED_LUMINANCE_ALPHA_ARB\n");
break;
case 3:
textureTargetFormat = GL_COMPRESSED_RGB_ARB;
//GfTrace("GL_COMPRESSED_RGB_ARB\n");
break;
default:
textureTargetFormat = GL_COMPRESSED_RGBA_ARB;
//GfTrace("GL_COMPRESSED_RGBA_ARB\n");
break;
}
} else {
textureTargetFormat = zsize;
//GfTrace("NON COMPRESSOR\n");
}
switch (zsize) {
case 1:
textureTargetFormat = GL_COMPRESSED_LUMINANCE_ARB;
//GfTrace("GL_COMPRESSED_LUMINANCE_ARB\n");
break;
case 2:
textureTargetFormat = GL_COMPRESSED_LUMINANCE_ALPHA_ARB;
//GfTrace("GL_COMPRESSED_LUMINANCE_ALPHA_ARB\n");
break;
case 3:
textureTargetFormat = GL_COMPRESSED_RGB_ARB;
//GfTrace("GL_COMPRESSED_RGB_ARB\n");
break;
default:
textureTargetFormat = GL_COMPRESSED_RGBA_ARB;
//GfTrace("GL_COMPRESSED_RGBA_ARB\n");
break;
}
} else {
textureTargetFormat = zsize;
//GfTrace("NON COMPRESSOR\n");
}
const int tlimit = GfglFeatures::self().getSelected(GfglFeatures::TextureMaxSize);
const int tlimit = GfglFeatures::self().getSelected(GfglFeatures::TextureMaxSize);
do {
if (xsize > tlimit || ysize > tlimit) {
ww = 0;
} else {
do {
if (xsize > tlimit || ysize > tlimit) {
ww = 0;
} else {
glTexImage2D(GL_PROXY_TEXTURE_2D, map_level, textureTargetFormat, xsize, ysize, FALSE /* Border */,
(zsize==1)?GL_LUMINANCE:
(zsize==2)?GL_LUMINANCE_ALPHA:
(zsize==3)?GL_RGB:
GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glTexImage2D(GL_PROXY_TEXTURE_2D, map_level, textureTargetFormat, xsize, ysize, FALSE /* Border */,
(zsize==1)?GL_LUMINANCE:
(zsize==2)?GL_LUMINANCE_ALPHA:
(zsize==3)?GL_RGB:
GL_RGBA,
GL_UNSIGNED_BYTE, NULL);
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &ww);
}
glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &ww);
}
if (ww == 0) {
free( texels[0] );
xsize >>= 1;
ysize >>= 1;
for (int l = 0; texels [l] != NULL; l++) {
texels [l] = texels[l+1];
}
if (ww == 0) {
free( texels[0] );
xsize >>= 1;
ysize >>= 1;
for (int l = 0; texels [l] != NULL; l++) {
texels [l] = texels[l+1];
}
if (xsize < 8 && ysize < 8) {
//ulSetError (UL_FATAL, "SSG: OpenGL will not accept a downsized version ?!?");
}
}
} while (ww == 0);
if (xsize < 8 && ysize < 8) {
//ulSetError (UL_FATAL, "SSG: OpenGL will not accept a downsized version ?!?");
}
}
} while (ww == 0);
for (int i = 0; texels[i] != NULL; i++) {
int w = xsize >> i;
int h = ysize >> i;
for (int i = 0; texels[i] != NULL; i++) {
int w = xsize >> i;
int h = ysize >> i;
if (w <= 0) {
w = 1;
}
if (h <= 0) {
h = 1;
}
if (w <= 0) {
w = 1;
}
if (h <= 0) {
h = 1;
}
if (mipmap == TRUE || i == 0) {
glTexImage2D ( GL_TEXTURE_2D,
map_level, textureTargetFormat, w, h, FALSE /* Border */,
(zsize==1)?GL_LUMINANCE:
(zsize==2)?GL_LUMINANCE_ALPHA:
(zsize==3)?GL_RGB:
GL_RGBA,
GL_UNSIGNED_BYTE, (GLvoid *) texels[i] ) ;
if (mipmap == TRUE || i == 0) {
glTexImage2D ( GL_TEXTURE_2D,
map_level, textureTargetFormat, w, h, FALSE /* Border */,
(zsize==1)?GL_LUMINANCE:
(zsize==2)?GL_LUMINANCE_ALPHA:
(zsize==3)?GL_RGB:
GL_RGBA,
GL_UNSIGNED_BYTE, (GLvoid *) texels[i] ) ;
/*int compressed;
glGetTexLevelParameteriv(GL_TEXTURE_2D, map_level, GL_TEXTURE_COMPRESSED_ARB, &compressed);
if (compressed == GL_TRUE) {
int csize;
glGetTexLevelParameteriv(GL_TEXTURE_2D, map_level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &csize);
GfTrace("compression ratio: %d to %d\n", csize, w*h*zsize);
} else {
GfTrace("not compressed\n");
}*/
}
/*int compressed;
glGetTexLevelParameteriv(GL_TEXTURE_2D, map_level, GL_TEXTURE_COMPRESSED_ARB, &compressed);
if (compressed == GL_TRUE) {
int csize;
glGetTexLevelParameteriv(GL_TEXTURE_2D, map_level, GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB, &csize);
GfTrace("compression ratio: %d to %d\n", csize, w*h*zsize);
} else {
GfTrace("not compressed\n");
}*/
}
map_level++ ;
free( texels[i] );
}
map_level++ ;
free( texels[i] );
}
return true;
return true;
}
void doAnisotropicFiltering(){
@ -415,15 +415,15 @@ void doAnisotropicFiltering(){
glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &fLargest);
switch(aniS)
{
case 1:
aniD = fLargest/2;
break;
case 2:
aniD = fLargest;
break;
default:
aniD = 0;
{
case 1:
aniD = fLargest/2;
break;
case 2:
aniD = fLargest;
break;
default:
aniD = 1;
}
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, aniD);/**/
@ -432,31 +432,31 @@ void doAnisotropicFiltering(){
bool grLoadPngTexture (const char *fname, ssgTextureInfo* info)
{
GLubyte *tex;
int w, h;
int mipmap = 1;
GLubyte *tex;
int w, h;
int mipmap = 1;
TRACE_GL("Load: loadPngTexture start");
TRACE_GL("Load: loadPngTexture start");
tex = (GLubyte*)GfTexReadImageFromPNG(fname, 2.0, &w, &h, 0, 0);
if (!tex) {
return false;
}
tex = (GLubyte*)GfTexReadImageFromPNG(fname, 2.0, &w, &h, 0, 0);
if (!tex) {
return false;
}
if (info) {
info -> width = w;
info -> height = h;
info -> depth = 4;
info -> alpha = true;
}
if (info) {
info -> width = w;
info -> height = h;
info -> depth = 4;
info -> alpha = true;
}
TRACE_GL("Load: loadPngTexture stop");
TRACE_GL("Load: loadPngTexture stop");
// TODO: Check if tex is freed => yes, it is in grMakeMipMaps through "free(texel[i])".
// Check/fix potential problems related to malloc/delete mixture
// (instead of malloc/free or new/delete). => done below
// TODO: Check if tex is freed => yes, it is in grMakeMipMaps through "free(texel[i])".
// Check/fix potential problems related to malloc/delete mixture
// (instead of malloc/free or new/delete). => done below
mipmap = doMipMap(fname, mipmap);
mipmap = doMipMap(fname, mipmap);
// Don't know why this code, but it allocates with new something that is later freed
// with free in grMakeMipMaps ... so I comment it out.
@ -476,27 +476,27 @@ bool grLoadPngTexture (const char *fname, ssgTextureInfo* info)
bool grLoadJpegTexture (const char *fname, ssgTextureInfo* info)
{
GLubyte *tex;
int w, h;
int mipmap = 1;
GLubyte *tex;
int w, h;
int mipmap = 1;
TRACE_GL("Load: loadJpegTexture start");
TRACE_GL("Load: loadJpegTexture start");
tex = (GLubyte*)GfTexReadImageFromJPEG(fname, 2.0, &w, &h, 0, 0);
if (!tex) {
return false;
}
tex = (GLubyte*)GfTexReadImageFromJPEG(fname, 2.0, &w, &h, 0, 0);
if (!tex) {
return false;
}
if (info) {
info -> width = w;
info -> height = h;
info -> depth = 4;
info -> alpha = true;
}
if (info) {
info -> width = w;
info -> height = h;
info -> depth = 4;
info -> alpha = true;
}
TRACE_GL("Load: loadPngTexture stop");
TRACE_GL("Load: loadPngTexture stop");
mipmap = doMipMap(fname, mipmap);
mipmap = doMipMap(fname, mipmap);
bool res = grMakeMipMaps(tex, w, h, 4, mipmap) == TRUE ? true : false;

View file

@ -1,8 +1,8 @@
/**************************************************************************
file : racestartstop.cpp
copyright : (C) 2011 by Jean-Philippe Meuret
email : pouillot@users.sourceforge.net
copyright : (C) 2011 by Jean-Philippe Meuret
email : pouillot@users.sourceforge.net
version : $Id$
***************************************************************************/
@ -47,7 +47,7 @@ static int curPlayerIdx = 0;
static void
rmAbortRaceHookActivate(void * /* dummy */)
{
LmRaceEngine().abortRace();
LmRaceEngine().abortRace();
}
static void *pvAbortRaceHookHandle = 0;
@ -55,17 +55,17 @@ static void *pvAbortRaceHookHandle = 0;
static void *
rmAbortRaceHookInit()
{
if (!pvAbortRaceHookHandle)
pvAbortRaceHookHandle = GfuiHookCreate(0, rmAbortRaceHookActivate);
if (!pvAbortRaceHookHandle)
pvAbortRaceHookHandle = GfuiHookCreate(0, rmAbortRaceHookActivate);
return pvAbortRaceHookHandle;
return pvAbortRaceHookHandle;
}
// Skip session hook ***************************************************
static void
rmSkipSessionHookActivate(void * /* dummy */)
{
LmRaceEngine().skipRaceSession();
LmRaceEngine().skipRaceSession();
}
static void *pvSkipSessionHookHandle = 0;
@ -73,29 +73,29 @@ static void *pvSkipSessionHookHandle = 0;
static void *
rmSkipSessionHookInit()
{
if (!pvSkipSessionHookHandle)
pvSkipSessionHookHandle = GfuiHookCreate(0, rmSkipSessionHookActivate);
if (!pvSkipSessionHookHandle)
pvSkipSessionHookHandle = GfuiHookCreate(0, rmSkipSessionHookActivate);
return pvSkipSessionHookHandle;
return pvSkipSessionHookHandle;
}
// Back to race hook ***************************************************
static void
rmBackToRaceHookActivate(void * /* dummy */)
{
// Temporary hack for the Paused race case, in order
// the race does not get ended (as is is currently stopped)
// TODO: Activate the Stop Race menu directly, as for the Help menu (F1),
// and no more through changing the race engine state to STOP
// But beware of the other hooks ...
LmRaceEngine().inData()->_reState = RE_STATE_RACE;
// Temporary hack for the Paused race case, in order
// the race does not get ended (as is is currently stopped)
// TODO: Activate the Stop Race menu directly, as for the Help menu (F1),
// and no more through changing the race engine state to STOP
// But beware of the other hooks ...
LmRaceEngine().inData()->_reState = RE_STATE_RACE;
// Back to the race screen in next display loop.
LegacyMenu::self().activateGameScreen();
// Back to the race screen in next display loop.
LegacyMenu::self().activateGameScreen();
// Launch the "slow resume race" manager if non-blind mode.
if ((!rmPreRacePause) && (LmRaceEngine().outData()->_displayMode == RM_DISP_MODE_NORMAL))
rmProgressiveTimeModifier.start();
// Launch the "slow resume race" manager if non-blind mode.
if ((!rmPreRacePause) && (LmRaceEngine().outData()->_displayMode == RM_DISP_MODE_NORMAL))
rmProgressiveTimeModifier.start();
}
static void *pvBackToRaceHookHandle = 0;
@ -103,17 +103,17 @@ static void *pvBackToRaceHookHandle = 0;
void *
RmBackToRaceHookInit()
{
if (!pvBackToRaceHookHandle)
pvBackToRaceHookHandle = GfuiHookCreate(0, rmBackToRaceHookActivate);
if (!pvBackToRaceHookHandle)
pvBackToRaceHookHandle = GfuiHookCreate(0, rmBackToRaceHookActivate);
return pvBackToRaceHookHandle;
return pvBackToRaceHookHandle;
}
// Restart race hook ***************************************************
static void
rmRestartRaceHookActivate(void * /* dummy */)
{
LmRaceEngine().restartRace();
LmRaceEngine().restartRace();
}
static void *pvRestartRaceHookHandle = 0;
@ -121,40 +121,40 @@ static void *pvRestartRaceHookHandle = 0;
static void *
rmRestartRaceHookInit()
{
if (!pvRestartRaceHookHandle)
pvRestartRaceHookHandle = GfuiHookCreate(0, rmRestartRaceHookActivate);
if (!pvRestartRaceHookHandle)
pvRestartRaceHookHandle = GfuiHookCreate(0, rmRestartRaceHookActivate);
return pvRestartRaceHookHandle;
return pvRestartRaceHookHandle;
}
// Controls hook *******************************************************
static void
rmControlsHookActivate(void * /* dummy */)
{
#if 0
GfuiScreenActivate(PlayerConfigMenuInit(hscreen));
GfuiScreenActivate(PlayerConfigMenuInit(hscreen));
#else
void *prHandle;
char buf[100];
const char *str;
tGearChangeMode gearChangeMode;
void *prHandle;
char buf[100];
const char *str;
tGearChangeMode gearChangeMode;
sprintf(buf, "%s%s", GfLocalDir(), HM_PREF_FILE);
prHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
sprintf(buf, "%s%s", GfLocalDir(), HM_PREF_FILE);
prHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
snprintf(buf, sizeof(buf), "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, curPlayerIdx);
str = GfParmGetStr(prHandle, buf, HM_ATT_TRANS, HM_VAL_AUTO);
snprintf(buf, sizeof(buf), "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, curPlayerIdx);
str = GfParmGetStr(prHandle, buf, HM_ATT_TRANS, HM_VAL_AUTO);
if (!strcmp(str, HM_VAL_AUTO)) {
gearChangeMode = GEAR_MODE_AUTO;
} else if (!strcmp(str, HM_VAL_GRID)) {
gearChangeMode = GEAR_MODE_GRID;
} else if (!strcmp(str, HM_VAL_HBOX)) {
gearChangeMode = GEAR_MODE_HBOX;
} else {
gearChangeMode = GEAR_MODE_SEQ;
}
if (!strcmp(str, HM_VAL_AUTO)) {
gearChangeMode = GEAR_MODE_AUTO;
} else if (!strcmp(str, HM_VAL_GRID)) {
gearChangeMode = GEAR_MODE_GRID;
} else if (!strcmp(str, HM_VAL_HBOX)) {
gearChangeMode = GEAR_MODE_HBOX;
} else {
gearChangeMode = GEAR_MODE_SEQ;
}
GfuiScreenActivate(ControlMenuInit(hscreen, prHandle, curPlayerIdx, gearChangeMode, 1));
GfuiScreenActivate(ControlMenuInit(hscreen, prHandle, curPlayerIdx, gearChangeMode, 1));
#endif
}
@ -163,10 +163,10 @@ static void *pvControlsHookHandle = 0;
static void *
rmControlsHookInit()
{
if (!pvControlsHookHandle)
pvControlsHookHandle = GfuiHookCreate(0, rmControlsHookActivate);
if (!pvControlsHookHandle)
pvControlsHookHandle = GfuiHookCreate(0, rmControlsHookActivate);
return pvControlsHookHandle;
return pvControlsHookHandle;
}
#if SDL_FORCEFEEDBACK
@ -174,29 +174,29 @@ rmControlsHookInit()
static void
rmForceFeedbackConfigHookActivate(void * /* dummy */)
{
void *prHandle;
char buf[100];
const char *str;
tGearChangeMode gearChangeMode;
void *prHandle;
char buf[100];
const char *str;
tGearChangeMode gearChangeMode;
sprintf(buf, "%s%s", GfLocalDir(), HM_PREF_FILE);
prHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
sprintf(buf, "%s%s", GfLocalDir(), HM_PREF_FILE);
prHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
snprintf(buf, sizeof(buf), "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, curPlayerIdx);
snprintf(buf, sizeof(buf), "%s/%s/%d", HM_SECT_PREF, HM_LIST_DRV, curPlayerIdx);
std::string carName = "";
//Find human cars
tRmInfo* pCurrReInfo = LmRaceEngine().inData();
for (int i = 0; i < pCurrReInfo->s->_ncars; i++) {
if(pCurrReInfo->s->cars[i]->_driverType == RM_DRV_HUMAN){
carName.append(pCurrReInfo->s->cars[i]->_carName);
}
}
std::string carName = "";
//Find human cars
tRmInfo* pCurrReInfo = LmRaceEngine().inData();
for (int i = 0; i < pCurrReInfo->s->_ncars; i++) {
if(pCurrReInfo->s->cars[i]->_driverType == RM_DRV_HUMAN){
carName.append(pCurrReInfo->s->cars[i]->_carName);
}
}
GfuiScreenActivate(ForceFeedbackMenuInit(hscreen, prHandle, curPlayerIdx, carName));
GfuiScreenActivate(ForceFeedbackMenuInit(hscreen, prHandle, curPlayerIdx, carName));
}
static void *pvForceFeedbackConfigHookHandle = 0;
@ -204,10 +204,10 @@ static void *pvForceFeedbackConfigHookHandle = 0;
static void *
rmForceFeedbackConfigHookInit()
{
if (!pvForceFeedbackConfigHookHandle)
pvForceFeedbackConfigHookHandle = GfuiHookCreate(0, rmForceFeedbackConfigHookActivate);
if (!pvForceFeedbackConfigHookHandle)
pvForceFeedbackConfigHookHandle = GfuiHookCreate(0, rmForceFeedbackConfigHookActivate);
return pvForceFeedbackConfigHookHandle;
return pvForceFeedbackConfigHookHandle;
}
#endif
@ -217,8 +217,8 @@ static void *rmStopScrHandle = 0;
static void
rmQuitHookActivate(void * /* dummy */)
{
if (rmStopScrHandle)
GfuiScreenActivate(ExitMenuInit(rmStopScrHandle));
if (rmStopScrHandle)
GfuiScreenActivate(ExitMenuInit(rmStopScrHandle));
}
static void *pvQuitHookHandle = 0;
@ -226,10 +226,10 @@ static void *pvQuitHookHandle = 0;
static void *
rmQuitHookInit()
{
if (!pvQuitHookHandle)
pvQuitHookHandle = GfuiHookCreate(0, rmQuitHookActivate);
if (!pvQuitHookHandle)
pvQuitHookHandle = GfuiHookCreate(0, rmQuitHookActivate);
return pvQuitHookHandle;
return pvQuitHookHandle;
}
// 2, 3, 4 or 5 buttons "Stop race" menu *******************************
@ -238,7 +238,7 @@ static void *QuitHdle[6] = { 0, 0, 0, 0, 0, 0 };
// Descriptor for 1 button.
typedef struct {
const char* role; // Button role.
void *screen; // Screen to activate if clicked.
@ -258,37 +258,37 @@ rmStopRaceMenu(const tButtonDesc aButtons[], int nButtons, int nCancelIndex)
// Create buttons from menu properties and button template.
const int xpos = (int)GfuiMenuGetNumProperty(hmenu, "xButton", 270);
const int dy = (int)GfuiMenuGetNumProperty(hmenu, "buttonShift", 30);
int ypos = (int)GfuiMenuGetNumProperty(hmenu, "yTopButton", 380);
char pszPropName[64];
const char* pszCancelTip = "";
int ypos = (int)GfuiMenuGetNumProperty(hmenu, "yTopButton", 380);
char pszPropName[64];
const char* pszCancelTip = "";
for (int nButInd = 0; nButInd < nButtons; nButInd++)
{
// Get text and tip from button role and menu properties.
sprintf(pszPropName, "%s.text", aButtons[nButInd].role);
const char* pszText = GfuiMenuGetStrProperty(hmenu, pszPropName, "");
sprintf(pszPropName, "%s.tip", aButtons[nButInd].role);
const char* pszTip = GfuiMenuGetStrProperty(hmenu, pszPropName, "");
if (nButInd == nCancelIndex)
pszCancelTip = pszTip;
// Create the button from the template.
GfuiMenuCreateTextButtonControl(hscreen, hmenu, "button",
aButtons[nButInd].screen, GfuiScreenActivate, 0, 0, 0,
true, // From template.
pszText, pszTip, xpos, ypos);
// Get text and tip from button role and menu properties.
sprintf(pszPropName, "%s.text", aButtons[nButInd].role);
const char* pszText = GfuiMenuGetStrProperty(hmenu, pszPropName, "");
sprintf(pszPropName, "%s.tip", aButtons[nButInd].role);
const char* pszTip = GfuiMenuGetStrProperty(hmenu, pszPropName, "");
if (nButInd == nCancelIndex)
pszCancelTip = pszTip;
// Next button if not last.
ypos -= dy;
// Create the button from the template.
GfuiMenuCreateTextButtonControl(hscreen, hmenu, "button",
aButtons[nButInd].screen, GfuiScreenActivate, 0, 0, 0,
true, // From template.
pszText, pszTip, xpos, ypos);
// Next button if not last.
ypos -= dy;
}
// Register keyboard shortcuts.
GfuiMenuDefaultKeysAdd(hscreen);
GfuiAddKey(hscreen, GFUIK_ESCAPE, pszCancelTip,
aButtons[nCancelIndex].screen, GfuiScreenActivate, NULL);
aButtons[nCancelIndex].screen, GfuiScreenActivate, NULL);
// Close menu XML descriptor.
GfParmReleaseHandle(hmenu);
// Activate the created screen.
GfuiScreenActivate(hscreen);
@ -298,12 +298,12 @@ rmStopRaceMenu(const tButtonDesc aButtons[], int nButtons, int nCancelIndex)
// Simpler front-end function for creating and activating the menu.
static void*
rmStopRaceMenu(const char *buttonRole1, void *screen1,
const char *buttonRole2, void *screen2,
const char *buttonRole3 = 0, void *screen3 = 0,
const char *buttonRole4 = 0, void *screen4 = 0,
const char *buttonRole5 = 0, void *screen5 = 0,
const char *buttonRole6 = 0, void *screen6 = 0,
const char *buttonRole7 = 0, void *screen7 = 0)
const char *buttonRole2, void *screen2,
const char *buttonRole3 = 0, void *screen3 = 0,
const char *buttonRole4 = 0, void *screen4 = 0,
const char *buttonRole5 = 0, void *screen5 = 0,
const char *buttonRole6 = 0, void *screen6 = 0,
const char *buttonRole7 = 0, void *screen7 = 0)
{
const tButtonDesc aButtons[7] =
{
@ -315,147 +315,149 @@ rmStopRaceMenu(const char *buttonRole1, void *screen1,
{ buttonRole6, screen6 },
{ buttonRole7, screen7 }
};
int nButtons = 2;
if (buttonRole3 && screen3)
{
nButtons++;
if (buttonRole4 && screen4)
{
nButtons++;
if (buttonRole5 && screen5)
{
nButtons++;
if (buttonRole6 && screen6)
nButtons++;
if (buttonRole7 && screen7)
nButtons++;
}
}
}
if (buttonRole3 && screen3)
{
nButtons++;
if (buttonRole4 && screen4)
{
nButtons++;
if (buttonRole5 && screen5)
{
nButtons++;
if (buttonRole6 && screen6)
{
nButtons++;
if (buttonRole7 && screen7)
nButtons++;
}
}
}
}
if (QuitHdle[nButtons-1])
GfuiScreenRelease(QuitHdle[nButtons-1]);
QuitHdle[nButtons-1] = rmStopRaceMenu(aButtons, nButtons, nButtons-1);
return QuitHdle[nButtons-1];
}
void
RmStopRaceMenu()
{
void* params = LmRaceEngine().outData()->params;
const char* pszRaceName = LmRaceEngine().outData()->_reRaceName;
void* params = LmRaceEngine().outData()->params;
const char* pszRaceName = LmRaceEngine().outData()->_reRaceName;
const char *buttonRole[7];
void *screen[7];
int i;
const char *buttonRole[7];
void *screen[7];
int i;
#if 1
int j;
void *grHandle;
void *hdHandle;
char buf[100];
const char *cur_name;
const char *test_name;
int j;
void *grHandle;
void *hdHandle;
char buf[100];
const char *cur_name;
const char *test_name;
sprintf(buf, "%s%s", GfLocalDir(), GR_PARAM_FILE);
grHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
sprintf(buf, "%s%s", GfLocalDir(), GR_PARAM_FILE);
grHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
sprintf(buf, "%s%s", GfLocalDir(), HM_DRV_FILE);
hdHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
sprintf(buf, "%s%s", GfLocalDir(), HM_DRV_FILE);
hdHandle = GfParmReadFile(buf, GFPARM_RMODE_REREAD);
#endif
// Mute sound.
if (LegacyMenu::self().soundEngine())
LegacyMenu::self().soundEngine()->mute();
// Mute sound.
if (LegacyMenu::self().soundEngine())
LegacyMenu::self().soundEngine()->mute();
for(i=0; i < 7; i++) {
buttonRole[i] = "";
screen[i] = NULL;
}
for(i=0; i < 7; i++) {
buttonRole[i] = "";
screen[i] = NULL;
}
// Build list of options
i = 0;
buttonRole[i] = "resume";
screen[i++] = RmBackToRaceHookInit();
// Build list of options
i = 0;
buttonRole[i] = "resume";
screen[i++] = RmBackToRaceHookInit();
if (strcmp(GfParmGetStr(params, pszRaceName, RM_ATTR_MUST_COMPLETE, RM_VAL_YES), RM_VAL_YES))
{
buttonRole[i] = "skip";
screen[i++] = rmSkipSessionHookInit();
}
if (strcmp(GfParmGetStr(params, pszRaceName, RM_ATTR_MUST_COMPLETE, RM_VAL_YES), RM_VAL_YES))
{
buttonRole[i] = "skip";
screen[i++] = rmSkipSessionHookInit();
}
if (strcmp(GfParmGetStr(params, pszRaceName, RM_ATTR_ALLOW_RESTART, RM_VAL_NO), RM_VAL_NO))
{
buttonRole[i] = "restart";
screen[i++] = rmRestartRaceHookInit();
}
if (strcmp(GfParmGetStr(params, pszRaceName, RM_ATTR_ALLOW_RESTART, RM_VAL_NO), RM_VAL_NO))
{
buttonRole[i] = "restart";
screen[i++] = rmRestartRaceHookInit();
}
buttonRole[i] = "abort";
screen[i++] = rmAbortRaceHookInit();
buttonRole[i] = "abort";
screen[i++] = rmAbortRaceHookInit();
#if 1
// get current driver
j = (int)GfParmGetNum(grHandle, GR_SCT_DISPMODE, GR_ATT_CUR_SCREEN, NULL, 0.0);
snprintf(buf, sizeof(buf), "%s/%d", GR_SCT_DISPMODE, j);
cur_name = GfParmGetStr(grHandle, buf, GR_ATT_CUR_DRV, "not found");
GfLogInfo("Current driver (on active split screen) is '%s'\n", cur_name);
// get current driver
j = (int)GfParmGetNum(grHandle, GR_SCT_DISPMODE, GR_ATT_CUR_SCREEN, NULL, 0.0);
snprintf(buf, sizeof(buf), "%s/%d", GR_SCT_DISPMODE, j);
cur_name = GfParmGetStr(grHandle, buf, GR_ATT_CUR_DRV, "not found");
GfLogInfo("Current driver (on active split screen) is '%s'\n", cur_name);
// Attempt to find a human driver
for (j=0; ; j++) {
snprintf(buf, sizeof(buf), "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, j+1);
test_name = GfParmGetStr(hdHandle, buf, ROB_ATTR_NAME, "");
// Attempt to find a human driver
for (j=0; ; j++) {
snprintf(buf, sizeof(buf), "%s/%s/%d", ROB_SECT_ROBOTS, ROB_LIST_INDEX, j+1);
test_name = GfParmGetStr(hdHandle, buf, ROB_ATTR_NAME, "");
if (strlen(test_name) == 0) break;
if (strlen(test_name) == 0) break;
if (strcmp(cur_name, test_name) == 0) {
GfLogInfo("Matching human driver found, setting index to %d.\n", j+1);
curPlayerIdx = j+1;
buttonRole[i] = "controls";
screen[i++] = rmControlsHookInit();
if (strcmp(cur_name, test_name) == 0) {
GfLogInfo("Matching human driver found, setting index to %d.\n", j+1);
curPlayerIdx = j+1;
buttonRole[i] = "controls";
screen[i++] = rmControlsHookInit();
#if SDL_FORCEFEEDBACK
buttonRole[i] = "forcefeedback";
screen[i++] = rmForceFeedbackConfigHookInit();
break;
buttonRole[i] = "forcefeedback";
screen[i++] = rmForceFeedbackConfigHookInit();
break;
#endif
}
}
}
}
#endif
buttonRole[i] = "quit";
screen[i++] = rmQuitHookInit();
buttonRole[i] = "quit";
screen[i++] = rmQuitHookInit();
rmStopScrHandle = rmStopRaceMenu(buttonRole[0], screen[0],
buttonRole[1], screen[1],
buttonRole[2], screen[2],
buttonRole[3], screen[3],
buttonRole[4], screen[4],
buttonRole[5], screen[5],
buttonRole[6], screen[6]);
rmStopScrHandle = rmStopRaceMenu(buttonRole[0], screen[0],
buttonRole[1], screen[1],
buttonRole[2], screen[2],
buttonRole[3], screen[3],
buttonRole[4], screen[4],
buttonRole[5], screen[5],
buttonRole[6], screen[6]);
}
void
RmStopRaceMenuShutdown()
{
GfuiHookRelease(pvAbortRaceHookHandle);
pvAbortRaceHookHandle = 0;
GfuiHookRelease(pvSkipSessionHookHandle);
pvSkipSessionHookHandle = 0;
GfuiHookRelease(pvBackToRaceHookHandle);
pvBackToRaceHookHandle = 0;
GfuiHookRelease(pvRestartRaceHookHandle);
pvRestartRaceHookHandle = 0;
GfuiHookRelease(pvControlsHookHandle);
pvControlsHookHandle = 0;
GfuiHookRelease(pvAbortRaceHookHandle);
pvAbortRaceHookHandle = 0;
GfuiHookRelease(pvQuitHookHandle);
pvQuitHookHandle = 0;
GfuiHookRelease(pvSkipSessionHookHandle);
pvSkipSessionHookHandle = 0;
GfuiHookRelease(pvBackToRaceHookHandle);
pvBackToRaceHookHandle = 0;
GfuiHookRelease(pvRestartRaceHookHandle);
pvRestartRaceHookHandle = 0;
GfuiHookRelease(pvControlsHookHandle);
pvControlsHookHandle = 0;
GfuiHookRelease(pvQuitHookHandle);
pvQuitHookHandle = 0;
}