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
22 #include <SDL_syswm.h>
23 #include <shellapi.h> // Windows header for drag & drop
25 #include "bbtablet/bbtablet.h"
31 StateMakerBase
* StateMakerBase::first
= 0;
32 State
* StateMakerBase::current
= 0;
34 int SDL_focus
= SDL_APPACTIVE
| SDL_APPINPUTFOCUS
; // Initial focus state
42 bool tablet_system
= false;
44 char* LoadSaveDialog(bool save
, bool levels
, const char * title
)
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","*.*");
61 f
.lStructSize
= sizeof(f
);
62 f
.lpstrFile
= filename
;
63 f
.nMaxFile
= sizeof(filename
);
64 f
.lpstrInitialDir
= path
;
67 if (GetSaveFileName(&f
)==TRUE
)
69 // Remember user's choice of path!
70 _getcwd(path
, sizeof(path
)/sizeof(path
[0])-1);
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");
89 char* LoadSaveDialog(bool save
, bool levels
, const char * title
)
97 int mouse_buttons
= 0;
98 int mousex
= 10, mousey
= 10;
102 double stylusx
= 0, stylusy
= 0;
104 float styluspressure
= 0;
105 SDL_Surface
* screen
= 0;
106 SDL_Surface
* realScreen
= 0;
108 extern State
* MakeWorld();
110 bool fullscreen
= false;
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
125 SDL_OPENGL
| (fullscreen
? SDL_FULLSCREEN
: 0) );
127 // printf("SDL_SetVideoMode (non-OpenGL)\n");
128 realScreen
= SDL_SetVideoMode(
129 SCREEN_W
, SCREEN_H
, // Width, Height
131 SDL_SWSURFACE
| SDL_DOUBLEBUF
| (fullscreen
? SDL_FULLSCREEN
: 0) );
135 SDL_FreeSurface(screen
);
137 SDL_Surface
* tempscreen
= SDL_CreateRGBSurface(
140 16, 0xf800, 0x07e0, 0x001f, 0);
142 screen
= SDL_DisplayFormat(tempscreen
);
143 SDL_FreeSurface(tempscreen
);
146 void ToggleFullscreen()
148 fullscreen
= !fullscreen
;
150 StateMakerBase::current
->ScreenModeChanged();
156 static int time
= SDL_GetTicks();
159 int x
= SDL_GetTicks() - time
;
161 if (x
<0) x
= 0, time
= SDL_GetTicks();
167 int main(int argc
, char * argv
[])
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);
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
!='\\')
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';
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));
200 SDL_Init(SDL_INIT_EVERYTHING
| SDL_INIT_NOPARACHUTE
);
202 SDL_Surface
* icon
= SDL_LoadBMP("graphics/icon.bmp");
205 static unsigned int mask
[32] = {
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
);
250 SDL_WarpMouse(SCREEN_W
/2, SCREEN_H
/2);
252 int videoExposed
= 1;
258 bbTabletDevice
&td
= bbTabletDevice::getInstance( );
259 SDL_EventState(SDL_SYSWMEVENT
, SDL_ENABLE
);
262 // printf("Main loop...\n");
264 StateMakerBase::GetNew();
265 int time
= SDL_GetTicks();
270 while(!SDL_PollEvent(&e
) && !quitting
)
274 if ((SDL_focus
& 6)==6)
286 StateMakerBase::current
->Update(x
/ 1000.0);
290 // Not focussed. Try not to eat too much CPU!
296 StateMakerBase::current
->Mouse(mousex
, mousey
, 0, 0, 0, 0, mouse_buttons
);
300 StateMakerBase::current
->Render();
303 SDL_GL_SwapBuffers();
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
);
316 // Tablet ////////////////////////
318 while(hwnd
!=NULL
&& td
.getNextEvent(evt
))
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
));;
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",
357 case SDL_VIDEOEXPOSE
:
364 SDL_SysWMmsg
* m
= e
.syswm
.msg
;
366 static bool init
=false;
370 DragAcceptFiles(hwnd
, TRUE
);
372 td
.initTablet(hwnd
, tablet_system
? bbTabletDevice::SYSTEM_POINTER
: bbTabletDevice::SEPARATE_POINTER
);
374 printf("No tablet/driver found\n");
377 if (m
->msg
== WM_DROPFILES
)
379 HDROP h
= (HDROP
)m
->wParam
;
382 if (DragQueryFile(h
, 0xffffffff, 0, 0) == 1)
384 DragQueryFile(h
, 0, name
, sizeof(name
)/sizeof(name
[0]));
386 StateMakerBase::current
->FileDrop(name
);
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
)
405 else if (gain
& SDL_APPMOUSEFOCUS
)
411 case SDL_MOUSEMOTION
:
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
;
416 case SDL_MOUSEBUTTONUP
:
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
;
423 case SDL_MOUSEBUTTONDOWN
:
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
;
432 StateMakerBase::current
->KeyReleased(e
.key
.keysym
.sym
);
437 SDL_KeyboardEvent
& k
= e
.key
;
439 if (k
.keysym
.sym
==SDLK_F4
&& (k
.keysym
.mod
& KMOD_ALT
))
443 else if (k
.keysym
.sym
==SDLK_F12
)
445 // Toggle system pointer controlled by tablet or not
449 tablet_system
= !tablet_system
;
450 td
.setPointerMode(tablet_system
? bbTabletDevice::SYSTEM_POINTER
: bbTabletDevice::SEPARATE_POINTER
);
454 else if (k
.keysym
.sym
==SDLK_RETURN
&& (k
.keysym
.mod
& KMOD_ALT
) && !(k
.keysym
.mod
& KMOD_CTRL
))
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
);