2012-05-30 07:17:40 -05:00
# ifdef USE_SDL
2012-01-08 11:39:03 -06:00
2012-07-06 10:53:59 -05:00
# include <map>
# include <string>
2012-01-08 11:39:03 -06:00
# include <time.h>
2014-06-08 18:33:58 -05:00
# ifdef SDL_INC
# include "SDL/SDL.h"
# else
2012-09-06 18:49:50 -05:00
# include "SDL.h"
2014-06-08 18:33:58 -05:00
# endif
2012-07-29 11:14:14 -05:00
# ifdef WIN
2013-06-22 08:36:10 -05:00
# define _WIN32_WINNT 0x0501 //Necessary for some macros and functions, tells windows.h to include functions only available in Windows XP or later
2012-08-08 11:42:04 -05:00
# include <direct.h>
2012-01-29 11:54:53 -06:00
# endif
2012-01-14 12:51:24 -06:00
# include <iostream>
# include <sstream>
# include <string>
2012-01-08 11:39:03 -06:00
# include "Config.h"
2012-07-06 10:06:26 -05:00
# include "graphics/Graphics.h"
2012-07-29 10:55:26 -05:00
# if defined(LIN)
2012-01-29 11:54:53 -06:00
# include "icon.h"
# endif
2013-05-19 01:02:42 -05:00
# include <signal.h>
2016-01-25 23:24:14 -06:00
# include <stdexcept>
2012-01-08 11:39:03 -06:00
2012-08-08 11:42:04 -05:00
# ifndef WIN
# include <unistd.h>
# endif
2013-02-14 22:31:31 -06:00
# ifdef MACOSX
# include <ApplicationServices/ApplicationServices.h>
2013-11-19 15:23:04 -06:00
extern " C " {
char * readClipboard ( ) ;
void writeClipboard ( const char * clipboardData ) ;
}
2013-02-14 22:31:31 -06:00
# endif
2012-08-08 11:42:04 -05:00
# include "Format.h"
2012-08-12 16:32:57 -05:00
2012-08-13 09:43:57 -05:00
# include "client/GameSave.h"
2012-08-17 10:08:03 -05:00
# include "client/SaveFile.h"
2012-06-21 19:04:55 -05:00
# include "simulation/SaveRenderer.h"
# include "client/Client.h"
2012-07-06 10:53:59 -05:00
# include "Misc.h"
2012-01-08 11:39:03 -06:00
2013-03-22 09:14:17 -05:00
# include "gui/game/GameController.h"
# include "gui/game/GameView.h"
2012-01-17 14:46:06 -06:00
2013-03-22 09:14:17 -05:00
# include "gui/dialogues/ErrorMessage.h"
2016-01-31 21:30:39 -06:00
# include "gui/dialogues/ConfirmPrompt.h"
2013-03-22 09:14:17 -05:00
# include "gui/interface/Keys.h"
# include "gui/Style.h"
2012-01-29 08:44:36 -06:00
2012-01-19 07:44:59 -06:00
# include "client/HTTP.h"
2012-01-14 12:51:24 -06:00
using namespace std ;
2014-06-08 18:33:58 -05:00
# if defined(WIN) || defined(LIN)
# ifdef SDL_INC
# include <SDL/SDL_syswm.h>
# else
2013-01-18 13:37:24 -06:00
# include <SDL_syswm.h>
# endif
2014-06-08 18:33:58 -05:00
# endif
2013-01-18 13:37:24 -06:00
# if defined(USE_SDL) && defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
SDL_SysWMinfo sdl_wminfo ;
2013-08-28 15:57:08 -05:00
Atom XA_CLIPBOARD , XA_TARGETS , XA_UTF8_STRING ;
2013-01-18 13:37:24 -06:00
# endif
2014-02-25 08:44:44 -06:00
std : : string clipboardText = " " ;
2012-08-13 09:43:57 -05:00
2012-09-05 11:31:49 -05:00
int desktopWidth = 1280 , desktopHeight = 1024 ;
2012-05-30 06:32:58 -05:00
SDL_Surface * sdl_scrn ;
2012-08-08 08:35:27 -05:00
int scale = 1 ;
bool fullscreen = false ;
2012-05-30 06:32:58 -05:00
2014-02-25 08:44:44 -06:00
void ClipboardPush ( std : : string text )
2013-01-18 13:37:24 -06:00
{
2014-02-25 08:44:44 -06:00
clipboardText = text ;
2013-01-18 13:37:24 -06:00
# ifdef MACOSX
2014-02-25 08:44:44 -06:00
writeClipboard ( text . c_str ( ) ) ;
2013-01-18 13:37:24 -06:00
# elif defined(WIN)
if ( OpenClipboard ( NULL ) )
{
HGLOBAL cbuffer ;
char * glbuffer ;
EmptyClipboard ( ) ;
2014-02-25 08:44:44 -06:00
cbuffer = GlobalAlloc ( GMEM_DDESHARE , text . size ( ) + 1 ) ;
2013-01-18 13:37:24 -06:00
glbuffer = ( char * ) GlobalLock ( cbuffer ) ;
2014-02-25 08:44:44 -06:00
strcpy ( glbuffer , text . c_str ( ) ) ;
2013-01-18 13:37:24 -06:00
GlobalUnlock ( cbuffer ) ;
SetClipboardData ( CF_TEXT , cbuffer ) ;
CloseClipboard ( ) ;
}
# elif defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
sdl_wminfo . info . x11 . lock_func ( ) ;
XSetSelectionOwner ( sdl_wminfo . info . x11 . display , XA_CLIPBOARD , sdl_wminfo . info . x11 . window , CurrentTime ) ;
XFlush ( sdl_wminfo . info . x11 . display ) ;
sdl_wminfo . info . x11 . unlock_func ( ) ;
# else
2014-07-04 18:16:38 -05:00
printf ( " Not implemented: put text on clipboard \" %s \" \n " , text . c_str ( ) ) ;
2013-01-18 13:37:24 -06:00
# endif
}
2013-10-24 15:46:41 -05:00
void EventProcess ( SDL_Event event ) ;
2014-02-25 08:44:44 -06:00
std : : string ClipboardPull ( )
2013-01-18 13:37:24 -06:00
{
# ifdef MACOSX
2014-02-25 08:44:44 -06:00
const char * text = readClipboard ( ) ;
2014-03-16 06:35:53 -05:00
return text ? std : : string ( text ) : " " ;
2013-01-18 13:37:24 -06:00
# elif defined(WIN)
if ( OpenClipboard ( NULL ) )
{
HANDLE cbuffer ;
char * glbuffer ;
cbuffer = GetClipboardData ( CF_TEXT ) ;
glbuffer = ( char * ) GlobalLock ( cbuffer ) ;
GlobalUnlock ( cbuffer ) ;
CloseClipboard ( ) ;
2014-03-16 06:35:53 -05:00
return glbuffer ? std : : string ( glbuffer ) : " " ;
2013-01-18 13:37:24 -06:00
}
# elif defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
2014-02-25 08:44:44 -06:00
std : : string text = " " ;
2013-08-28 15:57:08 -05:00
Window selectionOwner ;
sdl_wminfo . info . x11 . lock_func ( ) ;
selectionOwner = XGetSelectionOwner ( sdl_wminfo . info . x11 . display , XA_CLIPBOARD ) ;
if ( selectionOwner ! = None )
{
2013-09-11 19:41:43 -05:00
unsigned char * data = NULL ;
Atom type ;
int format , result ;
unsigned long len , bytesLeft ;
2013-08-28 15:57:08 -05:00
XConvertSelection ( sdl_wminfo . info . x11 . display , XA_CLIPBOARD , XA_UTF8_STRING , XA_CLIPBOARD , sdl_wminfo . info . x11 . window , CurrentTime ) ;
XFlush ( sdl_wminfo . info . x11 . display ) ;
sdl_wminfo . info . x11 . unlock_func ( ) ;
while ( 1 )
{
SDL_Event event ;
SDL_WaitEvent ( & event ) ;
if ( event . type = = SDL_SYSWMEVENT )
{
XEvent xevent = event . syswm . msg - > event . xevent ;
if ( xevent . type = = SelectionNotify & & xevent . xselection . requestor = = sdl_wminfo . info . x11 . window )
break ;
2013-10-24 15:46:41 -05:00
else
EventProcess ( event ) ;
2013-08-28 15:57:08 -05:00
}
2013-10-24 15:46:41 -05:00
else
EventProcess ( event ) ;
2013-08-28 15:57:08 -05:00
}
sdl_wminfo . info . x11 . lock_func ( ) ;
XGetWindowProperty ( sdl_wminfo . info . x11 . display , sdl_wminfo . info . x11 . window , XA_CLIPBOARD , 0 , 0 , 0 , AnyPropertyType , & type , & format , & len , & bytesLeft , & data ) ;
if ( data )
{
XFree ( data ) ;
data = NULL ;
}
if ( bytesLeft )
{
2013-09-11 19:41:43 -05:00
result = XGetWindowProperty ( sdl_wminfo . info . x11 . display , sdl_wminfo . info . x11 . window , XA_CLIPBOARD , 0 , bytesLeft , 0 , AnyPropertyType , & type , & format , & len , & bytesLeft , & data ) ;
2013-08-28 15:57:08 -05:00
if ( result = = Success )
{
2014-02-25 08:44:44 -06:00
text = data ? ( const char * ) data : " " ;
2013-08-28 15:57:08 -05:00
XFree ( data ) ;
}
2013-10-24 15:46:41 -05:00
else
{
printf ( " Failed to pull from clipboard \n " ) ;
2014-02-25 08:44:44 -06:00
return " ? " ;
2013-10-24 15:46:41 -05:00
}
2013-08-28 15:57:08 -05:00
}
2013-10-24 15:46:41 -05:00
else
2014-02-25 08:44:44 -06:00
return " " ;
2013-08-28 15:57:08 -05:00
XDeleteProperty ( sdl_wminfo . info . x11 . display , sdl_wminfo . info . x11 . window , XA_CLIPBOARD ) ;
}
sdl_wminfo . info . x11 . unlock_func ( ) ;
return text ;
2013-01-18 13:37:24 -06:00
# else
printf ( " Not implemented: get text from clipboard \n " ) ;
# endif
2014-02-25 08:44:44 -06:00
return clipboardText ;
2013-01-18 13:37:24 -06:00
}
2012-06-23 08:59:07 -05:00
# ifdef OGLI
2012-05-30 06:32:58 -05:00
void blit ( )
{
SDL_GL_SwapBuffers ( ) ;
}
# else
2016-03-31 21:08:04 -05:00
int mousex = 0 , mousey = 0 ;
void DrawPixel ( pixel * vid , pixel color , int x , int y )
{
if ( x > = 0 & & x < WINDOWW & & y > = 0 & & y < WINDOWH )
vid [ x + y * WINDOWW ] = color ;
}
2016-04-01 23:10:15 -05:00
// draws a custom cursor, used to make 3D mode work properly (normal cursor ruins the effect)
2016-03-31 21:08:04 -05:00
void DrawCursor ( pixel * vid )
{
2016-04-01 21:06:21 -05:00
for ( int j = 0 ; j < = 9 ; j + + )
2016-03-31 21:08:04 -05:00
{
for ( int i = 0 ; i < = j ; i + + )
{
if ( i = = 0 | | i = = j )
DrawPixel ( vid , 0xFFFFFFFF , mousex + i , mousey + j ) ;
else
DrawPixel ( vid , 0xFF000000 , mousex + i , mousey + j ) ;
}
}
DrawPixel ( vid , 0xFFFFFFFF , mousex , mousey + 10 ) ;
for ( int i = 0 ; i < 5 ; i + + )
{
DrawPixel ( vid , 0xFF000000 , mousex + 1 + i , mousey + 10 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 6 + i , mousey + 10 ) ;
}
DrawPixel ( vid , 0xFFFFFFFF , mousex , mousey + 11 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 1 , mousey + 11 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 2 , mousey + 11 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 3 , mousey + 11 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 4 , mousey + 11 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 5 , mousey + 11 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 6 , mousey + 11 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex , mousey + 12 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 1 , mousey + 12 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 2 , mousey + 12 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 4 , mousey + 12 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 5 , mousey + 12 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 6 , mousey + 12 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 7 , mousey + 12 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex , mousey + 13 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 1 , mousey + 13 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 4 , mousey + 13 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 5 , mousey + 13 ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 6 , mousey + 13 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 7 , mousey + 13 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex , mousey + 14 ) ;
for ( int i = 0 ; i < 2 ; i + + )
{
DrawPixel ( vid , 0xFFFFFFFF , mousex + 5 , mousey + 14 + i ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 6 , mousey + 14 + i ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 7 , mousey + 14 + i ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 8 , mousey + 14 + i ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 6 , mousey + 16 + i ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 7 , mousey + 16 + i ) ;
DrawPixel ( vid , 0xFF000000 , mousex + 8 , mousey + 16 + i ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 9 , mousey + 16 + i ) ;
}
DrawPixel ( vid , 0xFFFFFFFF , mousex + 7 , mousey + 18 ) ;
DrawPixel ( vid , 0xFFFFFFFF , mousex + 8 , mousey + 18 ) ;
}
2012-05-30 06:32:58 -05:00
void blit ( pixel * vid )
{
2016-04-01 23:10:15 -05:00
if ( sdl_scrn )
2012-05-30 06:32:58 -05:00
{
2016-04-01 23:10:15 -05:00
int depth3d = ui : : Engine : : Ref ( ) . Get3dDepth ( ) ;
2016-03-31 21:08:04 -05:00
if ( depth3d )
DrawCursor ( vid ) ;
2012-05-30 06:32:58 -05:00
pixel * src = vid ;
2013-11-10 03:02:55 -06:00
int j , x = 0 , y = 0 , w = WINDOWW , h = WINDOWH , pitch = WINDOWW ;
2012-08-08 08:35:27 -05:00
pixel * dst ;
2012-05-30 06:32:58 -05:00
if ( SDL_MUSTLOCK ( sdl_scrn ) )
if ( SDL_LockSurface ( sdl_scrn ) < 0 )
return ;
dst = ( pixel * ) sdl_scrn - > pixels + y * sdl_scrn - > pitch / PIXELSIZE + x ;
2012-08-08 08:35:27 -05:00
if ( SDL_MapRGB ( sdl_scrn - > format , 0x33 , 0x55 , 0x77 ) ! = PIXPACK ( 0x335577 ) )
2012-05-30 06:32:58 -05:00
{
2016-04-01 21:06:21 -05:00
//pixel format conversion, used for strange formats (OS X specifically)
2012-08-08 08:35:27 -05:00
int i ;
2016-04-01 21:06:21 -05:00
unsigned int red , green , blue ;
2016-03-31 21:08:04 -05:00
pixel px , lastpx , nextpx ;
2012-08-08 08:35:27 -05:00
SDL_PixelFormat * fmt = sdl_scrn - > format ;
for ( j = 0 ; j < h ; j + + )
{
for ( i = 0 ; i < w ; i + + )
{
2016-03-31 21:08:04 -05:00
if ( depth3d )
{
lastpx = i > = depth3d & & i < w + depth3d ? src [ i - depth3d ] : 0 ;
nextpx = i > = - depth3d & & i < w - depth3d ? src [ i + depth3d ] : 0 ;
2016-04-01 21:06:21 -05:00
int redshift = PIXB ( lastpx ) + PIXG ( lastpx ) ;
if ( redshift > 255 )
redshift = 255 ;
int blueshift = PIXR ( nextpx ) + PIXG ( nextpx ) ;
if ( blueshift > 255 )
blueshift = 255 ;
red = ( ( int ) ( PIXR ( lastpx ) * .69f + redshift * .3f ) > > fmt - > Rloss ) < < fmt - > Rshift ;
green = ( ( int ) ( PIXG ( nextpx ) * .3f ) > > fmt - > Gloss ) < < fmt - > Gshift ;
blue = ( ( int ) ( PIXB ( nextpx ) * .69f + blueshift * .3f ) > > fmt - > Bloss ) < < fmt - > Bshift ;
2016-03-31 21:08:04 -05:00
}
else
2016-04-01 21:06:21 -05:00
{
px = src [ i ] ;
red = ( PIXR ( px ) > > fmt - > Rloss ) < < fmt - > Rshift ;
green = ( PIXG ( px ) > > fmt - > Gloss ) < < fmt - > Gshift ;
blue = ( PIXB ( px ) > > fmt - > Bloss ) < < fmt - > Bshift ;
}
dst [ i ] = red | green | blue ;
2012-08-08 08:35:27 -05:00
}
dst + = sdl_scrn - > pitch / PIXELSIZE ;
src + = pitch ;
}
}
else
{
2016-03-31 21:08:04 -05:00
int i ;
2012-08-08 08:35:27 -05:00
for ( j = 0 ; j < h ; j + + )
{
2016-04-01 21:06:21 -05:00
if ( depth3d )
2016-03-31 21:08:04 -05:00
{
2016-04-01 21:06:21 -05:00
pixel lastpx , nextpx ;
for ( i = 0 ; i < w ; i + + )
2016-03-31 21:08:04 -05:00
{
lastpx = i > = depth3d & & i < w + depth3d ? src [ i - depth3d ] : 0 ;
nextpx = i > = - depth3d & & i < w - depth3d ? src [ i + depth3d ] : 0 ;
2016-04-01 21:06:21 -05:00
int redshift = PIXB ( lastpx ) + PIXG ( lastpx ) ;
if ( redshift > 255 )
redshift = 255 ;
int blueshift = PIXR ( nextpx ) + PIXG ( nextpx ) ;
if ( blueshift > 255 )
blueshift = 255 ;
dst [ i ] = PIXRGB ( ( int ) ( PIXR ( lastpx ) * .69f + redshift * .3f ) , ( int ) ( PIXG ( nextpx ) * .3f ) , ( int ) ( PIXB ( nextpx ) * .69f + blueshift * .3f ) ) ;
2016-03-31 21:08:04 -05:00
}
}
2016-04-01 21:06:21 -05:00
else
memcpy ( dst , src , w * PIXELSIZE ) ;
2012-08-08 08:35:27 -05:00
dst + = sdl_scrn - > pitch / PIXELSIZE ;
src + = pitch ;
}
}
if ( SDL_MUSTLOCK ( sdl_scrn ) )
SDL_UnlockSurface ( sdl_scrn ) ;
SDL_UpdateRect ( sdl_scrn , 0 , 0 , 0 , 0 ) ;
}
}
void blit2 ( pixel * vid , int currentScale )
{
2016-04-01 23:10:15 -05:00
if ( sdl_scrn )
2012-08-08 08:35:27 -05:00
{
2016-04-01 23:10:15 -05:00
int depth3d = ui : : Engine : : Ref ( ) . Get3dDepth ( ) ;
2016-03-31 21:08:04 -05:00
if ( depth3d )
DrawCursor ( vid ) ;
2012-08-08 08:35:27 -05:00
pixel * src = vid ;
2013-11-10 03:02:55 -06:00
int j , x = 0 , y = 0 , w = WINDOWW , h = WINDOWH , pitch = WINDOWW ;
2012-08-08 08:35:27 -05:00
pixel * dst ;
2016-03-31 21:08:04 -05:00
pixel px , lastpx , nextpx ;
2012-08-08 08:35:27 -05:00
int i , k ;
if ( SDL_MUSTLOCK ( sdl_scrn ) )
if ( SDL_LockSurface ( sdl_scrn ) < 0 )
return ;
dst = ( pixel * ) sdl_scrn - > pixels + y * sdl_scrn - > pitch / PIXELSIZE + x ;
if ( SDL_MapRGB ( sdl_scrn - > format , 0x33 , 0x55 , 0x77 ) ! = PIXPACK ( 0x335577 ) )
{
//pixel format conversion
SDL_PixelFormat * fmt = sdl_scrn - > format ;
2016-04-01 21:06:21 -05:00
int red , green , blue ;
2012-08-08 08:35:27 -05:00
for ( j = 0 ; j < h ; j + + )
{
for ( k = 0 ; k < currentScale ; k + + )
{
for ( i = 0 ; i < w ; i + + )
{
2016-03-31 21:08:04 -05:00
if ( depth3d )
{
2016-04-01 21:06:21 -05:00
lastpx = i > = depth3d & & i < w + depth3d ? src [ i - depth3d ] : 0 ;
nextpx = i > = - depth3d & & i < w - depth3d ? src [ i + depth3d ] : 0 ;
int redshift = PIXB ( lastpx ) + PIXG ( lastpx ) ;
if ( redshift > 255 )
redshift = 255 ;
int blueshift = PIXR ( nextpx ) + PIXG ( nextpx ) ;
if ( blueshift > 255 )
blueshift = 255 ;
red = ( ( int ) ( PIXR ( lastpx ) * .69f + redshift * .3f ) > > fmt - > Rloss ) < < fmt - > Rshift ;
green = ( ( int ) ( PIXG ( nextpx ) * .3f ) > > fmt - > Gloss ) < < fmt - > Gshift ;
blue = ( ( int ) ( PIXB ( nextpx ) * .69f + blueshift * .3f ) > > fmt - > Bloss ) < < fmt - > Bshift ;
}
else
{
px = src [ i ] ;
red = ( PIXR ( px ) > > fmt - > Rloss ) < < fmt - > Rshift ;
green = ( PIXG ( px ) > > fmt - > Gloss ) < < fmt - > Gshift ;
blue = ( PIXB ( px ) > > fmt - > Bloss ) < < fmt - > Bshift ;
2016-03-31 21:08:04 -05:00
}
2016-04-01 21:06:21 -05:00
dst [ i * 2 ] = red | green | blue ;
dst [ i * 2 + 1 ] = red | green | blue ;
2012-08-08 08:35:27 -05:00
}
dst + = sdl_scrn - > pitch / PIXELSIZE ;
}
src + = pitch ;
}
}
else
{
for ( j = 0 ; j < h ; j + + )
{
for ( k = 0 ; k < currentScale ; k + + )
{
for ( i = 0 ; i < w ; i + + )
{
2016-03-31 21:08:04 -05:00
px = src [ i ] ;
if ( depth3d )
{
2016-04-01 21:06:21 -05:00
lastpx = i > = depth3d & & i < w + depth3d ? src [ i - depth3d ] : 0 ;
nextpx = i > = - depth3d & & i < w - depth3d ? src [ i + depth3d ] : 0 ;
int redshift = PIXB ( lastpx ) + PIXG ( lastpx ) ;
if ( redshift > 255 )
redshift = 255 ;
int blueshift = PIXR ( nextpx ) + PIXG ( nextpx ) ;
if ( blueshift > 255 )
blueshift = 255 ;
px = PIXRGB ( ( int ) ( PIXR ( lastpx ) * .69f + redshift * .3f ) , ( int ) ( PIXG ( nextpx ) * .3f ) , ( int ) ( PIXB ( nextpx ) * .69f + blueshift * .3f ) ) ;
2016-03-31 21:08:04 -05:00
}
dst [ i * 2 ] = px ;
dst [ i * 2 + 1 ] = px ;
2012-08-08 08:35:27 -05:00
}
dst + = sdl_scrn - > pitch / PIXELSIZE ;
}
src + = pitch ;
}
2012-05-30 06:32:58 -05:00
}
if ( SDL_MUSTLOCK ( sdl_scrn ) )
SDL_UnlockSurface ( sdl_scrn ) ;
SDL_UpdateRect ( sdl_scrn , 0 , 0 , 0 , 0 ) ;
}
}
2012-05-30 07:17:40 -05:00
# endif
2012-05-30 06:32:58 -05:00
2012-08-08 08:35:27 -05:00
int SDLOpen ( )
2012-01-08 11:39:03 -06:00
{
2012-07-29 11:14:14 -05:00
# if defined(WIN) && defined(WINCONSOLE)
2012-01-14 12:51:24 -06:00
FILE * console = fopen ( " CON " , " w " ) ;
# endif
2012-01-08 11:39:03 -06:00
if ( SDL_Init ( SDL_INIT_VIDEO ) < 0 )
{
fprintf ( stderr , " Initializing SDL: %s \n " , SDL_GetError ( ) ) ;
2012-08-08 08:35:27 -05:00
return 1 ;
2012-01-08 11:39:03 -06:00
}
2012-09-05 11:31:49 -05:00
const SDL_VideoInfo * vidInfo = SDL_GetVideoInfo ( ) ;
desktopWidth = vidInfo - > current_w ;
desktopHeight = vidInfo - > current_h ;
2012-01-24 17:33:32 -06:00
SDL_EnableUNICODE ( 1 ) ;
2012-07-29 11:14:14 -05:00
# if defined(WIN) && defined(WINCONSOLE)
2012-01-14 12:51:24 -06:00
//On Windows, SDL redirects stdout to stdout.txt, which can be annoying when debugging, here we redirect back to the console
if ( console )
{
freopen ( " CON " , " w " , stdout ) ;
2012-02-05 10:37:36 -06:00
freopen ( " CON " , " w " , stderr ) ;
//fclose(console);
2012-01-14 12:51:24 -06:00
}
# endif
2012-07-29 11:14:14 -05:00
# ifdef WIN
2012-01-29 11:54:53 -06:00
SDL_SysWMinfo SysInfo ;
SDL_VERSION ( & SysInfo . version ) ;
if ( SDL_GetWMInfo ( & SysInfo ) < = 0 ) {
Fix some problems noted in http://www.viva64.com/en/b/0298/
I've left some of the less important items, like SearchView.cpp "'then' statement is equivalent to the 'else' statement", and RequestBroker::Request::~Request, because I don't feel like spending a few days entirely rewriting those files at the moment (which is what I'd end up doing if I started fixing minor problems and refactoring...)
GameSave::readOPS - not changed. At some point we may have to move to a larger type for element IDs (probably two or four bytes), but PT_NUM isn't likely to be raised to the maximum value of that type immediately, so this check will be needed then. There should be an elements[partsData[i]].Enabled check in there too, but it might be a bit difficult - I'm not sure how to access a Simulation object from GameSave::readOPS...
Notes on changes:
Graphics::textsize, Element_FRZW::Element_FRZW - typos
Button::Draw - the extra case was originally used to invert the icon (draw it in black instead of in white) when the button was clicked. However, the icon colour is now automatically set depending on the background colour. (Note similar conditions "if(Enabled) { if(isButtonDown || (isTogglable && toggle)) " near the start of the function - same logic but in a different place, setting icon colour indirectly).
Simulation::transform_save - unused redundant function, everything uses GameSave::Transform which does much the same thing.
PreviewView::NotifySaveChanged - should be height==YRES/2, it's checking whether the preview image is the correct size, and resizing it if it isn't.
Element_FWRK::update - no idea why that line was there, even though it was my commit that originally added it...
2014-12-25 09:55:14 -06:00
printf ( " %s : %p \n " , SDL_GetError ( ) , SysInfo . window ) ;
2012-01-29 11:54:53 -06:00
exit ( - 1 ) ;
}
HWND WindowHandle = SysInfo . window ;
2013-04-22 12:04:43 -05:00
// Use GetModuleHandle to get the Exe HMODULE/HINSTANCE
HMODULE hModExe = GetModuleHandle ( NULL ) ;
HICON hIconSmall = ( HICON ) LoadImage ( hModExe , MAKEINTRESOURCE ( 101 ) , IMAGE_ICON , 16 , 16 , LR_SHARED ) ;
HICON hIconBig = ( HICON ) LoadImage ( hModExe , MAKEINTRESOURCE ( 101 ) , IMAGE_ICON , 32 , 32 , LR_SHARED ) ;
2012-01-29 11:54:53 -06:00
SendMessage ( WindowHandle , WM_SETICON , ICON_SMALL , ( LPARAM ) hIconSmall ) ;
SendMessage ( WindowHandle , WM_SETICON , ICON_BIG , ( LPARAM ) hIconBig ) ;
2012-07-29 10:55:26 -05:00
# elif defined(LIN)
2015-01-09 21:40:48 -06:00
SDL_Surface * icon = SDL_CreateRGBSurfaceFrom ( ( void * ) app_icon , 48 , 48 , 24 , 144 , 0x00FF0000 , 0x0000FF00 , 0x000000FF , 0 ) ;
SDL_WM_SetIcon ( icon , ( Uint8 * ) app_icon_bitmap ) ;
2015-06-30 18:06:18 -05:00
SDL_FreeSurface ( icon ) ;
2012-01-29 11:54:53 -06:00
# endif
SDL_WM_SetCaption ( " The Powder Toy " , " Powder Toy " ) ;
2012-03-03 11:58:33 -06:00
//SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
2012-01-08 11:39:03 -06:00
atexit ( SDL_Quit ) ;
2012-04-22 11:13:43 -05:00
2012-08-08 08:35:27 -05:00
return 0 ;
}
2012-04-22 11:13:43 -05:00
2012-08-08 08:35:27 -05:00
SDL_Surface * SDLSetScreen ( int newScale , bool newFullscreen )
{
scale = newScale ;
fullscreen = newFullscreen ;
SDL_Surface * surface ;
# ifndef OGLI
2013-11-10 03:02:55 -06:00
surface = SDL_SetVideoMode ( WINDOWW * newScale , WINDOWH * newScale , 32 , SDL_SWSURFACE | ( newFullscreen ? SDL_FULLSCREEN : 0 ) ) ;
2012-08-08 08:35:27 -05:00
# else
2013-11-10 03:02:55 -06:00
surface = SDL_SetVideoMode ( WINDOWW * newScale , WINDOWH * newScale , 32 , SDL_OPENGL | SDL_RESIZABLE | ( newFullscreen ? SDL_FULLSCREEN : 0 ) ) ;
2012-08-08 08:35:27 -05:00
# endif
return surface ;
2012-01-08 11:39:03 -06:00
}
2016-04-01 23:10:15 -05:00
void SetCursorEnabled ( int enabled )
{
SDL_ShowCursor ( enabled ) ;
}
2012-07-06 10:53:59 -05:00
std : : map < std : : string , std : : string > readArguments ( int argc , char * argv [ ] )
{
std : : map < std : : string , std : : string > arguments ;
2012-11-16 17:20:48 -06:00
//Defaults
2012-07-06 10:53:59 -05:00
arguments [ " scale " ] = " " ;
arguments [ " proxy " ] = " " ;
2012-11-16 17:20:48 -06:00
arguments [ " nohud " ] = " false " ; //the nohud, sound, and scripts commands currently do nothing.
2012-07-06 10:53:59 -05:00
arguments [ " sound " ] = " false " ;
arguments [ " kiosk " ] = " false " ;
arguments [ " scripts " ] = " false " ;
arguments [ " open " ] = " " ;
arguments [ " ddir " ] = " " ;
arguments [ " ptsave " ] = " " ;
for ( int i = 1 ; i < argc ; i + + )
{
if ( ! strncmp ( argv [ i ] , " scale: " , 6 ) & & argv [ i ] + 6 )
{
arguments [ " scale " ] = std : : string ( argv [ i ] + 6 ) ;
}
2012-08-08 12:34:37 -05:00
else if ( ! strncmp ( argv [ i ] , " proxy: " , 6 ) )
2012-07-06 10:53:59 -05:00
{
2012-08-08 12:34:37 -05:00
if ( argv [ i ] + 6 )
arguments [ " proxy " ] = std : : string ( argv [ i ] + 6 ) ;
else
arguments [ " proxy " ] = " false " ;
2012-07-06 10:53:59 -05:00
}
else if ( ! strncmp ( argv [ i ] , " nohud " , 5 ) )
{
arguments [ " nohud " ] = " true " ;
}
else if ( ! strncmp ( argv [ i ] , " kiosk " , 5 ) )
{
arguments [ " kiosk " ] = " true " ;
}
else if ( ! strncmp ( argv [ i ] , " sound " , 5 ) )
{
arguments [ " sound " ] = " true " ;
}
else if ( ! strncmp ( argv [ i ] , " scripts " , 8 ) )
{
arguments [ " scripts " ] = " true " ;
}
else if ( ! strncmp ( argv [ i ] , " open " , 5 ) & & i + 1 < argc )
{
arguments [ " open " ] = std : : string ( argv [ i + 1 ] ) ; ;
i + + ;
}
else if ( ! strncmp ( argv [ i ] , " ddir " , 5 ) & & i + 1 < argc )
{
arguments [ " ddir " ] = std : : string ( argv [ i + 1 ] ) ;
i + + ;
}
else if ( ! strncmp ( argv [ i ] , " ptsave " , 7 ) & & i + 1 < argc )
{
arguments [ " ptsave " ] = std : : string ( argv [ i + 1 ] ) ;
i + + ;
break ;
}
}
return arguments ;
}
2014-02-27 10:39:16 -06:00
SDLKey MapNumpad ( SDLKey key )
{
switch ( key )
{
case KEY_NUM_UP :
return KEY_UP ;
case KEY_NUM_DOWN :
return KEY_DOWN ;
case KEY_NUM_RIGHT :
return KEY_RIGHT ;
case KEY_NUM_LEFT :
return KEY_LEFT ;
case KEY_NUM_HOME :
return KEY_HOME ;
case KEY_NUM_END :
return KEY_END ;
2014-03-12 10:04:16 -05:00
case KEY_NUM_PERIOD :
return KEY_DELETE ;
case KEY_NUM_INS :
case KEY_NUM_PGUP :
case KEY_NUM_PGDOWN :
return KEY_UNKNOWN ;
2014-02-27 10:39:16 -06:00
default :
return key ;
}
}
2012-08-18 16:08:20 -05:00
int elapsedTime = 0 , currentTime = 0 , lastTime = 0 , currentFrame = 0 ;
unsigned int lastTick = 0 ;
float fps = 0 , delta = 1.0f , inputScale = 1.0f ;
ui : : Engine * engine = NULL ;
2016-01-31 21:30:39 -06:00
bool showDoubleScreenDialog = false ;
2012-11-16 15:50:02 -06:00
float currentWidth , currentHeight ;
2013-10-24 15:46:41 -05:00
void EventProcess ( SDL_Event event )
{
2014-03-11 11:53:42 -05:00
if ( event . type = = SDL_KEYDOWN | | event . type = = SDL_KEYUP )
2014-03-12 10:05:54 -05:00
{
if ( event . key . keysym . unicode = = 0 )
2014-03-11 11:53:42 -05:00
{
2014-03-12 10:05:54 -05:00
// If unicode is zero, this could be a numpad key with numlock off, or numlock on and shift on (unicode is set to 0 by SDL or the OS in these circumstances. If numlock is on, unicode is the relevant digit character).
// For some unknown reason, event.key.keysym.mod seems to be unreliable on some computers (keysum.mod&KEY_MOD_NUM is opposite to the actual value), so check keysym.unicode instead.
// Note: unicode is always zero for SDL_KEYUP events, so this translation won't always work properly for keyup events.
2014-03-11 11:53:42 -05:00
SDLKey newKey = MapNumpad ( event . key . keysym . sym ) ;
if ( newKey ! = event . key . keysym . sym )
{
event . key . keysym . sym = newKey ;
event . key . keysym . unicode = 0 ;
}
}
2014-03-12 10:05:54 -05:00
}
2013-10-24 15:46:41 -05:00
switch ( event . type )
{
case SDL_QUIT :
if ( engine - > GetFastQuit ( ) | | engine - > CloseWindow ( ) )
engine - > Exit ( ) ;
break ;
case SDL_KEYDOWN :
engine - > onKeyPress ( event . key . keysym . sym , event . key . keysym . unicode , event . key . keysym . mod & KEY_MOD_SHIFT , event . key . keysym . mod & KEY_MOD_CONTROL , event . key . keysym . mod & KEY_MOD_ALT ) ;
break ;
case SDL_KEYUP :
engine - > onKeyRelease ( event . key . keysym . sym , event . key . keysym . unicode , event . key . keysym . mod & KEY_MOD_SHIFT , event . key . keysym . mod & KEY_MOD_CONTROL , event . key . keysym . mod & KEY_MOD_ALT ) ;
break ;
case SDL_MOUSEMOTION :
engine - > onMouseMove ( event . motion . x * inputScale , event . motion . y * inputScale ) ;
2016-03-31 21:08:04 -05:00
mousex = event . motion . x * inputScale ;
mousey = event . motion . y * inputScale ;
2013-10-24 15:46:41 -05:00
break ;
case SDL_MOUSEBUTTONDOWN :
2014-03-11 11:53:42 -05:00
if ( event . button . button = = SDL_BUTTON_WHEELUP )
2013-10-24 15:46:41 -05:00
{
engine - > onMouseWheel ( event . motion . x * inputScale , event . motion . y * inputScale , 1 ) ;
}
else if ( event . button . button = = SDL_BUTTON_WHEELDOWN )
{
engine - > onMouseWheel ( event . motion . x * inputScale , event . motion . y * inputScale , - 1 ) ;
}
else
{
engine - > onMouseClick ( event . motion . x * inputScale , event . motion . y * inputScale , event . button . button ) ;
}
2016-03-31 21:08:04 -05:00
mousex = event . motion . x * inputScale ;
mousey = event . motion . y * inputScale ;
2013-10-24 15:46:41 -05:00
break ;
case SDL_MOUSEBUTTONUP :
2014-03-11 11:53:42 -05:00
if ( event . button . button ! = SDL_BUTTON_WHEELUP & & event . button . button ! = SDL_BUTTON_WHEELDOWN )
2013-10-24 15:46:41 -05:00
engine - > onMouseUnclick ( event . motion . x * inputScale , event . motion . y * inputScale , event . button . button ) ;
2016-03-31 21:08:04 -05:00
mousex = event . motion . x * inputScale ;
mousey = event . motion . y * inputScale ;
2013-10-24 15:46:41 -05:00
break ;
# ifdef OGLI
case SDL_VIDEORESIZE :
{
2013-11-10 03:02:55 -06:00
float ratio = ( float ) WINDOWW / WINDOWH ;
2013-10-24 15:46:41 -05:00
float width = event . resize . w ;
float height = width / ratio ;
sdl_scrn = SDL_SetVideoMode ( event . resize . w , height , 32 , SDL_OPENGL | SDL_RESIZABLE ) ;
glViewport ( 0 , 0 , width , height ) ;
engine - > g - > Reset ( ) ;
//glScaled(width/currentWidth, height/currentHeight, 1.0f);
currentWidth = width ;
currentHeight = height ;
2013-11-10 03:02:55 -06:00
inputScale = ( float ) WINDOWW / currentWidth ;
2013-10-24 15:46:41 -05:00
2013-11-10 03:02:55 -06:00
glLineWidth ( currentWidth / ( float ) WINDOWW ) ;
2013-10-24 15:46:41 -05:00
if ( sdl_scrn = = NULL )
{
std : : cerr < < " Oh bugger " < < std : : endl ;
}
break ;
}
# endif
# if defined (USE_SDL) && defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
case SDL_SYSWMEVENT :
if ( event . syswm . msg - > subsystem ! = SDL_SYSWM_X11 )
break ;
sdl_wminfo . info . x11 . lock_func ( ) ;
XEvent xe = event . syswm . msg - > event . xevent ;
if ( xe . type = = SelectionClear )
{
2014-02-25 08:44:44 -06:00
clipboardText = " " ;
2013-10-24 15:46:41 -05:00
}
else if ( xe . type = = SelectionRequest )
{
XEvent xr ;
xr . xselection . type = SelectionNotify ;
xr . xselection . requestor = xe . xselectionrequest . requestor ;
xr . xselection . selection = xe . xselectionrequest . selection ;
xr . xselection . target = xe . xselectionrequest . target ;
xr . xselection . property = xe . xselectionrequest . property ;
xr . xselection . time = xe . xselectionrequest . time ;
if ( xe . xselectionrequest . target = = XA_TARGETS )
{
// send list of supported formats
Atom targets [ ] = { XA_TARGETS , XA_STRING , XA_UTF8_STRING } ;
xr . xselection . property = xe . xselectionrequest . property ;
XChangeProperty ( sdl_wminfo . info . x11 . display , xe . xselectionrequest . requestor , xe . xselectionrequest . property , XA_ATOM , 32 , PropModeReplace , ( unsigned char * ) targets , ( int ) ( sizeof ( targets ) / sizeof ( Atom ) ) ) ;
}
// TODO: Supporting more targets would be nice
2014-02-25 08:44:44 -06:00
else if ( ( xe . xselectionrequest . target = = XA_STRING | | xe . xselectionrequest . target = = XA_UTF8_STRING ) )
2013-10-24 15:46:41 -05:00
{
2014-02-25 08:44:44 -06:00
XChangeProperty ( sdl_wminfo . info . x11 . display , xe . xselectionrequest . requestor , xe . xselectionrequest . property , xe . xselectionrequest . target , 8 , PropModeReplace , ( unsigned char * ) clipboardText . c_str ( ) , clipboardText . size ( ) + 1 ) ;
2013-10-24 15:46:41 -05:00
}
else
{
// refuse clipboard request
xr . xselection . property = None ;
}
XSendEvent ( sdl_wminfo . info . x11 . display , xe . xselectionrequest . requestor , 0 , 0 , & xr ) ;
}
sdl_wminfo . info . x11 . unlock_func ( ) ;
# endif
}
}
2016-01-31 21:30:39 -06:00
void DoubleScreenDialog ( )
{
std : : stringstream message ;
message < < " Switching to double size mode since your screen was determined to be large enough: " ;
message < < desktopWidth < < " x " < < desktopHeight < < " detected, " < < WINDOWW * 2 < < " x " < < WINDOWH * 2 < < " required " ;
message < < " \n To undo this, hit Cancel. You can toggle double size mode in settings at any time. " ;
if ( ! ConfirmPrompt : : Blocking ( " Large screen detected " , message . str ( ) ) )
{
Client : : Ref ( ) . SetPref ( " Scale " , 1 ) ;
engine - > SetScale ( 1 ) ;
engine - > CloseWindow ( ) ;
2016-01-31 21:59:29 -06:00
# ifdef WIN
2016-01-31 21:30:39 -06:00
LoadWindowPosition ( 1 ) ;
2016-01-31 21:59:29 -06:00
# endif
2016-01-31 21:30:39 -06:00
}
}
2016-03-31 21:08:04 -05:00
2012-08-18 16:08:20 -05:00
void EngineProcess ( )
{
2015-02-03 19:13:51 -06:00
double frameTimeAvg = 0.0f , correctedFrameTimeAvg = 0.0f ;
2012-08-18 16:08:20 -05:00
SDL_Event event ;
while ( engine - > Running ( ) )
{
2015-02-03 19:13:51 -06:00
int frameStart = SDL_GetTicks ( ) ;
2012-08-19 06:16:51 -05:00
if ( engine - > Broken ( ) ) { engine - > UnBreak ( ) ; break ; }
2012-08-18 16:08:20 -05:00
event . type = 0 ;
while ( SDL_PollEvent ( & event ) )
{
2013-10-24 15:46:41 -05:00
EventProcess ( event ) ;
2012-08-18 16:08:20 -05:00
event . type = 0 ; //Clear last event
}
2012-08-19 06:16:51 -05:00
if ( engine - > Broken ( ) ) { engine - > UnBreak ( ) ; break ; }
2012-08-18 16:08:20 -05:00
engine - > Tick ( ) ;
engine - > Draw ( ) ;
2013-05-21 22:05:27 -05:00
if ( scale ! = engine - > Scale | | fullscreen ! = engine - > Fullscreen )
{
sdl_scrn = SDLSetScreen ( engine - > Scale , engine - > Fullscreen ) ;
2015-02-03 19:13:51 -06:00
inputScale = 1.0f / ( float ) scale ;
2013-05-21 22:05:27 -05:00
}
# ifdef OGLI
blit ( ) ;
# else
if ( engine - > Scale = = 2 )
blit2 ( engine - > g - > vid , engine - > Scale ) ;
else
blit ( engine - > g - > vid ) ;
# endif
2015-02-03 19:13:51 -06:00
int frameTime = SDL_GetTicks ( ) - frameStart ;
frameTimeAvg = frameTimeAvg * 0.8 + frameTime * 0.2 ;
int fpsLimit = ui : : Engine : : Ref ( ) . FpsLimit ;
if ( fpsLimit > 2 )
2012-10-05 08:21:38 -05:00
{
2015-02-03 19:13:51 -06:00
double offset = 1000.0 / fpsLimit - frameTimeAvg ;
if ( offset > 0 )
SDL_Delay ( offset + 0.5 ) ;
2012-10-05 08:21:38 -05:00
}
2015-02-03 19:13:51 -06:00
int correctedFrameTime = SDL_GetTicks ( ) - frameStart ;
correctedFrameTimeAvg = correctedFrameTimeAvg * 0.95 + correctedFrameTime * 0.05 ;
engine - > SetFps ( 1000.0 / correctedFrameTimeAvg ) ;
if ( frameStart - lastTick > 1000 )
2012-08-18 16:08:20 -05:00
{
//Run client tick every second
2012-10-05 08:21:38 -05:00
lastTick = frameStart ;
2012-08-18 16:08:20 -05:00
Client : : Ref ( ) . Tick ( ) ;
}
2016-01-31 21:30:39 -06:00
if ( showDoubleScreenDialog )
{
showDoubleScreenDialog = false ;
DoubleScreenDialog ( ) ;
}
2012-08-18 16:08:20 -05:00
}
2012-08-18 18:40:20 -05:00
# ifdef DEBUG
std : : cout < < " Breaking out of EngineProcess " < < std : : endl ;
# endif
2012-08-18 16:08:20 -05:00
}
2013-02-14 22:31:31 -06:00
int GetModifiers ( )
{
return SDL_GetModState ( ) ;
}
2013-04-22 12:04:43 -05:00
# ifdef WIN
// Returns true if the loaded position was set
// Returns false if something went wrong: SDL_GetWMInfo failed or the loaded position was invalid
2013-05-03 18:11:44 -05:00
bool LoadWindowPosition ( int scale )
2013-04-22 12:04:43 -05:00
{
SDL_SysWMinfo sysInfo ;
SDL_VERSION ( & sysInfo . version ) ;
if ( SDL_GetWMInfo ( & sysInfo ) > 0 )
{
2013-11-10 03:02:55 -06:00
int windowW = WINDOWW * scale ;
int windowH = WINDOWH * scale ;
2013-04-22 12:04:43 -05:00
2013-05-02 12:00:13 -05:00
int savedWindowX = Client : : Ref ( ) . GetPrefInteger ( " WindowX " , INT_MAX ) ;
int savedWindowY = Client : : Ref ( ) . GetPrefInteger ( " WindowY " , INT_MAX ) ;
2013-05-03 18:11:44 -05:00
// Center the window on the primary desktop by default
2013-05-02 12:00:13 -05:00
int newWindowX = ( desktopWidth - windowW ) / 2 ;
int newWindowY = ( desktopHeight - windowH ) / 2 ;
2013-04-22 12:04:43 -05:00
2013-05-02 12:00:13 -05:00
bool success = false ;
2013-04-22 12:04:43 -05:00
2013-05-02 12:00:13 -05:00
if ( savedWindowX ! = INT_MAX & & savedWindowY ! = INT_MAX )
2013-04-22 12:04:43 -05:00
{
POINT windowPoints [ ] = {
2013-05-02 12:00:13 -05:00
{ savedWindowX , savedWindowY } , // Top-left
{ savedWindowX + windowW , savedWindowY + windowH } // Bottom-right
2013-04-22 12:04:43 -05:00
} ;
MONITORINFO monitor ;
monitor . cbSize = sizeof ( monitor ) ;
2013-05-02 12:00:13 -05:00
if ( GetMonitorInfo ( MonitorFromPoint ( windowPoints [ 0 ] , MONITOR_DEFAULTTONEAREST ) , & monitor ) ! = 0 )
2013-04-22 12:04:43 -05:00
{
2013-05-03 18:11:44 -05:00
// Only use the saved window position if it lies inside the visible screen
2013-04-22 12:04:43 -05:00
if ( PtInRect ( & monitor . rcMonitor , windowPoints [ 0 ] ) & & PtInRect ( & monitor . rcMonitor , windowPoints [ 1 ] ) )
{
2013-05-02 12:00:13 -05:00
newWindowX = savedWindowX ;
newWindowY = savedWindowY ;
2013-04-22 12:04:43 -05:00
2013-05-02 12:00:13 -05:00
success = true ;
}
else
{
2013-05-03 18:11:44 -05:00
// Center the window on the nearest monitor
2013-05-02 12:00:13 -05:00
newWindowX = monitor . rcMonitor . left + ( monitor . rcMonitor . right - monitor . rcMonitor . left - windowW ) / 2 ;
newWindowY = monitor . rcMonitor . top + ( monitor . rcMonitor . bottom - monitor . rcMonitor . top - windowH ) / 2 ;
2013-04-22 12:04:43 -05:00
}
}
}
2013-05-02 12:00:13 -05:00
SetWindowPos ( sysInfo . window , 0 , newWindowX , newWindowY , 0 , 0 , SWP_NOSIZE | SWP_NOZORDER | SWP_NOOWNERZORDER ) ;
2013-04-22 12:04:43 -05:00
2013-05-03 18:11:44 -05:00
// True if we didn't use the default, i.e. the position was valid
2013-05-02 12:00:13 -05:00
return success ;
2013-04-22 12:04:43 -05:00
}
return false ;
}
// Returns true if the window position was saved
bool SaveWindowPosition ( )
{
SDL_SysWMinfo sysInfo ;
SDL_VERSION ( & sysInfo . version ) ;
if ( SDL_GetWMInfo ( & sysInfo ) > 0 )
{
WINDOWPLACEMENT placement ;
placement . length = sizeof ( placement ) ;
GetWindowPlacement ( sysInfo . window , & placement ) ;
2013-05-04 09:00:45 -05:00
Client : : Ref ( ) . SetPref ( " WindowX " , ( int ) placement . rcNormalPosition . left ) ;
Client : : Ref ( ) . SetPref ( " WindowY " , ( int ) placement . rcNormalPosition . top ) ;
2013-04-22 12:04:43 -05:00
return true ;
}
return false ;
}
# endif
2013-10-26 10:38:50 -05:00
void BlueScreen ( const char * detailMessage ) {
2013-05-04 15:39:43 -05:00
ui : : Engine * engine = & ui : : Engine : : Ref ( ) ;
engine - > g - > fillrect ( 0 , 0 , engine - > GetWidth ( ) , engine - > GetHeight ( ) , 17 , 114 , 169 , 210 ) ;
std : : string errorTitle = " ERROR " ;
std : : string errorDetails = " Details: " + std : : string ( detailMessage ) ;
2015-05-18 15:15:54 -05:00
std : : string errorHelp = " An unrecoverable fault has occurred, please report the error by visiting the website below \n "
2013-05-04 15:39:43 -05:00
" http:// " SERVER ;
int currentY = 0 , width , height ;
int errorWidth = 0 ;
Graphics : : textsize ( errorHelp . c_str ( ) , errorWidth , height ) ;
engine - > g - > drawtext ( ( engine - > GetWidth ( ) / 2 ) - ( errorWidth / 2 ) , ( ( engine - > GetHeight ( ) / 2 ) - 100 ) + currentY , errorTitle . c_str ( ) , 255 , 255 , 255 , 255 ) ;
Graphics : : textsize ( errorTitle . c_str ( ) , width , height ) ;
currentY + = height + 4 ;
engine - > g - > drawtext ( ( engine - > GetWidth ( ) / 2 ) - ( errorWidth / 2 ) , ( ( engine - > GetHeight ( ) / 2 ) - 100 ) + currentY , errorDetails . c_str ( ) , 255 , 255 , 255 , 255 ) ;
Graphics : : textsize ( errorTitle . c_str ( ) , width , height ) ;
currentY + = height + 4 ;
engine - > g - > drawtext ( ( engine - > GetWidth ( ) / 2 ) - ( errorWidth / 2 ) , ( ( engine - > GetHeight ( ) / 2 ) - 100 ) + currentY , errorHelp . c_str ( ) , 255 , 255 , 255 , 255 ) ;
Graphics : : textsize ( errorTitle . c_str ( ) , width , height ) ;
currentY + = height + 4 ;
//Death loop
SDL_Event event ;
while ( true )
{
while ( SDL_PollEvent ( & event ) )
if ( event . type = = SDL_QUIT )
exit ( - 1 ) ;
# ifdef OGLI
blit ( ) ;
# else
if ( engine - > Scale = = 2 )
blit2 ( engine - > g - > vid , engine - > Scale ) ;
else
blit ( engine - > g - > vid ) ;
# endif
}
}
void SigHandler ( int signal )
{
switch ( signal ) {
case SIGSEGV :
BlueScreen ( " Memory read/write error " ) ;
break ;
case SIGFPE :
BlueScreen ( " Floating point exception " ) ;
break ;
case SIGILL :
BlueScreen ( " Program execution exception " ) ;
break ;
case SIGABRT :
BlueScreen ( " Unexpected program abort " ) ;
break ;
}
}
2012-01-08 11:39:03 -06:00
int main ( int argc , char * argv [ ] )
{
2013-11-10 03:02:55 -06:00
currentWidth = WINDOWW ;
currentHeight = WINDOWH ;
2012-11-16 15:50:02 -06:00
2012-01-08 11:39:03 -06:00
2012-07-06 10:53:59 -05:00
std : : map < std : : string , std : : string > arguments = readArguments ( argc , argv ) ;
2012-08-08 11:42:04 -05:00
if ( arguments [ " ddir " ] . length ( ) )
# ifdef WIN
_chdir ( arguments [ " ddir " ] . c_str ( ) ) ;
# else
chdir ( arguments [ " ddir " ] . c_str ( ) ) ;
# endif
int tempScale = 1 ;
bool tempFullscreen = false ;
tempScale = Client : : Ref ( ) . GetPrefInteger ( " Scale " , 1 ) ;
tempFullscreen = Client : : Ref ( ) . GetPrefBool ( " Fullscreen " , false ) ;
if ( arguments [ " kiosk " ] = = " true " )
{
tempFullscreen = true ;
Client : : Ref ( ) . SetPref ( " Fullscreen " , tempFullscreen ) ;
}
if ( arguments [ " scale " ] . length ( ) )
{
tempScale = format : : StringToNumber < int > ( arguments [ " scale " ] ) ;
Client : : Ref ( ) . SetPref ( " Scale " , tempScale ) ;
}
2012-08-08 12:34:37 -05:00
std : : string proxyString = " " ;
if ( arguments [ " proxy " ] . length ( ) )
{
if ( arguments [ " proxy " ] = = " false " )
{
proxyString = " " ;
Client : : Ref ( ) . SetPref ( " Proxy " , " " ) ;
}
else
{
proxyString = ( arguments [ " proxy " ] ) ;
Client : : Ref ( ) . SetPref ( " Proxy " , arguments [ " proxy " ] ) ;
}
}
else if ( Client : : Ref ( ) . GetPrefString ( " Proxy " , " " ) . length ( ) )
{
proxyString = ( Client : : Ref ( ) . GetPrefString ( " Proxy " , " " ) ) ;
}
Client : : Ref ( ) . Initialise ( proxyString ) ;
2012-08-08 11:42:04 -05:00
if ( tempScale ! = 1 & & tempScale ! = 2 )
tempScale = 1 ;
2015-01-10 21:43:33 -06:00
SDLOpen ( ) ;
2015-09-01 11:39:58 -05:00
if ( Client : : Ref ( ) . IsFirstRun ( ) & & desktopWidth > WINDOWW * 2 + 50 & & desktopHeight > WINDOWH * 2 + 50 )
2015-05-14 22:22:20 -05:00
{
tempScale = 2 ;
Client : : Ref ( ) . SetPref ( " Scale " , 2 ) ;
2016-01-31 21:30:39 -06:00
showDoubleScreenDialog = true ;
2015-05-14 22:22:20 -05:00
}
2013-04-22 12:04:43 -05:00
# ifdef WIN
2013-05-03 18:11:44 -05:00
LoadWindowPosition ( tempScale ) ;
2013-04-22 12:04:43 -05:00
# endif
2013-05-03 18:11:44 -05:00
sdl_scrn = SDLSetScreen ( tempScale , tempFullscreen ) ;
2013-04-22 12:04:43 -05:00
2012-06-23 08:59:07 -05:00
# ifdef OGLI
2012-05-30 06:32:58 -05:00
SDL_GL_SetAttribute ( SDL_GL_DOUBLEBUFFER , 1 ) ;
2012-06-25 10:10:40 -05:00
//glScaled(2.0f, 2.0f, 1.0f);
2012-08-12 13:29:27 -05:00
# endif
# if defined(OGLI)
int status = glewInit ( ) ;
if ( status ! = GLEW_OK )
{
fprintf ( stderr , " Initializing Glew: %d \n " , status ) ;
exit ( - 1 ) ;
}
2012-05-30 06:32:58 -05:00
# endif
2013-01-19 10:46:21 -06:00
# if defined (USE_SDL) && defined(LIN) && defined(SDL_VIDEO_DRIVER_X11)
2013-01-18 13:37:24 -06:00
SDL_EventState ( SDL_SYSWMEVENT , SDL_ENABLE ) ;
SDL_VERSION ( & sdl_wminfo . version ) ;
SDL_GetWMInfo ( & sdl_wminfo ) ;
sdl_wminfo . info . x11 . lock_func ( ) ;
XA_CLIPBOARD = XInternAtom ( sdl_wminfo . info . x11 . display , " CLIPBOARD " , 1 ) ;
XA_TARGETS = XInternAtom ( sdl_wminfo . info . x11 . display , " TARGETS " , 1 ) ;
2013-08-28 15:57:08 -05:00
XA_UTF8_STRING = XInternAtom ( sdl_wminfo . info . x11 . display , " UTF8_STRING " , 1 ) ;
2013-01-18 13:37:24 -06:00
sdl_wminfo . info . x11 . unlock_func ( ) ;
2013-01-19 10:46:21 -06:00
# endif
2012-01-17 14:46:06 -06:00
ui : : Engine : : Ref ( ) . g = new Graphics ( ) ;
2012-08-08 11:42:04 -05:00
ui : : Engine : : Ref ( ) . Scale = scale ;
inputScale = 1.0f / float ( scale ) ;
ui : : Engine : : Ref ( ) . Fullscreen = fullscreen ;
2012-01-15 13:35:40 -06:00
2012-08-18 16:08:20 -05:00
engine = & ui : : Engine : : Ref ( ) ;
2012-09-05 11:31:49 -05:00
engine - > SetMaxSize ( desktopWidth , desktopHeight ) ;
2013-11-10 03:02:55 -06:00
engine - > Begin ( WINDOWW , WINDOWH ) ;
2012-10-03 17:55:19 -05:00
engine - > SetFastQuit ( Client : : Ref ( ) . GetPrefBool ( " FastQuit " , true ) ) ;
2012-01-17 14:46:06 -06:00
2013-07-10 15:59:10 -05:00
# if !defined(DEBUG) && !defined(_DEBUG)
2013-05-04 15:39:43 -05:00
//Get ready to catch any dodgy errors
signal ( SIGSEGV , SigHandler ) ;
signal ( SIGFPE , SigHandler ) ;
signal ( SIGILL , SigHandler ) ;
signal ( SIGABRT , SigHandler ) ;
2012-08-08 15:32:10 -05:00
# endif
2013-05-04 15:39:43 -05:00
GameController * gameController = NULL ;
2013-12-03 21:05:20 -06:00
# if !defined(DEBUG) && !defined(_DEBUG)
2013-05-04 15:39:43 -05:00
try {
# endif
gameController = new GameController ( ) ;
engine - > ShowWindow ( gameController - > GetView ( ) ) ;
if ( arguments [ " open " ] . length ( ) )
2012-08-08 14:24:23 -05:00
{
2013-12-03 21:05:20 -06:00
# ifdef DEBUG
2013-05-04 15:39:43 -05:00
std : : cout < < " Loading " < < arguments [ " open " ] < < std : : endl ;
2013-12-03 21:05:20 -06:00
# endif
2013-05-04 15:39:43 -05:00
if ( Client : : Ref ( ) . FileExists ( arguments [ " open " ] ) )
2012-08-08 14:24:23 -05:00
{
2013-05-04 15:39:43 -05:00
try
2012-08-08 14:24:23 -05:00
{
2013-05-04 15:39:43 -05:00
std : : vector < unsigned char > gameSaveData = Client : : Ref ( ) . ReadFile ( arguments [ " open " ] ) ;
if ( ! gameSaveData . size ( ) )
{
new ErrorMessage ( " Error " , " Could not read file " ) ;
}
else
{
SaveFile * newFile = new SaveFile ( arguments [ " open " ] ) ;
GameSave * newSave = new GameSave ( gameSaveData ) ;
newFile - > SetGameSave ( newSave ) ;
gameController - > LoadSaveFile ( newFile ) ;
delete newFile ;
}
2012-08-08 14:24:23 -05:00
}
2013-05-04 15:39:43 -05:00
catch ( std : : exception & e )
2012-08-08 14:24:23 -05:00
{
2013-05-04 15:39:43 -05:00
new ErrorMessage ( " Error " , " Could not open save file: \n " + std : : string ( e . what ( ) ) ) ;
2012-08-08 14:24:23 -05:00
}
}
2013-05-04 15:39:43 -05:00
else
2012-08-08 14:24:23 -05:00
{
2013-05-04 15:39:43 -05:00
new ErrorMessage ( " Error " , " Could not open file " ) ;
2012-08-08 14:24:23 -05:00
}
}
2013-05-04 15:39:43 -05:00
if ( arguments [ " ptsave " ] . length ( ) )
2012-08-08 15:32:10 -05:00
{
2013-05-04 15:39:43 -05:00
engine - > g - > fillrect ( ( engine - > GetWidth ( ) / 2 ) - 101 , ( engine - > GetHeight ( ) / 2 ) - 26 , 202 , 52 , 0 , 0 , 0 , 210 ) ;
engine - > g - > drawrect ( ( engine - > GetWidth ( ) / 2 ) - 100 , ( engine - > GetHeight ( ) / 2 ) - 25 , 200 , 50 , 255 , 255 , 255 , 180 ) ;
engine - > g - > drawtext ( ( engine - > GetWidth ( ) / 2 ) - ( Graphics : : textwidth ( " Loading save... " ) / 2 ) , ( engine - > GetHeight ( ) / 2 ) - 5 , " Loading save... " , style : : Colour : : InformationTitle . Red , style : : Colour : : InformationTitle . Green , style : : Colour : : InformationTitle . Blue , 255 ) ;
2013-12-03 21:05:20 -06:00
# ifdef OGLI
2013-05-04 15:39:43 -05:00
blit ( ) ;
2013-12-03 21:05:20 -06:00
# else
2013-05-04 15:39:43 -05:00
if ( engine - > Scale = = 2 )
blit2 ( engine - > g - > vid , engine - > Scale ) ;
2012-08-08 15:32:10 -05:00
else
2013-05-04 15:39:43 -05:00
blit ( engine - > g - > vid ) ;
2013-12-03 21:05:20 -06:00
# endif
2013-05-04 15:39:43 -05:00
std : : string ptsaveArg = arguments [ " ptsave " ] ;
try
2012-08-08 15:32:10 -05:00
{
2015-08-29 12:14:17 -05:00
if ( ptsaveArg . find ( " ptsave: " ) )
throw std : : runtime_error ( " Invalid save link " ) ;
2013-05-04 15:39:43 -05:00
std : : string saveIdPart = " " ;
int saveId ;
2015-01-16 22:39:42 -06:00
size_t hashPos = ptsaveArg . find ( ' # ' ) ;
if ( hashPos ! = std : : string : : npos )
2013-05-04 15:39:43 -05:00
{
saveIdPart = ptsaveArg . substr ( 7 , hashPos - 7 ) ;
}
else
{
saveIdPart = ptsaveArg . substr ( 7 ) ;
}
2015-08-29 12:14:17 -05:00
if ( ! saveIdPart . length ( ) )
2013-05-04 15:39:43 -05:00
throw std : : runtime_error ( " No Save ID " ) ;
2015-08-29 12:14:17 -05:00
# ifdef DEBUG
std : : cout < < " Got Ptsave: id: " < < saveIdPart < < std : : endl ;
# endif
saveId = format : : StringToNumber < int > ( saveIdPart ) ;
if ( ! saveId )
throw std : : runtime_error ( " Invalid Save ID " ) ;
SaveInfo * newSave = Client : : Ref ( ) . GetSave ( saveId , 0 ) ;
if ( ! newSave )
throw std : : runtime_error ( " Could not load save info " ) ;
std : : vector < unsigned char > saveData = Client : : Ref ( ) . GetSaveData ( saveId , 0 ) ;
if ( ! saveData . size ( ) )
throw std : : runtime_error ( " Could not load save \n " + Client : : Ref ( ) . GetLastError ( ) ) ;
GameSave * newGameSave = new GameSave ( saveData ) ;
newSave - > SetGameSave ( newGameSave ) ;
gameController - > LoadSave ( newSave ) ;
delete newSave ;
2013-05-04 15:39:43 -05:00
}
catch ( std : : exception & e )
2012-08-08 15:32:10 -05:00
{
2015-08-29 12:14:17 -05:00
new ErrorMessage ( " Error " , e . what ( ) ) ;
2012-08-08 15:32:10 -05:00
}
}
2015-01-31 13:09:50 -06:00
//initial mouse coords
int sdl_x , sdl_y ;
SDL_GetMouseState ( & sdl_x , & sdl_y ) ;
engine - > onMouseMove ( sdl_x * inputScale , sdl_y * inputScale ) ;
2013-05-04 15:39:43 -05:00
EngineProcess ( ) ;
2015-01-31 13:09:50 -06:00
# ifdef WIN
2013-05-04 15:39:43 -05:00
SaveWindowPosition ( ) ;
2015-01-31 13:09:50 -06:00
# endif
2013-05-04 15:39:43 -05:00
2013-12-03 21:05:20 -06:00
# if !defined(DEBUG) && !defined(_DEBUG)
2013-05-04 15:39:43 -05:00
}
2013-12-03 21:05:20 -06:00
catch ( exception & e )
2013-05-04 15:39:43 -05:00
{
2013-12-03 21:05:20 -06:00
BlueScreen ( e . what ( ) ) ;
2013-05-04 15:39:43 -05:00
}
2013-04-22 12:04:43 -05:00
# endif
2012-01-21 07:19:10 -06:00
ui : : Engine : : Ref ( ) . CloseWindow ( ) ;
delete gameController ;
delete ui : : Engine : : Ref ( ) . g ;
2012-06-21 19:04:55 -05:00
Client : : Ref ( ) . Shutdown ( ) ;
2012-05-30 07:17:40 -05:00
return 0 ;
2012-01-08 11:39:03 -06:00
}
2012-05-30 07:17:40 -05:00
# endif