/******************/ /*** Layer Tile ***/ /******************/ #include "stdafx.h" #include #include #include #include "GLEnabledView.h" #include "MapEdit.h" #include "MapEditDoc.h" #include "MapEditView.h" #include "MainFrm.h" #include "Core.h" #include "Layer.h" #include "LayerTile.h" #include "Utils.h" #include "Select.h" #include "Export.h" /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ // New Layer CLayerTile::CLayerTile(int _SubType,int Width,int Height) { SubType=_SubType; if (SubType==LAYERTILE_BACK) // Back is fixed size { Width=32; Height=32; } SetDefaultParams(); Mode=MouseModePaint; if (ResizeFlag) { Width=TileLayerMinWidth+(Width-TileLayerMinWidth)/ScaleFactor; Height=TileLayerMinHeight+(Height-TileLayerMinHeight)/ScaleFactor; } if (WidthRead(&Render3dFlag,sizeof(BOOL)); File->Read(&ScaleFactor,sizeof(float)); File->Read(&ResizeFlag,sizeof(BOOL)); File->Read(&VisibleFlag,sizeof(BOOL)); File->Read(&Mode,sizeof(MouseMode)); File->Read(&SubType,sizeof(int)); Map.Load(File,Version); TRACE1("%s\t",GetName()); TRACE1("Scl:%g\t",ScaleFactor); TRACE1("%i\n",VisibleFlag); } /*****************************************************************************/ void CLayerTile::Save(CFile *File) { // Always Save current version File->Write(&Render3dFlag,sizeof(BOOL)); File->Write(&ScaleFactor,sizeof(float)); File->Write(&ResizeFlag,sizeof(BOOL)); File->Write(&VisibleFlag,sizeof(BOOL)); File->Write(&Mode,sizeof(MouseMode)); File->Write(&SubType,sizeof(SubType)); Map.Save(File); } /*****************************************************************************/ void CLayerTile::CheckLayerSize(int Width,int Height) { if (Resize(Width,Height)) { CString mexstr; mexstr.Format("%s Layer Resized to Correct Size\nPlease re-save\n", GetName()); AfxMessageBox(mexstr,MB_OK | MB_ICONEXCLAMATION); } } /*****************************************************************************/ BOOL CLayerTile::Resize(int Width,int Height) { if (!ResizeFlag) return(FALSE); // Its a fixed size, so DONT DO IT! int ThisWidth=Map.GetWidth(); int ThisHeight=Map.GetHeight(); Width=TileLayerMinWidth+(Width-TileLayerMinWidth)/ScaleFactor; Height=TileLayerMinHeight+(Height-TileLayerMinHeight)/ScaleFactor; if (ThisWidth!=Width || ThisHeight!=Height) { Map.Resize(Width,Height); return(TRUE); } return(FALSE); } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ void CLayerTile::Render(CCore *Core,Vector3 &CamPos,BOOL Is3d) { Vector3 ThisCam=Core->OffsetCam(CamPos,GetScaleFactor()); if (Is3d && Render3dFlag) { glEnable(GL_DEPTH_TEST); Render(Core,ThisCam,Map,TRUE); glDisable(GL_DEPTH_TEST); } else { Render(Core,ThisCam,Map,FALSE); } } /*****************************************************************************/ void CLayerTile::RenderCursorPaint(CCore *Core,Vector3 &CamPos,BOOL Is3d) { CTileBank &TileBank=Core->GetTileBank(); Vector3 ThisCam=Core->OffsetCam(CamPos,GetScaleFactor()); CPoint &CursPos=Core->GetCursorPos(); CMap &Brush=TileBank.GetActiveBrush(); Vector3 Ofs; if (!Brush.IsValid()) return; if (CursPos.x<0 || CursPos.y<0) return; Ofs.x=-(CursPos.x-(int)ThisCam.x); Ofs.y=-(CursPos.y-(int)ThisCam.y); ThisCam.x-=(int)ThisCam.x; ThisCam.y-=(int)ThisCam.y; if (Is3d && Render3dFlag) { glEnable(GL_DEPTH_TEST); Render(Core,ThisCam,Brush,TRUE,0.5,&Ofs); glDisable(GL_DEPTH_TEST); } else { Render(Core,ThisCam,Brush,FALSE,0.5,&Ofs); } } /*****************************************************************************/ void CLayerTile::Render(CCore *Core,Vector3 &ThisCam,CMap &ThisMap,BOOL Render3d,float Alpha,Vector3 *Ofs) { int MapWidth=ThisMap.GetWidth(); int MapHeight=ThisMap.GetHeight(); float ZoomW=Core->GetZoomW(); float ZoomH=Core->GetZoomH(); float ScrOfsX=(ZoomW/2); float ScrOfsY=(ZoomH/2); Vector3 &Scale=Core->GetScaleVector(); int StartX=(int)ThisCam.x; int StartY=(int)ThisCam.y; float ShiftX=ThisCam.x - (int)ThisCam.x; float ShiftY=ThisCam.y - (int)ThisCam.y; if (StartX<0) StartX=0; if (StartY<0) StartY=0; int DrawW=ZoomW+8; int DrawH=ZoomH+8; if (StartX+DrawW>MapWidth) DrawW=MapWidth-StartX; if (StartY+DrawH>MapHeight) DrawH=MapHeight-StartY; glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glScalef(Scale.x,Scale.y,Scale.z); glTranslatef(-ShiftX,ShiftY,0); // Set scroll offset glTranslatef(-ScrOfsX,ScrOfsY,0); // Bring to top left corner if (Ofs) { glTranslatef(-Ofs->x,Ofs->y,0); // Set scroll offset } glColor4f(1,1,1,Alpha); for (int YLoop=0; YLoopIsTileValid(ThisElem.Set,ThisElem.Tile)) { // Render Non Zero Tiles CTile &ThisTile=Core->GetTile(ThisElem.Set,ThisElem.Tile); ThisTile.Render(ThisElem.Flags,Render3d); } glTranslatef(1.0f,0,0); // Next X } glTranslatef(-DrawW,-1,0); // Next y, rewind to start X } glPopMatrix(); } /*****************************************************************************/ void CLayerTile::RenderSelection(CCore *Core,Vector3 &CamPos) { CRect Rect=Selection.GetRect(); Vector3 ThisCam=Core->OffsetCam(CamPos,GetScaleFactor()); float ZoomW=Core->GetZoomW(); float ZoomH=Core->GetZoomH(); float ScrOfsX=(ZoomW/2); float ScrOfsY=(ZoomH/2); Vector3 &Scale=Core->GetScaleVector(); if (!Selection.IsValid()) return; glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glScalef(Scale.x,Scale.y,Scale.z); glTranslatef(-ThisCam.x,ThisCam.y,0); glTranslatef(-ScrOfsX,ScrOfsY,0); // Bring to top left corner glColor4f(1,0,1,0.5f); glBegin (GL_QUADS); float X0=Rect.left; float X1=Rect.right; float Y0=Rect.top-1; float Y1=Rect.bottom-1; glVertex3f( X0, -Y0, 0); glVertex3f( X1, -Y0, 0); glVertex3f( X1, -Y1, 0); glVertex3f( X0, -Y1, 0); glEnd(); glPopMatrix(); } /*****************************************************************************/ void CLayerTile::RenderGrid(CCore *Core,Vector3 &CamPos,BOOL Active) { Vector3 ThisCam=Core->OffsetCam(CamPos,GetScaleFactor()); int MapWidth=Map.GetWidth(); int MapHeight=Map.GetHeight(); float ZoomW=Core->GetZoomW(); float ZoomH=Core->GetZoomH(); float ScrOfsX=(ZoomW/2); float ScrOfsY=(ZoomH/2); Vector3 &Scale=Core->GetScaleVector(); float Col; const float OverVal=0.1f; glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glScalef(Scale.x,Scale.y,Scale.z); glTranslatef(-ThisCam.x,ThisCam.y,0); glTranslatef(-ScrOfsX,ScrOfsY,0); // Bring to top left corner if (Active) Col=1; else Col=0.5f; glBegin(GL_LINES); glColor3f(Col,Col,Col); for (int YLoop=0; YLoopOffsetCam(CamPos,GetScaleFactor()); int MapWidth=Map.GetWidth(); int MapHeight=Map.GetHeight(); float ZoomW=Core->GetZoomW(); float ZoomH=Core->GetZoomH(); float ScrOfsX=(ZoomW/2); float ScrOfsY=(ZoomH/2); Vector3 &Scale=Core->GetScaleVector(); GLint Viewport[4]; GLuint SelectBuffer[SELECT_BUFFER_SIZE]; int TileID=0; CPoint &CursorPos=Core->GetCursorPos(); int StartX=(int)ThisCam.x; int StartY=(int)ThisCam.y; float ShiftX=ThisCam.x - (int)ThisCam.x; float ShiftY=ThisCam.y - (int)ThisCam.y; if (StartX<0) StartX=0; if (StartY<0) StartY=0; int DrawW=ZoomW+8; int DrawH=ZoomH+8; if (StartX+DrawW>MapWidth) DrawW=MapWidth-StartX; if (StartY+DrawH>MapHeight) DrawH=MapHeight-StartY; 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(); glLoadIdentity(); glScalef(Scale.x,Scale.y,Scale.z); // glTranslatef(-ThisCam.x,ThisCam.y,0); glTranslatef(-ShiftX,ShiftY,0); glTranslatef(-ScrOfsX,ScrOfsY,0); // Bring to top left corner for (int YLoop=0; YLoopGetMainWnd(); CMultiBar *ParamBar=Frm->GetParamBar(); ParamBar->Add(Frm->GetLayerTileToolbar(),IDD_LAYERTILE_TOOLBAR,TRUE); ParamBar->Add(Frm->GetLayerTileGUI(),IDD_LAYERTILE_GUI,TRUE); } /*****************************************************************************/ void CLayerTile::UpdateGUI(CCore *Core) { CMainFrame *Frm=(CMainFrame*)AfxGetApp()->GetMainWnd(); CLayerTileToolbar *Bar=(CLayerTileToolbar *)Frm->GetDialog(IDD_LAYERTILE_TOOLBAR); if (Bar) { Bar->ResetButtons(); switch(Mode) { case MouseModePaint: Bar->SetButtonState(CLayerTileToolbar::PAINT,TRUE); break; case MouseModeSelect: Bar->SetButtonState(CLayerTileToolbar::SELECT,TRUE); break; default: break; } } Core->UpdateTileViewGUI(); } /*****************************************************************************/ /*** Functions ***************************************************************/ /*****************************************************************************/ BOOL CLayerTile::SetMode(int NewMode) { BOOL Ret=FALSE; // Clean up last mode Ret|=ExitMode(); Mode=(MouseMode)NewMode; Ret|=InitMode(); return(Ret); } /*****************************************************************************/ BOOL CLayerTile::InitMode() { switch(Mode) { case MouseModePaint: break; case MouseModeSelect: break; default: break; } return(FALSE); } /*****************************************************************************/ BOOL CLayerTile::ExitMode() { switch(Mode) { case MouseModePaint: break; case MouseModeSelect: break; default: break; } return(FALSE); } /*****************************************************************************/ BOOL CLayerTile::LButtonControl(CCore *Core,CMapEditView *View,UINT nFlags, CPoint &CursorPos,BOOL DownFlag) { BOOL Ret=FALSE; CTileBank &TileBank=Core->GetTileBank(); switch(Mode) { case MouseModePaint: if (DownFlag) Ret=Paint(TileBank.GetLBrush(),CursorPos); break; case MouseModeSelect: Ret=Selection.Handle(CursorPos,nFlags); if (Selection.HasSelection()) { TRACE0("LMB Selection\n"); } break; default: break; } return(Ret); } /*****************************************************************************/ BOOL CLayerTile::RButtonControl(CCore *Core,CMapEditView *View,UINT nFlags, CPoint &CursorPos,BOOL DownFlag) { BOOL Ret=FALSE; CTileBank &TileBank=Core->GetTileBank(); switch(Mode) { case MouseModePaint: if (DownFlag) Ret=Paint(TileBank.GetRBrush(),CursorPos); break; case MouseModeSelect: Ret=Selection.Handle(CursorPos,nFlags); if (Selection.HasSelection()) { TRACE0("RMB Selection\n"); } break; default: break; } return(Ret); } /*****************************************************************************/ BOOL CLayerTile::MouseMove(CCore *Core,CMapEditView *View,UINT nFlags, CPoint &CursorPos) { BOOL Ret=FALSE; CTileBank &TileBank=Core->GetTileBank(); switch(Mode) { case MouseModePaint: if (nFlags & MK_LBUTTON) Ret=Paint(TileBank.GetLBrush(),CursorPos); else if (nFlags & MK_RBUTTON) Ret=Paint(TileBank.GetRBrush(),CursorPos); break; case MouseModeSelect: Ret=Selection.Handle(CursorPos,nFlags); break; default: break; } return(Ret); } /*****************************************************************************/ void CLayerTile::RenderCursor(CCore *Core,Vector3 &CamPos,BOOL Is3d) { switch(Mode) { case MouseModePaint: RenderCursorPaint(Core,CamPos,Is3d); break; case MouseModeSelect: RenderSelection(Core,CamPos); break; default: break; } } /*****************************************************************************/ BOOL CLayerTile::MirrorX(CCore *Core) { switch(Mode) { case MouseModePaint: { CTileBank &TileBank=Core->GetTileBank(); TileBank.GetLBrush().MirrorX(TILE_FLAG_MIRROR_X); TileBank.GetRBrush().MirrorX(TILE_FLAG_MIRROR_X); } break; case MouseModeSelect: { if (!Selection.IsValid()) return(false); // No Selection CRect R=Selection.GetRect(); Map.MirrorX(TILE_FLAG_MIRROR_X,&R); } break; default: break; } return(TRUE); } /*****************************************************************************/ BOOL CLayerTile::MirrorY(CCore *Core) { switch(Mode) { case MouseModePaint: { CTileBank &TileBank=Core->GetTileBank(); TileBank.GetLBrush().MirrorY(TILE_FLAG_MIRROR_Y); TileBank.GetRBrush().MirrorY(TILE_FLAG_MIRROR_Y); } break; case MouseModeSelect: { if (!Selection.IsValid()) return(false); // No Selection CRect R=Selection.GetRect(); Map.MirrorY(TILE_FLAG_MIRROR_Y,&R); } break; default: break; } return(TRUE); } /*****************************************************************************/ BOOL CLayerTile::CopySelection(CCore *Core) { if (Mode!=MouseModeSelect) return(false); // Not in select mode if (!Selection.IsValid()) return(false); // No Selection CTileBank &TileBank=Core->GetTileBank(); CRect Rect=Selection.GetRect(); TileBank.GetActiveBrush().Set(Map,Rect.left,Rect.top,Rect.Width(),Rect.Height()); return(true); } /*****************************************************************************/ BOOL CLayerTile::PasteSelection(CCore *Core) { if (Mode!=MouseModeSelect) return(false); // Not in select mode if (!Selection.IsValid()) return(false); // No Selection CTileBank &TileBank=Core->GetTileBank(); CRect Rect=Selection.GetRect(); Map.Paste(TileBank.GetActiveBrush(),&Rect); return(true); } /*****************************************************************************/ /*****************************************************************************/ /*****************************************************************************/ BOOL CLayerTile::Paint(CMap &Blk,CPoint &CursorPos) { if (CursorPos.y==-1 || CursorPos.y==-1) return(FALSE); // Off Map? if (!Blk.IsValid()) return(FALSE); // Invalid tile? Map.Set(CursorPos.x,CursorPos.y,Blk); return(TRUE); } /*****************************************************************************/ void CLayerTile::Export(CCore *Core,CExport &Exp) { Exp.ExportLayerTile(Core,GetName(),SubType,Map); } /*****************************************************************************/ void CLayerTile::DeleteSet(int Set) { Map.DeleteSet(Set); } /*****************************************************************************/ void CLayerTile::RemapSet(int OrigSet,int NewSet) { Map.RemapSet(OrigSet,NewSet); }