1 /***************************************************************************
2 sdlhandler.cpp - Interface to SDL
3 -------------------
4 begin : Sat May 3 2003
5 copyright : (C) 2003 by Gabor Torok
6 email : cctorok@yahoo.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "common/constants.h"
19 #include "sdlhandler.h"
20 #include "gameadapter.h"
21 #include "gui/window.h"
22 #include "gui/eventhandler.h"
23 #include "preferences.h"
24 #include "sdleventhandler.h"
25 #include "sdlscreenview.h"
26 #include "session.h"
27 #include "party.h"
28 #include "debug.h"
29 #include "freetype/fontmgr.h"
30 #include "sound.h"
31 #include "sqbinding/sqbinding.h"
32 #include "render/cutscene.h"
33 #include "render/texture.h"
34
35 // ###### MS Visual C++ specific ######
36 #if defined(_MSC_VER) && defined(_DEBUG)
37 # define new DEBUG_NEW
38 # undef THIS_FILE
39 static char THIS_FILE[] = __FILE__;
40 #endif
41
42 using namespace std;
43
44 // FIXME: use static member variable, std::string is clear by default
45 string willSavePath = "";
46
47 vector<SDLHandler::FontInfo*> SDLHandler::fontInfos;
48 vector<string> modeDescriptions;
49 int videoModeCount;
50
51 #define FORBIDDEN_CURSOR_TIME 2000
52
53 #define FADEOUT_SPEED 10
54
55 //#define DEBUG_MOUSE_FOCUS 1
56
57 bool SDLHandler::stencilBufferUsed = false;
58 bool SDLHandler::showDebugInfo = SHOW_FPS;
59
60 // milllis
61 #define DOUBLE_CLICK_INTERVAL 500
62 // pixel range
63 #define DOUBLE_CLICK_TOLERANCE 5
64
65 #define DEFAULT_MIN_DEPTH -3000
66 #define DEFAULT_MAX_DEPTH 1000
67
SDLHandler(GameAdapter * gameAdapter)68 SDLHandler::SDLHandler( GameAdapter *gameAdapter ) {
69 /* These are to calculate our fps */
70 this->gameAdapter = gameAdapter;
71 T0 = 0;
72 Frames = 0;
73 fps = 0;
74 screen = NULL;
75 lastMouseX = lastMouseY = mouseX = mouseY = mouseButton = mouseEvent = 0;
76 mouseFocusX = mouseFocusY = 0;
77 mouseDragging = false;
78 mouseIsMovingOverMap = false;
79 handlerCount = 0;
80 invertMouse = false;
81 cursorMode = Constants::CURSOR_NORMAL;
82 font_initialized = false;
83 debugStr = NULL;
84 lastLeftClick = 0;
85 lastMouseMoveTime = SDL_GetTicks();
86 isDoubleClick = false;
87 dontUpdateScreen = false;
88 mouseLock = NULL;
89 willUnlockMouse = false;
90 willBlockEvent = false;
91 forbiddenTimer = 0;
92 fadeoutStartAlpha = fadeoutEndAlpha = 0;
93 fadeoutSteps = 16;
94 fadeoutCurrentStep = 0;
95 fadeoutTimer = 0;
96 cursorVisible = true;
97 continueFunc = "";
98 continueTimeout = continueStart = 0;
99 orthoDepthMin = DEFAULT_MIN_DEPTH;
100 orthoDepthMax = DEFAULT_MAX_DEPTH;
101 }
102
~SDLHandler()103 SDLHandler::~SDLHandler() {
104 // undoing XXX by ShapePalette::initFonts() + SDLHandler::initFonts()
105 for ( size_t i = 0; i < fontInfos.size(); ++i ) {
106 delete fontInfos[ i ]->fontMgr;
107 delete fontInfos[ i ];
108 }
109 fontInfos.clear();
110 }
111
pushHandlers(SDLEventHandler * eventHandler,SDLScreenView * screenView)112 void SDLHandler::pushHandlers( SDLEventHandler *eventHandler,
113 SDLScreenView *screenView ) {
114 if ( handlerCount == 10 ) {
115 fprintf( stderr, "Error: can't push any more handlers." );
116 exit( 1 );
117 }
118 eventHandlers[handlerCount] = this->eventHandler;
119 screenViews[handlerCount] = this->screenView;
120 handlerCount++;
121 setHandlers( eventHandler, screenView );
122 }
123
popHandlers()124 bool SDLHandler::popHandlers() {
125 if ( handlerCount == 0 ) return true;
126 handlerCount--;
127 setHandlers( eventHandlers[handlerCount], screenViews[handlerCount] );
128 return false;
129 }
130
setHandlers(SDLEventHandler * eventHandler,SDLScreenView * screenView)131 void SDLHandler::setHandlers( SDLEventHandler *eventHandler,
132 SDLScreenView *screenView ) {
133 this->eventHandler = eventHandler;
134 this->screenView = screenView;
135 if ( screen ) resizeWindow( screen->w, screen->h );
136 }
137
138 /* function to release/destroy our resources and restoring the old desktop */
quit(int returnCode)139 void SDLHandler::quit( int returnCode ) {
140 gameAdapter->getSession()->setExiting( true );
141
142 #ifdef HAVE_SDL_NET
143 // shutdown SDL_net
144 SDLNet_Quit();
145 #endif
146
147 /* clean up the window */
148 SDL_Quit( );
149
150 /* and exit appropriately */
151 exit( returnCode );
152 }
153
resetDepthLimits()154 void SDLHandler::resetDepthLimits() {
155 setDepthLimits( DEFAULT_MIN_DEPTH, DEFAULT_MAX_DEPTH );
156 }
157
setDepthLimits(float min,float max)158 void SDLHandler::setDepthLimits( float min, float max ) {
159 this->orthoDepthMin = min;
160 this->orthoDepthMax = max;
161 resizeWindow( screen->w, screen->h );
162 }
163
164 /* function to reset our viewport after a window resize */
resizeWindow(int width,int height)165 int SDLHandler::resizeWindow( int width, int height ) {
166 // Height / width ratio
167 // GLfloat ratio;
168
169 // Protect against a divide by zero
170 if ( height == 0 ) height = 1;
171 lastWidth = width;
172 lastHeight = height;
173
174 // ratio = ( GLfloat )width / ( GLfloat )height;
175
176 // Setup our viewport.
177 glViewport( 0, 0, ( GLsizei )width, ( GLsizei )height );
178
179 // change to the projection matrix and set our viewing volume.
180 glMatrixMode( GL_PROJECTION );
181 glLoadIdentity( );
182
183 // Set our perspective
184 //gluPerspective( 45.0f, ratio, 0.1f, 100.0f );
185 setOrthoView();
186
187 // Make sure we're chaning the model view and not the projection
188 glMatrixMode( GL_MODELVIEW );
189
190 // Reset The View
191 glLoadIdentity( );
192
193 return( TRUE );
194 }
195
196 // Note: !!! also called from Map::getMapXYZAtScreenXY !!!
setOrthoView()197 void SDLHandler::setOrthoView() {
198 glOrtho( 0.0f, lastWidth, lastHeight, 0.0f, orthoDepthMin, orthoDepthMax );
199 }
200
201 /* general OpenGL initialization function */
initGL()202 int SDLHandler::initGL() {
203 /* Enable Texture Mapping */
204 glEnable( GL_TEXTURE_2D );
205
206 /* Enable smooth shading */
207 glShadeModel( GL_SMOOTH );
208
209 // We use ortho projection, so perspective correction isn't needed
210 glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST );
211
212 // Create really nice mipmaps.
213 glHint( GL_GENERATE_MIPMAP_HINT, GL_NICEST );
214
215 // Use per-vertex fog.
216 glHint( GL_FOG_HINT, GL_FASTEST );
217
218 // Faster antialiasing for primitives.
219 glHint( GL_POINT_SMOOTH_HINT, GL_FASTEST );
220 glHint( GL_LINE_SMOOTH_HINT, GL_FASTEST );
221
222 // which one to use?
223 // default is good
224 //glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST);
225 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
226 glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
227
228 /* Set the background black */
229 glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );
230
231 /* Depth buffer setup */
232 glClearDepth( 1.0f );
233 if ( stencilBufferUsed ) glClearStencil( 0 ); // Clear The Stencil Buffer To 0
234
235 /* Enables Depth Testing */
236 glEnable( GL_DEPTH_TEST );
237
238 /* The Type Of Depth Test To Do */
239 glDepthFunc( GL_LEQUAL );
240
241 // Don't dither textures on truecolor displays.
242 if ( gameAdapter->getPreferences()->getBpp() > 16 ) {
243 glDisable( GL_DITHER );
244 } else {
245 glEnable( GL_DITHER );
246 }
247
248 glColorMaterial ( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ) ;
249 glEnable( GL_COLOR_MATERIAL );
250
251 /* initialize opengl extensions */
252 if ( Constants::multitexture ) {
253 // fprintf(stderr, "BEFORE: glSDLActiveTextureARB=%u\n", glSDLActiveTextureARB);
254 glSDLActiveTextureARB =
255 ( PFNGLACTIVETEXTUREARBPROC )SDL_GL_GetProcAddress ( "glActiveTextureARB" );
256 // fprintf(stderr, "AFTER: glSDLActiveTextureARB=%u\n", glSDLActiveTextureARB);
257 glSDLMultiTexCoord2fARB =
258 ( PFNGLMULTITEXCOORD2FARBPROC )SDL_GL_GetProcAddress ( "glMultiTexCoord2fARB" );
259 glSDLMultiTexCoord2iARB =
260 ( PFNGLMULTITEXCOORD2IARBPROC )SDL_GL_GetProcAddress ( "glMultiTexCoord2iARB" );
261 }
262 return( TRUE );
263 }
264
testModesInFormat(SDL_PixelFormat * format,Uint32 flags)265 bool testModesInFormat( SDL_PixelFormat *format, Uint32 flags ) {
266 SDL_Rect **modes;
267 int i;
268
269 printf( "Available modes with given flags in %d bpp:\n", format->BitsPerPixel );
270
271 /* Get available fullscreen/hardware modes */
272 modes = SDL_ListModes( format, flags );
273
274 /* Check is there are any modes available */
275 if ( modes == ( SDL_Rect ** )0 ) {
276 printf( "\tNo modes available!\n" );
277 return false;
278 }
279
280 /* Check if our resolution is restricted */
281 if ( modes == ( SDL_Rect ** ) - 1 ) {
282 printf( "\tAll resolutions available.\n" );
283 return true;
284 }
285
286 /* Print valid modes */
287 for ( i = 0;modes[i];++i )
288 printf( "\t%d x %d\n", modes[i]->w, modes[i]->h );
289
290 //free(modes); // crashes; ok to not free since we only do this a few times
291 return true;
292 }
293
testModes(Uint32 flags,bool findMaxBpp=false)294 int testModes( Uint32 flags, bool findMaxBpp = false ) {
295 int bpp[] = { 32, 24, 16, 15, 8, 0 };
296 SDL_PixelFormat format;
297 for ( int i = 0; bpp[i]; i++ ) {
298 format.BitsPerPixel = bpp[i];
299 if ( testModesInFormat( &format, flags ) && findMaxBpp ) return bpp[i];
300 }
301 return -1;
302 }
303
304
getVideoModes()305 void SDLHandler::getVideoModes() {
306 SDL_Rect **modes;
307 Uint32 flags;
308
309 modeDescriptions.clear();
310
311 if ( !screen ) {
312 fprintf( stderr, "SDLHandler :: you must allocate screen before calling getVideoModes!!\n" );
313 exit( -1 );
314 }
315
316 // Get current video flags (hwsurface/swsurface, fullscreen/not fullscreen..)
317 flags = screen->flags;
318
319 // Get available modes for the current flags
320 modes = SDL_ListModes( NULL, flags );
321
322 // Copy them to a char array
323 if ( modes != ( SDL_Rect ** )0 ) {
324 videoModeCount = 0;
325 if ( modes == ( SDL_Rect ** ) - 1 ) {
326 // All modes are available, so let's go..
327 videoModeCount = 14;
328 modeDescriptions.push_back( "800 x 600" );
329 modeDescriptions.push_back( "1024 x 600" );
330 modeDescriptions.push_back( "1024 x 768" );
331 modeDescriptions.push_back( "1152 x 864" );
332 modeDescriptions.push_back( "1280 x 768" );
333 modeDescriptions.push_back( "1280 x 800" );
334 modeDescriptions.push_back( "1280 x 960" );
335 modeDescriptions.push_back( "1280 x 1024" );
336 modeDescriptions.push_back( "1400 x 1050" );
337 modeDescriptions.push_back( "1440 x 900" );
338 modeDescriptions.push_back( "1600 x 1200" );
339 modeDescriptions.push_back( "1680 x 1050" );
340 modeDescriptions.push_back( "1920 x 1200" );
341 modeDescriptions.push_back( "2048 x 1536" );
342 } else {
343 // Only a few modes available, which ones ?
344 for ( videoModeCount = 0; modes[videoModeCount]; videoModeCount++ );
345 if ( videoModeCount ) {
346 for ( int i = 0; i < videoModeCount; i++ ) {
347 if ( modes[i]->h > 599 && modes[i]->w < 2049 ) {
348 char temp[ 50 ];
349 snprintf( temp, 50, "%d x %d", modes[i]->w, modes[i]->h );
350 modeDescriptions.push_back( temp );
351 }
352 }
353 videoModeCount = modeDescriptions.size();
354 } else {
355 videoModeCount = 1;
356 modeDescriptions.push_back( "No modes available!\n" );
357 }
358 }
359 } else {
360 videoModeCount = 1;
361 modeDescriptions.push_back( "No modes available!\n" );
362 }
363 }
364
getVideoModeCount()365 int SDLHandler::getVideoModeCount() {
366 getVideoModes();
367 return videoModeCount;
368 }
369
getVideoMode(int mode)370 std::string SDLHandler::getVideoMode( int mode ) {
371 // char vm[255];
372 // snprintf(vm, 255, "%s", modeDescriptions[mode].c_str());
373 return modeDescriptions[mode];
374 // return vm;
375 }
376
setVideoMode(Preferences * uc)377 void SDLHandler::setVideoMode( Preferences * uc ) {
378 /* this holds some info about our display */
379 const SDL_VideoInfo *videoInfo;
380
381 /* initialize SDL */
382 if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) {
383 fprintf( stderr, "Video initialization failed: %s\n", SDL_GetError( ) );
384 quit( 1 );
385 }
386
387 if ( TTF_Init() < 0 ) {
388 fprintf( stderr, "Couldn't initialize SDL_ttf: %s\n", SDL_GetError() );
389 quit( 1 );
390 }
391
392 #ifdef HAVE_SDL_NET
393 // initialize SDL_net
394 if ( SDLNet_Init() == -1 ) {
395 cerr << "*** error: SDLNet_Init: " << SDL_GetError() << endl;
396 exit( 2 );
397 }
398 #endif
399
400 /* Fetch the video info */
401 videoInfo = SDL_GetVideoInfo( );
402
403 if ( !videoInfo ) {
404 fprintf( stderr, "Video query failed: %s\n", SDL_GetError( ) );
405 quit( 1 );
406 }
407
408
409 videoFlags = SDL_OPENGL; /* Enable OpenGL in SDL */
410
411 // these make no sense, accrd. to: http://osdl.sourceforge.net/main/documentation/rendering/SDL-openGL.html#flags
412 //if(uc->getDoublebuf()) {
413 //videoFlags |= SDL_GL_DOUBLEBUFFER; /* Enable double buffering */
414 //}
415 //if(uc->getHwpal())
416 //videoFlags |= SDL_HWPALETTE; /* Store the palette in hardware */
417 /* This checks to see if surfaces can be stored in memory */
418 // if(uc->getForce_hwsurf()) videoFlags |= SDL_HWSURFACE;
419 // else if(uc->getForce_swsurf()) videoFlags |= SDL_SWSURFACE;
420 // else {
421 //if ( videoInfo->hw_available ) videoFlags |= SDL_HWSURFACE;
422 //else videoFlags |= SDL_SWSURFACE;
423 //}
424 ///* This checks if hardware blits can be done */
425 //if ( uc->getHwaccel() && videoInfo->blit_hw ) videoFlags |= SDL_HWACCEL;
426
427 if ( uc->getFullscreen() ) {
428 videoFlags |= SDL_FULLSCREEN;
429 } else if ( uc->getResizeable() ) {
430 videoFlags |= SDL_RESIZABLE; // Enable window resizing
431 }
432
433 if ( uc->getTest() ) {
434 testModes( videoFlags );
435 quit( 0 );
436 }
437
438 // try to find the highest bpp for this mode
439 int bpp;
440 if ( uc->getBpp() == -1 ) {
441 bpp = testModes( videoFlags, true );
442 if ( bpp == -1 ) {
443 fprintf( stderr, "Could not detect suitable opengl video mode.\n" );
444 fprintf( stderr, "You can manually select one with the -bpp option\n" );
445 quit( 0 );
446 } else {
447 uc->setBpp( bpp );
448 }
449 }
450
451 /* Sets up OpenGL double buffering */
452 if ( uc->getDoublebuf() ) {
453 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1 );
454 } else {
455 SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 0 );
456 }
457
458 // vertical retrace (0-off, 1-on, >1 every n-th retrace)
459 SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 0 );
460
461 if ( uc->getStencilbuf() ) {
462 uc->setStencilBufInitialized( true );
463 stencilBufferUsed = true;
464 SDL_GL_SetAttribute( SDL_GL_STENCIL_SIZE, 8 );
465 }
466
467 cout << "Setting video mode: " << uc->getW() << "x" << uc->getH() << "x" << uc->getBpp() << endl;
468
469 /* get a SDL surface */
470 screen = SDL_SetVideoMode( uc->getW(), uc->getH(), uc->getBpp(), videoFlags );
471 /* Verify there is a surface */
472 if ( !screen ) {
473 fprintf( stderr, "Video mode set failed: %s\n", SDL_GetError( ) );
474 quit( 1 );
475 }
476
477 /* hide the mouse cursor; we have our own */
478 SDL_ShowCursor( SDL_DISABLE );
479 SDL_WM_SetCaption( "Scourge", NULL );
480
481 /* initialize OpenGL */
482 initGL( );
483
484 /* resize the initial window */
485 resizeWindow( screen->w, screen->h );
486 SDL_WarpMouse ( uc->getW() / 2, uc->getH() / 2 );
487 }
488
fireEvent(Widget * widget,SDL_Event * event)489 void SDLHandler::fireEvent( Widget *widget, SDL_Event *event ) {
490 storedWidget = widget;
491 storedEvent = event;
492 }
493
firedEventWaiting()494 bool SDLHandler::firedEventWaiting() {
495 return storedEvent != NULL;
496 }
497
applyMouseOffset(int x,int y,int * newX,int * newY)498 void SDLHandler::applyMouseOffset( int x, int y, int *newX, int *newY ) {
499 if ( cursorMode == Constants::CURSOR_CROSSHAIR ) {
500 mouseFocusX = mouseFocusY = 24;
501 } else {
502 mouseFocusX = mouseFocusY = 0;
503 }
504 *newX = x + mouseFocusX;
505 *newY = y + mouseFocusY;
506 }
507
508 Uint32 lastAmbientTime = 0;
mainLoop()509 void SDLHandler::mainLoop() {
510 bool isActive = true;
511 running = true;
512 while ( true ) {
513 if ( processEvents( &isActive ) ) return;
514 if ( !running && popHandlers() ) return;
515
516 /*if ( isActive )*/ drawScreen();
517 gameAdapter->getSession()->getSound()->checkMusic( gameAdapter->getCurrentCombatMusic() || gameAdapter->inTurnBasedCombat(),
518 gameAdapter->getCurrentCombatMusic() );
519 Uint32 now = SDL_GetTicks();
520 if ( !gameAdapter->getAmbientPaused() && now - lastAmbientTime > AMBIENT_PAUSE_MIN ) {
521 lastAmbientTime = now;
522 if ( Util::dice( AMBIENT_ROLL ) == 0 ) {
523 gameAdapter->getSession()->getSound()->
524 startAmbientSound( gameAdapter->getSession()->getAmbientSoundName(),
525 gameAdapter->getCurrentDepth() );
526 }
527 }
528 if ( continueTimeout > 0 && now - continueStart > continueTimeout ) {
529 char tmp[200];
530 strcpy( tmp, continueFunc.c_str() );
531 // clear it first, in case continueAt is called again from squirrel
532 continueStart = continueTimeout = 0;
533 continueFunc = "";
534 gameAdapter->getSession()->getSquirrel()->callNoArgMethod( tmp );
535 }
536 }
537 }
538
processEvents(bool * isActive)539 bool SDLHandler::processEvents( bool *isActive ) {
540 SDL_Event event;
541 int mx, my;
542
543 Uint32 now = SDL_GetTicks();
544 mouseIsMovingOverMap = false;
545 while ( SDL_PollEvent( &event ) ) {
546 isDoubleClick = false;
547 mouseEvent = mouseButton = 0;
548 Widget *widget = NULL;
549 Window *win = NULL;
550 switch ( event.type ) {
551 case SDL_MOUSEMOTION:
552 if ( invertMouse ) event.motion.y = screen->h - event.motion.y;
553 applyMouseOffset( event.motion.x, event.motion.y, &mx, &my );
554 mouseX = mx;
555 mouseY = my;
556 mouseButton = event.button.button;
557 mouseEvent = SDL_MOUSEMOTION;
558 // don't process events during a fade
559 if ( fadeoutTimer <= 0 && cursorVisible ) widget = Window::delegateEvent( &event, mouseX, mouseY, &win );
560 if ( !widget && !win ) {
561 mouseIsMovingOverMap = true;
562 lastMouseMoveTime = now;
563 }
564 break;
565 case SDL_MOUSEBUTTONUP:
566 if ( invertMouse ) event.button.y = screen->h - event.button.y;
567 applyMouseOffset( event.button.x, event.button.y, &mx, &my );
568 mouseEvent = SDL_MOUSEBUTTONUP;
569 mouseButton = event.button.button;
570 mouseDragging = false;
571 if ( event.button.button == SDL_BUTTON_LEFT || event.button.button == SDL_BUTTON_RIGHT ) {
572 isDoubleClick = ( now - lastLeftClick < DOUBLE_CLICK_INTERVAL &&
573 abs( lastMouseX - event.button.x ) < DOUBLE_CLICK_TOLERANCE &&
574 abs( lastMouseY - event.button.y ) < DOUBLE_CLICK_TOLERANCE );
575 lastLeftClick = now;
576 // don't process events during a fade
577 if ( fadeoutTimer <= 0 && cursorVisible ) widget = Window::delegateEvent( &event, mx, my, &win );
578 }
579 lastMouseX = event.button.x;
580 lastMouseY = event.button.y;
581 break;
582 case SDL_MOUSEBUTTONDOWN:
583 if ( invertMouse ) event.button.y = screen->h - event.button.y;
584 applyMouseOffset( event.button.x, event.button.y, &mx, &my );
585 mouseEvent = SDL_MOUSEBUTTONDOWN;
586 mouseButton = event.button.button;
587 mouseDragging = ( event.button.button == SDL_BUTTON_LEFT );
588 //if(event.button.button == SDL_BUTTON_LEFT || event.button.button == SDL_BUTTON_RIGHT) {
589 // don't process events during a fade
590 if ( fadeoutTimer <= 0 && cursorVisible ) widget = Window::delegateEvent( &event, mx, my, &win );
591 //}
592 break;
593 case SDL_ACTIVEEVENT:
594 /* Something's happend with our focus
595 * If we lost focus or we are iconified, we
596 * shouldn't draw the screen
597 */
598 if ( isActive ) {
599 *isActive = ( event.active.gain == 0 ? false : true );
600 }
601 break;
602 case SDL_VIDEORESIZE:
603 /* handle resize event */
604 screen = SDL_SetVideoMode( event.resize.w,
605 event.resize.h,
606 16, videoFlags );
607 if ( !screen ) {
608 fprintf( stderr, "Could not get a surface after resize: %s\n", SDL_GetError( ) );
609 quit( 1 );
610 }
611 resizeWindow( event.resize.w, event.resize.h );
612 break;
613 case SDL_KEYUP:
614 // only process CTRL + F1 once (on keyup)
615 if ( event.key.keysym.sym == SDLK_F1 &&
616 event.key.keysym.mod & KMOD_CTRL ) {
617 SDL_WM_ToggleFullScreen( screen );
618 break;
619 }
620 case SDL_KEYDOWN:
621 applyMouseOffset( mouseX, mouseY, &mx, &my );
622 // don't process events during a fade
623 if ( fadeoutTimer <= 0 && cursorVisible ) widget = Window::delegateEvent( &event, mx, my, &win );
624 break;
625 case SDL_QUIT:
626 quit( 0 ); // handle quit requests
627 break;
628 default:
629 break;
630 }
631
632 // Show pointer over widgets unless casting a spell
633 if ( getCursorMode() == Constants::CURSOR_FORBIDDEN &&
634 SDL_GetTicks() - forbiddenTimer > FORBIDDEN_CURSOR_TIME ) {
635 setCursorMode( Constants::CURSOR_NORMAL );
636 }
637
638 if ( !mouseIsMovingOverMap && getCursorMode() != Constants::CURSOR_CROSSHAIR ) {
639 setCursorMode( Constants::CURSOR_NORMAL );
640 }
641
642 // swallow this event
643 if ( willBlockEvent ) {
644 willBlockEvent = false;
645 continue;
646 }
647
648 bool res = false;
649 // don't process events during a fade
650 if ( fadeoutTimer <= 0 ) {
651 if ( widget ) {
652 if ( !mouseLock || mouseLock == widget ) {
653 EventHandler *eh = getEventHandler( widget );
654 if( eh ) {
655 // new-style event handling
656 res = eh->handleEvent( widget, &event );
657 } else {
658 // old-style event handling
659 res = eventHandler->handleEvent( widget, &event );
660 }
661 if ( event.type == SDL_MOUSEMOTION ) {
662 if( win && win->getRawEventHandler() ) {
663 res = win->getRawEventHandler()->handleEvent( &event );
664 }
665
666 // also run the generic event handler.
667 // this is so that moving the cursor over a
668 // window doesn't scroll the map forever
669 res = eventHandler->handleEvent( &event );
670 }
671 }
672 } else {
673 if ( !mouseLock ) {
674 if( win && win->getRawEventHandler() ) {
675 res = win->getRawEventHandler()->handleEvent( &event );
676 }
677
678 // also run the generic event handler
679 res = eventHandler->handleEvent( &event );
680 }
681 }
682 if ( res ) {
683 if ( popHandlers() ) {
684 return true;
685 }
686 }
687 }
688 }
689
690 if ( willUnlockMouse ) {
691 mouseLock = NULL;
692 willUnlockMouse = false;
693 }
694
695 return false;
696 }
697
drawCursor()698 void SDLHandler::drawCursor() {
699 // for cursor: do alpha bit testing
700 // glEnable( GL_ALPHA_TEST );
701 // glAlphaFunc( GL_NOTEQUAL, 0 ); // this works better for people with the reverse alpha problem (see forums)
702 glEnable( GL_BLEND );
703 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
704 glEnable( GL_TEXTURE_2D );
705 glDisable( GL_DEPTH_TEST );
706 glDisable( GL_CULL_FACE );
707 glPushMatrix();
708 glLoadIdentity();
709 glTranslatef( mouseX - mouseFocusX, mouseY - mouseFocusY, 0 );
710 gameAdapter->getCursorTexture( cursorMode ).glBind();
711 glColor4f( 1, 1, 1, 1 );
712 // glNormal3f( 0, 0, 1 );
713 glBegin( GL_TRIANGLE_STRIP );
714 glTexCoord2f( 0, 0 );
715 glVertex2f( 0, 0 );
716 glTexCoord2f( 1, 0 );
717 glVertex2f( gameAdapter->getCursorWidth(), 0 );
718 glTexCoord2f( 0, 1 );
719 glVertex2f( 0, gameAdapter->getCursorHeight() );
720 glTexCoord2f( 1, 1 );
721 glVertex2f( gameAdapter->getCursorWidth(), gameAdapter->getCursorHeight() );
722 glEnd();
723 glPopMatrix();
724
725 // glDisable( GL_ALPHA_TEST );
726 glDisable( GL_TEXTURE_2D );
727 glDisable( GL_BLEND );
728
729 #ifdef DEBUG_MOUSE_FOCUS
730 // cursor focus
731 glPushMatrix();
732 glLoadIdentity();
733 glTranslatef( mouseX, mouseY, 0 );
734 glColor4f( 1, 1, 1, 1 );
735 glBegin( GL_TRIANGLE_STRIP );
736 glVertex2f( 0, 0 );
737 glVertex2f( 10, 0 );
738 glVertex2f( 0, 10 );
739 glVertex2f( 10, 10 );
740 glEnd();
741 glPopMatrix();
742 #endif
743
744 glEnable( GL_DEPTH_TEST );
745 glEnable( GL_CULL_FACE );
746 }
747
processEventsAndRepaint()748 void SDLHandler::processEventsAndRepaint() {
749 processEvents();
750 drawScreen();
751 }
752
drawScreen()753 void SDLHandler::drawScreen() {
754
755 if ( eventHandler == NULL ) { // it's never set to NULL
756 SDL_GL_SwapBuffers();
757 return;
758 }
759
760 drawScreenInternal();
761
762 if ( !willSavePath.empty() ) { // it's always empty
763 saveScreenInternal( willSavePath );
764 willSavePath.clear();
765 }
766
767 /* Gather our frames per second */
768 calculateFps();
769 }
770
saveScreen(string & path,bool thumbnail)771 void SDLHandler::saveScreen( string& path, bool thumbnail ) {
772 drawScreenInternal();
773 saveScreenInternal( path, thumbnail );
774 }
775
drawScreenInternal()776 void SDLHandler::drawScreenInternal() {
777 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
778 if ( stencilBufferUsed ) glClear( GL_STENCIL_BUFFER_BIT );
779 glClearColor( 0.0f, 0.0f, 0.0f, 0.5f );
780 glClearDepth( 1.0f );
781 screenView->drawView();
782
783 // redraw the gui
784 Window::drawVisibleWindows();
785
786 screenView->drawAfter();
787
788 if ( fadeoutTimer > 0 ) {
789 drawFadeout();
790 }
791
792 if ( cursorVisible ) drawCursor();
793
794 if ( showDebugInfo ) {
795 drawDebugInfo();
796 }
797
798 // these tie cpu execution to the gpu's so there is no benefit from the overlap
799 //glFlush();
800 //glFinish();
801
802 /* Draw it to the screen */
803 SDL_GL_SwapBuffers( );
804 }
805
806 #define SCREEN_SHOT_WIDTH 160
807 #define SCREEN_SHOT_HEIGHT 120
808
saveScreenInternal(string & path,bool thumbnail)809 void SDLHandler::saveScreenInternal( string& path, bool thumbnail ) {
810 if ( !gameAdapter->getPreferences()->getEnableScreenshots() ) {
811 cerr << "*** Screenshots disabled in options. Not saving: " << path << endl;
812 return;
813 }
814
815 SDL_Surface *surface = SDL_CreateRGBSurface( SDL_SWSURFACE, screen->w, screen->h, 24,
816 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
817 0x00FF0000, 0x0000FF00, 0x000000FF, 0 );
818 #else
819 0x000000FF, 0x0000FF00, 0x00FF0000, 0 );
820 #endif
821
822 // read the center of the screen
823 int sx = ( screen->w - surface->w ) / 2;
824 int sy = ( screen->h - surface->h ) / 2;
825
826 glReadPixels( sx, sy, surface->w, surface->h, GL_BGR, GL_UNSIGNED_BYTE, surface->pixels );
827
828 int w, h;
829 if ( thumbnail ) {
830 w = SCREEN_SHOT_WIDTH; h = SCREEN_SHOT_HEIGHT;
831 } else {
832 w = surface->w; h = surface->h;
833 }
834
835 SDL_Surface *scaled = SDL_CreateRGBSurface( SDL_SWSURFACE, w, h, 24,
836 #if SDL_BYTEORDER == SDL_LIL_ENDIAN
837 0x00FF0000, 0x0000FF00, 0x000000FF, 0 );
838 #else
839 0x000000FF, 0x0000FF00, 0x00FF0000, 0 );
840 #endif
841
842 // scale to desired size (also flip image at the same time)
843 Uint8 *src = ( Uint8* )surface->pixels;
844 Uint8 *dst = ( Uint8* )scaled->pixels;
845 float dx = ( static_cast<float>( surface->w ) / static_cast<float>( scaled->w ) );
846 float dy = ( static_cast<float>( surface->h ) / static_cast<float>( scaled->h ) );
847
848 for ( int x = 0; x < w; x++ ) {
849 for ( int y = 0; y < h; y++ ) {
850 memcpy( dst + ( scaled->pitch * y + x * scaled->format->BytesPerPixel ), src + ( surface->pitch * ( surface->h - 1 - static_cast<int>( y * dy ) ) + static_cast<int>( x * dx ) * surface->format->BytesPerPixel ), scaled->format->BytesPerPixel );
851 }
852 }
853
854 SDL_SaveBMP( scaled, path.c_str() );
855
856 SDL_FreeSurface( surface );
857 SDL_FreeSurface( scaled );
858 }
859
calculateFps()860 void SDLHandler::calculateFps() {
861 Frames++;
862 GLint t = SDL_GetTicks();
863 if ( t - T0 >= 2500 ) {
864 GLfloat seconds = ( t - T0 ) / 1000.0;
865 fps = Frames / seconds;
866 //printf("%d frames in %g seconds = %g FPS\n", Frames, seconds, fps);
867 T0 = t;
868 Frames = 0;
869 }
870 }
871
drawDebugInfo()872 void SDLHandler::drawDebugInfo() {
873 glPushMatrix();
874 glDisable( GL_DEPTH_TEST );
875 glDepthMask( GL_FALSE );
876 glDisable( GL_CULL_FACE );
877 glLoadIdentity();
878 glColor3f( 0, 0, 0 );
879 glBegin( GL_TRIANGLE_STRIP );
880 glVertex2f( 400, 0 );
881 glVertex2f( screen->w, 0 );
882 glVertex2f( 400, 12 );
883 glVertex2f( screen->w, 12 );
884 glEnd();
885 glEnable( GL_TEXTURE_2D );
886 glColor4f( 0.8f, 0.7f, 0.2f, 1.0f );
887 texPrint( 400, 10, "FPS: %g %s", getFPS(), ( debugStr ? debugStr : "" ) );
888 glEnable( GL_DEPTH_TEST );
889 glDepthMask( GL_TRUE );
890 glPopMatrix();
891 }
892
drawFadeout()893 void SDLHandler::drawFadeout() {
894 glPushMatrix();
895 glEnable( GL_BLEND );
896 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
897 glDisable( GL_TEXTURE_2D );
898 glDisable( GL_DEPTH_TEST );
899
900 if ( fadeoutStartAlpha < fadeoutEndAlpha ) {
901 glColor4f( 0, 0, 0, ( fadeoutStartAlpha + ( ( ( fadeoutEndAlpha - fadeoutStartAlpha ) *
902 fadeoutCurrentStep ) / static_cast<float>( fadeoutSteps ) ) ) );
903 } else {
904 glColor4f( 0, 0, 0, ( fadeoutStartAlpha - ( ( ( fadeoutStartAlpha - fadeoutEndAlpha ) *
905 fadeoutCurrentStep ) / static_cast<float>( fadeoutSteps ) ) ) );
906 }
907 glLoadIdentity();
908 glBegin( GL_TRIANGLE_STRIP );
909 glVertex2d( 0, 0 );
910 glVertex2d( screen->w, 0 );
911 glVertex2d( 0, screen->h );
912 glVertex2d( screen->w, screen->h );
913 glEnd();
914
915 glEnable( GL_DEPTH_TEST );
916 glDisable( GL_BLEND );
917 glEnable( GL_TEXTURE_2D );
918 glPopMatrix();
919
920
921 Uint32 t = SDL_GetTicks();
922 if ( t - fadeoutTimer > FADEOUT_SPEED ) {
923 fadeoutCurrentStep++;
924 if ( fadeoutCurrentStep > fadeoutSteps ) {
925 fadeoutTimer = 0;
926 } else {
927 fadeoutTimer = t;
928 }
929 }
930 }
931
fade(float startAlpha,float endAlpha,int steps)932 void SDLHandler::fade( float startAlpha, float endAlpha, int steps ) {
933 fadeoutEndAlpha = endAlpha;
934 fadeoutStartAlpha = startAlpha;
935 fadeoutSteps = steps;
936 fadeoutCurrentStep = 0;
937 fadeoutTimer = SDL_GetTicks();
938 while ( fadeoutTimer > 0 ) {
939 processEventsAndRepaint();
940 }
941 setCursorMode( Constants::CURSOR_NORMAL );
942 }
943
getCurrentTTFFont()944 TTF_Font *SDLHandler::getCurrentTTFFont() {
945 initFonts();
946 return fontInfos[ fontType ]->font;
947 }
948
getCurrentFontManager()949 FontMgr *SDLHandler::getCurrentFontManager() {
950 initFonts();
951 return fontInfos[ fontType ]->fontMgr;
952 }
953
954
textWidth(const char * fmt,...)955 int SDLHandler::textWidth( const char *fmt, ... ) {
956 char str[256]; // Holds our string
957 va_list ap; // Pointer to our list of elements
958
959 // If there's no text, do nothing
960 if ( fmt == NULL ) return 0;
961
962 // Parses The String For Variables
963 va_start( ap, fmt );
964
965 // Converts Symbols To Actual Numbers
966 vsprintf( str, fmt, ap );
967 va_end( ap );
968
969 initFonts();
970
971 //return getTextLengthSimple( *(getCurrentFont()), str );
972 SDL_Rect r;
973 getCurrentFontManager()->textSizeUTF8( str, &r );
974 return r.w;
975 }
976
texPrint(GLfloat x,GLfloat y,const char * fmt,...)977 void SDLHandler::texPrint( GLfloat x, GLfloat y,
978 const char *fmt, ... ) {
979 char str[256]; // Holds our string
980 va_list ap; // Pointer to our list of elements
981
982 // If there's no text, do nothing
983 if ( fmt == NULL ) return;
984
985 // Parses The String For Variables
986 va_start( ap, fmt );
987
988 // Converts Symbols To Actual Numbers
989 vsprintf( str, fmt, ap );
990 va_end( ap );
991
992 initFonts();
993
994 // freetype_print_simple( *(getCurrentFont()), x, y, str );
995 fontInfos[ fontType ]->fontMgr->drawTextUTF8( str,
996 toint( x ),
997 toint( y + fontInfos[ fontType ]->yoffset ) );
998 }
999
1000 // XXX: second-half-initializing first half is done by ShapePalette
initFonts()1001 void SDLHandler::initFonts() {
1002 if ( !font_initialized ) {
1003 //cerr << "Loading " << fontInfos.size() << " fonts: " << endl;
1004 for ( unsigned int i = 0; i < fontInfos.size(); i++ ) {
1005 FontInfo *info = fontInfos[i];
1006 //cerr << "\t" << info->path << endl;
1007 string s = rootDir + "/" + info->path;
1008 info->font = TTF_OpenFont( s.c_str(), info->size );
1009 TTF_SetFontStyle( info->font, info->style );
1010 if ( !info->font ) {
1011 fprintf( stderr, "Couldn't load %d pt font from %s: %s\n", info->size, s.c_str(), SDL_GetError() );
1012 quit( 2 );
1013 } else {
1014 //cerr << "\t\tSuccess." << endl;
1015 info->fontMgr = new FontMgr( info->font, info->shadowX, info->shadowY );
1016 }
1017 }
1018 //cerr << "Done loading fonts." << endl;
1019 font_initialized = true;
1020 }
1021 }
1022
sectionIntersects(int a1,int a2,int b1,int b2)1023 bool SDLHandler::sectionIntersects( int a1, int a2, int b1, int b2 ) {
1024 return( ( ( a1 <= b1 && a2 > b1 ) || ( a1 >= b1 && a1 < b2 ) )
1025 ? true : false );
1026 }
1027
intersects(SDL_Rect * a,SDL_Rect * b)1028 bool SDLHandler::intersects( SDL_Rect *a, SDL_Rect *b ) {
1029 return( ( sectionIntersects( a->x, a->x + a->w, b->x, b->x + b->w ) &&
1030 sectionIntersects( a->y, a->y + a->h, b->y, b->y + b->h ) )
1031 ? true : false );
1032 }
1033
intersects(int x,int y,int w,int h,int x2,int y2,int w2,int h2)1034 bool SDLHandler::intersects( int x, int y, int w, int h,
1035 int x2, int y2, int w2, int h2 ) {
1036 SDL_Rect ra = {
1037 x, y, w, h
1038 };
1039 SDL_Rect rb = {
1040 x2, y2, w2, h2
1041 };
1042 return intersects( &ra, &rb );
1043 }
1044
drawTooltip(float xpos2,float ypos2,float zpos2,float zrot,float yrot,char * message,float r,float g,float b,float zoom)1045 void SDLHandler::drawTooltip( float xpos2, float ypos2, float zpos2,
1046 float zrot, float yrot,
1047 char *message,
1048 float r, float g, float b,
1049 float zoom ) {
1050 setFontType( Constants::SCOURGE_MONO_FONT );
1051
1052 int w = 0;
1053 vector<int> widths;
1054 vector<string> lines = Util::Tokenize<vector<string> >( message, "|" );
1055 for ( vector<string>::iterator i = lines.begin(); i != lines.end(); i++ ) {
1056 int ww = textWidth( i->c_str() ) + 10;
1057 widths.push_back( ww );
1058 if ( w < ww )
1059 w = ww;
1060 }
1061
1062 //int w = textWidth( message ) + 10;
1063 //int w = strlen( message ) * 8 + 4;
1064 int h = 12 * lines.size() + 5;
1065 int x = -2;
1066 int y = -14;
1067
1068 // only for widget tooltips: see if it hangs off the screen
1069 bool right = false;
1070 if ( zrot == 0 && yrot == 0 ) {
1071 // do gluProject b/c parent window coordinates aren't part of xpos2.
1072 GLdouble screenx, screeny, screenz;
1073 double projection[16];
1074 double modelview[16];
1075 GLint viewport[4];
1076 glGetDoublev( GL_PROJECTION_MATRIX, projection );
1077 glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
1078 glGetIntegerv( GL_VIEWPORT, viewport );
1079 int res = gluProject( xpos2 + w + x, 0, 0,
1080 modelview,
1081 projection,
1082 viewport,
1083 &screenx, &screeny, &screenz );
1084 if ( res && screenx > getScreenWidth() ) {
1085 xpos2 -= ( w + x );
1086 right = true;
1087 }
1088 }
1089
1090 // for widget tooltips only (hence the check for zrot/yrot)
1091 if ( zrot == 0 && yrot == 0 && xpos2 + w + x > screen->w ) {
1092
1093 }
1094
1095 glPushMatrix();
1096 glTranslatef( xpos2, ypos2 - ( y + h - 20 ), zpos2 );
1097 glRotatef( zrot, 0.0f, 0.0f, 1.0f );
1098 glRotatef( yrot, 1.0f, 0.0f, 0.0f );
1099
1100 glScalef( zoom, zoom, zoom );
1101
1102 glDisable( GL_DEPTH_TEST );
1103 glDisable( GL_CULL_FACE );
1104 glEnable( GL_BLEND );
1105 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
1106
1107 //glColor4f( 0, 0.15f, 0.05f, 0.5 );
1108 glColor4f( r, g, b, 0.8f );
1109 glBegin( GL_TRIANGLE_STRIP );
1110 glVertex2f( x, y );
1111 glVertex2f( x + w, y );
1112 glVertex2f( x, y + h );
1113 glVertex2f( x + w, y + h );
1114 glEnd();
1115 glBegin( GL_TRIANGLES );
1116 if ( right ) {
1117 glVertex2f( x + w, y + h - 5 );
1118 glVertex2f( x + w + 5, y + h + 5 );
1119 glVertex2f( x + w - 5, y + h );
1120 } else {
1121 glVertex2f( x, y + h - 5 );
1122 glVertex2f( x - 5, y + h + 5 );
1123 glVertex2f( x + 5, y + h );
1124 }
1125 glEnd();
1126 glDisable( GL_BLEND );
1127
1128 //glColor4f( 0, 0.4f, 0.15f, 0.5 );
1129 for ( int i = 0; i < 2; i++ ) {
1130 if ( !i ) {
1131 glLineWidth( 3.0f );
1132 glColor4f( 0, 0, 0, 0 );
1133 } else {
1134 glLineWidth( 1.0f );
1135 glColor4f( r + 0.35f, g + 0.35f, b + 0.35f, 0.8f );
1136 }
1137 glBegin( GL_LINE_LOOP );
1138 if ( right ) {
1139 glVertex2f( x + w, y );
1140 glVertex2f( x, y );
1141 glVertex2f( x, y + h );
1142 glVertex2f( x + w - 5, y + h );
1143 glVertex2f( x + w + 5, y + h + 5 );
1144 glVertex2f( x + w, y + h - 5 );
1145 } else {
1146 glVertex2f( x + w, y );
1147 glVertex2f( x, y );
1148 glVertex2f( x, y + h - 5 );
1149 glVertex2f( x - 5, y + h + 5 );
1150 glVertex2f( x + 5, y + h );
1151 glVertex2f( x + w, y + h );
1152 }
1153 glEnd();
1154 }
1155
1156 glColor4f( 1, 1, 1, 1 );
1157 for ( unsigned int i = 0; i < lines.size(); i++ ) {
1158 int ww = widths[ i ];
1159 int x = static_cast<int>( ( w - ww ) / 2.0f ) + 5;
1160 texPrint( x, i * 12, "%s", lines[i].c_str() );
1161 }
1162 //texPrint( 0, 0, "%s", message );
1163 setFontType( Constants::SCOURGE_DEFAULT_FONT );
1164 glPopMatrix();
1165 }
1166
testDrawView()1167 void SDLHandler::testDrawView() {
1168 /* Clear The Screen And The Depth Buffer */
1169 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
1170
1171 /* Move Right 3 Units */
1172 glLoadIdentity( );
1173 glTranslatef( 1.5f, 0.0f, -6.0f );
1174
1175 /* Rotate The Quad On The X axis ( NEW ) */
1176 glRotatef( rquad, 1.0f, 0.0f, 0.0f );
1177
1178 /* Set The Color To Blue One Time Only */
1179 glColor3f( 0.5f, 0.5f, 1.0f );
1180
1181 glBegin( GL_QUADS ); /* Draw A Quad */
1182 glColor3f( 0.0f, 1.0f, 0.0f ); /* Set The Color To Green */
1183 glVertex3f( 1.0f, 1.0f, -1.0f ); /* Top Right Of The Quad (Top) */
1184 glVertex3f( -1.0f, 1.0f, -1.0f ); /* Top Left Of The Quad (Top) */
1185 glVertex3f( -1.0f, 1.0f, 1.0f ); /* Bottom Left Of The Quad (Top) */
1186 glVertex3f( 1.0f, 1.0f, 1.0f ); /* Bottom Right Of The Quad (Top) */
1187
1188 glColor3f( 1.0f, 0.5f, 0.0f ); /* Set The Color To Orange */
1189 glVertex3f( 1.0f, -1.0f, 1.0f ); /* Top Right Of The Quad (Botm) */
1190 glVertex3f( -1.0f, -1.0f, 1.0f ); /* Top Left Of The Quad (Botm) */
1191 glVertex3f( -1.0f, -1.0f, -1.0f ); /* Bottom Left Of The Quad (Botm) */
1192 glVertex3f( 1.0f, -1.0f, -1.0f ); /* Bottom Right Of The Quad (Botm) */
1193
1194 glColor3f( 1.0f, 0.0f, 0.0f ); /* Set The Color To Red */
1195 glVertex3f( 1.0f, 1.0f, 1.0f ); /* Top Right Of The Quad (Front) */
1196 glVertex3f( -1.0f, 1.0f, 1.0f ); /* Top Left Of The Quad (Front) */
1197 glVertex3f( -1.0f, -1.0f, 1.0f ); /* Bottom Left Of The Quad (Front) */
1198 glVertex3f( 1.0f, -1.0f, 1.0f ); /* Bottom Right Of The Quad (Front) */
1199
1200 glColor3f( 1.0f, 1.0f, 0.0f ); /* Set The Color To Yellow */
1201 glVertex3f( 1.0f, -1.0f, -1.0f ); /* Bottom Left Of The Quad (Back) */
1202 glVertex3f( -1.0f, -1.0f, -1.0f ); /* Bottom Right Of The Quad (Back) */
1203 glVertex3f( -1.0f, 1.0f, -1.0f ); /* Top Right Of The Quad (Back) */
1204 glVertex3f( 1.0f, 1.0f, -1.0f ); /* Top Left Of The Quad (Back) */
1205
1206 glColor3f( 0.0f, 0.0f, 1.0f ); /* Set The Color To Blue */
1207 glVertex3f( -1.0f, 1.0f, 1.0f ); /* Top Right Of The Quad (Left) */
1208 glVertex3f( -1.0f, 1.0f, -1.0f ); /* Top Left Of The Quad (Left) */
1209 glVertex3f( -1.0f, -1.0f, -1.0f ); /* Bottom Left Of The Quad (Left) */
1210 glVertex3f( -1.0f, -1.0f, 1.0f ); /* Bottom Right Of The Quad (Left) */
1211
1212 glColor3f( 1.0f, 0.0f, 1.0f ); /* Set The Color To Violet */
1213 glVertex3f( 1.0f, 1.0f, -1.0f ); /* Top Right Of The Quad (Right) */
1214 glVertex3f( 1.0f, 1.0f, 1.0f ); /* Top Left Of The Quad (Right) */
1215 glVertex3f( 1.0f, -1.0f, 1.0f ); /* Bottom Left Of The Quad (Right) */
1216 glVertex3f( 1.0f, -1.0f, -1.0f ); /* Bottom Right Of The Quad (Right) */
1217 glEnd( ); /* Done Drawing The Quad */
1218
1219 /* Move Left 1.5 Units And Into The Screen 6.0 */
1220 glLoadIdentity();
1221 glTranslatef( 0.5f, 0.0f, -8.0f );
1222
1223 /* Rotate The Triangle On The Y axis ( NEW ) */
1224 glRotatef( rtri, 0.0f, 1.0f, 0.0f );
1225
1226 glBegin( GL_TRIANGLES ); /* Drawing Using Triangles */
1227 glColor3f( 1.0f, 0.0f, 0.0f ); /* Red */
1228 glVertex3f( 0.0f, 1.0f, 0.0f ); /* Top Of Triangle (Front) */
1229 glColor3f( 0.0f, 1.0f, 0.0f ); /* Green */
1230 glVertex3f( -1.0f, -1.0f, 1.0f ); /* Left Of Triangle (Front) */
1231 glColor3f( 0.0f, 0.0f, 1.0f ); /* Blue */
1232 glVertex3f( 1.0f, -1.0f, 1.0f ); /* Right Of Triangle (Front) */
1233
1234 glColor3f( 1.0f, 0.0f, 0.0f ); /* Red */
1235 glVertex3f( 0.0f, 1.0f, 0.0f ); /* Top Of Triangle (Right) */
1236 glColor3f( 0.0f, 0.0f, 1.0f ); /* Blue */
1237 glVertex3f( 1.0f, -1.0f, 1.0f ); /* Left Of Triangle (Right) */
1238 glColor3f( 0.0f, 1.0f, 0.0f ); /* Green */
1239 glVertex3f( 1.0f, -1.0f, -1.0f ); /* Right Of Triangle (Right) */
1240
1241 glColor3f( 1.0f, 0.0f, 0.0f ); /* Red */
1242 glVertex3f( 0.0f, 1.0f, 0.0f ); /* Top Of Triangle (Back) */
1243 glColor3f( 0.0f, 1.0f, 0.0f ); /* Green */
1244 glVertex3f( 1.0f, -1.0f, -1.0f ); /* Left Of Triangle (Back) */
1245 glColor3f( 0.0f, 0.0f, 1.0f ); /* Blue */
1246 glVertex3f( -1.0f, -1.0f, -1.0f ); /* Right Of Triangle (Back) */
1247
1248 glColor3f( 1.0f, 0.0f, 0.0f ); /* Red */
1249 glVertex3f( 0.0f, 1.0f, 0.0f ); /* Top Of Triangle (Left) */
1250 glColor3f( 0.0f, 0.0f, 1.0f ); /* Blue */
1251 glVertex3f( -1.0f, -1.0f, -1.0f ); /* Left Of Triangle (Left) */
1252 glColor3f( 0.0f, 1.0f, 0.0f ); /* Green */
1253 glVertex3f( -1.0f, -1.0f, 1.0f ); /* Right Of Triangle (Left) */
1254 glEnd( ); /* Finished Drawing The Triangle */
1255
1256 /* Increase The Rotation Variable For The Triangle ( NEW ) */
1257 rtri += 0.2f;
1258 /* Decrease The Rotation Variable For The Quad ( NEW ) */
1259 rquad -= 0.15f;
1260 }
1261
getHighlightTexture()1262 Texture const& SDLHandler::getHighlightTexture() {
1263 return gameAdapter->getHighlightTexture();
1264 }
1265
getGuiTexture()1266 Texture const& SDLHandler::getGuiTexture() {
1267 return gameAdapter->getGuiTexture();
1268 }
1269
getGuiTexture2()1270 Texture const& SDLHandler::getGuiTexture2() {
1271 return gameAdapter->getGuiTexture2();
1272 }
1273
loadSystemTexture(char * line)1274 Texture const& SDLHandler::loadSystemTexture( char *line ) {
1275 return gameAdapter->loadSystemTexture( line );
1276 }
1277
allWindowsClosed()1278 void SDLHandler::allWindowsClosed() {
1279 /*
1280 if( gameAdapter->getSession()->getParty() &&
1281 gameAdapter->getSession()->getParty()->getPartySize() > 0 ) {
1282 gameAdapter->getSession()->getParty()->toggleRound( false );
1283 }
1284 */
1285 }
1286
setCursorMode(int n,bool useTimer)1287 void SDLHandler::setCursorMode( int n, bool useTimer ) {
1288 cursorMode = n;
1289 if ( cursorMode == Constants::CURSOR_FORBIDDEN && useTimer ) {
1290 forbiddenTimer = SDL_GetTicks();
1291 }
1292 }
1293
setUpdate(char * message,int n,int total)1294 void SDLHandler::setUpdate( char *message, int n, int total ) {
1295 if ( screenView->setUpdate( message, n, total ) ) {
1296 processEventsAndRepaint();
1297 }
1298 }
1299
playSound(const std::string & file,int panning)1300 void SDLHandler::playSound( const std::string& file, int panning ) {
1301 gameAdapter->getSession()->getSound()->playSound( file, panning );
1302 }
1303
setContinueAt(char * func,int timeout)1304 void SDLHandler::setContinueAt( char *func, int timeout ) {
1305 this->continueFunc = func;
1306 this->continueTimeout = timeout;
1307 this->continueStart = SDL_GetTicks();
1308 }
1309