Gettextize program so that it can be translated to other languages
[hex-a-hop.git] / gfx.cpp
blob3501938b859f8e9df60823f782f5b5bf3cfe06c8
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 "i18n.h"
21 #include "state.h"
23 #ifdef WIN32
24 #include <SDL_syswm.h>
25 #include <shellapi.h> // Windows header for drag & drop
26 #ifdef USE_BBTABLET
27 #include "bbtablet/bbtablet.h"
28 #endif
29 #else
30 #undef USE_BBTABLET
31 #endif
33 StateMakerBase* StateMakerBase::first = 0;
34 State* StateMakerBase::current = 0;
36 int SDL_focus = SDL_APPACTIVE | SDL_APPINPUTFOCUS; // Initial focus state
38 #ifdef WIN32
39 #include <windows.h>
40 #include <winuser.h>
41 #include <commdlg.h>
42 #include <direct.h>
44 bool tablet_system = false;
46 char* LoadSaveDialog(bool save, bool levels, const char * title)
48 OPENFILENAME f;
49 static char filename[1025] = "";
50 static char path[1025] = "C:\\WINDOWS\\Desktop\\New Folder\\Foo\\Levels";
51 char backupPath[1025];
52 _getcwd(backupPath, sizeof(backupPath)/sizeof(backupPath[0])-1);
54 memset(&f, 0, sizeof(f));
56 #define FILTER(desc, f) desc " (" f ")\0" f "\0"
57 f.lpstrFilter = FILTER("All known files","*.lev;*.sol")
58 FILTER("Level files","*.lev")
59 FILTER("Solution files","*.sol")
60 FILTER("All files","*.*");
61 #undef FILTER
63 f.lStructSize = sizeof(f);
64 f.lpstrFile = filename;
65 f.nMaxFile = sizeof(filename);
66 f.lpstrInitialDir = path;
67 f.lpstrTitle = title;
69 if (GetSaveFileName(&f)==TRUE)
71 // Remember user's choice of path!
72 _getcwd(path, sizeof(path)/sizeof(path[0])-1);
74 if (save)
76 int i = strlen(filename)-1;
77 while (i>0 && filename[i]!='.' && filename[i]!='\\' && filename[i]!='/') i--;
78 if (filename[i]!='.' && levels)
79 strcat(filename, ".lev");
80 if (filename[i]!='.' && !levels)
81 strcat(filename, ".sol");
83 _chdir(backupPath);
84 return filename;
87 _chdir(backupPath);
88 return 0;
90 #else
91 char* LoadSaveDialog(bool save, bool levels, const char * title)
93 return 0;
95 #endif
97 extern void test();
99 int mouse_buttons = 0;
100 int mousex= 10, mousey = 10;
101 int noMouse = 0;
102 int quitting = 0;
104 double stylusx= 0, stylusy= 0;
105 int stylusok= 0;
106 float styluspressure = 0;
107 SDL_Surface * screen = 0;
108 SDL_Surface * realScreen = 0;
110 extern State* MakeWorld();
112 bool fullscreen = false;
114 void InitScreen()
116 #ifdef USE_OPENGL
117 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
118 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
119 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
120 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
121 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
123 // printf("SDL_SetVideoMode (OpenGL)\n");
124 realScreen = SDL_SetVideoMode(
125 SCREEN_W, SCREEN_H, // Width, Height
126 0, // Current BPP
127 SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0) );
128 #else
129 // printf("SDL_SetVideoMode (non-OpenGL)\n");
130 realScreen = SDL_SetVideoMode(
131 SCREEN_W, SCREEN_H, // Width, Height
132 0, // Current BPP
133 SDL_SWSURFACE | SDL_DOUBLEBUF | (fullscreen ? SDL_FULLSCREEN : 0) );
134 #endif
136 if (screen)
137 SDL_FreeSurface(screen);
139 SDL_Surface* tempscreen = SDL_CreateRGBSurface(
140 SDL_SWSURFACE,
141 SCREEN_W, SCREEN_H,
142 16, 0xf800, 0x07e0, 0x001f, 0);
144 screen = SDL_DisplayFormat(tempscreen);
145 SDL_FreeSurface(tempscreen);
148 void ToggleFullscreen()
150 fullscreen = !fullscreen;
151 InitScreen();
152 StateMakerBase::current->ScreenModeChanged();
154 String base_path;
156 int TickTimer()
158 static int time = SDL_GetTicks();
159 int cap=40;
161 int x = SDL_GetTicks() - time;
162 time += x;
163 if (x<0) x = 0, time = SDL_GetTicks();
164 if (x>cap) x = cap;
166 return x;
169 int main(int argc, char * argv[])
171 base_path = argv[0];
172 for (int i=strlen(base_path)-1; i>=0; i--)
173 if (base_path[i]=='/' || base_path[i]=='\\')
175 base_path.truncate(i+1);
176 break;
178 // Check the path ends with a directory seperator
179 if (strlen(base_path)>0)
181 char last = base_path[strlen(base_path)-1];
182 if (last!='/' && last!='\\')
183 base_path = "";
185 #ifdef WIN32
186 if (strstr(base_path, "\\foo2___Win32_Debug\\"))
187 strstr(base_path, "\\foo2___Win32_Debug\\")[1] = '\0';
188 if (strstr(base_path, "\\Release\\"))
189 strstr(base_path, "\\Release\\")[1] = '\0';
190 #endif
191 // printf("SDL_Init\n");
194 // Experimental - create a splash screen window whilst loading
195 SDL_Init(SDL_INIT_VIDEO);
196 screen = SDL_SetVideoMode( 200,200,0,SDL_NOFRAME );
197 SDL_Rect r = {0,0,200,200};
198 SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 0, 50));
199 SDL_Flip(screen);
202 SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_NOPARACHUTE);
204 SDL_Surface* icon = SDL_LoadBMP("graphics/icon.bmp");
205 if (icon)
207 static unsigned int mask[32] = {
208 0x00001fc0,
209 0x00003fe0,
210 0x00007ff0,
211 0x00007df8,
212 0x0000f0f8,
213 0x0000f07c,
214 0x0005f87c,
215 0x0fbfff3c,
217 0x1ffffffe,
218 0x3ffffffe,
219 0x3ffffffe,
220 0x7ffffffe,
221 0x7ffffffe,
222 0x7ffffffe,
223 0x7ffffffe,
224 0xefffffff,
226 0x1fffffff,
227 0x3fffffff,
228 0x3fffffff,
229 0x3fffffff,
230 0x3fffffff,
231 0x3fffffff,
232 0x3fffffff,
233 0x3ffffffe,
235 0x3ffffff8,
236 0x3ffffff0,
237 0x3ffffff0,
238 0x3ffffff0,
239 0x3fffffe0,
240 0x3fffffe0,
241 0x1ffffff0,
242 0x1ffffff1,
244 for (int i=0; i<32; i++)
245 mask[i] = mask[i]>>24 | (mask[i]>>8)&0xff00 | (mask[i]<<8)&0xff0000 | (mask[i]<<24)&0xff000000;
246 SDL_WM_SetIcon(icon, (unsigned char*) mask);
247 SDL_FreeSurface(icon);
250 InitScreen();
252 SDL_WarpMouse(SCREEN_W/2, SCREEN_H/2);
254 int videoExposed = 1;
256 #ifdef WIN32
257 HWND hwnd = 0;
258 #endif
259 #ifdef USE_BBTABLET
260 bbTabletDevice &td = bbTabletDevice::getInstance( );
261 SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
262 #endif
264 // printf("Main loop...\n");
266 StateMakerBase::GetNew();
267 int time = SDL_GetTicks();
269 while(!quitting)
271 SDL_Event e;
272 while(!SDL_PollEvent(&e) && !quitting)
274 int x = 0;
276 if ((SDL_focus & 6)==6)
278 videoExposed = 1;
280 x = TickTimer();
282 while (x<10)
284 SDL_Delay(10-x);
285 x += TickTimer();
288 StateMakerBase::current->Update(x / 1000.0);
290 else
292 // Not focussed. Try not to eat too much CPU!
293 SDL_Delay(150);
296 // experimental...
297 if (!noMouse)
298 StateMakerBase::current->Mouse(mousex, mousey, 0, 0, 0, 0, mouse_buttons);
300 if (videoExposed)
302 StateMakerBase::current->Render();
304 #ifdef USE_OPENGL
305 SDL_GL_SwapBuffers();
306 #else
307 if (screen && realScreen!=screen)
309 SDL_Rect r = {0,0,SCREEN_W,SCREEN_H};
310 SDL_BlitSurface(screen, &r, realScreen, &r);
312 SDL_Flip(realScreen);
313 #endif
314 videoExposed = 0;
317 #ifdef USE_BBTABLET
318 // Tablet ////////////////////////
319 bbTabletEvent evt;
320 while(hwnd!=NULL && td.getNextEvent(evt))
322 stylusok = 1;
323 RECT r;
324 if (tablet_system)
326 GetWindowRect(hwnd, &r);
327 stylusx = evt.x * GetSystemMetrics(SM_CXSCREEN);
328 stylusy = (1.0 - evt.y) * GetSystemMetrics(SM_CYSCREEN);
329 stylusx -= (r.left + GetSystemMetrics(SM_CXFIXEDFRAME));
330 stylusy -= (r.top + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION));;
332 else
334 GetClientRect(hwnd, &r);
335 stylusx = evt.x * r.right;
336 stylusy = (1.0 - evt.y) * r.bottom;
338 styluspressure = (evt.buttons & 1) ? evt.pressure : 0;
341 printf("id=%d csrtype=%d b=%x (%0.3f, %0.3f, %0.3f) p=%0.3f tp=%0.3f\n",
342 evt.id,
343 evt.type,
344 evt.buttons,
345 evt.x,
346 evt.y,
347 evt.z,
348 evt.pressure,
349 evt.tpressure
354 #endif
357 switch (e.type)
359 case SDL_VIDEOEXPOSE:
360 videoExposed = 1;
361 break;
363 #ifdef WIN32
364 case SDL_SYSWMEVENT:
366 SDL_SysWMmsg* m = e.syswm.msg;
367 hwnd = m->hwnd;
368 static bool init=false;
369 if (!init)
371 init = true;
372 DragAcceptFiles(hwnd, TRUE);
373 #ifdef USE_BBTABLET
374 td.initTablet(hwnd, tablet_system ? bbTabletDevice::SYSTEM_POINTER : bbTabletDevice::SEPARATE_POINTER );
375 if (!td.isValid())
376 printf("No tablet/driver found\n");
377 #endif
379 if (m->msg == WM_DROPFILES)
381 HDROP h = (HDROP)m->wParam;
383 char name[512];
384 if (DragQueryFile(h, 0xffffffff, 0, 0) == 1)
386 DragQueryFile(h, 0, name, sizeof(name)/sizeof(name[0]));
388 StateMakerBase::current->FileDrop(name);
391 DragFinish(h);
394 break;
396 #endif
398 case SDL_ACTIVEEVENT:
400 int gain = e.active.gain ? e.active.state : 0;
401 int loss = e.active.gain ? 0 : e.active.state;
402 SDL_focus = (SDL_focus | gain) & ~loss;
403 if (gain & SDL_APPACTIVE)
404 StateMakerBase::current->ScreenModeChanged();
405 if (loss & SDL_APPMOUSEFOCUS)
406 noMouse = 1;
407 else if (gain & SDL_APPMOUSEFOCUS)
408 noMouse = 0;
410 break;
413 case SDL_MOUSEMOTION:
414 noMouse = false;
415 StateMakerBase::current->Mouse(e.motion.x, e.motion.y, e.motion.x-mousex, e.motion.y-mousey, 0, 0, mouse_buttons);
416 mousex = e.motion.x; mousey = e.motion.y;
417 break;
418 case SDL_MOUSEBUTTONUP:
419 noMouse = false;
420 mouse_buttons &= ~(1<<(e.button.button-1));
421 StateMakerBase::current->Mouse(e.button.x, e.button.y, e.button.x-mousex, e.button.y-mousey,
422 0, 1<<(e.button.button-1), mouse_buttons);
423 mousex = e.button.x; mousey = e.button.y ;
424 break;
425 case SDL_MOUSEBUTTONDOWN:
426 noMouse = false;
427 mouse_buttons |= 1<<(e.button.button-1);
428 StateMakerBase::current->Mouse(e.button.x, e.button.y, e.button.x-mousex, e.button.y-mousey,
429 1<<(e.button.button-1), 0, mouse_buttons);
430 mousex = e.button.x; mousey = e.button.y ;
431 break;
433 case SDL_KEYUP:
434 StateMakerBase::current->KeyReleased(e.key.keysym.sym);
435 break;
437 case SDL_KEYDOWN:
439 SDL_KeyboardEvent & k = e.key;
441 if (k.keysym.sym==SDLK_F4 && (k.keysym.mod & KMOD_ALT))
443 quitting = 1;
445 else if (k.keysym.sym==SDLK_F12)
447 // Toggle system pointer controlled by tablet or not
448 #ifdef USE_BBTABLET
449 if (td.isValid())
451 tablet_system = !tablet_system;
452 td.setPointerMode(tablet_system ? bbTabletDevice::SYSTEM_POINTER : bbTabletDevice::SEPARATE_POINTER);
454 #endif
456 else if (k.keysym.sym==SDLK_RETURN && (k.keysym.mod & KMOD_ALT) && !(k.keysym.mod & KMOD_CTRL))
458 ToggleFullscreen();
460 else if (StateMakerBase::current->KeyPressed(k.keysym.sym, k.keysym.mod))
463 else if ((k.keysym.mod & (KMOD_ALT | KMOD_CTRL))==0)
465 StateMakerBase::GetNew(k.keysym.sym);
468 break;
470 case SDL_QUIT:
471 quitting = 1;
472 break;
476 SDL_Quit();
477 return 0;