Patch the game to show better than par punctuation
[hex-a-hop.git] / gfx.cpp
blob041ee76982d555de58028cfb11e1a141c2ee5ace
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 StateMakerBase* StateMakerBase::first = 0;
32 State* StateMakerBase::current = 0;
34 int SDL_focus = SDL_APPACTIVE | SDL_APPINPUTFOCUS; // Initial focus state
36 #ifdef WIN32
37 #include <windows.h>
38 #include <winuser.h>
39 #include <commdlg.h>
40 #include <direct.h>
42 bool tablet_system = false;
44 char* LoadSaveDialog(bool save, bool levels, const char * title)
46 OPENFILENAME f;
47 static char filename[1025] = "";
48 static char path[1025] = "C:\\WINDOWS\\Desktop\\New Folder\\Foo\\Levels";
49 char backupPath[1025];
50 _getcwd(backupPath, sizeof(backupPath)/sizeof(backupPath[0])-1);
52 memset(&f, 0, sizeof(f));
54 #define FILTER(desc, f) desc " (" f ")\0" f "\0"
55 f.lpstrFilter = FILTER("All known files","*.lev;*.sol")
56 FILTER("Level files","*.lev")
57 FILTER("Solution files","*.sol")
58 FILTER("All files","*.*");
59 #undef FILTER
61 f.lStructSize = sizeof(f);
62 f.lpstrFile = filename;
63 f.nMaxFile = sizeof(filename);
64 f.lpstrInitialDir = path;
65 f.lpstrTitle = title;
67 if (GetSaveFileName(&f)==TRUE)
69 // Remember user's choice of path!
70 _getcwd(path, sizeof(path)/sizeof(path[0])-1);
72 if (save)
74 int i = strlen(filename)-1;
75 while (i>0 && filename[i]!='.' && filename[i]!='\\' && filename[i]!='/') i--;
76 if (filename[i]!='.' && levels)
77 strcat(filename, ".lev");
78 if (filename[i]!='.' && !levels)
79 strcat(filename, ".sol");
81 _chdir(backupPath);
82 return filename;
85 _chdir(backupPath);
86 return 0;
88 #else
89 char* LoadSaveDialog(bool save, bool levels, const char * title)
91 return 0;
93 #endif
95 extern void test();
97 int mouse_buttons = 0;
98 int mousex= 10, mousey = 10;
99 int noMouse = 0;
100 int quitting = 0;
102 double stylusx= 0, stylusy= 0;
103 int stylusok= 0;
104 float styluspressure = 0;
105 SDL_Surface * screen = 0;
106 SDL_Surface * realScreen = 0;
108 extern State* MakeWorld();
110 bool fullscreen = false;
112 void InitScreen()
114 #ifdef USE_OPENGL
115 SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 5 );
116 SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 5 );
117 SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 5 );
118 SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16 );
119 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
121 // printf("SDL_SetVideoMode (OpenGL)\n");
122 realScreen = SDL_SetVideoMode(
123 SCREEN_W, SCREEN_H, // Width, Height
124 0, // Current BPP
125 SDL_OPENGL | (fullscreen ? SDL_FULLSCREEN : 0) );
126 #else
127 // printf("SDL_SetVideoMode (non-OpenGL)\n");
128 realScreen = SDL_SetVideoMode(
129 SCREEN_W, SCREEN_H, // Width, Height
130 0, // Current BPP
131 SDL_SWSURFACE | SDL_DOUBLEBUF | (fullscreen ? SDL_FULLSCREEN : 0) );
132 #endif
134 if (screen)
135 SDL_FreeSurface(screen);
137 SDL_Surface* tempscreen = SDL_CreateRGBSurface(
138 SDL_SWSURFACE,
139 SCREEN_W, SCREEN_H,
140 16, 0xf800, 0x07e0, 0x001f, 0);
142 screen = SDL_DisplayFormat(tempscreen);
143 SDL_FreeSurface(tempscreen);
146 void ToggleFullscreen()
148 fullscreen = !fullscreen;
149 InitScreen();
150 StateMakerBase::current->ScreenModeChanged();
152 String base_path;
154 int TickTimer()
156 static int time = SDL_GetTicks();
157 int cap=40;
159 int x = SDL_GetTicks() - time;
160 time += x;
161 if (x<0) x = 0, time = SDL_GetTicks();
162 if (x>cap) x = cap;
164 return x;
167 int main(int argc, char * argv[])
169 base_path = argv[0];
170 for (int i=strlen(base_path)-1; i>=0; i--)
171 if (base_path[i]=='/' || base_path[i]=='\\')
173 base_path.truncate(i+1);
174 break;
176 // Check the path ends with a directory seperator
177 if (strlen(base_path)>0)
179 char last = base_path[strlen(base_path)-1];
180 if (last!='/' && last!='\\')
181 base_path = "";
183 #ifdef WIN32
184 if (strstr(base_path, "\\foo2___Win32_Debug\\"))
185 strstr(base_path, "\\foo2___Win32_Debug\\")[1] = '\0';
186 if (strstr(base_path, "\\Release\\"))
187 strstr(base_path, "\\Release\\")[1] = '\0';
188 #endif
189 // printf("SDL_Init\n");
192 // Experimental - create a splash screen window whilst loading
193 SDL_Init(SDL_INIT_VIDEO);
194 screen = SDL_SetVideoMode( 200,200,0,SDL_NOFRAME );
195 SDL_Rect r = {0,0,200,200};
196 SDL_FillRect(screen, &r, SDL_MapRGB(screen->format, 0, 0, 50));
197 SDL_Flip(screen);
200 SDL_Init(SDL_INIT_EVERYTHING | SDL_INIT_NOPARACHUTE);
202 SDL_Surface* icon = SDL_LoadBMP("graphics/icon.bmp");
203 if (icon)
205 static unsigned int mask[32] = {
206 0x00001fc0,
207 0x00003fe0,
208 0x00007ff0,
209 0x00007df8,
210 0x0000f0f8,
211 0x0000f07c,
212 0x0005f87c,
213 0x0fbfff3c,
215 0x1ffffffe,
216 0x3ffffffe,
217 0x3ffffffe,
218 0x7ffffffe,
219 0x7ffffffe,
220 0x7ffffffe,
221 0x7ffffffe,
222 0xefffffff,
224 0x1fffffff,
225 0x3fffffff,
226 0x3fffffff,
227 0x3fffffff,
228 0x3fffffff,
229 0x3fffffff,
230 0x3fffffff,
231 0x3ffffffe,
233 0x3ffffff8,
234 0x3ffffff0,
235 0x3ffffff0,
236 0x3ffffff0,
237 0x3fffffe0,
238 0x3fffffe0,
239 0x1ffffff0,
240 0x1ffffff1,
242 for (int i=0; i<32; i++)
243 mask[i] = mask[i]>>24 | (mask[i]>>8)&0xff00 | (mask[i]<<8)&0xff0000 | (mask[i]<<24)&0xff000000;
244 SDL_WM_SetIcon(icon, (unsigned char*) mask);
245 SDL_FreeSurface(icon);
248 InitScreen();
250 SDL_WarpMouse(SCREEN_W/2, SCREEN_H/2);
252 int videoExposed = 1;
254 #ifdef WIN32
255 HWND hwnd = 0;
256 #endif
257 #ifdef USE_BBTABLET
258 bbTabletDevice &td = bbTabletDevice::getInstance( );
259 SDL_EventState(SDL_SYSWMEVENT, SDL_ENABLE);
260 #endif
262 // printf("Main loop...\n");
264 StateMakerBase::GetNew();
265 int time = SDL_GetTicks();
267 while(!quitting)
269 SDL_Event e;
270 while(!SDL_PollEvent(&e) && !quitting)
272 int x = 0;
274 if ((SDL_focus & 6)==6)
276 videoExposed = 1;
278 x = TickTimer();
280 while (x<10)
282 SDL_Delay(10-x);
283 x += TickTimer();
286 StateMakerBase::current->Update(x / 1000.0);
288 else
290 // Not focussed. Try not to eat too much CPU!
291 SDL_Delay(150);
294 // experimental...
295 if (!noMouse)
296 StateMakerBase::current->Mouse(mousex, mousey, 0, 0, 0, 0, mouse_buttons);
298 if (videoExposed)
300 StateMakerBase::current->Render();
302 #ifdef USE_OPENGL
303 SDL_GL_SwapBuffers();
304 #else
305 if (screen && realScreen!=screen)
307 SDL_Rect r = {0,0,SCREEN_W,SCREEN_H};
308 SDL_BlitSurface(screen, &r, realScreen, &r);
310 SDL_Flip(realScreen);
311 #endif
312 videoExposed = 0;
315 #ifdef USE_BBTABLET
316 // Tablet ////////////////////////
317 bbTabletEvent evt;
318 while(hwnd!=NULL && td.getNextEvent(evt))
320 stylusok = 1;
321 RECT r;
322 if (tablet_system)
324 GetWindowRect(hwnd, &r);
325 stylusx = evt.x * GetSystemMetrics(SM_CXSCREEN);
326 stylusy = (1.0 - evt.y) * GetSystemMetrics(SM_CYSCREEN);
327 stylusx -= (r.left + GetSystemMetrics(SM_CXFIXEDFRAME));
328 stylusy -= (r.top + GetSystemMetrics(SM_CYFIXEDFRAME) + GetSystemMetrics(SM_CYCAPTION));;
330 else
332 GetClientRect(hwnd, &r);
333 stylusx = evt.x * r.right;
334 stylusy = (1.0 - evt.y) * r.bottom;
336 styluspressure = (evt.buttons & 1) ? evt.pressure : 0;
339 printf("id=%d csrtype=%d b=%x (%0.3f, %0.3f, %0.3f) p=%0.3f tp=%0.3f\n",
340 evt.id,
341 evt.type,
342 evt.buttons,
343 evt.x,
344 evt.y,
345 evt.z,
346 evt.pressure,
347 evt.tpressure
352 #endif
355 switch (e.type)
357 case SDL_VIDEOEXPOSE:
358 videoExposed = 1;
359 break;
361 #ifdef WIN32
362 case SDL_SYSWMEVENT:
364 SDL_SysWMmsg* m = e.syswm.msg;
365 hwnd = m->hwnd;
366 static bool init=false;
367 if (!init)
369 init = true;
370 DragAcceptFiles(hwnd, TRUE);
371 #ifdef USE_BBTABLET
372 td.initTablet(hwnd, tablet_system ? bbTabletDevice::SYSTEM_POINTER : bbTabletDevice::SEPARATE_POINTER );
373 if (!td.isValid())
374 printf("No tablet/driver found\n");
375 #endif
377 if (m->msg == WM_DROPFILES)
379 HDROP h = (HDROP)m->wParam;
381 char name[512];
382 if (DragQueryFile(h, 0xffffffff, 0, 0) == 1)
384 DragQueryFile(h, 0, name, sizeof(name)/sizeof(name[0]));
386 StateMakerBase::current->FileDrop(name);
389 DragFinish(h);
392 break;
394 #endif
396 case SDL_ACTIVEEVENT:
398 int gain = e.active.gain ? e.active.state : 0;
399 int loss = e.active.gain ? 0 : e.active.state;
400 SDL_focus = (SDL_focus | gain) & ~loss;
401 if (gain & SDL_APPACTIVE)
402 StateMakerBase::current->ScreenModeChanged();
403 if (loss & SDL_APPMOUSEFOCUS)
404 noMouse = 1;
405 else if (gain & SDL_APPMOUSEFOCUS)
406 noMouse = 0;
408 break;
411 case SDL_MOUSEMOTION:
412 noMouse = false;
413 StateMakerBase::current->Mouse(e.motion.x, e.motion.y, e.motion.x-mousex, e.motion.y-mousey, 0, 0, mouse_buttons);
414 mousex = e.motion.x; mousey = e.motion.y;
415 break;
416 case SDL_MOUSEBUTTONUP:
417 noMouse = false;
418 mouse_buttons &= ~(1<<(e.button.button-1));
419 StateMakerBase::current->Mouse(e.button.x, e.button.y, e.button.x-mousex, e.button.y-mousey,
420 0, 1<<(e.button.button-1), mouse_buttons);
421 mousex = e.button.x; mousey = e.button.y ;
422 break;
423 case SDL_MOUSEBUTTONDOWN:
424 noMouse = false;
425 mouse_buttons |= 1<<(e.button.button-1);
426 StateMakerBase::current->Mouse(e.button.x, e.button.y, e.button.x-mousex, e.button.y-mousey,
427 1<<(e.button.button-1), 0, mouse_buttons);
428 mousex = e.button.x; mousey = e.button.y ;
429 break;
431 case SDL_KEYUP:
432 StateMakerBase::current->KeyReleased(e.key.keysym.sym);
433 break;
435 case SDL_KEYDOWN:
437 SDL_KeyboardEvent & k = e.key;
439 if (k.keysym.sym==SDLK_F4 && (k.keysym.mod & KMOD_ALT))
441 quitting = 1;
443 else if (k.keysym.sym==SDLK_F12)
445 // Toggle system pointer controlled by tablet or not
446 #ifdef USE_BBTABLET
447 if (td.isValid())
449 tablet_system = !tablet_system;
450 td.setPointerMode(tablet_system ? bbTabletDevice::SYSTEM_POINTER : bbTabletDevice::SEPARATE_POINTER);
452 #endif
454 else if (k.keysym.sym==SDLK_RETURN && (k.keysym.mod & KMOD_ALT) && !(k.keysym.mod & KMOD_CTRL))
456 ToggleFullscreen();
458 else if (StateMakerBase::current->KeyPressed(k.keysym.sym, k.keysym.mod))
461 else if ((k.keysym.mod & (KMOD_ALT | KMOD_CTRL))==0)
463 StateMakerBase::GetNew(k.keysym.sym);
466 break;
468 case SDL_QUIT:
469 quitting = 1;
470 break;
474 SDL_Quit();
475 return 0;