|
|
@@ -499,10 +499,16 @@ Platform* Platform::create(Game* game, void* attachToWindow)
|
|
|
__attachToWindow = (Window)attachToWindow;
|
|
|
FileSystem::setResourcePath("./");
|
|
|
Platform* platform = new Platform(game);
|
|
|
-
|
|
|
- // Get window configuration
|
|
|
-
|
|
|
- // Default values
|
|
|
+
|
|
|
+ // Get the display and initialize
|
|
|
+ __display = XOpenDisplay(NULL);
|
|
|
+ if (__display == NULL)
|
|
|
+ {
|
|
|
+ perror("XOpenDisplay");
|
|
|
+ return NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the window configuration values
|
|
|
const char *title = NULL;
|
|
|
int __x = 0, __y = 0, __width = 1280, __height = 800;
|
|
|
bool fullscreen = false;
|
|
|
@@ -516,35 +522,29 @@ Platform* Platform::create(Game* game, void* attachToWindow)
|
|
|
|
|
|
// Read window rect.
|
|
|
int x = config->getInt("x");
|
|
|
- if (x != 0) __x = x;
|
|
|
-
|
|
|
int y = config->getInt("y");
|
|
|
- if (y != 0) __y = y;
|
|
|
-
|
|
|
int width = config->getInt("width");
|
|
|
- if (width != 0) __width = width;
|
|
|
-
|
|
|
int height = config->getInt("height");
|
|
|
- if (height != 0) __height = height;
|
|
|
-
|
|
|
fullscreen = config->getBool("fullscreen");
|
|
|
|
|
|
-
|
|
|
+ if (fullscreen && width == 0 && height == 0)
|
|
|
+ {
|
|
|
+ // Use the screen resolution if fullscreen is true but width and height were not set in the config
|
|
|
+ int screen_num = DefaultScreen(__display);
|
|
|
+ width = DisplayWidth(__display, screen_num);
|
|
|
+ height = DisplayHeight(__display, screen_num);
|
|
|
+ }
|
|
|
+ if (x != 0) __x = x;
|
|
|
+ if (y != 0) __y = y;
|
|
|
+ if (width != 0) __width = width;
|
|
|
+ if (height != 0) __height = height;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // Get the display and initialize.
|
|
|
- __display = XOpenDisplay(NULL);
|
|
|
- if (__display == NULL)
|
|
|
- {
|
|
|
- perror("XOpenDisplay");
|
|
|
- return NULL;
|
|
|
- }
|
|
|
-
|
|
|
// GLX version
|
|
|
GLint majorGLX, minorGLX = 0;
|
|
|
glXQueryVersion(__display, &majorGLX, &minorGLX);
|
|
|
- if(majorGLX == 1 && minorGLX < 2)
|
|
|
+ if (majorGLX == 1 && minorGLX < 2)
|
|
|
{
|
|
|
perror("GLX 1.2 or greater is required.");
|
|
|
XCloseDisplay(__display);
|
|
|
@@ -563,25 +563,25 @@ Platform* Platform::create(Game* game, void* attachToWindow)
|
|
|
|
|
|
// Get the configs
|
|
|
int configAttribs[] =
|
|
|
- {
|
|
|
+ {
|
|
|
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
|
|
GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
|
|
|
GLX_X_RENDERABLE, True,
|
|
|
- GLX_DEPTH_SIZE, 24,
|
|
|
+ GLX_DEPTH_SIZE, 24,
|
|
|
GLX_STENCIL_SIZE, 8,
|
|
|
GLX_RED_SIZE, 8,
|
|
|
GLX_GREEN_SIZE, 8,
|
|
|
GLX_BLUE_SIZE, 8,
|
|
|
GLX_DOUBLEBUFFER, True,
|
|
|
- 0
|
|
|
+ 0
|
|
|
};
|
|
|
GLXFBConfig* configs;
|
|
|
int configCount = 0;
|
|
|
configs = glXChooseFBConfig(__display, DefaultScreen(__display), configAttribs, &configCount);
|
|
|
- if( configCount == 0 || configs == 0 )
|
|
|
- {
|
|
|
+ if ( configCount == 0 || configs == 0 )
|
|
|
+ {
|
|
|
perror( "glXChooseFBConfig" );
|
|
|
- return NULL;
|
|
|
+ return NULL;
|
|
|
}
|
|
|
|
|
|
// Create the windows
|
|
|
@@ -591,8 +591,8 @@ Platform* Platform::create(Game* game, void* attachToWindow)
|
|
|
XSetWindowAttributes winAttribs;
|
|
|
long eventMask;
|
|
|
eventMask = ExposureMask | VisibilityChangeMask | StructureNotifyMask |
|
|
|
- KeyPressMask | KeyReleaseMask | PointerMotionMask |
|
|
|
- ButtonPressMask | ButtonReleaseMask |
|
|
|
+ KeyPressMask | KeyReleaseMask | PointerMotionMask |
|
|
|
+ ButtonPressMask | ButtonReleaseMask |
|
|
|
EnterWindowMask | LeaveWindowMask;
|
|
|
winAttribs.event_mask = eventMask;
|
|
|
winAttribs.border_pixel = 0;
|
|
|
@@ -602,9 +602,9 @@ Platform* Platform::create(Game* game, void* attachToWindow)
|
|
|
GLint winMask;
|
|
|
winMask = CWBorderPixel | CWBitGravity | CWEventMask| CWColormap;
|
|
|
|
|
|
- __window = XCreateWindow(__display, DefaultRootWindow(__display), __x, __y, __width, __height, 0,
|
|
|
+ __window = XCreateWindow(__display, DefaultRootWindow(__display), __x, __y, __width, __height, 0,
|
|
|
visualInfo->depth, InputOutput, visualInfo->visual, winMask,
|
|
|
- &winAttribs);
|
|
|
+ &winAttribs);
|
|
|
|
|
|
// Tell the window manager that it should send the delete window notification through ClientMessage
|
|
|
__atomWmDeleteWindow = XInternAtom(__display, "WM_DELETE_WINDOW", False);
|
|
|
@@ -635,7 +635,7 @@ Platform* Platform::create(Game* game, void* attachToWindow)
|
|
|
XStoreName(__display, __window, title ? title : "");
|
|
|
|
|
|
__context = glXCreateContext(__display, visualInfo, NULL, True);
|
|
|
- if(!__context)
|
|
|
+ if (!__context)
|
|
|
{
|
|
|
perror("glXCreateContext");
|
|
|
return NULL;
|
|
|
@@ -645,7 +645,7 @@ Platform* Platform::create(Game* game, void* attachToWindow)
|
|
|
// Use OpenGL 2.x with GLEW
|
|
|
glewExperimental = GL_TRUE;
|
|
|
GLenum glewStatus = glewInit();
|
|
|
- if(glewStatus != GLEW_OK)
|
|
|
+ if (glewStatus != GLEW_OK)
|
|
|
{
|
|
|
perror("glewInit");
|
|
|
return NULL;
|
|
|
@@ -685,14 +685,14 @@ double timespec2millis(struct timespec *a)
|
|
|
return (1000.0 * a->tv_sec) + (0.000001 * a->tv_nsec);
|
|
|
}
|
|
|
|
|
|
-void updateWindowSize()
|
|
|
-{
|
|
|
- GP_ASSERT(__display);
|
|
|
+void updateWindowSize()
|
|
|
+{
|
|
|
+ GP_ASSERT(__display);
|
|
|
GP_ASSERT(__window);
|
|
|
- XWindowAttributes windowAttrs;
|
|
|
- XGetWindowAttributes(__display, __window, &windowAttrs);
|
|
|
- __windowSize[0] = windowAttrs.width;
|
|
|
- __windowSize[1] = windowAttrs.height;
|
|
|
+ XWindowAttributes windowAttrs;
|
|
|
+ XGetWindowAttributes(__display, __window, &windowAttrs);
|
|
|
+ __windowSize[0] = windowAttrs.width;
|
|
|
+ __windowSize[1] = windowAttrs.height;
|
|
|
}
|
|
|
|
|
|
int Platform::enterMessagePump()
|
|
|
@@ -717,7 +717,7 @@ int Platform::enterMessagePump()
|
|
|
// Run the game.
|
|
|
_game->run();
|
|
|
|
|
|
- // Setup select for message handling (to allow non-blocking)
|
|
|
+ // Setup select for message handling (to allow non-blocking)
|
|
|
int x11_fd = ConnectionNumber(__display);
|
|
|
|
|
|
pollfd xpolls[1];
|
|
|
@@ -728,12 +728,12 @@ int Platform::enterMessagePump()
|
|
|
while (true)
|
|
|
{
|
|
|
poll( xpolls, 1, 16 );
|
|
|
- // handle all pending events in one block
|
|
|
- while (XPending(__display))
|
|
|
+ // handle all pending events in one block
|
|
|
+ while (XPending(__display))
|
|
|
{
|
|
|
XNextEvent(__display, &evt);
|
|
|
|
|
|
- switch (evt.type)
|
|
|
+ switch (evt.type)
|
|
|
{
|
|
|
case ClientMessage:
|
|
|
{
|
|
|
@@ -751,7 +751,7 @@ int Platform::enterMessagePump()
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
- case Expose:
|
|
|
+ case Expose:
|
|
|
{
|
|
|
updateWindowSize();
|
|
|
}
|
|
|
@@ -764,18 +764,18 @@ int Platform::enterMessagePump()
|
|
|
|
|
|
//TempSym needed because XConvertCase operates on two keysyms: One lower and the other upper, we are only interested in the upper case
|
|
|
KeySym tempSym;
|
|
|
- if(capsOn && !shiftDown)
|
|
|
+ if (capsOn && !shiftDown)
|
|
|
XConvertCase(sym, &tempSym, &sym);
|
|
|
|
|
|
Keyboard::Key key = getKey(sym);
|
|
|
gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_PRESS, key);
|
|
|
|
|
|
- if(key == Keyboard::KEY_CAPS_LOCK)
|
|
|
+ if (key == Keyboard::KEY_CAPS_LOCK)
|
|
|
capsOn = !capsOn;
|
|
|
- if(key == Keyboard::KEY_SHIFT)
|
|
|
+ if (key == Keyboard::KEY_SHIFT)
|
|
|
shiftDown = true;
|
|
|
|
|
|
- if(int character = getUnicode(key))
|
|
|
+ if (int character = getUnicode(key))
|
|
|
gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_CHAR, character);
|
|
|
|
|
|
}
|
|
|
@@ -785,10 +785,10 @@ int Platform::enterMessagePump()
|
|
|
{
|
|
|
//detect and drop repeating keystrokes (no other way to do this using the event interface)
|
|
|
XEvent next;
|
|
|
- if( XPending(__display) )
|
|
|
+ if ( XPending(__display) )
|
|
|
{
|
|
|
XPeekEvent(__display,&next);
|
|
|
- if( next.type == KeyPress
|
|
|
+ if ( next.type == KeyPress
|
|
|
&& next.xkey.time == evt.xkey.time
|
|
|
&& next.xkey.keycode == evt.xkey.keycode )
|
|
|
{
|
|
|
@@ -801,7 +801,7 @@ int Platform::enterMessagePump()
|
|
|
Keyboard::Key key = getKey(sym);
|
|
|
gameplay::Platform::keyEventInternal(gameplay::Keyboard::KEY_RELEASE, key);
|
|
|
|
|
|
- if(key == Keyboard::KEY_SHIFT)
|
|
|
+ if (key == Keyboard::KEY_SHIFT)
|
|
|
shiftDown = false;
|
|
|
}
|
|
|
break;
|
|
|
@@ -809,7 +809,7 @@ int Platform::enterMessagePump()
|
|
|
case ButtonPress:
|
|
|
{
|
|
|
gameplay::Mouse::MouseEvent mouseEvt;
|
|
|
- switch(evt.xbutton.button)
|
|
|
+ switch (evt.xbutton.button)
|
|
|
{
|
|
|
case 1:
|
|
|
mouseEvt = gameplay::Mouse::MOUSE_PRESS_LEFT_BUTTON;
|
|
|
@@ -822,8 +822,8 @@ int Platform::enterMessagePump()
|
|
|
break;
|
|
|
case 4:
|
|
|
case 5:
|
|
|
- gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL,
|
|
|
- evt.xbutton.x, evt.xbutton.y,
|
|
|
+ gameplay::Platform::mouseEventInternal(gameplay::Mouse::MOUSE_WHEEL,
|
|
|
+ evt.xbutton.x, evt.xbutton.y,
|
|
|
evt.xbutton.button == Button4 ? 1 : -1);
|
|
|
break;
|
|
|
default:
|
|
|
@@ -839,7 +839,7 @@ int Platform::enterMessagePump()
|
|
|
case ButtonRelease:
|
|
|
{
|
|
|
gameplay::Mouse::MouseEvent mouseEvt;
|
|
|
- switch(evt.xbutton.button)
|
|
|
+ switch (evt.xbutton.button)
|
|
|
{
|
|
|
case 1:
|
|
|
mouseEvt = gameplay::Mouse::MOUSE_RELEASE_LEFT_BUTTON;
|
|
|
@@ -895,7 +895,7 @@ int Platform::enterMessagePump()
|
|
|
{
|
|
|
// Game state will be uninitialized if game was closed through Game::exit()
|
|
|
if (_game->getState() == Game::UNINITIALIZED)
|
|
|
- break;
|
|
|
+ break;
|
|
|
|
|
|
_game->frame();
|
|
|
}
|
|
|
@@ -908,15 +908,15 @@ int Platform::enterMessagePump()
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-void Platform::signalShutdown()
|
|
|
-{
|
|
|
+void Platform::signalShutdown()
|
|
|
+{
|
|
|
// nothing to do
|
|
|
}
|
|
|
-
|
|
|
-bool Platform::canExit()
|
|
|
-{
|
|
|
- return true;
|
|
|
-}
|
|
|
+
|
|
|
+bool Platform::canExit()
|
|
|
+{
|
|
|
+ return true;
|
|
|
+}
|
|
|
|
|
|
unsigned int Platform::getDisplayWidth()
|
|
|
{
|