/*********************/ /*** TileSet Stuph ***/ /*********************/ #include "stdafx.h" #include #include #include #include "GLEnabledView.h" #include //#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) char *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; FilePath=RootPath.Drive(); FilePath+=RootPath.Dir(); FilePath.Append('\\'); 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); RelName.Append(c); } RelName.Upper(); { // Dodgy arse artist fix RelName=FixName(RelName); } RootPath.makeabsolute(FilePath,RelName,FullName); AddTileSet(FullName); } } /*****************************************************************************/ void CTileBank::Save(CFile *File) { int ListSize=TileSet.size(); int NewListSize=ListSize-1; GString FilePath; GFName RootPath=File->GetFilePath(); FilePath=RootPath.Drive(); FilePath+=RootPath.Dir(); FilePath.Append('\\'); 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(); if (FindTileSet(Filename) ==-1) { TileSet.push_back(CTileSet(Filename,ListSize)); LoadFlag=TRUE; } } /*****************************************************************************/ int CTileBank::FindTileSet(const char *Filename) { int ListSize=TileSet.size(); CTileSet FindSet(Filename,ListSize); for (int i=0; i=0 && Tile>=0); return(TileSet[Bank].GetTile(Tile)); } /*****************************************************************************/ void CTileBank::RenderSet(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); } TileSet[CurrentSet].RenderCursor(CamPos,CursorPos,SelStart,SelEnd); if (Core->IsGridOn()) TileSet[CurrentSet].RenderGrid(CamPos); } /*****************************************************************************/ void CTileBank::FindCursorPos(CCore *Core,CMapEditView *View,Vector3 &CamPos,CPoint &MousePos) { if (!TileSet.size()) return; // No tiles, return CursorPos=TileSet[CurrentSet].FindCursorPos(Core,View,CamPos,MousePos); SelEnd=CursorPos; } /*****************************************************************************/ /*** Gui *********************************************************************/ /*****************************************************************************/ void CTileBank::UpdateGUI(CCore *Core,BOOL IsTileView) { CMainFrame *Frm=(CMainFrame*)AfxGetApp()->GetMainWnd(); CLayerTileGUI *Dlg=(CLayerTileGUI*)Frm->GetDialog(IDD_LAYERTILE_GUI); int ListSize=TileSet.size(); if (Dlg) { Dlg->m_List.ResetContent(); if (ListSize-1) { for (int i=1; im_List.AddString(TileSet[i].GetName()); } Dlg->m_List.SetCurSel(CurrentSet-1); } else { IsTileView=FALSE; } Dlg->m_List.EnableWindow(IsTileView); } } /*****************************************************************************/ /*** Functions ***************************************************************/ /*****************************************************************************/ BOOL CTileBank::Select(int BrushID,BOOL DownFlag) { if (DownFlag && SelStart==-1) { if (CursorPos<0) return(FALSE); SelStart=CursorPos; if (CursorPos==0) { SetBrush(GetBrush(BrushID)); SelStart=-1; TRACE0("Selected Blank\n"); } } else if (!DownFlag && SelStart!=-1) { if (CursorPos==-1) return(SelectCancel()); SetBrush(GetBrush(BrushID)); SelStart=-1; TRACE0("END SEL\n"); } return(TRUE); } /*****************************************************************************/ void CTileBank::SetBrush(CMap &ThisBrush) { int BW=TileSet[CurrentSet].GetTileBrowserWidth(); CPoint S=IDToPoint(SelStart-1,BW); CPoint E=IDToPoint(SelEnd-1,BW); int Width=abs(E.x-S.x)+1; int Height=abs(E.y-S.y)+1; sMapElem ThisElem; int MaxTile=TileSet[CurrentSet].GetTileCount(); // if (PointToID(End,BW)>=MaxTile) SelectCancel(); // Invalid selection ThisElem.Set=CurrentSet; ThisElem.Flags=0; ThisBrush.Delete(); ThisBrush.SetSize(Width,Height); for (int Y=0; YGetTexCache(); int TexID=TexCache.ProcessTexture((char*)Filename.FullName(),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());} } /*****************************************************************************/ BOOL CTileSet::IsTileValidGB(int No) { // ASSERT(NoTile.size()) return(FALSE); return(Tile[No].IsValidGB()); } /*****************************************************************************/ 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(Vector3 &CamPos) { 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,CMapEditView *View,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); View->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); }