mirror of
https://gitlab.com/dosowisko.net/libsuperderpy.git
synced 2025-02-01 02:56:43 +01:00
reorganize source files a bit
This commit is contained in:
parent
c964f72d66
commit
617f9c0270
9 changed files with 495 additions and 353 deletions
|
@ -4,6 +4,8 @@ SET(SRC_LIST
|
|||
timeline.c
|
||||
gamestate.c
|
||||
libsuperderpy.c
|
||||
character.c
|
||||
internal.c
|
||||
)
|
||||
|
||||
add_library("libsuperderpy" SHARED ${SRC_LIST})
|
||||
|
|
204
src/character.c
Normal file
204
src/character.c
Normal file
|
@ -0,0 +1,204 @@
|
|||
/*! \file character.c
|
||||
* \brief Character and spritesheet functions.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Sebastian Krzyszkowiak <dos@dosowisko.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#include "stdio.h"
|
||||
#include "string.h"
|
||||
#include "utils.h"
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
while (tmp) {
|
||||
if (!strcmp(tmp->name, name)) {
|
||||
character->spritesheet = tmp;
|
||||
if (character->successor) free(character->successor);
|
||||
if (tmp->successor) {
|
||||
character->successor = strdup(tmp->successor);
|
||||
} else {
|
||||
character->successor = NULL;
|
||||
}
|
||||
character->pos = 0;
|
||||
if (character->bitmap) {
|
||||
if ((al_get_bitmap_width(character->bitmap) != tmp->width / tmp->cols) || (al_get_bitmap_height(character->bitmap) != tmp->height / tmp->rows)) {
|
||||
al_destroy_bitmap(character->bitmap);
|
||||
character->bitmap = al_create_bitmap(tmp->width / tmp->cols, tmp->height / tmp->rows);
|
||||
}
|
||||
} else {
|
||||
character->bitmap = al_create_bitmap(tmp->width / tmp->cols, tmp->height / tmp->rows);
|
||||
}
|
||||
PrintConsole(game, "SUCCESS: Spritesheet for %s activated: %s (%dx%d)", character->name, character->spritesheet->name, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap));
|
||||
return;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
PrintConsole(game, "ERROR: No spritesheets registered for %s with given name: %s", character->name, name);
|
||||
return;
|
||||
}
|
||||
|
||||
void ChangeSpritesheet(struct Game *game, struct Character *character, char* name) {
|
||||
if (character->successor) free(character->successor);
|
||||
character->successor = strdup(name);
|
||||
}
|
||||
|
||||
void LoadSpritesheets(struct Game *game, struct Character *character) {
|
||||
PrintConsole(game, "Loading spritesheets for character %s...", character->name);
|
||||
struct Spritesheet *tmp = character->spritesheets;
|
||||
while (tmp) {
|
||||
if (!tmp->bitmap) {
|
||||
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);
|
||||
tmp->height = al_get_bitmap_height(tmp->bitmap);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void UnloadSpritesheets(struct Game *game, struct Character *character) {
|
||||
PrintConsole(game, "Unloading spritesheets for character %s...", character->name);
|
||||
struct Spritesheet *tmp = character->spritesheets;
|
||||
while (tmp) {
|
||||
if (tmp->bitmap) al_destroy_bitmap(tmp->bitmap);
|
||||
tmp->bitmap = NULL;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
s = s->next;
|
||||
}
|
||||
PrintConsole(game, "Registering %s spritesheet: %s", character->name, name);
|
||||
char filename[255] = { };
|
||||
snprintf(filename, 255, "sprites/%s/%s.ini", character->name, name);
|
||||
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->kill = false;
|
||||
const char *kill = al_get_config_value(config, "", "kill");
|
||||
if (kill) s->kill = atoi(kill);
|
||||
s->successor=NULL;
|
||||
const char* successor = al_get_config_value(config, "", "successor");
|
||||
if (successor) {
|
||||
s->successor = malloc(255*sizeof(char));
|
||||
strncpy(s->successor, successor, 255);
|
||||
}
|
||||
s->next = character->spritesheets;
|
||||
character->spritesheets = s;
|
||||
al_destroy_config(config);
|
||||
}
|
||||
|
||||
struct Character* CreateCharacter(struct Game *game, char* name) {
|
||||
PrintConsole(game, "Creating character %s...", name);
|
||||
struct Character *character = malloc(sizeof(struct Character));
|
||||
character->name = strdup(name);
|
||||
character->angle = 0;
|
||||
character->bitmap = NULL;
|
||||
character->data = NULL;
|
||||
character->pos = 0;
|
||||
character->pos_tmp = 0;
|
||||
character->x = -1;
|
||||
character->y = -1;
|
||||
character->spritesheets = NULL;
|
||||
character->spritesheet = NULL;
|
||||
character->successor = NULL;
|
||||
character->shared = false;
|
||||
character->dead = false;
|
||||
return character;
|
||||
}
|
||||
|
||||
void DestroyCharacter(struct Game *game, struct Character *character) {
|
||||
PrintConsole(game, "Destroying character %s...", character->name);
|
||||
if (!character->shared) {
|
||||
struct Spritesheet *tmp, *s = character->spritesheets;
|
||||
tmp = s;
|
||||
while (s) {
|
||||
tmp = s;
|
||||
s = s->next;
|
||||
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);
|
||||
free(character->name);
|
||||
free(character);
|
||||
}
|
||||
|
||||
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->spritesheet->kill) {
|
||||
character->dead = true;
|
||||
} else if (character->successor) {
|
||||
SelectSpritesheet(game, character, character->successor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MoveCharacter(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;
|
||||
}
|
||||
|
||||
void SetCharacterPosition(struct Game *game, struct Character *character, int x, int y, float angle) {
|
||||
if (character->dead) return;
|
||||
character->x = x;
|
||||
character->y = y;
|
||||
character->angle = angle;
|
||||
}
|
||||
|
||||
void DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tint, 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 + al_get_bitmap_width(character->bitmap)/2, character->y + al_get_bitmap_height(character->bitmap)/2, 1, 1, character->angle, flags);
|
||||
}
|
79
src/character.h
Normal file
79
src/character.h
Normal file
|
@ -0,0 +1,79 @@
|
|||
/*! \file character.h
|
||||
* \brief Headers of character and spritesheet functions.
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) Sebastian Krzyszkowiak <dos@dosowisko.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef LIBSUPERDERPY_CHARACTER_H
|
||||
#define LIBSUPERDERPY_CHARACTER_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;
|
||||
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.). */
|
||||
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 DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tilt, int flags);
|
||||
|
||||
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 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 SetCharacterPosition(struct Game *game, struct Character *character, int x, int y, float angle);
|
||||
|
||||
#endif
|
|
@ -22,7 +22,7 @@
|
|||
#include "utils.h"
|
||||
#include "gamestate.h"
|
||||
|
||||
struct Gamestate* AddNewGamestate(struct Game *game) {
|
||||
__attribute__((visibility("hidden"))) struct Gamestate* AddNewGamestate(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
if (!tmp) {
|
||||
game->_priv.gamestates = malloc(sizeof(struct Gamestate));
|
||||
|
@ -45,7 +45,7 @@ struct Gamestate* AddNewGamestate(struct Game *game) {
|
|||
return tmp;
|
||||
}
|
||||
|
||||
struct Gamestate* FindGamestate(struct Game *game, const char* name) {
|
||||
__attribute__((visibility("hidden"))) struct Gamestate* FindGamestate(struct Game *game, const char* name) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if (!strcmp(name, tmp->name)) {
|
||||
|
|
169
src/internal.c
Normal file
169
src/internal.c
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
* Copyright (c) Sebastian Krzyszkowiak <dos@dosowisko.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* Also, ponies.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#include "libsuperderpy.h"
|
||||
|
||||
__attribute__((visibility("hidden"))) void DrawGamestates(struct Game *game) {
|
||||
al_set_target_backbuffer(game->display);
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started)) {
|
||||
(*tmp->api.Gamestate_Draw)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void LogicGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||
(*tmp->api.Gamestate_Logic)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||
(*tmp->api.Gamestate_ProcessEvent)(game, tmp->data, ev);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void PauseGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started)) {
|
||||
(*tmp->api.Gamestate_Pause)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__attribute__((visibility("hidden"))) void ResumeGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started)) {
|
||||
(*tmp->api.Gamestate_Resume)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void DrawConsole(struct Game *game) {
|
||||
if (game->_priv.showconsole) {
|
||||
al_set_target_backbuffer(game->display);
|
||||
ALLEGRO_TRANSFORM trans;
|
||||
al_identity_transform(&trans);
|
||||
int clipX, clipY, clipWidth, clipHeight;
|
||||
al_get_clipping_rectangle(&clipX, &clipY, &clipWidth, &clipHeight);
|
||||
al_use_transform(&trans);
|
||||
|
||||
al_draw_bitmap(game->_priv.console, clipX, clipY, 0);
|
||||
double game_time = al_get_time();
|
||||
if(game_time - game->_priv.fps_count.old_time >= 1.0) {
|
||||
game->_priv.fps_count.fps = game->_priv.fps_count.frames_done / (game_time - game->_priv.fps_count.old_time);
|
||||
game->_priv.fps_count.frames_done = 0;
|
||||
game->_priv.fps_count.old_time = game_time;
|
||||
}
|
||||
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);
|
||||
|
||||
al_use_transform(&game->projection);
|
||||
|
||||
}
|
||||
game->_priv.fps_count.frames_done++;
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void Console_Load(struct Game *game) {
|
||||
game->_priv.font_console = NULL;
|
||||
game->_priv.console = NULL;
|
||||
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.console = al_create_bitmap((al_get_display_width(game->display) / 320) * 320, al_get_font_line_height(game->_priv.font_console)*5);
|
||||
al_set_target_bitmap(game->_priv.console);
|
||||
al_clear_to_color(al_map_rgba(0,0,0,80));
|
||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void Console_Unload(struct Game *game) {
|
||||
al_destroy_font(game->_priv.font_console);
|
||||
al_destroy_bitmap(game->_priv.console);
|
||||
}
|
||||
|
||||
|
||||
void SetupViewport(struct Game *game) {
|
||||
game->viewport.width = 320;
|
||||
game->viewport.height = 180;
|
||||
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
|
||||
int resolution = al_get_display_width(game->display) / 320;
|
||||
if (al_get_display_height(game->display) / 180 < resolution) resolution = al_get_display_height(game->display) / 180;
|
||||
if (resolution < 1) resolution = 1;
|
||||
|
||||
if (atoi(GetConfigOptionDefault(game, "SuperDerpy", "letterbox", "1"))) {
|
||||
int clipWidth = 320 * resolution, clipHeight = 180 * resolution;
|
||||
int clipX = (al_get_display_width(game->display) - clipWidth) / 2, clipY = (al_get_display_height(game->display) - clipHeight) / 2;
|
||||
al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight);
|
||||
|
||||
al_build_transform(&game->projection, clipX, clipY, resolution, resolution, 0.0f);
|
||||
al_use_transform(&game->projection);
|
||||
|
||||
} else if ((atoi(GetConfigOptionDefault(game, "SuperDerpy", "rotate", "1"))) && (game->viewport.height > game->viewport.width)) {
|
||||
al_identity_transform(&game->projection);
|
||||
al_rotate_transform(&game->projection, 0.5*ALLEGRO_PI);
|
||||
al_translate_transform(&game->projection, game->viewport.width, 0);
|
||||
al_scale_transform(&game->projection, resolution, resolution);
|
||||
al_use_transform(&game->projection);
|
||||
int temp = game->viewport.height;
|
||||
game->viewport.height = game->viewport.width;
|
||||
game->viewport.width = temp;
|
||||
}
|
||||
if (game->_priv.console) Console_Unload(game);
|
||||
Console_Load(game);
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void GamestateProgress(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.cur_gamestate.tmp;
|
||||
game->_priv.cur_gamestate.p++;
|
||||
DrawGamestates(game);
|
||||
float progress = ((game->_priv.cur_gamestate.p / (*(tmp->api.Gamestate_ProgressCount) ? (float)*(tmp->api.Gamestate_ProgressCount) : 1))/(float)game->_priv.cur_gamestate.toLoad)+(game->_priv.cur_gamestate.loaded/(float)game->_priv.cur_gamestate.toLoad);
|
||||
if (game->config.debug) PrintConsole(game, "[%s] Progress: %d% (%d/%d)", tmp->name, (int)(progress*100), game->_priv.cur_gamestate.p, *(tmp->api.Gamestate_ProgressCount));
|
||||
if (tmp->showLoading) (*game->_priv.loading.Draw)(game, game->_priv.loading.data, progress);
|
||||
DrawConsole(game);
|
||||
if (al_get_time() - game->_priv.cur_gamestate.t >= 1/60.0) {
|
||||
al_flip_display();
|
||||
}
|
||||
game->_priv.cur_gamestate.t = al_get_time();
|
||||
}
|
37
src/internal.h
Normal file
37
src/internal.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) Sebastian Krzyszkowiak <dos@dosowisko.net>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef LIBSUPERDERPY_INTERNAL_H
|
||||
#define LIBSUPERDERPY_INTERNAL_H
|
||||
|
||||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include "libsuperderpy.h"
|
||||
|
||||
void DrawGamestates(struct Game *game);
|
||||
void LogicGamestates(struct Game *game);
|
||||
void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev);
|
||||
void PauseGamestates(struct Game *game);
|
||||
void ResumeGamestates(struct Game *game);
|
||||
void DrawConsole(struct Game *game);
|
||||
void Console_Load(struct Game *game);
|
||||
void Console_Unload(struct Game *game);
|
||||
void SetupViewport(struct Game *game);
|
||||
void GamestateProgress(struct Game *game);
|
||||
|
||||
#endif
|
|
@ -34,77 +34,9 @@
|
|||
#include <mach-o/dyld.h>
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "internal.h"
|
||||
#include "libsuperderpy.h"
|
||||
|
||||
__attribute__((visibility("hidden"))) void DrawGamestates(struct Game *game) {
|
||||
al_set_target_backbuffer(game->display);
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started)) {
|
||||
(*tmp->api.Gamestate_Draw)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void LogicGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||
(*tmp->api.Gamestate_Logic)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started) && (!tmp->paused)) {
|
||||
(*tmp->api.Gamestate_ProcessEvent)(game, tmp->data, ev);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void PauseGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started)) {
|
||||
(*tmp->api.Gamestate_Pause)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
__attribute__((visibility("hidden"))) void ResumeGamestates(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.gamestates;
|
||||
while (tmp) {
|
||||
if ((tmp->loaded) && (tmp->started)) {
|
||||
(*tmp->api.Gamestate_Resume)(game, tmp->data);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((visibility("hidden"))) void gamestate_progress(struct Game *game) {
|
||||
struct Gamestate *tmp = game->_priv.cur_gamestate.tmp;
|
||||
game->_priv.cur_gamestate.p++;
|
||||
DrawGamestates(game);
|
||||
float progress = ((game->_priv.cur_gamestate.p / (*(tmp->api.Gamestate_ProgressCount) ? (float)*(tmp->api.Gamestate_ProgressCount) : 1))/(float)game->_priv.cur_gamestate.toLoad)+(game->_priv.cur_gamestate.loaded/(float)game->_priv.cur_gamestate.toLoad);
|
||||
if (game->config.debug) PrintConsole(game, "[%s] Progress: %d% (%d/%d)", tmp->name, (int)(progress*100), game->_priv.cur_gamestate.p, *(tmp->api.Gamestate_ProgressCount));
|
||||
if (tmp->showLoading) (*game->_priv.loading.Draw)(game, game->_priv.loading.data, progress);
|
||||
DrawConsole(game);
|
||||
if (al_get_time() - game->_priv.cur_gamestate.t >= 1/60.0) {
|
||||
al_flip_display();
|
||||
}
|
||||
game->_priv.cur_gamestate.t = al_get_time();
|
||||
}
|
||||
|
||||
struct Game* libsuperderpy_init(int argc, char** argv, const char* name) {
|
||||
|
||||
struct Game *game = malloc(sizeof(struct Game));
|
||||
|
@ -381,7 +313,7 @@ int libsuperderpy_run(struct Game *game) {
|
|||
}
|
||||
game->_priv.cur_gamestate.t = al_get_time();
|
||||
game->_priv.cur_gamestate.tmp = tmp;
|
||||
tmp->data = (*tmp->api.Gamestate_Load)(game, &gamestate_progress);
|
||||
tmp->data = (*tmp->api.Gamestate_Load)(game, &GamestateProgress);
|
||||
game->_priv.cur_gamestate.loaded++;
|
||||
|
||||
tmp->loaded = true;
|
||||
|
|
257
src/utils.c
257
src/utils.c
|
@ -27,84 +27,6 @@
|
|||
#include "math.h"
|
||||
#include "utils.h"
|
||||
|
||||
void DrawConsole(struct Game *game) {
|
||||
if (game->_priv.showconsole) {
|
||||
al_set_target_backbuffer(game->display);
|
||||
ALLEGRO_TRANSFORM trans;
|
||||
al_identity_transform(&trans);
|
||||
int clipX, clipY, clipWidth, clipHeight;
|
||||
al_get_clipping_rectangle(&clipX, &clipY, &clipWidth, &clipHeight);
|
||||
al_use_transform(&trans);
|
||||
|
||||
al_draw_bitmap(game->_priv.console, clipX, clipY, 0);
|
||||
double game_time = al_get_time();
|
||||
if(game_time - game->_priv.fps_count.old_time >= 1.0) {
|
||||
game->_priv.fps_count.fps = game->_priv.fps_count.frames_done / (game_time - game->_priv.fps_count.old_time);
|
||||
game->_priv.fps_count.frames_done = 0;
|
||||
game->_priv.fps_count.old_time = game_time;
|
||||
}
|
||||
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);
|
||||
|
||||
al_use_transform(&game->projection);
|
||||
|
||||
}
|
||||
game->_priv.fps_count.frames_done++;
|
||||
}
|
||||
|
||||
void Console_Load(struct Game *game) {
|
||||
game->_priv.font_console = NULL;
|
||||
game->_priv.console = NULL;
|
||||
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.console = al_create_bitmap((al_get_display_width(game->display) / 320) * 320, al_get_font_line_height(game->_priv.font_console)*5);
|
||||
al_set_target_bitmap(game->_priv.console);
|
||||
al_clear_to_color(al_map_rgba(0,0,0,80));
|
||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||
}
|
||||
|
||||
void Console_Unload(struct Game *game) {
|
||||
al_destroy_font(game->_priv.font_console);
|
||||
al_destroy_bitmap(game->_priv.console);
|
||||
}
|
||||
|
||||
|
||||
void SetupViewport(struct Game *game) {
|
||||
game->viewport.width = 320;
|
||||
game->viewport.height = 180;
|
||||
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
|
||||
int resolution = al_get_display_width(game->display) / 320;
|
||||
if (al_get_display_height(game->display) / 180 < resolution) resolution = al_get_display_height(game->display) / 180;
|
||||
if (resolution < 1) resolution = 1;
|
||||
|
||||
if (atoi(GetConfigOptionDefault(game, "SuperDerpy", "letterbox", "1"))) {
|
||||
int clipWidth = 320 * resolution, clipHeight = 180 * resolution;
|
||||
int clipX = (al_get_display_width(game->display) - clipWidth) / 2, clipY = (al_get_display_height(game->display) - clipHeight) / 2;
|
||||
al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight);
|
||||
|
||||
al_build_transform(&game->projection, clipX, clipY, resolution, resolution, 0.0f);
|
||||
al_use_transform(&game->projection);
|
||||
|
||||
} else if ((atoi(GetConfigOptionDefault(game, "SuperDerpy", "rotate", "1"))) && (game->viewport.height > game->viewport.width)) {
|
||||
al_identity_transform(&game->projection);
|
||||
al_rotate_transform(&game->projection, 0.5*ALLEGRO_PI);
|
||||
al_translate_transform(&game->projection, game->viewport.width, 0);
|
||||
al_scale_transform(&game->projection, resolution, resolution);
|
||||
al_use_transform(&game->projection);
|
||||
int temp = game->viewport.height;
|
||||
game->viewport.height = game->viewport.width;
|
||||
game->viewport.width = temp;
|
||||
}
|
||||
if (game->_priv.console) Console_Unload(game);
|
||||
Console_Load(game);
|
||||
}
|
||||
|
||||
void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom) {
|
||||
ALLEGRO_VERTEX v[] = {
|
||||
|
@ -355,182 +277,3 @@ void PrintConsole(struct Game *game, char* format, ...) {
|
|||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||
al_destroy_bitmap(con);
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
while (tmp) {
|
||||
if (!strcmp(tmp->name, name)) {
|
||||
character->spritesheet = tmp;
|
||||
if (character->successor) free(character->successor);
|
||||
if (tmp->successor) {
|
||||
character->successor = strdup(tmp->successor);
|
||||
} else {
|
||||
character->successor = NULL;
|
||||
}
|
||||
character->pos = 0;
|
||||
if (character->bitmap) {
|
||||
if ((al_get_bitmap_width(character->bitmap) != tmp->width / tmp->cols) || (al_get_bitmap_height(character->bitmap) != tmp->height / tmp->rows)) {
|
||||
al_destroy_bitmap(character->bitmap);
|
||||
character->bitmap = al_create_bitmap(tmp->width / tmp->cols, tmp->height / tmp->rows);
|
||||
}
|
||||
} else {
|
||||
character->bitmap = al_create_bitmap(tmp->width / tmp->cols, tmp->height / tmp->rows);
|
||||
}
|
||||
PrintConsole(game, "SUCCESS: Spritesheet for %s activated: %s (%dx%d)", character->name, character->spritesheet->name, al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap));
|
||||
return;
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
PrintConsole(game, "ERROR: No spritesheets registered for %s with given name: %s", character->name, name);
|
||||
return;
|
||||
}
|
||||
|
||||
void ChangeSpritesheet(struct Game *game, struct Character *character, char* name) {
|
||||
if (character->successor) free(character->successor);
|
||||
character->successor = strdup(name);
|
||||
}
|
||||
|
||||
void LoadSpritesheets(struct Game *game, struct Character *character) {
|
||||
PrintConsole(game, "Loading spritesheets for character %s...", character->name);
|
||||
struct Spritesheet *tmp = character->spritesheets;
|
||||
while (tmp) {
|
||||
if (!tmp->bitmap) {
|
||||
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);
|
||||
tmp->height = al_get_bitmap_height(tmp->bitmap);
|
||||
}
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
void UnloadSpritesheets(struct Game *game, struct Character *character) {
|
||||
PrintConsole(game, "Unloading spritesheets for character %s...", character->name);
|
||||
struct Spritesheet *tmp = character->spritesheets;
|
||||
while (tmp) {
|
||||
if (tmp->bitmap) al_destroy_bitmap(tmp->bitmap);
|
||||
tmp->bitmap = NULL;
|
||||
tmp = tmp->next;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
s = s->next;
|
||||
}
|
||||
PrintConsole(game, "Registering %s spritesheet: %s", character->name, name);
|
||||
char filename[255] = { };
|
||||
snprintf(filename, 255, "sprites/%s/%s.ini", character->name, name);
|
||||
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->kill = false;
|
||||
const char *kill = al_get_config_value(config, "", "kill");
|
||||
if (kill) s->kill = atoi(kill);
|
||||
s->successor=NULL;
|
||||
const char* successor = al_get_config_value(config, "", "successor");
|
||||
if (successor) {
|
||||
s->successor = malloc(255*sizeof(char));
|
||||
strncpy(s->successor, successor, 255);
|
||||
}
|
||||
s->next = character->spritesheets;
|
||||
character->spritesheets = s;
|
||||
al_destroy_config(config);
|
||||
}
|
||||
|
||||
struct Character* CreateCharacter(struct Game *game, char* name) {
|
||||
PrintConsole(game, "Creating character %s...", name);
|
||||
struct Character *character = malloc(sizeof(struct Character));
|
||||
character->name = strdup(name);
|
||||
character->angle = 0;
|
||||
character->bitmap = NULL;
|
||||
character->data = NULL;
|
||||
character->pos = 0;
|
||||
character->pos_tmp = 0;
|
||||
character->x = -1;
|
||||
character->y = -1;
|
||||
character->spritesheets = NULL;
|
||||
character->spritesheet = NULL;
|
||||
character->successor = NULL;
|
||||
character->shared = false;
|
||||
character->dead = false;
|
||||
return character;
|
||||
}
|
||||
|
||||
void DestroyCharacter(struct Game *game, struct Character *character) {
|
||||
PrintConsole(game, "Destroying character %s...", character->name);
|
||||
if (!character->shared) {
|
||||
struct Spritesheet *tmp, *s = character->spritesheets;
|
||||
tmp = s;
|
||||
while (s) {
|
||||
tmp = s;
|
||||
s = s->next;
|
||||
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);
|
||||
free(character->name);
|
||||
free(character);
|
||||
}
|
||||
|
||||
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->spritesheet->kill) {
|
||||
character->dead = true;
|
||||
} else if (character->successor) {
|
||||
SelectSpritesheet(game, character, character->successor);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void MoveCharacter(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;
|
||||
}
|
||||
|
||||
void SetCharacterPosition(struct Game *game, struct Character *character, int x, int y, float angle) {
|
||||
if (character->dead) return;
|
||||
character->x = x;
|
||||
character->y = y;
|
||||
character->angle = angle;
|
||||
}
|
||||
|
||||
void DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tint, 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 + al_get_bitmap_width(character->bitmap)/2, character->y + al_get_bitmap_height(character->bitmap)/2, 1, 1, character->angle, flags);
|
||||
}
|
||||
|
|
24
src/utils.h
24
src/utils.h
|
@ -34,13 +34,6 @@
|
|||
#define LIBRARY_EXTENSION ".so"
|
||||
#endif
|
||||
|
||||
void SetupViewport(struct Game *game);
|
||||
void Console_Unload(struct Game *game);
|
||||
void DrawConsole(struct Game *game);
|
||||
|
||||
void AdvanceLevel(struct Game *game, bool won);
|
||||
void ShowLevelStatistics(struct Game *game);
|
||||
|
||||
/*! \brief Draws rectangle filled with vertical gradient. */
|
||||
void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom);
|
||||
/*! \brief Draws rectangle filled with horizontal gradient. */
|
||||
|
@ -103,21 +96,4 @@ struct Character {
|
|||
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 DrawCharacter(struct Game *game, struct Character *character, ALLEGRO_COLOR tilt, int flags);
|
||||
|
||||
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 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 SetCharacterPosition(struct Game *game, struct Character *character, int x, int y, float angle);
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in a new issue