OpenGL-ES converstion
Specific device options for pandora, gcw, gph
This commit is contained in:
parent
5e85fbc8b9
commit
70eef55ab5
|
@ -0,0 +1,701 @@
|
|||
/**
|
||||
*
|
||||
* EGLPORT.C
|
||||
* Copyright (C) 2011-2013 Scott R. Smith
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "eglport.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if defined(USE_EGL_SDL)
|
||||
#include "SDL.h"
|
||||
#include "SDL_syswm.h"
|
||||
SDL_SysWMinfo sysWmInfo; /** Holds our X Display/Window information */
|
||||
#endif /* USE_EGL_SDL */
|
||||
|
||||
#if defined(PANDORA) /* Pandora VSync Support */
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/fb.h>
|
||||
|
||||
#ifndef FBIO_WAITFORVSYNC
|
||||
#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
|
||||
#endif
|
||||
int fbdev = -1;
|
||||
|
||||
#elif defined(RPI)
|
||||
#include "bcm_host.h"
|
||||
|
||||
#endif
|
||||
|
||||
enum EGL_RENDER_T {
|
||||
RENDER_RAW=0, /** Sets render mode to raw or framebuffer mode. */
|
||||
RENDER_SDL, /** Sets render mode to X11/SDL mode. */
|
||||
RENDER_TOTAL
|
||||
};
|
||||
|
||||
enum EGL_SETTINGS_T {
|
||||
CFG_MODE=0, /** Render mode for EGL 0=RAW 1=SDL. */
|
||||
CFG_VSYNC, /** Controls system vsync if available. */
|
||||
CFG_FSAA, /** Number of samples for full screen AA. 0 is off, 2/4 samples. */
|
||||
CFG_FPS, /** Calculate and report frame per second. */
|
||||
CFG_RED_SIZE, /** Number of bits of Red in the color buffer. */
|
||||
CFG_GREEN_SIZE, /** Number of bits of Green in the color buffer. */
|
||||
CFG_BLUE_SIZE, /** Number of bits of Blue in the color buffer. */
|
||||
CFG_ALPHA_SIZE, /** Number of bits of Alpha in the color buffer. */
|
||||
CFG_DEPTH_SIZE, /** Number of bits of Z in the depth buffer. */
|
||||
CFG_BUFFER_SIZE, /** The total color component bits in the color buffer. */
|
||||
CFG_STENCIL_SIZE, /** Number of bits of Stencil in the stencil buffer. */
|
||||
CFG_TOTAL /** Total number of settings. */
|
||||
};
|
||||
|
||||
NativeDisplayType nativeDisplay = 0; /** Reference to the systems native display */
|
||||
NativeWindowType nativeWindow = 0; /** Reference to the systems native window */
|
||||
EGLint eglSettings[CFG_TOTAL]; /** Stores setting values. */
|
||||
EGLDisplay eglDisplay = NULL; /** Reference to the EGL display */
|
||||
EGLConfig eglConfig = NULL; /** Reference to the EGL config */
|
||||
EGLContext eglContext = NULL; /** Reference to the EGL context */
|
||||
EGLSurface eglSurface = NULL; /** Reference to the EGL surface */
|
||||
|
||||
#define totalConfigsIn 5 /** Total number of configurations to request */
|
||||
EGLint totalConfigsFound = 0; /** Total number of configurations matching attributes */
|
||||
EGLConfig eglConfigs[totalConfigsIn]; /** Structure containing references to matching configurations */
|
||||
|
||||
uint32_t fpsCount = 0; /** Total number of frames counted */
|
||||
uint32_t fpsTime = 0; /** Start time of frame count measurment */
|
||||
|
||||
/** Private API */
|
||||
void OpenCfg ( const char* file );
|
||||
int8_t ConfigureEGL ( EGLConfig config );
|
||||
int8_t FindEGLConfigs ( void );
|
||||
int8_t CheckEGLErrors ( const char* file, uint16_t line );
|
||||
|
||||
int8_t GetNativeDisplay ( void );
|
||||
int8_t GetNativeWindow ( uint16_t width, uint16_t height );
|
||||
void FreeNativeDisplay ( void );
|
||||
void FreeNativeWindow ( void );
|
||||
|
||||
void Platform_Open ( void );
|
||||
void Platform_Close ( void );
|
||||
void Platform_VSync ( void );
|
||||
uint32_t Platform_GetTicks ( void );
|
||||
|
||||
/** @brief Release all EGL and system resources
|
||||
*/
|
||||
void EGL_Close( void )
|
||||
{
|
||||
/* Release EGL resources */
|
||||
if (eglDisplay != NULL)
|
||||
{
|
||||
peglMakeCurrent( eglDisplay, NULL, NULL, EGL_NO_CONTEXT );
|
||||
if (eglContext != NULL) {
|
||||
peglDestroyContext( eglDisplay, eglContext );
|
||||
}
|
||||
if (eglSurface != NULL) {
|
||||
peglDestroySurface( eglDisplay, eglSurface );
|
||||
}
|
||||
peglTerminate( eglDisplay );
|
||||
}
|
||||
|
||||
eglSurface = NULL;
|
||||
eglContext = NULL;
|
||||
eglDisplay = NULL;
|
||||
|
||||
/* Release platform resources */
|
||||
FreeNativeWindow();
|
||||
FreeNativeDisplay();
|
||||
Platform_Close();
|
||||
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
|
||||
printf( "EGLport: Closed\n" );
|
||||
}
|
||||
|
||||
/** @brief Swap the surface buffer onto the display
|
||||
*/
|
||||
void EGL_SwapBuffers( void )
|
||||
{
|
||||
if (eglSettings[CFG_VSYNC] != 0) {
|
||||
Platform_VSync();
|
||||
}
|
||||
|
||||
peglSwapBuffers( eglDisplay, eglSurface );
|
||||
|
||||
if (eglSettings[CFG_FPS] != 0) {
|
||||
fpsCount++;
|
||||
|
||||
if (fpsTime - Platform_GetTicks() >= 1000)
|
||||
{
|
||||
printf( "EGLport: %d fps\n", fpsCount );
|
||||
fpsTime = Platform_GetTicks();
|
||||
fpsCount = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Obtain the system display and initialize EGL
|
||||
* @param width : desired pixel width of the window (not used by all platforms)
|
||||
* @param height : desired pixel height of the window (not used by all platforms)
|
||||
* @return : 0 if the function passed, else 1
|
||||
*/
|
||||
int8_t EGL_Open( uint16_t width, uint16_t height )
|
||||
{
|
||||
EGLint eglMajorVer, eglMinorVer;
|
||||
EGLBoolean result;
|
||||
uint32_t configIndex = 0;
|
||||
const char* output;
|
||||
|
||||
static const EGLint contextAttribs[] =
|
||||
{
|
||||
#if defined(USE_GLES2)
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
#endif
|
||||
EGL_NONE
|
||||
};
|
||||
|
||||
#if defined(DEBUG)
|
||||
printf( "EGLport Warning: DEBUG is enabled which may effect performance\n" );
|
||||
#endif
|
||||
|
||||
/* Check that system is not open */
|
||||
if (eglDisplay != NULL || eglContext != NULL || eglSurface != NULL)
|
||||
{
|
||||
printf( "EGLport Warning: EGL system is already open!\n" );
|
||||
peglMakeCurrent( eglDisplay, NULL, NULL, EGL_NO_CONTEXT );
|
||||
peglDestroyContext( eglDisplay, eglContext );
|
||||
peglDestroySurface( eglDisplay, eglSurface );
|
||||
peglTerminate( eglDisplay );
|
||||
|
||||
eglSurface = NULL;
|
||||
eglContext = NULL;
|
||||
eglDisplay = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check for the cfg file to alternative settings */
|
||||
OpenCfg( "eglport.cfg" );
|
||||
|
||||
/* Setup any platform specific bits */
|
||||
Platform_Open();
|
||||
|
||||
printf( "EGLport: Opening EGL native splay\n" );
|
||||
if (GetNativeDisplay() != 0)
|
||||
{
|
||||
printf( "EGLport ERROR: Unable to obtain native display!\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "EGLport: Opening native window surface\n" );
|
||||
if (GetNativeWindow( width, height ) != 0)
|
||||
{
|
||||
printf( "EGLport ERROR: Unable to obtain native window!\n" );
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
printf( "EGLport: Opening EGL display\n" );
|
||||
eglDisplay = peglGetDisplay( nativeDisplay );
|
||||
if (eglDisplay == EGL_NO_DISPLAY)
|
||||
{
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
printf( "EGLport ERROR: Unable to create EGL display.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "EGLport: Initializing\n" );
|
||||
result = peglInitialize( eglDisplay, &eglMajorVer, &eglMinorVer );
|
||||
if (result != EGL_TRUE )
|
||||
{
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
printf( "EGLport ERROR: Unable to initialize EGL display.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Get EGL Library Information */
|
||||
printf( "EGL Implementation Version: Major %d Minor %d\n", eglMajorVer, eglMinorVer );
|
||||
output = peglQueryString( eglDisplay, EGL_VENDOR );
|
||||
printf( "EGL_VENDOR: %s\n", output );
|
||||
output = peglQueryString( eglDisplay, EGL_VERSION );
|
||||
printf( "EGL_VERSION: %s\n", output );
|
||||
output = peglQueryString( eglDisplay, EGL_EXTENSIONS );
|
||||
printf( "EGL_EXTENSIONS: %s\n", output );
|
||||
|
||||
if (FindEGLConfigs() != 0)
|
||||
{
|
||||
printf( "EGLport ERROR: Unable to configure EGL. See previous error.\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "EGLport: Using Config %d\n", configIndex );
|
||||
#if defined(EGL_VERSION_1_2)
|
||||
/* Bind GLES and create the context */
|
||||
printf( "EGLport: Binding API\n" );
|
||||
result = peglBindAPI( EGL_OPENGL_ES_API );
|
||||
if ( result == EGL_FALSE )
|
||||
{
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
printf( "EGLport ERROR: Could not bind EGL API.\n" );
|
||||
return 1;
|
||||
}
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
|
||||
printf( "EGLport: Creating Context\n" );
|
||||
eglContext = peglCreateContext( eglDisplay, eglConfigs[configIndex], NULL, contextAttribs );
|
||||
if (eglContext == EGL_NO_CONTEXT)
|
||||
{
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
printf( "EGLport ERROR: Unable to create GLES context!\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "EGLport: Creating window surface\n" );
|
||||
eglSurface = peglCreateWindowSurface( eglDisplay, eglConfigs[configIndex], nativeWindow, 0 );
|
||||
if (eglSurface == EGL_NO_SURFACE)
|
||||
{
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
printf( "EGLport ERROR: Unable to create EGL surface!\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "EGLport: Making Current\n" );
|
||||
result = peglMakeCurrent( eglDisplay, eglSurface, eglSurface, eglContext );
|
||||
if (result != EGL_TRUE)
|
||||
{
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
printf( "EGLport ERROR: Unable to make GLES context current\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
printf( "EGLport: Setting swap interval\n" );
|
||||
peglSwapInterval( eglDisplay, (eglSettings[CFG_VSYNC] > 0) ? 1 : 0 );
|
||||
|
||||
printf( "EGLport: Complete\n" );
|
||||
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Read settings that configure how to use EGL
|
||||
* @param file : name of the config file
|
||||
*/
|
||||
void OpenCfg ( const char* file )
|
||||
{
|
||||
#define MAX_STRING 20
|
||||
#define MAX_SIZE 100
|
||||
uint8_t i;
|
||||
FILE* fp = NULL;
|
||||
char* location = NULL;
|
||||
char eglStrings[CFG_TOTAL][MAX_STRING];
|
||||
char buffer[MAX_SIZE];
|
||||
|
||||
strncpy( eglStrings[CFG_MODE], "egl_mode=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_VSYNC], "use_vsync=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_FSAA], "use_fsaa=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_FPS], "use_fsp=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_RED_SIZE], "size_red=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_GREEN_SIZE], "size_green=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_BLUE_SIZE], "size_blue=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_ALPHA_SIZE], "size_alpha=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_DEPTH_SIZE], "size_depth=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_BUFFER_SIZE], "size_buffer=", MAX_STRING );
|
||||
strncpy( eglStrings[CFG_STENCIL_SIZE], "size_stencil=", MAX_STRING );
|
||||
|
||||
/* Set defaults */
|
||||
#if defined(USE_EGL_SDL)
|
||||
eglSettings[CFG_MODE] = RENDER_SDL;
|
||||
#else
|
||||
eglSettings[CFG_MODE] = RENDER_RAW;
|
||||
#endif
|
||||
eglSettings[CFG_VSYNC] = 0;
|
||||
eglSettings[CFG_FSAA] = 0;
|
||||
eglSettings[CFG_FPS] = 0;
|
||||
eglSettings[CFG_RED_SIZE] = 5;
|
||||
eglSettings[CFG_GREEN_SIZE] = 6;
|
||||
eglSettings[CFG_BLUE_SIZE] = 5;
|
||||
eglSettings[CFG_ALPHA_SIZE] = 0;
|
||||
eglSettings[CFG_DEPTH_SIZE] = 16;
|
||||
eglSettings[CFG_BUFFER_SIZE] = 16;
|
||||
eglSettings[CFG_STENCIL_SIZE] = 0;
|
||||
|
||||
/* Parse INI file */
|
||||
fp = fopen( file, "r");
|
||||
if (fp != NULL)
|
||||
{
|
||||
while (fgets( buffer, MAX_SIZE, fp ) != NULL)
|
||||
{
|
||||
for (i=0; i<CFG_TOTAL; i++)
|
||||
{
|
||||
location = strstr( buffer, eglStrings[i] );
|
||||
if (location != NULL)
|
||||
{
|
||||
eglSettings[i] = atol( location+strlen( eglStrings[i] ) );
|
||||
printf( "EGLport: %s set to %d.\n", eglStrings[i], eglSettings[i] );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fclose( fp );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "EGL ERROR: Unable to read ini settings from file '%s'. Using defaults\n", file );
|
||||
}
|
||||
}
|
||||
|
||||
/** @brief Find a EGL configuration tht matches the defined attributes
|
||||
* @return : 0 if the function passed, else 1
|
||||
*/
|
||||
int8_t FindEGLConfigs( void )
|
||||
{
|
||||
EGLBoolean result;
|
||||
int attrib = 0;
|
||||
EGLint ConfigAttribs[23];
|
||||
|
||||
ConfigAttribs[attrib++] = EGL_RED_SIZE; /* 1 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_RED_SIZE]; /* 2 */
|
||||
ConfigAttribs[attrib++] = EGL_GREEN_SIZE; /* 3 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_GREEN_SIZE]; /* 4 */
|
||||
ConfigAttribs[attrib++] = EGL_BLUE_SIZE; /* 5 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_BLUE_SIZE]; /* 6 */
|
||||
ConfigAttribs[attrib++] = EGL_ALPHA_SIZE; /* 7 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_ALPHA_SIZE]; /* 8 */
|
||||
ConfigAttribs[attrib++] = EGL_DEPTH_SIZE; /* 9 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_DEPTH_SIZE]; /* 10 */
|
||||
ConfigAttribs[attrib++] = EGL_BUFFER_SIZE; /* 11 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_BUFFER_SIZE]; /* 12 */
|
||||
ConfigAttribs[attrib++] = EGL_STENCIL_SIZE; /* 13 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_STENCIL_SIZE]; /* 14 */
|
||||
ConfigAttribs[attrib++] = EGL_SURFACE_TYPE; /* 15 */
|
||||
ConfigAttribs[attrib++] = EGL_WINDOW_BIT; /* 16 */
|
||||
#if defined(EGL_VERSION_1_2)
|
||||
ConfigAttribs[attrib++] = EGL_RENDERABLE_TYPE; /* 17 */
|
||||
#if defined(USE_GLES1)
|
||||
ConfigAttribs[attrib++] = EGL_OPENGL_ES_BIT;
|
||||
#elif defined(USE_GLES2)
|
||||
ConfigAttribs[attrib++] = EGL_OPENGL_ES2_BIT; /* 18 */
|
||||
#endif /* USE_GLES1 */
|
||||
#endif /* EGL_VERSION_1_2 */
|
||||
ConfigAttribs[attrib++] = EGL_SAMPLE_BUFFERS; /* 19 */
|
||||
ConfigAttribs[attrib++] = (eglSettings[CFG_FSAA] > 0) ? 1 : 0; /* 20 */
|
||||
ConfigAttribs[attrib++] = EGL_SAMPLES; /* 21 */
|
||||
ConfigAttribs[attrib++] = eglSettings[CFG_FSAA]; /* 22 */
|
||||
ConfigAttribs[attrib++] = EGL_NONE; /* 23 */
|
||||
|
||||
result = peglChooseConfig( eglDisplay, ConfigAttribs, eglConfigs, totalConfigsIn, &totalConfigsFound );
|
||||
if (result != EGL_TRUE || totalConfigsFound == 0)
|
||||
{
|
||||
CheckEGLErrors( __FILE__, __LINE__ );
|
||||
printf( "EGLport ERROR: Unable to query for available configs, found %d.\n", totalConfigsFound );
|
||||
return 1;
|
||||
}
|
||||
printf( "EGLport: Found %d available configs\n", totalConfigsFound );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Error checking function
|
||||
* @param file : string reference that contains the source file that the check is occuring in
|
||||
* @param line : numeric reference that contains the line number that the check is occuring in
|
||||
* @return : 0 if the function passed, else 1
|
||||
*/
|
||||
int8_t CheckEGLErrors( const char* file, uint16_t line )
|
||||
{
|
||||
EGLenum error;
|
||||
const char* errortext;
|
||||
const char* description;
|
||||
|
||||
error = eglGetError();
|
||||
|
||||
if (error != EGL_SUCCESS && error != 0)
|
||||
{
|
||||
switch (error)
|
||||
{
|
||||
case EGL_NOT_INITIALIZED:
|
||||
errortext = "EGL_NOT_INITIALIZED.";
|
||||
description = "EGL is not or could not be initialized, for the specified display.";
|
||||
break;
|
||||
case EGL_BAD_ACCESS:
|
||||
errortext = "EGL_BAD_ACCESS EGL";
|
||||
description = "cannot access a requested resource (for example, a context is bound in another thread).";
|
||||
break;
|
||||
case EGL_BAD_ALLOC:
|
||||
errortext = "EGL_BAD_ALLOC EGL";
|
||||
description = "failed to allocate resources for the requested operation.";
|
||||
break;
|
||||
case EGL_BAD_ATTRIBUTE:
|
||||
errortext = "EGL_BAD_ATTRIBUTE";
|
||||
description = "An unrecognized attribute or attribute value was passed in anattribute list.";
|
||||
break;
|
||||
case EGL_BAD_CONFIG:
|
||||
errortext = "EGL_BAD_CONFIG";
|
||||
description = "An EGLConfig argument does not name a valid EGLConfig.";
|
||||
break;
|
||||
case EGL_BAD_CONTEXT:
|
||||
errortext = "EGL_BAD_CONTEXT";
|
||||
description = "An EGLContext argument does not name a valid EGLContext.";
|
||||
break;
|
||||
case EGL_BAD_CURRENT_SURFACE:
|
||||
errortext = "EGL_BAD_CURRENT_SURFACE";
|
||||
description = "The current surface of the calling thread is a window, pbuffer,or pixmap that is no longer valid.";
|
||||
break;
|
||||
case EGL_BAD_DISPLAY:
|
||||
errortext = "EGL_BAD_DISPLAY";
|
||||
description = "An EGLDisplay argument does not name a valid EGLDisplay.";
|
||||
break;
|
||||
case EGL_BAD_MATCH:
|
||||
errortext = "EGL_BAD_MATCH";
|
||||
description = "Arguments are inconsistent; for example, an otherwise valid context requires buffers (e.g. depth or stencil) not allocated by an otherwise valid surface.";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_PIXMAP:
|
||||
errortext = "EGL_BAD_NATIVE_PIXMAP";
|
||||
description = "An EGLNativePixmapType argument does not refer to a validnative pixmap.";
|
||||
break;
|
||||
case EGL_BAD_NATIVE_WINDOW:
|
||||
errortext = "EGL_BAD_NATIVE_WINDOW";
|
||||
description = "An EGLNativeWindowType argument does not refer to a validnative window.";
|
||||
break;
|
||||
case EGL_BAD_PARAMETER:
|
||||
errortext = "EGL_BAD_PARAMETER";
|
||||
description = "One or more argument values are invalid.";
|
||||
break;
|
||||
case EGL_BAD_SURFACE:
|
||||
errortext = "EGL_BAD_SURFACE";
|
||||
description = "An EGLSurface argument does not name a valid surface (window,pbuffer, or pixmap) configured for rendering";
|
||||
break;
|
||||
case EGL_CONTEXT_LOST:
|
||||
errortext = "EGL_CONTEXT_LOST";
|
||||
description = "A power management event has occurred. The application mustdestroy all contexts and reinitialise client API state and objects to continue rendering.";
|
||||
break;
|
||||
default:
|
||||
errortext = "Unknown EGL Error";
|
||||
description = "";
|
||||
break;
|
||||
}
|
||||
|
||||
printf( "EGLport ERROR: EGL Error detected in file %s at line %d: %s (0x%X)\n Description: %s\n", file, line, errortext, error, description );
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Obtain a reference to the system's native display
|
||||
* @param window : pointer to save the display reference
|
||||
* @return : 0 if the function passed, else 1
|
||||
*/
|
||||
int8_t GetNativeDisplay( void )
|
||||
{
|
||||
if (eglSettings[CFG_MODE] == RENDER_RAW) /* RAW FB mode */
|
||||
{
|
||||
printf( "EGLport: Using EGL_DEFAULT_DISPLAY\n" );
|
||||
nativeDisplay = EGL_DEFAULT_DISPLAY;
|
||||
}
|
||||
else if (eglSettings[CFG_MODE] == RENDER_SDL) /* SDL/X11 mode */
|
||||
{
|
||||
#if defined(USE_EGL_SDL)
|
||||
printf( "EGLport: Opening SDL/X11 display\n" );
|
||||
SDL_VERSION(&sysWmInfo.version);
|
||||
SDL_GetWMInfo(&sysWmInfo);
|
||||
nativeDisplay = (EGLNativeDisplayType)sysWmInfo.info.x11.display;
|
||||
|
||||
if (nativeDisplay == 0)
|
||||
{
|
||||
printf( "EGLport ERROR: unable to get display!\n" );
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
|
||||
#endif
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Obtain a reference to the system's native window
|
||||
* @param width : desired pixel width of the window (not used by all platforms)
|
||||
* @param height : desired pixel height of the window (not used by all platforms)
|
||||
* @return : 0 if the function passed, else 1
|
||||
*/
|
||||
int8_t GetNativeWindow( uint16_t width, uint16_t height )
|
||||
{
|
||||
nativeWindow = 0;
|
||||
|
||||
#if defined(WIZ) || defined(CAANOO)
|
||||
|
||||
printf( "EGLport: Allocating memory for CAANOO/WIZ\n" );
|
||||
nativeWindow = (NativeWindowType)malloc(16*1024);
|
||||
|
||||
if(nativeWindow == NULL) {
|
||||
printf( "EGLport ERROR: Memory for window Failed\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#elif defined(RPI)
|
||||
|
||||
EGLBoolean result;
|
||||
uint32_t screen_width, screen_height;
|
||||
static EGL_DISPMANX_WINDOW_T nativewindow;
|
||||
DISPMANX_ELEMENT_HANDLE_T dispman_element;
|
||||
DISPMANX_DISPLAY_HANDLE_T dispman_display;
|
||||
DISPMANX_UPDATE_HANDLE_T dispman_update;
|
||||
VC_RECT_T dst_rect;
|
||||
VC_RECT_T src_rect;
|
||||
|
||||
VC_DISPMANX_ALPHA_T alpha = { DISPMANX_FLAGS_ALPHA_FROM_SOURCE | DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,255,0 };
|
||||
|
||||
/* create an EGL window surface */
|
||||
result = graphics_get_display_size(0 /* LCD */, &screen_width, &screen_height);
|
||||
if(result < 0) {
|
||||
printf( "EGLport ERROR: RPi graphicget_display_size failed\n" );
|
||||
return 1;
|
||||
}
|
||||
|
||||
dst_rect.x = 0;
|
||||
dst_rect.y = 0;
|
||||
dst_rect.width = screen_width;
|
||||
dst_rect.height = screen_height;
|
||||
|
||||
src_rect.x = 0;
|
||||
src_rect.y = 0;
|
||||
src_rect.width = width << 16;
|
||||
src_rect.height = height << 16;
|
||||
|
||||
dispman_display = vc_dispmanx_display_open( 0 /* LCD */);
|
||||
dispman_update = vc_dispmanx_update_start( 0 );
|
||||
dispman_element = vc_dispmanx_element_add ( dispman_update, dispman_display,
|
||||
0 /*layer*/, &dst_rect, 0 /*src*/,
|
||||
&src_rect, DISPMANX_PROTECTION_NONE, &alpha /*alpha*/, (DISPMANX_CLAMP_T*)0 /*clamp*/, (DISPMANX_TRANSFORM_T)0 /*transform*/);
|
||||
|
||||
nativewindow.element = dispman_element;
|
||||
nativewindow.width = screen_width;
|
||||
nativewindow.height = screen_height;
|
||||
vc_dispmanx_update_submit_sync( dispman_update );
|
||||
|
||||
nativeWindow = (NativeWindowType)&nativewindow;
|
||||
|
||||
#else /* default */
|
||||
|
||||
if (eglSettings[CFG_MODE] == RENDER_RAW) /* RAW FB mode */
|
||||
{
|
||||
nativeWindow = 0;
|
||||
}
|
||||
else if(eglSettings[CFG_MODE] == RENDER_SDL) /* SDL/X11 mode */
|
||||
{
|
||||
#if defined(USE_EGL_SDL)
|
||||
/* SDL_GetWMInfo is populated when display was opened */
|
||||
nativeWindow = (NativeWindowType)sysWmInfo.info.x11.window;
|
||||
|
||||
if (nativeWindow == 0)
|
||||
{
|
||||
printf( "EGLport ERROR: unable to get window!\n" );
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "EGLport ERROR: Unknown EGL render mode %d!\n", eglSettings[CFG_MODE] );
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* WIZ / CAANOO */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @brief Release the system's native display
|
||||
*/
|
||||
void FreeNativeDisplay( void )
|
||||
{
|
||||
}
|
||||
|
||||
/** @brief Release the system's native window
|
||||
*/
|
||||
void FreeNativeWindow( void )
|
||||
{
|
||||
#if defined(WIZ) || defined(CAANOO)
|
||||
if (nativeWindow != NULL) {
|
||||
free( nativeWindow );
|
||||
}
|
||||
nativeWindow = NULL;
|
||||
#endif /* WIZ / CAANOO */
|
||||
}
|
||||
|
||||
/** @brief Open any system specific resources
|
||||
*/
|
||||
void Platform_Open( void )
|
||||
{
|
||||
#if defined(PANDORA)
|
||||
/* Pandora VSync */
|
||||
fbdev = open( "/dev/fb0", O_RDONLY /* O_RDWR */ );
|
||||
if ( fbdev < 0 ) {
|
||||
printf( "EGLport ERROR: Couldn't open /dev/fb0 for Pandora Vsync\n" );
|
||||
}
|
||||
#elif defined(RPI)
|
||||
bcm_host_init();
|
||||
#endif /* PANDORA */
|
||||
}
|
||||
|
||||
/** @brief Release any system specific resources
|
||||
*/
|
||||
void Platform_Close( void )
|
||||
{
|
||||
#if defined(PANDORA)
|
||||
/* Pandora VSync */
|
||||
close( fbdev );
|
||||
fbdev = -1;
|
||||
#endif /* PANDORA */
|
||||
}
|
||||
|
||||
/** @brief Check the systems vsync state
|
||||
*/
|
||||
void Platform_VSync( void )
|
||||
{
|
||||
#if defined(PANDORA)
|
||||
/* Pandora VSync */
|
||||
if (fbdev >= 0) {
|
||||
int arg = 0;
|
||||
ioctl( fbdev, FBIO_WAITFORVSYNC, &arg );
|
||||
}
|
||||
#endif /* PANDORA */
|
||||
}
|
||||
|
||||
/** @brief Get the system tick time (ms)
|
||||
*/
|
||||
uint32_t Platform_GetTicks( void )
|
||||
{
|
||||
uint32_t ticks = 0;
|
||||
#if defined(USE_EGL_SDL)
|
||||
ticks = SDL_GetTicks();
|
||||
#else
|
||||
printf( "EGLport ERROR: SDL mode was not enabled in this compile!\n" );
|
||||
#endif
|
||||
return ticks;
|
||||
}
|
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
*
|
||||
* EGLPORT.H
|
||||
* Copyright (C) 2011-2013 Scott R. Smith
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef EGLPORT_H
|
||||
#define EGLPORT_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "EGL/egl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** Defines (in every case choose only one) */
|
||||
/** Common: */
|
||||
/** DEBUG : enable additional error monitoring per EGL function call */
|
||||
/** Native display and window system for use with EGL */
|
||||
/** USE_EGL_SDL : used for access to a SDL X11 window */
|
||||
/** Platform: settings that are specific to that device */
|
||||
/** PANDORA (USE_GLES1 or USE_GLES2) */
|
||||
/** WIZ (USE_GLES1) */
|
||||
/** CAANOO (USE_GLES1) */
|
||||
/** RPI (USE_GLES1 or USE_GLES2) */
|
||||
/** GCW (USE_GLES1 or USE_GLES2) */
|
||||
/** GLES Version */
|
||||
/** USE_GLES1 : EGL for use with OpenGL-ES 1.X contexts */
|
||||
/** USE_GLES2 : EGL for use with OpenGL-ES 2.0 contexts */
|
||||
|
||||
/** Public API */
|
||||
void EGL_Close ( void );
|
||||
int8_t EGL_Open ( uint16_t width, uint16_t height );
|
||||
void EGL_SwapBuffers ( void );
|
||||
|
||||
/** Simple Examples */
|
||||
/** Raw mode:
|
||||
EGL_Open( window_width, window_height );
|
||||
do while(!quit) {
|
||||
... run app
|
||||
EGL_SwapBuffers();
|
||||
}
|
||||
EGL_Close();
|
||||
*/
|
||||
/** X11/SDL mode:
|
||||
SDL_Init( SDL_INIT_VIDEO );
|
||||
SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_SWSURFACE|SDL_FULLSCREEN);
|
||||
EGL_Open( window_width, window_height );
|
||||
do while(!quit) {
|
||||
... run app
|
||||
EGL_SwapBuffers();
|
||||
}
|
||||
EGL_Close();
|
||||
SDL_Quit();
|
||||
*/
|
||||
|
||||
#if defined(DEBUG)
|
||||
#define GET_EGLERROR(FUNCTION) \
|
||||
FUNCTION; \
|
||||
{ \
|
||||
CheckEGLErrors(__FILE__, __LINE__); \
|
||||
}
|
||||
#else
|
||||
#define GET_EGLERROR(FUNCTION) FUNCTION;
|
||||
#endif
|
||||
|
||||
#define peglQueryString(A,B) GET_EGLERROR(eglQueryString(A,B))
|
||||
#define peglDestroyContext(A,B) GET_EGLERROR(eglDestroyContext(A,B))
|
||||
#define peglDestroySurface(A,B) GET_EGLERROR(eglDestroySurface(A,B))
|
||||
#define peglTerminate(A) GET_EGLERROR(eglTerminate(A))
|
||||
#define peglSwapBuffers(A,B) GET_EGLERROR(eglSwapBuffers(A,B))
|
||||
#define peglGetDisplay(A) GET_EGLERROR(eglGetDisplay(A))
|
||||
#define peglBindAPI(A) GET_EGLERROR(eglBindAPI(A))
|
||||
#define peglCreateContext(A,B,C,D) GET_EGLERROR(eglCreateContext(A,B,C,D))
|
||||
#define peglCreateWindowSurface(A,B,C,D) GET_EGLERROR(eglCreateWindowSurface(A,B,C,D))
|
||||
#define peglInitialize(A,B,C) GET_EGLERROR(eglInitialize(A,B,C))
|
||||
#define peglMakeCurrent(A,B,C,D) GET_EGLERROR(eglMakeCurrent(A,B,C,D))
|
||||
#define peglChooseConfig(A,B,C,D,E) GET_EGLERROR(eglChooseConfig(A,B,C,D,E))
|
||||
#define peglSwapInterval(A,B) GET_EGLERROR(eglSwapInterval(A,B))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* EGLPORT_H */
|
|
@ -0,0 +1,359 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2011 Scott R. Smith
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "in_gph.h"
|
||||
|
||||
int8_t Volume = 20;
|
||||
uint8_t VolumeDirection = 0;
|
||||
int32_t HandleStick = 0;
|
||||
int32_t HandleGpio = 0;
|
||||
uint32_t ButtonsCurrent = 0;
|
||||
uint32_t ButtonsPrevious = 0;
|
||||
uint32_t Ticksup = 0;
|
||||
uint32_t Ticksdown = 0;
|
||||
|
||||
SDLKey gph_map[GPH_MAX_BUTTONS] = {
|
||||
SDLK_UP, // GPH_UP
|
||||
0, // GPH_UP_LEFT
|
||||
SDLK_LEFT, // GPH_LEFT
|
||||
0, // GPH_DOWN_LEFT
|
||||
SDLK_DOWN, // GPH_DOWN
|
||||
0, // GPH_DOWN_RIGHT
|
||||
SDLK_RIGHT, // GPH_RIGHT
|
||||
0, // GPH_UP_RIGHT
|
||||
SDLK_RETURN, // GPH_START
|
||||
SDLK_ESCAPE, // GPH_SELECT
|
||||
SDLK_l, // GPH_L
|
||||
SDLK_r, // GPH_R
|
||||
SDLK_a, // GPH_A
|
||||
SDLK_b, // GPH_B`
|
||||
SDLK_x, // GPH_Y
|
||||
SDLK_y, // GPH_X
|
||||
0, // GPH_VOL_UP
|
||||
0, // GPH_VOL_DOWN
|
||||
SDLK_p, // GPH_PUSH
|
||||
SDLK_q, // GPH_HELP1
|
||||
SDLK_1, // AB
|
||||
SDLK_F1, // AX
|
||||
SDLK_2, // AY
|
||||
SDLK_3, // BX
|
||||
SDLK_4, // BY
|
||||
SDLK_5, // XY
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
void GPH_Close( void )
|
||||
{
|
||||
close(HandleGpio);
|
||||
#if defined(CAANOO)
|
||||
close(HandleStick);
|
||||
#endif
|
||||
}
|
||||
|
||||
int8_t GPH_Open( void )
|
||||
{
|
||||
#if defined(CAANOO)
|
||||
HandleStick = open( "/dev/input/event1", O_RDONLY|O_NONBLOCK );
|
||||
if (HandleStick < 0)
|
||||
{
|
||||
printf( "GPH Input Analog stick OPEN FAIL\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("GPH Input Caanoo stick loaded\n");
|
||||
}
|
||||
#endif
|
||||
HandleGpio = open( "/dev/GPIO", O_RDWR|O_NDELAY );
|
||||
if (HandleGpio < 0)
|
||||
{
|
||||
printf( "GPH Input GPIO OPEN FAIL\n");
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("GPH Input Wiz/Caanoo buttons loaded\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GPH_Input( void )
|
||||
{
|
||||
ButtonsPrevious = ButtonsCurrent;
|
||||
|
||||
GPH_ReadButtons();
|
||||
#if defined(CAANOO)
|
||||
GPH_ReadAnalog();
|
||||
#endif
|
||||
|
||||
return ButtonsCurrent;
|
||||
}
|
||||
|
||||
void GPH_ReadButtons( void )
|
||||
{
|
||||
uint8_t button;
|
||||
uint16_t index;
|
||||
|
||||
read( HandleGpio, &ButtonsCurrent, 4 );
|
||||
|
||||
#if defined(WIZ)
|
||||
// Use diagonals
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_UP_LEFT)) &&
|
||||
!((ButtonsCurrent&GPH_BUTTON(GPH_UP)) || (ButtonsCurrent&GPH_BUTTON(GPH_LEFT))))
|
||||
{
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_UP);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_LEFT);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_UP_RIGHT)) &&
|
||||
!((ButtonsCurrent&GPH_BUTTON(GPH_UP)) || (ButtonsCurrent&GPH_BUTTON(GPH_RIGHT))))
|
||||
{
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_UP);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_RIGHT);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_DOWN_LEFT)) &&
|
||||
!((ButtonsCurrent&GPH_BUTTON(GPH_DOWN)) || (ButtonsCurrent&GPH_BUTTON(GPH_LEFT))))
|
||||
{
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_DOWN);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_LEFT);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_DOWN_RIGHT)) &&
|
||||
!((ButtonsCurrent&GPH_BUTTON(GPH_DOWN)) || (ButtonsCurrent&GPH_BUTTON(GPH_RIGHT))))
|
||||
{
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_DOWN);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_RIGHT);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Map combos
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_A)) && (ButtonsCurrent&GPH_BUTTON(GPH_B)) )
|
||||
{
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_A);
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_B);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_AB);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_A)) && (ButtonsCurrent&GPH_BUTTON(GPH_X)) )
|
||||
{
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_A);
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_X);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_AX);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_A)) && (ButtonsCurrent&GPH_BUTTON(GPH_Y)) )
|
||||
{
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_A);
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_Y);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_AY);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_B)) && (ButtonsCurrent&GPH_BUTTON(GPH_X)) )
|
||||
{
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_B);
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_X);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_BX);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_B)) && (ButtonsCurrent&GPH_BUTTON(GPH_Y)) )
|
||||
{
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_B);
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_Y);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_BY);
|
||||
}
|
||||
if ( (ButtonsCurrent&GPH_BUTTON(GPH_X)) && (ButtonsCurrent&GPH_BUTTON(GPH_Y)) )
|
||||
{
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_X);
|
||||
ButtonsCurrent ^= GPH_BUTTON(GPH_Y);
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_XY);
|
||||
}
|
||||
|
||||
#if defined(WIZ)
|
||||
// Volume Up
|
||||
if ((((ButtonsPrevious & GPH_BUTTON(GPH_VOL_UP)) == 0) && ((ButtonsCurrent & GPH_BUTTON(GPH_VOL_UP))> 0)) ||
|
||||
(((ButtonsPrevious & GPH_BUTTON(GPH_VOL_UP)) > 0) && ((ButtonsCurrent & GPH_BUTTON(GPH_VOL_UP))> 0) && ((SDL_GetTicks() - Ticksup) > VOLUME_TIME_RATE )) )
|
||||
{
|
||||
Ticksup = SDL_GetTicks();
|
||||
GPH_AdjustVolume(VOLUME_UP);
|
||||
}
|
||||
// Volume Down
|
||||
if ((((ButtonsPrevious & GPH_BUTTON(GPH_VOL_DOWN)) == 0) && ((ButtonsCurrent & GPH_BUTTON(GPH_VOL_DOWN))> 0)) ||
|
||||
(((ButtonsPrevious & GPH_BUTTON(GPH_VOL_DOWN)) > 0) && ((ButtonsCurrent & GPH_BUTTON(GPH_VOL_DOWN))> 0) && ((SDL_GetTicks() - Ticksdown) > VOLUME_TIME_RATE )) )
|
||||
{
|
||||
Ticksdown = SDL_GetTicks();
|
||||
GPH_AdjustVolume(VOLUME_DOWN);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(CAANOO)
|
||||
#define ZERO_POINT 128
|
||||
#define OPT_DEADZONE 64
|
||||
|
||||
int8_t up, down, left, right = 0;
|
||||
|
||||
void GPH_ReadAnalog( void )
|
||||
{
|
||||
struct input_event event[16];
|
||||
int32_t rbytes;
|
||||
uint32_t i;
|
||||
|
||||
rbytes = read( HandleStick, &event, sizeof(event) );
|
||||
if (rbytes > 0)
|
||||
{
|
||||
for (i=0; i<rbytes/sizeof(struct input_event); i++)
|
||||
{
|
||||
switch (event[i].type)
|
||||
{
|
||||
case EV_ABS:
|
||||
switch (event[i].code)
|
||||
{
|
||||
case ABS_X:
|
||||
if (event[i].value>ZERO_POINT+OPT_DEADZONE) {
|
||||
right = 1;
|
||||
} else {
|
||||
right = 0;
|
||||
}
|
||||
|
||||
if (event[i].value<ZERO_POINT-OPT_DEADZONE) {
|
||||
left = 1;
|
||||
} else {
|
||||
left = 0;
|
||||
}
|
||||
|
||||
//printf("x = 0x%x\n", event[i].value);
|
||||
break;
|
||||
case ABS_Y:
|
||||
if (event[i].value<ZERO_POINT-OPT_DEADZONE) {
|
||||
up = 1;
|
||||
} else {
|
||||
up = 0;
|
||||
}
|
||||
|
||||
if (event[i].value>ZERO_POINT+OPT_DEADZONE) {
|
||||
down = 1;
|
||||
} else {
|
||||
down = 0;
|
||||
}
|
||||
|
||||
//printf("y = 0x%x\n", event[i].value);
|
||||
break;
|
||||
default:
|
||||
//printf("type = 0x%x, code = 0x%x\n", event[i].type, event[i].code);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (event[i].type) {
|
||||
//printf("type = 0x%x, code = 0x%x\n", event[i].type, event[i].code);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (right)
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_RIGHT);
|
||||
|
||||
if (left)
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_LEFT);
|
||||
|
||||
if (up)
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_UP);
|
||||
|
||||
if (down)
|
||||
ButtonsCurrent |= GPH_BUTTON(GPH_DOWN);
|
||||
}
|
||||
#endif /* if defined(CAANOO) */
|
||||
|
||||
#if defined(WIZ)
|
||||
void GPH_AdjustVolume( uint8_t direction )
|
||||
{
|
||||
if (direction != VOLUME_NOCHG)
|
||||
{
|
||||
if (Volume <= 10)
|
||||
{
|
||||
if (direction == VOLUME_UP) Volume += VOLUME_CHANGE_RATE/2;
|
||||
if (direction == VOLUME_DOWN) Volume -= VOLUME_CHANGE_RATE/2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (direction == VOLUME_UP) Volume += VOLUME_CHANGE_RATE;
|
||||
if (direction == VOLUME_DOWN) Volume -= VOLUME_CHANGE_RATE;
|
||||
}
|
||||
|
||||
if (Volume < VOLUME_MIN) Volume = VOLUME_MIN;
|
||||
if (Volume > VOLUME_MAX) Volume = VOLUME_MAX;
|
||||
|
||||
printf( "Volume Change: %i\n", Volume );
|
||||
|
||||
unsigned long soundDev = open("/dev/mixer", O_RDWR);
|
||||
if (soundDev)
|
||||
{
|
||||
int vol = ((Volume << 8) | Volume);
|
||||
ioctl(soundDev, SOUND_MIXER_WRITE_PCM, &vol);
|
||||
close(soundDev);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* if defined(WIZ) */
|
||||
|
||||
int8_t GPH_GetButttonState( uint32_t button )
|
||||
{
|
||||
uint32_t current_state;
|
||||
uint32_t previous_state;
|
||||
|
||||
current_state = button & ButtonsCurrent;
|
||||
previous_state = button & ButtonsPrevious;
|
||||
|
||||
// Was released and now pressed
|
||||
if (previous_state == 0 && current_state == button)
|
||||
{
|
||||
//printf ("GPH_RELEASED_TO_PRESSED %X\n", button );
|
||||
return GPH_RELEASED_TO_PRESSED;
|
||||
}
|
||||
else // Was pressed and still being pressed
|
||||
if (previous_state == button && current_state == button)
|
||||
{
|
||||
//printf ("GPH_PRESSED %X\n", button );
|
||||
return GPH_PRESSED;
|
||||
}
|
||||
else // Was pressed and now released
|
||||
if (previous_state == button && current_state == 0)
|
||||
{
|
||||
//printf ("GPH_PRESSED_TO_RELEASED %X\n", button );
|
||||
return GPH_PRESSED_TO_RELEASED;
|
||||
}
|
||||
else // Was released and still released
|
||||
if (previous_state == 0 && current_state == 0)
|
||||
{
|
||||
//printf ("GPH_RELEASED %X\n", button );
|
||||
return GPH_RELEASED;
|
||||
}
|
||||
else // Shouldnt ever have this state
|
||||
{
|
||||
printf( "GPH Input Wiz/Caanoo detected unexpected button state: previous %X current %X\n", ButtonsPrevious, ButtonsCurrent );
|
||||
return GPH_NONE;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
/**
|
||||
*
|
||||
* Copyright (C) 2011 Scott R. Smith
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef CGPH_H
|
||||
#define CGPH_H
|
||||
|
||||
#include <SDL.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/soundcard.h>
|
||||
|
||||
enum {
|
||||
GPH_NONE=0,
|
||||
GPH_RELEASED_TO_PRESSED,
|
||||
GPH_PRESSED,
|
||||
GPH_PRESSED_TO_RELEASED,
|
||||
GPH_RELEASED
|
||||
};
|
||||
|
||||
#define GPH_MAX_BUTTONS 32
|
||||
#define GPH_BUTTON(X) (1<<X)
|
||||
|
||||
#if defined(CAANOO)
|
||||
#include <linux/input.h>
|
||||
#endif
|
||||
|
||||
#define GPH_UP 0
|
||||
#define GPH_UP_LEFT 1
|
||||
#define GPH_LEFT 2
|
||||
#define GPH_DOWN_LEFT 3
|
||||
#define GPH_DOWN 4
|
||||
#define GPH_DOWN_RIGHT 5
|
||||
#define GPH_RIGHT 6
|
||||
#define GPH_UP_RIGHT 7
|
||||
#define GPH_START 8 // Caanoo HOME
|
||||
#define GPH_SELECT 9 // Cannoo HELP2
|
||||
#define GPH_L 10
|
||||
#define GPH_R 11
|
||||
#define GPH_A 12
|
||||
#define GPH_B 13
|
||||
#define GPH_X 14
|
||||
#define GPH_Y 15
|
||||
#define GPH_VOL_UP 16
|
||||
#define GPH_VOL_DOWN 17
|
||||
#define GPH_PUSH 18 // Caanoo only
|
||||
#define GPH_HELP1 19 // Caanoo only
|
||||
|
||||
#define GPH_AB 20
|
||||
#define GPH_AX 21
|
||||
#define GPH_AY 22
|
||||
#define GPH_BX 23
|
||||
#define GPH_BY 24
|
||||
#define GPH_XY 25
|
||||
|
||||
#if defined(WIZ)
|
||||
#define VOLUME_MIN 0
|
||||
#define VOLUME_MAX 100
|
||||
#define VOLUME_CHANGE_RATE 2
|
||||
#define VOLUME_NOCHG 0
|
||||
#define VOLUME_DOWN 1
|
||||
#define VOLUME_UP 2
|
||||
#define VOLUME_TIME_RATE 20
|
||||
#endif
|
||||
|
||||
void GPH_Close ( void );
|
||||
int8_t GPH_Open ( void );
|
||||
void GPH_Input ( void );
|
||||
|
||||
void GPH_ReadButtons ( void );
|
||||
#if defined(CAANOO)
|
||||
void GPH_ReadAnalog ( void );
|
||||
#endif
|
||||
#if defined(WIZ)
|
||||
void GPH_AdjustVolume ( uint8_t direction );
|
||||
#endif
|
||||
int8_t GPH_GetButttonState ( uint32_t button );
|
||||
|
||||
extern SDLKey gph_map[GPH_MAX_BUTTONS];
|
||||
|
||||
#endif // CGPH_H
|
||||
|
Loading…
Reference in New Issue