Fix code to remove compiler warnings
[hex-a-hop.git] / gfx.cpp
blob7bbe80c2e4764acd1b9bccc235073ef3ea12d55a
1 /*
2 Copyright (C) 2005-2007 Tom Beaumont
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "state.h"
21 #ifdef WIN32
22 #include <SDL_syswm.h>
23 #include <shellapi.h> // Windows header for drag & drop
24 #ifdef USE_BBTABLET
25 #include "bbtablet/bbtablet.h"
26 #endif
27 #else
28 #undef USE_BBTABLET
29 #endif
31 #ifndef DATA_DIR
32 #define DATA_DIR "."
33 #endif
35 StateMakerBase* StateMakerBase::first = 0;
36 State* StateMakerBase::current = 0;
38 int SDL_focus = SDL_APPACTIVE | SDL_APPINPUTFOCUS; // Initial focus state
40 #ifdef WIN32
41 #include <windows.h>
42 #include <winuser.h>
43 #include <commdlg.h>
44 #include <direct.h>
46 bool tablet_system = false;
48 char* LoadSaveDialog(bool save, bool levels, const char * title)
50 OPENFILENAME f;
51 static char filename[1025] = "";
52 static char path[1025] = "C:\\WINDOWS\\Desktop\\New Folder\\Foo\\Levels";
53 char backupPath[1025];
54 _getcwd(backupPath, sizeof(backupPath)/sizeof(backupPath[0])-1);
56 memset(&f, 0, sizeof(f));
58 #define FILTER(desc, f) desc " (" f ")\0" f "\0"
59 f.lpstrFilter = FILTER("All known files","*.lev;*.sol")
60 FILTER("Level files","*.lev")
61 FILTER("Solution files","*.sol")
62 FILTER("All files","*.*");
63 #undef FILTER
65 f.lStructSize = sizeof(f);
66 f.lpstrFile = filename;
67 f.nMaxFile = sizeof(filename);
68 f.lpstrInitialDir = path;
69 f.lpstrTitle = title;
71 if (GetSaveFileName(&f)==TRUE)
73 // Remember user's choice of path!
74 _getcwd(path, sizeof(path)/sizeof(path[0])-1);
76 if (save)
78 int i = strlen(filename)-1;
79 while (i>0 && filename[i]!='.' && filename[i]!='\\' && filename[i]!='/') i--;
80 if (filename[i]!='.' && levels)
81 strcat(filename, ".lev");
82 if (filename[i]!='.' && !levels)
83 strcat(filename, ".sol");
85 _chdir(backupPath);
86 return filename;
89 _chdir(backupPath);
90 return 0;
92 #else
93 char* LoadSaveDialog(bool /*save*/, bool /*levels*/, const char * /*title*/)
95 return 0;
97 #endif
99 extern void test();
101 int mouse_buttons = 0;
102 int mousex= 10, mousey = 10;
103 int noMouse = 0;
104 int quitting = 0;
106 double stylusx= 0, stylusy= 0;
107 int stylusok= 0;
108 float styluspressure = 0;
109 SDL_Surface * screen = 0;
110 SDL_Surface * realScreen = 0;
112 extern State* MakeWorld();
114 bool fullscreen = false;
116 void InitScreen()
118 #ifdef USE_OPENGL
119 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
120 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
121 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
122 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
123 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
125 // printf("SDL_SetVideoMode (OpenGL)\n");
126 realScreen = SDL_SetVideoMode(
127 SCREEN_W, SCREEN_H, // Width, Height
128 0, // Current BPP
129 SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0) );
130 #else
131 // printf("SDL_SetVideoMode (non-OpenGL)\n");
132 realScreen = SDL_SetVideoMode(
133 SCREEN_W, SCREEN_H, // Width, Height
134 0, // Current BPP
135 SDL_SWSURFACE | SDL_DOUBLEBUF | (fullscreen ? SDL_FULLSCREEN : 0) );
136 #endif
138 if (screen)
139 SDL_FreeSurface(screen);
141 SDL_Surface* tempscreen = SDL_CreateRGBSurface(
142 SDL_SWSURFACE,
143 SCREEN_W, SCREEN_H,
144 16, 0xf800, 0x07e0, 0x001f, 0);
146 screen = SDL_DisplayFormat(tempscreen);
147 SDL_FreeSurface(tempscreen);
150 void ToggleFullscreen()
152 fullscreen = !fullscreen;
153 InitScreen();
154 StateMakerBase::current->ScreenModeChanged();
156 String base_path;
158 int TickTimer()
160 static int time = SDL_GetTicks();
161 int cap=40;
163 int x = SDL_GetTicks() - time;
164 time += x;
165 if (x<0) x = 0, time = SDL_GetTicks();
166 if (x>cap) x = cap;
168 return x;
171 int main(int /*argc*/, char * /*argv*/[])
173 base_path = DATA_DIR "/";
174 for (int i=strlen(base_path)-1; i>=0; i--)
175 if (base_path[i]=='/' || base_path[i]=='\\')
177 base_path.truncate(i+1);
178 break;
180 // Check the path ends with a directory seperator
181 if (strlen(base_path)>0)
183 char last = base_path[strlen(base_path)-1];
184 if (last!='/' && last!='\\')
185 base_path = "";
187 #ifdef WIN32
188 if (strstr(base_path, "\\foo2___Win32_Debug\\"))
189 strstr(base_path, "\\foo2___Win32_Debug\\")[1] = '\0';
190 if (strstr(base_path, "\\Release\\"))
191 strstr(base_path, "\\Release\\")[1] = '\0';
192 #endif
193 // printf("SDL_Init\n");
196 // Experimental - create a splash screen window whilst loading
197 SDL_Init(SDL_INIT_VIDEO);
198 screen = SDL_SetVideoMode( 200,200,0,SDL_NOFRAME );
199 SDL_Rect r = {0,0,200,200};
200 SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 0, 50));
201 SDL_Flip(screen);
204 SDL_Init(SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE);
206 SDL_Surface* icon = SDL_LoadBMP("graphics/icon.bmp");
207 if (icon)
209 static unsigned int mask[32] = {
210 0x00001fc0,
211 0x00003fe0,
212 0x00007ff0,
213 0x00007df8,
214 0x0000f0f8,
215 0x0000f07c,
216 0x0005f87c,
217 0x0fbfff3c,
219 0x1ffffffe,
220 0x3ffffffe,
221 0x3ffffffe,
222 0x7ffffffe,
223 0x7ffffffe,
224 0x7ffffffe,
225 0x7ffffffe,
226 0xefffffff,
228 0x1fffffff,
229 0x3fffffff,
230 0x3fffffff,
231 0x3fffffff,
232 0x3fffffff,
233 0x3fffffff,
234 0x3fffffff,
235 0x3ffffffe,
237 0x3ffffff8,
238 0x3ffffff0,
239 0x3ffffff0,
240 0x3ffffff0,
241 0x3fffffe0,
242 0x3fffffe0,
243 0x1ffffff0,
244 0x1ffffff1,
246 for (int i=0; i<32; i++)
247 mask[i] = mask[i]>>24 | (mask[i]>>8)&0xff00 | (mask[i]<<8)&0xff0000 | (mask[i]<<24)&0xff000000;
248 SDL_WM_SetIcon(icon, (unsigned char*) mask);
249 SDL_FreeSurface(icon);
252 InitScreen();
254 SDL_WarpMouse(SCREEN_W/2, SCREEN_H/2);
256 int videoExposed = 1;
258 #ifdef WIN32
259 HWND hwnd = 0;
260 #endif
261 #ifdef USE_BBTABLET
262 bbTabletDevice &td = bbTabletDevice::getInstance( );
263 SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
264 #endif
266 // printf("Main loop...\n");
268 StateMakerBase::GetNew();
270 while(!quitting)
272 SDL_Event e;
273 while(!SDL_PollEvent(&e) && !quitting)
275 int x = 0;
277 if ((SDL_focus & 6)==6)
279 videoExposed = 1;
281 x = TickTimer();
283 while (x<10)
285 SDL_Delay(10-x);
286 x += TickTimer();
289 StateMakerBase::current->Update(x / 1000.0);
291 else
293 // Not focussed. Try not to eat too much CPU!
294 SDL_Delay(150);
297 // experimental...
298 if (!noMouse)
299 StateMakerBase::current->Mouse(mousex, mousey, 0, 0, 0, 0, mouse_buttons);
301 if (videoExposed)
303 StateMakerBase::current->Render();
305 #ifdef USE_OPENGL
306 SDL_GL_SwapBuffers();
307 #else
308 if (screen && realScreen!=screen)
310 SDL_Rect r = {0,0,SCREEN_W,SCREEN_H};
311 SDL_BlitSurface(screen, &r, realScreen, &r);
313 SDL_Flip(realScreen);
314 #endif
315 videoExposed = 0;
318 #ifdef USE_BBTABLET
319 // Tablet ////////////////////////
320 bbTabletEvent evt;
321 while(hwnd!=NULL && td.getNextEvent(evt))
323 stylusok = 1;
324 RECT r;
325 if (tablet_system)
327 GetWindowRect(hwnd, &r);
328 stylusx = evt.x * GetSystemMetrics(SM_CXSCREEN);
329 stylusy = (1.0 - evt.y) * GetSystemMetrics(SM_CYSCREEN);
330 stylusx -= (r.left + GetSystemMetrics(SM_CXFIXEDFRAME));
331 stylusy -= (r.top + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION));;
333 else
335 GetClientRect(hwnd, &r);
336 stylusx = evt.x * r.right;
337 stylusy = (1.0 - evt.y) * r.bottom;
339 styluspressure = (evt.buttons & 1) ? evt.pressure : 0;
342 printf("id=%d csrtype=%d b=%x (%0.3f, %0.3f, %0.3f) p=%0.3f tp=%0.3f\n",
343 evt.id,
344 evt.type,
345 evt.buttons,
346 evt.x,
347 evt.y,
348 evt.z,
349 evt.pressure,
350 evt.tpressure
355 #endif
358 switch (e.type)
360 case SDL_VIDEOEXPOSE:
361 videoExposed = 1;
362 break;
364 #ifdef WIN32
365 case SDL_SYSWMEVENT:
367 SDL_SysWMmsg* m = e.syswm.msg;
368 hwnd = m->hwnd;
369 static bool init=false;
370 if (!init)
372 init = true;
373 DragAcceptFiles(hwnd, TRUE);
374 #ifdef USE_BBTABLET
375 td.initTablet(hwnd, tablet_system ? bbTabletDevice::SYSTEM_POINTER : bbTabletDevice::SEPARATE_POINTER );
376 if (!td.isValid())
377 printf("No tablet/driver found\n");
378 #endif
380 if (m->msg == WM_DROPFILES)
382 HDROP h = (HDROP)m->wParam;
384 char name[512];
385 if (DragQueryFile(h, 0xffffffff, 0, 0) == 1)
387 DragQueryFile(h, 0, name, sizeof(name)/sizeof(name[0]));
389 StateMakerBase::current->FileDrop(name);
392 DragFinish(h);
395 break;
397 #endif
399 case SDL_ACTIVEEVENT:
401 int gain = e.active.gain ? e.active.state : 0;
402 int loss = e.active.gain ? 0 : e.active.state;
403 SDL_focus = (SDL_focus | gain) & ~loss;
404 if (gain & SDL_APPACTIVE)
405 StateMakerBase::current->ScreenModeChanged();
406 if (loss & SDL_APPMOUSEFOCUS)
407 noMouse = 1;
408 else if (gain & SDL_APPMOUSEFOCUS)
409 noMouse = 0;
411 break;
414 case SDL_MOUSEMOTION:
415 noMouse = false;
416 StateMakerBase::current->Mouse(e.motion.x, e.motion.y, e.motion.x-mousex, e.motion.y-mousey, 0, 0, mouse_buttons);
417 mousex = e.motion.x; mousey = e.motion.y;
418 break;
419 case SDL_MOUSEBUTTONUP:
420 noMouse = false;
421 mouse_buttons &= ~(1<<(e.button.button-1));
422 StateMakerBase::current->Mouse(e.button.x, e.button.y, e.button.x-mousex, e.button.y-mousey,
423 0, 1<<(e.button.button-1), mouse_buttons);
424 mousex = e.button.x; mousey = e.button.y ;
425 break;
426 case SDL_MOUSEBUTTONDOWN:
427 noMouse = false;
428 mouse_buttons |= 1<<(e.button.button-1);
429 StateMakerBase::current->Mouse(e.button.x, e.button.y, e.button.x-mousex, e.button.y-mousey,
430 1<<(e.button.button-1), 0, mouse_buttons);
431 mousex = e.button.x; mousey = e.button.y ;
432 break;
434 case SDL_KEYUP:
435 StateMakerBase::current->KeyReleased(e.key.keysym.sym);
436 break;
438 case SDL_KEYDOWN:
440 SDL_KeyboardEvent & k = e.key;
442 if (k.keysym.sym==SDLK_F4 && (k.keysym.mod & KMOD_ALT))
444 quitting = 1;
446 else if (k.keysym.sym==SDLK_F12)
448 // Toggle system pointer controlled by tablet or not
449 #ifdef USE_BBTABLET
450 if (td.isValid())
452 tablet_system = !tablet_system;
453 td.setPointerMode(tablet_system ? bbTabletDevice::SYSTEM_POINTER : bbTabletDevice::SEPARATE_POINTER);
455 #endif
457 else if (k.keysym.sym==SDLK_RETURN && (k.keysym.mod & KMOD_ALT) && !(k.keysym.mod & KMOD_CTRL))
459 ToggleFullscreen();
461 else if (StateMakerBase::current->KeyPressed(k.keysym.sym, k.keysym.mod))
464 else if ((k.keysym.mod & (KMOD_ALT | KMOD_CTRL))==0)
466 StateMakerBase::GetNew(k.keysym.sym);
469 break;
471 case SDL_QUIT:
472 quitting = 1;
473 break;
477 SDL_Quit();
478 return 0;