diff --git a/Makefile b/Makefile old mode 100644 new mode 100755 index dbbfe0bb..fecabc97 --- a/Makefile +++ b/Makefile @@ -6,10 +6,16 @@ # make CC=i686-mingw32-gcc CC=gcc +PANDORA=1 + # general compiler settings ifeq ($(M32),1) FLAGS= -m32 endif +ifeq ($(PANDORA),1) + FLAGS= -mcpu=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mno-unaligned-access -DHAVE_GLES -DPANDORA -DARM + HAVE_GLES=1 +endif FLAGS+= -std=gnu99 -pipe CFLAGS=$(FLAGS) -Wall -Wextra LDFLAGS=$(FLAGS) @@ -19,7 +25,7 @@ LDFLAGS=$(FLAGS) DEBUG=1 # might as well leave gprof support on by default as well -PROFILE=1 +PROFILE=0 # use this if you want to build everything statically STATIC=0 @@ -45,7 +51,7 @@ ifeq ($(SSP),1) endif ifeq ($(DEBUG),1) - FLAGS+= -g + FLAGS+= -g -gdwarf-2 else CFLAGS+=-O3 -Winit-self LDFLAGS+=-s @@ -64,13 +70,14 @@ endif # # some systems use lua5.1 -LUA=$(shell pkg-config lua && echo lua || echo lua5.1) +LUA=$(shell libs/pkgconfig.sh lua && echo lua || echo lua5.1) MACOSX=$(shell uname -a | grep -qi darwin && echo 1 || echo 0) # which version of sdl do you want to ask pkgconfig for ? SDL=1 ifeq ($(SDL),1) SDL_=sdl + CFLAGS+=`sdl-config --cflags` else SDL_=sdl$(SDL) endif @@ -82,7 +89,8 @@ $(if $(shell test "$(GL)" -ge 3 -a "$(SDL)" -lt 2 && echo fail), \ $(error "GL >= 3 only supported with SDL >= 2")) # library headers -CFLAGS+= `pkg-config --cflags $(SDL_) $(LUA) $(LUA)-socket libenet libpng zlib openal` +CFLAGS+= `libs/pkgconfig.sh --cflags $(LUA) $(LUA)-socket libenet` +CFLAGS+= `pkg-config --cflags $(SDL_) libpng zlib openal` ifeq ($(MACOSX),1) CFLAGS += -DMACOSX endif @@ -95,13 +103,16 @@ ifeq ($(STATIC),1) LIB+= -Wl,-dn PKG_CFG_OPTS= --static endif -LIB+= `pkg-config $(PKG_CFG_OPTS) --libs $(LUA) $(LUA)-socket libenet libpng zlib openal` -lm +LIB+= `libs/pkgconfig.sh $(PKG_CFG_OPTS) --libs $(LUA) $(LUA)-socket libenet` +LIB+= `pkg-config $(PKG_CFG_OPTS) --libs libpng zlib openal` +LIB+= -lm ifeq ($(STATIC),1) LIB+= -Wl,-dy endif # dynamic only libraries -LIB+= `pkg-config --libs $(SDL_)` +#LIB+= `pkg-config --libs $(SDL_)` +LIB+= `sdl-config --libs` ifeq ($(MINGW),1) LIB += -L./mingw/bin LIB += -lglu32 -lopengl32 @@ -111,9 +122,14 @@ else ifeq ($(MACOSX),1) #LIB += -L/usr/X11/lib/ -lGL -lGLU LIB += -framework OpenGL # OpenGL bundle on OSX. LIB += -framework Cocoa # Used to target Quartz by SDL_. +else +ifeq ($(HAVE_GLES),1) + LIB += -lGLES_CM -lEGL + CFLAGS += -DHAVE_GLES -DPANDORA else LIB += -lGL -lGLU endif +endif ifneq ($(MINGW),1) # apparently on some systems -ldl is explicitly required # perhaps this is part of the default libs on others...? diff --git a/bsp.c b/bsp.c index 93f576de..23ba90ae 100755 --- a/bsp.c +++ b/bsp.c @@ -148,10 +148,18 @@ static bool BSP_LoadPortal( BSP_PORTAL *p, char **Buffer ) int16_tpnt = (int16_t *) *Buffer; p->group = *int16_tpnt++; floatpnt = (float *) int16_tpnt; +#ifdef ARM + memcpy(&p->normal, floatpnt, 4*3); + floatpnt+=3; + memcpy(&p->offset, floatpnt, 4); + floatpnt++; +#else p->normal.x = *floatpnt++; p->normal.y = *floatpnt++; p->normal.z = *floatpnt++; p->offset = *floatpnt++; + +#endif *Buffer = (char *) floatpnt; return BSP_Loadtree( &p->bsp, Buffer ); diff --git a/camera.c b/camera.c index e720c2d9..9382e9ab 100755 --- a/camera.c +++ b/camera.c @@ -111,7 +111,14 @@ bool Cameraload( char * Filename ) int16Pnt = (int16_t*) Buffer; CamPnt->Group = *int16Pnt++; FloatPnt = (float*) int16Pnt; - +#ifdef ARM + memcpy(&CamPnt->Pos, FloatPnt, 4*3); + FloatPnt+=3; + memcpy(&CamPnt->Dir, FloatPnt, 4*3); + FloatPnt+=3; + memcpy(&CamPnt->Up, FloatPnt, 4*3); + FloatPnt+=3; +#else CamPnt->Pos.x = *FloatPnt++; CamPnt->Pos.y = *FloatPnt++; CamPnt->Pos.z = *FloatPnt++; @@ -121,6 +128,7 @@ bool Cameraload( char * Filename ) CamPnt->Up.x = *FloatPnt++; CamPnt->Up.y = *FloatPnt++; CamPnt->Up.z = *FloatPnt++; +#endif Buffer = (char*) FloatPnt; Tempv.x = CamPnt->Pos.x + CamPnt->Dir.x; Tempv.y = CamPnt->Pos.y + CamPnt->Dir.y; diff --git a/config.c b/config.c index 948ff612..05fb4c7b 100755 --- a/config.c +++ b/config.c @@ -38,12 +38,31 @@ USERCONFIG default_config = { "Player", // player name 0, // bike (0=Lokasenna) 1, // bike computer ( 1 = Brenda ) +#ifdef PANDORA + 0.3F, // mouse x sensitivity + 0.2F, // mouse y sensitivity +#else 0.6F, // mouse x sensitivity 0.6F, // mouse y sensitivity +#endif 0, // pilot control (pitch forward = down, backward = up) 0, // roll control... 0.05F, // autolevel rate // { num_keys, { key list [ num_keys ] } }, +#ifdef PANDORA + { 2, { SDLK_q } }, // pitch forward + { 2, { SDLK_e } }, // pitch backward + { 2, { SDLK_1 } }, // yaw left + { 2, { SDLK_3 } }, // yaw right + { 2, { SDLK_LEFT } }, // roll left + { 2, { SDLK_RIGHT } }, // roll right + { 1, { SDLK_q } }, // slide left + { 1, { SDLK_e } }, // slide right + { 1, { SDLK_UP } }, // slide up + { 1, { SDLK_DOWN } }, // slide down + { 1, { SDLK_2 } }, // forward + { 1, { SDLK_4 } }, // backward +#else { 2, { SDLK_DOWN } }, // pitch forward { 2, { SDLK_UP } }, // pitch backward { 2, { SDLK_LEFT } }, // yaw left @@ -56,6 +75,7 @@ USERCONFIG default_config = { { 1, { SDLK_KP_PLUS } }, // slide down { 1, { SDLK_a } }, // forward { 1, { SDLK_z } }, // backward +#endif { 1, { SDLK_LALT } }, // slide { 0, {} }, // roll { 1, { SDLK_s } }, // turbo @@ -63,7 +83,11 @@ USERCONFIG default_config = { { 0, {} }, // cruise slower { 2, { LEFT_MOUSE } }, // fire primary { 2, { RIGHT_MOUSE } }, // fire secondary +#ifdef PANDORA + { 1, { SDLK_BACKSPACE } }, // fire mine +#else { 1, { SDLK_b } }, // fire mine +#endif { 1, { SDLK_PAGEDOWN } }, // select next primary { 1, { SDLK_PAGEUP } }, // select prev primary { 1, { SDLK_HOME } }, // select next secondary @@ -71,7 +95,11 @@ USERCONFIG default_config = { { 1, { SDLK_r } }, // select rear view { 1, { SDLK_h } }, // toggle headlights { +#ifdef PANDORA + { 1, { SDLK_q } }, // select primary #1 +#else { 1, { SDLK_BACKQUOTE } }, // select primary #1 +#endif { 1, { SDLK_1 } }, // select primary #2 { 1, { SDLK_4 } }, // select primary #3 { 1, { SDLK_3 } }, // select primary #4 @@ -156,12 +184,31 @@ USERCONFIG my_controls = { "Player", // player name 0, // bike (0=Lokasenna) 1, // bike computer ( 1 = Brenda ) +#ifdef PANDORA + 0.3F, // mouse x sensitivity + 0.2F, // mouse y sensitivity +#else 0.6F, // mouse x sensitivity 0.6F, // mouse y sensitivity +#endif 0, // pilot control (pitch forward = down, backward = up) 0, // roll control... 0.05F, // autolevel rate // { num_keys, { key list [ num_keys ] } }, +#ifdef PANDORA + { 2, { SDLK_q } }, // pitch forward + { 2, { SDLK_e } }, // pitch backward + { 2, { SDLK_1 } }, // yaw left + { 2, { SDLK_3 } }, // yaw right + { 2, { SDLK_LEFT } }, // roll left + { 2, { SDLK_RIGHT } }, // roll right + { 1, { SDLK_q } }, // slide left + { 1, { SDLK_e } }, // slide right + { 1, { SDLK_UP } }, // slide up + { 1, { SDLK_DOWN } }, // slide down + { 1, { SDLK_2 } }, // forward + { 1, { SDLK_4 } }, // backward +#else { 2, { SDLK_UP } }, // pitch forward { 2, { SDLK_DOWN } }, // pitch backward { 2, { SDLK_LEFT } }, // yaw left @@ -174,6 +221,7 @@ USERCONFIG my_controls = { { 1, { SDLK_KP_PLUS } }, // slide down { 1, { SDLK_a } }, // forward { 1, { SDLK_z } }, // backward +#endif { 1, { SDLK_LALT } }, // slide { 0, {} }, // roll { 1, { SDLK_s } }, // turbo @@ -181,7 +229,11 @@ USERCONFIG my_controls = { { 0, {} }, // cruise slower { 2, { LEFT_MOUSE } }, // fire primary { 2, { RIGHT_MOUSE } }, // fire secondary +#ifdef PANDORA + { 1, { SDLK_BACKSPACE } }, // fire mine +#else { 1, { SDLK_b } }, // fire mine +#endif { 1, { SDLK_PAGEDOWN } }, // select next primary { 1, { SDLK_PAGEUP } }, // select prev primary { 1, { SDLK_HOME } }, // select next secondary @@ -189,7 +241,11 @@ USERCONFIG my_controls = { { 1, { SDLK_r } }, // select rear view { 1, { SDLK_h } }, // toggle headlights { +#ifdef PANDORA + { 1, { SDLK_q } }, // select primary #1 +#else { 1, { SDLK_BACKQUOTE } }, // select primary #1 +#endif { 1, { SDLK_1 } }, // select primary #2 { 1, { SDLK_4 } }, // select primary #3 { 1, { SDLK_3 } }, // select primary #4 @@ -1156,10 +1212,17 @@ void ConfigureSpaceorbAxis( int joystick ) JoystickInfo[ joystick ].Axis[ k ].fine = false; } +#ifdef PANDORA + JoystickInfo[ joystick ].Axis[ AXIS_XAxis ].action = SHIPACTION_SlideLeft; + JoystickInfo[ joystick ].Axis[ AXIS_YAxis ].action = SHIPACTION_MoveForward; + JoystickInfo[ joystick ].Axis[ AXIS_ZAxis ].action = SHIPACTION_SlideUp; + JoystickInfo[ joystick ].Axis[ AXIS_RzAxis ].action = SHIPACTION_RotateUp; +#else JoystickInfo[ joystick ].Axis[ AXIS_XAxis ].action = SHIPACTION_SlideLeft; JoystickInfo[ joystick ].Axis[ AXIS_YAxis ].action = SHIPACTION_SlideUp; JoystickInfo[ joystick ].Axis[ AXIS_ZAxis ].action = SHIPACTION_MoveForward; JoystickInfo[ joystick ].Axis[ AXIS_RzAxis ].action = SHIPACTION_RotateUp; +#endif JoystickInfo[ joystick ].Axis[ AXIS_SliderAxis0 ].action = SHIPACTION_RotateLeft; JoystickInfo[ joystick ].Axis[ AXIS_SliderAxis1 ].action = SHIPACTION_RollLeft; #if NOT_DONE_THIS_WAY @@ -1230,13 +1293,22 @@ void DefaultJoystickSettings( USERCONFIG *u ) for ( k = AXIS_Start; k <= AXIS_End; k++ ) { JoystickInfo[ j ].Axis[ k ].action = SHIPACTION_Nothing; +#ifdef PANDORA + JoystickInfo[ j ].Axis[ k ].sensitivity = 0.01F; +#else JoystickInfo[ j ].Axis[ k ].sensitivity = 0.02F; +#endif JoystickInfo[ j ].Axis[ k ].deadzone = 20; JoystickInfo[ j ].Axis[ k ].inverted = false; JoystickInfo[ j ].Axis[ k ].fine = true; } +#ifdef PANDORA + JoystickInfo[ j ].Axis[ AXIS_XAxis ].action = SHIPACTION_SlideLeft; + JoystickInfo[ j ].Axis[ AXIS_YAxis ].action = SHIPACTION_MoveForward; +#else JoystickInfo[ j ].Axis[ AXIS_XAxis ].action = SHIPACTION_RotateLeft; JoystickInfo[ j ].Axis[ AXIS_YAxis ].action = SHIPACTION_RotateUp; +#endif } AddButton( j, 0, &u->fire_primary ); AddButton( j, 1, &u->fire_secondary ); @@ -1281,11 +1353,21 @@ void ReInitJoysticks( void ) for ( k = AXIS_Start; k <= AXIS_End; k++ ) { tempJoystickInfo[ j ].Axis[ k ].action = SHIPACTION_Nothing; +#ifdef PANDORA + tempJoystickInfo[ j ].Axis[ k ].sensitivity = 0.01F; +#else tempJoystickInfo[ j ].Axis[ k ].sensitivity = 0.02F; +#endif tempJoystickInfo[ j ].Axis[ k ].deadzone = 20; tempJoystickInfo[ j ].Axis[ k ].inverted = false; tempJoystickInfo[ j ].Axis[ k ].fine = true; } +#ifdef PANDORA + tempJoystickInfo[ j ].Axis[ AXIS_XAxis ].action = SHIPACTION_SlideLeft; + tempJoystickInfo[ j ].Axis[ AXIS_YAxis ].action = SHIPACTION_MoveForward; + if (j==0) tempJoystickInfo[j].assigned = true; // always 1 nub activated, we want it enabled + +#endif j++; } } @@ -1303,7 +1385,6 @@ read_config( USERCONFIG *u, char *cfg_name ) FILE *f; char token[80]; int j; - // all the config settings static READCONFIGTABLE jumptab[] = { { "down", read_down }, @@ -1372,6 +1453,10 @@ read_config( USERCONFIG *u, char *cfg_name ) // tell debuggers DebugPrintf( "read_config: couldn't open '%s'\n", cfg_name ); +printf( "read_config: couldn't open '%s'\n", cfg_name ); + + // reset all joystick settings before exiting... + ReInitJoysticks(); // failed ... return 0; @@ -1386,14 +1471,18 @@ read_config( USERCONFIG *u, char *cfg_name ) // files... u->invert_turn = 0; u->invert_pitch = 0; +#ifdef PANDORA + u->mouse_x_sensitivity = 0.3F; + u->mouse_y_sensitivity = 0.2F; +#else u->mouse_x_sensitivity = 0.6F; u->mouse_y_sensitivity = 0.6F; +#endif u->send_msg.key[ 0 ] = SDLK_RETURN; // reset all joystick settings ReInitJoysticks(); - // get a 80 character wide string from file if ( fscanf( f, " %80s", token ) == 1 ) { diff --git a/eglport.c b/eglport.c new file mode 100755 index 00000000..473968fe --- /dev/null +++ b/eglport.c @@ -0,0 +1,708 @@ +#ifdef HAVE_GLES +/** + * + * 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 +#include + +#define USE_EGL_SDL 1 +#define USE_GLES1 1 + +#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 +#include +#include +#include + +#ifndef FBIO_WAITFORVSYNC +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) +#endif +int fbdev = -1; + +#elif defined(RPI) +#include "bcm_host.h" +#endif /* PANDORA */ + +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 */ + +int8_t eglColorbits = 0; +int8_t eglDepthbits = 0; +int8_t eglStencilbits = 0; + + +/** 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; + + eglColorbits = 0; + eglDepthbits = 0; + eglStencilbits = 0; + + /* 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 ERROR: EGL system is already open!\n" ); + return 1; + } + + /* Check for the cfg file to alternative settings */ + OpenCfg( "eglport.cfg" ); + + /* Setup any platform specific bits */ + Platform_Open(); + + printf( "EGLport: Opening EGL display\n" ); + if (GetNativeDisplay() != 0) + { + printf( "EGLport ERROR: Unable to obtain native display!\n" ); + return 1; + } + + 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" ); + if (GetNativeWindow( width, height ) != 0) + { + printf( "EGLport ERROR: Unable to obtain native window!\n" ); + return 1; + } + + 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; + } + + { + EGLint color, depth, stencil; + eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_BUFFER_SIZE, &color); + eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_DEPTH_SIZE, &depth); + eglGetConfigAttrib(eglDisplay, eglConfigs[configIndex], EGL_STENCIL_SIZE, &stencil); + eglColorbits = (color==16)?5:8; //quick hack + eglDepthbits = depth; + eglStencilbits = stencil; + } + + 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_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 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) + + 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; + + /* 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, (VC_DISPMANX_ALPHA_T*)0 /*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; +} +#endif //HAVE_GLES \ No newline at end of file diff --git a/eglport.h b/eglport.h new file mode 100755 index 00000000..736456cd --- /dev/null +++ b/eglport.h @@ -0,0 +1,108 @@ +/** + * + * 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 +#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) */ +/** 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 ); + +extern int8_t eglColorbits; +extern int8_t eglDepthbits; +extern int8_t eglStencilbits; + +/** 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 */ diff --git a/extforce.c b/extforce.c index 3a2def53..9476c2fe 100755 --- a/extforce.c +++ b/extforce.c @@ -147,6 +147,20 @@ bool ExternalForcesLoad( char * Filename ) } floatpnt = (float *) Buffer; +#ifdef ARM + memcpy(&EFpnt->Origin, floatpnt, 4*3); + floatpnt+=3; + memcpy(&EFpnt->Dir, floatpnt, 4*3); + floatpnt+=3; + memcpy(&EFpnt->Up, floatpnt, 4*3); + floatpnt+=3; + memcpy(&EFpnt->MinForce, floatpnt++, 4); + memcpy(&EFpnt->MaxForce, floatpnt++, 4); + memcpy(&EFpnt->Width, floatpnt++, 4); + memcpy(&EFpnt->Height, floatpnt++, 4); + memcpy(&EFpnt->Range , floatpnt++, 4); + EFpnt->Range=1.0f/EFpnt->Range; +#else EFpnt->Origin.x = *floatpnt++; EFpnt->Origin.y = *floatpnt++; EFpnt->Origin.z = *floatpnt++; @@ -161,6 +175,7 @@ bool ExternalForcesLoad( char * Filename ) EFpnt->Width = *floatpnt++; EFpnt->Height = *floatpnt++; EFpnt->Range = 1.0F / *floatpnt++; +#endif Buffer = (char *) floatpnt; Uint16Pnt = (u_int16_t *) Buffer; @@ -168,12 +183,19 @@ bool ExternalForcesLoad( char * Filename ) Buffer = (char *) Uint16Pnt; floatpnt = (float *) Buffer; +#ifdef ARM + memcpy(&EFpnt->Pos, floatpnt, 4*3); + floatpnt+=3; + memcpy(&EFpnt->half_size, floatpnt, 4*3); + floatpnt+=3; +#else EFpnt->Pos.x = *floatpnt++; EFpnt->Pos.y = *floatpnt++; EFpnt->Pos.z = *floatpnt++; EFpnt->half_size.x = *floatpnt++; EFpnt->half_size.y = *floatpnt++; EFpnt->half_size.z = *floatpnt++; +#endif Buffer = (char *) floatpnt; if( EFpnt->Type != ZONE_Sphere ) @@ -198,10 +220,16 @@ bool ExternalForcesLoad( char * Filename ) // appears that the file data stops ! // but we were told that there was more data... // we would need to properly track the location in the stream and not go over the stream size +#ifdef ARM + memcpy(&ZonePnt->normal, floatpnt, 4*3); + floatpnt+=3; + memcpy(&ZonePnt->offset, floatpnt++, 4); +#else ZonePnt->normal.x = *floatpnt++; ZonePnt->normal.y = *floatpnt++; ZonePnt->normal.z = *floatpnt++; ZonePnt->offset = *floatpnt++; +#endif ZonePnt++; } Buffer = (char*) floatpnt; diff --git a/goal.c b/goal.c index 225c7709..45d35164 100755 --- a/goal.c +++ b/goal.c @@ -139,6 +139,19 @@ bool GoalLoad( void ) GoalPnt->state = GOALSTATE_Off; floatpnt = (float * ) u_int16_tpnt; +#ifdef ARM + memcpy(&GoalPnt->pos, floatpnt, 4*3); + floatpnt+=3; + memcpy(&GoalPnt->half_size, floatpnt, 4*3); + floatpnt+=3; + memcpy(&GoalPnt->dir, floatpnt, 4*3); + floatpnt+=3; + memcpy(&GoalPnt->up, floatpnt, 4*3); + floatpnt+=3; + memcpy(&GoalPnt->width, floatpnt++, 4); + memcpy(&GoalPnt->height, floatpnt++, 4); + memcpy(&GoalPnt->depth, floatpnt++, 4); +#else GoalPnt->pos.x = *floatpnt++; GoalPnt->pos.y = *floatpnt++; GoalPnt->pos.z = *floatpnt++; @@ -154,7 +167,7 @@ bool GoalLoad( void ) GoalPnt->width = *floatpnt++; GoalPnt->height = *floatpnt++; GoalPnt->depth = *floatpnt++; - +#endif Buffer = (char*) floatpnt; if( GoalPnt->type != ZONE_Sphere ) { @@ -179,10 +192,16 @@ bool GoalLoad( void ) for( j = 0 ; j < GoalPnt->num_sides ; j++ ) { +#ifdef ARM + memcpy(&ZonePnt->normal, floatpnt, 4*3); + floatpnt+=3; + memcpy(&ZonePnt->offset, floatpnt++, 4); +#else ZonePnt->normal.x = *floatpnt++; ZonePnt->normal.y = *floatpnt++; ZonePnt->normal.z = *floatpnt++; ZonePnt->offset = *floatpnt++; +#endif ZonePnt++; } Buffer = (char*) floatpnt; diff --git a/input_sdl.c b/input_sdl.c old mode 100644 new mode 100755 index 6e459428..e463c6c0 --- a/input_sdl.c +++ b/input_sdl.c @@ -244,9 +244,35 @@ void app_keyboard( SDL_KeyboardEvent * key ) #endif MenuGoFullScreen( NULL ); } +#ifdef PANDORA + // redirect shoulder buttons to left/right click + if (key->keysym.sym==SDLK_RSHIFT) { + int button = 0; + mouse_state.buttons[ button ] = 0; + return; + } else if (key->keysym.sym==SDLK_RCTRL) { + int button = 2; + mouse_state.buttons[ button ] = 0; + return; + } +#endif } if( key->type == SDL_KEYDOWN ) { +#ifdef PANDORA + // redirect shoulder buttons to left/right click + if (key->keysym.sym==SDLK_RSHIFT) { + int button = 0; + input_buffer_send( button + LEFT_MOUSE ); + mouse_state.buttons[ button ] = 1; + return; + } else if (key->keysym.sym==SDLK_RCTRL) { + int button = 2; + input_buffer_send( button + LEFT_MOUSE ); + mouse_state.buttons[ button ] = 1; + return; + } +#endif input_buffer_send( key->keysym.unicode ? key->keysym.unicode : @@ -526,6 +552,7 @@ bool joysticks_init(void) Num_Joysticks = SDL_NumJoysticks(); DebugPrintf( "joysticks_init: %d joysticks connected\n", Num_Joysticks ); +printf( "joysticks_init: %d joysticks connected\n", Num_Joysticks ); if (Num_Joysticks > MAX_JOYSTICKS) Num_Joysticks = MAX_JOYSTICKS; @@ -562,6 +589,11 @@ bool joysticks_init(void) i, JoystickInfo[i].Name, JoystickInfo[i].NumAxis, JoystickInfo[i].NumButtons, JoystickInfo[i].NumPOVs ); +printf( + "joysticks_init: joystick (%d), name='%s', axises=%d, buttons=%d, hats=%d\n", + i, JoystickInfo[i].Name, JoystickInfo[i].NumAxis, JoystickInfo[i].NumButtons, + JoystickInfo[i].NumPOVs + ); for (j = 0; j < JoystickInfo[i].NumAxis; j++) { diff --git a/main.c b/main.c index cab9eff6..72b195d2 100644 --- a/main.c +++ b/main.c @@ -14,6 +14,9 @@ #include #include "input.h" #include "sound.h" +#ifdef HAVE_GLES +extern void EGL_Close ( void ); +#endif #ifndef WIN32 #include @@ -382,6 +385,9 @@ void CleanUpAndPostQuit(void) #endif +#ifdef HAVE_GLES + EGL_Close(); +#endif // should come last SDL_Quit(); } @@ -454,7 +460,6 @@ static bool AppInit( char * lpCmdLine ) // if(!sdl_init()) return false; - // parse chdir from command line first if(!parse_chdir(lpCmdLine)) return false; diff --git a/main_sdl.c b/main_sdl.c old mode 100644 new mode 100755 index 2fa32929..886a23a5 --- a/main_sdl.c +++ b/main_sdl.c @@ -3,8 +3,12 @@ #include "version.h" #include "main_sdl.h" #ifdef GL +#ifdef HAVE_GLES +#include "SDL_opengles.h" +#else #include "SDL_opengl.h" #endif +#endif extern render_info_t render_info; extern bool render_init( render_info_t * info ); @@ -52,9 +56,17 @@ bool sdl_init( void ) #define NUMBER_MODES 19 render_display_mode_t video_modes[NUMBER_MODES] = { +#ifdef HAVE_GLES +{800,480}, +#else {0,0}, // current video mode of the desktop +#endif {640,480}, +#ifdef HAVE_GLES +{800,480}, // Pandora mode +#else {800,600}, // default window mode +#endif {1024,768}, {1152,864}, {1280,600}, @@ -134,8 +146,9 @@ static void set_opengl_settings( void ) { #ifdef GL // BPP should be left alone to match whatever the desktop is at. - +#ifndef HAVE_GLES SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); +#endif #if SDL_VERSION_ATLEAST(2,0,0) #if GL == 3 @@ -149,17 +162,21 @@ static void set_opengl_settings( void ) // this causes issues on at least one card I've seen. // best to leave this as an option. if someone says they have // low frame rate then suggest them to pass -forceaccel on cli +#ifndef HAVE_GLES if(render_info.force_accel) { DebugPrintf("main_sdl: enabling accelerated visual\n"); SDL_GL_SetAttribute(SDL_GL_ACCELERATED_VISUAL, 1 ); } +#endif // this is now done during creation of the renderer #if !SDL_VERSION_ATLEAST(2,0,0) +#ifndef HAVE_GLES DebugPrintf("vsync set to %d\n",render_info.vsync); SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, render_info.vsync ); #endif +#endif #endif } @@ -180,9 +197,11 @@ static void print_info( void ) ); #endif +#ifndef HAVE_GLES // actual depth size set by sdl SDL_GL_GetAttribute(SDL_GL_DEPTH_SIZE, &bpp); DebugPrintf("main_sdl: depth buffer is %d bpp\n", bpp); +#endif // TODO #if !SDL_VERSION_ATLEAST(2,0,0) @@ -200,10 +219,14 @@ static u_int32_t create_video_flags( void ) u_int32_t flags = SDL_ANYFORMAT; #ifdef GL +#ifndef HAVE_GLES flags |= SDL_OPENGL; #endif +#endif +#ifndef HAVE_GLES if(render_info.fullscreen) +#endif flags |= SDL_FULLSCREEN; return flags; @@ -257,6 +280,7 @@ static bool create_video_surface( u_int32_t window_flags, u_int32_t renderer_fla Msg("main_sdl: failed to create window: %s\n",SDL_GetError()); return false; } + render_info.renderer = SDL_CreateRenderer( render_info.window, -1, @@ -269,18 +293,27 @@ static bool create_video_surface( u_int32_t window_flags, u_int32_t renderer_fla } #else +#ifdef HAVE_GLES +render_info.ThisMode.w=800; +render_info.ThisMode.h=480; +window_flags=SDL_FULLSCREEN; +#endif render_info.screen = SDL_SetVideoMode( render_info.ThisMode.w, render_info.ThisMode.h, 0, // BPP should be left alone to match whatever the desktop is at. window_flags // on older sdl only 1 set of flags was used ); +printf("video_mode is %ix%i flags=%x\n", render_info.ThisMode.w,render_info.ThisMode.h,window_flags); if(!render_info.screen) { Msg("main_sdl: failed to create video surface: %s\n",SDL_GetError()); return false; } +#ifdef HAVE_GLES + EGL_Open(render_info.ThisMode.w,render_info.ThisMode.h); +#endif #endif print_info(); @@ -350,7 +383,12 @@ void sdl_render_present( render_info_t * info ) { #if SDL_VERSION_ATLEAST(2,0,0) SDL_RenderPresent(info->renderer); +#else +#ifdef HAVE_GLES +//printf("swap buffers\n"); + EGL_SwapBuffers(); #else SDL_GL_SwapBuffers(); #endif +#endif } diff --git a/mload.c b/mload.c index 652fadff..08ff45e6 100755 --- a/mload.c +++ b/mload.c @@ -839,7 +839,12 @@ bool Mload( char * Filename, MLOADHEADER * Mloadheader ) Buffer = (char *) Uint16Pnt; FloatPnt = ( float * ) Buffer; +#ifdef ARM + memcpy(&Mloadheader->CellSize, FloatPnt++, 4); + Mloadheader->CellSize = 1.0f/Mloadheader->CellSize; +#else Mloadheader->CellSize = 1.0F / *FloatPnt++; +#endif Buffer = (char * ) FloatPnt; for( group=0 ; groupnum_groups; group++) @@ -850,9 +855,14 @@ bool Mload( char * Filename, MLOADHEADER * Mloadheader ) for( execbuf=0 ; execbufGroup[group].num_execbufs; execbuf++) { FloatPnt = (float * ) Buffer; +#ifdef ARM + memcpy(&Mloadheader->Group[group].cell_origin[execbuf], FloatPnt, 4*3); + FloatPnt+=3; +#else Mloadheader->Group[group].cell_origin[execbuf].x = *FloatPnt++; Mloadheader->Group[group].cell_origin[execbuf].y = *FloatPnt++; Mloadheader->Group[group].cell_origin[execbuf].z = *FloatPnt++; +#endif Buffer = (char * ) FloatPnt; Uint16Pnt = (u_int16_t *) Buffer; Mloadheader->Group[group].xcells[execbuf] = *Uint16Pnt++; @@ -956,9 +966,14 @@ bool Mload( char * Filename, MLOADHEADER * Mloadheader ) up = (float *) Buffer; for ( i = 0; i < Mloadheader->num_groups; i++ ) { +#ifdef ARM + memcpy(&Mloadheader->Group[ i ].up, up, 4*3); + up+=3; +#else Mloadheader->Group[ i ].up.x = *up++; Mloadheader->Group[ i ].up.y = *up++; Mloadheader->Group[ i ].up.z = *up++; +#endif } Buffer = (char *) up; } @@ -1086,8 +1101,13 @@ bool Mload( char * Filename, MLOADHEADER * Mloadheader ) FloatPnt = (float*) Buffer; for( o = 0 ; o < vertices*frames ; o++ ) { +#ifdef ARM + memcpy(&TanimUV->u, FloatPnt++, 4); + memcpy(&TanimUV->v, FloatPnt++, 4); +#else TanimUV->u = *FloatPnt++; TanimUV->v = *FloatPnt++; +#endif TanimUV++; } Buffer = ( char * ) FloatPnt; @@ -1815,7 +1835,11 @@ void ReadSoundInfo( MLOADHEADER *m, char **pbuf ) { for ( k = 0; k < m->num_groups; k++ ) { +#ifdef ARM + memcpy(&SoundInfo[ j ][ k ], buf++, 4); +#else SoundInfo[ j ][ k ] = *buf++; +#endif } } diff --git a/models.c b/models.c index d57e813e..5f2904a3 100755 --- a/models.c +++ b/models.c @@ -867,7 +867,6 @@ bool InitModel( /*LPDIRECT3DDEVICE lpDev,*/ MODELNAME * NamePnt) // bjd if( !Mxaload( &TempFilename[0] , &MxaModelHeaders[i], NamePnt->StoreTriangles ) ) return false; // the model and visipoly data ModelHeaders[i].LOD = NamePnt->LOD; - TopLeft = TempVector; BottomRight = TempVector; GetMXABoundingBox( &MxaModelHeaders[i], &MATRIX_Identity, &TempVector, &TopLeft, &BottomRight ); diff --git a/mxaload.c b/mxaload.c index 1ba5f535..96af4a43 100755 --- a/mxaload.c +++ b/mxaload.c @@ -184,7 +184,6 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle Uint16Pnt = (u_int16_t *) Buffer; Mxaloadheader->num_groups = *Uint16Pnt++; Buffer = (char *) Uint16Pnt; - if ( Mxaloadheader->num_groups > MAXGROUPS ) { Msg( "Mxaload() num_groups > MAXGROUPS\n", Filename ); @@ -198,7 +197,7 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle Uint16Pnt = (u_int16_t *) Buffer; Mxaloadheader->Group[group].num_execbufs = *Uint16Pnt++; Buffer = (char *) Uint16Pnt; - + if ( Mxaloadheader->Group[group].num_execbufs > MAXEXECBUFSPERGROUP ) { Msg( "Mxaload() num_execbufs > MAXEXECBUFSPERGROUP\n", Filename ); @@ -217,7 +216,7 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle /* get the number of verts in execution buffer */ num_vertices = *Uint16Pnt++; Buffer = (char *) Uint16Pnt; - + /* record how what type of exec buffer */ Mxaloadheader->Group[group].exec_type[execbuf] = exec_type; @@ -267,7 +266,6 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle // lpLVERTEX->dwReserved = 0; lpLVERTEX2++; } - /* bjd - allows us to retrieve copies of the original vertices in the new format! */ Mxaloadheader->Group[group].originalVerts[execbuf] = malloc(sizeof(LVERTEX) * num_vertices); memmove(Mxaloadheader->Group[group].originalVerts[execbuf], &lpLVERTEX[0], sizeof(LVERTEX) * num_vertices);//memcpy @@ -317,7 +315,6 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle tempBuffer = (char *) MFacePnt; triangleCount += numTriangles; } - /* create an index buffer */ if (!FSCreateIndexBuffer(&Mxaloadheader->Group[group].renderObject[execbuf], triangleCount * 3)) { @@ -474,7 +471,6 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle } } - Uint16Pnt = (u_int16_t *) Buffer; // is there any vispoly info..... if ( *Uint16Pnt++ == 2) // 2 means .mxa format @@ -623,6 +619,14 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle { FirePointPtr->ID = *Uint16Pnt++; // ID ( u_int16_t ) FloatPnt = (float *) Uint16Pnt; +#ifdef ARM + memcpy(&FirePointPtr->Pos, FloatPnt, 4*3); // Pos ( 3 floats ) + FloatPnt+=3; + memcpy(&FirePointPtr->Dir, FloatPnt, 3*4); // Dir ( 3 floats ) + FloatPnt+=3; + memcpy(&FirePointPtr->Up, FloatPnt, 3*4); // Up ( 3 floats ) + FloatPnt+=3; +#else FirePointPtr->Pos.x = *FloatPnt++; // Pos ( 3 floats ) FirePointPtr->Pos.y = *FloatPnt++; FirePointPtr->Pos.z = *FloatPnt++; @@ -632,6 +636,7 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle FirePointPtr->Up.x = *FloatPnt++; // Up ( 3 floats ) FirePointPtr->Up.y = *FloatPnt++; FirePointPtr->Up.z = *FloatPnt++; +#endif Uint16Pnt = (u_int16_t *) FloatPnt; FirePointPtr++; } @@ -661,6 +666,17 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle { SpotFXPtr->Type = *Uint16Pnt++; // Type ( u_int16_t ) FloatPnt = (float *) Uint16Pnt; +#ifdef ARM + memcpy(&SpotFXPtr->Pos, FloatPnt, 4*3); + FloatPnt+=3; + memcpy(&SpotFXPtr->DirVector.x, FloatPnt, 4*3); + FloatPnt+=3; + memcpy(&SpotFXPtr->UpVector, FloatPnt, 4*3); + FloatPnt+=3; + memcpy(&SpotFXPtr->StartDelay, FloatPnt++, 4); SpotFXPtr->StartDelay*= ANIM_SECOND; // Start Delay + memcpy(&SpotFXPtr->ActiveDelay, FloatPnt++,4); SpotFXPtr->ActiveDelay*= ANIM_SECOND; // Active Delay + memcpy(&SpotFXPtr->InactiveDelay, FloatPnt++, 4); SpotFXPtr->InactiveDelay*= ANIM_SECOND; // Inactive Delay +#else SpotFXPtr->Pos.x = *FloatPnt++; // Pos ( 3 floats ) SpotFXPtr->Pos.y = *FloatPnt++; SpotFXPtr->Pos.z = *FloatPnt++; @@ -673,12 +689,12 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle SpotFXPtr->StartDelay = ( *FloatPnt++ * ANIM_SECOND ); // Start Delay SpotFXPtr->ActiveDelay = ( *FloatPnt++ * ANIM_SECOND ); // Active Delay SpotFXPtr->InactiveDelay = ( *FloatPnt++ * ANIM_SECOND ); // Inactive Delay +#endif Int16Pnt = (int16_t *) FloatPnt; SpotFXPtr->Primary = (int8_t) *Int16Pnt++; // Primary ( int16_t ) SpotFXPtr->Secondary = (int8_t) *Int16Pnt++; // Secondary ( int16_t ) Uint32Pnt = (u_int32_t *) Int16Pnt; Colour = *Uint32Pnt++; - #if MXA_VERSION_NUMBER == 2 // Int16Pnt = (int16_t *) Uint32Pnt; // SpotFXPtr->SoundFX = *Int16Pnt++; @@ -712,8 +728,13 @@ bool Mxaload( char * Filename, MXALOADHEADER * Mxaloadheader, bool StoreTriangle } FloatPnt = (float *) Int8Pnt; +#ifdef ARM + memcpy(&SpotFXPtr->SoundFXVolume, FloatPnt++, 4); + memcpy(&SpotFXPtr->SoundFXSpeed, FloatPnt++, 4); +#else SpotFXPtr->SoundFXVolume = *FloatPnt++; SpotFXPtr->SoundFXSpeed = *FloatPnt++; +#endif Uint16Pnt = (u_int16_t *) FloatPnt; #else Uint16Pnt = (u_int16_t *) Uint32Pnt; @@ -1001,11 +1022,22 @@ bool InterpFrames( MXALOADHEADER * Mxaloadheader , int FromFrame, int ToFrame , for( num_anim_vertices = 0 ; num_anim_vertices < Mxaloadheader->num_anim_vertices[FromFrame][group][execbuf][texgroup] ; num_anim_vertices++ ) { +#ifdef ARM + MXAVERT fromVert, toVert; + memcpy(&fromVert, FromVert, sizeof(MXAVERT)); + memcpy(&toVert, ToVert, sizeof(MXAVERT)); // To have them correctly alligned for ARM... +#endif if ( FromVert->flags & MXA_ANIM_POS ) { +#ifdef ARM + lpLVERTEX->x = fromVert.x + ( toVert.x - fromVert.x ) * Interp; + lpLVERTEX->y = fromVert.y + ( toVert.y - fromVert.y ) * Interp; + lpLVERTEX->z = fromVert.z + ( toVert.z - fromVert.z ) * Interp; +#else lpLVERTEX->x = FromVert->x + ( ToVert->x - FromVert->x ) * Interp; lpLVERTEX->y = FromVert->y + ( ToVert->y - FromVert->y ) * Interp; lpLVERTEX->z = FromVert->z + ( ToVert->z - FromVert->z ) * Interp; +#endif } if ( FromVert->flags & MXA_ANIM_RGB ) { @@ -1023,8 +1055,13 @@ bool InterpFrames( MXALOADHEADER * Mxaloadheader , int FromFrame, int ToFrame , } if ( FromVert->flags & MXA_ANIM_UV ) { - lpLVERTEX->tu = FromVert->tu + ( ToVert->tu - FromVert->tu ) * Interp; - lpLVERTEX->tv = FromVert->tv + ( ToVert->tv - FromVert->tv ) * Interp; +#ifdef ARM + lpLVERTEX->tu = fromVert.tu + ( toVert.tu - fromVert.tu ) * Interp; + lpLVERTEX->tv = fromVert.tv + ( toVert.tv - fromVert.tv ) * Interp; +#else + lpLVERTEX->tu = fromVert->tu + ( toVert->tu - fromVert->tu ) * Interp; + lpLVERTEX->tv = fromVert->tv + ( toVert->tv - fromVert->tv ) * Interp; +#endif } lpLVERTEX++; diff --git a/mxload.c b/mxload.c index d2fbaf63..6823b7a5 100755 --- a/mxload.c +++ b/mxload.c @@ -648,8 +648,13 @@ bool Mxload( char * Filename, MXLOADHEADER * Mxloadheader , bool Panel, bool Sto FloatPnt = (float*) Buffer; for( o = 0 ; o < vertices*frames ; o++ ) { +#ifdef ARM + memcpy(&TanimUV->u, FloatPnt++, 4); + memcpy(&TanimUV->v, FloatPnt++, 4); +#else TanimUV->u = *FloatPnt++; TanimUV->v = *FloatPnt++; +#endif TanimUV++; } Buffer = ( char * ) FloatPnt; @@ -704,6 +709,14 @@ bool Mxload( char * Filename, MXLOADHEADER * Mxloadheader , bool Panel, bool Sto { FirePointPtr->ID = *Uint16Pnt++; // ID ( u_int16_t ) FloatPnt = (float *) Uint16Pnt; +#ifdef ARM + memcpy(&FirePointPtr->Pos, FloatPnt, 4*3); // Pos ( 3 floats ) + FloatPnt+=3; + memcpy(&FirePointPtr->Dir, FloatPnt, 4*3); // Dir ( 3 floats ) + FloatPnt+=3; + memcpy(&FirePointPtr->Up, FloatPnt, 4*3); // Up ( 3 floats ) + FloatPnt+=3; +#else FirePointPtr->Pos.x = *FloatPnt++; // Pos ( 3 floats ) FirePointPtr->Pos.y = *FloatPnt++; FirePointPtr->Pos.z = *FloatPnt++; @@ -713,6 +726,7 @@ bool Mxload( char * Filename, MXLOADHEADER * Mxloadheader , bool Panel, bool Sto FirePointPtr->Up.x = *FloatPnt++; // Up ( 3 floats ) FirePointPtr->Up.y = *FloatPnt++; FirePointPtr->Up.z = *FloatPnt++; +#endif Uint16Pnt = (u_int16_t *) FloatPnt; FirePointPtr++; } @@ -742,6 +756,17 @@ bool Mxload( char * Filename, MXLOADHEADER * Mxloadheader , bool Panel, bool Sto { SpotFXPtr->Type = *Uint16Pnt++; // Type ( u_int16_t ) FloatPnt = (float *) Uint16Pnt; +#ifdef ARM + memcpy(&SpotFXPtr->Pos, FloatPnt, 3*4); // Pos ( 3 floats ) + FloatPnt+=3; + memcpy(&SpotFXPtr->DirVector, FloatPnt, 3*4); // Dir ( 3 floats ) + FloatPnt+=3; + memcpy(&SpotFXPtr->UpVector, FloatPnt, 3*4); // Up ( 3 floats ) + FloatPnt+=3; + memcpy(&SpotFXPtr->StartDelay, FloatPnt++, 4); SpotFXPtr->StartDelay *= ANIM_SECOND; // Start Delay + memcpy(&SpotFXPtr->ActiveDelay, FloatPnt++, 4); SpotFXPtr->ActiveDelay *= ANIM_SECOND; // Active Delay + memcpy(&SpotFXPtr->InactiveDelay, FloatPnt++, 4); SpotFXPtr->InactiveDelay *= ANIM_SECOND; // Inactive Delay +#else SpotFXPtr->Pos.x = *FloatPnt++; // Pos ( 3 floats ) SpotFXPtr->Pos.y = *FloatPnt++; SpotFXPtr->Pos.z = *FloatPnt++; @@ -754,6 +779,7 @@ bool Mxload( char * Filename, MXLOADHEADER * Mxloadheader , bool Panel, bool Sto SpotFXPtr->StartDelay = ( *FloatPnt++ * ANIM_SECOND ); // Start Delay SpotFXPtr->ActiveDelay = ( *FloatPnt++ * ANIM_SECOND ); // Active Delay SpotFXPtr->InactiveDelay = ( *FloatPnt++ * ANIM_SECOND ); // Inactive Delay +#endif Int16Pnt = (int16_t *) FloatPnt; SpotFXPtr->Primary = (int8_t) *Int16Pnt++; // Primary ( int16_t ) SpotFXPtr->Secondary = (int8_t) *Int16Pnt++; // Secondary ( int16_t ) @@ -793,8 +819,13 @@ bool Mxload( char * Filename, MXLOADHEADER * Mxloadheader , bool Panel, bool Sto } FloatPnt = (float *) Int8Pnt; +#ifdef ARM + memcpy(&SpotFXPtr->SoundFXVolume, FloatPnt++, 4); + memcpy(&SpotFXPtr->SoundFXSpeed, FloatPnt++, 4); +#else SpotFXPtr->SoundFXVolume = *FloatPnt++; SpotFXPtr->SoundFXSpeed = *FloatPnt++; +#endif Uint16Pnt = (u_int16_t *) FloatPnt; #else Uint16Pnt = (u_int16_t *) Uint32Pnt; diff --git a/node.c b/node.c index e04d91de..b9c6ed03 100755 --- a/node.c +++ b/node.c @@ -168,12 +168,16 @@ bool Nodeload( char * Filename ) FloatPnt = (float*) int16Pnt; NodePnt->NodeNum = e; - +#ifdef ARM + memcpy(&NodePnt->Pos, FloatPnt, 4*3); + FloatPnt+=3; + memcpy(&NodePnt->Radius, FloatPnt++, 4); +#else NodePnt->Pos.x = *FloatPnt++; NodePnt->Pos.y = *FloatPnt++; NodePnt->Pos.z = *FloatPnt++; NodePnt->Radius = *FloatPnt++; - +#endif u_int32Pnt = (u_int32_t*) FloatPnt; NodePnt->NetMask = *u_int32Pnt++; // which networks this node is in... diff --git a/render_gl1.c b/render_gl1.c old mode 100644 new mode 100755 index 7c3df409..a5ff7c7c --- a/render_gl1.c +++ b/render_gl1.c @@ -13,6 +13,11 @@ // so we can render the static objects as display lists // +#ifdef HAVE_GLES +#define glColor4ubv(a) glColor4ub((a)[0], (a)[1], (a)[2], (a)[3]) +#define gluOrtho2D(a, b, c, d) glOrthof(a, b, c, d, -1, 1) +#endif + bool FSCreateVertexBuffer(RENDEROBJECT *renderObject, int numVertices) { renderObject->lpVertexBuffer = malloc( numVertices * sizeof(LVERTEX) ); @@ -55,6 +60,7 @@ bool FSCreateDynamic2dVertexBuffer(RENDEROBJECT *renderObject, int numVertices) bool FSLockPretransformedVertexBuffer(RENDEROBJECT *renderObject, TLVERTEX **verts) {*verts = (void*)renderObject->lpVertexBuffer; return true;} +#ifndef HAVE_GLES static void set_color( COLOR c ) { // COLOR is the value loaded from the files @@ -63,6 +69,7 @@ static void set_color( COLOR c ) c = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16); glColor4ubv((GLubyte*)&c); } +#endif int render_color_blend_red = 0; int render_color_blend_green = 0; @@ -309,6 +316,21 @@ void light_vert( LVERTEX * vert, u_int8_t * color ) MIX_COLOR_BLEND_LIGHT( color[2], render_color_blend_red, r ); } } +#ifdef HAVE_GLES +#define MAX_VTX 10240 +static GLfloat vtx[MAX_VTX*3]; +static GLfloat tex[MAX_VTX*2]; +static COLOR col[MAX_VTX]; +static int idx; +static void set_color( COLOR c ) +{ + // COLOR is the value loaded from the files + // it's packed as uchar[4] (bgra) and glColor expects (rgba) + // so we flip the red/blue values with each other + c = (c & 0xff00ff00) | ((c & 0x00ff0000) >> 16) | ((c & 0x000000ff) << 16); + col[idx]=c; +} +#endif static void draw_vert( void * _vert, bool orthographic ) { @@ -317,8 +339,14 @@ static void draw_vert( void * _vert, bool orthographic ) if(orthographic) { set_color( tlvert->color ); +#ifdef HAVE_GLES + tex[idx*2+0]=tlvert->tu; tex[idx*2+1]=tlvert->tv; + vtx[idx*2+0]=tlvert->x; vtx[idx*2+1]=tlvert->y; + idx++; +#else glTexCoord2f( tlvert->tu, tlvert->tv ); glVertex2f( tlvert->x, tlvert->y ); +#endif } else { @@ -329,8 +357,14 @@ static void draw_vert( void * _vert, bool orthographic ) #else set_color( vert->color ); #endif +#ifdef HAVE_GLES + tex[idx*2+0]=vert->tu; tex[idx*2+1]= vert->tv; + vtx[idx*3+0]=vert->x; vtx[idx*3+1]=vert->y; vtx[idx*3+2]=vert->z; + idx++; +#else glTexCoord2f( vert->tu, vert->tv ); glVertex3f( vert->x, vert->y, vert->z ); +#endif } } @@ -360,6 +394,11 @@ bool draw_render_object( RENDEROBJECT *renderObject, int primitive_type, bool or WORD * indices = (WORD*) renderObject->lpIndexBuffer; //assert(renderObject->vbLocked == 0); +#ifdef HAVE_GLES + glEnableClientState(GL_VERTEX_ARRAY); + glEnableClientState(GL_COLOR_ARRAY); + idx=0; +#endif if(orthographic) { @@ -388,11 +427,18 @@ bool draw_render_object( RENDEROBJECT *renderObject, int primitive_type, bool or if( renderObject->textureGroups[group].texture ) { GLuint texture = *(GLuint*)renderObject->textureGroups[group].texture; +//printf("group=%i, texture=%i\n", group, texture); glEnable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, texture); +#ifdef HAVE_GLES + glEnableClientState(GL_TEXTURE_COORD_ARRAY); +#endif } - +#ifdef HAVE_GLES + idx=0; +#else glBegin(primitive_type); +#endif // draw vertex list using index list if(renderObject->lpIndexBuffer) @@ -418,11 +464,22 @@ bool draw_render_object( RENDEROBJECT *renderObject, int primitive_type, bool or else draw_vert( &verts[i], orthographic ); } - +#ifdef HAVE_GLES + if( renderObject->textureGroups[group].texture ) + glTexCoordPointer(2, GL_FLOAT, 0, tex); + glColorPointer(4, GL_UNSIGNED_BYTE, 0, col); + glVertexPointer((orthographic)?2:3, GL_FLOAT, 0, vtx); + glDrawArrays(primitive_type, 0, idx); +#else glEnd(); +#endif - if( renderObject->textureGroups[group].texture ) + if( renderObject->textureGroups[group].texture ) { glDisable(GL_TEXTURE_2D); +#ifdef HAVE_GLES + glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#endif + } if(renderObject->textureGroups[group].colourkey) unset_alpha_ignore(); @@ -433,7 +490,10 @@ bool draw_render_object( RENDEROBJECT *renderObject, int primitive_type, bool or glMatrixMode(GL_PROJECTION); glPopMatrix(); } - +#ifdef HAVE_GLES + glDisableClientState(GL_VERTEX_ARRAY); + glDisableClientState(GL_COLOR_ARRAY); +#endif return true; } diff --git a/render_gl_shared.c b/render_gl_shared.c old mode 100644 new mode 100755 index bdca529f..648fac70 --- a/render_gl_shared.c +++ b/render_gl_shared.c @@ -36,7 +36,11 @@ const char * render_error_description( int e ) { CHECK_GL_ERRORS; if(render_last_gl_error != GL_NO_ERROR) + #ifdef HAVE_GLES + return (const char*) "Error"; + #else return (const char *) gluErrorString(render_last_gl_error); + #endif else return NULL; } @@ -45,17 +49,23 @@ const char * render_error_description( int e ) void render_mode_wireframe(void) { +#ifndef HAVE_GLES glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); +#endif } void render_mode_points(void) { +#ifndef HAVE_GLES glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); +#endif } void render_mode_fill(void) { +#ifndef HAVE_GLES glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); +#endif } // unused in opengl @@ -105,12 +115,70 @@ void release_texture( LPTEXTURE texture ) free(texture); } +static void DownSizeTexture( unsigned *in, int inWidth, int inHeight ) { + int i, j, k; + unsigned char *outpix; + int inWidthMask, inHeightMask; + int total; + int outWidth, outHeight; + unsigned *temp; + + outWidth = inWidth >> 1; + outHeight = inHeight >> 1; + temp = malloc( outWidth * outHeight * 4 ); + + inWidthMask = inWidth - 1; + inHeightMask = inHeight - 1; + + for ( i = 0 ; i < outHeight ; i++ ) { + for ( j = 0 ; j < outWidth ; j++ ) { + outpix = (unsigned char *) ( temp + i * outWidth + j ); + for ( k = 0 ; k < 4 ; k++ ) { + total = + 1 * ((unsigned char *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + + 2 * ((unsigned char *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + + 2 * ((unsigned char *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + + 1 * ((unsigned char *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] + + + 2 * ((unsigned char *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + + 4 * ((unsigned char *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + + 4 * ((unsigned char *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + + 2 * ((unsigned char *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] + + + 2 * ((unsigned char *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + + 4 * ((unsigned char *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + + 4 * ((unsigned char *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + + 2 * ((unsigned char *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] + + + 1 * ((unsigned char *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + + 2 * ((unsigned char *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + + 2 * ((unsigned char *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + + 1 * ((unsigned char *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k]; + outpix[k] = total / 36; + } + } + } + + memcpy( in, temp, outWidth * outHeight * 4 ); + free( temp ); +} + + static bool create_texture(LPTEXTURE *t, const char *path, u_int16_t *width, u_int16_t *height, int numMips, bool * colorkey) { texture_t *texdata; texture_image_t image; Change_Ext( path, image.path, ".PNG" ); +/* Need to change \ to / and remove all capital letters ! */ +#ifdef PANDORA + int idx= 0; + while(image.path[idx]!='\0') { + if (image.path[idx]=='\\') image.path[idx]='/'; + if ((image.path[idx]>='A') && (image.path[idx]<='Z')) image.path[idx]+='a'-'A'; + idx++; + } +#endif if( ! File_Exists( (char*) image.path ) ) { DebugPrintf("Could not find texture file: %s\n",path); @@ -127,6 +195,15 @@ static bool create_texture(LPTEXTURE *t, const char *path, u_int16_t *width, u_i *width = (u_int16_t) image.w; *height = (u_int16_t) image.h; (*colorkey) = (bool) image.colorkey; + +#ifdef PANDORA + // resize bigger texture, they are way too big for Pandora memory, and Pandora screen + if (!(image.colorkey) && ((image.w>=128) || (image.h>=128))) { + DownSizeTexture(image.data, image.w, image.h); + image.w/=2; + image.h/=2; + } +#endif // employ colour key and gamma correction { @@ -142,21 +219,26 @@ static bool create_texture(LPTEXTURE *t, const char *path, u_int16_t *width, u_i // (x*size) is the length of each pixel data (column) DWORD index = (y*pitch)+(x*size); - // image.data is packed in rgba - image.data[index] = (char) gamma_table[ (u_int8_t) image.data[index]]; // red - image.data[index+1] = (char) gamma_table[ (u_int8_t) image.data[index+1]]; // green - image.data[index+2] = (char) gamma_table[ (u_int8_t) image.data[index+2]]; // blue - image.data[index+3] = (char) gamma_table[ (u_int8_t) image.data[index+3]]; // alpha - // colour key if( image.colorkey && (image.data[index] + image.data[index+1] + image.data[index+2]) == 0 ) image.data[index+3] = 0; // alpha - pixel will not be rendered do to alpha value tests - + else + { + // image.data is packed in rgba + image.data[index] = (char) gamma_table[ (u_int8_t) image.data[index]]; // red + image.data[index+1] = (char) gamma_table[ (u_int8_t) image.data[index+1]]; // green + image.data[index+2] = (char) gamma_table[ (u_int8_t) image.data[index+2]]; // blue + //image.data[index+3] = (char) gamma_table[ (u_int8_t) image.data[index+3]]; // alpha *SEB* no gamma on alpha + } } } } glPixelStorei(GL_UNPACK_ALIGNMENT, 1); +#ifdef HAVE_GLES + glPixelStorei(GL_PACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, GL_TRUE); +#endif // create a new opengl texture if( ! *t ) @@ -175,19 +257,25 @@ static bool create_texture(LPTEXTURE *t, const char *path, u_int16_t *width, u_i glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, image.w, image.h, GL_RGBA, GL_UNSIGNED_BYTE, image.data); CHECK_GL_ERRORS; } +//printf("load image \"%s\", size=%ix%i, colorkey=%i, numMips=%i, glTexture=%i\n", image.path, *width, *height, *colorkey, numMips, texdata->id); // when texture area is small, bilinear filter the closest mipmap +#ifdef HAVE_GLES + glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); +#else glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST ); +#endif // when texture area is large, bilinear filter the original glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); // the texture wraps over at the edges (repeat) glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ); - +#ifndef HAVE_GLES // anisotropic settings if(caps.anisotropic) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, caps.anisotropic); - +#endif +#ifndef HAVE_GLES #if GL > 1 glGenerateMipmap( GL_TEXTURE_2D ); #else @@ -198,7 +286,7 @@ static bool create_texture(LPTEXTURE *t, const char *path, u_int16_t *width, u_i return false; } #endif - +#endif if ( render_error_description(0) ) return false; @@ -225,15 +313,20 @@ bool FSCreateTexture(LPTEXTURE *texture, const char *fileName, u_int16_t *width, static void print_info( void ) { +#ifndef HAVE_GLES GLboolean b; glGetBooleanv(GL_STEREO,&b); - +#endif DebugPrintf( "gl vendor='%s', renderer='%s', version='%s', shader='%s', stereo='%s'\n", glGetString(GL_VENDOR), glGetString(GL_RENDERER), glGetString(GL_VERSION), +#ifdef HAVE_GLES + "none", "false"); +#else glGetString(GL_SHADING_LANGUAGE_VERSION), (b)?"true":"false"); +#endif #if GL < 3 DebugPrintf( "extensions='%s'\n", glGetString(GL_EXTENSIONS)); @@ -698,6 +791,10 @@ void set_whiteout_state( void ) // perhaps we can automate and remove need for rect arg ? // clears color/zbuff same time to opaque black +#ifdef HAVE_GLES +#define glClearDepth glClearDepthf +#define glDepthRange glDepthRangef +#endif bool FSClear(XYRECT * rect) { int width = rect->x2 - rect->x1; diff --git a/render_gl_shared.h b/render_gl_shared.h old mode 100644 new mode 100755 index 980b889c..ea0dfe9f --- a/render_gl_shared.h +++ b/render_gl_shared.h @@ -13,7 +13,11 @@ #include "file.h" #include #include "main_sdl.h" +#ifdef HAVE_GLES +#include "SDL_opengles.h" +#else #include "SDL_opengl.h" +#endif extern render_info_t render_info; @@ -36,6 +40,19 @@ extern GLenum render_last_gl_error; const char * render_error_description( int e ); +#ifdef HAVE_GLES +#define CHECK_GL_ERRORS \ + do \ + { \ + GLenum e; \ + while( ( e = glGetError() ) != GL_NO_ERROR ) \ + { \ + render_last_gl_error = e; \ + DebugPrintf( "GL error: %i (%s:%d)\n", \ + e, __FILE__, __LINE__ ); \ + } \ + } while (0) +#else #define CHECK_GL_ERRORS \ do \ { \ @@ -47,7 +64,7 @@ const char * render_error_description( int e ); gluErrorString(e), __FILE__, __LINE__ ); \ } \ } while (0) - +#endif typedef struct { float anisotropic; } gl_caps_t; extern gl_caps_t caps; diff --git a/teleport.c b/teleport.c index 10e33202..382190d4 100755 --- a/teleport.c +++ b/teleport.c @@ -159,7 +159,18 @@ bool TeleportsLoad( char * Filename ) Buffer = (char *) Uint16Pnt; floatpnt = (float *) Buffer; - +#ifdef ARM + memcpy(&TPpnt->Pos, floatpnt, 4*3); + floatpnt+=3; +#if TELEPORTS_VERSION_NUMBER >= 2 + memcpy(&TPpnt->Dir, floatpnt, 4*3); + floatpnt+=3; + memcpy(&TPpnt->Up, floatpnt, 4*3); + floatpnt+=3; +#endif + memcpy(&TPpnt->half_size, floatpnt, 4*3); + floatpnt+=3; +#else TPpnt->Pos.x = *floatpnt++; TPpnt->Pos.y = *floatpnt++; TPpnt->Pos.z = *floatpnt++; @@ -177,6 +188,7 @@ bool TeleportsLoad( char * Filename ) TPpnt->half_size.x = *floatpnt++; TPpnt->half_size.y = *floatpnt++; TPpnt->half_size.z = *floatpnt++; +#endif Buffer = (char *) floatpnt; Uint16Pnt = (u_int16_t *) Buffer; @@ -201,10 +213,16 @@ bool TeleportsLoad( char * Filename ) floatpnt = (float * ) Buffer; for( j = 0 ; j < TPpnt->num_sides ; j++ ) { +#ifdef ARM + memcpy(&ZonePnt->normal, floatpnt, 4*3); + floatpnt+=3; + memcpy(&ZonePnt->offset, floatpnt++, 4); +#else ZonePnt->normal.x = *floatpnt++; ZonePnt->normal.y = *floatpnt++; ZonePnt->normal.z = *floatpnt++; ZonePnt->offset = *floatpnt++; +#endif ZonePnt++; } Buffer = (char*) floatpnt; diff --git a/title.c b/title.c index 5ea35694..eab07bcc 100755 --- a/title.c +++ b/title.c @@ -8123,7 +8123,7 @@ void GetDefaultPilot(void) else { char * name; - if( (name = find_file( "Pilots\\*.txt" ))) + if( (name = find_file( "pilots\\*.txt" ))) { strncpy( &pilot_name[0], name, sizeof(pilot_name) ); @@ -9336,7 +9336,11 @@ void GetGamePrefs( void ) CLAMP( WaterDetailSlider.value, WaterDetailSlider.max ); SetWaterDetail( &WaterDetailSlider ); +#ifdef PANDORA + TextScaleSlider.value = config_get_int("TextScale", 1.0F); // need bigger font on the Pandora +#else TextScaleSlider.value = config_get_int("TextScale", 0.0F); +#endif CLAMP(TextScaleSlider.value, TextScaleSlider.max); SetTextScale( &TextScaleSlider ); diff --git a/trigarea.c b/trigarea.c index b8a12b94..fe57e63d 100755 --- a/trigarea.c +++ b/trigarea.c @@ -153,7 +153,11 @@ bool TriggerAreaload( char * Filename ) AreaPnt->group = *u_int16_tpnt++; AreaPnt->generation_type = *u_int16_tpnt++; floatpnt = (float * ) u_int16_tpnt; +#ifdef ARM + memcpy(&AreaPnt->generation_delay, floatpnt++, 4); +#else AreaPnt->generation_delay = *floatpnt++; +#endif u_int16_tpnt = (u_int16_t *) floatpnt; if( AreaPnt->generation_type != TRIGGER_AREA_GENTYPE_Initialised ) @@ -166,14 +170,19 @@ bool TriggerAreaload( char * Filename ) AreaPnt->type = *u_int16_tpnt++; floatpnt = (float * ) u_int16_tpnt; - +#ifdef ARM + memcpy(&AreaPnt->pos, floatpnt, 4*3); + floatpnt+=3; + memcpy(&AreaPnt->half_size, floatpnt, 4*3); + floatpnt+=3; +#else AreaPnt->pos.x = *floatpnt++; AreaPnt->pos.y = *floatpnt++; AreaPnt->pos.z = *floatpnt++; AreaPnt->half_size.x = *floatpnt++; AreaPnt->half_size.y = *floatpnt++; AreaPnt->half_size.z = *floatpnt++; - +#endif Buffer = (char*) floatpnt; if( AreaPnt->type != ZONE_Sphere ) { @@ -188,10 +197,16 @@ bool TriggerAreaload( char * Filename ) for( j = 0 ; j < AreaPnt->num_sides ; j++ ) { +#ifdef ARM + memcpy(&ZonePnt->normal, floatpnt, 4*3); + floatpnt+=3; + memcpy(&ZonePnt->offset, floatpnt++, 4); +#else ZonePnt->normal.x = *floatpnt++; ZonePnt->normal.y = *floatpnt++; ZonePnt->normal.z = *floatpnt++; ZonePnt->offset = *floatpnt++; +#endif ZonePnt++; } Buffer = (char*) floatpnt; diff --git a/triggers.c b/triggers.c index 2927b4e3..63c4f5e9 100755 --- a/triggers.c +++ b/triggers.c @@ -988,7 +988,12 @@ bool Triggerload( char * Filename ) m->Val = *intpnt++; floatptr = (float*) intpnt; +#ifdef ARM + memcpy(&m->Time, floatptr++, 4); + m->Time *= 60.0f; +#else m->Time = *floatptr++ * 60.0F; +#endif intpnt = (int*) floatptr; j = *intpnt++; diff --git a/water.c b/water.c index 2689d59d..bb5faf62 100755 --- a/water.c +++ b/water.c @@ -220,13 +220,24 @@ bool WaterLoad( void ) Uint16Pnt = (u_int16_t *) Buffer; WO->Group = *Uint16Pnt++; FloatPnt = (float*) Uint16Pnt; - +#ifdef ARM + memcpy(&WO->Pos, FloatPnt, 4*3); + FloatPnt+=3; +#else WO->Pos.x = *FloatPnt++; WO->Pos.y = *FloatPnt++; WO->Pos.z = *FloatPnt++; +#endif WO->offset = 0.0F; GroupWaterLevel[WO->Group] = WO->Pos.y + WATER_CELLSIZE; - +#ifdef ARM + memcpy(&WO->XSize, FloatPnt++, 4); + memcpy(&WO->YSize, FloatPnt++, 4); + memcpy(&WO->uTL, FloatPnt++, 4); + memcpy(&WO->vTL, FloatPnt++, 4); + memcpy(&WO->uBR, FloatPnt++, 4); + memcpy(&WO->vBR, FloatPnt++, 4); +#else WO->XSize = *FloatPnt++; WO->YSize = *FloatPnt++; @@ -234,7 +245,7 @@ bool WaterLoad( void ) WO->vTL = *FloatPnt++; // Uv coords... Top Left... WO->uBR = *FloatPnt++; // Uv coords... Bottom Right... WO->vBR = *FloatPnt++; // Uv coords... Bottom Right... - +#endif WO->uRange = WO->uBR - WO->uTL; WO->vRange = WO->vBR - WO->vTL; @@ -271,13 +282,21 @@ bool WaterLoad( void ) Buffer = (char*) D3DColourPnt; FloatPnt = (float*) Buffer; - +#ifdef ARM + memcpy(&WO->MaxLevel, FloatPnt++, 4); + memcpy(&WO->MinLevel, FloatPnt++, 4); + memcpy(&WO->FillRate, FloatPnt++, 4); WO->FillRate/=60.0f; + memcpy(&WO->DrainRate, FloatPnt++, 4); WO->DrainRate/=60.0f; + memcpy(&WO->Density, FloatPnt++, 4); + memcpy(&WO->MaxWaveSize, FloatPnt++, 4); +#else WO->MaxLevel = *FloatPnt++; WO->MinLevel = *FloatPnt++; WO->FillRate = *FloatPnt++ / 60.0F; WO->DrainRate = *FloatPnt++ / 60.0F; WO->Density = *FloatPnt++; WO->MaxWaveSize = *FloatPnt++; +#endif Buffer = (char *) FloatPnt; Uint16Pnt = (u_int16_t *) Buffer;