diff --git a/base/PCMain.cpp b/base/PCMain.cpp
index 4510d008e2..7540cf1d22 100644
--- a/base/PCMain.cpp
+++ b/base/PCMain.cpp
@@ -234,13 +234,11 @@ int main(int argc, char *argv[]) {
bool nextFrameMD = 0;
float t = 0;
while (true) {
- SDL_Event event;
-
input_state.accelerometer_valid = false;
input_state.mouse_valid = true;
int quitRequested = 0;
- // input_state.mouse_down[1] = nextFrameMD;
+ SDL_Event event;
while (SDL_PollEvent(&event)) {
float mx = event.motion.x * dp_xscale;
float my = event.motion.y * dp_yscale;
@@ -289,7 +287,7 @@ int main(int argc, char *argv[]) {
SDL_GL_SwapBuffers();
- // Simple framerate limiting
+ // Simple frame rate limiting
while (time_now() < t + 1.0f/60.0f) {
sleep_ms(0);
time_update();
@@ -299,7 +297,8 @@ int main(int argc, char *argv[]) {
framecount++;
}
// Faster exit, thanks to the OS. Remove this if you want to debug shutdown
- exit(0);
+ // The speed difference is only really noticable on Linux. On Windows you do notice it though
+ // exit(0);
NativeShutdownGraphics();
SDL_PauseAudio(1);
@@ -307,5 +306,6 @@ int main(int argc, char *argv[]) {
SDL_CloseAudio();
SDL_Quit();
net::Shutdown();
+ exit(0);
return 0;
}
diff --git a/native.vcxproj b/native.vcxproj
index 0402ee4795..7c1069b6fd 100644
--- a/native.vcxproj
+++ b/native.vcxproj
@@ -148,6 +148,7 @@
+
@@ -211,6 +212,7 @@
+
diff --git a/native.vcxproj.filters b/native.vcxproj.filters
index 61af2a0391..8bda8682a6 100644
--- a/native.vcxproj.filters
+++ b/native.vcxproj.filters
@@ -181,6 +181,9 @@
android
+
+ ui
+
@@ -330,6 +333,9 @@
android
+
+ ui
+
diff --git a/ui/CMakeLists.txt b/ui/CMakeLists.txt
index 9a98c118d9..4b6f2c5758 100644
--- a/ui/CMakeLists.txt
+++ b/ui/CMakeLists.txt
@@ -1,5 +1,6 @@
set(SRCS
ui.cpp
+ screen.cpp
)
set(SRCS ${SRCS})
diff --git a/ui/screen.cpp b/ui/screen.cpp
new file mode 100644
index 0000000000..581c3eabd9
--- /dev/null
+++ b/ui/screen.cpp
@@ -0,0 +1,81 @@
+#include "base/logging.h"
+#include "input/input_state.h"
+#include "ui/screen.h"
+
+ScreenManager screenManager;
+
+Screen::Screen() { }
+Screen::~Screen() { }
+
+ScreenManager::ScreenManager() {
+ currentScreen_=0;
+ nextScreen_=0;
+}
+
+ScreenManager::~ScreenManager() {
+ delete currentScreen_;
+}
+
+void ScreenManager::switchScreen(Screen *screen) {
+ // Note that if a dialog is found, this will be a silent background switch that
+ // will only become apparent if the dialog is closed. The previous screen will stick around
+ // until that switch.
+ if (nextScreen_ != 0) {
+ FLOG("WTF? Already had nextScreen_");
+ }
+ nextScreen_ = screen;
+}
+
+void ScreenManager::update(const InputState &input) {
+ if (dialog_.size()) {
+ dialog_.back()->update(input);
+ return;
+ }
+
+ if (nextScreen_) {
+ Screen *temp = currentScreen_;
+ currentScreen_ = nextScreen_;
+ delete temp;
+ temp = 0;
+ nextScreen_ = 0;
+ }
+ if (currentScreen_) {
+ currentScreen_->update(input);
+ }
+}
+
+void ScreenManager::render() {
+ if (dialog_.size()) {
+ dialog_.back()->render();
+ }
+ if (currentScreen_) {
+ currentScreen_->render();
+ }
+ else {
+ ELOG("No current screen!");
+ }
+}
+
+void ScreenManager::shutdown() {
+ if (nextScreen_) {
+ delete nextScreen_;
+ nextScreen_ = 0;
+ }
+ if (currentScreen_) {
+ delete currentScreen_;
+ currentScreen_ = 0;
+ }
+}
+
+void ScreenManager::push(Screen *screen) {
+ dialog_.push_back(screen);
+}
+
+void ScreenManager::pop() {
+ if (dialog_.size()) {
+ delete dialog_.back();
+ dialog_.pop_back();
+ } else {
+ ELOG("Can't push when no dialog is shown");
+ }
+}
\ No newline at end of file
diff --git a/ui/screen.h b/ui/screen.h
new file mode 100644
index 0000000000..5dcd8a841b
--- /dev/null
+++ b/ui/screen.h
@@ -0,0 +1,62 @@
+// Super basic screen manager. Let's you, well, switch between screens. Can also be used
+// to pop one screen in front for a bit while keeping another one running, it's basically
+// a native "activity stack". Well actually that part is still a TODO.
+//
+// Semantics
+//
+// switchScreen: When you call this, on a newed screen, the ScreenManager takes ownership.
+// On the next update, it switches to the new screen and deletes the previous screen.
+//
+// TODO: A way to do smooth transitions between screens. Will probably involve screenshotting
+// the previous screen and then animating it on top of the current screen with transparency
+// and/or other similar effects.
+
+#pragma once
+
+#include
+#include "base/display.h"
+
+struct InputState;
+
+class Screen {
+public:
+ Screen();
+ virtual ~Screen();
+ virtual void update(const InputState &input) = 0;
+ virtual void render() {}
+ virtual void dialogFinished(const Screen &dialog) {}
+};
+
+class Transition {
+public:
+ Transition() {}
+};
+
+class ScreenManager {
+public:
+ ScreenManager();
+ virtual ~ScreenManager();
+
+ void switchScreen(Screen *screen);
+ void update(const InputState &input);
+ void render();
+ void shutdown();
+
+ // Push a dialog box in front. Currently 1-level only.
+ void push(Screen *screen);
+
+ // Pops the dialog away.
+ void pop();
+
+private:
+ // Base screen. These don't "stack" and you can move in any order between them.
+ Screen *currentScreen_;
+ Screen *nextScreen_;
+
+ // Dialog stack. These are shown "on top" of base screens and back works as expected.
+ // Used for options, in-game menus and other things you expect to be able to back out from onto something.
+ std::list dialog_;
+};
+
+// Yeah, an old school non enforced singleton. Good enough.
+extern ScreenManager screenManager;