diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..0764ea1 --- /dev/null +++ b/Android.mk @@ -0,0 +1,26 @@ +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := Engine + +SDL_PATH := ../SDL +SDL_IMAGE_PATH := ../SDL_image +SDL_MIXER_PATH := ../SDL_mixer +SDL_TTF_PATH := ../SDL_ttf + +LOCAL_C_INCLUDES := \ + $(LOCAL_PATH)/include \ + $(LOCAL_PATH)/$(SDL_PATH)/include \ + $(LOCAL_PATH)/$(SDL_MIXER_PATH)/include \ + $(LOCAL_PATH)/$(SDL_IMAGE_PATH) \ + $(LOCAL_PATH)/$(SDL_TTF_PATH) + +# Add your application source files here... +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/src/*.c) + +LOCAL_SHARED_LIBRARIES := SDL2 SDL2_image SDL2_mixer SDL2_ttf + +LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid + +include $(BUILD_SHARED_LIBRARY) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8664283..9516207 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ add_library(${PROJECT_NAME} SHARED src/ObjectStore.c src/AssetManager.c src/reusable_ids.c + src/math_utils.c ) target_include_directories(${PROJECT_NAME} PUBLIC @@ -54,6 +55,7 @@ install(FILES include/ObjectStore.h include/AssetManager.h include/reusable_ids.h + include/math_utils.h CONFIGURATIONS Release DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} ) diff --git a/include/Renderer.h b/include/Renderer.h index d858a00..073a9a0 100644 --- a/include/Renderer.h +++ b/include/Renderer.h @@ -29,13 +29,6 @@ Renderer *create_renderer(SDL_Window *window); */ void get_render_output_size(Renderer *renderer, int32_t *w, int32_t *h); -/** - * Attempts to load an SDL_Texture from a file path. - * - * Returns a pointer to the object if it succeeds or NULL when it fails. - */ -SDL_Texture *load_texture(const Renderer *renderer, const char *path); - void render_clear(const Renderer *renderer, SDL_Color color); void fill_rect(const Renderer *renderer, SDL_Color color, float x, float y, float w, float h); @@ -45,6 +38,13 @@ void render_texture(const Renderer *renderer, SDL_Texture *texture, float x, float y, float w, float h); void swap_buffers(const Renderer *renderer); +/** + * Attempts to load an SDL_Texture from a file path. + * + * Returns a pointer to the object if it succeeds or NULL when it fails. + */ +SDL_Texture *load_texture(const Renderer *renderer, const char *path); + /** * Frees the memory allocated to the Renderer object and performs the * necessary cleanup. diff --git a/include/math_utils.h b/include/math_utils.h new file mode 100644 index 0000000..295580f --- /dev/null +++ b/include/math_utils.h @@ -0,0 +1,17 @@ +#ifndef MATH_UTILS_H +#define MATH_UTILS_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif // !__cplusplus + +int32_t max_int(int32_t a, int32_t b); +int32_t min_int(int32_t a, int32_t b); + +#ifdef __cplusplus +} +#endif // !__cplusplus + // +#endif // !MATH_UTILS_H diff --git a/src/GameEngine.c b/src/GameEngine.c index c503ebc..75ecd77 100644 --- a/src/GameEngine.c +++ b/src/GameEngine.c @@ -9,6 +9,7 @@ #include "SDL_image.h" #include "SDL_mixer.h" #include "SDL_pixels.h" +#include "SDL_platform.h" #include "SDL_render.h" #include "SDL_surface.h" #include "SDL_timer.h" @@ -18,11 +19,11 @@ #include "constants.h" #include "engine_build_config.h" #include "reusable_ids.h" -#include #include #include #include #include +#include #ifdef DEBUG_ENGINE #include @@ -42,8 +43,11 @@ bool init_engine(const char *game_name, WindowSize window_size, SDL_Color window_background_color, bool full_screen, uint8_t audio_tracks) { bool initialisation_complete = true; + const char *current_platform = SDL_GetPlatform(); - SDL_SetHint(SDL_HINT_VIDEODRIVER, "wayland,x11"); + if (strcmp(current_platform, "Linux") == 0) { + SDL_SetHint(SDL_HINT_VIDEODRIVER, "wayland,x11"); + } if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { #ifdef DEBUG_ENGINE @@ -53,7 +57,15 @@ bool init_engine(const char *game_name, WindowSize window_size, return false; } - uint32_t img_flags = IMG_INIT_PNG | IMG_INIT_TIF; + uint32_t img_flags = IMG_INIT_PNG; + if (strcmp(current_platform, "Android") != 0) { + // Apparently, Android devices don't support TIFF images, so we only enable + // TIFF support when we are not running Android. + // + // TODO (Abdelrahman): Check if iOS devices support TIFF images. + img_flags |= IMG_INIT_TIF; + } + if ((IMG_Init(img_flags) & img_flags) != img_flags) { #ifdef DEBUG_ENGINE printf("Failed to initialise SDL_image. Error: %s\n", IMG_GetError()); diff --git a/src/Renderer.c b/src/Renderer.c index 37e7574..da830bc 100644 --- a/src/Renderer.c +++ b/src/Renderer.c @@ -1,8 +1,10 @@ #include "Renderer.h" #include "SDL.h" #include "SDL_image.h" +#include "SDL_platform.h" #include "SDL_rect.h" #include "SDL_render.h" +#include "SDL_video.h" #include "engine_build_config.h" #include #include diff --git a/src/Window.c b/src/Window.c index 167a82b..4cd41a8 100644 --- a/src/Window.c +++ b/src/Window.c @@ -1,24 +1,55 @@ #include "Window.h" #include "Renderer.h" +#include "SDL_platform.h" #include "SDL_video.h" #include "engine_build_config.h" +#include "math_utils.h" #include - #include +#include #ifdef DEBUG_ENGINE #include #endif /* DEBUG_ENGINE */ +typedef enum { + MOBILE_ORIENTATION_LANDSCAPE, + MOBILE_ORIENTATION_PORTRAIT +} MobileOrientation; + bool init_window(Window *wnd, const char *title, WindowSize size, SDL_Color color, bool full_screen) { if (!wnd) { return false; } + const char *current_platform = SDL_GetPlatform(); + Uint32 window_flags = SDL_WINDOW_ALLOW_HIGHDPI; - if (full_screen) { + if (strcmp(current_platform, "Android") == 0 || + strcmp(current_platform, "iOS") == 0) { + // Calculate the mobile orientation based on the user-defined width and + // height + MobileOrientation orientation; + + if (size.width > size.height) { + orientation = MOBILE_ORIENTATION_LANDSCAPE; + } else { + orientation = MOBILE_ORIENTATION_PORTRAIT; + } + + SDL_DisplayMode mode; + SDL_GetCurrentDisplayMode(0, &mode); + + if (orientation == MOBILE_ORIENTATION_LANDSCAPE) { + size.width = max_int(mode.w, mode.h); + size.height = min_int(mode.w, mode.h); + } else { + size.width = min_int(mode.w, mode.h); + size.height = max_int(mode.w, mode.h); + } + } else if (full_screen) { window_flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; } @@ -52,7 +83,8 @@ bool init_window(Window *wnd, const char *title, WindowSize size, wnd->drawing_area.width = wnd->real_size.width; wnd->drawing_area.height = wnd->real_size.height; - if (full_screen) { + if (full_screen && strcmp(current_platform, "Android") != 0 && + strcmp(current_platform, "iOS") != 0) { // Fit the window into the screen when running in full screen mode on // a non-mobile platform. Mobile platforms will be handled differently @@ -84,6 +116,14 @@ bool init_window(Window *wnd, const char *title, WindowSize size, wnd->defined_size.width = mode.w; wnd->defined_size.height = mode.h; + } else if (strcmp(current_platform, "Android") == 0 || + strcmp(current_platform, "iOS") == 0) { + // Get the correct real_size and drawing_area when running on a mobile + // platform, since the get_render_output_size function doesn't work + // properly on mobile + + wnd->real_size.width = wnd->drawing_area.width = wnd->defined_size.width; + wnd->real_size.height = wnd->drawing_area.height = wnd->defined_size.height; } #ifdef DEBUG_ENGINE @@ -100,7 +140,10 @@ void clear_window(const Window *wnd) { return; } - if (wnd->full_screen) { + const char *current_platform = SDL_GetPlatform(); + + if (wnd->full_screen && strcmp(current_platform, "Android") != 0 && + strcmp(current_platform, "iOS") != 0) { // When rendering in full screen on a non-mobile platform, we fill the // entire screen with black, then fill an area that fits the window // dimensions with the user-defined backgroud color of the window diff --git a/src/math_utils.c b/src/math_utils.c new file mode 100644 index 0000000..52a6107 --- /dev/null +++ b/src/math_utils.c @@ -0,0 +1,6 @@ +#include "math_utils.h" +#include + +int32_t max_int(int32_t a, int32_t b) { return a >= b ? a : b; } + +int32_t min_int(int32_t a, int32_t b) { return a <= b ? a : b; }