mirror of
https://gitlab.com/dosowisko.net/libsuperderpy.git
synced 2025-02-01 02:56:43 +01:00
clang-tidy support; clang-tidy and clang-format fixes
This commit is contained in:
parent
0a4580a762
commit
2b1248ce14
17 changed files with 754 additions and 710 deletions
|
@ -4,7 +4,7 @@
|
|||
# ALLEGRO5_ACODEC_INCLUDE_DIR - the allrgo5 include directory
|
||||
# ALLEGRO5_ACODEC_LIBRARIES - Link these to use allegro5
|
||||
#
|
||||
message(${ALLEGRO5_INCLUDE_DIR})
|
||||
|
||||
FIND_PATH(ALLEGRO5_ACODEC_INCLUDE_DIR allegro5/allegro_acodec.h HINTS ${ALLEGRO5_INCLUDE_DIR})
|
||||
|
||||
SET(ALLEGRO5_ACODEC_NAMES ${ALLEGRO5_ACODEC_NAMES} allegro_acodec allegro_acodec_static liballegro_acodec liballegro_acodec_static AllegroAcodec-5.2 allegro_acodec-debug)
|
||||
|
|
|
@ -6,7 +6,9 @@ if (NOT LIBSUPERDERPY_CONFIG_INCLUDED)
|
|||
|
||||
set(EMSCRIPTEN_TOTAL_MEMORY "32" CACHE STRING "Amount of memory allocated by Emscripten (MB, must be multiple of 16)" )
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -std=c11")
|
||||
set(CMAKE_C_STANDARD 11)
|
||||
set(CMAKE_C_STANDARD_REQUIRED true)
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O1 -fno-optimize-sibling-calls -fno-omit-frame-pointer -fsanitize=leak -DLEAK_SANITIZER=1 -fno-common -fsanitize-recover=all")
|
||||
if(APPLE)
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error")
|
||||
|
@ -14,6 +16,17 @@ if (NOT LIBSUPERDERPY_CONFIG_INCLUDED)
|
|||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
|
||||
endif(APPLE)
|
||||
|
||||
find_program(
|
||||
CLANG_TIDY_EXE
|
||||
NAMES "clang-tidy"
|
||||
DOC "Path to clang-tidy executable"
|
||||
)
|
||||
if(NOT CLANG_TIDY_EXE)
|
||||
message(STATUS "clang-tidy not found.")
|
||||
else()
|
||||
set(CMAKE_C_CLANG_TIDY "${CLANG_TIDY_EXE}" "-checks=*,-clang-analyzer-alpha.*,-google-readability-todo,-performance-type-promotion-in-math-fn,-misc-unused-parameters,-cert-msc30-c,-cert-msc50-cpp")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
if(CMAKE_INSTALL_PREFIX MATCHES "/usr/local")
|
||||
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}")
|
||||
|
|
136
src/character.c
136
src/character.c
|
@ -18,15 +18,15 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "internal.h"
|
||||
#include "utils.h"
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "internal.h"
|
||||
#include "utils.h"
|
||||
|
||||
SYMBOL_EXPORT void SelectSpritesheet(struct Game *game, struct Character *character, char *name) {
|
||||
struct Spritesheet *tmp = character->spritesheets;
|
||||
SYMBOL_EXPORT void SelectSpritesheet(struct Game* game, struct Character* character, char* name) {
|
||||
struct Spritesheet* tmp = character->spritesheets;
|
||||
PrintConsole(game, "Selecting spritesheet for %s: %s", character->name, name);
|
||||
if (!tmp) {
|
||||
PrintConsole(game, "ERROR: No spritesheets registered for %s!", character->name);
|
||||
|
@ -35,7 +35,9 @@ SYMBOL_EXPORT void SelectSpritesheet(struct Game *game, struct Character *charac
|
|||
while (tmp) {
|
||||
if (!strcmp(tmp->name, name)) {
|
||||
character->spritesheet = tmp;
|
||||
if (character->successor) free(character->successor);
|
||||
if (character->successor) {
|
||||
free(character->successor);
|
||||
}
|
||||
if (tmp->successor) {
|
||||
character->successor = strdup(tmp->successor);
|
||||
} else {
|
||||
|
@ -57,20 +59,21 @@ SYMBOL_EXPORT void SelectSpritesheet(struct Game *game, struct Character *charac
|
|||
tmp = tmp->next;
|
||||
}
|
||||
PrintConsole(game, "ERROR: No spritesheets registered for %s with given name: %s", character->name, name);
|
||||
return;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void ChangeSpritesheet(struct Game *game, struct Character *character, char* name) {
|
||||
if (character->successor) free(character->successor);
|
||||
SYMBOL_EXPORT void ChangeSpritesheet(struct Game* game, struct Character* character, char* name) {
|
||||
if (character->successor) {
|
||||
free(character->successor);
|
||||
}
|
||||
character->successor = strdup(name);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void LoadSpritesheets(struct Game *game, struct Character *character) {
|
||||
SYMBOL_EXPORT void LoadSpritesheets(struct Game* game, struct Character* character) {
|
||||
PrintConsole(game, "Loading spritesheets for character %s...", character->name);
|
||||
struct Spritesheet *tmp = character->spritesheets;
|
||||
struct Spritesheet* tmp = character->spritesheets;
|
||||
while (tmp) {
|
||||
if (!tmp->bitmap) {
|
||||
char filename[255] = { };
|
||||
char filename[255] = {};
|
||||
snprintf(filename, 255, "sprites/%s/%s.png", character->name, tmp->name);
|
||||
tmp->bitmap = al_load_bitmap(GetDataFilePath(game, filename));
|
||||
tmp->width = al_get_bitmap_width(tmp->bitmap);
|
||||
|
@ -80,18 +83,20 @@ SYMBOL_EXPORT void LoadSpritesheets(struct Game *game, struct Character *charact
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void UnloadSpritesheets(struct Game *game, struct Character *character) {
|
||||
SYMBOL_EXPORT void UnloadSpritesheets(struct Game* game, struct Character* character) {
|
||||
PrintConsole(game, "Unloading spritesheets for character %s...", character->name);
|
||||
struct Spritesheet *tmp = character->spritesheets;
|
||||
struct Spritesheet* tmp = character->spritesheets;
|
||||
while (tmp) {
|
||||
if (tmp->bitmap) al_destroy_bitmap(tmp->bitmap);
|
||||
if (tmp->bitmap) {
|
||||
al_destroy_bitmap(tmp->bitmap);
|
||||
}
|
||||
tmp->bitmap = NULL;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void RegisterSpritesheet(struct Game *game, struct Character *character, char* name) {
|
||||
struct Spritesheet *s = character->spritesheets;
|
||||
SYMBOL_EXPORT void RegisterSpritesheet(struct Game* game, struct Character* character, char* name) {
|
||||
struct Spritesheet* s = character->spritesheets;
|
||||
while (s) {
|
||||
if (!strcmp(s->name, name)) {
|
||||
//PrintConsole(game, "%s spritesheet %s already registered!", character->name, name);
|
||||
|
@ -100,29 +105,31 @@ SYMBOL_EXPORT void RegisterSpritesheet(struct Game *game, struct Character *char
|
|||
s = s->next;
|
||||
}
|
||||
PrintConsole(game, "Registering %s spritesheet: %s", character->name, name);
|
||||
char filename[255] = { };
|
||||
char filename[255] = {};
|
||||
snprintf(filename, 255, "sprites/%s/%s.ini", character->name, name);
|
||||
ALLEGRO_CONFIG *config = al_load_config_file(GetDataFilePath(game, filename));
|
||||
ALLEGRO_CONFIG* config = al_load_config_file(GetDataFilePath(game, filename));
|
||||
s = malloc(sizeof(struct Spritesheet));
|
||||
s->name = strdup(name);
|
||||
s->bitmap = NULL;
|
||||
s->cols = atoi(al_get_config_value(config, "", "cols"));
|
||||
s->rows = atoi(al_get_config_value(config, "", "rows"));
|
||||
s->blanks = atoi(al_get_config_value(config, "", "blanks"));
|
||||
s->delay = atof(al_get_config_value(config, "", "delay"));
|
||||
s->cols = strtol(al_get_config_value(config, "", "cols"), NULL, 10);
|
||||
s->rows = strtol(al_get_config_value(config, "", "rows"), NULL, 10);
|
||||
s->blanks = strtol(al_get_config_value(config, "", "blanks"), NULL, 10);
|
||||
s->delay = strtod(al_get_config_value(config, "", "delay"), NULL);
|
||||
const char* val = al_get_config_value(config, "", "repeat");
|
||||
if (val) {
|
||||
s->repeat = atof(val);
|
||||
s->repeat = strtod(val, NULL);
|
||||
} else {
|
||||
s->repeat = 0;
|
||||
}
|
||||
s->kill = false;
|
||||
const char *kill = al_get_config_value(config, "", "kill");
|
||||
if (kill) s->kill = atoi(kill);
|
||||
s->successor=NULL;
|
||||
const char* kill = al_get_config_value(config, "", "kill");
|
||||
if (kill) {
|
||||
s->kill = strtol(kill, NULL, 10);
|
||||
}
|
||||
s->successor = NULL;
|
||||
const char* successor = al_get_config_value(config, "", "successor");
|
||||
if (successor) {
|
||||
s->successor = malloc(255*sizeof(char));
|
||||
s->successor = malloc(255 * sizeof(char));
|
||||
strncpy(s->successor, successor, 255);
|
||||
}
|
||||
s->next = character->spritesheets;
|
||||
|
@ -130,9 +137,9 @@ SYMBOL_EXPORT void RegisterSpritesheet(struct Game *game, struct Character *char
|
|||
al_destroy_config(config);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT struct Character* CreateCharacter(struct Game *game, char* name) {
|
||||
SYMBOL_EXPORT struct Character* CreateCharacter(struct Game* game, char* name) {
|
||||
PrintConsole(game, "Creating character %s...", name);
|
||||
struct Character *character = malloc(sizeof(struct Character));
|
||||
struct Character* character = malloc(sizeof(struct Character));
|
||||
character->name = strdup(name);
|
||||
character->angle = 0;
|
||||
character->bitmap = NULL;
|
||||
|
@ -150,36 +157,44 @@ SYMBOL_EXPORT struct Character* CreateCharacter(struct Game *game, char* name) {
|
|||
return character;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void DestroyCharacter(struct Game *game, struct Character *character) {
|
||||
SYMBOL_EXPORT void DestroyCharacter(struct Game* game, struct Character* character) {
|
||||
PrintConsole(game, "Destroying character %s...", character->name);
|
||||
if (!character->shared) {
|
||||
struct Spritesheet *tmp, *s = character->spritesheets;
|
||||
while (s) {
|
||||
tmp = s;
|
||||
s = s->next;
|
||||
if (tmp->bitmap) al_destroy_bitmap(tmp->bitmap);
|
||||
if (tmp->successor) free(tmp->successor);
|
||||
if (tmp->bitmap) {
|
||||
al_destroy_bitmap(tmp->bitmap);
|
||||
}
|
||||
if (tmp->successor) {
|
||||
free(tmp->successor);
|
||||
}
|
||||
free(tmp->name);
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if (character->bitmap) al_destroy_bitmap(character->bitmap);
|
||||
if (character->successor) free(character->successor);
|
||||
if (character->bitmap) {
|
||||
al_destroy_bitmap(character->bitmap);
|
||||
}
|
||||
if (character->successor) {
|
||||
free(character->successor);
|
||||
}
|
||||
free(character->name);
|
||||
free(character);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void AnimateCharacter(struct Game *game, struct Character *character, float speed_modifier) {
|
||||
if (character->dead) return;
|
||||
SYMBOL_EXPORT void AnimateCharacter(struct Game* game, struct Character* character, float speed_modifier) {
|
||||
if (character->dead) { return; }
|
||||
if (speed_modifier) {
|
||||
character->pos_tmp++;
|
||||
if (character->pos_tmp >= character->spritesheet->delay / speed_modifier) {
|
||||
character->pos_tmp = 0;
|
||||
character->pos++;
|
||||
}
|
||||
if (character->pos>=character->spritesheet->cols*character->spritesheet->rows-character->spritesheet->blanks) {
|
||||
character->pos=0;
|
||||
if (character->pos >= character->spritesheet->cols * character->spritesheet->rows - character->spritesheet->blanks) {
|
||||
character->pos = 0;
|
||||
if (character->repeat) {
|
||||
character->repeat--;
|
||||
} else {
|
||||
|
@ -193,64 +208,63 @@ SYMBOL_EXPORT void AnimateCharacter(struct Game *game, struct Character *charact
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void MoveCharacter(struct Game *game, struct Character *character, float x, float y, float angle) {
|
||||
SYMBOL_EXPORT void MoveCharacter(struct Game* game, struct Character* character, float x, float y, float angle) {
|
||||
MoveCharacterF(game, character, x / (float)game->viewport.width, y / (float)game->viewport.height, angle);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void MoveCharacterF(struct Game *game, struct Character *character, float x, float y, float angle) {
|
||||
if (character->dead) return;
|
||||
SYMBOL_EXPORT void MoveCharacterF(struct Game* game, struct Character* character, float x, float y, float angle) {
|
||||
if (character->dead) { return; }
|
||||
character->x += x;
|
||||
character->y += y;
|
||||
character->angle += angle;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void SetCharacterPositionF(struct Game *game, struct Character *character, float x, float y, float angle) {
|
||||
if (character->dead) return;
|
||||
SYMBOL_EXPORT void SetCharacterPositionF(struct Game* game, struct Character* character, float x, float y, float angle) {
|
||||
if (character->dead) { return; }
|
||||
character->x = x;
|
||||
character->y = y;
|
||||
character->angle = angle;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void SetCharacterPosition(struct Game *game, struct Character *character, float x, float y, float angle) {
|
||||
SYMBOL_EXPORT void SetCharacterPosition(struct Game* game, struct Character* character, float x, float y, float angle) {
|
||||
SetCharacterPositionF(game, character, x / (float)game->viewport.width, y / (float)game->viewport.height, angle);
|
||||
}
|
||||
|
||||
|
||||
SYMBOL_EXPORT void DrawScaledCharacterF(struct Game *game, struct Character *character, ALLEGRO_COLOR tint, float scalex, float scaley, int flags) {
|
||||
if (character->dead) return;
|
||||
int spritesheetX = al_get_bitmap_width(character->bitmap)*(character->pos%character->spritesheet->cols);
|
||||
int spritesheetY = al_get_bitmap_height(character->bitmap)*(character->pos/character->spritesheet->cols);
|
||||
al_draw_tinted_scaled_rotated_bitmap_region(character->spritesheet->bitmap, spritesheetX, spritesheetY, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap), tint, al_get_bitmap_width(character->bitmap)/2, al_get_bitmap_height(character->bitmap)/2, character->x*game->viewport.width + al_get_bitmap_width(character->bitmap)*scalex/2, character->y*game->viewport.height + al_get_bitmap_height(character->bitmap)*scaley/2, scalex, scaley, character->angle, flags);
|
||||
SYMBOL_EXPORT void DrawScaledCharacterF(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, float scalex, float scaley, int flags) {
|
||||
if (character->dead) { return; }
|
||||
int spritesheetX = al_get_bitmap_width(character->bitmap) * (character->pos % character->spritesheet->cols);
|
||||
int spritesheetY = al_get_bitmap_height(character->bitmap) * (character->pos / character->spritesheet->cols);
|
||||
al_draw_tinted_scaled_rotated_bitmap_region(character->spritesheet->bitmap, spritesheetX, spritesheetY, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap), tint, al_get_bitmap_width(character->bitmap) / 2, al_get_bitmap_height(character->bitmap) / 2, character->x * game->viewport.width + al_get_bitmap_width(character->bitmap) * scalex / 2, character->y * game->viewport.height + al_get_bitmap_height(character->bitmap) * scaley / 2, scalex, scaley, character->angle, flags);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void DrawCharacterF(struct Game *game, struct Character *character, ALLEGRO_COLOR tint, int flags) {
|
||||
SYMBOL_EXPORT void DrawCharacterF(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, int flags) {
|
||||
DrawScaledCharacterF(game, character, tint, 1, 1, flags);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void DrawScaledCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tint, float scalex, float scaley, int flags) {
|
||||
if (character->dead) return;
|
||||
int spritesheetX = al_get_bitmap_width(character->bitmap)*(character->pos%character->spritesheet->cols);
|
||||
int spritesheetY = al_get_bitmap_height(character->bitmap)*(character->pos/character->spritesheet->cols);
|
||||
al_draw_tinted_scaled_rotated_bitmap_region(character->spritesheet->bitmap, spritesheetX, spritesheetY, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap), tint, al_get_bitmap_width(character->bitmap)/2, al_get_bitmap_height(character->bitmap)/2, (int)(character->x*game->viewport.width + al_get_bitmap_width(character->bitmap)*scalex/2), (int)(character->y*game->viewport.height + al_get_bitmap_height(character->bitmap)*scaley/2), scalex, scaley, character->angle, flags);
|
||||
SYMBOL_EXPORT void DrawScaledCharacter(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, float scalex, float scaley, int flags) {
|
||||
if (character->dead) { return; }
|
||||
int spritesheetX = al_get_bitmap_width(character->bitmap) * (character->pos % character->spritesheet->cols);
|
||||
int spritesheetY = al_get_bitmap_height(character->bitmap) * (character->pos / character->spritesheet->cols);
|
||||
al_draw_tinted_scaled_rotated_bitmap_region(character->spritesheet->bitmap, spritesheetX, spritesheetY, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap), tint, al_get_bitmap_width(character->bitmap) / 2, al_get_bitmap_height(character->bitmap) / 2, (int)(character->x * game->viewport.width + al_get_bitmap_width(character->bitmap) * scalex / 2), (int)(character->y * game->viewport.height + al_get_bitmap_height(character->bitmap) * scaley / 2), scalex, scaley, character->angle, flags);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tint, int flags) {
|
||||
SYMBOL_EXPORT void DrawCharacter(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, int flags) {
|
||||
DrawScaledCharacter(game, character, tint, 1, 1, flags);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT int GetCharacterX(struct Game *game, struct Character *character) {
|
||||
SYMBOL_EXPORT int GetCharacterX(struct Game* game, struct Character* character) {
|
||||
return character->x * game->viewport.width;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT int GetCharacterY(struct Game *game, struct Character *character) {
|
||||
SYMBOL_EXPORT int GetCharacterY(struct Game* game, struct Character* character) {
|
||||
return character->y * game->viewport.height;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT float GetCharacterAngle(struct Game *game, struct Character *character) {
|
||||
SYMBOL_EXPORT float GetCharacterAngle(struct Game* game, struct Character* character) {
|
||||
return character->angle;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT bool IsOnCharacter(struct Game *game, struct Character *character, int x, int y) {
|
||||
SYMBOL_EXPORT bool IsOnCharacter(struct Game* game, struct Character* character, int x, int y) {
|
||||
int x1 = GetCharacterX(game, character), y1 = GetCharacterY(game, character);
|
||||
int x2 = x1 + al_get_bitmap_width(character->bitmap), y2 = y1 + al_get_bitmap_height(character->bitmap);
|
||||
|
||||
|
|
|
@ -21,70 +21,70 @@
|
|||
#ifndef LIBSUPERDERPY_CHARACTER_H
|
||||
#define LIBSUPERDERPY_CHARACTER_H
|
||||
|
||||
#include "libsuperderpy.h"
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include "libsuperderpy.h"
|
||||
|
||||
/*! \brief Structure representing one spritesheet for character animation. */
|
||||
struct Spritesheet {
|
||||
char* name; /*!< Name of the spritesheet (used in file paths). */
|
||||
ALLEGRO_BITMAP* bitmap; /*!< Spritesheet bitmap. */
|
||||
int rows; /*!< Number of rows in the spritesheet. */
|
||||
int cols; /*!< Number of columns in the spritesheet. */
|
||||
int blanks; /*!< Number of blank frames at the end of the spritesheet. */
|
||||
int width;
|
||||
int height;
|
||||
int delay;
|
||||
bool kill;
|
||||
int repeat;
|
||||
float scale; /*!< Scale modifier of the frame. */
|
||||
char* successor; /*!< Name of animation successor. If it's not blank, then animation will be played only once. */
|
||||
struct Spritesheet* next; /*!< Next spritesheet in the queue. */
|
||||
char* name; /*!< Name of the spritesheet (used in file paths). */
|
||||
ALLEGRO_BITMAP* bitmap; /*!< Spritesheet bitmap. */
|
||||
int rows; /*!< Number of rows in the spritesheet. */
|
||||
int cols; /*!< Number of columns in the spritesheet. */
|
||||
int blanks; /*!< Number of blank frames at the end of the spritesheet. */
|
||||
int width;
|
||||
int height;
|
||||
int delay;
|
||||
bool kill;
|
||||
int repeat;
|
||||
float scale; /*!< Scale modifier of the frame. */
|
||||
char* successor; /*!< Name of animation successor. If it's not blank, then animation will be played only once. */
|
||||
struct Spritesheet* next; /*!< Next spritesheet in the queue. */
|
||||
};
|
||||
|
||||
/*! \brief Structure representing one visible character. */
|
||||
struct Character {
|
||||
char* name; /*!< Name of the character (used in file paths). */
|
||||
struct Spritesheet *spritesheet; /*!< Current spritesheet used by character. */
|
||||
struct Spritesheet *spritesheets; /*!< List of all spritesheets registered to character. */
|
||||
char* successor;
|
||||
ALLEGRO_BITMAP* bitmap;
|
||||
int pos; /*!< Current spritesheet position. */
|
||||
int pos_tmp; /*!< A counter used to slow down spritesheet animation. */
|
||||
float x; /*!< Horizontal position of character. */
|
||||
float y; /*!< Vertical position of character. */
|
||||
float angle; /*!< Characters display angle (radians). */
|
||||
void* data; /*!< Additional, custom character data (HP etc.). */
|
||||
int repeat;
|
||||
bool shared;
|
||||
bool dead;
|
||||
char* name; /*!< Name of the character (used in file paths). */
|
||||
struct Spritesheet* spritesheet; /*!< Current spritesheet used by character. */
|
||||
struct Spritesheet* spritesheets; /*!< List of all spritesheets registered to character. */
|
||||
char* successor;
|
||||
ALLEGRO_BITMAP* bitmap;
|
||||
int pos; /*!< Current spritesheet position. */
|
||||
int pos_tmp; /*!< A counter used to slow down spritesheet animation. */
|
||||
float x; /*!< Horizontal position of character. */
|
||||
float y; /*!< Vertical position of character. */
|
||||
float angle; /*!< Characters display angle (radians). */
|
||||
void* data; /*!< Additional, custom character data (HP etc.). */
|
||||
int repeat;
|
||||
bool shared;
|
||||
bool dead;
|
||||
};
|
||||
|
||||
void SelectSpritesheet(struct Game *game, struct Character *character, char* name);
|
||||
void ChangeSpritesheet(struct Game *game, struct Character *character, char* name);
|
||||
void RegisterSpritesheet(struct Game *game, struct Character *character, char* name);
|
||||
void SelectSpritesheet(struct Game* game, struct Character* character, char* name);
|
||||
void ChangeSpritesheet(struct Game* game, struct Character* character, char* name);
|
||||
void RegisterSpritesheet(struct Game* game, struct Character* character, char* name);
|
||||
|
||||
void DrawCharacterF(struct Game *game, struct Character *character, ALLEGRO_COLOR tilt, int flags);
|
||||
void DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tilt, int flags);
|
||||
void DrawScaledCharacterF(struct Game *game, struct Character *character, ALLEGRO_COLOR tilt, float scalex, float scaley, int flags);
|
||||
void DrawScaledCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tilt, float scalex, float scaley, int flags);
|
||||
void DrawCharacterF(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, int flags);
|
||||
void DrawCharacter(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, int flags);
|
||||
void DrawScaledCharacterF(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, float scalex, float scaley, int flags);
|
||||
void DrawScaledCharacter(struct Game* game, struct Character* character, ALLEGRO_COLOR tint, float scalex, float scaley, int flags);
|
||||
|
||||
struct Character* CreateCharacter(struct Game *game, char* name);
|
||||
void DestroyCharacter(struct Game *game, struct Character *character);
|
||||
struct Character* CreateCharacter(struct Game* game, char* name);
|
||||
void DestroyCharacter(struct Game* game, struct Character* character);
|
||||
|
||||
void LoadSpritesheets(struct Game *game, struct Character *character);
|
||||
void UnloadSpritesheets(struct Game *game, struct Character *character);
|
||||
void LoadSpritesheets(struct Game* game, struct Character* character);
|
||||
void UnloadSpritesheets(struct Game* game, struct Character* character);
|
||||
|
||||
void AnimateCharacter(struct Game *game, struct Character *character, float speed_modifier);
|
||||
void MoveCharacter(struct Game *game, struct Character *character, float x, float y, float angle);
|
||||
void MoveCharacterF(struct Game *game, struct Character *character, float x, float y, float angle);
|
||||
void SetCharacterPosition(struct Game *game, struct Character *character, float x, float y, float angle);
|
||||
void SetCharacterPositionF(struct Game *game, struct Character *character, float x, float y, float angle);
|
||||
void AnimateCharacter(struct Game* game, struct Character* character, float speed_modifier);
|
||||
void MoveCharacter(struct Game* game, struct Character* character, float x, float y, float angle);
|
||||
void MoveCharacterF(struct Game* game, struct Character* character, float x, float y, float angle);
|
||||
void SetCharacterPosition(struct Game* game, struct Character* character, float x, float y, float angle);
|
||||
void SetCharacterPositionF(struct Game* game, struct Character* character, float x, float y, float angle);
|
||||
|
||||
int GetCharacterX(struct Game *game, struct Character *character);
|
||||
int GetCharacterY(struct Game *game, struct Character *character);
|
||||
float GetCharacterAngle(struct Game *game, struct Character *character);
|
||||
int GetCharacterX(struct Game* game, struct Character* character);
|
||||
int GetCharacterY(struct Game* game, struct Character* character);
|
||||
float GetCharacterAngle(struct Game* game, struct Character* character);
|
||||
|
||||
bool IsOnCharacter(struct Game *game, struct Character *character, int x, int y);
|
||||
bool IsOnCharacter(struct Game* game, struct Character* character, int x, int y);
|
||||
|
||||
#endif
|
||||
|
|
35
src/config.c
35
src/config.c
|
@ -17,41 +17,46 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <allegro5/allegro.h>
|
||||
#include "internal.h"
|
||||
#include "config.h"
|
||||
#include "internal.h"
|
||||
#include <allegro5/allegro.h>
|
||||
|
||||
SYMBOL_EXPORT void InitConfig(struct Game *game) {
|
||||
const ALLEGRO_FILE_INTERFACE *interface = al_get_new_file_interface();
|
||||
SYMBOL_EXPORT void InitConfig(struct Game* game) {
|
||||
const ALLEGRO_FILE_INTERFACE* interface = al_get_new_file_interface();
|
||||
al_set_standard_file_interface();
|
||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH);
|
||||
ALLEGRO_PATH *data = al_create_path("SuperDerpy.ini");
|
||||
ALLEGRO_PATH* path = al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH);
|
||||
ALLEGRO_PATH* data = al_create_path("SuperDerpy.ini");
|
||||
al_join_paths(path, data);
|
||||
game->_priv.config = al_load_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
if (!game->_priv.config) game->_priv.config=al_create_config();
|
||||
if (!game->_priv.config) {
|
||||
game->_priv.config = al_create_config();
|
||||
}
|
||||
al_destroy_path(path);
|
||||
al_destroy_path(data);
|
||||
al_set_new_file_interface(interface);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void SetConfigOption(struct Game *game, char* section, char* name, char* value) {
|
||||
SYMBOL_EXPORT void SetConfigOption(struct Game* game, char* section, char* name, char* value) {
|
||||
al_set_config_value(game->_priv.config, section, name, value);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT const char* GetConfigOption(struct Game *game, char* section, char* name) {
|
||||
SYMBOL_EXPORT const char* GetConfigOption(struct Game* game, char* section, char* name) {
|
||||
return al_get_config_value(game->_priv.config, section, name);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT const char* GetConfigOptionDefault(struct Game *game, char* section, char* name, const char* def) {
|
||||
SYMBOL_EXPORT const char* GetConfigOptionDefault(struct Game* game, char* section, char* name, const char* def) {
|
||||
const char* ret = GetConfigOption(game, section, name);
|
||||
if (!ret) return def; else return ret;
|
||||
if (!ret) {
|
||||
return def;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void DeinitConfig(struct Game *game) {
|
||||
const ALLEGRO_FILE_INTERFACE *interface = al_get_new_file_interface();
|
||||
SYMBOL_EXPORT void DeinitConfig(struct Game* game) {
|
||||
const ALLEGRO_FILE_INTERFACE* interface = al_get_new_file_interface();
|
||||
al_set_standard_file_interface();
|
||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH);
|
||||
ALLEGRO_PATH *data = al_create_path("SuperDerpy.ini");
|
||||
ALLEGRO_PATH* path = al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH);
|
||||
ALLEGRO_PATH* data = al_create_path("SuperDerpy.ini");
|
||||
al_make_directory(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
al_join_paths(path, data);
|
||||
al_save_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), game->_priv.config);
|
||||
|
|
10
src/config.h
10
src/config.h
|
@ -24,14 +24,14 @@
|
|||
#include "libsuperderpy.h"
|
||||
|
||||
/*! \brief Reads config from file into memory. */
|
||||
void InitConfig(struct Game *game);
|
||||
void InitConfig(struct Game* game);
|
||||
/*! \brief Returns value of requested config entry. */
|
||||
const char* GetConfigOption(struct Game *game, char* section, char* name);
|
||||
const char* GetConfigOption(struct Game* game, char* section, char* name);
|
||||
/*! \brief Returns value of requested config entry, or def if no such entry exists. */
|
||||
const char* GetConfigOptionDefault(struct Game *game, char* section, char* name, const char* def);
|
||||
const char* GetConfigOptionDefault(struct Game* game, char* section, char* name, const char* def);
|
||||
/*! \brief Sets new value of requested config entry, or created new if no such entry exists. */
|
||||
void SetConfigOption(struct Game *game, char* section, char* name, char* value);
|
||||
void SetConfigOption(struct Game* game, char* section, char* name, char* value);
|
||||
/*! \brief Writes config from memory to file. */
|
||||
void DeinitConfig(struct Game *game);
|
||||
void DeinitConfig(struct Game* game);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -20,55 +20,53 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef LIBSUPERDERPY_EMSCRIPTEN_H
|
||||
#define LIBSUPERDERPY_EMSCRIPTEN_H
|
||||
|
||||
typedef struct {
|
||||
ALLEGRO_SAMPLE *sample;
|
||||
ALLEGRO_SAMPLE_INSTANCE *instance;
|
||||
ALLEGRO_SAMPLE* sample;
|
||||
ALLEGRO_SAMPLE_INSTANCE* instance;
|
||||
} EMSCRIPTEN_AUDIO_STREAM;
|
||||
|
||||
ALLEGRO_AUDIO_STREAM *emscripten_load_audio_stream(const char* filename, size_t buffer_count, unsigned int samples);
|
||||
ALLEGRO_AUDIO_STREAM *emscripten_load_audio_stream_f(ALLEGRO_FILE *file, const char *ident, size_t buffer_count, unsigned int samples);
|
||||
bool emscripten_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream, float val);
|
||||
bool emscripten_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream, bool val);
|
||||
bool emscripten_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_PLAYMODE mode);
|
||||
bool emscripten_get_audio_stream_playing(ALLEGRO_AUDIO_STREAM *stream);
|
||||
bool emscripten_get_audio_stream_attached(ALLEGRO_AUDIO_STREAM *stream);
|
||||
ALLEGRO_PLAYMODE emscripten_get_audio_stream_playmode(ALLEGRO_AUDIO_STREAM *stream);
|
||||
bool emscripten_rewind_audio_stream(ALLEGRO_AUDIO_STREAM *stream);
|
||||
bool emscripten_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_MIXER *mixer);
|
||||
bool emscripten_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM *stream, ALLEGRO_VOICE *voice);
|
||||
bool emscripten_detach_audio_stream(ALLEGRO_AUDIO_STREAM *stream);
|
||||
unsigned int emscripten_get_audio_stream_frequency(ALLEGRO_AUDIO_STREAM *stream);
|
||||
ALLEGRO_CHANNEL_CONF emscripten_get_audio_stream_channels(ALLEGRO_AUDIO_STREAM *stream);
|
||||
ALLEGRO_AUDIO_DEPTH emscripten_get_audio_stream_depth(ALLEGRO_AUDIO_STREAM *stream);
|
||||
unsigned int emscripten_get_audio_stream_length(ALLEGRO_AUDIO_STREAM *stream);
|
||||
float emscripten_get_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream);
|
||||
float emscripten_get_audio_stream_gain(ALLEGRO_AUDIO_STREAM *stream);
|
||||
float emscripten_get_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream);
|
||||
bool emscripten_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM *stream, float val);
|
||||
bool emscripten_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM *stream, float val);
|
||||
double emscripten_get_audio_stream_length_sec(ALLEGRO_AUDIO_STREAM *stream);
|
||||
bool emscripten_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM *stream, double val);
|
||||
double emscripten_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM *stream);
|
||||
void emscripten_destroy_audio_stream(ALLEGRO_AUDIO_STREAM *stream);
|
||||
ALLEGRO_AUDIO_STREAM* emscripten_load_audio_stream(const char* filename, size_t buffer_count, unsigned int samples);
|
||||
ALLEGRO_AUDIO_STREAM* emscripten_load_audio_stream_f(ALLEGRO_FILE* file, const char* ident, size_t buffer_count, unsigned int samples);
|
||||
bool emscripten_set_audio_stream_gain(ALLEGRO_AUDIO_STREAM* stream, float val);
|
||||
bool emscripten_set_audio_stream_playing(ALLEGRO_AUDIO_STREAM* stream, bool val);
|
||||
bool emscripten_set_audio_stream_playmode(ALLEGRO_AUDIO_STREAM* stream, ALLEGRO_PLAYMODE mode);
|
||||
bool emscripten_get_audio_stream_playing(ALLEGRO_AUDIO_STREAM* stream);
|
||||
bool emscripten_get_audio_stream_attached(ALLEGRO_AUDIO_STREAM* stream);
|
||||
ALLEGRO_PLAYMODE emscripten_get_audio_stream_playmode(ALLEGRO_AUDIO_STREAM* stream);
|
||||
bool emscripten_rewind_audio_stream(ALLEGRO_AUDIO_STREAM* stream);
|
||||
bool emscripten_attach_audio_stream_to_mixer(ALLEGRO_AUDIO_STREAM* stream, ALLEGRO_MIXER* mixer);
|
||||
bool emscripten_attach_audio_stream_to_voice(ALLEGRO_AUDIO_STREAM* stream, ALLEGRO_VOICE* voice);
|
||||
bool emscripten_detach_audio_stream(ALLEGRO_AUDIO_STREAM* stream);
|
||||
unsigned int emscripten_get_audio_stream_frequency(ALLEGRO_AUDIO_STREAM* stream);
|
||||
ALLEGRO_CHANNEL_CONF emscripten_get_audio_stream_channels(ALLEGRO_AUDIO_STREAM* stream);
|
||||
ALLEGRO_AUDIO_DEPTH emscripten_get_audio_stream_depth(ALLEGRO_AUDIO_STREAM* stream);
|
||||
unsigned int emscripten_get_audio_stream_length(ALLEGRO_AUDIO_STREAM* stream);
|
||||
float emscripten_get_audio_stream_speed(ALLEGRO_AUDIO_STREAM* stream);
|
||||
float emscripten_get_audio_stream_gain(ALLEGRO_AUDIO_STREAM* stream);
|
||||
float emscripten_get_audio_stream_pan(ALLEGRO_AUDIO_STREAM* stream);
|
||||
bool emscripten_set_audio_stream_speed(ALLEGRO_AUDIO_STREAM* stream, float val);
|
||||
bool emscripten_set_audio_stream_pan(ALLEGRO_AUDIO_STREAM* stream, float val);
|
||||
double emscripten_get_audio_stream_length_sec(ALLEGRO_AUDIO_STREAM* stream);
|
||||
bool emscripten_seek_audio_stream_secs(ALLEGRO_AUDIO_STREAM* stream, double val);
|
||||
double emscripten_get_audio_stream_position_secs(ALLEGRO_AUDIO_STREAM* stream);
|
||||
void emscripten_destroy_audio_stream(ALLEGRO_AUDIO_STREAM* stream);
|
||||
#ifdef ALLEGRO_UNSTABLE
|
||||
bool emscripten_set_audio_stream_channel_matrix(ALLEGRO_AUDIO_STREAM *stream, const float *val);
|
||||
bool emscripten_set_audio_stream_channel_matrix(ALLEGRO_AUDIO_STREAM* stream, const float* val);
|
||||
#endif
|
||||
|
||||
uint64_t emscripten_get_audio_stream_played_samples(ALLEGRO_AUDIO_STREAM *stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
void *emscripten_get_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
bool emscripten_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM *stream, void *val) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
bool emscripten_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM *stream, double start, double end) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
unsigned int emscripten_get_audio_stream_fragments(ALLEGRO_AUDIO_STREAM *stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
unsigned int emscripten_get_available_audio_stream_fragments(ALLEGRO_AUDIO_STREAM *stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
ALLEGRO_EVENT_SOURCE *emscripten_get_audio_stream_event_source(ALLEGRO_AUDIO_STREAM *stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
void emscripten_drain_audio_stream(ALLEGRO_AUDIO_STREAM *stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
uint64_t emscripten_get_audio_stream_played_samples(ALLEGRO_AUDIO_STREAM* stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
void* emscripten_get_audio_stream_fragment(ALLEGRO_AUDIO_STREAM* stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
bool emscripten_set_audio_stream_fragment(ALLEGRO_AUDIO_STREAM* stream, void* val) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
bool emscripten_set_audio_stream_loop_secs(ALLEGRO_AUDIO_STREAM* stream, double start, double end) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
unsigned int emscripten_get_audio_stream_fragments(ALLEGRO_AUDIO_STREAM* stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
unsigned int emscripten_get_available_audio_stream_fragments(ALLEGRO_AUDIO_STREAM* stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
ALLEGRO_EVENT_SOURCE* emscripten_get_audio_stream_event_source(ALLEGRO_AUDIO_STREAM* stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
void emscripten_drain_audio_stream(ALLEGRO_AUDIO_STREAM* stream) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
ALLEGRO_AUDIO_STREAM* emscripten_create_audio_stream(size_t fragment_count, unsigned int frag_samples, unsigned int freq, ALLEGRO_AUDIO_DEPTH depth, ALLEGRO_CHANNEL_CONF chan_conf) __attribute__((unavailable("won't work in Emscripten until proper audio stream support is fixed!")));
|
||||
|
||||
|
||||
#define al_create_audio_stream emscripten_create_audio_stream
|
||||
#define al_load_audio_stream emscripten_load_audio_stream
|
||||
#define al_load_audio_stream_f emscripten_load_audio_stream_f
|
||||
|
|
|
@ -18,12 +18,12 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "gamestate.h"
|
||||
#include "internal.h"
|
||||
#include "utils.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
static struct Gamestate* AddNewGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
static struct Gamestate* AddNewGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
if (!tmp) {
|
||||
game->_priv.gamestates = AllocateGamestate(game, name);
|
||||
tmp = game->_priv.gamestates;
|
||||
|
@ -37,8 +37,8 @@ static struct Gamestate* AddNewGamestate(struct Game *game, const char* name) {
|
|||
return tmp;
|
||||
}
|
||||
|
||||
static struct Gamestate* FindGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
static struct Gamestate* FindGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if (!strcmp(name, tmp->name)) {
|
||||
return tmp;
|
||||
|
@ -48,8 +48,8 @@ static struct Gamestate* FindGamestate(struct Game *game, const char* name) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void RegisterGamestate(struct Game *game, const char* name, struct Gamestate_API *api) {
|
||||
struct Gamestate *gs = FindGamestate(game, name);
|
||||
SYMBOL_EXPORT void RegisterGamestate(struct Game* game, const char* name, struct Gamestate_API* api) {
|
||||
struct Gamestate* gs = FindGamestate(game, name);
|
||||
if (!gs) {
|
||||
gs = AddNewGamestate(game, name);
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ SYMBOL_EXPORT void RegisterGamestate(struct Game *game, const char* name, struct
|
|||
PrintConsole(game, "Gamestate \"%s\" registered.", name);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void LoadGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *gs = FindGamestate(game, name);
|
||||
SYMBOL_EXPORT void LoadGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* gs = FindGamestate(game, name);
|
||||
if (gs) {
|
||||
if (gs->loaded && !gs->pending_unload) {
|
||||
PrintConsole(game, "Gamestate \"%s\" already loaded.", name);
|
||||
|
@ -78,8 +78,8 @@ SYMBOL_EXPORT void LoadGamestate(struct Game *game, const char* name) {
|
|||
game->_priv.gamestate_scheduled = true;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void UnloadGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *gs = FindGamestate(game, name);
|
||||
SYMBOL_EXPORT void UnloadGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* gs = FindGamestate(game, name);
|
||||
if (gs) {
|
||||
if (gs->pending_load) {
|
||||
gs->pending_load = false;
|
||||
|
@ -90,7 +90,7 @@ SYMBOL_EXPORT void UnloadGamestate(struct Game *game, const char* name) {
|
|||
PrintConsole(game, "Gamestate \"%s\" already unloaded.", name);
|
||||
return;
|
||||
}
|
||||
if (gs->started) gs->pending_stop=true;
|
||||
if (gs->started) { gs->pending_stop = true; }
|
||||
gs->pending_unload = true;
|
||||
PrintConsole(game, "Gamestate \"%s\" marked to be UNLOADED.", name);
|
||||
} else {
|
||||
|
@ -99,8 +99,8 @@ SYMBOL_EXPORT void UnloadGamestate(struct Game *game, const char* name) {
|
|||
game->_priv.gamestate_scheduled = true;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void StartGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *gs = FindGamestate(game, name);
|
||||
SYMBOL_EXPORT void StartGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* gs = FindGamestate(game, name);
|
||||
if (gs) {
|
||||
if (gs->started && !gs->pending_stop) {
|
||||
PrintConsole(game, "Gamestate \"%s\" already started.", name);
|
||||
|
@ -114,8 +114,8 @@ SYMBOL_EXPORT void StartGamestate(struct Game *game, const char* name) {
|
|||
game->_priv.gamestate_scheduled = true;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void StopGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *gs = FindGamestate(game, name);
|
||||
SYMBOL_EXPORT void StopGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* gs = FindGamestate(game, name);
|
||||
if (gs) {
|
||||
if (gs->pending_start) {
|
||||
gs->pending_start = false;
|
||||
|
@ -134,8 +134,8 @@ SYMBOL_EXPORT void StopGamestate(struct Game *game, const char* name) {
|
|||
game->_priv.gamestate_scheduled = true;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void PauseGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *gs = FindGamestate(game, name);
|
||||
SYMBOL_EXPORT void PauseGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* gs = FindGamestate(game, name);
|
||||
if (gs) {
|
||||
if (!gs->started) {
|
||||
PrintConsole(game, "Tried to pause gamestate \"%s\" which is not started.", name);
|
||||
|
@ -154,8 +154,8 @@ SYMBOL_EXPORT void PauseGamestate(struct Game *game, const char* name) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void ResumeGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *gs = FindGamestate(game, name);
|
||||
SYMBOL_EXPORT void ResumeGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* gs = FindGamestate(game, name);
|
||||
if (gs) {
|
||||
if (!gs->started) {
|
||||
PrintConsole(game, "Tried to resume gamestate \"%s\" which is not started.", name);
|
||||
|
@ -174,16 +174,16 @@ SYMBOL_EXPORT void ResumeGamestate(struct Game *game, const char* name) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void UnloadAllGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_EXPORT void UnloadAllGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
UnloadGamestate(game, tmp->name);
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void PauseAllGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_EXPORT void PauseAllGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if (tmp->started || !tmp->paused) {
|
||||
PauseGamestate(game, tmp->name);
|
||||
|
@ -192,8 +192,8 @@ SYMBOL_EXPORT void PauseAllGamestates(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void ResumeAllGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_EXPORT void ResumeAllGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if (tmp->paused) {
|
||||
ResumeGamestate(game, tmp->name);
|
||||
|
@ -202,35 +202,35 @@ SYMBOL_EXPORT void ResumeAllGamestates(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void SwitchGamestate(struct Game *game, const char* current, const char* n) {
|
||||
SYMBOL_EXPORT void SwitchGamestate(struct Game* game, const char* current, const char* n) {
|
||||
StopGamestate(game, current);
|
||||
UnloadGamestate(game, current);
|
||||
LoadGamestate(game, n);
|
||||
StartGamestate(game, n);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void ChangeGamestate(struct Game *game, const char* current, const char* n) {
|
||||
SYMBOL_EXPORT void ChangeGamestate(struct Game* game, const char* current, const char* n) {
|
||||
StopGamestate(game, current);
|
||||
LoadGamestate(game, n);
|
||||
StartGamestate(game, n);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void SwitchCurrentGamestate(struct Game *game, const char* n) {
|
||||
SYMBOL_EXPORT void SwitchCurrentGamestate(struct Game* game, const char* n) {
|
||||
SwitchGamestate(game, game->_priv.current_gamestate->name, n);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void ChangeCurrentGamestate(struct Game *game, const char* n) {
|
||||
SYMBOL_EXPORT void ChangeCurrentGamestate(struct Game* game, const char* n) {
|
||||
ChangeGamestate(game, game->_priv.current_gamestate->name, n);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void StopCurrentGamestate(struct Game *game) {
|
||||
SYMBOL_EXPORT void StopCurrentGamestate(struct Game* game) {
|
||||
StopGamestate(game, game->_priv.current_gamestate->name);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void PauseCurrentGamestate(struct Game *game) {
|
||||
SYMBOL_EXPORT void PauseCurrentGamestate(struct Game* game) {
|
||||
PauseGamestate(game, game->_priv.current_gamestate->name);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void UnloadCurrentGamestate(struct Game *game) {
|
||||
SYMBOL_EXPORT void UnloadCurrentGamestate(struct Game* game) {
|
||||
UnloadGamestate(game, game->_priv.current_gamestate->name);
|
||||
}
|
||||
|
|
|
@ -20,56 +20,55 @@
|
|||
#ifndef LIBSUPERDERPY_GAMESTATE_H
|
||||
#define LIBSUPERDERPY_GAMESTATE_H
|
||||
|
||||
#include "libsuperderpy.h"
|
||||
#include <allegro5/allegro.h>
|
||||
|
||||
struct Game;
|
||||
|
||||
struct Gamestate_API {
|
||||
void (*Gamestate_Draw)(struct Game *game, void* data);
|
||||
void (*Gamestate_Logic)(struct Game *game, void* data);
|
||||
void (*Gamestate_Draw)(struct Game* game, void* data);
|
||||
void (*Gamestate_Logic)(struct Game* game, void* data);
|
||||
|
||||
void* (*Gamestate_Load)(struct Game *game, void (*progress)(struct Game *game));
|
||||
void (*Gamestate_Start)(struct Game *game, void* data);
|
||||
void (*Gamestate_Pause)(struct Game *game, void* data);
|
||||
void (*Gamestate_Resume)(struct Game *game, void* data);
|
||||
void (*Gamestate_Stop)(struct Game *game, void* data);
|
||||
void (*Gamestate_Unload)(struct Game *game, void* data);
|
||||
void* (*Gamestate_Load)(struct Game* game, void (*progress)(struct Game* game));
|
||||
void (*Gamestate_Start)(struct Game* game, void* data);
|
||||
void (*Gamestate_Pause)(struct Game* game, void* data);
|
||||
void (*Gamestate_Resume)(struct Game* game, void* data);
|
||||
void (*Gamestate_Stop)(struct Game* game, void* data);
|
||||
void (*Gamestate_Unload)(struct Game* game, void* data);
|
||||
|
||||
void (*Gamestate_ProcessEvent)(struct Game *game, void* data, ALLEGRO_EVENT *ev);
|
||||
void (*Gamestate_Reload)(struct Game *game, void* data);
|
||||
void (*Gamestate_ProcessEvent)(struct Game* game, void* data, ALLEGRO_EVENT* ev);
|
||||
void (*Gamestate_Reload)(struct Game* game, void* data);
|
||||
|
||||
int *Gamestate_ProgressCount;
|
||||
int* Gamestate_ProgressCount;
|
||||
};
|
||||
|
||||
struct Gamestate {
|
||||
char* name;
|
||||
void* handle;
|
||||
bool loaded, pending_load, pending_unload;
|
||||
bool started, pending_start, pending_stop;
|
||||
bool frozen;
|
||||
bool showLoading;
|
||||
bool paused;
|
||||
struct Gamestate *next;
|
||||
void* data;
|
||||
struct Gamestate_API *api;
|
||||
char* name;
|
||||
void* handle;
|
||||
bool loaded, pending_load, pending_unload;
|
||||
bool started, pending_start, pending_stop;
|
||||
bool frozen;
|
||||
bool showLoading;
|
||||
bool paused;
|
||||
struct Gamestate* next;
|
||||
void* data;
|
||||
struct Gamestate_API* api;
|
||||
};
|
||||
|
||||
void LoadGamestate(struct Game *game, const char* name);
|
||||
void UnloadGamestate(struct Game *game, const char* name);
|
||||
void RegisterGamestate(struct Game *game, const char* name, struct Gamestate_API *api);
|
||||
void StartGamestate(struct Game *game, const char* name);
|
||||
void StopGamestate(struct Game *game, const char* name);
|
||||
void PauseGamestate(struct Game *game, const char* name);
|
||||
void ResumeGamestate(struct Game *game, const char* name);
|
||||
void PauseAllGamestates(struct Game *game);
|
||||
void ResumeAllGamestates(struct Game *game);
|
||||
void UnloadAllGamestates(struct Game *game);
|
||||
void SwitchGamestate(struct Game *game, const char* current, const char* n);
|
||||
void SwitchCurrentGamestate(struct Game *game, const char* n);
|
||||
void ChangeGamestate(struct Game *game, const char* current, const char* n);
|
||||
void ChangeCurrentGamestate(struct Game *game, const char* n);
|
||||
void StopCurrentGamestate(struct Game *game);
|
||||
void PauseCurrentGamestate(struct Game *game);
|
||||
void UnloadCurrentGamestate(struct Game *game);
|
||||
void LoadGamestate(struct Game* game, const char* name);
|
||||
void UnloadGamestate(struct Game* game, const char* name);
|
||||
void RegisterGamestate(struct Game* game, const char* name, struct Gamestate_API* api);
|
||||
void StartGamestate(struct Game* game, const char* name);
|
||||
void StopGamestate(struct Game* game, const char* name);
|
||||
void PauseGamestate(struct Game* game, const char* name);
|
||||
void ResumeGamestate(struct Game* game, const char* name);
|
||||
void PauseAllGamestates(struct Game* game);
|
||||
void ResumeAllGamestates(struct Game* game);
|
||||
void UnloadAllGamestates(struct Game* game);
|
||||
void SwitchGamestate(struct Game* game, const char* current, const char* n);
|
||||
void SwitchCurrentGamestate(struct Game* game, const char* n);
|
||||
void ChangeGamestate(struct Game* game, const char* current, const char* n);
|
||||
void ChangeCurrentGamestate(struct Game* game, const char* n);
|
||||
void StopCurrentGamestate(struct Game* game);
|
||||
void PauseCurrentGamestate(struct Game* game);
|
||||
void UnloadCurrentGamestate(struct Game* game);
|
||||
|
||||
#endif
|
||||
|
|
166
src/internal.c
166
src/internal.c
|
@ -17,17 +17,17 @@
|
|||
* Also, ponies.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#include "internal.h"
|
||||
#include "libsuperderpy.h"
|
||||
#include "3rdparty/valgrind.h"
|
||||
#include "libsuperderpy.h"
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
|
||||
SYMBOL_INTERNAL void DrawGamestates(struct Game *game) {
|
||||
SYMBOL_INTERNAL void DrawGamestates(struct Game* game) {
|
||||
ClearScreen(game);
|
||||
al_set_target_backbuffer(game->display);
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started)) {
|
||||
game->_priv.current_gamestate = tmp;
|
||||
|
@ -37,8 +37,8 @@ SYMBOL_INTERNAL void DrawGamestates(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void LogicGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_INTERNAL void LogicGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||
game->_priv.current_gamestate = tmp;
|
||||
|
@ -48,8 +48,8 @@ SYMBOL_INTERNAL void LogicGamestates(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void ReloadGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_INTERNAL void ReloadGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if (tmp->loaded) {
|
||||
game->_priv.current_gamestate = tmp;
|
||||
|
@ -59,8 +59,8 @@ SYMBOL_INTERNAL void ReloadGamestates(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_INTERNAL void EventGamestates(struct Game* game, ALLEGRO_EVENT* ev) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||
game->_priv.current_gamestate = tmp;
|
||||
|
@ -70,8 +70,8 @@ SYMBOL_INTERNAL void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void FreezeGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_INTERNAL void FreezeGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if (tmp->started && !tmp->paused) {
|
||||
tmp->frozen = true;
|
||||
|
@ -81,8 +81,8 @@ SYMBOL_INTERNAL void FreezeGamestates(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void UnfreezeGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
SYMBOL_INTERNAL void UnfreezeGamestates(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if (tmp->frozen) {
|
||||
ResumeGamestate(game, tmp->name);
|
||||
|
@ -92,7 +92,7 @@ SYMBOL_INTERNAL void UnfreezeGamestates(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void DrawConsole(struct Game *game) {
|
||||
SYMBOL_INTERNAL void DrawConsole(struct Game* game) {
|
||||
if (game->_priv.showconsole) {
|
||||
al_set_target_backbuffer(game->display);
|
||||
ALLEGRO_TRANSFORM trans;
|
||||
|
@ -107,21 +107,21 @@ SYMBOL_INTERNAL void DrawConsole(struct Game *game) {
|
|||
}
|
||||
|
||||
int size = sizeof(game->_priv.console) / sizeof(game->_priv.console[0]);
|
||||
for (int i=0; i<size; i++) {
|
||||
al_draw_filled_rectangle(clipX, clipY, clipX + width, clipY + al_get_font_line_height(game->_priv.font_console)*(size-i), al_map_rgba(0,0,0,80));
|
||||
for (int i = 0; i < size; i++) {
|
||||
al_draw_filled_rectangle(clipX, clipY, clipX + width, clipY + al_get_font_line_height(game->_priv.font_console) * (size - i), al_map_rgba(0, 0, 0, 80));
|
||||
}
|
||||
int cur = game->_priv.console_pos + size;
|
||||
for (int i=0; i<size; i++) {
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (cur >= size) {
|
||||
cur -= size;
|
||||
}
|
||||
al_draw_text(game->_priv.font_console, al_map_rgb(255,255,255), clipX + (int)(game->viewport.width*0.005), clipY + al_get_font_line_height(game->_priv.font_console)*i, ALLEGRO_ALIGN_LEFT, game->_priv.console[cur]);
|
||||
al_draw_text(game->_priv.font_console, al_map_rgb(255, 255, 255), clipX + (int)(game->viewport.width * 0.005), clipY + al_get_font_line_height(game->_priv.font_console) * i, ALLEGRO_ALIGN_LEFT, game->_priv.console[cur]);
|
||||
cur++;
|
||||
}
|
||||
|
||||
char sfps[6] = { };
|
||||
char sfps[6] = {};
|
||||
snprintf(sfps, 6, "%.0f", game->_priv.fps_count.fps);
|
||||
DrawTextWithShadow(game->_priv.font_console, al_map_rgb(255,255,255), clipX + clipWidth, clipY, ALLEGRO_ALIGN_RIGHT, sfps);
|
||||
DrawTextWithShadow(game->_priv.font_console, al_map_rgb(255, 255, 255), clipX + clipWidth, clipY, ALLEGRO_ALIGN_RIGHT, sfps);
|
||||
|
||||
al_use_transform(&game->projection);
|
||||
|
||||
|
@ -137,23 +137,23 @@ SYMBOL_INTERNAL void DrawConsole(struct Game *game) {
|
|||
game->_priv.fps_count.frames_done++;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void Console_Load(struct Game *game) {
|
||||
game->_priv.font_console = al_load_ttf_font(GetDataFilePath(game, "fonts/DejaVuSansMono.ttf"),al_get_display_height(game->display)*0.025,0 );
|
||||
if (al_get_display_height(game->display)*0.025 >= 16) {
|
||||
game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/PerfectDOSVGA437.ttf"),16 * ((al_get_display_height(game->display) > 1080) ? 2 : 1) ,0 );
|
||||
SYMBOL_INTERNAL void Console_Load(struct Game* game) {
|
||||
game->_priv.font_console = al_load_ttf_font(GetDataFilePath(game, "fonts/DejaVuSansMono.ttf"), al_get_display_height(game->display) * 0.025, 0);
|
||||
if (al_get_display_height(game->display) * 0.025 >= 16) {
|
||||
game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/PerfectDOSVGA437.ttf"), 16 * ((al_get_display_height(game->display) > 1080) ? 2 : 1), 0);
|
||||
} 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.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/DejaVuSansMono.ttf"), al_get_display_height(game->display) * 0.025, 0);
|
||||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void Console_Unload(struct Game *game) {
|
||||
SYMBOL_INTERNAL void Console_Unload(struct Game* game) {
|
||||
if (game->_priv.font_console) {
|
||||
al_destroy_font(game->_priv.font_console);
|
||||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void* GamestateLoadingThread(void *arg) {
|
||||
struct GamestateLoadingThreadData *data = arg;
|
||||
SYMBOL_INTERNAL void* GamestateLoadingThread(void* arg) {
|
||||
struct GamestateLoadingThreadData* data = arg;
|
||||
data->game->_priv.loading.inProgress = true;
|
||||
al_set_new_bitmap_flags(data->bitmap_flags);
|
||||
GamestateProgress(data->game);
|
||||
|
@ -163,9 +163,9 @@ SYMBOL_INTERNAL void* GamestateLoadingThread(void *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void* ScreenshotThread(void *arg) {
|
||||
struct ScreenshotThreadData *data = arg;
|
||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH);
|
||||
SYMBOL_INTERNAL void* ScreenshotThread(void* arg) {
|
||||
struct ScreenshotThreadData* data = arg;
|
||||
ALLEGRO_PATH* path = al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH);
|
||||
char filename[255];
|
||||
snprintf(filename, 255, "%s_%ju_%ju.png", data->game->name, (uintmax_t)time(NULL), (uintmax_t)clock());
|
||||
al_set_path_filename(path, filename);
|
||||
|
@ -177,13 +177,15 @@ SYMBOL_INTERNAL void* ScreenshotThread(void *arg) {
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void GamestateProgress(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.loading.current;
|
||||
SYMBOL_INTERNAL void GamestateProgress(struct Game* game) {
|
||||
struct Gamestate* tmp = game->_priv.loading.current;
|
||||
game->_priv.loading.progress++;
|
||||
float progressCount = *(tmp->api->Gamestate_ProgressCount) ? (float)*(tmp->api->Gamestate_ProgressCount) : 1;
|
||||
float progress = ((game->_priv.loading.progress / progressCount) / (float)game->_priv.loading.toLoad) + (game->_priv.loading.loaded/(float)game->_priv.loading.toLoad);
|
||||
float progress = ((game->_priv.loading.progress / progressCount) / (float)game->_priv.loading.toLoad) + (game->_priv.loading.loaded / (float)game->_priv.loading.toLoad);
|
||||
game->loading_progress = progress;
|
||||
if (game->config.debug) PrintConsole(game, "[%s] Progress: %d% (%d/%d)", tmp->name, (int)(progress*100), game->_priv.loading.progress, *(tmp->api->Gamestate_ProgressCount));
|
||||
if (game->config.debug) {
|
||||
PrintConsole(game, "[%s] Progress: %d% (%d/%d)", tmp->name, (int)(progress * 100), game->_priv.loading.progress, *(tmp->api->Gamestate_ProgressCount));
|
||||
}
|
||||
#ifdef LIBSUPERDERPY_SINGLE_THREAD
|
||||
DrawGamestates(game);
|
||||
if (tmp->showLoading) (*game->_priv.loading.gamestate->api->Gamestate_Draw)(game, game->_priv.loading.gamestate->data);
|
||||
|
@ -192,7 +194,7 @@ SYMBOL_INTERNAL void GamestateProgress(struct Game *game) {
|
|||
#endif
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL bool OpenGamestate(struct Game *game, struct Gamestate *gamestate) {
|
||||
SYMBOL_INTERNAL bool OpenGamestate(struct Game* game, struct Gamestate* gamestate) {
|
||||
PrintConsole(game, "Opening gamestate \"%s\"...", gamestate->name);
|
||||
char libname[1024];
|
||||
snprintf(libname, 1024, "libsuperderpy-%s-%s" LIBRARY_EXTENSION, game->name, gamestate->name);
|
||||
|
@ -204,11 +206,12 @@ SYMBOL_INTERNAL bool OpenGamestate(struct Game *game, struct Gamestate *gamestat
|
|||
return true;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL bool LinkGamestate(struct Game *game, struct Gamestate *gamestate) {
|
||||
SYMBOL_INTERNAL bool LinkGamestate(struct Game* game, struct Gamestate* gamestate) {
|
||||
gamestate->api = malloc(sizeof(struct Gamestate_API));
|
||||
|
||||
#define GS_ERROR FatalError(game, false, "Error on resolving gamestate's %s symbol: %s", gamestate->name, dlerror()); /* TODO: move out */ \
|
||||
free(gamestate->api); \
|
||||
#define GS_ERROR \
|
||||
FatalError(game, false, "Error on resolving gamestate's %s symbol: %s", gamestate->name, dlerror()); /* TODO: move out */ \
|
||||
free(gamestate->api); \
|
||||
return false;
|
||||
|
||||
if (!(gamestate->api->Gamestate_Draw = dlsym(gamestate->handle, "Gamestate_Draw"))) { GS_ERROR; }
|
||||
|
@ -231,8 +234,8 @@ SYMBOL_INTERNAL bool LinkGamestate(struct Game *game, struct Gamestate *gamestat
|
|||
return true;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL struct Gamestate* AllocateGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *tmp = malloc(sizeof(struct Gamestate));
|
||||
SYMBOL_INTERNAL struct Gamestate* AllocateGamestate(struct Game* game, const char* name) {
|
||||
struct Gamestate* tmp = malloc(sizeof(struct Gamestate));
|
||||
tmp->name = strdup(name);
|
||||
tmp->handle = NULL;
|
||||
tmp->loaded = false;
|
||||
|
@ -248,7 +251,7 @@ SYMBOL_INTERNAL struct Gamestate* AllocateGamestate(struct Game *game, const cha
|
|||
return tmp;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void CloseGamestate(struct Game *game, struct Gamestate *gamestate) {
|
||||
SYMBOL_INTERNAL void CloseGamestate(struct Game* game, struct Gamestate* gamestate) {
|
||||
if (gamestate->handle && !RUNNING_ON_VALGRIND) {
|
||||
#ifndef LEAK_SANITIZER
|
||||
PrintConsole(game, "Closing gamestate \"%s\"...", gamestate->name);
|
||||
|
@ -261,13 +264,13 @@ SYMBOL_INTERNAL void CloseGamestate(struct Game *game, struct Gamestate *gamesta
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL struct libsuperderpy_list* AddToList(struct libsuperderpy_list *list, void* data) {
|
||||
SYMBOL_INTERNAL struct libsuperderpy_list* AddToList(struct libsuperderpy_list* list, void* data) {
|
||||
if (!list) {
|
||||
list = malloc(sizeof(struct libsuperderpy_list));
|
||||
list->data = data;
|
||||
list->next = NULL;
|
||||
} else {
|
||||
struct libsuperderpy_list *elem = malloc(sizeof(struct libsuperderpy_list));
|
||||
struct libsuperderpy_list* elem = malloc(sizeof(struct libsuperderpy_list));
|
||||
elem->next = list;
|
||||
elem->data = data;
|
||||
list = elem;
|
||||
|
@ -275,7 +278,7 @@ SYMBOL_INTERNAL struct libsuperderpy_list* AddToList(struct libsuperderpy_list *
|
|||
return list;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list **list, bool (*identity)(struct libsuperderpy_list* elem, void* data), void* data) {
|
||||
SYMBOL_INTERNAL struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list** list, bool (*identity)(struct libsuperderpy_list* elem, void* data), void* data) {
|
||||
struct libsuperderpy_list *prev = NULL, *tmp = *list, *start;
|
||||
void* d = NULL;
|
||||
while (tmp) {
|
||||
|
@ -285,13 +288,12 @@ SYMBOL_INTERNAL struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_l
|
|||
d = tmp->data;
|
||||
free(tmp);
|
||||
return d;
|
||||
} else {
|
||||
start = tmp->next;
|
||||
d = tmp->data;
|
||||
free(tmp);
|
||||
*list = start;
|
||||
return d;
|
||||
}
|
||||
start = tmp->next;
|
||||
d = tmp->data;
|
||||
free(tmp);
|
||||
*list = start;
|
||||
return d;
|
||||
}
|
||||
prev = tmp;
|
||||
tmp = tmp->next;
|
||||
|
@ -299,13 +301,13 @@ SYMBOL_INTERNAL struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_l
|
|||
return NULL;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void* AddGarbage(struct Game *game, void* data) {
|
||||
SYMBOL_INTERNAL void* AddGarbage(struct Game* game, void* data) {
|
||||
game->_priv.garbage = AddToList(game->_priv.garbage, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void ClearGarbage(struct Game *game) {
|
||||
struct libsuperderpy_list *tmp;
|
||||
SYMBOL_INTERNAL void ClearGarbage(struct Game* game) {
|
||||
struct libsuperderpy_list* tmp;
|
||||
while (game->_priv.garbage) {
|
||||
free(game->_priv.garbage->data);
|
||||
tmp = game->_priv.garbage->next;
|
||||
|
@ -314,21 +316,21 @@ SYMBOL_INTERNAL void ClearGarbage(struct Game *game) {
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void AddTimeline(struct Game *game, struct Timeline *timeline) {
|
||||
SYMBOL_INTERNAL void AddTimeline(struct Game* game, struct Timeline* timeline) {
|
||||
game->_priv.timelines = AddToList(game->_priv.timelines, timeline);
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void RemoveTimeline(struct Game *game, struct Timeline *timeline) {
|
||||
struct libsuperderpy_list *tmp = game->_priv.timelines;
|
||||
SYMBOL_INTERNAL void RemoveTimeline(struct Game* game, struct Timeline* timeline) {
|
||||
struct libsuperderpy_list* tmp = game->_priv.timelines;
|
||||
if (tmp->data == timeline) {
|
||||
struct libsuperderpy_list *next = tmp->next;
|
||||
struct libsuperderpy_list* next = tmp->next;
|
||||
free(tmp);
|
||||
game->_priv.timelines = next;
|
||||
return;
|
||||
}
|
||||
while (tmp->next) {
|
||||
if (tmp->next->data == timeline) {
|
||||
struct libsuperderpy_list *next = tmp->next->next;
|
||||
struct libsuperderpy_list* next = tmp->next->next;
|
||||
free(tmp->next);
|
||||
tmp->next = next;
|
||||
return;
|
||||
|
@ -337,7 +339,7 @@ SYMBOL_INTERNAL void RemoveTimeline(struct Game *game, struct Timeline *timeline
|
|||
}
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void ClearScreen(struct Game *game) {
|
||||
SYMBOL_INTERNAL void ClearScreen(struct Game* game) {
|
||||
ALLEGRO_TRANSFORM identity;
|
||||
int clipX, clipY, clipWidth, clipHeight;
|
||||
al_set_target_backbuffer(game->display);
|
||||
|
@ -345,37 +347,35 @@ SYMBOL_INTERNAL void ClearScreen(struct Game *game) {
|
|||
al_set_clipping_rectangle(0, 0, al_get_display_width(game->display), al_get_display_height(game->display));
|
||||
al_identity_transform(&identity);
|
||||
al_use_transform(&identity);
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
al_clear_to_color(al_map_rgb(0, 0, 0));
|
||||
al_use_transform(&game->projection);
|
||||
al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight);
|
||||
}
|
||||
|
||||
static void DrawQueue(struct Game *game, struct TM_Action* queue, int clipX, int clipY) {
|
||||
|
||||
static void DrawQueue(struct Game* game, struct TM_Action* queue, int clipX, int clipY) {
|
||||
int pos = clipX;
|
||||
|
||||
struct TM_Action *pom = queue;
|
||||
while (pom!=NULL) {
|
||||
|
||||
struct TM_Action* pom = queue;
|
||||
while (pom != NULL) {
|
||||
int width = al_get_text_width(game->_priv.font_console, pom->name);
|
||||
al_draw_filled_rectangle(pos-(10/3200.0)*al_get_display_width(game->display), clipY, pos+width+(10/3200.0)*al_get_display_width(game->display), clipY+ (60/1800.0)*al_get_display_height(game->display), pom->active ? al_map_rgba(255,255,255,192) : al_map_rgba(0, 0, 0, 0) );
|
||||
al_draw_rectangle(pos-(10/3200.0)*al_get_display_width(game->display), clipY, pos+width+(10/3200.0)*al_get_display_width(game->display), clipY+ (60/1800.0)*al_get_display_height(game->display), al_map_rgb(255,255,255), 2);
|
||||
al_draw_text(game->_priv.font_console, pom->active ? al_map_rgb(0,0,0) : al_map_rgb(255,255,255), pos, clipY, ALLEGRO_ALIGN_LEFT, pom->name);
|
||||
al_draw_filled_rectangle(pos - (10 / 3200.0) * al_get_display_width(game->display), clipY, pos + width + (10 / 3200.0) * al_get_display_width(game->display), clipY + (60 / 1800.0) * al_get_display_height(game->display), pom->active ? al_map_rgba(255, 255, 255, 192) : al_map_rgba(0, 0, 0, 0));
|
||||
al_draw_rectangle(pos - (10 / 3200.0) * al_get_display_width(game->display), clipY, pos + width + (10 / 3200.0) * al_get_display_width(game->display), clipY + (60 / 1800.0) * al_get_display_height(game->display), al_map_rgb(255, 255, 255), 2);
|
||||
al_draw_text(game->_priv.font_console, pom->active ? al_map_rgb(0, 0, 0) : al_map_rgb(255, 255, 255), pos, clipY, ALLEGRO_ALIGN_LEFT, pom->name);
|
||||
|
||||
if (pom->delay) {
|
||||
al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), pos, clipY - (50/1800.0)*al_get_display_height(game->display), ALLEGRO_ALIGN_LEFT, "%d", pom->delay);
|
||||
al_draw_textf(game->_priv.font_console, al_map_rgb(255, 255, 255), pos, clipY - (50 / 1800.0) * al_get_display_height(game->display), ALLEGRO_ALIGN_LEFT, "%d", pom->delay);
|
||||
}
|
||||
|
||||
if (strncmp(pom->name, "TM_BackgroundAction", 19) == 0) {
|
||||
al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), pos, clipY - (50/1800.0)*al_get_display_height(game->display), ALLEGRO_ALIGN_LEFT, "%s", (char*)pom->arguments->next->next->value);
|
||||
al_draw_textf(game->_priv.font_console, al_map_rgb(255, 255, 255), pos, clipY - (50 / 1800.0) * al_get_display_height(game->display), ALLEGRO_ALIGN_LEFT, "%s", (char*)pom->arguments->next->next->value);
|
||||
}
|
||||
|
||||
pos += width + (20/3200.0)*al_get_display_width(game->display);
|
||||
pos += width + (20 / 3200.0) * al_get_display_width(game->display);
|
||||
pom = pom->next;
|
||||
}
|
||||
}
|
||||
|
||||
static void DrawTimeline(struct Game *game, struct Timeline* timeline, int pos) {
|
||||
static void DrawTimeline(struct Game* game, struct Timeline* timeline, int pos) {
|
||||
al_set_target_backbuffer(game->display);
|
||||
ALLEGRO_TRANSFORM trans;
|
||||
al_identity_transform(&trans);
|
||||
|
@ -383,22 +383,22 @@ static void DrawTimeline(struct Game *game, struct Timeline* timeline, int pos)
|
|||
al_get_clipping_rectangle(&clipX, &clipY, &clipWidth, &clipHeight);
|
||||
al_use_transform(&trans);
|
||||
|
||||
al_draw_filled_rectangle(clipX, clipY+clipHeight-(340/1800.0)*al_get_display_height(game->display)*(pos+1), clipX + clipWidth, clipY+clipHeight-(340/1800.0)*al_get_display_height(game->display)*pos, al_map_rgba(0,0,0,92));
|
||||
al_draw_filled_rectangle(clipX, clipY + clipHeight - (340 / 1800.0) * al_get_display_height(game->display) * (pos + 1), clipX + clipWidth, clipY + clipHeight - (340 / 1800.0) * al_get_display_height(game->display) * pos, al_map_rgba(0, 0, 0, 92));
|
||||
|
||||
al_draw_textf(game->_priv.font_console, al_map_rgb(255,255,255), clipX + clipWidth / 2, clipY+clipHeight-(340/1800.0)*al_get_display_height(game->display)*(pos+1) + (10/1800.0)*al_get_display_height(game->display), ALLEGRO_ALIGN_CENTER, "Timeline: %s", timeline->name);
|
||||
al_draw_textf(game->_priv.font_console, al_map_rgb(255, 255, 255), clipX + clipWidth / 2, clipY + clipHeight - (340 / 1800.0) * al_get_display_height(game->display) * (pos + 1) + (10 / 1800.0) * al_get_display_height(game->display), ALLEGRO_ALIGN_CENTER, "Timeline: %s", timeline->name);
|
||||
|
||||
DrawQueue(game, timeline->queue, clipX + (25/3200.0)*al_get_display_width(game->display), clipY + clipHeight - (220/1800.0)*al_get_display_height(game->display) - (340/1800.0)*al_get_display_height(game->display)*pos);
|
||||
DrawQueue(game, timeline->background, clipX + (25/3200.0)*al_get_display_width(game->display), clipY + clipHeight - (100/1800.0)*al_get_display_height(game->display) - (340/1800.0)*al_get_display_height(game->display)*pos);
|
||||
DrawQueue(game, timeline->queue, clipX + (25 / 3200.0) * al_get_display_width(game->display), clipY + clipHeight - (220 / 1800.0) * al_get_display_height(game->display) - (340 / 1800.0) * al_get_display_height(game->display) * pos);
|
||||
DrawQueue(game, timeline->background, clipX + (25 / 3200.0) * al_get_display_width(game->display), clipY + clipHeight - (100 / 1800.0) * al_get_display_height(game->display) - (340 / 1800.0) * al_get_display_height(game->display) * pos);
|
||||
|
||||
al_use_transform(&game->projection);
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void DrawTimelines(struct Game *game) {
|
||||
SYMBOL_INTERNAL void DrawTimelines(struct Game* game) {
|
||||
if (!game->_priv.showtimeline) {
|
||||
return;
|
||||
}
|
||||
struct libsuperderpy_list *tmp = game->_priv.timelines;
|
||||
int i=0;
|
||||
struct libsuperderpy_list* tmp = game->_priv.timelines;
|
||||
int i = 0;
|
||||
while (tmp) {
|
||||
DrawTimeline(game, tmp->data, i);
|
||||
i++;
|
||||
|
|
|
@ -18,64 +18,64 @@
|
|||
#ifndef LIBSUPERDERPY_INTERNAL_H
|
||||
#define LIBSUPERDERPY_INTERNAL_H
|
||||
|
||||
#include "libsuperderpy.h"
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include "libsuperderpy.h"
|
||||
|
||||
#if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define SYMBOL_INTERNAL
|
||||
# define SYMBOL_EXPORT __declspec(dllexport)
|
||||
# define SYMBOL_IMPORT __declspec(dllimport)
|
||||
#define SYMBOL_INTERNAL
|
||||
#define SYMBOL_EXPORT __declspec(dllexport)
|
||||
#define SYMBOL_IMPORT __declspec(dllimport)
|
||||
#else
|
||||
# if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
# define SYMBOL_INTERNAL __attribute__ ((visibility ("hidden")))
|
||||
# define SYMBOL_EXPORT __attribute__ ((visibility ("default")))
|
||||
# else
|
||||
# define SYMBOL_INTERNAL
|
||||
# define SYMBOL_EXPORT
|
||||
# endif
|
||||
# define SYMBOL_IMPORT extern
|
||||
#if defined(__GNUC__) && (__GNUC__ >= 4)
|
||||
#define SYMBOL_INTERNAL __attribute__((visibility("hidden")))
|
||||
#define SYMBOL_EXPORT __attribute__((visibility("default")))
|
||||
#else
|
||||
#define SYMBOL_INTERNAL
|
||||
#define SYMBOL_EXPORT
|
||||
#endif
|
||||
#define SYMBOL_IMPORT extern
|
||||
#endif
|
||||
|
||||
struct libsuperderpy_list {
|
||||
void *data;
|
||||
struct libsuperderpy_list *next;
|
||||
void* data;
|
||||
struct libsuperderpy_list* next;
|
||||
};
|
||||
|
||||
struct GamestateLoadingThreadData {
|
||||
struct Game *game;
|
||||
struct Gamestate *gamestate;
|
||||
int bitmap_flags;
|
||||
struct Game* game;
|
||||
struct Gamestate* gamestate;
|
||||
int bitmap_flags;
|
||||
};
|
||||
|
||||
struct ScreenshotThreadData {
|
||||
struct Game *game;
|
||||
ALLEGRO_BITMAP *bitmap;
|
||||
struct Game* game;
|
||||
ALLEGRO_BITMAP* bitmap;
|
||||
};
|
||||
|
||||
void DrawGamestates(struct Game *game);
|
||||
void LogicGamestates(struct Game *game);
|
||||
void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev);
|
||||
void ReloadGamestates(struct Game *game);
|
||||
void FreezeGamestates(struct Game *game);
|
||||
void UnfreezeGamestates(struct Game *game);
|
||||
void DrawConsole(struct Game *game);
|
||||
void Console_Load(struct Game *game);
|
||||
void Console_Unload(struct Game *game);
|
||||
void* GamestateLoadingThread(void *arg);
|
||||
void* ScreenshotThread(void *arg);
|
||||
void GamestateProgress(struct Game *game);
|
||||
void* AddGarbage(struct Game *game, void* data);
|
||||
void ClearGarbage(struct Game *game);
|
||||
void ClearScreen(struct Game *game);
|
||||
struct libsuperderpy_list* AddToList(struct libsuperderpy_list *list, void* data);
|
||||
struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list **list, bool (*identity)(struct libsuperderpy_list* elem, void* data), void* data);
|
||||
void AddTimeline(struct Game *game, struct Timeline *timeline);
|
||||
void RemoveTimeline(struct Game *game, struct Timeline *timeline);
|
||||
void DrawTimelines(struct Game *game);
|
||||
bool OpenGamestate(struct Game *game, struct Gamestate *gamestate);
|
||||
bool LinkGamestate(struct Game *game, struct Gamestate *gamestate);
|
||||
void CloseGamestate(struct Game *game, struct Gamestate *gamestate);
|
||||
struct Gamestate* AllocateGamestate(struct Game *game, const char* name);
|
||||
void DrawGamestates(struct Game* game);
|
||||
void LogicGamestates(struct Game* game);
|
||||
void EventGamestates(struct Game* game, ALLEGRO_EVENT* ev);
|
||||
void ReloadGamestates(struct Game* game);
|
||||
void FreezeGamestates(struct Game* game);
|
||||
void UnfreezeGamestates(struct Game* game);
|
||||
void DrawConsole(struct Game* game);
|
||||
void Console_Load(struct Game* game);
|
||||
void Console_Unload(struct Game* game);
|
||||
void* GamestateLoadingThread(void* arg);
|
||||
void* ScreenshotThread(void* arg);
|
||||
void GamestateProgress(struct Game* game);
|
||||
void* AddGarbage(struct Game* game, void* data);
|
||||
void ClearGarbage(struct Game* game);
|
||||
void ClearScreen(struct Game* game);
|
||||
struct libsuperderpy_list* AddToList(struct libsuperderpy_list* list, void* data);
|
||||
struct libsuperderpy_list* RemoveFromList(struct libsuperderpy_list** list, bool (*identity)(struct libsuperderpy_list* elem, void* data), void* data);
|
||||
void AddTimeline(struct Game* game, struct Timeline* timeline);
|
||||
void RemoveTimeline(struct Game* game, struct Timeline* timeline);
|
||||
void DrawTimelines(struct Game* game);
|
||||
bool OpenGamestate(struct Game* game, struct Gamestate* gamestate);
|
||||
bool LinkGamestate(struct Game* game, struct Gamestate* gamestate);
|
||||
void CloseGamestate(struct Game* game, struct Gamestate* gamestate);
|
||||
struct Gamestate* AllocateGamestate(struct Game* game, const char* name);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -25,22 +25,21 @@
|
|||
#define ALLEGRO_UNSTABLE
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <locale.h>
|
||||
#include <dlfcn.h>
|
||||
#include <unistd.h>
|
||||
#include <libgen.h>
|
||||
#include <sys/param.h>
|
||||
#include "internal.h"
|
||||
#include "libsuperderpy.h"
|
||||
#include "internal.h"
|
||||
#include <dlfcn.h>
|
||||
#include <libgen.h>
|
||||
#include <locale.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/param.h>
|
||||
#include <unistd.h>
|
||||
#ifdef ALLEGRO_MACOSX
|
||||
#include <mach-o/dyld.h>
|
||||
#endif
|
||||
|
||||
SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char* name, struct Viewport viewport) {
|
||||
|
||||
struct Game *game = calloc(1, sizeof(struct Game));
|
||||
struct Game* game = calloc(1, sizeof(struct Game));
|
||||
|
||||
game->name = name;
|
||||
game->viewport_config = viewport;
|
||||
|
@ -53,8 +52,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
chdir(dirname(exe_path));
|
||||
#endif
|
||||
|
||||
|
||||
if(!al_init()) {
|
||||
if (!al_init()) {
|
||||
fprintf(stderr, "failed to initialize allegro!\n");
|
||||
free(game);
|
||||
return NULL;
|
||||
|
@ -69,7 +67,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
game->_priv.font_console = NULL;
|
||||
game->_priv.font_bsod = NULL;
|
||||
game->_priv.console_pos = 0;
|
||||
for (unsigned int i=0; i<(sizeof(game->_priv.console)/sizeof(game->_priv.console[0])); i++) {
|
||||
for (unsigned int i = 0; i < (sizeof(game->_priv.console) / sizeof(game->_priv.console[0])); i++) {
|
||||
game->_priv.console[i][0] = '\0';
|
||||
}
|
||||
|
||||
|
@ -79,61 +77,61 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
game->handlers.event = NULL;
|
||||
game->handlers.destroy = NULL;
|
||||
|
||||
game->config.fullscreen = atoi(GetConfigOptionDefault(game, "SuperDerpy", "fullscreen", "1"));
|
||||
game->config.music = atoi(GetConfigOptionDefault(game, "SuperDerpy", "music", "10"));
|
||||
game->config.voice = atoi(GetConfigOptionDefault(game, "SuperDerpy", "voice", "10"));
|
||||
game->config.fx = atoi(GetConfigOptionDefault(game, "SuperDerpy", "fx", "10"));
|
||||
game->config.debug = atoi(GetConfigOptionDefault(game, "SuperDerpy", "debug", "0"));
|
||||
game->config.width = atoi(GetConfigOptionDefault(game, "SuperDerpy", "width", "1280"));
|
||||
if (game->config.width<320) game->config.width=320;
|
||||
game->config.height = atoi(GetConfigOptionDefault(game, "SuperDerpy", "height", "720"));
|
||||
if (game->config.height<180) game->config.height=180;
|
||||
game->config.fullscreen = strtol(GetConfigOptionDefault(game, "SuperDerpy", "fullscreen", "1"), NULL, 10);
|
||||
game->config.music = strtol(GetConfigOptionDefault(game, "SuperDerpy", "music", "10"), NULL, 10);
|
||||
game->config.voice = strtol(GetConfigOptionDefault(game, "SuperDerpy", "voice", "10"), NULL, 10);
|
||||
game->config.fx = strtol(GetConfigOptionDefault(game, "SuperDerpy", "fx", "10"), NULL, 10);
|
||||
game->config.debug = strtol(GetConfigOptionDefault(game, "SuperDerpy", "debug", "0"), NULL, 10);
|
||||
game->config.width = strtol(GetConfigOptionDefault(game, "SuperDerpy", "width", "1280"), NULL, 10);
|
||||
if (game->config.width < 320) { game->config.width = 320; }
|
||||
game->config.height = strtol(GetConfigOptionDefault(game, "SuperDerpy", "height", "720"), NULL, 10);
|
||||
if (game->config.height < 180) { game->config.height = 180; }
|
||||
|
||||
game->_priv.showconsole = game->config.debug;
|
||||
game->_priv.showtimeline = false;
|
||||
|
||||
if(!al_init_image_addon()) {
|
||||
if (!al_init_image_addon()) {
|
||||
fprintf(stderr, "failed to initialize image addon!\n");
|
||||
/*al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!",
|
||||
NULL, ALLEGRO_MESSAGEBOX_ERROR);*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!al_install_audio()){
|
||||
if (!al_install_audio()) {
|
||||
fprintf(stderr, "failed to initialize audio!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!al_init_acodec_addon()){
|
||||
if (!al_init_acodec_addon()) {
|
||||
fprintf(stderr, "failed to initialize audio codecs!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!al_install_keyboard()){
|
||||
if (!al_install_keyboard()) {
|
||||
fprintf(stderr, "failed to initialize keyboard!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!al_init_primitives_addon()){
|
||||
if (!al_init_primitives_addon()) {
|
||||
fprintf(stderr, "failed to initialize primitives!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!al_install_mouse()) {
|
||||
if (!al_install_mouse()) {
|
||||
fprintf(stderr, "failed to initialize the mouse!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
al_init_font_addon();
|
||||
|
||||
if(!al_init_ttf_addon()){
|
||||
if (!al_init_ttf_addon()) {
|
||||
fprintf(stderr, "failed to initialize fonts!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
game->touch = false;
|
||||
|
||||
if (!atoi(GetConfigOptionDefault(game, "SuperDerpy", "disableTouch", "0"))) {
|
||||
if (!strtol(GetConfigOptionDefault(game, "SuperDerpy", "disableTouch", "0"), NULL, 10)) {
|
||||
game->touch = al_install_touch_input();
|
||||
}
|
||||
|
||||
|
@ -149,7 +147,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
#ifdef __EMSCRIPTEN__
|
||||
al_set_new_display_flags((al_get_new_display_flags() | ALLEGRO_WINDOWED) ^ ALLEGRO_FULLSCREEN_WINDOW);
|
||||
#endif
|
||||
al_set_new_display_option(ALLEGRO_VSYNC, 2-atoi(GetConfigOptionDefault(game, "SuperDerpy", "vsync", "1")), ALLEGRO_SUGGEST);
|
||||
al_set_new_display_option(ALLEGRO_VSYNC, 2 - strtol(GetConfigOptionDefault(game, "SuperDerpy", "vsync", "1"), NULL, 10), ALLEGRO_SUGGEST);
|
||||
al_set_new_display_option(ALLEGRO_OPENGL, true, ALLEGRO_REQUIRE);
|
||||
|
||||
#ifdef LIBSUPERDERPY_ORIENTATION_LANDSCAPE
|
||||
|
@ -164,7 +162,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
|
||||
al_set_new_window_title(game->name);
|
||||
game->display = al_create_display(game->config.width, game->config.height);
|
||||
if(!game->display) {
|
||||
if (!game->display) {
|
||||
fprintf(stderr, "failed to create display!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -178,11 +176,11 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
|
||||
PrintConsole(game, "Viewport %dx%d", game->viewport.width, game->viewport.height);
|
||||
|
||||
ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(game, GetGameName(game, "icons/%s.png")));
|
||||
ALLEGRO_BITMAP* icon = al_load_bitmap(GetDataFilePath(game, GetGameName(game, "icons/%s.png")));
|
||||
al_set_display_icon(game->display, icon);
|
||||
al_destroy_bitmap(icon);
|
||||
|
||||
if (game->config.fullscreen) al_hide_mouse_cursor(game->display);
|
||||
if (game->config.fullscreen) { al_hide_mouse_cursor(game->display); }
|
||||
al_inhibit_screensaver(true);
|
||||
|
||||
al_add_new_bitmap_flag(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
||||
|
@ -193,7 +191,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
al_init_user_event_source(&(game->event_source));
|
||||
|
||||
game->_priv.event_queue = al_create_event_queue();
|
||||
if(!game->_priv.event_queue) {
|
||||
if (!game->_priv.event_queue) {
|
||||
FatalError(game, true, "Failed to create event queue.");
|
||||
al_destroy_display(game->display);
|
||||
return NULL;
|
||||
|
@ -217,9 +215,9 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
al_attach_mixer_to_mixer(game->audio.fx, game->audio.mixer);
|
||||
al_attach_mixer_to_mixer(game->audio.music, game->audio.mixer);
|
||||
al_attach_mixer_to_mixer(game->audio.voice, game->audio.mixer);
|
||||
al_set_mixer_gain(game->audio.fx, game->config.fx/10.0);
|
||||
al_set_mixer_gain(game->audio.music, game->config.music/10.0);
|
||||
al_set_mixer_gain(game->audio.voice, game->config.voice/10.0);
|
||||
al_set_mixer_gain(game->audio.fx, game->config.fx / 10.0);
|
||||
al_set_mixer_gain(game->audio.music, game->config.music / 10.0);
|
||||
al_set_mixer_gain(game->audio.voice, game->config.voice / 10.0);
|
||||
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
|
@ -238,7 +236,7 @@ SYMBOL_EXPORT struct Game* libsuperderpy_init(int argc, char** argv, const char*
|
|||
return game;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) {
|
||||
SYMBOL_EXPORT int libsuperderpy_run(struct Game* game) {
|
||||
al_register_event_source(game->_priv.event_queue, al_get_display_event_source(game->display));
|
||||
al_register_event_source(game->_priv.event_queue, al_get_mouse_event_source());
|
||||
al_register_event_source(game->_priv.event_queue, al_get_keyboard_event_source());
|
||||
|
@ -251,9 +249,9 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) {
|
|||
}
|
||||
al_register_event_source(game->_priv.event_queue, &(game->event_source));
|
||||
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
al_clear_to_color(al_map_rgb(0, 0, 0));
|
||||
game->_priv.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer
|
||||
if(!game->_priv.timer) {
|
||||
if (!game->_priv.timer) {
|
||||
FatalError(game, true, "Failed to create logic timer.");
|
||||
return 1;
|
||||
}
|
||||
|
@ -262,7 +260,7 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) {
|
|||
al_flip_display();
|
||||
al_start_timer(game->_priv.timer);
|
||||
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
// don't show loading screen on init if requested
|
||||
tmp->showLoading = game->show_loading_on_launch;
|
||||
|
@ -280,22 +278,22 @@ SYMBOL_EXPORT int libsuperderpy_run(struct Game *game) {
|
|||
game->_priv.draw = true;
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
void libsuperderpy_mainloop(void *game);
|
||||
void libsuperderpy_mainloop(void* game);
|
||||
emscripten_set_main_loop_arg(libsuperderpy_mainloop, game, 0, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool redraw = false;
|
||||
|
||||
SYMBOL_INTERNAL void libsuperderpy_mainloop_exit(struct Game *game) {
|
||||
SYMBOL_INTERNAL void libsuperderpy_mainloop_exit(struct Game* game) {
|
||||
libsuperderpy_destroy(game);
|
||||
free(game);
|
||||
printf("Halted.\n");
|
||||
emscripten_cancel_main_loop();
|
||||
}
|
||||
|
||||
SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
||||
struct Game *game = (struct Game*)g;
|
||||
SYMBOL_INTERNAL void libsuperderpy_mainloop(void* g) {
|
||||
struct Game* game = (struct Game*)g;
|
||||
while (!al_is_event_queue_empty(game->_priv.event_queue) || redraw) {
|
||||
#else
|
||||
bool redraw = false;
|
||||
|
@ -306,9 +304,8 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
// TODO: split mainloop to functions to make it readable
|
||||
ALLEGRO_EVENT ev;
|
||||
if (game->_priv.draw && ((redraw && al_is_event_queue_empty(game->_priv.event_queue)) || (game->_priv.gamestate_scheduled))) {
|
||||
|
||||
game->_priv.gamestate_scheduled = false;
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
struct Gamestate* tmp = game->_priv.gamestates;
|
||||
|
||||
game->_priv.loading.toLoad = 0;
|
||||
game->_priv.loading.loaded = 0;
|
||||
|
@ -324,8 +321,8 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
tmp->pending_stop = false;
|
||||
}
|
||||
|
||||
if (tmp->pending_load) game->_priv.loading.toLoad++;
|
||||
tmp=tmp->next;
|
||||
if (tmp->pending_load) { game->_priv.loading.toLoad++; }
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
tmp = game->_priv.gamestates;
|
||||
|
@ -342,7 +339,9 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
}
|
||||
if (tmp->pending_load) {
|
||||
al_stop_timer(game->_priv.timer);
|
||||
if (tmp->showLoading) (*game->_priv.loading.gamestate->api->Gamestate_Start)(game, game->_priv.loading.gamestate->data);
|
||||
if (tmp->showLoading) {
|
||||
(*game->_priv.loading.gamestate->api->Gamestate_Start)(game, game->_priv.loading.gamestate->data);
|
||||
}
|
||||
|
||||
if (!tmp->api) {
|
||||
if (!OpenGamestate(game, tmp) || !LinkGamestate(game, tmp)) {
|
||||
|
@ -359,14 +358,16 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
game->_priv.loading.current = tmp;
|
||||
game->_priv.current_gamestate = tmp;
|
||||
|
||||
struct GamestateLoadingThreadData data = { .game = game, .gamestate = tmp, .bitmap_flags = al_get_new_bitmap_flags() };
|
||||
struct GamestateLoadingThreadData data = {.game = game, .gamestate = tmp, .bitmap_flags = al_get_new_bitmap_flags()};
|
||||
game->_priv.loading.inProgress = true;
|
||||
|
||||
#ifndef LIBSUPERDERPY_SINGLE_THREAD
|
||||
al_run_detached_thread(GamestateLoadingThread, &data);
|
||||
while (game->_priv.loading.inProgress) {
|
||||
DrawGamestates(game);
|
||||
if (tmp->showLoading) (*game->_priv.loading.gamestate->api->Gamestate_Draw)(game, game->_priv.loading.gamestate->data);
|
||||
if (tmp->showLoading) {
|
||||
(*game->_priv.loading.gamestate->api->Gamestate_Draw)(game, game->_priv.loading.gamestate->data);
|
||||
}
|
||||
DrawConsole(game);
|
||||
al_flip_display();
|
||||
}
|
||||
|
@ -381,20 +382,21 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
|
||||
tmp->loaded = true;
|
||||
tmp->pending_load = false;
|
||||
|
||||
}
|
||||
if (tmp->showLoading) (*game->_priv.loading.gamestate->api->Gamestate_Stop)(game, game->_priv.loading.gamestate->data);
|
||||
if (tmp->showLoading) {
|
||||
(*game->_priv.loading.gamestate->api->Gamestate_Stop)(game, game->_priv.loading.gamestate->data);
|
||||
}
|
||||
al_resume_timer(game->_priv.timer);
|
||||
}
|
||||
|
||||
tmp=tmp->next;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
bool gameActive = false;
|
||||
tmp=game->_priv.gamestates;
|
||||
tmp = game->_priv.gamestates;
|
||||
|
||||
while (tmp) {
|
||||
if ((tmp->pending_start) && (tmp->loaded)) {
|
||||
if ((tmp->pending_start) && (tmp->loaded)) {
|
||||
PrintConsole(game, "Starting gamestate \"%s\"...", tmp->name);
|
||||
al_stop_timer(game->_priv.timer);
|
||||
game->_priv.current_gamestate = tmp;
|
||||
|
@ -404,8 +406,10 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
al_resume_timer(game->_priv.timer);
|
||||
}
|
||||
|
||||
if ((tmp->started) || (tmp->pending_start) || (tmp->pending_load)) gameActive = true;
|
||||
tmp=tmp->next;
|
||||
if ((tmp->started) || (tmp->pending_start) || (tmp->pending_load)) {
|
||||
gameActive = true;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
||||
if (!gameActive) {
|
||||
|
@ -424,7 +428,6 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
redraw = false;
|
||||
|
||||
} else {
|
||||
|
||||
#ifdef __EMSCRIPTEN__
|
||||
if (al_is_event_queue_empty(game->_priv.event_queue)) {
|
||||
return;
|
||||
|
@ -442,22 +445,19 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game->_priv.timer)) {
|
||||
LogicGamestates(game);
|
||||
redraw = true;
|
||||
}
|
||||
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
||||
} else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
||||
#ifdef __EMSCRIPTEN__
|
||||
libsuperderpy_mainloop_exit(game);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
else if(ev.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) {
|
||||
} else if (ev.type == ALLEGRO_EVENT_DISPLAY_HALT_DRAWING) {
|
||||
PrintConsole(game, "Engine halted.");
|
||||
game->_priv.draw = false;
|
||||
al_stop_timer(game->_priv.timer);
|
||||
al_detach_voice(game->audio.v);
|
||||
FreezeGamestates(game);
|
||||
al_acknowledge_drawing_halt(game->display);
|
||||
}
|
||||
else if(ev.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) {
|
||||
} else if (ev.type == ALLEGRO_EVENT_DISPLAY_RESUME_DRAWING) {
|
||||
game->_priv.draw = true;
|
||||
al_acknowledge_drawing_resume(game->display);
|
||||
PrintConsole(game, "Engine resumed.");
|
||||
|
@ -465,8 +465,7 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
UnfreezeGamestates(game);
|
||||
al_attach_mixer_to_voice(game->audio.mixer, game->audio.v);
|
||||
al_resume_timer(game->_priv.timer);
|
||||
}
|
||||
else if(ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) {
|
||||
} else if (ev.type == ALLEGRO_EVENT_DISPLAY_RESIZE) {
|
||||
al_acknowledge_resize(game->display);
|
||||
SetupViewport(game, game->viewport_config);
|
||||
}
|
||||
|
@ -479,41 +478,40 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
if (ev.keyboard.modifiers & ALLEGRO_KEYMOD_CTRL) {
|
||||
game->_priv.showtimeline = game->_priv.showconsole;
|
||||
}
|
||||
}
|
||||
else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) {
|
||||
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) {
|
||||
int i;
|
||||
for (i=0; i<512; i++) {
|
||||
for (i = 0; i < 512; i++) {
|
||||
LogicGamestates(game);
|
||||
}
|
||||
game->_priv.showconsole = true;
|
||||
PrintConsole(game, "DEBUG: 512 frames skipped...");
|
||||
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F10)) {
|
||||
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F10)) {
|
||||
double speed = ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game->_priv.timer)); // inverting
|
||||
speed -= 10;
|
||||
if (speed<10) speed = 10;
|
||||
if (speed < 10) { speed = 10; }
|
||||
al_set_timer_speed(game->_priv.timer, ALLEGRO_BPS_TO_SECS(speed));
|
||||
game->_priv.showconsole = true;
|
||||
PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed/60.0);
|
||||
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F11)) {
|
||||
PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0);
|
||||
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game->config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F11)) {
|
||||
double speed = ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game->_priv.timer)); // inverting
|
||||
speed += 10;
|
||||
if (speed>600) speed = 600;
|
||||
if (speed > 600) { speed = 600; }
|
||||
al_set_timer_speed(game->_priv.timer, ALLEGRO_BPS_TO_SECS(speed));
|
||||
game->_priv.showconsole = true;
|
||||
PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed/60.0);
|
||||
PrintConsole(game, "DEBUG: Gameplay speed: %.2fx", speed / 60.0);
|
||||
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_F12)) {
|
||||
DrawGamestates(game);
|
||||
int flags = al_get_new_bitmap_flags();
|
||||
al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
|
||||
ALLEGRO_BITMAP *bitmap = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display));
|
||||
ALLEGRO_BITMAP* bitmap = al_create_bitmap(al_get_display_width(game->display), al_get_display_height(game->display));
|
||||
al_set_new_bitmap_flags(flags);
|
||||
ALLEGRO_BITMAP *target = al_get_target_bitmap();
|
||||
ALLEGRO_BITMAP* target = al_get_target_bitmap();
|
||||
al_set_target_bitmap(bitmap);
|
||||
al_draw_bitmap(al_get_backbuffer(game->display), 0, 0, 0);
|
||||
al_set_target_bitmap(target);
|
||||
PrintConsole(game, "Screenshot made! Storing...");
|
||||
|
||||
struct ScreenshotThreadData *data = malloc(sizeof(struct ScreenshotThreadData));
|
||||
struct ScreenshotThreadData* data = malloc(sizeof(struct ScreenshotThreadData));
|
||||
data->game = game;
|
||||
data->bitmap = bitmap;
|
||||
#ifndef LIBSUPERDERPY_SINGLE_THREAD
|
||||
|
@ -534,7 +532,7 @@ SYMBOL_INTERNAL void libsuperderpy_mainloop(void *g) {
|
|||
#endif
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void libsuperderpy_destroy(struct Game *game) {
|
||||
SYMBOL_EXPORT void libsuperderpy_destroy(struct Game* game) {
|
||||
game->shutting_down = true;
|
||||
|
||||
ClearGarbage(game);
|
||||
|
@ -556,7 +554,7 @@ SYMBOL_EXPORT void libsuperderpy_destroy(struct Game *game) {
|
|||
CloseGamestate(game, tmp);
|
||||
pom = tmp->next;
|
||||
free(tmp);
|
||||
tmp=pom;
|
||||
tmp = pom;
|
||||
}
|
||||
|
||||
(*game->_priv.loading.gamestate->api->Gamestate_Unload)(game, game->_priv.loading.gamestate->data);
|
||||
|
@ -570,14 +568,14 @@ SYMBOL_EXPORT void libsuperderpy_destroy(struct Game *game) {
|
|||
ClearScreen(game);
|
||||
#ifdef __EMSCRIPTEN__
|
||||
{
|
||||
ALLEGRO_BITMAP *bmp = al_create_bitmap(320, 180);
|
||||
ALLEGRO_BITMAP* bmp = al_create_bitmap(320, 180);
|
||||
al_set_target_bitmap(bmp);
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
ALLEGRO_FONT *font = al_create_builtin_font();
|
||||
al_draw_text(font, al_map_rgb(228,127,59), 320/2, 180/2 - 8 - 6, ALLEGRO_ALIGN_CENTER, "It's now safe to turn off");
|
||||
al_draw_text(font, al_map_rgb(228,127,59), 320/2, 180/2 - 8 + 6, ALLEGRO_ALIGN_CENTER, "your browser.");
|
||||
al_clear_to_color(al_map_rgb(0, 0, 0));
|
||||
ALLEGRO_FONT* font = al_create_builtin_font();
|
||||
al_draw_text(font, al_map_rgb(228, 127, 59), 320 / 2, 180 / 2 - 8 - 6, ALLEGRO_ALIGN_CENTER, "It's now safe to turn off");
|
||||
al_draw_text(font, al_map_rgb(228, 127, 59), 320 / 2, 180 / 2 - 8 + 6, ALLEGRO_ALIGN_CENTER, "your browser.");
|
||||
al_set_target_backbuffer(game->display);
|
||||
al_draw_scaled_bitmap(bmp, 0, 0, 320, 180, 0, -game->viewport.height*0.2, game->viewport.width, game->viewport.height*1.4, 0);
|
||||
al_draw_scaled_bitmap(bmp, 0, 0, 320, 180, 0, -game->viewport.height * 0.2, game->viewport.width, game->viewport.height * 1.4, 0);
|
||||
al_flip_display();
|
||||
al_destroy_bitmap(bmp);
|
||||
al_destroy_font(font);
|
||||
|
|
|
@ -22,26 +22,28 @@
|
|||
#ifndef LIBSUPERDERPY_MAIN_H
|
||||
#define LIBSUPERDERPY_MAIN_H
|
||||
|
||||
struct Game;
|
||||
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_audio.h>
|
||||
#include <allegro5/allegro_image.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
#include <allegro5/allegro_acodec.h>
|
||||
#include <allegro5/allegro_audio.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include <allegro5/allegro_image.h>
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#ifdef ALLEGRO_ANDROID
|
||||
#include <allegro5/allegro_android.h>
|
||||
#endif
|
||||
#ifdef __EMSCRIPTEN__
|
||||
#include <emscripten.h>
|
||||
#include "emscripten-audio-stream.h"
|
||||
#include <emscripten.h>
|
||||
#endif
|
||||
#include <sys/param.h>
|
||||
#include "gamestate.h"
|
||||
#include "character.h"
|
||||
#include "config.h"
|
||||
#include "gamestate.h"
|
||||
#include "timeline.h"
|
||||
#include "utils.h"
|
||||
#include "character.h"
|
||||
#include <sys/param.h>
|
||||
|
||||
#ifndef LIBSUPERDERPY_DATA_TYPE
|
||||
#define LIBSUPERDERPY_DATA_TYPE void
|
||||
|
@ -50,116 +52,115 @@
|
|||
struct Gamestate;
|
||||
|
||||
struct Viewport {
|
||||
int width; /*!< Actual available width of the drawing canvas. */
|
||||
int height; /*!< Actual available height of the drawing canvas. */
|
||||
float aspect;
|
||||
bool integer_scaling;
|
||||
int width; /*!< Actual available width of the drawing canvas. */
|
||||
int height; /*!< Actual available height of the drawing canvas. */
|
||||
float aspect;
|
||||
bool integer_scaling;
|
||||
};
|
||||
|
||||
/*! \brief Main struct of the game. */
|
||||
struct Game {
|
||||
ALLEGRO_DISPLAY *display; /*!< Main Allegro display. */
|
||||
ALLEGRO_DISPLAY* display; /*!< Main Allegro display. */
|
||||
|
||||
ALLEGRO_TRANSFORM projection; /*!< Projection of the game canvas into the actual game window. */
|
||||
ALLEGRO_TRANSFORM projection; /*!< Projection of the game canvas into the actual game window. */
|
||||
|
||||
struct Viewport viewport, viewport_config;
|
||||
struct Viewport viewport, viewport_config;
|
||||
|
||||
struct {
|
||||
int fx; /*!< Effects volume. */
|
||||
int music; /*!< Music volume. */
|
||||
int voice; /*!< Voice volume. */
|
||||
bool fullscreen; /*!< Fullscreen toggle. */
|
||||
bool debug; /*!< Toggles debug mode. */
|
||||
int width; /*!< Width of window as being set in configuration. */
|
||||
int height; /*!< Height of window as being set in configuration. */
|
||||
} config;
|
||||
|
||||
struct {
|
||||
ALLEGRO_VOICE* v; /*!< Main voice used by the game. */
|
||||
ALLEGRO_MIXER* mixer; /*!< Main mixer of the game. */
|
||||
ALLEGRO_MIXER* music; /*!< Music mixer. */
|
||||
ALLEGRO_MIXER* voice; /*!< Voice mixer. */
|
||||
ALLEGRO_MIXER* fx; /*!< Effects mixer. */
|
||||
} audio; /*!< Audio resources. */
|
||||
|
||||
struct {
|
||||
struct Gamestate* gamestates; /*!< List of known gamestates. */
|
||||
bool gamestate_scheduled; /*!< Whether there's some gamestate lifecycle management work to do. */
|
||||
ALLEGRO_FONT* font_console; /*!< Font used in game console. */
|
||||
ALLEGRO_FONT* font_bsod; /*!< Font used in Blue Screens of Derp. */
|
||||
char console[5][1024];
|
||||
unsigned int console_pos;
|
||||
ALLEGRO_EVENT_QUEUE* event_queue; /*!< Main event queue. */
|
||||
ALLEGRO_TIMER* timer; /*!< Main LPS (logic) timer. */
|
||||
bool showconsole; /*!< If true, game console is rendered on screen. */
|
||||
bool showtimeline;
|
||||
|
||||
struct {
|
||||
int fx; /*!< Effects volume. */
|
||||
int music; /*!< Music volume. */
|
||||
int voice; /*!< Voice volume. */
|
||||
bool fullscreen; /*!< Fullscreen toggle. */
|
||||
bool debug; /*!< Toggles debug mode. */
|
||||
int width; /*!< Width of window as being set in configuration. */
|
||||
int height; /*!< Height of window as being set in configuration. */
|
||||
} config;
|
||||
double old_time, fps;
|
||||
int frames_done;
|
||||
} fps_count; /*!< Used for counting the effective FPS. */
|
||||
|
||||
ALLEGRO_CONFIG* config; /*!< Configuration file interface. */
|
||||
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
struct {
|
||||
ALLEGRO_VOICE *v; /*!< Main voice used by the game. */
|
||||
ALLEGRO_MIXER *mixer; /*!< Main mixer of the game. */
|
||||
ALLEGRO_MIXER *music; /*!< Music mixer. */
|
||||
ALLEGRO_MIXER *voice; /*!< Voice mixer. */
|
||||
ALLEGRO_MIXER *fx; /*!< Effects mixer. */
|
||||
} audio; /*!< Audio resources. */
|
||||
struct Gamestate* gamestate;
|
||||
struct Gamestate* current;
|
||||
int progress;
|
||||
int loaded, toLoad;
|
||||
bool inProgress;
|
||||
} loading;
|
||||
|
||||
struct {
|
||||
struct Gamestate *gamestates; /*!< List of known gamestates. */
|
||||
bool gamestate_scheduled; /*!< Whether there's some gamestate lifecycle management work to do. */
|
||||
ALLEGRO_FONT *font_console; /*!< Font used in game console. */
|
||||
ALLEGRO_FONT *font_bsod; /*!< Font used in Blue Screens of Derp. */
|
||||
char console[5][1024];
|
||||
unsigned int console_pos;
|
||||
ALLEGRO_EVENT_QUEUE *event_queue; /*!< Main event queue. */
|
||||
ALLEGRO_TIMER *timer; /*!< Main LPS (logic) timer. */
|
||||
bool showconsole; /*!< If true, game console is rendered on screen. */
|
||||
bool showtimeline;
|
||||
struct Gamestate* current_gamestate;
|
||||
|
||||
struct {
|
||||
double old_time, fps;
|
||||
int frames_done;
|
||||
} fps_count; /*!< Used for counting the effective FPS. */
|
||||
struct libsuperderpy_list *garbage, *timelines;
|
||||
|
||||
ALLEGRO_CONFIG *config; /*!< Configuration file interface. */
|
||||
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
struct {
|
||||
struct Gamestate *gamestate;
|
||||
struct Gamestate *current;
|
||||
int progress;
|
||||
int loaded, toLoad;
|
||||
bool inProgress;
|
||||
} loading;
|
||||
|
||||
struct Gamestate *current_gamestate;
|
||||
|
||||
struct libsuperderpy_list *garbage, *timelines;
|
||||
|
||||
bool draw;
|
||||
bool draw;
|
||||
|
||||
#ifdef ALLEGRO_MACOSX
|
||||
char cwd[MAXPATHLEN];
|
||||
char cwd[MAXPATHLEN];
|
||||
#endif
|
||||
|
||||
} _priv; /*!< Private resources. Do not use in gamestates! */
|
||||
} _priv; /*!< Private resources. Do not use in gamestates! */
|
||||
|
||||
bool shutting_down; /*!< If true then shut down of the game is pending. */
|
||||
bool restart; /*!< If true then restart of the game is pending. */
|
||||
bool touch;
|
||||
bool shutting_down; /*!< If true then shut down of the game is pending. */
|
||||
bool restart; /*!< If true then restart of the game is pending. */
|
||||
bool touch;
|
||||
|
||||
bool show_loading_on_launch;
|
||||
bool show_loading_on_launch;
|
||||
|
||||
const char* name;
|
||||
const char* name;
|
||||
|
||||
ALLEGRO_EVENT_SOURCE event_source;
|
||||
ALLEGRO_EVENT_SOURCE event_source;
|
||||
|
||||
float loading_progress;
|
||||
float loading_progress;
|
||||
|
||||
struct {
|
||||
bool (*event)(struct Game *game, ALLEGRO_EVENT *ev);
|
||||
void (*destroy)(struct Game *game);
|
||||
} handlers;
|
||||
|
||||
LIBSUPERDERPY_DATA_TYPE *data;
|
||||
struct {
|
||||
bool (*event)(struct Game* game, ALLEGRO_EVENT* ev);
|
||||
void (*destroy)(struct Game* game);
|
||||
} handlers;
|
||||
|
||||
LIBSUPERDERPY_DATA_TYPE* data;
|
||||
};
|
||||
|
||||
struct Game* libsuperderpy_init(int argc, char **argv, const char* name, struct 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);
|
||||
|
||||
struct GamestateResources;
|
||||
extern int Gamestate_ProgressCount;
|
||||
void Gamestate_ProcessEvent(struct Game *game, struct GamestateResources *data, ALLEGRO_EVENT *ev);
|
||||
void Gamestate_Logic(struct Game *game, struct GamestateResources *data);
|
||||
void Gamestate_Draw(struct Game *game, struct GamestateResources *data);
|
||||
void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*));
|
||||
void Gamestate_Unload(struct Game *game, struct GamestateResources *data);
|
||||
void Gamestate_Start(struct Game *game, struct GamestateResources *data);
|
||||
void Gamestate_Stop(struct Game *game, struct GamestateResources *data);
|
||||
void Gamestate_Reload(struct Game *game, struct GamestateResources* data);
|
||||
void Gamestate_Pause(struct Game *game, struct GamestateResources* data);
|
||||
void Gamestate_Resume(struct Game *game, struct GamestateResources* data);
|
||||
void Gamestate_ProcessEvent(struct Game* game, struct GamestateResources* data, ALLEGRO_EVENT* ev);
|
||||
void Gamestate_Logic(struct Game* game, struct GamestateResources* data);
|
||||
void Gamestate_Draw(struct Game* game, struct GamestateResources* data);
|
||||
void* Gamestate_Load(struct Game* game, void (*progress)(struct Game*));
|
||||
void Gamestate_Unload(struct Game* game, struct GamestateResources* data);
|
||||
void Gamestate_Start(struct Game* game, struct GamestateResources* data);
|
||||
void Gamestate_Stop(struct Game* game, struct GamestateResources* data);
|
||||
void Gamestate_Reload(struct Game* game, struct GamestateResources* data);
|
||||
void Gamestate_Pause(struct Game* game, struct GamestateResources* data);
|
||||
void Gamestate_Resume(struct Game* game, struct GamestateResources* data);
|
||||
|
||||
#endif
|
||||
|
|
100
src/timeline.c
100
src/timeline.c
|
@ -17,10 +17,10 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <allegro5/allegro.h>
|
||||
#include "timeline.h"
|
||||
#include "internal.h"
|
||||
#include "utils.h"
|
||||
#include "timeline.h"
|
||||
#include <allegro5/allegro.h>
|
||||
|
||||
SYMBOL_EXPORT struct Timeline* TM_Init(struct Game* game, char* name) {
|
||||
PrintConsole(game, "Timeline Manager[%s]: init", name);
|
||||
|
@ -49,8 +49,8 @@ SYMBOL_EXPORT void TM_Process(struct Timeline* timeline) {
|
|||
timeline->queue->active = true;
|
||||
if ((*timeline->queue->function)(timeline->game, timeline->queue, TM_ACTIONSTATE_RUNNING)) {
|
||||
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: destroy action (%d - %s)", timeline->name, timeline->queue->id, timeline->queue->name);
|
||||
timeline->queue->active=false;
|
||||
struct TM_Action *tmp = timeline->queue;
|
||||
timeline->queue->active = false;
|
||||
struct TM_Action* tmp = timeline->queue;
|
||||
timeline->queue = timeline->queue->next;
|
||||
(*tmp->function)(timeline->game, tmp, TM_ACTIONSTATE_DESTROY);
|
||||
TM_DestroyArgs(tmp->arguments);
|
||||
|
@ -62,7 +62,7 @@ SYMBOL_EXPORT void TM_Process(struct Timeline* timeline) {
|
|||
} else {
|
||||
/* delay handling */
|
||||
if (timeline->queue->active) {
|
||||
struct TM_Action *tmp = timeline->queue;
|
||||
struct TM_Action* tmp = timeline->queue;
|
||||
timeline->queue = timeline->queue->next;
|
||||
free(tmp->name);
|
||||
free(tmp);
|
||||
|
@ -81,12 +81,12 @@ SYMBOL_EXPORT void TM_Process(struct Timeline* timeline) {
|
|||
/* process all elements from background marked as active */
|
||||
struct TM_Action *tmp, *tmp2, *pom = timeline->background;
|
||||
tmp = NULL;
|
||||
while (pom!=NULL) {
|
||||
while (pom != NULL) {
|
||||
bool destroy = false;
|
||||
if (pom->active) {
|
||||
if (*pom->function) {
|
||||
if ((*pom->function)(timeline->game, pom, TM_ACTIONSTATE_RUNNING)) {
|
||||
pom->active=false;
|
||||
pom->active = false;
|
||||
PrintConsole(timeline->game, "Timeline Manager[%s]: background: destroy action (%d - %s)", timeline->name, pom->id, pom->name);
|
||||
(*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
||||
if (tmp) {
|
||||
|
@ -117,12 +117,13 @@ SYMBOL_EXPORT void TM_Process(struct Timeline* timeline) {
|
|||
tmp2 = tmp;
|
||||
if (!tmp) {
|
||||
if (timeline->background) {
|
||||
pom=timeline->background->next;
|
||||
pom = timeline->background->next;
|
||||
} else {
|
||||
pom=NULL;
|
||||
pom = NULL;
|
||||
}
|
||||
} else {
|
||||
pom = tmp->next;
|
||||
}
|
||||
else pom=tmp->next;
|
||||
tmp = tmp2;
|
||||
}
|
||||
}
|
||||
|
@ -133,7 +134,9 @@ static void PauseTimers(struct Timeline* timeline, bool pause) {
|
|||
if (timeline->queue->timer) {
|
||||
if (pause) {
|
||||
al_stop_timer(timeline->queue->timer);
|
||||
} else if (!timeline->queue->active) al_resume_timer(timeline->queue->timer);
|
||||
} else if (!timeline->queue->active) {
|
||||
al_resume_timer(timeline->queue->timer);
|
||||
}
|
||||
}
|
||||
}
|
||||
struct TM_Action* tmp = timeline->background;
|
||||
|
@ -141,7 +144,9 @@ static void PauseTimers(struct Timeline* timeline, bool pause) {
|
|||
if (tmp->timer) {
|
||||
if (pause) {
|
||||
al_stop_timer(tmp->timer);
|
||||
} else if (!tmp->active) al_resume_timer(tmp->timer);
|
||||
} else if (!tmp->active) {
|
||||
al_resume_timer(tmp->timer);
|
||||
}
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
|
@ -154,8 +159,8 @@ static void TM_Propagate(struct Timeline* timeline, enum TM_ActionState action)
|
|||
}
|
||||
}
|
||||
/* process all elements from background marked as active */
|
||||
struct TM_Action *pom = timeline->background;
|
||||
while (pom!=NULL) {
|
||||
struct TM_Action* pom = timeline->background;
|
||||
while (pom != NULL) {
|
||||
if (pom->active) {
|
||||
if (*pom->function) {
|
||||
(*pom->function)(timeline->game, pom, action);
|
||||
|
@ -181,11 +186,11 @@ SYMBOL_EXPORT void TM_Resume(struct Timeline* timeline) {
|
|||
PauseTimers(timeline, false);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void TM_HandleEvent(struct Timeline* timeline, ALLEGRO_EVENT *ev) {
|
||||
if (ev->type != ALLEGRO_EVENT_TIMER) return;
|
||||
SYMBOL_EXPORT void TM_HandleEvent(struct Timeline* timeline, ALLEGRO_EVENT* ev) {
|
||||
if (ev->type != ALLEGRO_EVENT_TIMER) { return; }
|
||||
if (timeline->queue) {
|
||||
if (ev->timer.source == timeline->queue->timer) {
|
||||
timeline->queue->active=true;
|
||||
timeline->queue->active = true;
|
||||
al_destroy_timer(timeline->queue->timer);
|
||||
timeline->queue->timer = NULL;
|
||||
if (timeline->queue->function) {
|
||||
|
@ -197,26 +202,26 @@ SYMBOL_EXPORT void TM_HandleEvent(struct Timeline* timeline, ALLEGRO_EVENT *ev)
|
|||
return;
|
||||
}
|
||||
}
|
||||
struct TM_Action *pom = timeline->background;
|
||||
struct TM_Action* pom = timeline->background;
|
||||
while (pom) {
|
||||
if (ev->timer.source == pom->timer) {
|
||||
PrintConsole(timeline->game, "Timeline Manager[%s]: background: delay reached, run action (%d - %s)", timeline->name, pom->id, pom->name);
|
||||
pom->active=true;
|
||||
pom->active = true;
|
||||
al_destroy_timer(pom->timer);
|
||||
pom->timer = NULL;
|
||||
(*pom->function)(timeline->game, pom, TM_ACTIONSTATE_START);
|
||||
return;
|
||||
}
|
||||
pom=pom->next;
|
||||
pom = pom->next;
|
||||
}
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT struct TM_Action* TM_AddAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, char* name) {
|
||||
struct TM_Action *action = malloc(sizeof(struct TM_Action));
|
||||
struct TM_Action* action = malloc(sizeof(struct TM_Action));
|
||||
if (timeline->queue) {
|
||||
struct TM_Action *pom = timeline->queue;
|
||||
while (pom->next!=NULL) {
|
||||
pom=pom->next;
|
||||
struct TM_Action* pom = timeline->queue;
|
||||
while (pom->next != NULL) {
|
||||
pom = pom->next;
|
||||
}
|
||||
pom->next = action;
|
||||
} else {
|
||||
|
@ -238,11 +243,11 @@ 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) {
|
||||
struct TM_Action *action = malloc(sizeof(struct TM_Action));
|
||||
struct TM_Action* action = malloc(sizeof(struct TM_Action));
|
||||
if (timeline->background) {
|
||||
struct TM_Action *pom = timeline->background;
|
||||
while (pom->next!=NULL) {
|
||||
pom=pom->next;
|
||||
struct TM_Action* pom = timeline->background;
|
||||
while (pom->next != NULL) {
|
||||
pom = pom->next;
|
||||
}
|
||||
pom->next = action;
|
||||
} else {
|
||||
|
@ -258,7 +263,7 @@ SYMBOL_EXPORT struct TM_Action* TM_AddBackgroundAction(struct Timeline* timeline
|
|||
PrintConsole(timeline->game, "Timeline Manager[%s]: background: init action with delay %d ms (%d - %s)", timeline->name, delay, action->id, action->name);
|
||||
(*action->function)(timeline->game, action, TM_ACTIONSTATE_INIT);
|
||||
action->active = false;
|
||||
action->timer = al_create_timer(delay/1000.0);
|
||||
action->timer = al_create_timer(delay / 1000.0);
|
||||
al_register_event_source(timeline->game->_priv.event_queue, al_get_timer_event_source(action->timer));
|
||||
al_start_timer(action->timer);
|
||||
} else {
|
||||
|
@ -274,11 +279,11 @@ SYMBOL_EXPORT struct TM_Action* TM_AddBackgroundAction(struct Timeline* timeline
|
|||
|
||||
/*! \brief Predefined action used by TM_AddQueuedBackgroundAction */
|
||||
static bool runinbackground(struct Game* game, struct TM_Action* action, enum TM_ActionState state) {
|
||||
int* delay = (int*) TM_GetArg(action->arguments, 1);
|
||||
char* name = (char*) TM_GetArg(action->arguments, 2);
|
||||
struct Timeline *timeline = (struct Timeline*) TM_GetArg(action->arguments, 3);
|
||||
struct TM_Arguments *arguments = (struct TM_Arguments*) TM_GetArg(action->arguments, 4);
|
||||
bool *used = (bool*) TM_GetArg(action->arguments, 5);
|
||||
int* delay = (int*)TM_GetArg(action->arguments, 1);
|
||||
char* name = (char*)TM_GetArg(action->arguments, 2);
|
||||
struct Timeline* timeline = (struct Timeline*)TM_GetArg(action->arguments, 3);
|
||||
struct TM_Arguments* arguments = (struct TM_Arguments*)TM_GetArg(action->arguments, 4);
|
||||
bool* used = (bool*)TM_GetArg(action->arguments, 5);
|
||||
if (state == TM_ACTIONSTATE_START) {
|
||||
TM_AddBackgroundAction(timeline, TM_GetArg(action->arguments, 0), arguments, *delay, name);
|
||||
*used = true;
|
||||
|
@ -297,8 +302,8 @@ static bool runinbackground(struct Game* game, struct TM_Action* action, enum TM
|
|||
SYMBOL_EXPORT struct TM_Action* TM_AddQueuedBackgroundAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) {
|
||||
TM_WrapArg(int, del, delay);
|
||||
TM_WrapArg(bool, used, false);
|
||||
struct TM_Arguments* arguments = TM_AddToArgs(NULL, 6, (void*) func, del, strdup(name), (void*) timeline, args, used);
|
||||
return TM_AddAction(timeline, *runinbackground, arguments, "TM_BackgroundAction");
|
||||
struct TM_Arguments* arguments = TM_AddToArgs(NULL, 6, (void*)func, del, strdup(name), (void*)timeline, args, used);
|
||||
return TM_AddAction(timeline, runinbackground, arguments, "TM_BackgroundAction");
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void TM_AddDelay(struct Timeline* timeline, int delay) {
|
||||
|
@ -309,15 +314,17 @@ SYMBOL_EXPORT void TM_AddDelay(struct Timeline* timeline, int delay) {
|
|||
struct TM_Action* tmp = TM_AddAction(timeline, NULL, NULL, "TM_Delay");
|
||||
PrintConsole(timeline->game, "Timeline Manager[%s]: queue: adding delay %d ms (%d)", timeline->name, delay, tmp->id);
|
||||
tmp->delay = delay;
|
||||
tmp->timer = al_create_timer(delay/1000.0);
|
||||
tmp->timer = al_create_timer(delay / 1000.0);
|
||||
al_register_event_source(timeline->game->_priv.event_queue, al_get_timer_event_source(tmp->timer));
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void TM_CleanQueue(struct Timeline* timeline) {
|
||||
PrintConsole(timeline->game, "Timeline Manager[%s]: cleaning queue", timeline->name);
|
||||
struct TM_Action *tmp, *pom = timeline->queue;
|
||||
while (pom!=NULL) {
|
||||
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
||||
while (pom != NULL) {
|
||||
if (*pom->function) {
|
||||
(*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
||||
}
|
||||
if (pom->timer) {
|
||||
al_stop_timer(pom->timer);
|
||||
al_destroy_timer(pom->timer);
|
||||
|
@ -334,8 +341,10 @@ SYMBOL_EXPORT void TM_CleanQueue(struct Timeline* timeline) {
|
|||
SYMBOL_EXPORT void TM_CleanBackgroundQueue(struct Timeline* timeline) {
|
||||
PrintConsole(timeline->game, "Timeline Manager[%s]: cleaning background queue", timeline->name);
|
||||
struct TM_Action *tmp, *pom = timeline->background;
|
||||
while (pom!=NULL) {
|
||||
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
||||
while (pom != NULL) {
|
||||
if (*pom->function) {
|
||||
(*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
||||
}
|
||||
if (pom->timer) {
|
||||
al_stop_timer(pom->timer);
|
||||
al_destroy_timer(pom->timer);
|
||||
|
@ -374,12 +383,11 @@ SYMBOL_EXPORT void TM_Destroy(struct Timeline* timeline) {
|
|||
}
|
||||
|
||||
SYMBOL_EXPORT struct TM_Arguments* TM_AddToArgs(struct TM_Arguments* args, int num, ...) {
|
||||
|
||||
va_list ap;
|
||||
int i;
|
||||
va_start(ap, num);
|
||||
struct TM_Arguments* tmp = args;
|
||||
for(i = 0; i < num; i++) {
|
||||
for (i = 0; i < num; i++) {
|
||||
if (!tmp) {
|
||||
tmp = malloc(sizeof(struct TM_Arguments));
|
||||
tmp->value = va_arg(ap, void*);
|
||||
|
@ -398,15 +406,15 @@ SYMBOL_EXPORT struct TM_Arguments* TM_AddToArgs(struct TM_Arguments* args, int n
|
|||
return args;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void* TM_GetArg(struct TM_Arguments *args, int num) {
|
||||
for (int i=0; i<num; i++) {
|
||||
SYMBOL_EXPORT void* TM_GetArg(struct TM_Arguments* args, int num) {
|
||||
for (int i = 0; i < num; i++) {
|
||||
args = args->next;
|
||||
}
|
||||
return args->value;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void TM_DestroyArgs(struct TM_Arguments* args) {
|
||||
struct TM_Arguments *pom;
|
||||
struct TM_Arguments* pom;
|
||||
while (args) {
|
||||
pom = args->next;
|
||||
free(args);
|
||||
|
|
|
@ -23,7 +23,9 @@
|
|||
|
||||
#include "libsuperderpy.h"
|
||||
|
||||
#define TM_WrapArg(type, result, val) type* result = malloc(sizeof(type)); *result = val;
|
||||
#define TM_WrapArg(type, result, val) \
|
||||
type* result = malloc(sizeof(type)); \
|
||||
*result = val;
|
||||
|
||||
/*! \brief State of the TM_Action. */
|
||||
enum TM_ActionState {
|
||||
|
@ -38,29 +40,29 @@ enum TM_ActionState {
|
|||
|
||||
/*! \brief Timeline structure. */
|
||||
struct Timeline {
|
||||
struct TM_Action *queue; /*!< Main timeline queue. */
|
||||
struct TM_Action *background; /*!< Background queue. */
|
||||
char* name; /*!< Name of the timeline. */
|
||||
unsigned int lastid; /*!< Last ID given to timeline action. */
|
||||
struct Game* game; /*!< Reference to the game object. */
|
||||
struct TM_Action* queue; /*!< Main timeline queue. */
|
||||
struct TM_Action* background; /*!< Background queue. */
|
||||
char* name; /*!< Name of the timeline. */
|
||||
unsigned int lastid; /*!< Last ID given to timeline action. */
|
||||
struct Game* game; /*!< Reference to the game object. */
|
||||
};
|
||||
|
||||
/*! \brief Arguments for TM_Action. */
|
||||
struct TM_Arguments {
|
||||
void *value; /*!< Value of argument. */
|
||||
struct TM_Arguments *next; /*!< Pointer to next argument. */
|
||||
void* value; /*!< Value of argument. */
|
||||
struct TM_Arguments* next; /*!< Pointer to next argument. */
|
||||
};
|
||||
|
||||
/*! \brief Timeline action. */
|
||||
struct TM_Action {
|
||||
bool (*function)(struct Game*, struct TM_Action*, enum TM_ActionState); /*!< Function callback of the action. */
|
||||
struct TM_Arguments *arguments; /*!< Arguments of the action. */
|
||||
ALLEGRO_TIMER *timer; /*!< Delay timer. */
|
||||
bool active; /*!< If false, then this action is waiting for it's delay to finish. */
|
||||
int delay; /*!< Number of miliseconds to delay before action is started. */
|
||||
struct TM_Action *next; /*!< Pointer to next action in queue. */
|
||||
unsigned int id; /*!< ID of the action. */
|
||||
char* name; /*!< "User friendly" name of the action. */
|
||||
bool (*function)(struct Game*, struct TM_Action*, enum TM_ActionState); /*!< Function callback of the action. */
|
||||
struct TM_Arguments* arguments; /*!< Arguments of the action. */
|
||||
ALLEGRO_TIMER* timer; /*!< Delay timer. */
|
||||
bool active; /*!< If false, then this action is waiting for it's delay to finish. */
|
||||
int delay; /*!< Number of miliseconds to delay before action is started. */
|
||||
struct TM_Action* next; /*!< Pointer to next action in queue. */
|
||||
unsigned int id; /*!< ID of the action. */
|
||||
char* name; /*!< "User friendly" name of the action. */
|
||||
};
|
||||
|
||||
/*! \brief Init timeline. */
|
||||
|
@ -74,7 +76,7 @@ void TM_Pause(struct Timeline*);
|
|||
/*! \brief Resumes the timeline. */
|
||||
void TM_Resume(struct Timeline*);
|
||||
/*! \brief Handle timer events. */
|
||||
void TM_HandleEvent(struct Timeline*, ALLEGRO_EVENT *ev);
|
||||
void TM_HandleEvent(struct Timeline*, ALLEGRO_EVENT* ev);
|
||||
/*! \brief Add new action to main queue. */
|
||||
struct TM_Action* TM_AddAction(struct Timeline*, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, char* name);
|
||||
/*! \brief Add new action to background queue. */
|
||||
|
@ -92,7 +94,7 @@ void TM_Destroy(struct Timeline*);
|
|||
/*! \brief Add data to TM_Arguments queue. */
|
||||
struct TM_Arguments* TM_AddToArgs(struct TM_Arguments* args, int num, ...);
|
||||
/*! \brief Get nth argument from TM_Arguments queue (counted from 0). */
|
||||
void* TM_GetArg(struct TM_Arguments *args, int num);
|
||||
void* TM_GetArg(struct TM_Arguments* args, int num);
|
||||
/*! \brief Destroy TM_Arguments queue. */
|
||||
void TM_DestroyArgs(struct TM_Arguments* args);
|
||||
/*! \brief Skip delay if it's currently the first action in the queue */
|
||||
|
|
186
src/utils.c
186
src/utils.c
|
@ -18,14 +18,14 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "internal.h"
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#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[] = {
|
||||
|
@ -45,59 +45,59 @@ SYMBOL_EXPORT void DrawHorizontalGradientRect(float x, float y, float w, float h
|
|||
al_draw_prim(v, NULL, NULL, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void DrawTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *text) {
|
||||
al_draw_text(font, al_map_rgba(0,0,0,128), x+1, y+1, flags, text);
|
||||
SYMBOL_EXPORT void DrawTextWithShadow(ALLEGRO_FONT* font, ALLEGRO_COLOR color, float x, float y, int flags, char const* text) {
|
||||
al_draw_text(font, al_map_rgba(0, 0, 0, 128), x + 1, y + 1, flags, text);
|
||||
al_draw_text(font, color, x, y, flags, text);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT int DrawWrappedText(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int width, int flags, char const* text) {
|
||||
SYMBOL_EXPORT int DrawWrappedText(ALLEGRO_FONT* font, ALLEGRO_COLOR color, float x, float y, int width, int flags, char const* text) {
|
||||
// TODO: use al_do_multiline_text; and switch to al_draw_multiline_text once it returns number of lines
|
||||
|
||||
char stext[1024]; // Copy of the passed text.
|
||||
char *pch; // A pointer to each word.
|
||||
char* pch; // A pointer to each word.
|
||||
char word[255]; // A string containing the word (for convienence)
|
||||
char *breakchar = "\n";
|
||||
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], "");
|
||||
strncpy(stext, text, 1024);
|
||||
strncpy(temp, "", 1024);
|
||||
for (int i = 0; i < 40; i += 1) {
|
||||
strncpy(lines[i], "", 1024);
|
||||
}
|
||||
//-------------------- Code Begins
|
||||
|
||||
char *context;
|
||||
char* context;
|
||||
|
||||
pch = strtok_r(stext," ", &context); // Get the first word.
|
||||
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
|
||||
strncpy(word, "", 255); // Truncate the string, to ensure there's no crazy stuff in there from memory.
|
||||
snprintf(word, 255, "%s ", pch);
|
||||
strncat(temp, word, 255); // 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
|
||||
if (strncmp(word, breakchar, 255) == 0) {
|
||||
line += 1; // Move down a Line
|
||||
strncpy(temp, "", 1024); // 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 (al_get_text_width(font, temp) >= (width)) { // Check if text is larger than the area.
|
||||
strncpy(temp, word, 255); // 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.
|
||||
strncat(lines[line], word, 255); // Append the word to whatever line we are currently on.
|
||||
}
|
||||
}
|
||||
pch = strtok_r (NULL, " ", &context); // Get the next word.
|
||||
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.
|
||||
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, x + (width/2), y + (i * height), ALLEGRO_ALIGN_CENTER, lines[i]);
|
||||
al_draw_text(font, color, x + (width / 2), y + (i * height), ALLEGRO_ALIGN_CENTER, lines[i]);
|
||||
break;
|
||||
case ALLEGRO_ALIGN_RIGHT:
|
||||
al_draw_text(font, color, x + width, y + (i * height), ALLEGRO_ALIGN_RIGHT, lines[i]);
|
||||
|
@ -108,25 +108,25 @@ SYMBOL_EXPORT int DrawWrappedText(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float
|
|||
break;
|
||||
}
|
||||
}
|
||||
return ((line+1) * height); // Return the actual height of the text in pixels.
|
||||
return ((line + 1) * height); // Return the actual height of the text in pixels.
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT int DrawWrappedTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int width, int flags, char const *text) {
|
||||
DrawWrappedText(font, al_map_rgba(0,0,0,128), x+1, y+1, width, flags, text);
|
||||
SYMBOL_EXPORT int DrawWrappedTextWithShadow(ALLEGRO_FONT* font, ALLEGRO_COLOR color, float x, float y, int width, int flags, char const* text) {
|
||||
DrawWrappedText(font, al_map_rgba(0, 0, 0, 128), x + 1, y + 1, width, flags, text);
|
||||
return DrawWrappedText(font, color, x, y, width, flags, text);
|
||||
}
|
||||
|
||||
/* 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),
|
||||
c1.g + frac * (c2.g - c1.g),
|
||||
c1.b + frac * (c2.b - c1.b),
|
||||
c1.a + frac * (c2.a - c1.a));
|
||||
c1.g + frac * (c2.g - c1.g),
|
||||
c1.b + frac * (c2.b - c1.b),
|
||||
c1.a + frac * (c2.a - c1.a));
|
||||
}
|
||||
|
||||
/*! \brief Scales bitmap using software linear filtering method to current target. */
|
||||
SYMBOL_EXPORT void ScaleBitmap(ALLEGRO_BITMAP* source, int width, int height) {
|
||||
if ((al_get_bitmap_width(source)==width) && (al_get_bitmap_height(source)==height)) {
|
||||
if ((al_get_bitmap_width(source) == width) && (al_get_bitmap_height(source) == height)) {
|
||||
al_draw_bitmap(source, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
@ -157,11 +157,11 @@ SYMBOL_EXPORT void ScaleBitmap(ALLEGRO_BITMAP* source, int width, int height) {
|
|||
al_unlock_bitmap(source);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, int height) {
|
||||
bool memoryscale = !atoi(GetConfigOptionDefault(game, "SuperDerpy", "GPU_scaling", "1"));
|
||||
SYMBOL_EXPORT ALLEGRO_BITMAP* LoadScaledBitmap(struct Game* game, char* filename, int width, int height) {
|
||||
bool memoryscale = !strtol(GetConfigOptionDefault(game, "SuperDerpy", "GPU_scaling", "1"), NULL, 10);
|
||||
ALLEGRO_BITMAP *source, *target = al_create_bitmap(width, height);
|
||||
al_set_target_bitmap(target);
|
||||
al_clear_to_color(al_map_rgba(0,0,0,0));
|
||||
al_clear_to_color(al_map_rgba(0, 0, 0, 0));
|
||||
char* origfn = GetDataFilePath(game, filename);
|
||||
|
||||
int flags = al_get_new_bitmap_flags();
|
||||
|
@ -169,12 +169,11 @@ SYMBOL_EXPORT ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename
|
|||
al_add_new_bitmap_flag(ALLEGRO_MEMORY_BITMAP);
|
||||
}
|
||||
|
||||
source = al_load_bitmap( origfn );
|
||||
source = al_load_bitmap(origfn);
|
||||
if (memoryscale) {
|
||||
al_set_new_bitmap_flags(flags);
|
||||
ScaleBitmap(source, width, height);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
al_draw_scaled_bitmap(source, 0, 0, al_get_bitmap_width(source), al_get_bitmap_height(source), 0, 0, width, height, 0);
|
||||
}
|
||||
|
||||
|
@ -182,10 +181,9 @@ SYMBOL_EXPORT ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename
|
|||
|
||||
free(origfn);
|
||||
return target;
|
||||
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void FatalError(struct Game *game, bool fatal, char* format, ...) {
|
||||
SYMBOL_EXPORT void FatalError(struct Game* game, bool exit, char* format, ...) {
|
||||
char text[1024] = {};
|
||||
PrintConsole(game, "Fatal Error, displaying Blue Screen of Derp...");
|
||||
va_list vl;
|
||||
|
@ -203,42 +201,40 @@ SYMBOL_EXPORT void FatalError(struct Game *game, bool fatal, char* format, ...)
|
|||
}
|
||||
|
||||
al_set_target_backbuffer(game->display);
|
||||
al_clear_to_color(al_map_rgb(0,0,170));
|
||||
al_clear_to_color(al_map_rgb(0, 0, 170));
|
||||
al_flip_display();
|
||||
al_rest(0.6);
|
||||
|
||||
bool done = false;
|
||||
while (!done) {
|
||||
|
||||
al_set_target_backbuffer(game->display);
|
||||
al_clear_to_color(al_map_rgb(0,0,170));
|
||||
al_clear_to_color(al_map_rgb(0, 0, 170));
|
||||
|
||||
const char *header = game->name;
|
||||
const char* header = game->name;
|
||||
|
||||
al_draw_filled_rectangle(al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header)/2 - 4, (int)(al_get_display_height(game->display) * 0.32), 4 + al_get_display_width(game->display)/2 + al_get_text_width(game->_priv.font_bsod, header)/2, (int)(al_get_display_height(game->display) * 0.32) + al_get_font_line_height(game->_priv.font_bsod), al_map_rgb(170,170,170));
|
||||
al_draw_filled_rectangle(al_get_display_width(game->display) / 2 - al_get_text_width(game->_priv.font_bsod, header) / 2 - 4, (int)(al_get_display_height(game->display) * 0.32), 4 + al_get_display_width(game->display) / 2 + al_get_text_width(game->_priv.font_bsod, header) / 2, (int)(al_get_display_height(game->display) * 0.32) + al_get_font_line_height(game->_priv.font_bsod), al_map_rgb(170, 170, 170));
|
||||
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(0, 0, 170), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32), ALLEGRO_ALIGN_CENTRE, header);
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(0, 0, 170), al_get_display_width(game->display) / 2, (int)(al_get_display_height(game->display) * 0.32), ALLEGRO_ALIGN_CENTRE, header);
|
||||
|
||||
const char *header2 = "A fatal exception 0xD3RP has occured at 0028:M00F11NZ in GST SD(01) +";
|
||||
const char* header2 = "A fatal exception 0xD3RP has occured at 0028:M00F11NZ in GST SD(01) +";
|
||||
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+2*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, header2);
|
||||
al_draw_textf(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+3*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "%p and system just doesn't know what went wrong.", game);
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2, (int)(al_get_display_height(game->display) * 0.32 + 2 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_CENTRE, header2);
|
||||
al_draw_textf(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2 - al_get_text_width(game->_priv.font_bsod, header2) / 2, (int)(al_get_display_height(game->display) * 0.32 + 3 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_LEFT, "%p and system just doesn't know what went wrong.", game);
|
||||
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+5*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, text);
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2, (int)(al_get_display_height(game->display) * 0.32 + 5 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_CENTRE, text);
|
||||
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+7*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to terminate this error.");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+8*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to destroy all muffins in the world.");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+9*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Just kidding, please press any key anyway.");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2 - al_get_text_width(game->_priv.font_bsod, header2) / 2, (int)(al_get_display_height(game->display) * 0.32 + 7 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to terminate this error.");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2 - al_get_text_width(game->_priv.font_bsod, header2) / 2, (int)(al_get_display_height(game->display) * 0.32 + 8 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to destroy all muffins in the world.");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2 - al_get_text_width(game->_priv.font_bsod, header2) / 2, (int)(al_get_display_height(game->display) * 0.32 + 9 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_LEFT, "* Just kidding, please press any key anyway.");
|
||||
|
||||
if (exit) {
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2 - al_get_text_width(game->_priv.font_bsod, header2) / 2, (int)(al_get_display_height(game->display) * 0.32 + 11 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_LEFT, "This is fatal error. My bad.");
|
||||
|
||||
if (fatal) {
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "This is fatal error. My bad.");
|
||||
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to quit _");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2, (int)(al_get_display_height(game->display) * 0.32 + 13 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to quit _");
|
||||
} else {
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "Anything I can do to help?");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2 - al_get_text_width(game->_priv.font_bsod, header2) / 2, (int)(al_get_display_height(game->display) * 0.32 + 11 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_LEFT, "Anything I can do to help?");
|
||||
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to continue _");
|
||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255, 255, 255), al_get_display_width(game->display) / 2, (int)(al_get_display_height(game->display) * 0.32 + 13 * al_get_font_line_height(game->_priv.font_bsod) * 1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to continue _");
|
||||
}
|
||||
|
||||
al_flip_display();
|
||||
|
@ -246,10 +242,10 @@ SYMBOL_EXPORT void FatalError(struct Game *game, bool fatal, char* format, ...)
|
|||
ALLEGRO_KEYBOARD_STATE kb;
|
||||
al_get_keyboard_state(&kb);
|
||||
|
||||
// FIXME: implement proper event loop there
|
||||
// FIXME: implement proper event loop there
|
||||
#ifndef __EMSCRIPTEN__
|
||||
int i;
|
||||
for (i=0; i<ALLEGRO_KEY_PAUSE; i++) {
|
||||
for (i = 0; i < ALLEGRO_KEY_PAUSE; i++) {
|
||||
if (al_key_down(&kb, i)) {
|
||||
done = true;
|
||||
break;
|
||||
|
@ -263,10 +259,10 @@ SYMBOL_EXPORT void FatalError(struct Game *game, bool fatal, char* format, ...)
|
|||
}
|
||||
|
||||
static void TestPath(char* filename, char* subpath, char** result) {
|
||||
if (*result) return; //already found
|
||||
ALLEGRO_PATH *tail = al_create_path(filename);
|
||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
|
||||
ALLEGRO_PATH *data = al_create_path(subpath);
|
||||
if (*result) { return; } //already found
|
||||
ALLEGRO_PATH* tail = al_create_path(filename);
|
||||
ALLEGRO_PATH* path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
|
||||
ALLEGRO_PATH* data = al_create_path(subpath);
|
||||
al_join_paths(path, data);
|
||||
al_join_paths(path, tail);
|
||||
//printf("Testing for %s\n", al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
|
@ -278,15 +274,21 @@ static void TestPath(char* filename, char* subpath, char** result) {
|
|||
al_destroy_path(path);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT char* GetGameName(struct Game *game, char* format) {
|
||||
char *result = malloc(sizeof(char)*255);
|
||||
#if defined(__clang__) || defined(__codemodel__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
SYMBOL_EXPORT char* GetGameName(struct Game* game, char* format) {
|
||||
char* result = malloc(sizeof(char) * 255);
|
||||
snprintf(result, 255, format, game->name);
|
||||
return AddGarbage(game, result);
|
||||
}
|
||||
#if defined(__clang__) || defined(__codemodel__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
static char* TestDataFilePath(struct Game *game, char* filename) {
|
||||
char *result = NULL;
|
||||
static char* TestDataFilePath(struct Game* game, char* filename) {
|
||||
char* result = NULL;
|
||||
|
||||
if (al_filename_exists(filename)) {
|
||||
return strdup(filename);
|
||||
|
@ -294,7 +296,7 @@ static char* TestDataFilePath(struct Game *game, char* filename) {
|
|||
|
||||
{
|
||||
char origfn[255] = "data/";
|
||||
strcat(origfn, filename);
|
||||
strncat(origfn, filename, 249);
|
||||
|
||||
if (al_filename_exists(origfn)) {
|
||||
return strdup(origfn);
|
||||
|
@ -313,9 +315,8 @@ static char* TestDataFilePath(struct Game *game, char* filename) {
|
|||
return result;
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT char* GetDataFilePath(struct Game *game, char* filename) {
|
||||
|
||||
char *result = 0;
|
||||
SYMBOL_EXPORT char* GetDataFilePath(struct Game* game, char* filename) {
|
||||
char* result = 0;
|
||||
|
||||
#ifdef ALLEGRO_ANDROID
|
||||
char origfn[255] = "android/";
|
||||
|
@ -357,11 +358,15 @@ SYMBOL_EXPORT char* GetDataFilePath(struct Game *game, char* filename) {
|
|||
|
||||
ALLEGRO_DEBUG_CHANNEL("libsuperderpy")
|
||||
|
||||
SYMBOL_EXPORT void PrintConsole(struct Game *game, char* format, ...) {
|
||||
#if defined(__clang__) || defined(__codemodel__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wformat-nonliteral"
|
||||
#endif
|
||||
SYMBOL_EXPORT void PrintConsole(struct Game* game, char* format, ...) {
|
||||
va_list vl;
|
||||
va_start(vl, format);
|
||||
char* text = game->_priv.console[game->_priv.console_pos];
|
||||
vsnprintf(text, (sizeof(game->_priv.console[0])/sizeof(game->_priv.console[0][0])), format, vl);
|
||||
vsnprintf(text, (sizeof(game->_priv.console[0]) / sizeof(game->_priv.console[0][0])), format, vl);
|
||||
va_end(vl);
|
||||
ALLEGRO_DEBUG("%s", text);
|
||||
#ifndef __EMSCRIPTEN__
|
||||
|
@ -372,14 +377,15 @@ SYMBOL_EXPORT void PrintConsole(struct Game *game, char* format, ...) {
|
|||
fflush(stdout);
|
||||
}
|
||||
game->_priv.console_pos++;
|
||||
if (game->_priv.console_pos >= (sizeof(game->_priv.console)/sizeof(game->_priv.console[0]))) {
|
||||
if (game->_priv.console_pos >= (sizeof(game->_priv.console) / sizeof(game->_priv.console[0]))) {
|
||||
game->_priv.console_pos = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#if defined(__clang__) || defined(__codemodel__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
SYMBOL_EXPORT void SetupViewport(struct Game *game, struct Viewport config) {
|
||||
|
||||
SYMBOL_EXPORT void SetupViewport(struct Game* game, struct Viewport config) {
|
||||
game->viewport = config;
|
||||
|
||||
if ((game->viewport.width == 0) || (game->viewport.height == 0)) {
|
||||
|
@ -387,7 +393,7 @@ SYMBOL_EXPORT void SetupViewport(struct Game *game, struct Viewport config) {
|
|||
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.width / (float)game->viewport.aspect;
|
||||
game->viewport.height = game->viewport.width / game->viewport.aspect;
|
||||
}
|
||||
}
|
||||
game->viewport.aspect = game->viewport.width / (float)game->viewport.height;
|
||||
|
@ -407,21 +413,21 @@ SYMBOL_EXPORT void SetupViewport(struct Game *game, struct Viewport config) {
|
|||
resolution = 1;
|
||||
}
|
||||
}
|
||||
if ((!atoi(GetConfigOptionDefault(game, "SuperDerpy", "downscale", "1"))) && (resolution < 1)) {
|
||||
if ((!strtol(GetConfigOptionDefault(game, "SuperDerpy", "downscale", "1"), NULL, 10)) && (resolution < 1)) {
|
||||
resolution = 1;
|
||||
}
|
||||
if (!atoi(GetConfigOptionDefault(game, "SuperDerpy", "scaling", "1"))) {
|
||||
if (!strtol(GetConfigOptionDefault(game, "SuperDerpy", "scaling", "1"), NULL, 10)) {
|
||||
resolution = 1;
|
||||
}
|
||||
|
||||
int clipWidth = game->viewport.width * resolution;
|
||||
int clipHeight = game->viewport.height * resolution;
|
||||
if (atoi(GetConfigOptionDefault(game, "SuperDerpy", "letterbox", "1"))) {
|
||||
if (strtol(GetConfigOptionDefault(game, "SuperDerpy", "letterbox", "1"), NULL, 10)) {
|
||||
int clipX = (al_get_display_width(game->display) - clipWidth) / 2;
|
||||
int clipY = (al_get_display_height(game->display) - clipHeight) / 2;
|
||||
al_build_transform(&game->projection, clipX, clipY, resolution, resolution, 0.0f);
|
||||
al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight);
|
||||
} else if (atoi(GetConfigOptionDefault(game, "SuperDerpy", "scaling", "1"))) {
|
||||
} else if (strtol(GetConfigOptionDefault(game, "SuperDerpy", "scaling", "1"), NULL, 10)) {
|
||||
al_build_transform(&game->projection, 0, 0, al_get_display_width(game->display) / (float)game->viewport.width, al_get_display_height(game->display) / (float)game->viewport.height, 0.0f);
|
||||
}
|
||||
al_use_transform(&game->projection);
|
||||
|
@ -429,7 +435,7 @@ SYMBOL_EXPORT void SetupViewport(struct Game *game, struct Viewport config) {
|
|||
Console_Load(game);
|
||||
}
|
||||
|
||||
SYMBOL_EXPORT void WindowCoordsToViewport(struct Game *game, int *x, int *y) {
|
||||
SYMBOL_EXPORT void WindowCoordsToViewport(struct Game* game, int* x, int* y) {
|
||||
int clipX, clipY, clipWidth, clipHeight;
|
||||
al_get_clipping_rectangle(&clipX, &clipY, &clipWidth, &clipHeight);
|
||||
*x -= clipX;
|
||||
|
@ -441,7 +447,7 @@ SYMBOL_EXPORT void WindowCoordsToViewport(struct Game *game, int *x, int *y) {
|
|||
SYMBOL_EXPORT ALLEGRO_BITMAP* CreateNotPreservedBitmap(int width, int height) {
|
||||
int flags = al_get_new_bitmap_flags();
|
||||
al_add_new_bitmap_flag(ALLEGRO_NO_PRESERVE_TEXTURE);
|
||||
ALLEGRO_BITMAP *bitmap = al_create_bitmap(width, height);
|
||||
ALLEGRO_BITMAP* bitmap = al_create_bitmap(width, height);
|
||||
al_set_new_bitmap_flags(flags);
|
||||
return bitmap;
|
||||
}
|
||||
|
|
22
src/utils.h
22
src/utils.h
|
@ -21,9 +21,9 @@
|
|||
#ifndef LIBSUPERDERPY_UTILS_H
|
||||
#define LIBSUPERDERPY_UTILS_H
|
||||
|
||||
#include "libsuperderpy.h"
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include "libsuperderpy.h"
|
||||
|
||||
#ifdef ALLEGRO_WINDOWS
|
||||
#define LIBRARY_EXTENSION ".dll"
|
||||
|
@ -46,21 +46,21 @@ void DrawHorizontalGradientRect(float x, float y, float w, float h, ALLEGRO_COLO
|
|||
* Draws given text two times: once with color (0,0,0,128) and 1px off in both x and y axis,
|
||||
* and second time with actual given color and position.
|
||||
*/
|
||||
void DrawTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int flags, char const *text);
|
||||
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, float x, float y, int width, int flags, char const *text);
|
||||
int DrawWrappedTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float y, int width, int flags, char const *text);
|
||||
int DrawWrappedText(ALLEGRO_FONT* font, ALLEGRO_COLOR color, float x, float y, int width, int flags, char const* text);
|
||||
int DrawWrappedTextWithShadow(ALLEGRO_FONT* font, ALLEGRO_COLOR color, float x, float y, int width, int flags, char const* text);
|
||||
|
||||
ALLEGRO_COLOR InterpolateColor(ALLEGRO_COLOR c1, ALLEGRO_COLOR c2, float frac);
|
||||
void ScaleBitmap(ALLEGRO_BITMAP* source, int width, int height);
|
||||
|
||||
/*! \brief Loads bitmap into memory and scales it with software linear filtering. */
|
||||
ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, int height);
|
||||
ALLEGRO_BITMAP* LoadScaledBitmap(struct Game* game, char* filename, int width, int height);
|
||||
|
||||
/*! \brief Finds path for data file. */
|
||||
char* GetDataFilePath(struct Game *game, char* filename);
|
||||
char* GetDataFilePath(struct Game* game, char* filename);
|
||||
|
||||
char* GetGameName(struct Game *game, char* format);
|
||||
char* GetGameName(struct Game* game, char* format);
|
||||
|
||||
/*! \brief Print some message on game console.
|
||||
*
|
||||
|
@ -68,13 +68,13 @@ char* GetGameName(struct Game *game, char* format);
|
|||
* If game->debug is true, then it also prints given message on stdout.
|
||||
* It needs to be called in printf style.
|
||||
*/
|
||||
void PrintConsole(struct Game *game, char* format, ...);
|
||||
void PrintConsole(struct Game* game, char* format, ...);
|
||||
|
||||
void FatalError(struct Game *game, bool exit, char* format, ...);
|
||||
void FatalError(struct Game* game, bool exit, char* format, ...);
|
||||
|
||||
void SetupViewport(struct Game *game, struct Viewport config);
|
||||
void SetupViewport(struct Game* game, struct Viewport config);
|
||||
|
||||
void WindowCoordsToViewport(struct Game *game, int *x, int *y);
|
||||
void WindowCoordsToViewport(struct Game* game, int* x, int* y);
|
||||
|
||||
ALLEGRO_BITMAP* CreateNotPreservedBitmap(int width, int height);
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue