20130313
[gdash.git] / src / sdl / sdlmainwindow.cpp
blob7610ff801a6bf7e11c42b114398347c2d7a5fe8f
1 /*
2 * Copyright (c) 2007-2013, Czirkos Zoltan http://code.google.com/p/gdash/
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 #include "config.h"
19 #include "settings.hpp"
20 #include "framework/app.hpp"
21 #include "framework/commands.hpp"
22 #include "framework/gameactivity.hpp"
23 #include "framework/titlescreenactivity.hpp"
24 #include "framework/messageactivity.hpp"
25 #include "gfx/fontmanager.hpp"
26 #include "sdl/sdlpixbuffactory.hpp"
27 #include "sdl/sdlgameinputhandler.hpp"
28 #include "sdl/sdlscreen.hpp"
30 #include "sdl/sdlmainwindow.hpp"
35 class SDLApp: public App {
36 public:
37 SDLApp();
40 SDLApp::SDLApp() {
41 pixbuf_factory = new SDLPixbufFactory;
42 pixbuf_factory->set_properties(GdScalingType(gd_cell_scale_game), gd_pal_emulation_game);
43 font_manager = new FontManager(*pixbuf_factory, "");
44 gameinput = new SDLGameInputHandler;
45 screen = new SDLScreen;
49 /* generate a user event */
50 static Uint32 timer_callback(Uint32 interval, void *param) {
51 SDL_Event ev;
53 ev.type=SDL_USEREVENT;
54 SDL_PushEvent(&ev);
56 return interval;
60 static Activity::KeyCode activity_keycode_from_sdl_key_event(SDL_KeyboardEvent const &ev) {
61 switch (ev.keysym.sym) {
62 case SDLK_UP: return App::Up;
63 case SDLK_DOWN: return App::Down;
64 case SDLK_LEFT: return App::Left;
65 case SDLK_RIGHT: return App::Right;
66 case SDLK_PAGEUP: return App::PageUp;
67 case SDLK_PAGEDOWN: return App::PageDown;
68 case SDLK_HOME: return App::Home;
69 case SDLK_END: return App::End;
70 case SDLK_F1: return App::F1;
71 case SDLK_F2: return App::F2;
72 case SDLK_F3: return App::F3;
73 case SDLK_F4: return App::F4;
74 case SDLK_F5: return App::F5;
75 case SDLK_F6: return App::F6;
76 case SDLK_F7: return App::F7;
77 case SDLK_F8: return App::F8;
78 case SDLK_F9: return App::F9;
79 case SDLK_BACKSPACE: return App::BackSpace;
80 case SDLK_RETURN: return App::Enter;
81 case SDLK_TAB: return App::Tab;
82 case SDLK_ESCAPE: return App::Escape;
84 default:
85 return ev.keysym.unicode;
90 class SetNextActionCommandSDL : public Command {
91 public:
92 SetNextActionCommandSDL(App *app, NextAction &na, NextAction to_what): Command(app), na(na), to_what(to_what) {}
93 private:
94 virtual void execute() { na = to_what; }
95 NextAction &na;
96 NextAction to_what;
100 static void run_the_app(App &the_app, NextAction &na) {
101 /* Running the APP */
102 int const timer_ms = 20;
103 SDL_InitSubSystem(SDL_INIT_TIMER);
104 SDL_TimerID id = SDL_AddTimer(timer_ms, timer_callback, NULL);
106 the_app.set_no_activity_command(new SetNextActionCommandSDL(&the_app, na, Quit));
108 /* sdl_waitevent will wait until at least one event appears. */
109 na = StartTitle;
110 while (na == StartTitle && SDL_WaitEvent(NULL)) {
111 /* and now we poll all the events, as there might be more than one. */
112 bool had_timer_event1 = false;
113 SDL_Event ev;
115 while (SDL_PollEvent(&ev)) {
116 switch (ev.type) {
117 case SDL_QUIT:
118 the_app.quit_event();
119 break;
120 case SDL_KEYDOWN:
121 if (ev.key.keysym.sym == SDLK_F11) {
122 gd_fullscreen = !gd_fullscreen;
123 the_app.screen->reinit();
124 the_app.redraw_event();
125 } else {
126 Activity::KeyCode keycode = activity_keycode_from_sdl_key_event(ev.key);
127 the_app.keypress_event(keycode, ev.key.keysym.sym);
129 break;
130 case SDL_KEYUP:
131 the_app.gameinput->keyrelease(ev.key.keysym.sym);
132 break;
133 case SDL_VIDEOEXPOSE:
134 the_app.redraw_event();
135 break;
136 case SDL_USEREVENT:
137 had_timer_event1 = true;
138 break;
139 case SDL_USEREVENT+1:
140 the_app.timer2_event();
141 break;
142 } // switch ev.type
143 } // while pollevent
145 if (had_timer_event1 && (SDL_GetAppState() & SDL_APPINPUTFOCUS))
146 the_app.timer_event(timer_ms);
148 // check if the g_main_loop has something to do. if it has,
149 // it is usually gtk stuff - so let gtk live :D
150 while (g_main_context_pending(NULL))
151 g_main_context_iteration(NULL, FALSE);
154 SDL_RemoveTimer(id);
157 #include "misc/about.hpp"
158 void gd_main_window_sdl_run(CaveSet *caveset, NextAction &na) {
159 SDLApp the_app;
161 /* normal application: title screen, menu etc */
162 the_app.caveset = caveset;
163 the_app.set_quit_event_command(new AskIfChangesDiscardedCommand(&the_app, new PopAllActivitiesCommand(&the_app)));
164 the_app.set_request_restart_command(new SetNextActionCommandSDL(&the_app, na, Restart));
165 the_app.set_start_editor_command(new SetNextActionCommandSDL(&the_app, na, StartEditor));
167 the_app.push_activity(new TitleScreenActivity(&the_app));
168 run_the_app(the_app, na);
172 void gd_main_window_sdl_run_a_game(GameControl *game) {
173 SDLApp the_app;
175 NextAction na = StartTitle; // because the func below needs one to work with
176 the_app.set_quit_event_command(new SetNextActionCommandSDL(&the_app, na, Quit));
177 the_app.push_activity(new GameActivity(&the_app, game));
178 run_the_app(the_app, na);