Support for Raspberry Pi - patch by derhass
This commit is contained in:
parent
3553ea3cf7
commit
758f2d64f8
|
@ -10,6 +10,10 @@ d1x-rebirth.xcodeproj/project.pbxproj, editor/ehostage.c, main/custom.c: Updated
|
|||
SConstruct: For the assembler build, make sure platform_settings is accessed from self, likely preventing a compiling error
|
||||
SConstruct: Changes towards building using SCons on Mac OS X
|
||||
|
||||
20130122
|
||||
--------
|
||||
README.RPi, SConstruct, arch/ogl/gr.c: Support for Raspberry Pi - patch by derhass
|
||||
|
||||
20130119
|
||||
--------
|
||||
main/gamerend.c, main/menu.c, main/multi.c, main/multi.h, main/net_udp.c, main/playsave.c, main/playsave.h: Added Rankings functionality like in D2X-Rebirth while still utilizing eff file from original D1X source
|
||||
|
|
72
README.RPi
Normal file
72
README.RPi
Normal file
|
@ -0,0 +1,72 @@
|
|||
DXX-Rebirth for the Raspberry Pi
|
||||
|
||||
BUILDING:
|
||||
=========
|
||||
Make sure you have installed (the development packages of) all of the required
|
||||
libraries (libsdl, libphysfs, ...). For building, you will also need scons (and
|
||||
for that, python). Most linux distributions should contain all the required
|
||||
packages, debain/raspbian do so for sure. Using a distribution with hardfp ABI
|
||||
is recommended for optimal performance. I developed/tested this on a raspbian
|
||||
wheezy.
|
||||
|
||||
To build directly on the device, just run:
|
||||
|
||||
scons raspberrypi=1 [... other options (see scons -h)...]
|
||||
|
||||
This assumes that the development files (libs/headers) for the VideoCore APIs
|
||||
are located in /opt/vc. You can use rpi_vc_path to specify another location.
|
||||
|
||||
Currently, there is no direct support for crosscompiling.
|
||||
|
||||
RUNNING:
|
||||
========
|
||||
The game should run with X11 or directly on the console (libsdl with fbcon/
|
||||
directfb driver).
|
||||
|
||||
NOTE: *** PLEASE USE THE 128/128MB MEMORY SPLIT ***
|
||||
|
||||
The game might completely freeze or diplay messed up graphics in
|
||||
out-of-(GPU)-memory situations. If you want to run it with the 192/64MB memory
|
||||
split, you might be able to do so by setting the texture filter to "NONE" in
|
||||
the graphics options. (This disables mip mapping and reduces the memory
|
||||
requirements of the textures. Note that the "BILINEAR" filter still uses
|
||||
mipmapping).
|
||||
|
||||
If the game freezes during the "Prepare for Descent" phase when loading a
|
||||
level, you probably do not have enough GPU memory.
|
||||
|
||||
RUNNING ON X11:
|
||||
===============
|
||||
Recommendation is to use fullscreen mode. However, you can run in "windowed"
|
||||
mode, too. The game will open an X11 window in that case, and the actual game
|
||||
output will be an overlay of the same size, but not at the same position, and
|
||||
always on top (and completely out of control of the X Server). Game input is
|
||||
still handled via the X11 window, so make sure it has the focus.
|
||||
|
||||
RUNNING ON THE CONSOLE:
|
||||
=======================
|
||||
libsdl supports running directly on the Linux console. While the SDL Video mode
|
||||
is technically not required on the RPi, we still have to use it to get all the
|
||||
input events we need. libsdl seems to have problems on the RPi, I always get a
|
||||
crash in libsdl when trying to change the resolution. To avoid such crashes,
|
||||
the code will try to detect if it is running on the console and activate a hack
|
||||
to prevent switching the resolution. Note that the in-game framebuffer
|
||||
resolution can still be changed, the RPi will just scale the output to the
|
||||
initial resolution (in "fullscreen" mode). "Windowed" mode will just result in
|
||||
unscaled output. As libsdl creates a black screen, you will not be able to have
|
||||
the "Window" on top of the linux console output :(
|
||||
|
||||
NOTE: You might need root privileges to use the libsdl fbcon/directfb drivers.
|
||||
|
||||
BUGS, SUGGESTIONS AND FEEDBACK:
|
||||
===============================
|
||||
|
||||
The RPi patch was written by:
|
||||
Marcel Heinz <derhass@arcor.de>
|
||||
|
||||
Send bug reports, suggestions and other feedback regarding the operation
|
||||
on the RPi to me via email, or post to the official dxx-rebirth forum at:
|
||||
http://www.dxx-rebirth.com/frm/index.php
|
||||
|
||||
-- derhass, 2012-08-09
|
||||
|
17
SConstruct
17
SConstruct
|
@ -37,12 +37,15 @@ class DXXProgram:
|
|||
PREFIX = str(ARGUMENTS.get('prefix', '/usr/local'))
|
||||
self.BIN_DIR = PREFIX + '/bin'
|
||||
self.DATA_DIR = PREFIX + '/share/games/' + target
|
||||
|
||||
# Paths for the Videocore libs/includes on the Raspberry Pi
|
||||
self.RPI_DEFAULT_VC_PATH='/opt/vc'
|
||||
|
||||
# command-line parms
|
||||
self.sharepath = str(ARGUMENTS.get('sharepath', self.DATA_DIR))
|
||||
self.debug = int(ARGUMENTS.get('debug', 0))
|
||||
self.profiler = int(ARGUMENTS.get('profiler', 0))
|
||||
self.opengl = int(ARGUMENTS.get('opengl', 1))
|
||||
self.opengles = int(ARGUMENTS.get('opengles', 0))
|
||||
self.asm = int(ARGUMENTS.get('asm', 0))
|
||||
self.editor = int(ARGUMENTS.get('editor', 0))
|
||||
self.extra_version = ARGUMENTS.get('extra_version', None)
|
||||
|
@ -51,6 +54,16 @@ class DXXProgram:
|
|||
self.use_udp = int(ARGUMENTS.get('use_udp', 1))
|
||||
self.use_tracker = int(ARGUMENTS.get('use_tracker', 1))
|
||||
self.verbosebuild = int(ARGUMENTS.get('verbosebuild', 0))
|
||||
self.raspberrypi = int(ARGUMENTS.get('raspberrypi', 0))
|
||||
self.rpi_vc_path = str(ARGUMENTS.get('rpi_vc_path', self.RPI_DEFAULT_VC_PATH))
|
||||
self.default_opengles = 0
|
||||
self.default_OGLES_LIB = 'GLES_CM'
|
||||
# automatic setup for raspberrypi
|
||||
if (self.raspberrypi == 1):
|
||||
self.default_opengles=1
|
||||
self.default_OGLES_LIB='GLESv2'
|
||||
self.opengles = int(ARGUMENTS.get('opengles', self.default_opengles))
|
||||
self.opengles_lib = str(ARGUMENTS.get('opengles_lib', self.default_OGLES_LIB))
|
||||
builddir_prefix = ARGUMENTS.get('builddir_prefix', None)
|
||||
builddir_suffix = ARGUMENTS.get('builddir_suffix', None)
|
||||
default_builddir = builddir_prefix or ''
|
||||
|
@ -546,6 +559,8 @@ Help(program.PROGRAM_NAME + ', SConstruct file help:' +
|
|||
'use_udp=[0/1]' enable UDP support [default: 1]
|
||||
'use_tracker=[0/1]' enable Tracker support (requires udp) [default :1]
|
||||
'verbosebuild=[0/1]' print out all compiler/linker messages during building [default: 0]
|
||||
'raspberrypi=[0/1]' build for Raspberry Pi (automatically sets opengles and opengles_lib) [default: 0]
|
||||
'rpi_vc_path=[DIR]' use [DIR] to look for VideoCore libraries/header files (RPi only)
|
||||
|
||||
Default values:
|
||||
""" + ' sharepath = ' + program.user_settings.DATA_DIR + """
|
||||
|
|
378
arch/ogl/gr.c
378
arch/ogl/gr.c
|
@ -6,6 +6,11 @@
|
|||
|
||||
#define DECLARE_VARS
|
||||
|
||||
#ifdef RPI
|
||||
// extra libraries for the Raspberry Pi
|
||||
#include "bcm_host.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
@ -51,7 +56,7 @@
|
|||
#include <OpenGL/glu.h>
|
||||
#else
|
||||
#ifdef OGLES
|
||||
#include <GLES/egl.h>
|
||||
#include <EGL/egl.h>
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <SDL/SDL_syswm.h>
|
||||
|
@ -62,18 +67,26 @@
|
|||
|
||||
#ifdef OGLES
|
||||
int sdl_video_flags = 0;
|
||||
|
||||
#ifdef RPI
|
||||
static EGL_DISPMANX_WINDOW_T nativewindow;
|
||||
static DISPMANX_ELEMENT_HANDLE_T dispman_element=DISPMANX_NO_HANDLE;
|
||||
static DISPMANX_DISPLAY_HANDLE_T dispman_display=DISPMANX_NO_HANDLE;
|
||||
#endif
|
||||
|
||||
#else
|
||||
int sdl_video_flags = SDL_OPENGL;
|
||||
#endif
|
||||
int gr_installed = 0;
|
||||
int gl_initialized=0;
|
||||
int linedotscale=1; // scalar of glLinewidth and glPointSize - only calculated once when resolution changes
|
||||
int sdl_no_modeswitch=0;
|
||||
|
||||
#ifdef OGLES
|
||||
EGLDisplay eglDisplay;
|
||||
EGLDisplay eglDisplay=EGL_NO_DISPLAY;
|
||||
EGLConfig eglConfig;
|
||||
EGLSurface eglSurface;
|
||||
EGLContext eglContext;
|
||||
EGLSurface eglSurface=EGL_NO_SURFACE;
|
||||
EGLContext eglContext=EGL_NO_CONTEXT;
|
||||
|
||||
bool TestEGLError(char* pszLocation)
|
||||
{
|
||||
|
@ -102,8 +115,176 @@ void ogl_swap_buffers_internal(void)
|
|||
#endif
|
||||
}
|
||||
|
||||
#ifdef RPI
|
||||
|
||||
// MH: I got the following constants for vc_dispmanx_element_change_attributes() from:
|
||||
// http://qt.gitorious.org/qt/qtbase/commit/5933205cfcd73481cb0645fa6183103063fe3e0d
|
||||
// I do not know where they got them from, but OTOH, they are quite obvious.
|
||||
|
||||
// these constants are not in any headers (yet)
|
||||
#define ELEMENT_CHANGE_LAYER (1<<0)
|
||||
#define ELEMENT_CHANGE_OPACITY (1<<1)
|
||||
#define ELEMENT_CHANGE_DEST_RECT (1<<2)
|
||||
#define ELEMENT_CHANGE_SRC_RECT (1<<3)
|
||||
#define ELEMENT_CHANGE_MASK_RESOURCE (1<<4)
|
||||
#define ELEMENT_CHANGE_TRANSFORM (1<<5)
|
||||
|
||||
void rpi_destroy_element(void)
|
||||
{
|
||||
if (dispman_element != DISPMANX_NO_HANDLE) {
|
||||
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||
con_printf(CON_DEBUG, "RPi: destroying display manager element\n");
|
||||
dispman_update = vc_dispmanx_update_start( 0 );
|
||||
if (vc_dispmanx_element_remove( dispman_update, dispman_element)) {
|
||||
con_printf(CON_URGENT, "RPi: failed to remove dispmanx element!\n");
|
||||
}
|
||||
vc_dispmanx_update_submit_sync( dispman_update );
|
||||
dispman_element = DISPMANX_NO_HANDLE;
|
||||
}
|
||||
}
|
||||
|
||||
int rpi_setup_element(int x, int y, Uint32 video_flags, int update)
|
||||
{
|
||||
// this code is based on the work of Ben O'Steen
|
||||
// http://benosteen.wordpress.com/2012/04/27/using-opengl-es-2-0-on-the-raspberry-pi-without-x-windows/
|
||||
// https://github.com/benosteen/opengles-book-samples/tree/master/Raspi
|
||||
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||
VC_RECT_T dst_rect;
|
||||
VC_RECT_T src_rect;
|
||||
VC_DISPMANX_ALPHA_T alpha_descriptor;
|
||||
|
||||
uint32_t rpi_display_device=DISPMANX_ID_MAIN_LCD;
|
||||
uint32_t display_width;
|
||||
uint32_t display_height;
|
||||
int success;
|
||||
|
||||
success = graphics_get_display_size(rpi_display_device, &display_width, &display_height);
|
||||
if ( success < 0 ) {
|
||||
con_printf(CON_URGENT, "Could not get RPi display size, assuming 640x480\n");
|
||||
display_width=640;
|
||||
display_height=480;
|
||||
}
|
||||
|
||||
if ((uint32_t)x > display_width) {
|
||||
con_printf(CON_URGENT, "RPi: Requested width %d exceeds display width %u, scaling down!\n",
|
||||
x,display_width);
|
||||
x=(int)display_width;
|
||||
}
|
||||
if ((uint32_t)y > display_height) {
|
||||
con_printf(CON_URGENT, "RPi: Requested height %d exceeds display height %u, scaling down!\n",
|
||||
y,display_height);
|
||||
y=(int)display_height;
|
||||
}
|
||||
|
||||
con_printf(CON_DEBUG, "RPi: display resolution %ux%u, game resolution: %dx%d (%s)\n", display_width, display_height, x, y, (video_flags & SDL_FULLSCREEN)?"fullscreen":"windowed");
|
||||
if (video_flags & SDL_FULLSCREEN) {
|
||||
/* scale to the full display size... */
|
||||
dst_rect.x = 0;
|
||||
dst_rect.y = 0;
|
||||
dst_rect.width = display_width;
|
||||
dst_rect.height= display_height;
|
||||
} else {
|
||||
/* TODO: we could query the position of the X11 window here
|
||||
and try to place the ovelray exactly above that...,
|
||||
we would have to track window movements, though ... */
|
||||
dst_rect.x = 0;
|
||||
dst_rect.y = 0;
|
||||
dst_rect.width = (uint32_t)x;
|
||||
dst_rect.height= (uint32_t)y;
|
||||
}
|
||||
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
src_rect.width = ((uint32_t)x)<< 16;
|
||||
src_rect.height =((uint32_t)y)<< 16;
|
||||
|
||||
/* we do not want our overlay to be blended against the background */
|
||||
alpha_descriptor.flags=DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS;
|
||||
alpha_descriptor.opacity=0xffffffff;
|
||||
alpha_descriptor.mask=0;
|
||||
|
||||
// open display, if we do not already have one ...
|
||||
if (dispman_display == DISPMANX_NO_HANDLE) {
|
||||
con_printf(CON_DEBUG, "RPi: opening display: %u\n",rpi_display_device);
|
||||
dispman_display = vc_dispmanx_display_open(rpi_display_device);
|
||||
if (dispman_display == DISPMANX_NO_HANDLE) {
|
||||
con_printf(CON_URGENT,"RPi: failed to open display: %u\n",rpi_display_device);
|
||||
}
|
||||
}
|
||||
|
||||
if (dispman_element != DISPMANX_NO_HANDLE) {
|
||||
if (!update) {
|
||||
// if the element already exists, and we cannot update it, so recreate it
|
||||
rpi_destroy_element();
|
||||
}
|
||||
} else {
|
||||
// if the element does not exist, we cannot do an update
|
||||
update=0;
|
||||
}
|
||||
|
||||
dispman_update = vc_dispmanx_update_start( 0 );
|
||||
|
||||
if (update) {
|
||||
con_printf(CON_DEBUG, "RPi: updating display manager element\n");
|
||||
vc_dispmanx_element_change_attributes ( dispman_update, nativewindow.element,
|
||||
ELEMENT_CHANGE_DEST_RECT | ELEMENT_CHANGE_SRC_RECT,
|
||||
0 /*layer*/, 0 /*opacity*/,
|
||||
&dst_rect, &src_rect,
|
||||
0 /*mask*/, VC_IMAGE_ROT0 /*transform*/);
|
||||
} else {
|
||||
// create a new element
|
||||
con_printf(CON_DEBUG, "RPi: creating display manager element\n");
|
||||
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
|
||||
0 /*layer*/, &dst_rect, 0 /*src*/,
|
||||
&src_rect, DISPMANX_PROTECTION_NONE,
|
||||
&alpha_descriptor, NULL /*clamp*/,
|
||||
VC_IMAGE_ROT0 /*transform*/);
|
||||
if (dispman_element == DISPMANX_NO_HANDLE) {
|
||||
con_printf(CON_URGENT,"RPi: failed to creat display manager elemenr\n");
|
||||
}
|
||||
nativewindow.element = dispman_element;
|
||||
}
|
||||
nativewindow.width = display_width;
|
||||
nativewindow.height = display_height;
|
||||
vc_dispmanx_update_submit_sync( dispman_update );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // RPI
|
||||
|
||||
#ifdef OGLES
|
||||
void ogles_destroy(void)
|
||||
{
|
||||
if( eglDisplay != EGL_NO_DISPLAY ) {
|
||||
eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT);
|
||||
}
|
||||
|
||||
if (eglContext != EGL_NO_CONTEXT) {
|
||||
con_printf(CON_DEBUG, "EGL: destroyig context\n");
|
||||
eglDestroyContext(eglDisplay, eglContext);
|
||||
eglContext = EGL_NO_CONTEXT;
|
||||
}
|
||||
|
||||
if (eglSurface != EGL_NO_SURFACE) {
|
||||
con_printf(CON_DEBUG, "EGL: destroyig surface\n");
|
||||
eglDestroySurface(eglDisplay, eglSurface);
|
||||
eglSurface = EGL_NO_SURFACE;
|
||||
}
|
||||
|
||||
if (eglDisplay != EGL_NO_DISPLAY) {
|
||||
con_printf(CON_DEBUG, "EGL: terminating\n");
|
||||
eglTerminate(eglDisplay);
|
||||
eglDisplay = EGL_NO_DISPLAY;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
int ogl_init_window(int x, int y)
|
||||
{
|
||||
int use_x,use_y,use_bpp;
|
||||
Uint32 use_flags;
|
||||
|
||||
#ifdef OGLES
|
||||
SDL_SysWMinfo info;
|
||||
Window x11Window = 0;
|
||||
|
@ -117,10 +298,16 @@ int ogl_init_window(int x, int y)
|
|||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT,
|
||||
EGL_NONE
|
||||
EGL_NONE, EGL_NONE
|
||||
};
|
||||
|
||||
// explicitely request an OpenGL ES 1.x context
|
||||
EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 1, EGL_NONE, EGL_NONE };
|
||||
// explicitely request a doublebuffering window
|
||||
EGLint winAttribs[] = { EGL_RENDER_BUFFER, EGL_BACK_BUFFER, EGL_NONE, EGL_NONE };
|
||||
|
||||
int iConfigs;
|
||||
#endif
|
||||
#endif // OGLES
|
||||
|
||||
if (gl_initialized)
|
||||
ogl_smash_texture_list_internal();//if we are or were fullscreen, changing vid mode will invalidate current textures
|
||||
|
@ -128,18 +315,38 @@ int ogl_init_window(int x, int y)
|
|||
SDL_WM_SetCaption(DESCENT_VERSION, "Descent");
|
||||
SDL_WM_SetIcon( SDL_LoadBMP( "d1x-rebirth.bmp" ), NULL );
|
||||
|
||||
if (!SDL_SetVideoMode(x, y, GameArg.DbgBpp, sdl_video_flags))
|
||||
use_x=x;
|
||||
use_y=y;
|
||||
use_bpp=GameArg.DbgBpp;
|
||||
use_flags=sdl_video_flags;
|
||||
if (sdl_no_modeswitch) {
|
||||
const SDL_VideoInfo *vinfo=SDL_GetVideoInfo();
|
||||
if (vinfo) {
|
||||
use_x=vinfo->current_w;
|
||||
use_y=vinfo->current_h;
|
||||
use_bpp=vinfo->vfmt->BitsPerPixel;
|
||||
use_flags=SDL_SWSURFACE | SDL_ANYFORMAT;
|
||||
} else {
|
||||
con_printf(CON_URGENT, "Could not query video info\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (!SDL_SetVideoMode(use_x, use_y, use_bpp, use_flags))
|
||||
{
|
||||
#ifdef RPI
|
||||
con_printf(CON_URGENT, "Could not set %dx%dx%d opengl video mode: %s\n (Ignored for RPI)",
|
||||
x, y, GameArg.DbgBpp, SDL_GetError());
|
||||
#else
|
||||
Error("Could not set %dx%dx%d opengl video mode: %s\n", x, y, GameArg.DbgBpp, SDL_GetError());
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef OGLES
|
||||
if( eglSurface || eglContext || eglDisplay )
|
||||
{
|
||||
eglMakeCurrent(eglDisplay, NULL, NULL, EGL_NO_CONTEXT);
|
||||
eglDestroyContext(eglDisplay, eglContext);
|
||||
eglDestroySurface(eglDisplay, eglSurface);
|
||||
}
|
||||
#ifndef RPI
|
||||
// NOTE: on the RPi, the EGL stuff is not connected to the X11 window,
|
||||
// so there is no need to destroy and recreate this
|
||||
ogles_destroy();
|
||||
#endif
|
||||
|
||||
SDL_VERSION(&info.version);
|
||||
|
||||
|
@ -147,42 +354,67 @@ int ogl_init_window(int x, int y)
|
|||
if (info.subsystem == SDL_SYSWM_X11) {
|
||||
x11Display = info.info.x11.display;
|
||||
x11Window = info.info.x11.window;
|
||||
printf ("Display: %p, Window: %i ===\n", x11Display, x11Window);
|
||||
con_printf (CON_DEBUG, "Display: %p, Window: %i ===\n", (void*)x11Display, (int)x11Window);
|
||||
}
|
||||
}
|
||||
|
||||
if (eglDisplay == EGL_NO_DISPLAY) {
|
||||
#ifdef RPI
|
||||
eglDisplay = eglGetDisplay((EGLNativeDisplayType)EGL_DEFAULT_DISPLAY);
|
||||
#else
|
||||
eglDisplay = eglGetDisplay((EGLNativeDisplayType)x11Display);
|
||||
#endif
|
||||
if (eglDisplay == EGL_NO_DISPLAY) {
|
||||
con_printf(CON_URGENT, "EGL: Error querying EGL Display\n");
|
||||
}
|
||||
|
||||
if (!eglInitialize(eglDisplay, &ver_maj, &ver_min)) {
|
||||
con_printf(CON_URGENT, "EGL: Error initializing EGL\n");
|
||||
} else {
|
||||
con_printf(CON_DEBUG, "EGL: Initialized, version: major %i minor %i\n", ver_maj, ver_min);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifdef RPI
|
||||
if (rpi_setup_element(x,y,sdl_video_flags,1)) {
|
||||
Error("RPi: Could not set up a %dx%d element\n", x, y);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (eglSurface == EGL_NO_SURFACE) {
|
||||
if (!eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
|
||||
con_printf(CON_URGENT, "EGL: Error choosing config\n");
|
||||
} else {
|
||||
con_printf(CON_DEBUG, "EGL: config chosen\n");
|
||||
}
|
||||
|
||||
#ifdef RPI
|
||||
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (EGLNativeWindowType)&nativewindow, winAttribs);
|
||||
#else
|
||||
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)x11Window, winAttribs);
|
||||
#endif
|
||||
if ((!TestEGLError("eglCreateWindowSurface")) || eglSurface == EGL_NO_SURFACE) {
|
||||
con_printf(CON_URGENT, "EGL: Error creating window surface\n");
|
||||
} else {
|
||||
con_printf(CON_DEBUG, "EGL: Created window surface\n");
|
||||
}
|
||||
}
|
||||
|
||||
eglDisplay = eglGetDisplay((NativeDisplayType)x11Display);
|
||||
if (!eglInitialize(eglDisplay, &ver_maj, &ver_min)) {
|
||||
con_printf(CON_URGENT, "EGL: Error initializing EGL\n");
|
||||
} else {
|
||||
con_printf(CON_URGENT, "EGL: Initialized, version: major %i minor %i\n", ver_maj, ver_min);
|
||||
}
|
||||
|
||||
if (!eglChooseConfig(eglDisplay, configAttribs, &eglConfig, 1, &iConfigs) || (iConfigs != 1)) {
|
||||
con_printf(CON_URGENT, "EGL: Error choosing config\n");
|
||||
} else {
|
||||
con_printf(CON_URGENT, "EGL: Choosed config\n", ver_maj, ver_min);
|
||||
}
|
||||
|
||||
eglSurface = eglCreateWindowSurface(eglDisplay, eglConfig, (NativeWindowType)x11Window, NULL);
|
||||
if (!TestEGLError("eglCreateWindowSurface")) {
|
||||
con_printf(CON_URGENT, "EGL: Error creating window surface\n");
|
||||
} else {
|
||||
con_printf(CON_URGENT, "EGL: Created window surface\n");
|
||||
}
|
||||
|
||||
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, NULL);
|
||||
if (!TestEGLError("eglCreateContext")) {
|
||||
con_printf(CON_URGENT, "EGL: Error creating context\n");
|
||||
} else {
|
||||
con_printf(CON_URGENT, "EGL: Created context\n");
|
||||
if (eglContext == EGL_NO_CONTEXT) {
|
||||
eglContext = eglCreateContext(eglDisplay, eglConfig, EGL_NO_CONTEXT, contextAttribs);
|
||||
if ((!TestEGLError("eglCreateContext")) || eglContext == EGL_NO_CONTEXT) {
|
||||
con_printf(CON_URGENT, "EGL: Error creating context\n");
|
||||
} else {
|
||||
con_printf(CON_DEBUG, "EGL: Created context\n");
|
||||
}
|
||||
}
|
||||
|
||||
eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext);
|
||||
if (!TestEGLError("eglMakeCurrent")) {
|
||||
con_printf(CON_URGENT, "EGL: Error making current\n");
|
||||
} else {
|
||||
con_printf(CON_URGENT, "EGL: Created current\n");
|
||||
con_printf(CON_DEBUG, "EGL: made context current\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -206,15 +438,22 @@ int gr_toggle_fullscreen(void)
|
|||
|
||||
if (gl_initialized)
|
||||
{
|
||||
if (!SDL_VideoModeOK(SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, sdl_video_flags))
|
||||
{
|
||||
con_printf(CON_URGENT,"Cannot set %ix%i. Fallback to 640x480\n",SM_W(Game_screen_mode), SM_H(Game_screen_mode));
|
||||
Game_screen_mode=SM(640,480);
|
||||
if (sdl_no_modeswitch == 0) {
|
||||
if (!SDL_VideoModeOK(SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, sdl_video_flags))
|
||||
{
|
||||
con_printf(CON_URGENT,"Cannot set %ix%i. Fallback to 640x480\n",SM_W(Game_screen_mode), SM_H(Game_screen_mode));
|
||||
Game_screen_mode=SM(640,480);
|
||||
}
|
||||
if (!SDL_SetVideoMode(SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, sdl_video_flags))
|
||||
{
|
||||
Error("Could not set %dx%dx%d opengl video mode: %s\n", SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, SDL_GetError());
|
||||
}
|
||||
}
|
||||
if (!SDL_SetVideoMode(SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, sdl_video_flags))
|
||||
{
|
||||
Error("Could not set %dx%dx%d opengl video mode: %s\n", SM_W(Game_screen_mode), SM_H(Game_screen_mode), GameArg.DbgBpp, SDL_GetError());
|
||||
#ifdef RPI
|
||||
if (rpi_setup_element(SM_W(Game_screen_mode), SM_H(Game_screen_mode), sdl_video_flags, 1)) {
|
||||
Error("RPi: Could not set up %dx%d element\n", SM_W(Game_screen_mode), SM_H(Game_screen_mode));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (gl_initialized) // update viewing values for menus
|
||||
|
@ -328,6 +567,11 @@ int gr_list_modes( u_int32_t gsmodes[] )
|
|||
int sdl_check_flags = SDL_OPENGL | SDL_FULLSCREEN; // always use Fullscreen as lead.
|
||||
#endif
|
||||
|
||||
if (sdl_no_modeswitch) {
|
||||
/* TODO: we could use the tvservice to list resolutions on the RPi */
|
||||
return 0;
|
||||
}
|
||||
|
||||
modes = SDL_ListModes(NULL, sdl_check_flags);
|
||||
|
||||
if (modes == (SDL_Rect**)0) // check if we get any modes - if not, return 0
|
||||
|
@ -361,7 +605,12 @@ int gr_check_mode(u_int32_t mode)
|
|||
w=SM_W(mode);
|
||||
h=SM_H(mode);
|
||||
|
||||
return SDL_VideoModeOK(w, h, GameArg.DbgBpp, sdl_video_flags);
|
||||
if (sdl_no_modeswitch == 0) {
|
||||
return SDL_VideoModeOK(w, h, GameArg.DbgBpp, sdl_video_flags);
|
||||
} else {
|
||||
// just tell the caller that any mode is valid...
|
||||
return 32;
|
||||
}
|
||||
}
|
||||
|
||||
int gr_set_mode(u_int32_t mode)
|
||||
|
@ -470,12 +719,32 @@ void gr_set_attributes(void)
|
|||
|
||||
int gr_init(int mode)
|
||||
{
|
||||
#ifdef RPI
|
||||
char sdl_driver[32];
|
||||
char *sdl_driver_ret;
|
||||
#endif
|
||||
|
||||
int retcode;
|
||||
|
||||
// Only do this function once!
|
||||
if (gr_installed==1)
|
||||
return -1;
|
||||
|
||||
#ifdef RPI
|
||||
// Initialize the broadcom host library
|
||||
// we have to call this before we can create an OpenGL ES context
|
||||
bcm_host_init();
|
||||
|
||||
// Check if we are running with SDL directfb driver ...
|
||||
sdl_driver_ret=SDL_VideoDriverName(sdl_driver,32);
|
||||
if (sdl_driver_ret) {
|
||||
if (strcmp(sdl_driver_ret,"x11")) {
|
||||
con_printf(CON_URGENT,"RPi: activating hack for console driver\n");
|
||||
sdl_no_modeswitch=1;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
ogl_init_load_library();
|
||||
#endif
|
||||
|
@ -534,6 +803,19 @@ void gr_close()
|
|||
if (ogl_rt_loaded)
|
||||
OpenGL_LoadLibrary(false);
|
||||
#endif
|
||||
|
||||
#ifdef OGLES
|
||||
ogles_destroy();
|
||||
#ifdef RPI
|
||||
con_printf(CON_DEBUG, "RPi: cleanuing up\n");
|
||||
if (dispman_display != DISPMANX_NO_HANDLE) {
|
||||
rpi_destroy_element();
|
||||
con_printf(CON_DEBUG, "RPi: closing display\n");
|
||||
vc_dispmanx_display_close(dispman_display);
|
||||
dispman_display = DISPMANX_NO_HANDLE;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
extern int r_upixelc;
|
||||
|
|
Loading…
Reference in a new issue