From af6636009e2d9b0de1979fadf60f549da39f6e5f Mon Sep 17 00:00:00 2001 From: Sebastian Krzyszkowiak Date: Tue, 23 Aug 2016 02:13:15 +0200 Subject: [PATCH] make viewport configurable --- src/internal.c | 8 ++++++-- src/libsuperderpy.c | 9 +++++---- src/libsuperderpy.h | 14 +++++++++----- src/utils.c | 24 ++++++++++++++++++------ src/utils.h | 4 +++- 5 files changed, 41 insertions(+), 18 deletions(-) diff --git a/src/internal.c b/src/internal.c index de13139..499c182 100644 --- a/src/internal.c +++ b/src/internal.c @@ -91,8 +91,12 @@ SYMBOL_INTERNAL void Console_Load(struct Game *game) { } else { game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/DejaVuSansMono.ttf"), al_get_display_height(game->display)*0.025,0 ); } - game->_priv.console = al_create_bitmap((al_get_display_width(game->display) / 320) * 320, al_get_font_line_height(game->_priv.font_console)*5); - game->_priv.console_tmp = al_create_bitmap((al_get_display_width(game->display) / 320) * 320, al_get_font_line_height(game->_priv.font_console)*5); + int width = (al_get_display_width(game->display) / game->viewport.width) * game->viewport.width; + if (game->viewport.allow_non_integer) { + width = (al_get_display_width(game->display) / (float)game->viewport.width) * game->viewport.width; + } + game->_priv.console = al_create_bitmap(width, al_get_font_line_height(game->_priv.font_console)*5); + game->_priv.console_tmp = al_create_bitmap(width, al_get_font_line_height(game->_priv.font_console)*5); al_set_target_bitmap(game->_priv.console); al_clear_to_color(al_map_rgba(0,0,0,80)); al_set_target_bitmap(al_get_backbuffer(game->display)); diff --git a/src/libsuperderpy.c b/src/libsuperderpy.c index 719d5d1..91d73f9 100644 --- a/src/libsuperderpy.c +++ b/src/libsuperderpy.c @@ -35,11 +35,12 @@ #include "internal.h" #include "libsuperderpy.h" -SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* name) { +SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* name, struct libsuperderpy_viewport viewport) { struct Game *game = malloc(sizeof(struct Game)); game->name = name; + game->viewport_config = viewport; #ifdef ALLEGRO_MACOSX char exe_path[MAXPATHLEN]; @@ -125,18 +126,18 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* al_set_new_window_position(20, 40); // workaround nasty Windows bug with window being created off-screen #endif + al_set_new_window_title(game->name); game->display = al_create_display(game->config.width, game->config.height); if(!game->display) { fprintf(stderr, "failed to create display!\n"); return NULL; } - SetupViewport(game); + SetupViewport(game, viewport); PrintConsole(game, "Viewport %dx%d", game->viewport.width, game->viewport.height); ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(game, GetGameName(game, "icons/%s.png"))); - al_set_window_title(game->display, game->name); al_set_display_icon(game->display, icon); al_destroy_bitmap(icon); @@ -371,7 +372,7 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) { break; } else if(ev.type == ALLEGRO_EVENT_DISPLAY_FOUND) { - SetupViewport(game); + SetupViewport(game, game->viewport_config); } #ifdef ALLEGRO_MACOSX else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == 104)) { //TODO: report to upstream diff --git a/src/libsuperderpy.h b/src/libsuperderpy.h index 0c1bd31..19653e9 100644 --- a/src/libsuperderpy.h +++ b/src/libsuperderpy.h @@ -47,16 +47,20 @@ struct libsuperderpy_list { struct libsuperderpy_list *next; }; +struct libsuperderpy_viewport { + int width; /*!< Actual available width of the drawing canvas. */ + int height; /*!< Actual available height of the drawing canvas. */ + float aspect; + bool allow_non_integer; +}; + /*! \brief Main struct of the game. */ struct Game { ALLEGRO_DISPLAY *display; /*!< Main Allegro display. */ ALLEGRO_TRANSFORM projection; /*!< Projection of the game canvas into the actual game window. */ - struct { - int width; /*!< Actual available width of the drawing canvas. */ - int height; /*!< Actual available height of the drawing canvas. */ - } viewport; + struct libsuperderpy_viewport viewport, viewport_config; struct { int fx; /*!< Effects volume. */ @@ -131,7 +135,7 @@ struct Game { }; -struct Game* libsuperderpy_init(int argc, char **argv, const char* name); +struct Game* libsuperderpy_init(int argc, char **argv, const char* name, struct libsuperderpy_viewport viewport); int libsuperderpy_run(struct Game* game); void libsuperderpy_destroy(struct Game* game); diff --git a/src/utils.c b/src/utils.c index 88829d3..62a44f5 100644 --- a/src/utils.c +++ b/src/utils.c @@ -276,18 +276,30 @@ SYMBOL_EXPORT void PrintConsole(struct Game *game, char* format, ...) { al_set_target_bitmap(al_get_backbuffer(game->display)); } -SYMBOL_EXPORT void SetupViewport(struct Game *game) { - game->viewport.width = 320; - game->viewport.height = 180; +SYMBOL_EXPORT void SetupViewport(struct Game *game, struct libsuperderpy_viewport config) { + + game->viewport = config; + + if ((game->viewport.width == 0) || (game->viewport.height == 0)) { + game->viewport.height = al_get_display_height(game->display); + game->viewport.width = game->viewport.aspect * game->viewport.height; + if (game->viewport.width > al_get_display_width(game->display)) { + game->viewport.width = al_get_display_width(game->display); + game->viewport.height = game->viewport.aspect / game->viewport.width; + } + } al_clear_to_color(al_map_rgb(0,0,0)); - int resolution = al_get_display_width(game->display) / 320; - if (al_get_display_height(game->display) / 180 < resolution) resolution = al_get_display_height(game->display) / 180; + float resolution = al_get_display_width(game->display) / (float)game->viewport.width; + if (al_get_display_height(game->display) / game->viewport.height < resolution) resolution = al_get_display_height(game->display) / (float)game->viewport.height; + if (!game->viewport.allow_non_integer) { + resolution = floor(resolution); + } if (resolution < 1) resolution = 1; if (atoi(GetConfigOptionDefault(game, "SuperDerpy", "letterbox", "1"))) { - int clipWidth = 320 * resolution, clipHeight = 180 * resolution; + int clipWidth = game->viewport.width * resolution, clipHeight = game->viewport.height * resolution; int clipX = (al_get_display_width(game->display) - clipWidth) / 2, clipY = (al_get_display_height(game->display) - clipHeight) / 2; al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight); diff --git a/src/utils.h b/src/utils.h index 542aff6..7c85015 100644 --- a/src/utils.h +++ b/src/utils.h @@ -34,6 +34,8 @@ #define LIBRARY_EXTENSION ".so" #endif +struct libsuperderpy_viewport; + /*! \brief Draws rectangle filled with vertical gradient. */ void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom); /*! \brief Draws rectangle filled with horizontal gradient. */ @@ -63,6 +65,6 @@ void PrintConsole(struct Game *game, char* format, ...); void FatalError(struct Game *game, bool exit, char* format, ...); -void SetupViewport(struct Game *game); +void SetupViewport(struct Game *game, struct libsuperderpy_viewport config); #endif