/*********************/ /*** TileSet Stuph ***/ /*********************/ #include "stdafx.h" #include #include #include #include "GLEnabledView.h" #include #include #include "Core.h" #include "TileSet.h" #include "GinTex.h" #include "utils.h" #include "MapEdit.h" #include "MapEditDoc.h" #include "MapEditView.h" #include "MainFrm.h" #include "LayerTileGui.h" // Reserve slot 0 for collision :o) GString ColFName="Collision.bmp"; /*****************************************************************************/ /*** TileBank ****************************************************************/ /*****************************************************************************/ const float TileBrowserGap=0.2f; const float TileBrowserX0=0-TileBrowserGap/2; const float TileBrowserX1=1+TileBrowserGap/2; const float TileBrowserY0=0-TileBrowserGap/2; const float TileBrowserY1=1+TileBrowserGap/2; /*****************************************************************************/ CTileBank::CTileBank() { GFName ExePath; GString Filename; // Get application path #ifdef _DEBUG ExePath="C:\\Spongebob\\tools\\mapedit\\"; #else char ExeFilename[2048]; GetModuleFileName(GetModuleHandle(NULL),ExeFilename,2048); ExePath=ExeFilename; ExePath.File(0); ExePath.Ext(0); #endif Filename=ExePath.FullName(); Filename+=ColFName; LoadFlag=FALSE; CurrentSet=0; LastSet=0; for (int i=0; iGetFilePath(); GString FilePath; char FixPath[1024]; FilePath=RootPath.Drive(); FilePath+=RootPath.Dir(); FilePath.Append('\\'); FilePath.Upper(); File->Read(&ListSize,sizeof(int)); File->Read(&CurrentSet,sizeof(int)); File->Read(&ActiveBrush,sizeof(int)); Brush[0].Load(File,Version); Brush[1].Load(File,Version); if (Version<2) { CurrentSet++; } // 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(&NewListSize,sizeof(int)); File->Write(&CurrentSet,sizeof(int)); File->Write(&ActiveBrush,sizeof(int)); Brush[0].Save(File); Brush[1].Save(File); for (int i=1; iWrite(Filename,strlen(Filename)+1); } } /*****************************************************************************/ void CTileBank::AddTileSet(const char *Filename) { int ListSize=TileSet.size(); CTileSet NewSet(Filename,ListSize); TileSet.Add(NewSet); if (TileSet.size()!=ListSize) LoadFlag=TRUE; } /*****************************************************************************/ void CTileBank::LoadTileSets(CCore *Core) { int ListSize=TileSet.size(); for (int i=0;i=0 && Tile>=0); return(TileSet[Bank].GetTile(Tile)); } /*****************************************************************************/ void CTileBank::Render(CCore *Core,Vector3 &CamPos,bool Is3d) { if (!TileSet.size()) return; // No tiles, return if (Is3d) { glEnable(GL_DEPTH_TEST); TileSet[CurrentSet].Render(Core,CamPos,GetLBrush(),GetRBrush(),TRUE); glDisable(GL_DEPTH_TEST); } else { TileSet[CurrentSet].Render(Core,CamPos,GetLBrush(),GetRBrush(),FALSE); } } /*****************************************************************************/ void CTileBank::RenderCursor(CCore *Core,Vector3 &CamPos,bool Is3d) { TileSet[CurrentSet].RenderCursor(CamPos,CursorPos,SelStart,SelEnd); } /*****************************************************************************/ void CTileBank::RenderGrid(CCore *Core,Vector3 &CamPos,bool Active) { TileSet[CurrentSet].RenderGrid(Core,CamPos,Active); } /*****************************************************************************/ void CTileBank::FindCursorPos(CCore *Core,Vector3 &CamPos,CPoint &MousePos) { if (!TileSet.size()) return; // No tiles, return CursorPos=TileSet[CurrentSet].FindCursorPos(Core,CamPos,MousePos); SelEnd=CursorPos; } /*****************************************************************************/ bool CTileBank::LButtonControl(CCore *Core,UINT nFlags, CPoint &CursorPos,bool DownFlag) { if (nFlags & MK_RBUTTON) { SelectCancel(); return(false); } Select(LBrush,DownFlag); return(true); } /*****************************************************************************/ bool CTileBank::RButtonControl(CCore *Core,UINT nFlags, CPoint &CursorPos,bool DownFlag) { if (nFlags & MK_LBUTTON) { SelectCancel(); return(false); } Select(RBrush,DownFlag); return(false); } /*****************************************************************************/ bool CTileBank::MouseMove(CCore *Core,UINT nFlags, CPoint &CursorPos) { return(false); } /*****************************************************************************/ bool CTileBank::Command(int CmdMsg,CCore *Core,int Param0,int Param1) { switch(CmdMsg) { case CmdMsg_SubViewLoad: LoadSet(Core); break; case CmdMsg_SubViewDelete: DeleteSet(Core); break; case CmdMsg_SubViewUpdate: ReloadAll(); Core->GetTexCache().Purge(); break; case CmdMsg_SubViewSet: CurrentSet=TileBankGUI.m_List.GetCurSel()+1; break; case CmdMsg_ActiveBrushLeft: ActiveBrush=LBrush; break; case CmdMsg_ActiveBrushRight: ActiveBrush=RBrush; default: TRACE3("TileBank-Unhandled Command %i (%i,%i)\n",CmdMsg,Param0,Param1); } return(true); } /*****************************************************************************/ /*** Gui *********************************************************************/ /*****************************************************************************/ void CTileBank::GUIInit(CCore *Core) { Core->GUIAdd(TileBankGUI,IDD_LAYERTILE_GUI); } /*****************************************************************************/ void CTileBank::GUIKill(CCore *Core) { Core->GUIRemove(TileBankGUI,IDD_LAYERTILE_GUI); } /*****************************************************************************/ void CTileBank::GUIUpdate(CCore *Core) { int ListSize=TileSet.size(); bool IsSubView=true;//Core->IsSubView(); if (TileBankGUI.m_List) { TileBankGUI.m_List.ResetContent(); if (ListSize-1) { for (int i=1; i=MaxTile) SelectCancel(); // Invalid selection ThisElem.Set=CurrentSet; ThisElem.Flags=0; ThisBrush.Delete(); ThisBrush.SetSize(Width,Height); for (int Y=0; YQuestion("Delete Current Tile Bank\n\nAll used tiles in current set will be set to blank\nAre you sure?")) { int SetCount=GetSetCount(); int i,ListSize=Core->GetLayerCount(); for (i=0;iGetLayer(i); if (ThisLayer->GetType()==LAYER_TYPE_TILE) { ThisLayer->DeleteSet(CurrentSet); } } DeleteCurrent(); for (int Set=CurrentSet+1; SetGetLayer(i); if (ThisLayer->GetType()==LAYER_TYPE_TILE) { ThisLayer->RemapSet(Set,Set-1); } } } } CurrentSet--; GUIUpdate(Core); } /*****************************************************************************/ /*****************************************************************************/ /*** TileSet *****************************************************************/ /*****************************************************************************/ /*****************************************************************************/ CTileSet::CTileSet(const char *_Filename,int Idx) { GFName FName=_Filename; Filename=_Filename; Name=FName.File(); Loaded=FALSE; SetNumber=Idx; } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ CTileSet::~CTileSet() { } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CTileSet::Load(CCore *Core) { GFName FName=Filename; GString Ext=FName.Ext(); Ext.Upper(); if (Ext=="GIN") { Load3d(Core); } else { Load2d(Core); } Loaded=TRUE; } /*****************************************************************************/ void CTileSet::Load2d(CCore *Core) { CTexCache &TexCache=Core->GetTexCache(); GString ColTest; int TexID=TexCache.ProcessTexture(Filename,0); sTex &ThisTex=TexCache.GetTex(TexID); int Width=ThisTex.TexWidth/16; int Height=ThisTex.TexHeight/16; // TRACE3("Load 2d TileBank %s (%i,%i)\n",Filename.FullName(),Width,Height); Tile.push_back(CTile(0)); // Insert Blank for (int Y=0; YTile.size()) return(FALSE); return(Tile[No].IsValid()); } /*****************************************************************************/ void CTileSet::Render(CCore *Core,Vector3 &CamPos,CMap &LBrush,CMap &RBrush,bool Render3d) { int ListSize=Tile.size(); int TileID=0; sMapElem ThisElem; int SelFlag; bool ValidTile=TRUE; //float Scale=1.0f/(float)TileBrowserWidth/CamPos.z; float Scale=CamPos.z/(float)TileBrowserWidth/2.0; ThisElem.Flags=0; ThisElem.Set=SetNumber; glMatrixMode(GL_MODELVIEW); glPushMatrix(); while(TileID!=ListSize) { CPoint Pos=GetTilePos(TileID); float XPos=(float)Pos.x*(1+TileBrowserGap); float YPos=(float)Pos.y*(1+TileBrowserGap); glLoadIdentity(); glScalef(Scale,Scale,Scale); glTranslatef(-CamPos.x+XPos,CamPos.y-YPos,0); ValidTile=IsTileValid(TileID); if (TileID && ValidTile) { glColor3f(1,1,1); Tile[TileID].Render(0,Render3d); } // Selection ThisElem.Tile=TileID; SelFlag=0; if (LBrush.DoesContainTile(ThisElem)) SelFlag|=1; if (RBrush.DoesContainTile(ThisElem)) SelFlag|=2; if (SelFlag) { glBegin(GL_QUADS); switch(SelFlag) { case 1: // L glColor4f(1,0,0,0.5); BuildGLQuad(TileBrowserX0,TileBrowserX1,TileBrowserY0,TileBrowserY1,0.01f); break; case 2: // R glColor4f(0,0,1,0.5); BuildGLQuad(TileBrowserX0,TileBrowserX1,TileBrowserY0,TileBrowserY1,0.01f); break; case 3: // LR glColor4f(1,0,0,0.5); BuildGLQuad(TileBrowserX0,0.5,TileBrowserY0,TileBrowserY1,0.01f); glColor4f(0,0,1,0.5); BuildGLQuad(0.5,TileBrowserX1,TileBrowserY0,TileBrowserY1,0.01f); break; } glEnd(); } // Invalid tile? if (!ValidTile) { glBegin(GL_LINES); glColor3f(1,1,1); glVertex3f( TileBrowserX0,TileBrowserY0,0); glVertex3f( TileBrowserX1,TileBrowserY1,0); glVertex3f( TileBrowserX1,TileBrowserY0,0); glVertex3f( TileBrowserX0,TileBrowserY1,0); glEnd(); } // Draw Box around bloody Blank so you can see it if (!TileID) { CPoint Pos=GetTilePos(TileID); glBegin(GL_LINES); glColor3f(1,1,1); glVertex3f( TileBrowserX0,TileBrowserY0,0); glVertex3f( TileBrowserX1,TileBrowserY0,0); glVertex3f( TileBrowserX0,TileBrowserY1,0); glVertex3f( TileBrowserX1,TileBrowserY1,0); glVertex3f( TileBrowserX0,TileBrowserY0,0); glVertex3f( TileBrowserX0,TileBrowserY1,0); glVertex3f( TileBrowserX1,TileBrowserY0,0); glVertex3f( TileBrowserX1,TileBrowserY1,0); glEnd(); } TileID++; } glPopMatrix(); } /*****************************************************************************/ void CTileSet::RenderCursor(Vector3 &CamPos,int CursorPos,int SelStart,int SelEnd) { int ListSize=Tile.size(); CPoint Start,End; int MaxTile=Tile.size(); //float Scale=1.0f/(float)TileBrowserWidth/CamPos.z; float Scale=CamPos.z/(float)TileBrowserWidth/2.0; if (CursorPos<-1 || CursorPos>ListSize) return; if (SelStart==-1) { Start=GetTilePos(CursorPos); End=Start; } else { CPoint S=IDToPoint(SelStart-1,TileBrowserWidth); CPoint E=IDToPoint(SelEnd-1,TileBrowserWidth); Start=CPoint( min(S.x,E.x), min(S.y,E.y)); End=CPoint( max(S.x,E.x), max(S.y,E.y)); if (PointToID(End,TileBrowserWidth)>=MaxTile) return; // Invalid selection } glMatrixMode(GL_MODELVIEW); glPushMatrix(); for (int Y=Start.y; Y<=End.y; Y++) { for (int X=Start.x; X<=End.x; X++) { float XPos=(float)X*(1+TileBrowserGap); float YPos=(float)Y*(1+TileBrowserGap); glLoadIdentity(); glScalef(Scale,Scale,Scale); glTranslatef(-CamPos.x+XPos,CamPos.y-YPos,0); glBegin(GL_QUADS); glColor4f(1,1,0,0.5); BuildGLQuad(TileBrowserX0,TileBrowserX1,TileBrowserY0,TileBrowserY1,0); glEnd(); } } glPopMatrix(); } /*****************************************************************************/ void CTileSet::RenderGrid(CCore *Core,Vector3 &CamPos,bool Active) { int ListSize=Tile.size(); int TileID=1; // Dont bother with blank, its sorted //float Scale=1.0f/(float)TileBrowserWidth/CamPos.z; float Scale=CamPos.z/(float)TileBrowserWidth/2.0; glMatrixMode(GL_MODELVIEW); glPushMatrix(); while(TileID!=ListSize) { CPoint Pos=GetTilePos(TileID); float XPos=(float)Pos.x*(1+TileBrowserGap); float YPos=(float)Pos.y*(1+TileBrowserGap); glLoadIdentity(); glScalef(Scale,Scale,Scale); glTranslatef(-CamPos.x+XPos,CamPos.y-YPos,0); glBegin(GL_LINES); glColor3f(1,1,1); glVertex3f( TileBrowserX0,TileBrowserY0,0); glVertex3f( TileBrowserX1,TileBrowserY0,0); glVertex3f( TileBrowserX0,TileBrowserY1,0); glVertex3f( TileBrowserX1,TileBrowserY1,0); glVertex3f( TileBrowserX0,TileBrowserY0,0); glVertex3f( TileBrowserX0,TileBrowserY1,0); glVertex3f( TileBrowserX1,TileBrowserY0,0); glVertex3f( TileBrowserX1,TileBrowserY1,0); glEnd(); TileID++; } glPopMatrix(); } /*****************************************************************************/ int CTileSet::FindCursorPos(CCore *Core,Vector3 &CamPos,CPoint &MousePos) { int ListSize=Tile.size(); GLint Viewport[4]; GLuint SelectBuffer[SELECT_BUFFER_SIZE]; int HitCount; int TileID=0; //float Scale=1.0f/(float)TileBrowserWidth/CamPos.z; float Scale=CamPos.z/(float)TileBrowserWidth/2.0; 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=GetTilePos(TileID); float XPos=(float)Pos.x*(1+TileBrowserGap); float YPos=(float)Pos.y*(1+TileBrowserGap); glLoadIdentity(); glScalef(Scale,Scale,Scale); glTranslatef(-CamPos.x+XPos,CamPos.y-YPos,0); glLoadName (TileID); glBegin (GL_QUADS); BuildGLQuad(TileBrowserX0,TileBrowserX1,TileBrowserY0,TileBrowserY1,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 return(TileID); }