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"
35 StateMakerBase
* StateMakerBase::first
= 0;
36 State
* StateMakerBase::current
= 0;
38 int SDL_focus
= SDL_APPACTIVE
| SDL_APPINPUTFOCUS
; // Initial focus state
46 bool tablet_system
= false;
48 char* LoadSaveDialog(bool save
, bool levels
, const char * title
)
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","*.*");
65 f
.lStructSize
= sizeof(f
);
66 f
.lpstrFile
= filename
;
67 f
.nMaxFile
= sizeof(filename
);
68 f
.lpstrInitialDir
= path
;
71 if (GetSaveFileName(&f
)==TRUE
)
73 // Remember user's choice of path!
74 _getcwd(path
, sizeof(path
)/sizeof(path
[0])-1);
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");
93 char* LoadSaveDialog(bool /*save*/, bool /*levels*/, const char * /*title*/)
101 int mouse_buttons
= 0;
102 int mousex
= 10, mousey
= 10;
106 double stylusx
= 0, stylusy
= 0;
108 float styluspressure
= 0;
109 SDL_Surface
* screen
= 0;
110 SDL_Surface
* realScreen
= 0;
112 extern State
* MakeWorld();
114 bool fullscreen
= false;
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
129 SDL_OPENGL
| (fullscreen
? SDL_FULLSCREEN
: 0) );
131 // printf("SDL_SetVideoMode (non-OpenGL)\n");
132 realScreen
= SDL_SetVideoMode(
133 SCREEN_W
, SCREEN_H
, // Width, Height
135 SDL_SWSURFACE
| SDL_DOUBLEBUF
| (fullscreen
? SDL_FULLSCREEN
: 0) );
139 SDL_FreeSurface(screen
);
141 SDL_Surface
* tempscreen
= SDL_CreateRGBSurface(
144 16, 0xf800, 0x07e0, 0x001f, 0);
146 screen
= SDL_DisplayFormat(tempscreen
);
147 SDL_FreeSurface(tempscreen
);
150 void ToggleFullscreen()
152 fullscreen
= !fullscreen
;
154 StateMakerBase::current
->ScreenModeChanged();
160 static int time
= SDL_GetTicks();
163 int x
= SDL_GetTicks() - time
;
165 if (x
<0) x
= 0, time
= SDL_GetTicks();
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);
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
!='\\')
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';
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));
204 SDL_Init(SDL_INIT_VIDEO
| SDL_INIT_NOPARACHUTE
);
206 SDL_Surface
* icon
= SDL_LoadBMP("graphics/icon.bmp");
209 static unsigned int mask
[32] = {
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
);
254 SDL_WarpMouse(SCREEN_W
/2, SCREEN_H
/2);
256 int videoExposed
= 1;
262 bbTabletDevice
&td
= bbTabletDevice::getInstance( );
263 SDL_EventState(SDL_SYSWMEVENT
, SDL_ENABLE
);
266 // printf("Main loop...\n");
268 StateMakerBase::GetNew();
273 while(!SDL_PollEvent(&e
) && !quitting
)
277 if ((SDL_focus
& 6)==6)
289 StateMakerBase::current
->Update(x
/ 1000.0);
293 // Not focussed. Try not to eat too much CPU!
299 StateMakerBase::current
->Mouse(mousex
, mousey
, 0, 0, 0, 0, mouse_buttons
);
303 StateMakerBase::current
->Render();
306 SDL_GL_SwapBuffers();
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
);
319 // Tablet ////////////////////////
321 while(hwnd
!=NULL
&& td
.getNextEvent(evt
))
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
));;
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",
360 case SDL_VIDEOEXPOSE
:
367 SDL_SysWMmsg
* m
= e
.syswm
.msg
;
369 static bool init
=false;
373 DragAcceptFiles(hwnd
, TRUE
);
375 td
.initTablet(hwnd
, tablet_system
? bbTabletDevice::SYSTEM_POINTER
: bbTabletDevice::SEPARATE_POINTER
);
377 printf("No tablet/driver found\n");
380 if (m
->msg
== WM_DROPFILES
)
382 HDROP h
= (HDROP
)m
->wParam
;
385 if (DragQueryFile(h
, 0xffffffff, 0, 0) == 1)
387 DragQueryFile(h
, 0, name
, sizeof(name
)/sizeof(name
[0]));
389 StateMakerBase::current
->FileDrop(name
);
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
)
408 else if (gain
& SDL_APPMOUSEFOCUS
)
414 case SDL_MOUSEMOTION
:
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
;
419 case SDL_MOUSEBUTTONUP
:
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
;
426 case SDL_MOUSEBUTTONDOWN
:
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
;
435 StateMakerBase::current
->KeyReleased(e
.key
.keysym
.sym
);
440 SDL_KeyboardEvent
& k
= e
.key
;
442 if (k
.keysym
.sym
==SDLK_F4
&& (k
.keysym
.mod
& KMOD_ALT
))
446 else if (k
.keysym
.sym
==SDLK_F12
)
448 // Toggle system pointer controlled by tablet or not
452 tablet_system
= !tablet_system
;
453 td
.setPointerMode(tablet_system
? bbTabletDevice::SYSTEM_POINTER
: bbTabletDevice::SEPARATE_POINTER
);
457 else if (k
.keysym
.sym
==SDLK_RETURN
&& (k
.keysym
.mod
& KMOD_ALT
) && !(k
.keysym
.mod
& KMOD_CTRL
))
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
);