/*********************/ /*** Elem Stuph ***/ /*********************/ #include "stdafx.h" #include #include #include #include "GLEnabledView.h" #include #include #include "Core.h" #include "TexCache.h" #include "Elem.h" #include "GinTex.h" #include "utils.h" #include "MapEdit.h" #include "MapEditDoc.h" #include "MapEditView.h" #include "MainFrm.h" #include "GUITileBank.h" const Vector3 DefOfs(+0.5f,0,+4.0f); int CElem::BlankID=-1; int CElem::InvalidID=-1; bool CElem::DefTexFlag=false; /*****************************************************************************/ // 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; /*****************************************************************************/ 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, }; /*****************************************************************************/ CElem::CElem(int Width,int Height) { ElemWidth=Width; ElemHeight=Height; UnitWidth=ElemWidth/UnitSize; UnitHeight=ElemHeight/UnitSize; ElemID=-1; int AW=AlignSize(ElemWidth); int AH=AlignSize(ElemHeight); ElemRGB=(u8*)MemAlloc(AW*AH*3); memset(ElemRGB,0,AW*AH*3); Type=ElemType2d; TexXOfs=0; TexYOfs=0; for (int i=0; iGetTexCache(); GFName Path=Filename; SetPath=Path.Drive(); SetPath+=Path.Dir(); SetPath.Append('\\'); Type=ElemType3d; TexXOfs=-1; TexYOfs=-1; Ofs.Zero(); Build3dElem(TexCache,ThisScene,Node); Calc3dSize(); Build3dDrawList(TexCache,DrawList[ElemType3d]); Ofs.Zero(); Create2dTexture(TexCache,Path.File(),Node); Build2dDrawList(TexCache,DrawList[ElemType2d]); if (!ValidFlag) { Purge(); // Clear whatever is already there for (int i=0; iGetTexCache(); GFName Path=Filename; ElemWidth=Width; ElemHeight=Height; UnitWidth=ElemWidth/UnitSize; UnitHeight=ElemHeight/UnitSize; Type=ElemType2d; TexXOfs=XOfs; TexYOfs=YOfs; Ofs.Zero(); 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) { Ofs.y-=(UnitHeight-1.0f)/2; } Build2dElem(Core,Path.File(),TexID); Build3dDrawList(TexCache,DrawList[ElemType3d]); Create2dTexture(TexCache,Path.File(),TexID); Build2dDrawList(TexCache,DrawList[ElemType2d]); if (!ValidFlag) { Purge(); // Clear whatever is already there for (int i=0; iGetTexCache(); sTex &ThisTex=TexCache.GetTex(TexID); 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; float u0=(TexXOfs*dU); float u1=u0+dU; float v1=1.0-(TexYOfs*dV); float v0=v1-dV; 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; } /*****************************************************************************/ void CElem::Build3dElem(CTexCache &TexCache,CScene &ThisScene,int Node) { CNode &ThisNode=ThisScene.GetNode(Node); CNode &ParentNode=ThisScene.GetNode(ThisNode.ParentIdx); int ChildCount=ThisNode.GetPruneChildCount(); std::vector const &NodeTriList=ThisNode.GetTris(); std::vectorconst &NodeVtxList=ThisNode.GetPts(); std::vector const &NodeUVList=ThisNode.GetUVTris(); std::vector const &NodeTriMat=ThisNode.GetTriMaterial(); std::vector const &SceneTexList=ThisScene.GetTexList(); std::vector const &SceneUsedMatList=ThisScene.GetUsedMaterialIdx(); int TexCount=SceneTexList.size(); int TriCount=NodeTriList.size(); int ListSize=TriList.size(); TriList.resize(ListSize+TriCount); for (int T=0; T=TexCount) { CString mexstr; mexstr.Format("Invalid TexId\n Wanted %i only have %i Id's for %s\nThis is gonna hurt!\n Dont ask me about this error, ask Kev.\n This MUST be fixed.",TexID,TexCount-1,ThisNode.Name); AfxMessageBox(mexstr,MB_OK | MB_ICONEXCLAMATION); TexID=0; } else { GString ThisName; GString TexName=SceneTexList[TexID]; ThisName=SetPath+TexName; TRACE2("%i !%s!\n",TexID,ThisName); TexID=TexCache.ProcessTexture(ThisName); } // Sort Rest of Tri info Matrix4x4 TransMtx; TransMtx.Identity(); if (ParentNode.GetTris().size() || !ThisNode.ParentIdx) { TransMtx=ThisNode.Mtx; TransMtx.Invert(); } for (int p=0; p<3; p++) { Tri.vtx[p]=TransMtx*NodeVtxList[ThisTri.p[p]]; Tri.uvs[p].u=ThisUV.p[p].u; Tri.uvs[p].v=ThisUV.p[p].v; Tri.Mat=TexID; } } for (int Child=0; ChildTri.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> PC_TILE_FLAG_COLLISION_SHIFT; if (ColFlags) { switch (ColFlags) { case PC_TILE_COLLISION_NORMAL: glColor4f(1.0f,1.0f,1.0f,0.5); break; case PC_TILE_COLLISION_DAMAGE: glColor4f(1.0f,0.0f,0.0f,0.5); break; case PC_TILE_COLLISION_SLIPPERY: glColor4f(0.0f,1.0f,0.0f,0.5); break; case PC_TILE_COLLISION_ELECTRIC: glColor4f(1.0f,0.0f,1.0f,0.5); break; case PC_TILE_COLLISION_STICKY: glColor4f(1.0f,1.0f,0.0f,0.5); break; case PC_TILE_COLLISION_WATER: glColor4f(0.0f,0.0f,1.0f,0.5); break; case PC_TILE_COLLISION_SOLID: glColor4f(0.0f,1.0f,1.0f,0.5); break; case PC_TILE_COLLISION_DEATH: glColor4f(1.0f,0.5f,0.5f,0.5); break; } } glEnable(GL_TEXTURE_2D); if (Render3d) { glEnable(GL_DEPTH_TEST); glCallList(DrawList[ElemType3d]); glDisable(GL_DEPTH_TEST); } else { glCallList(DrawList[ElemType2d]); } glDisable(GL_TEXTURE_2D); glPopMatrix(); } /*****************************************************************************/ void CElem::Purge() { for (int i=0; iGetTexCache(); int TexID=TexCache.ProcessTexture(Filename); sTex &ThisTex=TexCache.GetTex(TexID); int Width,Height; if (MaxWidth==-1) MaxWidth=ThisTex.OldW; if (MaxHeight==-1) MaxHeight=ThisTex.OldH; Width=ThisTex.OldW/MaxWidth; Height=ThisTex.OldH/MaxHeight; for (int Y=0; Y=ListSize) return(false); return(ElemList[No].IsValid()); } /*****************************************************************************/ /*****************************************************************************/ /*** Elem Bank ***************************************************************/ /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ CElemBank::CElemBank(int W,int H,bool Blank,int Centre) { MaxWidth=W; MaxHeight=H; BlankFlag=Blank; CentreMode=Centre; LoadFlag=false; CurrentSet=0; LayerDef.VisibleFlag=true; } /*****************************************************************************/ CElemBank::~CElemBank() { } /*****************************************************************************/ void CElemBank::CleanUp() { int ListSize=SetList.size(); for (int i=0; iGetFilePath(); GString FilePath; char FixPath[1024]; FilePath=RootPath.Drive(); FilePath+=RootPath.Dir(); FilePath.Append('\\'); FilePath.Upper(); if (Version>=5) { File->Read(&CurrentSet,sizeof(int)); } File->Read(&ListSize,sizeof(int)); // New Style rel storage for (int i=0;iRead(&c,1); FullName.Append(c); } FullName.Upper(); GFName::makeabsolute(FilePath,FullName,FixPath); FullName=FixPath; _fullpath( FixPath, FullName, 1024); for (int z=0; zGetFilePath(); GString SavePath; SavePath=RootPath.Drive(); SavePath+=RootPath.Dir(); SavePath.Append('\\'); SavePath.Upper(); File->Write(&CurrentSet,sizeof(int)); File->Write(&ListSize,sizeof(int)); for (int i=0; iWrite(Filename,strlen(Filename)+1); } } /*****************************************************************************/ int CElemBank::AddSet(const char *Filename) { int ListSize=SetList.size(); CElemSet NewSet(Filename,ListSize,MaxWidth,MaxHeight,BlankFlag,CentreMode); int Idx=SetList.Add(NewSet); if (SetList.size()!=ListSize) LoadFlag=TRUE; return(Idx); } /*****************************************************************************/ void CElemBank::LoadAllSets(CCore *Core) { int ListSize=SetList.size(); if (!LoadFlag) return; for (int i=0;i=SetList.size()) return(false); // if (Set>SetList.size()) return(false); ASSERT(SetGetView()->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