diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp index 80f45ff87..a4a99c2b9 100644 --- a/src/game/GameController.cpp +++ b/src/game/GameController.cpp @@ -241,6 +241,25 @@ void GameController::DrawPoints(int toolSelection, queue & pointQueu } } +void GameController::StampRegion(ui::Point point1, ui::Point point2) +{ + int saveSize; + unsigned char * saveData; + saveData = gameModel->GetSimulation()->Save(point1.X, point1.Y, point2.X, point2.Y, saveSize); + if(saveData && saveSize) + gameModel->AddStamp(saveData, saveSize); +} + +void GameController::CopyRegion(ui::Point point1, ui::Point point2) +{ + int saveSize; + unsigned char * saveData; + saveData = gameModel->GetSimulation()->Save(point1.X, point1.Y, point2.X, point2.Y, saveSize); + + if(saveData && saveSize) + gameModel->SetClipboard(saveData, saveSize); +} + void GameController::Update() { gameModel->GetSimulation()->update_particles(); diff --git a/src/game/GameController.h b/src/game/GameController.h index d405051c0..cf26f5100 100644 --- a/src/game/GameController.h +++ b/src/game/GameController.h @@ -52,6 +52,8 @@ public: void DrawRect(int toolSelection, ui::Point point1, ui::Point point2); void DrawLine(int toolSelection, ui::Point point1, ui::Point point2); void DrawFill(int toolSelection, ui::Point point); + void StampRegion(ui::Point point1, ui::Point point2); + void CopyRegion(ui::Point point1, ui::Point point2); void Update(); void SetPaused(bool pauseState); void SetPaused(); diff --git a/src/game/GameModel.cpp b/src/game/GameModel.cpp index bcc52c769..85f4249c4 100644 --- a/src/game/GameModel.cpp +++ b/src/game/GameModel.cpp @@ -16,7 +16,8 @@ GameModel::GameModel(): currentBrush(0), currentUser(0, ""), currentSave(NULL), - colourSelector(false) + colourSelector(false), + clipboardData(NULL) { sim = new Simulation(); ren = new Renderer(ui::Engine::Ref().g, sim); @@ -405,6 +406,27 @@ void GameModel::ClearSimulation() sim->clear_sim(); } +void GameModel::AddStamp(unsigned char * saveData, int saveSize) +{ + //Do nothing + + //die alone +} + +void GameModel::SetClipboard(unsigned char * saveData, int saveSize) +{ + if(clipboardData) + free(clipboardData); + clipboardData = saveData; + clipboardSize = saveSize; +} + +unsigned char * GameModel::GetClipboard(int & saveSize) +{ + saveSize = clipboardSize; + return clipboardData; +} + void GameModel::notifyColourSelectorColourChanged() { for(int i = 0; i < observers.size(); i++) @@ -508,3 +530,11 @@ void GameModel::notifyZoomChanged() observers[i]->NotifyZoomChanged(this); } } + +void GameModel::notifyClipboardChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + observers[i]->NotifyClipboardChanged(this); + } +} diff --git a/src/game/GameModel.h b/src/game/GameModel.h index 0f170df9f..14e42acaa 100644 --- a/src/game/GameModel.h +++ b/src/game/GameModel.h @@ -31,6 +31,8 @@ public: class GameModel { private: + int clipboardSize; + unsigned char * clipboardData; vector observers; vector toolList; vector menuList; @@ -56,6 +58,7 @@ private: void notifyActiveToolsChanged(); void notifyUserChanged(); void notifyZoomChanged(); + void notifyClipboardChanged(); void notifyColourSelectorColourChanged(); void notifyColourSelectorVisibilityChanged(); public: @@ -101,6 +104,9 @@ public: ui::Point GetZoomPosition(); void SetZoomWindowPosition(ui::Point position); ui::Point GetZoomWindowPosition(); + void AddStamp(unsigned char * saveData, int saveSize); + void SetClipboard(unsigned char * saveData, int saveSize); + unsigned char * GetClipboard(int & saveSize); }; #endif // GAMEMODEL_H diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index 1fa039c4a..16f755107 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -21,7 +21,10 @@ GameView::GameView(): drawPoint1(0, 0), drawPoint2(0, 0), drawMode(DrawPoints), - drawModeReset(false) + drawModeReset(false), + selectMode(SelectNone), + selectPoint1(0, 0), + selectPoint2(0, 0) { int currentX = 1; //Set up UI @@ -461,6 +464,12 @@ void GameView::NotifyBrushChanged(GameModel * sender) void GameView::OnMouseMove(int x, int y, int dx, int dy) { + if(selectMode!=SelectNone) + { + if(selectPoint1.X!=-1) + selectPoint2 = ui::Point(x, y); + return; + } currentMouse = ui::Point(x, y); if(isMouseDown && drawMode == DrawPoints) { @@ -471,6 +480,15 @@ void GameView::OnMouseMove(int x, int y, int dx, int dy) void GameView::OnMouseDown(int x, int y, unsigned button) { + if(selectMode!=SelectNone) + { + if(button!=3) + { + selectPoint1 = ui::Point(x, y); + selectPoint2 = selectPoint1; + } + return; + } if(currentMouse.X > 0 && currentMouse.X < XRES && currentMouse.Y > 0 && currentMouse.Y < YRES && !(zoomEnabled && !zoomCursorFixed)) { if(button == BUTTON_LEFT) @@ -493,6 +511,23 @@ void GameView::OnMouseDown(int x, int y, unsigned button) void GameView::OnMouseUp(int x, int y, unsigned button) { + if(selectMode!=SelectNone) + { + int x2 = (selectPoint1.X>selectPoint2.X)?selectPoint1.X:selectPoint2.X; + int y2 = (selectPoint1.Y>selectPoint2.Y)?selectPoint1.Y:selectPoint2.Y; + int x1 = (selectPoint2.X0 && y2-y1>0) + { + if(selectMode==SelectCopy) + c->CopyRegion(ui::Point(x1, y1), ui::Point(x2, y2)); + else if(selectMode==SelectStamp) + c->StampRegion(ui::Point(x1, y1), ui::Point(x2, y2)); + } + selectMode = SelectNone; + return; + } + if(zoomEnabled && !zoomCursorFixed) zoomCursorFixed = true; else @@ -529,6 +564,10 @@ void GameView::OnMouseWheel(int x, int y, int d) { if(!d) return; + if(selectMode!=SelectNone) + { + return; + } if(zoomEnabled && !zoomCursorFixed) { c->AdjustZoomSize(d); @@ -545,6 +584,10 @@ void GameView::OnMouseWheel(int x, int y, int d) void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { + if(selectMode!=SelectNone) + { + return; + } switch(key) { case KEY_CTRL: @@ -588,11 +631,26 @@ void GameView::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool if(ctrl) c->SetDecoration(); break; + case 's': + selectMode = SelectStamp; + selectPoint1 = ui::Point(-1, -1); + break; + case 'c': + if(ctrl) + { + selectMode = SelectCopy; + selectPoint1 = ui::Point(-1, -1); + } + break; } } void GameView::OnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt) { + if(selectMode!=SelectNone) + { + return; + } if(!isMouseDown) drawMode = DrawPoints; else @@ -633,6 +691,11 @@ void GameView::NotifyZoomChanged(GameModel * sender) zoomEnabled = sender->GetZoomEnabled(); } +void GameView::NotifyClipboardChanged(GameModel * sender) +{ + //Could use this to have a mini preview of the clipboard, meh +} + void GameView::changeColour() { c->SetColour(ui::Colour(colourRSlider->GetValue(), colourGSlider->GetValue(), colourBSlider->GetValue(), colourASlider->GetValue())); @@ -642,6 +705,7 @@ void GameView::OnDraw() { if(ren) { + Graphics * g = ui::Engine::Ref().g; ren->render_parts(); ren->render_fire(); ren->DrawWalls(); @@ -649,18 +713,46 @@ void GameView::OnDraw() { if(drawMode==DrawRect && isMouseDown) { - activeBrush->RenderRect(ui::Engine::Ref().g, c->PointTranslate(drawPoint1), c->PointTranslate(currentMouse)); + activeBrush->RenderRect(g, c->PointTranslate(drawPoint1), c->PointTranslate(currentMouse)); } else if(drawMode==DrawLine && isMouseDown) { - activeBrush->RenderLine(ui::Engine::Ref().g, c->PointTranslate(drawPoint1), c->PointTranslate(currentMouse)); + activeBrush->RenderLine(g, c->PointTranslate(drawPoint1), c->PointTranslate(currentMouse)); } else { - activeBrush->RenderPoint(ui::Engine::Ref().g, c->PointTranslate(currentMouse)); + activeBrush->RenderPoint(g, c->PointTranslate(currentMouse)); } } ren->RenderZoom(); ren->DrawSigns(); + + if(selectMode!=SelectNone) + { + if(selectPoint1.X==-1) + { + g->fillrect(0, 0, XRES, YRES, 0, 0, 0, 100); + } + else + { + int x2 = (selectPoint1.X>selectPoint2.X)?selectPoint1.X:selectPoint2.X; + int y2 = (selectPoint1.Y>selectPoint2.Y)?selectPoint1.Y:selectPoint2.Y; + int x1 = (selectPoint2.XXRES-1) + x2 = XRES-1; + if(y2>YRES-1) + y2 = YRES-1; + + g->fillrect(0, 0, XRES, y1, 0, 0, 0, 100); + g->fillrect(0, y2, XRES, YRES-y2, 0, 0, 0, 100); + + g->fillrect(0, y1-1, x1, (y2-y1)+2, 0, 0, 0, 100); + g->fillrect(x2, y1-1, XRES-x2, (y2-y1)+2, 0, 0, 0, 100); + + g->xor_rect(x1, y1, (x2-x1)+1, (y2-y1)+1); + } + } } } diff --git a/src/game/GameView.h b/src/game/GameView.h index 18cd8e47a..0b3118279 100644 --- a/src/game/GameView.h +++ b/src/game/GameView.h @@ -19,6 +19,11 @@ enum DrawMode DrawPoints, DrawLine, DrawRect, DrawFill }; +enum SelectMode +{ + SelectNone, SelectStamp, SelectCopy +}; + class GameController; class GameModel; class GameView: public ui::Window @@ -57,6 +62,11 @@ private: bool drawModeReset; ui::Point drawPoint1; ui::Point drawPoint2; + + SelectMode selectMode; + ui::Point selectPoint1; + ui::Point selectPoint2; + void changeColour(); public: GameView(); @@ -73,6 +83,7 @@ public: void NotifyZoomChanged(GameModel * sender); void NotifyColourSelectorVisibilityChanged(GameModel * sender); void NotifyColourSelectorColourChanged(GameModel * sender); + void NotifyClipboardChanged(GameModel * sender); virtual void OnMouseMove(int x, int y, int dx, int dy); virtual void OnMouseDown(int x, int y, unsigned button); virtual void OnMouseUp(int x, int y, unsigned button); diff --git a/src/simulation/Simulation.cpp b/src/simulation/Simulation.cpp index 3f82f1bec..ceaae07b2 100644 --- a/src/simulation/Simulation.cpp +++ b/src/simulation/Simulation.cpp @@ -18,6 +18,11 @@ unsigned char * Simulation::Save(int & dataLength) return SaveLoader::BuildSave(dataLength, this, 0, 0, XRES, YRES); } +unsigned char * Simulation::Save(int x1, int y1, int x2, int y2, int & dataLength) +{ + return SaveLoader::BuildSave(dataLength, this, x1, y1, x2-x1, y2-y1); +} + void Simulation::clear_area(int area_x, int area_y, int area_w, int area_h) { int cx = 0; diff --git a/src/simulation/Simulation.h b/src/simulation/Simulation.h index 007f3c214..b33b3492b 100644 --- a/src/simulation/Simulation.h +++ b/src/simulation/Simulation.h @@ -208,6 +208,7 @@ public: int Load(unsigned char * data, int dataLength); unsigned char * Save(int & dataLength); + unsigned char * Save(int x1, int y1, int x2, int y2, int & dataLength); inline int is_blocking(int t, int x, int y); inline int is_boundary(int pt, int x, int y); inline int find_next_boundary(int pt, int *x, int *y, int dm, int *em);