2001-03-01 20:42:09 +01:00
/*********************/
2001-03-05 21:49:46 +01:00
/*** Elem Stuph ***/
2001-03-01 20:42:09 +01:00
/*********************/
# include "stdafx.h"
# include <Vector3.h>
# include <gl\gl.h>
# include <gl\glu.h>
2001-03-22 21:49:58 +01:00
# include "GLEnabledView.h"
2001-03-01 20:42:09 +01:00
# include <Vector>
# include <GFName.hpp>
# include "Core.h"
# include "TexCache.h"
2001-03-05 21:49:46 +01:00
# include "Elem.h"
2001-03-01 20:42:09 +01:00
# include "GinTex.h"
# include "utils.h"
2001-03-22 21:49:58 +01:00
# include "MapEdit.h"
# include "MapEditDoc.h"
# include "MapEditView.h"
# include "MainFrm.h"
2001-03-01 20:42:09 +01:00
2001-03-22 21:49:58 +01:00
# include "GUITileBank.h"
const Vector3 DefOfs ( + 0.5f , 0 , + 4.0f ) ;
2001-03-27 18:26:43 +02:00
int CElem : : BlankID = - 1 ;
int CElem : : InvalidID = - 1 ;
bool CElem : : DefTexFlag = false ;
2001-03-22 21:49:58 +01:00
/*****************************************************************************/
// All Elems MUST run from 0,0 ->
/*****************************************************************************/
const float ElemBrowserGap = 0.2f ;
const float ElemBrowserX0 = 0 - ElemBrowserGap / 2 ;
const float ElemBrowserX1 = 1 + ElemBrowserGap / 2 ;
const float ElemBrowserY0 = 0 - ElemBrowserGap / 2 ;
const float ElemBrowserY1 = 1 + ElemBrowserGap / 2 ;
2001-03-01 20:42:09 +01:00
/*****************************************************************************/
const float XFlipMtx [ ] =
{
- 1 , 0 , 0 , 0 ,
0 , 1 , 0 , 0 ,
0 , 0 , 1 , 0 ,
0 , 0 , 0 , 1 ,
} ;
const float YFlipMtx [ ] =
{
1 , 0 , 0 , 0 ,
0 , - 1 , 0 , 0 ,
0 , 0 , 1 , 0 ,
0 , 0 , 0 , 1 ,
} ;
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
CElem : : CElem ( int Width , int Height )
2001-03-01 20:42:09 +01:00
{
2001-03-05 21:49:46 +01:00
ElemWidth = Width ;
ElemHeight = Height ;
UnitWidth = ElemWidth / UnitSize ;
UnitHeight = ElemHeight / UnitSize ;
ElemID = - 1 ;
2001-03-31 03:30:53 +02:00
int AW = AlignSize ( ElemWidth ) ;
int AH = AlignSize ( ElemHeight ) ;
2001-04-07 23:05:33 +02:00
ElemRGB = 0 ;
2001-03-31 03:30:53 +02:00
ElemRGB = ( u8 * ) MemAlloc ( AW * AH * 3 ) ;
memset ( ElemRGB , 0 , AW * AH * 3 ) ;
2001-03-05 21:49:46 +01:00
Type = ElemType2d ;
TexXOfs = 0 ;
TexYOfs = 0 ;
2001-04-07 23:05:33 +02:00
BlankFlag = true ;
2001-03-01 20:42:09 +01:00
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
// 3d Elem (From Gin File)
CElem : : CElem ( CCore * Core , const char * Filename , CScene & ThisScene , int Node )
2001-03-01 20:42:09 +01:00
{
CNode & ThisNode = ThisScene . GetNode ( Node ) ;
CTexCache & TexCache = Core - > GetTexCache ( ) ;
GFName Path = Filename ;
SetPath = Path . Drive ( ) ;
SetPath + = Path . Dir ( ) ;
SetPath . Append ( ' \\ ' ) ;
2001-03-05 21:49:46 +01:00
Type = ElemType3d ;
2001-03-01 20:42:09 +01:00
TexXOfs = - 1 ;
TexYOfs = - 1 ;
2001-04-07 23:05:33 +02:00
ElemRGB = 0 ;
2001-03-22 21:49:58 +01:00
Ofs . Zero ( ) ;
2001-03-05 21:49:46 +01:00
Build3dElem ( TexCache , ThisScene , Node ) ;
Calc3dSize ( ) ;
Build3dDrawList ( TexCache , DrawList [ ElemType3d ] ) ;
2001-03-22 21:49:58 +01:00
Ofs . Zero ( ) ;
2001-03-01 20:42:09 +01:00
Create2dTexture ( TexCache , Path . File ( ) , Node ) ;
2001-03-05 21:49:46 +01:00
Build2dDrawList ( TexCache , DrawList [ ElemType2d ] ) ;
2001-04-07 23:05:33 +02:00
BlankFlag = false ;
2001-05-02 20:40:41 +02:00
// if (!ValidFlag) SetInvalid();
2001-03-01 20:42:09 +01:00
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
// 2d Elem (From Bmp File)
2001-03-31 17:40:20 +02:00
// 0,0 1,0 1,1 0,1
CElem : : CElem ( CCore * Core , const char * Filename , int TexID , int XOfs , int YOfs , int Width , int Height , int CentreMode )
2001-03-01 20:42:09 +01:00
{
CTexCache & TexCache = Core - > GetTexCache ( ) ;
GFName Path = Filename ;
2001-03-05 21:49:46 +01:00
ElemWidth = Width ;
ElemHeight = Height ;
UnitWidth = ElemWidth / UnitSize ;
UnitHeight = ElemHeight / UnitSize ;
2001-04-07 23:05:33 +02:00
ElemRGB = 0 ;
2001-03-05 21:49:46 +01:00
Type = ElemType2d ;
2001-03-01 20:42:09 +01:00
TexXOfs = XOfs ;
TexYOfs = YOfs ;
Ofs . Zero ( ) ;
2001-03-31 17:40:20 +02:00
if ( CentreMode & CentreModeL )
{
// Nothing to do, already there
}
if ( CentreMode & CentreModeR )
{
Ofs . x - = UnitWidth ;
}
if ( CentreMode & CentreModeT )
{
Ofs . y - = UnitHeight ;
}
if ( CentreMode & CentreModeB )
{
// Nothing to do, already there
}
if ( CentreMode & CentreModeLR )
{
Ofs . x - = ( UnitWidth - 1.0f ) / 2 ;
}
if ( CentreMode & CentreModeTB )
2001-03-22 21:49:58 +01:00
{
2001-03-31 17:40:20 +02:00
Ofs . y - = ( UnitHeight - 1.0f ) / 2 ;
2001-03-22 21:49:58 +01:00
}
Build2dElem ( Core , Path . File ( ) , TexID ) ;
2001-03-05 21:49:46 +01:00
Build3dDrawList ( TexCache , DrawList [ ElemType3d ] ) ;
2001-03-01 20:42:09 +01:00
Create2dTexture ( TexCache , Path . File ( ) , TexID ) ;
2001-03-05 21:49:46 +01:00
Build2dDrawList ( TexCache , DrawList [ ElemType2d ] ) ;
2001-04-07 23:05:33 +02:00
BlankFlag = false ;
if ( ! ValidFlag ) SetInvalid ( ) ;
2001-03-01 20:42:09 +01:00
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
void CElem : : CleanUp ( )
{
2001-04-07 23:05:33 +02:00
if ( ElemRGB ) MemFree ( ElemRGB ) ;
ElemRGB = 0 ;
}
/*****************************************************************************/
void CElem : : SetBlank ( )
{
for ( int i = 0 ; i < ElemTypeMax ; i + + ) DrawList [ i ] = BlankID ;
}
/*****************************************************************************/
void CElem : : SetInvalid ( )
{
Purge ( ) ; // Clear whatever is already there
for ( int i = 0 ; i < ElemTypeMax ; i + + ) DrawList [ i ] = InvalidID ;
2001-03-05 21:49:46 +01:00
}
/*****************************************************************************/
void CElem : : Build2dElem ( CCore * Core , const char * Filename , int TexID )
2001-03-01 20:42:09 +01:00
{
2001-03-22 21:49:58 +01:00
float X0 = 0 ;
float X1 = + UnitWidth ;
float Y0 = 0 ;
float Y1 = + UnitHeight ;
Vector3 P0 ( X0 , Y0 , 0 ) ;
Vector3 P1 ( X1 , Y0 , 0 ) ;
Vector3 P2 ( X0 , Y1 , 0 ) ;
Vector3 P3 ( X1 , Y1 , 0 ) ;
2001-03-01 20:42:09 +01:00
int ListSize = TriList . size ( ) ;
TriList . resize ( ListSize + 2 ) ;
sTriFace & Tri0 = TriList [ ListSize + 0 ] ;
sTriFace & Tri1 = TriList [ ListSize + 1 ] ;
CTexCache & TexCache = Core - > GetTexCache ( ) ;
sTex & ThisTex = TexCache . GetTex ( TexID ) ;
2001-03-31 03:30:53 +02:00
int CountW = ThisTex . OldW / ElemWidth ;
int CountH = ThisTex . OldH / ElemHeight ;
float dU = ThisTex . ScaleU / ( float ) CountW ;
float dV = ThisTex . ScaleV / ( float ) CountH ;
dU = ( 1.0f / CountW ) ;
dV = ( 1.0f / CountH ) ;
// dU=ThisTex.ScaleU;
// dV=ThisTex.ScaleV;
2001-03-01 20:42:09 +01:00
2001-03-22 21:49:58 +01:00
float u0 = ( TexXOfs * dU ) ;
float u1 = u0 + dU ;
float v1 = 1.0 - ( TexYOfs * dV ) ;
float v0 = v1 - dV ;
2001-03-01 20:42:09 +01:00
Tri0 . Mat = TexID ;
Tri0 . vtx [ 0 ] = P0 ;
Tri0 . vtx [ 1 ] = P1 ;
Tri0 . vtx [ 2 ] = P2 ;
Tri0 . uvs [ 0 ] . u = u0 ; Tri0 . uvs [ 0 ] . v = v0 ;
Tri0 . uvs [ 1 ] . u = u1 ; Tri0 . uvs [ 1 ] . v = v0 ;
Tri0 . uvs [ 2 ] . u = u0 ; Tri0 . uvs [ 2 ] . v = v1 ;
Tri1 . Mat = TexID ;
Tri1 . vtx [ 0 ] = P1 ;
Tri1 . vtx [ 1 ] = P2 ;
Tri1 . vtx [ 2 ] = P3 ;
Tri1 . uvs [ 0 ] . u = u1 ; Tri1 . uvs [ 0 ] . v = v0 ;
Tri1 . uvs [ 1 ] . u = u0 ; Tri1 . uvs [ 1 ] . v = v1 ;
Tri1 . uvs [ 2 ] . u = u1 ; Tri1 . uvs [ 2 ] . v = v1 ;
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
void CElem : : Build3dElem ( CTexCache & TexCache , CScene & ThisScene , int Node )
2001-03-01 20:42:09 +01:00
{
CNode & ThisNode = ThisScene . GetNode ( Node ) ;
2001-03-22 21:49:58 +01:00
CNode & ParentNode = ThisScene . GetNode ( ThisNode . ParentIdx ) ;
int ChildCount = ThisNode . GetPruneChildCount ( ) ;
2001-03-01 20:42:09 +01:00
std : : vector < sGinTri > const & NodeTriList = ThisNode . GetTris ( ) ;
2001-03-22 21:49:58 +01:00
std : : vector < Vector3 > const & NodeVtxList = ThisNode . GetPts ( ) ;
2001-03-01 20:42:09 +01:00
std : : vector < sUVTri > const & NodeUVList = ThisNode . GetUVTris ( ) ;
std : : vector < int > const & NodeTriMat = ThisNode . GetTriMaterial ( ) ;
2001-03-22 21:49:58 +01:00
std : : vector < GString > const & SceneTexList = ThisScene . GetTexList ( ) ;
std : : vector < int > const & SceneUsedMatList = ThisScene . GetUsedMaterialIdx ( ) ;
2001-05-02 20:40:41 +02:00
std : : vector < Material > const & SceneMatList = ThisScene . GetMaterials ( ) ;
2001-03-26 23:29:09 +02:00
int TexCount = SceneTexList . size ( ) ;
2001-03-01 20:42:09 +01:00
int TriCount = NodeTriList . size ( ) ;
int ListSize = TriList . size ( ) ;
TriList . resize ( ListSize + TriCount ) ;
for ( int T = 0 ; T < TriCount ; T + + )
{
sGinTri const & ThisTri = NodeTriList [ T ] ;
sUVTri const & ThisUV = NodeUVList [ T ] ;
sTriFace & Tri = TriList [ ListSize + T ] ;
int ThisMat = NodeTriMat [ T ] ;
2001-05-02 20:40:41 +02:00
int TexID , TexFlags ;
2001-03-01 20:42:09 +01:00
2001-03-26 23:29:09 +02:00
// Sort Textures - Only add the ones that are used :o)
2001-03-22 21:49:58 +01:00
TexID = SceneUsedMatList [ ThisMat ] ;
2001-03-26 23:29:09 +02:00
if ( TexID < 0 | | TexID > = TexCount )
{
CString mexstr ;
2001-03-31 03:30:53 +02:00
mexstr . Format ( " Invalid TexId \n Wanted %i only have %i Id's for %s \n This is gonna hurt! \n Dont ask me about this error, ask Kev. \n This MUST be fixed. " , TexID , TexCount - 1 , ThisNode . Name ) ;
2001-03-26 23:29:09 +02:00
AfxMessageBox ( mexstr , MB_OK | MB_ICONEXCLAMATION ) ;
TexID = 0 ;
}
2001-05-02 20:40:41 +02:00
// else
2001-03-26 23:29:09 +02:00
{
2001-05-02 20:40:41 +02:00
TexFlags = SceneMatList [ TexID ] . Flags ;
2001-03-26 23:29:09 +02:00
GString ThisName ;
GString TexName = SceneTexList [ TexID ] ;
2001-05-02 20:40:41 +02:00
2001-03-26 23:29:09 +02:00
ThisName = SetPath + TexName ;
2001-05-05 23:18:12 +02:00
// TRACE2("%i !%s!\n",TexID,ThisName);
2001-03-26 23:29:09 +02:00
TexID = TexCache . ProcessTexture ( ThisName ) ;
}
2001-03-05 21:49:46 +01:00
// Sort Rest of Tri info
2001-03-22 21:49:58 +01:00
Matrix4x4 TransMtx ;
TransMtx . Identity ( ) ;
if ( ParentNode . GetTris ( ) . size ( ) | | ! ThisNode . ParentIdx )
{
TransMtx = ThisNode . Mtx ;
TransMtx . Invert ( ) ;
}
2001-03-01 20:42:09 +01:00
for ( int p = 0 ; p < 3 ; p + + )
{
2001-03-22 21:49:58 +01:00
Tri . vtx [ p ] = TransMtx * NodeVtxList [ ThisTri . p [ p ] ] ;
2001-03-01 20:42:09 +01:00
Tri . uvs [ p ] . u = ThisUV . p [ p ] . u ;
Tri . uvs [ p ] . v = ThisUV . p [ p ] . v ;
Tri . Mat = TexID ;
2001-05-02 20:40:41 +02:00
Tri . Flags = TexFlags ;
2001-03-01 20:42:09 +01:00
}
}
2001-03-05 21:49:46 +01:00
for ( int Child = 0 ; Child < ChildCount ; Child + + ) Build3dElem ( TexCache , ThisScene , ThisNode . PruneChildList [ Child ] ) ;
2001-03-01 20:42:09 +01:00
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
void CElem : : Calc3dSize ( )
{
2001-03-22 21:49:58 +01:00
int i , ListSize = TriList . size ( ) ;
Vector3 Min ( + 32000 , + 32000 , + 32000 ) ;
Vector3 Max ( - 32000 , - 32000 , - 32000 ) ;
Vector3 Mid ;
2001-03-05 21:49:46 +01:00
2001-03-22 21:49:58 +01:00
for ( i = 0 ; i < ListSize ; i + + )
2001-03-05 21:49:46 +01:00
{
sTriFace & Tri = TriList [ i ] ;
for ( int p = 0 ; p < 3 ; p + + )
{
2001-03-22 21:49:58 +01:00
if ( Min . x > Tri . vtx [ p ] . x ) Min . x = Tri . vtx [ p ] . x ;
if ( Min . y > Tri . vtx [ p ] . y ) Min . y = Tri . vtx [ p ] . y ;
if ( Min . z > Tri . vtx [ p ] . z ) Min . z = Tri . vtx [ p ] . z ;
if ( Max . x < Tri . vtx [ p ] . x ) Max . x = Tri . vtx [ p ] . x ;
if ( Max . y < Tri . vtx [ p ] . y ) Max . y = Tri . vtx [ p ] . y ;
if ( Max . z < Tri . vtx [ p ] . z ) Max . z = Tri . vtx [ p ] . z ;
2001-03-05 21:49:46 +01:00
}
}
2001-03-22 21:49:58 +01:00
UnitWidth = round ( Max . x - Min . x ) ;
UnitHeight = round ( Max . y - Min . y ) ;
2001-03-05 21:49:46 +01:00
if ( UnitWidth < 1 ) UnitWidth = 1 ;
if ( UnitHeight < 1 ) UnitHeight = 1 ;
ElemWidth = UnitWidth * UnitSize ;
ElemHeight = UnitHeight * UnitSize ;
2001-03-22 21:49:58 +01:00
Min . z = 0 ;
Ofs = DefOfs ;
// Ofs.x=+0.5f; Ofs.y=0; Ofs.z=+4.0f;
2001-03-05 21:49:46 +01:00
}
/*****************************************************************************/
void CElem : : Build2dDrawList ( CTexCache & TexCache , GLint & List )
2001-03-01 20:42:09 +01:00
{
2001-03-22 21:49:58 +01:00
float X0 = Ofs . x ;
float X1 = Ofs . x + UnitWidth ;
float Y0 = Ofs . y ;
float Y1 = Ofs . y + UnitHeight ;
float Z = Ofs . z ;
2001-03-31 03:30:53 +02:00
sTex & Tex = TexCache . GetTex ( ElemID ) ;
float u0 = 0 ;
float u1 = 1.0f ; //Tex.ScaleU;
float v0 = 0 ;
float v1 = 1.0f ; //Tex.ScaleU;
2001-03-22 21:49:58 +01:00
2001-03-01 20:42:09 +01:00
List = glGenLists ( 1 ) ;
glNewList ( List , GL_COMPILE ) ;
2001-04-30 23:49:54 +02:00
TexID = Tex . TexID ;
2001-03-31 03:30:53 +02:00
glBindTexture ( GL_TEXTURE_2D , Tex . TexID ) ;
2001-03-01 20:42:09 +01:00
glBegin ( GL_QUADS ) ;
2001-03-31 03:30:53 +02:00
glTexCoord2f ( u0 , v0 ) ;
2001-03-22 21:49:58 +01:00
glVertex3f ( X0 , Y0 , Z ) ;
2001-03-01 20:42:09 +01:00
2001-03-31 03:30:53 +02:00
glTexCoord2f ( u1 , v0 ) ;
2001-03-22 21:49:58 +01:00
glVertex3f ( X1 , Y0 , Z ) ;
2001-03-01 20:42:09 +01:00
2001-03-31 03:30:53 +02:00
glTexCoord2f ( u1 , v1 ) ;
2001-03-22 21:49:58 +01:00
glVertex3f ( X1 , Y1 , Z ) ;
2001-03-01 20:42:09 +01:00
2001-03-31 03:30:53 +02:00
glTexCoord2f ( u0 , v1 ) ;
2001-03-22 21:49:58 +01:00
glVertex3f ( X0 , Y1 , Z ) ;
2001-03-01 20:42:09 +01:00
glEnd ( ) ;
glEndList ( ) ;
}
/*****************************************************************************/
// Build OpenGL display lists, sorted by material (luckily by gin!!)
2001-03-05 21:49:46 +01:00
void CElem : : Build3dDrawList ( CTexCache & TexCache , GLint & List )
2001-03-01 20:42:09 +01:00
{
int TriCount = TriList . size ( ) ;
int LastMat = - 1 , ThisMat ;
2001-03-22 21:49:58 +01:00
float ScaleU , ScaleV ;
2001-03-01 20:42:09 +01:00
List = glGenLists ( 1 ) ;
glNewList ( List , GL_COMPILE ) ;
for ( int T = 0 ; T < TriCount ; T + + )
{
sTriFace & ThisTri = TriList [ T ] ;
ThisMat = ThisTri . Mat ;
if ( ! T | | ThisMat ! = LastMat ) // First Tri or new material
2001-03-22 21:49:58 +01:00
{
2001-03-01 20:42:09 +01:00
if ( T ) glEnd ( ) ; // Not first tri, so end previous mat set
glBindTexture ( GL_TEXTURE_2D , TexCache . GetTexGLId ( ThisMat ) ) ;
glBegin ( GL_TRIANGLES ) ;
LastMat = ThisMat ;
2001-03-22 21:49:58 +01:00
sTex & Tex = TexCache . GetTex ( ThisMat ) ;
2001-03-31 03:30:53 +02:00
ScaleU = Tex . ScaleU ;
ScaleV = Tex . ScaleV ;
2001-03-22 21:49:58 +01:00
}
2001-03-01 20:42:09 +01:00
for ( int p = 0 ; p < 3 ; p + + )
{
Vector3 & ThisVtx = ThisTri . vtx [ p ] ;
2001-03-22 21:49:58 +01:00
float u = ThisTri . uvs [ p ] . u * ScaleU ;
float v = ThisTri . uvs [ p ] . v * ScaleV ;
glTexCoord2f ( u , v ) ;
2001-03-01 20:42:09 +01:00
glVertex3f ( ( ThisVtx . x + Ofs . x ) , ( ThisVtx . y + Ofs . y ) , - ( ThisVtx . z + Ofs . z ) ) ; // Neg Z (cos openGL)
}
}
glEnd ( ) ;
glEndList ( ) ;
}
/*****************************************************************************/
2001-05-30 19:02:54 +02:00
struct sColTab
{
u8 R , G , B ;
} ;
sColTab ColTable [ ] =
{
{ 255 , 255 , 255 } , // PC_TILE_COLLISION_NORMAL:
{ 255 , 0 , 0 } , // PC_TILE_COLLISION_DAMAGE:
{ 0 , 255 , 0 } , // PC_TILE_COLLISION_SLIPPERY:
{ 255 , 0 , 255 } , // PC_TILE_COLLISION_ELECTRIC:
{ 200 , 127 , 180 } , // PC_TILE_COLLISION_DESTRUCTABLE_WALL:
2001-05-31 16:00:48 +02:00
{ 0 , 127 , 255 } , // PC_TILE_COLLISION_SOAK_UP:
2001-05-30 19:02:54 +02:00
{ 0 , 255 , 255 } , // PC_TILE_COLLISION_SOLID:
{ 200 , 0 , 0 } , // PC_TILE_COLLISION_DEATH_FALL:
{ 127 , 200 , 180 } , // PC_TILE_COLLISION_DESTRUCTABLE_FLOOR:
{ 255 , 127 , 127 } , // PC_TILE_COLLISION_DEATH_INSTANT:
{ 0 , 127 , 0 } , // PC_TILE_COLLISION_MOVE_LEFT:
{ 0 , 127 , 127 } , // PC_TILE_COLLISION_MOVE_RIGHT:
2001-05-31 16:00:48 +02:00
{ 0 , 0 , 255 } , // PC_TILE_COLLISION_DEATH_LIQUID:
2001-05-30 19:02:54 +02:00
2001-07-05 23:17:31 +02:00
{ 255 , 127 , 0 } , // PC_TILE_COLLISION_SB_NOMOVE
2001-05-30 19:02:54 +02:00
} ;
2001-03-05 21:49:46 +01:00
void CElem : : Render ( int Flags , bool Render3d )
2001-03-01 20:42:09 +01:00
{
2001-04-07 23:05:33 +02:00
if ( BlankFlag )
{
glCallList ( BlankID ) ;
return ;
}
2001-03-01 20:42:09 +01:00
glPushMatrix ( ) ;
if ( Flags & PC_TILE_FLAG_MIRROR_X )
{
glTranslatef ( 1 , 0 , 0 ) ;
glMultMatrixf ( XFlipMtx ) ;
}
if ( Flags & PC_TILE_FLAG_MIRROR_Y )
{
glTranslatef ( 0 , 1 , 0 ) ;
glMultMatrixf ( YFlipMtx ) ;
}
int ColFlags = Flags > > PC_TILE_FLAG_COLLISION_SHIFT ;
if ( ColFlags )
{
2001-05-30 19:02:54 +02:00
sColTab & ThisCol = ColTable [ ColFlags ] ;
glColor4ub ( ThisCol . R , ThisCol . G , ThisCol . B , 127 ) ;
2001-03-01 20:42:09 +01:00
}
glEnable ( GL_TEXTURE_2D ) ;
2001-03-05 21:49:46 +01:00
if ( Render3d )
{
glEnable ( GL_DEPTH_TEST ) ;
glCallList ( DrawList [ ElemType3d ] ) ;
glDisable ( GL_DEPTH_TEST ) ;
}
else
{
glCallList ( DrawList [ ElemType2d ] ) ;
}
2001-03-01 20:42:09 +01:00
glDisable ( GL_TEXTURE_2D ) ;
glPopMatrix ( ) ;
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
void CElem : : Purge ( )
2001-03-01 20:42:09 +01:00
{
2001-03-05 21:49:46 +01:00
for ( int i = 0 ; i < ElemTypeMax ; i + + )
glDeleteLists ( DrawList [ i ] , 1 ) ;
2001-04-07 23:05:33 +02:00
CleanUp ( ) ;
2001-05-02 20:40:41 +02:00
// TriList.clear();
2001-03-01 20:42:09 +01:00
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
// Only created for the tile browser, should NEVER appear in main view
2001-03-27 18:26:43 +02:00
void CElem : : CreateDefaultTileGfx ( )
2001-03-05 21:49:46 +01:00
{
float X0 = 0 ;
2001-03-27 18:26:43 +02:00
float X1 = 1.0f ;
2001-03-05 21:49:46 +01:00
float Y0 = 0 ;
2001-03-27 18:26:43 +02:00
float Y1 = 1.0f ;
DefTexFlag = true ;
// Blank
if ( BlankID = = - 1 )
2001-03-05 21:49:46 +01:00
{
2001-03-27 18:26:43 +02:00
BlankID = glGenLists ( 1 ) ;
glNewList ( BlankID , GL_COMPILE ) ;
2001-03-05 21:49:46 +01:00
glBindTexture ( GL_TEXTURE_2D , 0 ) ;
glBegin ( GL_LINES ) ;
glColor4f ( 1 , 1 , 1 , 1 ) ;
2001-03-27 18:26:43 +02:00
2001-03-05 21:49:46 +01:00
glVertex3f ( X0 , Y0 , 0 ) ;
glVertex3f ( X1 , Y0 , 0 ) ;
2001-03-27 18:26:43 +02:00
2001-03-05 21:49:46 +01:00
glVertex3f ( X0 , Y1 , 0 ) ;
glVertex3f ( X1 , Y1 , 0 ) ;
2001-03-27 18:26:43 +02:00
2001-03-05 21:49:46 +01:00
glVertex3f ( X0 , Y0 , 0 ) ;
glVertex3f ( X0 , Y1 , 0 ) ;
2001-03-27 18:26:43 +02:00
2001-03-05 21:49:46 +01:00
glVertex3f ( X1 , Y0 , 0 ) ;
glVertex3f ( X1 , Y1 , 0 ) ;
glEnd ( ) ;
glEndList ( ) ;
2001-03-27 18:26:43 +02:00
}
// Invalid
if ( InvalidID = = - 1 )
2001-03-05 21:49:46 +01:00
{
2001-03-27 18:26:43 +02:00
InvalidID = glGenLists ( 1 ) ;
glNewList ( InvalidID , GL_COMPILE ) ;
2001-03-05 21:49:46 +01:00
glBindTexture ( GL_TEXTURE_2D , 0 ) ;
glBegin ( GL_LINES ) ;
glColor4f ( 1 , 1 , 1 , 1 ) ;
glVertex3f ( X0 , Y0 , 0 ) ;
glVertex3f ( X1 , Y1 , 0 ) ;
glVertex3f ( X1 , Y0 , 0 ) ;
glVertex3f ( X0 , Y1 , 0 ) ;
glEnd ( ) ;
glEndList ( ) ;
2001-03-27 18:26:43 +02:00
}
2001-03-05 21:49:46 +01:00
}
2001-03-27 18:26:43 +02:00
2001-03-05 21:49:46 +01:00
/*****************************************************************************/
void CElem : : RenderElem4Texture ( sRGBData & RGBData )
2001-03-01 20:42:09 +01:00
{
2001-03-22 21:49:58 +01:00
float W = UnitWidth ;
float H = UnitHeight ;
2001-03-01 20:42:09 +01:00
2001-03-05 21:49:46 +01:00
glClearColor ( 1 , 0 , 1 , 1 ) ;
2001-03-22 21:49:58 +01:00
// glClearColor(1,1,1,1 );
2001-03-01 20:42:09 +01:00
glPushAttrib ( GL_VIEWPORT_BIT ) ;
2001-03-31 03:30:53 +02:00
glViewport ( 0 , 0 , RGBData . TexW , RGBData . TexH ) ;
2001-03-01 20:42:09 +01:00
glMatrixMode ( GL_PROJECTION ) ;
glPushMatrix ( ) ;
glLoadIdentity ( ) ;
2001-03-22 21:49:58 +01:00
glOrtho ( 0 , W , 0 , H , - 16.0f , + 16.0f ) ;
2001-03-01 20:42:09 +01:00
glMatrixMode ( GL_MODELVIEW ) ;
glPushMatrix ( ) ;
glLoadIdentity ( ) ;
2001-03-22 21:49:58 +01:00
glTranslatef ( - Ofs . x , - Ofs . y , - Ofs . z ) ;
2001-03-01 20:42:09 +01:00
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ; // Clear Screen
glColor3f ( 1 , 1 , 1 ) ;
glEnable ( GL_TEXTURE_2D ) ;
glEnable ( GL_DEPTH_TEST ) ;
2001-03-05 21:49:46 +01:00
glCallList ( DrawList [ ElemType3d ] ) ;
2001-03-01 20:42:09 +01:00
glDisable ( GL_DEPTH_TEST ) ;
glDisable ( GL_TEXTURE_2D ) ;
glPopMatrix ( ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPopMatrix ( ) ;
glPopAttrib ( ) ;
2001-03-31 03:30:53 +02:00
glReadPixels ( 0 , 0 , RGBData . TexW , RGBData . TexH , GL_RGB , GL_UNSIGNED_BYTE , RGBData . RGB ) ;
2001-03-05 21:49:46 +01:00
glClearColor ( 0 , 0 , 0 , 1 ) ;
glClear ( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ) ; // Clear Screen
2001-03-01 20:42:09 +01:00
}
/*****************************************************************************/
// ID used to create unique textures within one set :o)
2001-03-05 21:49:46 +01:00
void CElem : : Create2dTexture ( CTexCache & TexCache , const char * Filename , int ID )
2001-03-01 20:42:09 +01:00
{
sRGBData RGBData ;
2001-03-22 21:49:58 +01:00
char TexName [ 256 ] ;
2001-03-01 20:42:09 +01:00
2001-03-22 21:49:58 +01:00
sprintf ( TexName , " _2dPc_%s_%03d " , Filename , ID ) ;
2001-03-31 03:30:53 +02:00
int AW = AlignSize ( ElemWidth ) ;
int AH = AlignSize ( ElemHeight ) ;
ElemRGB = ( u8 * ) MemAlloc ( AW * AH * 3 ) ;
RGBData . TexW = AlignSize ( ElemWidth ) ;
RGBData . TexH = AlignSize ( ElemHeight ) ;
RGBData . ScaleU = 1.0f ;
RGBData . ScaleV = 1.0f ;
2001-03-05 21:49:46 +01:00
RGBData . RGB = ElemRGB ;
RenderElem4Texture ( RGBData ) ;
2001-03-22 21:49:58 +01:00
ElemID = TexCache . ProcessTexture ( TexName , & RGBData ) ;
2001-03-01 20:42:09 +01:00
ValidFlag = CheckHasData ( RGBData ) ;
# ifdef _DEBUG
if ( 0 )
{
char Filename [ 256 ] ;
sprintf ( Filename , " /x/%s.Tga " , TexName ) ;
2001-03-05 21:49:46 +01:00
SaveTGA ( Filename , ElemWidth , ElemHeight , ElemRGB ) ;
2001-03-01 20:42:09 +01:00
}
# endif
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
bool CElem : : CheckHasData ( sRGBData & RGBData )
2001-03-01 20:42:09 +01:00
{
u8 * Src = RGBData . RGB ;
2001-03-31 03:30:53 +02:00
int Size = RGBData . TexW * RGBData . TexH ;
2001-03-01 20:42:09 +01:00
2001-03-31 03:30:53 +02:00
while ( Size - - )
2001-03-01 20:42:09 +01:00
{
u8 R = * Src + + ;
u8 G = * Src + + ;
u8 B = * Src + + ;
2001-03-31 03:30:53 +02:00
if ( R ! = 255 | | G ! = 0 | | B ! = 255 ) return ( true ) ;
2001-03-01 20:42:09 +01:00
}
2001-03-31 03:30:53 +02:00
2001-03-22 21:49:58 +01:00
return ( false ) ;
2001-03-01 20:42:09 +01:00
}
/*****************************************************************************/
2001-03-05 21:49:46 +01:00
/*****************************************************************************/
/*** Elem Set ****************************************************************/
/*****************************************************************************/
/*****************************************************************************/
2001-03-31 17:40:20 +02:00
CElemSet : : CElemSet ( const char * _Filename , int Idx , int Width , int Height , bool CreateBlank , int Centre )
2001-03-05 21:49:46 +01:00
{
GFName FName = _Filename ;
Filename = _Filename ;
Name = FName . File ( ) ;
2001-03-22 21:49:58 +01:00
MaxWidth = Width ;
MaxHeight = Height ;
2001-03-31 17:40:20 +02:00
CentreMode = Centre ;
2001-03-05 21:49:46 +01:00
Loaded = FALSE ;
SetNumber = Idx ;
2001-03-22 21:49:58 +01:00
if ( CreateBlank )
{
ElemList . push_back ( CElem ( MaxWidth , MaxHeight ) ) ; // Insert Blank
}
2001-03-05 21:49:46 +01:00
}
/*****************************************************************************/
CElemSet : : ~ CElemSet ( )
{
2001-03-06 19:39:42 +01:00
}
/*****************************************************************************/
void CElemSet : : CleanUp ( )
{
2001-03-05 21:49:46 +01:00
int ListSize = ElemList . size ( ) ;
for ( int i = 0 ; i < ListSize ; i + + )
{
ElemList [ i ] . CleanUp ( ) ;
}
}
/*****************************************************************************/
void CElemSet : : Load ( CCore * Core )
{
GFName FName = Filename ;
GString Ext = FName . Ext ( ) ;
Ext . Upper ( ) ;
2001-03-27 18:26:43 +02:00
if ( ! CElem : : DefTexFlag ) CElem : : CreateDefaultTileGfx ( ) ;
2001-04-07 23:05:33 +02:00
if ( ! ElemList . size ( ) )
{
// ElemList[0].SetBlank();
}
2001-03-05 21:49:46 +01:00
if ( Ext = = " GIN " )
Load3d ( Core ) ;
else
Load2d ( Core ) ;
Loaded = TRUE ;
}
/*****************************************************************************/
void CElemSet : : Load2d ( CCore * Core )
{
CTexCache & TexCache = Core - > GetTexCache ( ) ;
2001-03-22 21:49:58 +01:00
int TexID = TexCache . ProcessTexture ( Filename ) ;
2001-03-05 21:49:46 +01:00
sTex & ThisTex = TexCache . GetTex ( TexID ) ;
2001-03-22 21:49:58 +01:00
int Width , Height ;
2001-03-31 03:30:53 +02:00
if ( MaxWidth = = - 1 ) MaxWidth = ThisTex . OldW ;
if ( MaxHeight = = - 1 ) MaxHeight = ThisTex . OldH ;
2001-03-22 21:49:58 +01:00
2001-03-31 03:30:53 +02:00
Width = ThisTex . OldW / MaxWidth ;
Height = ThisTex . OldH / MaxHeight ;
2001-03-05 21:49:46 +01:00
for ( int Y = 0 ; Y < Height ; Y + + )
{
for ( int X = 0 ; X < Width ; X + + )
{
2001-03-31 17:40:20 +02:00
ElemList . push_back ( CElem ( Core , Filename , TexID , X , Y , MaxWidth , MaxHeight , CentreMode ) ) ;
2001-03-05 21:49:46 +01:00
}
}
ElemBrowserWidth = Width ;
}
/*****************************************************************************/
void CElemSet : : Load3d ( CCore * Core )
{
CScene Scene ;
2001-03-01 20:42:09 +01:00
2001-03-05 21:49:46 +01:00
Scene . Load ( Filename ) ;
2001-03-01 20:42:09 +01:00
2001-03-05 21:49:46 +01:00
CNode & ThisNode = Scene . GetSceneNode ( 0 ) ;
int ChildCount = ThisNode . GetPruneChildCount ( ) ;
2001-04-07 23:05:33 +02:00
2001-03-05 21:49:46 +01:00
for ( int Child = 0 ; Child < ChildCount ; Child + + )
{
ElemList . push_back ( CElem ( Core , Filename , Scene , ThisNode . PruneChildList [ Child ] ) ) ;
}
ElemBrowserWidth = DEF_ELEMBROWSWEWIDTH ;
}
/*****************************************************************************/
void CElemSet : : Purge ( )
{
2001-04-07 23:05:33 +02:00
int i , ListSize = ElemList . size ( ) ;
2001-03-05 21:49:46 +01:00
2001-04-07 23:05:33 +02:00
for ( i = 0 ; i < ListSize ; i + + )
{
if ( ! ElemList [ i ] . IsBlank ( ) )
{
ElemList [ i ] . Purge ( ) ;
}
}
if ( ElemList [ 0 ] . IsBlank ( ) )
{
ElemList . erase ( 1 , ListSize ) ;
}
else
2001-03-05 21:49:46 +01:00
{
2001-04-07 23:05:33 +02:00
ElemList . clear ( ) ;
2001-03-05 21:49:46 +01:00
}
Loaded = FALSE ;
}
/*****************************************************************************/
CPoint CElemSet : : GetElemPos ( int ID )
{
if ( ID = = 0 )
return ( CPoint ( - 1 , - 1 ) ) ;
else
return ( IDToPoint ( ID - 1 , ElemBrowserWidth ) ) ;
}
/*****************************************************************************/
bool CElemSet : : IsValid ( int No )
{
int ListSize = ElemList . size ( ) ;
2001-03-27 18:26:43 +02:00
if ( No > = ListSize ) return ( false ) ;
2001-03-05 21:49:46 +01:00
return ( ElemList [ No ] . IsValid ( ) ) ;
}
/*****************************************************************************/
/*****************************************************************************/
/*** Elem Bank ***************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
2001-03-31 17:40:20 +02:00
CElemBank : : CElemBank ( int W , int H , bool Blank , int Centre )
2001-03-05 21:49:46 +01:00
{
2001-03-22 21:49:58 +01:00
MaxWidth = W ;
MaxHeight = H ;
BlankFlag = Blank ;
2001-03-31 17:40:20 +02:00
CentreMode = Centre ;
2001-03-22 21:49:58 +01:00
LoadFlag = false ;
CurrentSet = 0 ;
2001-03-26 23:29:09 +02:00
LayerDef . VisibleFlag = true ;
2001-03-05 21:49:46 +01:00
}
/*****************************************************************************/
CElemBank : : ~ CElemBank ( )
{
}
2001-03-06 19:39:42 +01:00
/*****************************************************************************/
void CElemBank : : CleanUp ( )
{
int ListSize = SetList . size ( ) ;
for ( int i = 0 ; i < ListSize ; i + + )
{
SetList [ i ] . CleanUp ( ) ;
}
}
2001-03-05 21:49:46 +01:00
/*****************************************************************************/
void CElemBank : : Load ( CFile * File , int Version )
{
int ListSize ;
GFName RootPath = File - > GetFilePath ( ) ;
GString FilePath ;
char FixPath [ 1024 ] ;
FilePath = RootPath . Drive ( ) ;
FilePath + = RootPath . Dir ( ) ;
FilePath . Append ( ' \\ ' ) ;
FilePath . Upper ( ) ;
2001-03-22 21:49:58 +01:00
if ( Version > = 5 )
{
File - > Read ( & CurrentSet , sizeof ( int ) ) ;
}
2001-03-05 21:49:46 +01:00
File - > Read ( & ListSize , sizeof ( int ) ) ;
// New Style rel storage
for ( int i = 0 ; i < ListSize ; i + + )
{
char c = 1 ;
GString FullName ; //=FilePath;
while ( c )
{
File - > Read ( & c , 1 ) ;
FullName . Append ( c ) ;
}
FullName . Upper ( ) ;
GFName : : makeabsolute ( FilePath , FullName , FixPath ) ;
FullName = FixPath ;
_fullpath ( FixPath , FullName , 1024 ) ;
for ( int z = 0 ; z < strlen ( FixPath ) ; z + + )
{ // Invalidate any long name short cackness
if ( FixPath [ z ] = = ' ~ ' ) FixPath [ z ] = ' _ ' ;
}
FullName = FixPath ;
CheckFilename ( FullName ) ;
FullName . Upper ( ) ;
AddSet ( FullName ) ;
}
}
/*****************************************************************************/
void CElemBank : : Save ( CFile * File )
{
int ListSize = SetList . size ( ) ;
GFName RootPath = File - > GetFilePath ( ) ;
GString SavePath ;
SavePath = RootPath . Drive ( ) ;
SavePath + = RootPath . Dir ( ) ;
SavePath . Append ( ' \\ ' ) ;
SavePath . Upper ( ) ;
2001-03-22 21:49:58 +01:00
File - > Write ( & CurrentSet , sizeof ( int ) ) ;
2001-03-05 21:49:46 +01:00
File - > Write ( & ListSize , sizeof ( int ) ) ;
for ( int i = 0 ; i < ListSize ; i + + )
{
char Filename [ 256 + 64 ] ;
RootPath . makerelative ( SavePath , SetList [ i ] . GetFilename ( ) , Filename ) ;
File - > Write ( Filename , strlen ( Filename ) + 1 ) ;
}
}
/*****************************************************************************/
2001-03-31 03:30:53 +02:00
int CElemBank : : AddSet ( const char * Filename )
2001-03-05 21:49:46 +01:00
{
int ListSize = SetList . size ( ) ;
2001-03-31 17:40:20 +02:00
CElemSet NewSet ( Filename , ListSize , MaxWidth , MaxHeight , BlankFlag , CentreMode ) ;
2001-03-05 21:49:46 +01:00
2001-03-31 03:30:53 +02:00
int Idx = SetList . Add ( NewSet ) ;
2001-03-05 21:49:46 +01:00
if ( SetList . size ( ) ! = ListSize ) LoadFlag = TRUE ;
2001-03-31 03:30:53 +02:00
return ( Idx ) ;
2001-03-05 21:49:46 +01:00
}
/*****************************************************************************/
void CElemBank : : LoadAllSets ( CCore * Core )
{
int ListSize = SetList . size ( ) ;
if ( ! LoadFlag ) return ;
for ( int i = 0 ; i < ListSize ; i + + )
{
CElemSet & ThisSet = SetList [ i ] ;
if ( ! ThisSet . IsLoaded ( ) ) ThisSet . Load ( Core ) ;
}
LoadFlag = false ;
}
/*****************************************************************************/
void CElemBank : : LoadNewSet ( CCore * Core )
{
char BASED_CODE GinFilter [ ] = " All Tile Files (*.Gin; *.Bmp)|*.gin;*.Bmp|3d Tile Files (*.Gin)|*.Gin|2d Tile Files (*.Bmp)|*.Bmp|All Files (*.*)|*.*|| " ;
CFileDialog Dlg ( TRUE , " Gin " , NULL , OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT , GinFilter ) ;
if ( Dlg . DoModal ( ) ! = IDOK ) return ;
char Filename [ 256 ] ;
sprintf ( Filename , " %s " , Dlg . GetPathName ( ) ) ;
AddSet ( Filename ) ;
}
/*****************************************************************************/
void CElemBank : : ReloadAllSets ( )
{
int ListSize = SetList . size ( ) ;
for ( int i = 0 ; i < ListSize ; i + + )
{
SetList [ i ] . Purge ( ) ;
}
LoadFlag = TRUE ;
}
/*****************************************************************************/
void CElemBank : : DeleteSet ( int Set )
{
SetList . erase ( Set ) ;
}
/*****************************************************************************/
bool CElemBank : : IsValid ( int Set , int Elem )
{
if ( Set < 0 | | Elem < 0 ) return ( false ) ;
if ( Elem = = 0 ) return ( true ) ;
2001-03-27 18:26:43 +02:00
if ( Set > = SetList . size ( ) ) return ( false ) ;
// if (Set>SetList.size()) return(false);
2001-03-05 21:49:46 +01:00
ASSERT ( Set < SetList . size ( ) ) ;
return ( SetList [ Set ] . IsValid ( Elem ) ) ;
}
2001-03-01 20:42:09 +01:00
2001-03-22 21:49:58 +01:00
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
/*****************************************************************************/
CPoint CElemBank : : GetElemPos ( int ID , int Width )
{
if ( ID = = 0 )
return ( CPoint ( - 1 , - 1 ) ) ;
else
return ( IDToPoint ( ID - 1 , Width ) ) ;
}
/*****************************************************************************/
void CElemBank : : RenderElem ( int Set , int Elem , int Flags , bool Is3d )
{
if ( IsValid ( Set , Elem ) )
{
SetList [ Set ] . RenderElem ( Elem , Flags , Is3d ) ;
}
else
{
2001-03-27 18:26:43 +02:00
RenderInvalid ( ) ;
2001-03-22 21:49:58 +01:00
}
}
/*****************************************************************************/
void CElemBank : : RenderGrid ( CCore * Core , Vector3 & CamPos , bool Active )
{
if ( ! GetSetCount ( ) ) return ;
CElemSet & ThisSet = SetList [ CurrentSet ] ;
int ListSize = ThisSet . GetCount ( ) ;
int BrowserWidth = ThisSet . GetBrowserWidth ( ) ;
int TileID = 1 ; // Dont bother with blank, its sorted
float Scale = CamPos . z / ( float ) BrowserWidth / 2.0 ;
if ( ! ListSize ) return ;
glMatrixMode ( GL_MODELVIEW ) ;
glPushMatrix ( ) ;
while ( TileID ! = ListSize )
{
CPoint Pos = GetElemPos ( TileID , BrowserWidth ) ;
float XPos = ( float ) Pos . x * ( 1 + ElemBrowserGap ) ;
float YPos = ( float ) Pos . y * ( 1 + ElemBrowserGap ) ;
glLoadIdentity ( ) ;
glScalef ( Scale , Scale , Scale ) ;
glTranslatef ( - CamPos . x + XPos , CamPos . y - YPos , 0 ) ;
glBegin ( GL_LINES ) ;
glColor3f ( 1 , 1 , 1 ) ;
glVertex3f ( ElemBrowserX0 , ElemBrowserY0 , 0 ) ;
glVertex3f ( ElemBrowserX1 , ElemBrowserY0 , 0 ) ;
glVertex3f ( ElemBrowserX0 , ElemBrowserY1 , 0 ) ;
glVertex3f ( ElemBrowserX1 , ElemBrowserY1 , 0 ) ;
glVertex3f ( ElemBrowserX0 , ElemBrowserY0 , 0 ) ;
glVertex3f ( ElemBrowserX0 , ElemBrowserY1 , 0 ) ;
glVertex3f ( ElemBrowserX1 , ElemBrowserY0 , 0 ) ;
glVertex3f ( ElemBrowserX1 , ElemBrowserY1 , 0 ) ;
glEnd ( ) ;
TileID + + ;
}
glPopMatrix ( ) ;
}
/*****************************************************************************/
void CElemBank : : FindCursorPos ( CCore * Core , Vector3 & CamPos , CPoint & MousePos )
{
if ( ! GetSetCount ( ) ) return ;
CElemSet & ThisSet = SetList [ CurrentSet ] ;
int ListSize = ThisSet . GetCount ( ) ;
int BrowserWidth = ThisSet . GetBrowserWidth ( ) ;
GLint Viewport [ 4 ] ;
GLuint SelectBuffer [ SELECT_BUFFER_SIZE ] ;
int HitCount ;
int TileID = 0 ;
float Scale = CamPos . z / ( float ) BrowserWidth / 2.0 ;
if ( ! ListSize ) return ;
glGetIntegerv ( GL_VIEWPORT , Viewport ) ;
glSelectBuffer ( SELECT_BUFFER_SIZE , SelectBuffer ) ;
glRenderMode ( GL_SELECT ) ;
glInitNames ( ) ;
glPushName ( - 1 ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPushMatrix ( ) ;
glLoadIdentity ( ) ;
gluPickMatrix ( MousePos . x , ( Viewport [ 3 ] - MousePos . y ) , 5.0 , 5.0 , Viewport ) ;
Core - > GetView ( ) - > SetupPersMatrix ( ) ;
glMatrixMode ( GL_MODELVIEW ) ;
glPushMatrix ( ) ;
while ( TileID ! = ListSize )
{
CPoint Pos = GetElemPos ( TileID , BrowserWidth ) ;
float XPos = ( float ) Pos . x * ( 1 + ElemBrowserGap ) ;
float YPos = ( float ) Pos . y * ( 1 + ElemBrowserGap ) ;
glLoadIdentity ( ) ;
glScalef ( Scale , Scale , Scale ) ;
glTranslatef ( - CamPos . x + XPos , CamPos . y - YPos , 0 ) ;
glLoadName ( TileID ) ;
glBegin ( GL_QUADS ) ;
BuildGLQuad ( ElemBrowserX0 , ElemBrowserX1 , ElemBrowserY0 , ElemBrowserY1 , 0 ) ;
glEnd ( ) ;
TileID + + ;
}
HitCount = glRenderMode ( GL_RENDER ) ;
glPopMatrix ( ) ;
glMatrixMode ( GL_PROJECTION ) ;
glPopMatrix ( ) ;
// Process hits
GLuint * HitPtr = SelectBuffer ;
TileID = - 2 ;
if ( HitCount ) // Just take 1st
{
TileID = HitPtr [ 3 ] ;
}
glMatrixMode ( GL_MODELVIEW ) ; // <-- Prevent arse GL assert
CursorPos = TileID ;
}
/*****************************************************************************/
/*** Gui *********************************************************************/
/*****************************************************************************/
void CElemBank : : GUIInit ( CCore * Core )
{
Core - > GUIAdd ( GUIElemList , IDD_ELEMLIST ) ;
}
/*****************************************************************************/
void CElemBank : : GUIKill ( CCore * Core )
{
Core - > GUIRemove ( GUIElemList , IDD_ELEMLIST ) ;
}
/*****************************************************************************/
void CElemBank : : GUIUpdate ( CCore * Core )
{
int ListSize = GetSetCount ( ) ;
bool IsSubView = Core - > IsSubView ( ) ;
if ( GUIElemList . m_List )
{
GUIElemList . m_List . ResetContent ( ) ;
if ( ListSize )
{
for ( int i = 0 ; i < ListSize ; i + + )
{
GUIElemList . m_List . AddString ( GetSetName ( i ) ) ;
}
GUIElemList . m_List . SetCurSel ( CurrentSet ) ;
}
else
{
IsSubView = FALSE ;
}
GUIElemList . m_List . EnableWindow ( IsSubView ) ;
}
}
/*****************************************************************************/
void CElemBank : : GUIChanged ( CCore * Core )
{
}
/*****************************************************************************/