Adding first APK build
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -380,9 +380,25 @@
|
||||
-include precompiled.h
|
||||
)
|
||||
|
||||
-add_executable(systemshock
|
||||
- ${MAC_SRC}
|
||||
-)
|
||||
+# Android has no standalone executables (Java loads a shared library via
|
||||
+# JNI instead), so this is the one part of this file Android needs to
|
||||
+# override - see android/engine-patches/. Everything else here (sources,
|
||||
+# dependency discovery, link libraries) is untouched and applies the same
|
||||
+# way on both platforms. ANDROID_EXTRA_SOURCES (passed in by
|
||||
+# android/app/build.gradle) is QuestShockActivity's own small native
|
||||
+# helper (android/app/src/main/cpp/) - not part of engine/ itself.
|
||||
+if(ANDROID)
|
||||
+ set(SHOCKOLATE_TARGET main)
|
||||
+ add_library(${SHOCKOLATE_TARGET} SHARED
|
||||
+ ${MAC_SRC}
|
||||
+ ${ANDROID_EXTRA_SOURCES}
|
||||
+ )
|
||||
+else()
|
||||
+ set(SHOCKOLATE_TARGET systemshock)
|
||||
+ add_executable(${SHOCKOLATE_TARGET}
|
||||
+ ${MAC_SRC}
|
||||
+ )
|
||||
+endif()
|
||||
|
||||
add_library(GAME_LIB ${GAME_SRC})
|
||||
|
||||
@@ -391,7 +407,7 @@
|
||||
set(WINDOWS_LIBRARIES "mingw32 -mwindows")
|
||||
endif(MINGW)
|
||||
|
||||
-target_link_libraries(systemshock
|
||||
+target_link_libraries(${SHOCKOLATE_TARGET}
|
||||
${WINDOWS_LIBRARIES} # Set it before any linker options! Beware WinMain@16 error!!
|
||||
GAME_LIB
|
||||
UI_LIB
|
||||
@@ -418,7 +434,10 @@
|
||||
${ALSA_LIBRARIES}
|
||||
)
|
||||
|
||||
-# Turn on address sanitizing if wanted
|
||||
-set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/externals/sanitizers/cmake" ${CMAKE_MODULE_PATH})
|
||||
-find_package(Sanitizers)
|
||||
-add_sanitizers(systemshock)
|
||||
+# Turn on address sanitizing if wanted (desktop only - not meaningful for
|
||||
+# an Android release build)
|
||||
+if(NOT ANDROID)
|
||||
+ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/externals/sanitizers/cmake" ${CMAKE_MODULE_PATH})
|
||||
+ find_package(Sanitizers)
|
||||
+ add_sanitizers(${SHOCKOLATE_TARGET})
|
||||
+endif()
|
||||
@@ -0,0 +1,20 @@
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -46,9 +46,15 @@
|
||||
|
||||
add_compile_options(-fsigned-char -fno-strict-aliasing)
|
||||
|
||||
-# Find OpenGL
|
||||
+# Find OpenGL. Android has no desktop GL/GLX for CMake's FindOpenGL module
|
||||
+# to find - just link the NDK's own GLESv2/EGL libraries directly.
|
||||
if(ENABLE_OPENGL)
|
||||
- find_package(OpenGL REQUIRED)
|
||||
+ if(ANDROID)
|
||||
+ set(OPENGL_INCLUDE_DIRS "")
|
||||
+ set(OPENGL_LIBRARIES GLESv2 EGL)
|
||||
+ else()
|
||||
+ find_package(OpenGL REQUIRED)
|
||||
+ endif()
|
||||
add_definitions(-DUSE_OPENGL)
|
||||
if(WIN32)
|
||||
list(APPEND OPENGL_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/build_ext/built_glew/include)
|
||||
@@ -0,0 +1,24 @@
|
||||
--- a/src/MacSrc/Shock.c 2026-07-19 21:10:52.654910439 +0200
|
||||
+++ b/src/MacSrc/Shock.c 2026-07-19 21:10:52.658910394 +0200
|
||||
@@ -167,9 +167,21 @@
|
||||
}
|
||||
|
||||
// TODO: figure out some universal set of settings that work...
|
||||
+#ifdef __ANDROID__
|
||||
+ // Desktop GL's compatibility/core profile split doesn't exist on
|
||||
+ // Android - EGL only ever gives out GLES contexts. Quest hardware
|
||||
+ // (Adreno on the XR2/XR2 Gen 2) supports GLES 3.2, which - unlike
|
||||
+ // GLES 2.0 - has GL_UNPACK_ROW_LENGTH and GL_CLAMP_TO_BORDER as core
|
||||
+ // (see android/engine-patches/03-android-opengl-es-render.patch),
|
||||
+ // avoiding needing workarounds for either in OpenGL.cc.
|
||||
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
|
||||
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 3);
|
||||
+ SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 2);
|
||||
+#else
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
|
||||
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
|
||||
+#endif
|
||||
SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
|
||||
SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
|
||||
@@ -0,0 +1,159 @@
|
||||
--- a/src/MacSrc/OpenGL.cc
|
||||
+++ b/src/MacSrc/OpenGL.cc
|
||||
@@ -7,6 +7,11 @@
|
||||
#define GLEW_STATIC 1
|
||||
#include <SDL.h>
|
||||
#include <GL/glew.h>
|
||||
+#elif defined(__ANDROID__)
|
||||
+// GLES 3.2 (see Shock.c's context creation) - none of the desktop GL
|
||||
+// headers below exist on Android; EGL only ever gives out GLES contexts.
|
||||
+#include <SDL.h>
|
||||
+#include <GLES3/gl32.h>
|
||||
#else
|
||||
#define GL_GLEXT_PROTOTYPES
|
||||
#ifdef __APPLE__
|
||||
@@ -20,6 +25,112 @@
|
||||
#include <SDL_opengl.h>
|
||||
#endif
|
||||
|
||||
+#ifdef __ANDROID__
|
||||
+// GLES has no immediate-mode rendering (glBegin/glVertex3f/glEnd, used
|
||||
+// throughout this file below) at all. These macros transparently replace
|
||||
+// it with an equivalent that accumulates vertex data into arrays and
|
||||
+// issues one glDrawArrays call at glEnd() time - every actual call site
|
||||
+// below (all unchanged) looks identical on both platforms. "position",
|
||||
+// bound to attribute location 0 in CreateShader() below, replaces
|
||||
+// gl_Vertex (a desktop-only builtin android/gles-shaders/main.vert can't
|
||||
+// use either).
|
||||
+#define glBegin questshock_glBegin
|
||||
+#define glVertex3f questshock_glVertex3f
|
||||
+#define glEnd questshock_glEnd
|
||||
+#define glVertexAttrib1f questshock_glVertexAttrib1f
|
||||
+#define glVertexAttrib2f questshock_glVertexAttrib2f
|
||||
+#define glPointSize questshock_glPointSize
|
||||
+
|
||||
+// Generous enough for both the largest opengl_draw_poly() polygon and a
|
||||
+// full frame's worth of opengl_draw_star() points accumulated between one
|
||||
+// opengl_begin_stars()/opengl_end_stars() pair.
|
||||
+static const int QUESTSHOCK_MAX_IM_VERTS = 4096;
|
||||
+static float questshock_im_pos[QUESTSHOCK_MAX_IM_VERTS * 3];
|
||||
+static float questshock_im_tc[QUESTSHOCK_MAX_IM_VERTS * 2];
|
||||
+static float questshock_im_light[QUESTSHOCK_MAX_IM_VERTS];
|
||||
+static int questshock_im_count;
|
||||
+static GLenum questshock_im_mode;
|
||||
+static float questshock_im_cur_tc[2];
|
||||
+static float questshock_im_cur_light;
|
||||
+static float questshock_point_size = 1.0f;
|
||||
+
|
||||
+// GLES has no glPointSize() at all - point size is instead read from
|
||||
+// gl_PointSize, set by a "pointSize" uniform in
|
||||
+// android/gles-shaders/main.vert. Stashed here and applied in
|
||||
+// questshock_glEnd() below, since opengl_begin_stars() calls this before
|
||||
+// glUseProgram(starShaderProgram...) - the star shader isn't the current
|
||||
+// program yet at this point.
|
||||
+static void questshock_glPointSize(GLfloat size) { questshock_point_size = size; }
|
||||
+
|
||||
+static void questshock_glBegin(GLenum mode) {
|
||||
+ questshock_im_mode = mode;
|
||||
+ questshock_im_count = 0;
|
||||
+ questshock_im_cur_tc[0] = questshock_im_cur_tc[1] = 0.0f;
|
||||
+ questshock_im_cur_light = 0.0f;
|
||||
+}
|
||||
+
|
||||
+static void questshock_glVertexAttrib1f(GLuint index, GLfloat v) {
|
||||
+ // Only ever called for "light" at these call sites.
|
||||
+ (void)index;
|
||||
+ questshock_im_cur_light = v;
|
||||
+}
|
||||
+
|
||||
+static void questshock_glVertexAttrib2f(GLuint index, GLfloat a, GLfloat b) {
|
||||
+ // Only ever called for "texcoords" at these call sites.
|
||||
+ (void)index;
|
||||
+ questshock_im_cur_tc[0] = a;
|
||||
+ questshock_im_cur_tc[1] = b;
|
||||
+}
|
||||
+
|
||||
+static void questshock_glVertex3f(GLfloat x, GLfloat y, GLfloat z) {
|
||||
+ if (questshock_im_count >= QUESTSHOCK_MAX_IM_VERTS)
|
||||
+ return;
|
||||
+ questshock_im_pos[questshock_im_count * 3 + 0] = x;
|
||||
+ questshock_im_pos[questshock_im_count * 3 + 1] = y;
|
||||
+ questshock_im_pos[questshock_im_count * 3 + 2] = z;
|
||||
+ questshock_im_tc[questshock_im_count * 2 + 0] = questshock_im_cur_tc[0];
|
||||
+ questshock_im_tc[questshock_im_count * 2 + 1] = questshock_im_cur_tc[1];
|
||||
+ questshock_im_light[questshock_im_count] = questshock_im_cur_light;
|
||||
+ questshock_im_count++;
|
||||
+}
|
||||
+
|
||||
+static void questshock_glEnd() {
|
||||
+ GLint program = 0;
|
||||
+ glGetIntegerv(GL_CURRENT_PROGRAM, &program);
|
||||
+ GLint posAttrib = glGetAttribLocation(program, "position");
|
||||
+ GLint tcAttrib = glGetAttribLocation(program, "texcoords");
|
||||
+ GLint lightAttrib = glGetAttribLocation(program, "light");
|
||||
+
|
||||
+ if (questshock_im_mode == GL_POINTS) {
|
||||
+ GLint pointSizeUniform = glGetUniformLocation(program, "pointSize");
|
||||
+ if (pointSizeUniform >= 0)
|
||||
+ glUniform1f(pointSizeUniform, questshock_point_size);
|
||||
+ }
|
||||
+
|
||||
+ if (posAttrib >= 0) {
|
||||
+ glVertexAttribPointer(posAttrib, 3, GL_FLOAT, GL_FALSE, 0, questshock_im_pos);
|
||||
+ glEnableVertexAttribArray(posAttrib);
|
||||
+ }
|
||||
+ if (tcAttrib >= 0) {
|
||||
+ glVertexAttribPointer(tcAttrib, 2, GL_FLOAT, GL_FALSE, 0, questshock_im_tc);
|
||||
+ glEnableVertexAttribArray(tcAttrib);
|
||||
+ }
|
||||
+ if (lightAttrib >= 0) {
|
||||
+ glVertexAttribPointer(lightAttrib, 1, GL_FLOAT, GL_FALSE, 0, questshock_im_light);
|
||||
+ glEnableVertexAttribArray(lightAttrib);
|
||||
+ }
|
||||
+
|
||||
+ glDrawArrays(questshock_im_mode, 0, questshock_im_count);
|
||||
+
|
||||
+ if (posAttrib >= 0)
|
||||
+ glDisableVertexAttribArray(posAttrib);
|
||||
+ if (tcAttrib >= 0)
|
||||
+ glDisableVertexAttribArray(tcAttrib);
|
||||
+ if (lightAttrib >= 0)
|
||||
+ glDisableVertexAttribArray(lightAttrib);
|
||||
+}
|
||||
+#endif // __ANDROID__
|
||||
+
|
||||
extern "C" {
|
||||
#include "mainloop.h"
|
||||
#include "map.h"
|
||||
@@ -229,6 +340,12 @@
|
||||
GLuint shaderProgram = glCreateProgram();
|
||||
glAttachShader(shaderProgram, vertShader);
|
||||
glAttachShader(shaderProgram, fragShader);
|
||||
+#ifdef __ANDROID__
|
||||
+ // Must be bound before linking. Matches questshock_glEnd()'s
|
||||
+ // glGetAttribLocation(program, "position") above and
|
||||
+ // android/gles-shaders/main.vert's "position" attribute.
|
||||
+ glBindAttribLocation(shaderProgram, 0, "position");
|
||||
+#endif
|
||||
glLinkProgram(shaderProgram);
|
||||
glUseProgram(shaderProgram);
|
||||
|
||||
@@ -313,10 +430,17 @@
|
||||
|
||||
glEnable(GL_CULL_FACE);
|
||||
glEnable(GL_BLEND);
|
||||
+#ifndef __ANDROID__
|
||||
+ // GLES has no fixed-function pipeline: no alpha test (emulated with a
|
||||
+ // discard in android/gles-shaders/texture.frag instead), and point
|
||||
+ // sprites are always implicitly on for GL_POINTS rendering (via
|
||||
+ // gl_PointCoord in android/gles-shaders/star.frag) - no enum/enable
|
||||
+ // for either exists in GLES at all.
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
glEnable(GL_POINT_SPRITE);
|
||||
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glAlphaFunc(GL_GEQUAL, 0.05f);
|
||||
+#endif
|
||||
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
CreateShader("main.vert", "texture.frag", &textureShaderProgram);
|
||||
CreateShader("main.vert", "color.frag", &colorShaderProgram);
|
||||
Reference in New Issue
Block a user