diff --git a/src/PowderToy.cpp b/src/PowderToy.cpp index c7b6da0fe..406e33479 100644 --- a/src/PowderToy.cpp +++ b/src/PowderToy.cpp @@ -88,6 +88,7 @@ int main(int argc, char * argv[]) engine->onKeyPress(event.key.keysym.unicode, false, false, false); break; case SDL_KEYUP: + engine->onKeyRelease(event.key.keysym.unicode, false, false, false); break; case SDL_MOUSEMOTION: engine->onMouseMove(event.motion.x, event.motion.y); diff --git a/src/Renderer.cpp b/src/Renderer.cpp index 9d263789c..5375d6407 100644 --- a/src/Renderer.cpp +++ b/src/Renderer.cpp @@ -19,6 +19,118 @@ extern "C" #include "hmap.h" } +void Renderer::RenderZoom() +{ + if(!zoomEnabled) + return; + #ifdef OGLR + int origBlendSrc, origBlendDst; + float zcx1, zcx0, zcy1, zcy0, yfactor, xfactor, i; //X-Factor is shit, btw + xfactor = 1.0f/(float)XRES; + yfactor = 1.0f/(float)YRES; + + zcx0 = (zoom_x)*xfactor; + zcx1 = (zoom_x+ZSIZE)*xfactor; + zcy0 = (zoom_y)*yfactor; + zcy1 = ((zoom_y+ZSIZE))*yfactor; + + glGetIntegerv(GL_BLEND_SRC, &origBlendSrc); + glGetIntegerv(GL_BLEND_DST, &origBlendDst); + glBlendFunc(GL_ONE, GL_ZERO); + + glEnable( GL_TEXTURE_2D ); + //glReadBuffer(GL_AUX0); + glBindTexture(GL_TEXTURE_2D, partsFboTex); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_QUADS); + glTexCoord2d(zcx1, zcy1); + glVertex3f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 1.0); + glTexCoord2d(zcx0, zcy1); + glVertex3f(zoom_wx*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 1.0); + glTexCoord2d(zcx0, zcy0); + glVertex3f(zoom_wx*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 1.0); + glTexCoord2d(zcx1, zcy0); + glVertex3f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 1.0); + glEnd(); + glBindTexture(GL_TEXTURE_2D, 0); + glDisable( GL_TEXTURE_2D ); + + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + glLineWidth(sdl_scale); + glEnable(GL_LINE_SMOOTH); + glBegin(GL_LINES); + glColor4f(0.0f, 0.0f, 0.0f, 1.0f); + for(i = 0; i < ZSIZE; i++) + { + glVertex2f((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR)+i*ZFACTOR)*sdl_scale); + glVertex2f(zoom_wx*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR)+i*ZFACTOR)*sdl_scale); + glVertex2f((zoom_wx+i*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale); + glVertex2f((zoom_wx+i*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale); + } + glEnd(); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_LINE_STRIP); + glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0); + glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 0); + glVertex3i((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-(zoom_wy+ZSIZE*ZFACTOR))*sdl_scale, 0); + glVertex3i((zoom_wx+ZSIZE*ZFACTOR)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0); + glVertex3i((zoom_wx-1)*sdl_scale, (YRES+MENUSIZE-zoom_wy)*sdl_scale, 0); + glEnd(); + glDisable(GL_LINE_SMOOTH); + + glDisable(GL_LINE_SMOOTH); + + if(zoom_en) + { + glEnable(GL_COLOR_LOGIC_OP); + //glEnable(GL_LINE_SMOOTH); + glLogicOp(GL_XOR); + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + glBegin(GL_LINE_STRIP); + glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0); + glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y+ZSIZE))*sdl_scale, 0); + glVertex3i((zoom_x+ZSIZE)*sdl_scale, (YRES+MENUSIZE-(zoom_y+ZSIZE))*sdl_scale, 0); + glVertex3i((zoom_x+ZSIZE)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0); + glVertex3i((zoom_x-1)*sdl_scale, (YRES+MENUSIZE-(zoom_y-1))*sdl_scale, 0); + glEnd(); + glDisable(GL_COLOR_LOGIC_OP); + } + glLineWidth(1); + glBlendFunc(origBlendSrc, origBlendDst); + #else + int x, y, i, j; + pixel pix; + pixel * img = g->vid; + g->drawrect(zoomWindowPosition.X-2, zoomWindowPosition.Y-2, zoomScopeSize*ZFACTOR+2, zoomScopeSize*ZFACTOR+2, 192, 192, 192, 255); + g->drawrect(zoomWindowPosition.X-1, zoomWindowPosition.Y-1, zoomScopeSize*ZFACTOR, zoomScopeSize*ZFACTOR, 0, 0, 0, 255); + g->clearrect(zoomWindowPosition.X, zoomWindowPosition.Y, zoomScopeSize*ZFACTOR, zoomScopeSize*ZFACTOR); + for (j=0; jxor_pixel(zoomScopePosition.X+j, zoomScopePosition.Y-1); + g->xor_pixel(zoomScopePosition.X+j, zoomScopePosition.Y+zoomScopeSize); + } + for (j=0; jxor_pixel(zoomScopePosition.X-1, zoomScopePosition.Y+j); + g->xor_pixel(zoomScopePosition.X+zoomScopeSize, zoomScopePosition.Y+j); + } + } + #endif +} + void Renderer::DrawWalls() { int x, y, i, j, cr, cg, cb; @@ -1645,7 +1757,11 @@ void Renderer::draw_grav_zones() Renderer::Renderer(Graphics * g, Simulation * sim): sim(NULL), - g(NULL) + g(NULL), + zoomWindowPosition(0, 0), + zoomScopePosition(0, 0), + zoomScopeSize(10), + ZFACTOR(8) { this->g = g; this->sim = sim; diff --git a/src/Renderer.h b/src/Renderer.h index d43e0cb5f..9ed7dbbeb 100644 --- a/src/Renderer.h +++ b/src/Renderer.h @@ -5,6 +5,7 @@ #include "Config.h" #include "simulation/Simulation.h" #include "Graphics.h" +#include "interface/Point.h" class Simulation; @@ -41,7 +42,15 @@ public: Graphics * g; gcache_item *graphicscache; + //Zoom window + ui::Point zoomWindowPosition; + ui::Point zoomScopePosition; + int zoomScopeSize; + bool zoomEnabled; + int ZFACTOR; + //Renderers + void RenderZoom(); void DrawWalls(); void DrawSigns(); void render_gravlensing(); diff --git a/src/game/GameController.cpp b/src/game/GameController.cpp index 277c32c1e..752a0babd 100644 --- a/src/game/GameController.cpp +++ b/src/game/GameController.cpp @@ -107,6 +107,36 @@ void GameController::AdjustBrushSize(int direction) gameModel->GetBrush()->SetRadius(newSize); } +void GameController::AdjustZoomSize(int direction) +{ + int newSize = gameModel->GetZoomSize()+direction; + if(newSize<5) + newSize = 5; + if(newSize>64) + newSize = 64; + gameModel->SetZoomSize(newSize); + + int newZoomFactor = 256/newSize; + if(newZoomFactor<3) + newZoomFactor = 3; + gameModel->SetZoomFactor(newZoomFactor); +} + +ui::Point GameController::PointTranslate(ui::Point point) +{ + bool zoomEnabled = gameModel->GetZoomEnabled(); + if(!zoomEnabled) + return point; + //If we try to draw inside the zoom window, normalise the coordinates + int zoomFactor = gameModel->GetZoomFactor(); + ui::Point zoomWindowPosition = gameModel->GetZoomWindowPosition(); + ui::Point zoomWindowSize = ui::Point(gameModel->GetZoomSize()*zoomFactor, gameModel->GetZoomSize()*zoomFactor); + + if(point.X > zoomWindowPosition.X && point.X > zoomWindowPosition.Y && point.X < zoomWindowPosition.X+zoomWindowSize.X && point.Y < zoomWindowPosition.Y+zoomWindowSize.Y) + return ((point-zoomWindowPosition)/gameModel->GetZoomFactor())+gameModel->GetZoomPosition(); + return point; +} + void GameController::DrawPoints(queue & pointQueue) { Simulation * sim = gameModel->GetSimulation(); @@ -123,26 +153,27 @@ void GameController::DrawPoints(queue & pointQueue) } } } + if(!pointQueue.empty()) { - ui::Point * sPoint = NULL; + ui::Point sPoint(0, 0); + bool first = true; while(!pointQueue.empty()) { - ui::Point * fPoint = pointQueue.front(); + ui::Point fPoint = PointTranslate(*pointQueue.front()); + delete pointQueue.front(); pointQueue.pop(); - if(sPoint) + if(!first) { - activeTool->DrawLine(sim, cBrush, *fPoint, *sPoint); - delete sPoint; + activeTool->DrawLine(sim, cBrush, fPoint, sPoint); } else { - activeTool->Draw(sim, cBrush, *fPoint); + first = false; + activeTool->Draw(sim, cBrush, fPoint); } sPoint = fPoint; } - if(sPoint) - delete sPoint; } } @@ -168,6 +199,25 @@ void GameController::Update() } } +void GameController::SetZoomEnabled(bool zoomEnabled) +{ + gameModel->SetZoomEnabled(zoomEnabled); +} + +void GameController::SetZoomPosition(ui::Point position) +{ + ui::Point zoomPosition = position-(gameModel->GetZoomSize()/2); + if(zoomPosition.X < 0) + zoomPosition.X = 0; + if(zoomPosition.Y < 0) + zoomPosition.Y = 0; + if(zoomPosition.X >= XRES-gameModel->GetZoomSize()) + zoomPosition.X = XRES-gameModel->GetZoomSize(); + if(zoomPosition.Y >= YRES-gameModel->GetZoomSize()) + zoomPosition.Y = YRES-gameModel->GetZoomSize(); + gameModel->SetZoomPosition(zoomPosition); +} + void GameController::SetPaused(bool pauseState) { gameModel->SetPaused(pauseState); diff --git a/src/game/GameController.h b/src/game/GameController.h index 2ec4523a3..7498e4787 100644 --- a/src/game/GameController.h +++ b/src/game/GameController.h @@ -31,7 +31,10 @@ public: GameController(); ~GameController(); GameView * GetView(); + void SetZoomEnabled(bool zoomEnable); + void SetZoomPosition(ui::Point position); void AdjustBrushSize(int direction); + void AdjustZoomSize(int direction); void DrawPoints(queue & pointQueue); void Update(); void SetPaused(bool pauseState); @@ -48,6 +51,7 @@ public: void ReloadSim(); void Vote(int direction); void ChangeBrush(); + ui::Point PointTranslate(ui::Point point); }; #endif // GAMECONTROLLER_H diff --git a/src/game/GameModel.cpp b/src/game/GameModel.cpp index 5dfc521dd..456d9c4b8 100644 --- a/src/game/GameModel.cpp +++ b/src/game/GameModel.cpp @@ -160,6 +160,61 @@ User GameModel::GetUser() return currentUser; } +void GameModel::SetZoomEnabled(bool enabled) +{ + ren->zoomEnabled = enabled; + notifyZoomChanged(); +} + +bool GameModel::GetZoomEnabled() +{ + return ren->zoomEnabled; +} + +void GameModel::SetZoomPosition(ui::Point position) +{ + ren->zoomScopePosition = position; + notifyZoomChanged(); +} + +ui::Point GameModel::GetZoomPosition() +{ + return ren->zoomScopePosition; +} + +void GameModel::SetZoomWindowPosition(ui::Point position) +{ + ren->zoomWindowPosition = position; + notifyZoomChanged(); +} + +ui::Point GameModel::GetZoomWindowPosition() +{ + return ren->zoomWindowPosition; +} + +void GameModel::SetZoomSize(int size) +{ + ren->zoomScopeSize = size; + notifyZoomChanged(); +} + +int GameModel::GetZoomSize() +{ + return ren->zoomScopeSize; +} + +void GameModel::SetZoomFactor(int factor) +{ + ren->ZFACTOR = factor; + notifyZoomChanged(); +} + +int GameModel::GetZoomFactor() +{ + return ren->ZFACTOR; +} + void GameModel::SetUser(User user) { currentUser = user; @@ -253,3 +308,11 @@ void GameModel::notifyUserChanged() observers[i]->NotifyUserChanged(this); } } + +void GameModel::notifyZoomChanged() +{ + for(int i = 0; i < observers.size(); i++) + { + observers[i]->NotifyZoomChanged(this); + } +} diff --git a/src/game/GameModel.h b/src/game/GameModel.h index 72e28758f..3c26bf3b4 100644 --- a/src/game/GameModel.h +++ b/src/game/GameModel.h @@ -32,6 +32,7 @@ private: Renderer * ren; Tool * activeTool; User currentUser; + //bool zoomEnabled; void notifyRendererChanged(); void notifySimulationChanged(); void notifyPausedChanged(); @@ -41,6 +42,7 @@ private: void notifyToolListChanged(); void notifyActiveToolChanged(); void notifyUserChanged(); + void notifyZoomChanged(); public: GameModel(); ~GameModel(); @@ -64,6 +66,16 @@ public: int GetBrushID(); Simulation * GetSimulation(); Renderer * GetRenderer(); + void SetZoomEnabled(bool enabled); + bool GetZoomEnabled(); + void SetZoomSize(int size); + int GetZoomSize(); + void SetZoomFactor(int factor); + int GetZoomFactor(); + void SetZoomPosition(ui::Point position); + ui::Point GetZoomPosition(); + void SetZoomWindowPosition(ui::Point position); + ui::Point GetZoomWindowPosition(); }; #endif // GAMEMODEL_H diff --git a/src/game/GameView.cpp b/src/game/GameView.cpp index 3a20b3e12..3b1cd26d3 100644 --- a/src/game/GameView.cpp +++ b/src/game/GameView.cpp @@ -380,7 +380,7 @@ void GameView::OnMouseMove(int x, int y, int dx, int dy) void GameView::OnMouseDown(int x, int y, unsigned button) { - if(currentMouse.X > 0 && currentMouse.X < XRES && currentMouse.Y > 0 && currentMouse.Y < YRES) + if(currentMouse.X > 0 && currentMouse.X < XRES && currentMouse.Y > 0 && currentMouse.Y < YRES && !(zoomEnabled && !zoomCursorFixed)) { isMouseDown = true; pointQueue.push(new ui::Point(x, y)); @@ -389,10 +389,15 @@ void GameView::OnMouseDown(int x, int y, unsigned button) void GameView::OnMouseUp(int x, int y, unsigned button) { - if(isMouseDown) + if(zoomEnabled && !zoomCursorFixed) + zoomCursorFixed = true; + else { - isMouseDown = false; - pointQueue.push(new ui::Point(x, y)); + if(isMouseDown) + { + isMouseDown = false; + pointQueue.push(new ui::Point(x, y)); + } } } @@ -400,10 +405,17 @@ void GameView::OnMouseWheel(int x, int y, int d) { if(!d) return; - c->AdjustBrushSize(d); - if(isMouseDown) + if(zoomEnabled && !zoomCursorFixed) { - pointQueue.push(new ui::Point(x, y)); + c->AdjustZoomSize(d); + } + else + { + c->AdjustBrushSize(d); + if(isMouseDown) + { + pointQueue.push(new ui::Point(x, y)); + } } } @@ -417,11 +429,29 @@ void GameView::OnKeyPress(int key, bool shift, bool ctrl, bool alt) case KEY_TAB: //Tab c->ChangeBrush(); break; + case 'z': + isMouseDown = false; + zoomCursorFixed = false; + c->SetZoomEnabled(true); + break; } } +void GameView::OnKeyRelease(int key, bool shift, bool ctrl, bool alt) +{ + //switch(key) + //{ + //case 'z': + if(!zoomCursorFixed) + c->SetZoomEnabled(false); + // break; + //} +} + void GameView::OnTick(float dt) { + if(zoomEnabled && !zoomCursorFixed) + c->SetZoomPosition(currentMouse); if(isMouseDown) { pointQueue.push(new ui::Point(currentMouse)); @@ -433,17 +463,23 @@ void GameView::OnTick(float dt) c->Update(); } +void GameView::NotifyZoomChanged(GameModel * sender) +{ + zoomEnabled = sender->GetZoomEnabled(); +} + void GameView::OnDraw() { if(ren) { ren->render_parts(); ren->render_fire(); - ren->DrawSigns(); ren->DrawWalls(); - } - if(activeBrush && currentMouse.X > 0 && currentMouse.X < XRES && currentMouse.Y > 0 && currentMouse.Y < YRES) - { - activeBrush->Render(ui::Engine::Ref().g, currentMouse); + if(activeBrush && currentMouse.X > 0 && currentMouse.X < XRES && currentMouse.Y > 0 && currentMouse.Y < YRES) + { + activeBrush->Render(ui::Engine::Ref().g, c->PointTranslate(currentMouse)); + } + ren->RenderZoom(); + ren->DrawSigns(); } } diff --git a/src/game/GameView.h b/src/game/GameView.h index f0c3e8256..610b953ca 100644 --- a/src/game/GameView.h +++ b/src/game/GameView.h @@ -18,6 +18,8 @@ class GameView: public ui::Window { private: bool isMouseDown; + bool zoomEnabled; + bool zoomCursorFixed; queue pointQueue; GameController * c; Renderer * ren; @@ -49,11 +51,13 @@ public: void NotifyToolListChanged(GameModel * sender); void NotifyActiveToolChanged(GameModel * sender); void NotifyUserChanged(GameModel * sender); + void NotifyZoomChanged(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); virtual void OnMouseWheel(int x, int y, int d); virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt); + virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt); //virtual void OnKeyPress(int key, bool shift, bool ctrl, bool alt) {} //virtual void OnKeyRelease(int key, bool shift, bool ctrl, bool alt) {} virtual void OnTick(float dt); diff --git a/src/interface/Point.h b/src/interface/Point.h index 0d0250cbc..d2eff6b27 100644 --- a/src/interface/Point.h +++ b/src/interface/Point.h @@ -32,11 +32,21 @@ struct Point return Point(X + v.X, Y + v.Y); } + inline Point operator + (const int v) const + { + return Point(X + v, Y + v); + } + inline Point operator - (const Point& v) const { return Point(X - v.X, Y - v.Y); } + inline Point operator - (const int v) const + { + return Point(X - v, Y - v); + } + inline Point operator * (const Point& v) const { return Point(X * v.X, Y * v.Y);