diff --git a/src/character.c b/src/character.c index 32a0cfa..82e8867 100644 --- a/src/character.c +++ b/src/character.c @@ -21,10 +21,10 @@ #include #include -#include "stdio.h" -#include "string.h" -#include "utils.h" +#include +#include #include "internal.h" +#include "utils.h" SYMBOL_EXPORT void SelectSpritesheet(struct Game *game, struct Character *character, char *name) { struct Spritesheet *tmp = character->spritesheets; diff --git a/src/config.c b/src/config.c index ae4db97..c110ae6 100644 --- a/src/config.c +++ b/src/config.c @@ -19,8 +19,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include -#include "config.h" #include "internal.h" +#include "config.h" SYMBOL_EXPORT void InitConfig(struct Game *game) { ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH); diff --git a/src/gamestate.c b/src/gamestate.c index 8e6a630..c1d29be 100644 --- a/src/gamestate.c +++ b/src/gamestate.c @@ -19,9 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include "internal.h" #include "utils.h" #include "gamestate.h" -#include "internal.h" SYMBOL_INTERNAL struct Gamestate* AddNewGamestate(struct Game *game, const char* name) { struct Gamestate *tmp = game->_priv.gamestates; diff --git a/src/gamestate.h b/src/gamestate.h index a28f242..bcba85b 100644 --- a/src/gamestate.h +++ b/src/gamestate.h @@ -21,7 +21,7 @@ #ifndef LIBSUPERDERPY_GAMESTATE_H #define LIBSUPERDERPY_GAMESTATE_H -#include "allegro5/allegro.h" +#include struct Game; diff --git a/src/internal.c b/src/internal.c index 492a758..0c2323c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -20,8 +20,8 @@ #include #include -#include "libsuperderpy.h" #include "internal.h" +#include "libsuperderpy.h" SYMBOL_INTERNAL void DrawGamestates(struct Game *game) { al_set_target_backbuffer(game->display); diff --git a/src/internal.h b/src/internal.h index af3d5ae..fc51078 100644 --- a/src/internal.h +++ b/src/internal.h @@ -38,6 +38,11 @@ # define SYMBOL_IMPORT extern #endif +struct libsuperderpy_list { + void *data; + struct libsuperderpy_list *next; +}; + void DrawGamestates(struct Game *game); void LogicGamestates(struct Game *game); void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev); diff --git a/src/libsuperderpy.c b/src/libsuperderpy.c index cd2a519..6531cea 100644 --- a/src/libsuperderpy.c +++ b/src/libsuperderpy.c @@ -28,15 +28,15 @@ #include #include #include +#include #include "internal.h" #include "libsuperderpy.h" #include "3rdparty/valgrind.h" #ifdef ALLEGRO_MACOSX #include -#include #endif -SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* name, struct libsuperderpy_viewport viewport) { +SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* name, struct Viewport viewport) { struct Game *game = malloc(sizeof(struct Game)); @@ -44,6 +44,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* game->viewport_config = viewport; #ifdef ALLEGRO_MACOSX + getcwd(game->_priv.cwd, MAXPATHLEN); char exe_path[MAXPATHLEN]; uint32_t size = sizeof(exe_path); _NSGetExecutablePath(exe_path, &size); @@ -233,6 +234,8 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) { bool redraw = false; while(1) { + // TODO: split mainloop to functions to make it readable + ALLEGRO_EVENT ev; if ((redraw && al_is_event_queue_empty(game->_priv.event_queue)) || (game->_priv.gamestate_scheduled)) { @@ -242,8 +245,7 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) { game->_priv.tmp_gamestate.toLoad = 0; game->_priv.tmp_gamestate.loaded = 0; - // FIXME: move to function - // TODO: support dependences + // TODO: support gamestate dependences while (tmp) { if (tmp->pending_stop) { PrintConsole(game, "Stopping gamestate \"%s\"...", tmp->name); @@ -258,8 +260,6 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) { } tmp = game->_priv.gamestates; - // FIXME: move to function - // TODO: support dependences game->_priv.tmp_gamestate.t = -1; @@ -487,6 +487,9 @@ SYMBOL_EXPORT void libsuperderpy_destroy(struct Game *game) { bool restart = game->restart; free(game); if (restart) { +#ifdef ALLEGRO_MACOSX + chdir(game->_priv.cwd); +#endif execv(argv[0], argv); // FIXME: on OSX there's chdir called which might break it } } diff --git a/src/libsuperderpy.h b/src/libsuperderpy.h index e1f01c2..e52d778 100644 --- a/src/libsuperderpy.h +++ b/src/libsuperderpy.h @@ -30,6 +30,7 @@ #include #include #include +#include #include "gamestate.h" #include "config.h" #include "timeline.h" @@ -42,12 +43,7 @@ struct Gamestate; -struct libsuperderpy_list { - void *data; - struct libsuperderpy_list *next; -}; - -struct libsuperderpy_viewport { +struct Viewport { int width; /*!< Actual available width of the drawing canvas. */ int height; /*!< Actual available height of the drawing canvas. */ float aspect; @@ -60,7 +56,7 @@ struct Game { ALLEGRO_TRANSFORM projection; /*!< Projection of the game canvas into the actual game window. */ - struct libsuperderpy_viewport viewport, viewport_config; + struct Viewport viewport, viewport_config; struct { int fx; /*!< Effects volume. */ @@ -122,6 +118,10 @@ struct Game { struct libsuperderpy_list *garbage; +#ifdef ALLEGRO_MACOSX + char cwd[MAXPATHLEN]; +#endif + } _priv; /*!< Private resources. Do not use in gamestates! */ bool shuttingdown; /*!< If true then shut down of the game is pending. */ @@ -137,7 +137,7 @@ struct Game { }; -struct Game* libsuperderpy_init(int argc, char **argv, const char* name, struct libsuperderpy_viewport viewport); +struct Game* libsuperderpy_init(int argc, char **argv, const char* name, struct Viewport viewport); int libsuperderpy_run(struct Game* game); void libsuperderpy_destroy(struct Game* game); diff --git a/src/timeline.c b/src/timeline.c index f44bf98..7408424 100644 --- a/src/timeline.c +++ b/src/timeline.c @@ -19,9 +19,9 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ #include +#include "internal.h" #include "utils.h" #include "timeline.h" -#include "internal.h" SYMBOL_EXPORT struct Timeline* TM_Init(struct Game* g, char* name) { PrintConsole(g, "Timeline Manager[%s]: init", name); @@ -238,7 +238,6 @@ SYMBOL_EXPORT struct TM_Action* TM_AddAction(struct Timeline* timeline, bool (*f } SYMBOL_EXPORT struct TM_Action* TM_AddBackgroundAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) { - // FIXME: some action wasn't freed! struct TM_Action *action = malloc(sizeof(struct TM_Action)); if (timeline->background) { struct TM_Action *pom = timeline->background; @@ -381,8 +380,6 @@ SYMBOL_EXPORT struct TM_Arguments* TM_AddToArgs(struct TM_Arguments* args, int n struct TM_Arguments* tmp = args; for(i = 0; i < num; i++) { if (!tmp) { - //FIXME: on some occasions some arguments weren't freed. Check it out. - // TM_AddQueuedBackgroundAction? possibly not only. tmp = malloc(sizeof(struct TM_Arguments)); tmp->value = va_arg(ap, void*); tmp->next = NULL; diff --git a/src/utils.c b/src/utils.c index 2ea3fab..2936259 100644 --- a/src/utils.c +++ b/src/utils.c @@ -21,12 +21,12 @@ #include #include -#include "stdio.h" -#include "config.h" -#include "string.h" -#include "math.h" -#include "utils.h" +#include +#include +#include #include "internal.h" +#include "config.h" +#include "utils.h" SYMBOL_EXPORT void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom) { ALLEGRO_VERTEX v[] = { @@ -51,6 +51,67 @@ SYMBOL_EXPORT void DrawTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, f al_draw_text(font, color, (int)x, (int)y, flags, text); } +SYMBOL_EXPORT int DrawWrappedText(ALLEGRO_FONT *font, ALLEGRO_COLOR color, int x1, int y1, int width, int flags, char const* text) { + + char stext[1024]; // Copy of the passed text. + char *pch; // A pointer to each word. + char word[255]; // A string containing the word (for convienence) + char *breakchar = "\n"; + char lines[40][1024]; // A lovely array of strings to hold all the lines (40 max atm) + char temp[1024]; // Holds the string data of the current line only. + int line = 0; // Counts which line we are currently using. + int height = al_get_font_line_height(font) + 1; + + // Setup our strings + strcpy(stext, text); + strcpy(temp, ""); + for (int i = 0; i < 40; i+=1) { + strcpy(lines[i], ""); + } + //-------------------- Code Begins + + char *context; + + pch = strtok_r(stext," ", &context); // Get the first word. + do { + strcpy(word, ""); // Truncate the string, to ensure there's no crazy stuff in there from memory. + sprintf(word,"%s ", pch); + strcat(temp, word); // Append the word to the end of TempLine + // This code checks for the new line character. + if (strcmp(word, breakchar) == 0) { + line += 1; // Move down a Line + strcpy(temp, ""); // Clear the tempstring + } else { + if (al_get_text_width(font, temp) >= (width)) { // Check if text is larger than the area. + strcpy(temp, word); // clear the templine and add the word to it. + line +=1; // Move to the next line. + } + if (line < 40) { + strcat(lines[line], word); // Append the word to whatever line we are currently on. + } + } + pch = strtok_r (NULL, " ", &context); // Get the next word. + } while (pch != NULL); + // ---------------------------------- Time to draw. + + for (int i = 0; i<=line; i+=1) { // Move through each line and draw according to the passed flags. + switch (flags) { + case ALLEGRO_ALIGN_CENTER: + al_draw_text(font, color, x1 + (width/2), y1 + (i * height), ALLEGRO_ALIGN_CENTER, lines[i]); + break; + case ALLEGRO_ALIGN_RIGHT: + al_draw_text(font, color, x1 + width, y1 + (i * height), ALLEGRO_ALIGN_RIGHT, lines[i]); + break; + case ALLEGRO_ALIGN_LEFT: + default: + al_draw_text(font, color, x1, y1 + (i * height), ALLEGRO_ALIGN_LEFT, lines[i]); + break; + } + } + return ((line+1) * height); // Return the actual height of the text in pixels. +} + + /* linear filtering code written by SiegeLord */ SYMBOL_EXPORT ALLEGRO_COLOR InterpolateColor(ALLEGRO_COLOR c1, ALLEGRO_COLOR c2, float frac) { return al_map_rgba_f(c1.r + frac * (c2.r - c1.r), @@ -214,7 +275,6 @@ SYMBOL_INTERNAL void TestPath(char* filename, char* subpath, char** result) { } SYMBOL_EXPORT char* GetGameName(struct Game *game, char* format) { - // FIXME: that's not how you program in C! char *result = malloc(sizeof(char)*255); snprintf(result, 255, format, game->name); return AddGarbage(game, result); @@ -222,10 +282,6 @@ SYMBOL_EXPORT char* GetGameName(struct Game *game, char* format) { SYMBOL_EXPORT char* GetDataFilePath(struct Game *game, char* filename) { - //TODO: support for current game - - //FIXME: strdups result in memory leaks! - char *result = 0; if (al_filename_exists(filename)) { @@ -276,7 +332,7 @@ 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, struct libsuperderpy_viewport config) { +SYMBOL_EXPORT void SetupViewport(struct Game *game, struct Viewport config) { game->viewport = config; diff --git a/src/utils.h b/src/utils.h index 7c85015..1571a5d 100644 --- a/src/utils.h +++ b/src/utils.h @@ -34,7 +34,7 @@ #define LIBRARY_EXTENSION ".so" #endif -struct libsuperderpy_viewport; +struct Viewport; /*! \brief Draws rectangle filled with vertical gradient. */ void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom); @@ -47,6 +47,8 @@ void DrawHorizontalGradientRect(float x, float y, float w, float h, ALLEGRO_COLO */ void DrawTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *text); +int DrawWrappedText(ALLEGRO_FONT *font, ALLEGRO_COLOR color, int x1, int y1, int width, int flags, char const *text); + /*! \brief Loads bitmap into memory and scales it with software linear filtering. */ ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, int height); @@ -65,6 +67,6 @@ void PrintConsole(struct Game *game, char* format, ...); void FatalError(struct Game *game, bool exit, char* format, ...); -void SetupViewport(struct Game *game, struct libsuperderpy_viewport config); +void SetupViewport(struct Game *game, struct Viewport config); #endif