mirror of
https://gitlab.com/dosowisko.net/libsuperderpy.git
synced 2024-12-12 20:18:00 +01:00
Remove everything!
Engine should be now clean from gamestate dependences. The next thing will be implementing dynamic gamestate loading.
This commit is contained in:
parent
5baf800f34
commit
e29382b5dc
13 changed files with 612 additions and 656 deletions
|
@ -1,10 +1,8 @@
|
|||
SET(SRC_LIST
|
||||
main.c
|
||||
allegro_utils.c
|
||||
utils.c
|
||||
config.c
|
||||
timeline.c
|
||||
gamestates/loading.c
|
||||
gamestates/menu.c
|
||||
gamestate.c
|
||||
)
|
||||
|
||||
find_package(Allegro5 REQUIRED)
|
||||
|
@ -25,10 +23,12 @@ if(MINGW)
|
|||
set(LINK_FLAGS -Wl,-subsystem,windows)
|
||||
endif(MINGW)
|
||||
|
||||
IF(${PACKAGE_BUILD})
|
||||
SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/superderpy:\$ORIGIN")
|
||||
ENDIF(${PACKAGE_BUILD})
|
||||
SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/superderpy:\$ORIGIN:\$ORIGIN/../lib")
|
||||
|
||||
#IF(${PACKAGE_BUILD})
|
||||
# SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
||||
# SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/superderpy:\$ORIGIN")
|
||||
#ENDIF(${PACKAGE_BUILD})
|
||||
|
||||
if(APPLE)
|
||||
set(EXECUTABLE "SuperDerpy")
|
||||
|
@ -36,11 +36,17 @@ else(APPLE)
|
|||
set(EXECUTABLE "superderpy")
|
||||
endif(APPLE)
|
||||
|
||||
add_executable(${EXECUTABLE} WIN32 MACOSX_BUNDLE ${SRC_LIST})
|
||||
add_library("libsuperderpy" SHARED ${SRC_LIST})
|
||||
add_executable(${EXECUTABLE} WIN32 MACOSX_BUNDLE "main.c")
|
||||
|
||||
SET_TARGET_PROPERTIES("libsuperderpy" PROPERTIES PREFIX "")
|
||||
|
||||
include_directories(${ALLEGRO5_INCLUDE_DIR} ${ALLEGRO5_FONT_INCLUDE_DIR} ${ALLEGRO5_TTF_INCLUDE_DIR} ${ALLEGRO5_PRIMITIVES_INCLUDE_DIR} ${ALLEGRO5_AUDIO_INCLUDE_DIR} ${ALLEGRO5_ACODEC_INCLUDE_DIR} ${ALLEGRO5_IMAGE_INCLUDE_DIR})
|
||||
|
||||
target_link_libraries(${EXECUTABLE} ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_MAIN_LIBRARIES} m)
|
||||
target_link_libraries(${EXECUTABLE} ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_MAIN_LIBRARIES} m libsuperderpy)
|
||||
|
||||
target_link_libraries("libsuperderpy" ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} ${ALLEGRO5_MAIN_LIBRARIES} m)
|
||||
|
||||
|
||||
if(ALLEGRO5_MAIN_FOUND)
|
||||
target_link_libraries(${EXECUTABLE} ${ALLEGRO5_MAIN_LIBRARIES})
|
||||
|
|
|
@ -1,45 +0,0 @@
|
|||
/*! \file allegro_utils.c
|
||||
* \brief Helper functions for Allegro.
|
||||
*/
|
||||
/*
|
||||
* 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 "allegro_utils.h"
|
||||
|
||||
void al_draw_vertical_gradient_rect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom) {
|
||||
ALLEGRO_VERTEX v[] = {
|
||||
{.x = x, .y = y, .z = 0, .color = top},
|
||||
{.x = x + w, .y = y, .z = 0, .color = top},
|
||||
{.x = x, .y = y + h, .z = 0, .color = bottom},
|
||||
{.x = x + w, .y = y + h, .z = 0, .color = bottom}};
|
||||
al_draw_prim(v, NULL, NULL, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
void al_draw_horizontal_gradient_rect(float x, float y, float w, float h, ALLEGRO_COLOR left, ALLEGRO_COLOR right) {
|
||||
ALLEGRO_VERTEX v[] = {
|
||||
{.x = x, .y = y, .z = 0, .color = left},
|
||||
{.x = x + w, .y = y, .z = 0, .color = right},
|
||||
{.x = x, .y = y + h, .z = 0, .color = left},
|
||||
{.x = x + w, .y = y + h, .z = 0, .color = right}};
|
||||
al_draw_prim(v, NULL, NULL, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
void al_draw_text_with_shadow(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);
|
||||
}
|
26
src/config.c
26
src/config.c
|
@ -21,38 +21,36 @@
|
|||
#include <allegro5/allegro.h>
|
||||
#include "config.h"
|
||||
|
||||
ALLEGRO_CONFIG *config;
|
||||
|
||||
void InitConfig(void) {
|
||||
void InitConfig(struct Game *game) {
|
||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_SETTINGS_PATH);
|
||||
ALLEGRO_PATH *data = al_create_path("SuperDerpy.ini");
|
||||
al_join_paths(path, data);
|
||||
config = al_load_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
if (!config) config=al_create_config();
|
||||
game->config.config = al_load_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
if (!game->config.config) game->config.config=al_create_config();
|
||||
al_destroy_path(path);
|
||||
al_destroy_path(data);
|
||||
}
|
||||
|
||||
void SetConfigOption(char* section, char* name, char* value) {
|
||||
al_set_config_value(config, section, name, value);
|
||||
void SetConfigOption(struct Game *game, char* section, char* name, char* value) {
|
||||
al_set_config_value(game->config.config, section, name, value);
|
||||
}
|
||||
|
||||
const char* GetConfigOption(char* section, char* name) {
|
||||
return al_get_config_value(config, section, name);
|
||||
const char* GetConfigOption(struct Game *game, char* section, char* name) {
|
||||
return al_get_config_value(game->config.config, section, name);
|
||||
}
|
||||
|
||||
const char* GetConfigOptionDefault(char* section, char* name, const char* def) {
|
||||
const char* ret = GetConfigOption(section, name);
|
||||
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;
|
||||
}
|
||||
|
||||
void DeinitConfig(void) {
|
||||
void DeinitConfig(struct Game *game) {
|
||||
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), config);
|
||||
al_save_config_file(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), game->config.config);
|
||||
al_destroy_path(path);
|
||||
al_destroy_path(data);
|
||||
al_destroy_config(config);
|
||||
al_destroy_config(game->config.config);
|
||||
}
|
||||
|
|
13
src/config.h
13
src/config.h
|
@ -18,13 +18,16 @@
|
|||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "main.h"
|
||||
|
||||
/*! \brief Reads config from file into memory. */
|
||||
void InitConfig(void);
|
||||
void InitConfig(struct Game *game);
|
||||
/*! \brief Returns value of requested config entry. */
|
||||
const char* GetConfigOption(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(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(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(void);
|
||||
void DeinitConfig(struct Game *game);
|
||||
|
|
53
src/gamestate.c
Normal file
53
src/gamestate.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*! \file allegro_utils.c
|
||||
* \brief Helper functions for Allegro.
|
||||
*/
|
||||
/*
|
||||
* 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 "utils.h"
|
||||
|
||||
void LoadGamestate(struct Game *game, const char* name) {
|
||||
PrintConsole(game, "load finished %s", name);
|
||||
}
|
||||
|
||||
void UnloadGamestate(struct Game *game, const char* name) {
|
||||
PrintConsole(game, "unload finished %s", name);
|
||||
}
|
||||
|
||||
void StartGamestate(struct Game *game, const char* name) {
|
||||
PrintConsole(game, "start finished %s", name);
|
||||
}
|
||||
|
||||
void StopGamestate(struct Game *game, const char* name) {
|
||||
PrintConsole(game, "stop finished %s", name);
|
||||
}
|
||||
|
||||
void PauseGamestate(struct Game *game, const char* name) {
|
||||
PrintConsole(game, "pause finished %s", name);
|
||||
}
|
||||
|
||||
void ResumeGamestate(struct Game *game, const char* name) {
|
||||
PrintConsole(game, "resume finished %s", name);
|
||||
}
|
||||
|
||||
void SwitchGamestate(struct Game *game, const char* current, const char* n) {
|
||||
StopGamestate(game, current);
|
||||
UnloadGamestate(game, current);
|
||||
LoadGamestate(game, n);
|
||||
StartGamestate(game, n);
|
||||
}
|
42
src/gamestate.h
Normal file
42
src/gamestate.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*! \file allegro_utils.h
|
||||
* \brief Headers of helper functions for Allegro.
|
||||
*/
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
struct Game;
|
||||
|
||||
struct Gamestate {
|
||||
char* name;
|
||||
void* handle;
|
||||
bool loaded, pending_load;
|
||||
bool started, pending_start;
|
||||
bool paused;
|
||||
bool fade;
|
||||
unsigned char fade_counter;
|
||||
char** after;
|
||||
struct Gamestate* next;
|
||||
};
|
||||
|
||||
void LoadGamestate(struct Game *game, const char* name);
|
||||
void UnloadGamestate(struct Game *game, const char* name);
|
||||
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 SwitchGamestate(struct Game *game, const char* current, const char* n);
|
|
@ -19,6 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include "../allegro_utils.h"
|
||||
#include "loading.h"
|
||||
|
||||
void Progress(struct Game *game, float p) {
|
||||
|
@ -49,7 +50,7 @@ void Loading_Draw(struct Game *game) {
|
|||
|
||||
al_stop_timer(game->timer);
|
||||
|
||||
PreloadGameState(game, &Progress);
|
||||
LoadGamestate(game, "");
|
||||
|
||||
al_wait_for_vsync();
|
||||
al_start_timer(game->timer);
|
||||
|
@ -73,7 +74,7 @@ void Loading_Draw(struct Game *game) {
|
|||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
DrawConsole(game);
|
||||
al_flip_display();
|
||||
LoadGameState(game);
|
||||
StartGamestate(game, "");
|
||||
}
|
||||
|
||||
void Loading_Load(struct Game *game) {
|
||||
|
|
|
@ -20,6 +20,57 @@
|
|||
*/
|
||||
#include "../main.h"
|
||||
|
||||
/*! \brief Enum of menu states in Menu and Pause game states. */
|
||||
enum menustate_enum {
|
||||
MENUSTATE_MAIN,
|
||||
MENUSTATE_OPTIONS,
|
||||
MENUSTATE_CONTROLS,
|
||||
MENUSTATE_VIDEO,
|
||||
MENUSTATE_PAUSE,
|
||||
MENUSTATE_AUDIO
|
||||
};
|
||||
|
||||
/*! \brief Resources used by Menu state. */
|
||||
struct Menu {
|
||||
ALLEGRO_BITMAP *image; /*!< Bitmap with lower portion of menu landscape. */
|
||||
ALLEGRO_BITMAP *cloud; /*!< Bitmap with bigger cloud. */
|
||||
ALLEGRO_BITMAP *cloud2; /*!< Bitmap with small cloud. */
|
||||
ALLEGRO_BITMAP *pie; /*!< Unscaled bitmap with pie. */
|
||||
ALLEGRO_BITMAP *pie_bitmap; /*!< Scaled and "rendered" bitmap with pies. */
|
||||
ALLEGRO_BITMAP *pinkcloud_bitmap; /*!< Scaled bitmap with pinkcloud and home. */
|
||||
ALLEGRO_BITMAP *pinkcloud; /*!< Unscaled bitmap with pinkcloud and home. */
|
||||
ALLEGRO_BITMAP *rain; /*!< Unscaled bitmap with rain drop. */
|
||||
ALLEGRO_BITMAP *rain_bitmap; /*!< Scaled and "rendered" bitmap with rain drops. */
|
||||
ALLEGRO_BITMAP *mountain; /*!< Flashing mountain in background bitmap. */
|
||||
ALLEGRO_BITMAP *logo; /*!< Logo displayed in the background. */
|
||||
ALLEGRO_BITMAP *logoblur; /*!< Prerendered blurred logo. */
|
||||
ALLEGRO_BITMAP *glass; /*!< Texture used for glass effect in the logo. */
|
||||
ALLEGRO_BITMAP *blurbg; /*!< Temporary bitmap used for blur effect in glass logo. */
|
||||
ALLEGRO_BITMAP *blurbg2; /*!< Temporary bitmap used for blur effect in glass logo. */
|
||||
float cloud_position; /*!< Position of bigger cloud. */
|
||||
float cloud2_position; /*!< Position of small cloud. */
|
||||
int mountain_position; /*!< Position of flashing mountain. */
|
||||
ALLEGRO_SAMPLE *sample; /*!< Background music sample. */
|
||||
ALLEGRO_SAMPLE *rain_sample; /*!< Rain sound sample. */
|
||||
ALLEGRO_SAMPLE *click_sample; /*!< Click sound sample. */
|
||||
ALLEGRO_SAMPLE_INSTANCE *music; /*!< Sample instance with background music. */
|
||||
ALLEGRO_SAMPLE_INSTANCE *rain_sound; /*!< Sample instance with rain sound. */
|
||||
ALLEGRO_SAMPLE_INSTANCE *click; /*!< Sample instance with click sound. */
|
||||
ALLEGRO_FONT *font_title; /*!< Font of "Super Derpy" text. */
|
||||
ALLEGRO_FONT *font_subtitle; /*!< Font of "Muffin Attack" text. */
|
||||
ALLEGRO_FONT *font; /*!< Font of standard menu item. */
|
||||
ALLEGRO_FONT *font_selected; /*!< Font of selected menu item. */
|
||||
int selected; /*!< Number of selected menu item. */
|
||||
enum menustate_enum menustate; /*!< Current menu page. */
|
||||
bool loaded; /*!< True if Menu state has been already loaded. */
|
||||
struct {
|
||||
bool fullscreen;
|
||||
int fps;
|
||||
int width;
|
||||
int height;
|
||||
} options; /*!< Options which can be changed in menu. */
|
||||
};
|
||||
|
||||
void DrawMenuState(struct Game *game);
|
||||
void Menu_Draw(struct Game *game);
|
||||
void Menu_Logic(struct Game *game);
|
||||
|
|
557
src/main.c
557
src/main.c
|
@ -27,382 +27,89 @@
|
|||
#include <getopt.h>
|
||||
#include <locale.h>
|
||||
#include <signal.h>
|
||||
#include "gamestates/menu.h"
|
||||
#include "gamestates/loading.h"
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "main.h"
|
||||
|
||||
/*! \brief Macro for preloading gamestate.
|
||||
*
|
||||
* Preloading of state happens when loading screen is displayed.
|
||||
*/
|
||||
#define PRELOAD_STATE(state, name) case state:\
|
||||
PrintConsole(game, "Preload %s...", #state); DrawConsole(game); al_flip_display(); name ## _Preload(game, progress); break;
|
||||
/*! \brief Macro for unloading gamestate.
|
||||
*
|
||||
* Unloading of state happens after it's fadeout.
|
||||
*/
|
||||
#define UNLOAD_STATE(state, name) case state:\
|
||||
PrintConsole(game, "Unload %s...", #state); name ## _Unload(game); break;
|
||||
/*! \brief Macro for loading gamestate.
|
||||
*
|
||||
* Loading of state means setting it as active and running it.
|
||||
*/
|
||||
#define LOAD_STATE(state, name) case state:\
|
||||
PrintConsole(game, "Load %s...", #state); name ## _Load(game); break;
|
||||
/*! \brief Macro for sending keydown events to gamestate. */
|
||||
#define KEYDOWN_STATE(state, name) else if (game.gamestate==state) { if (name ## _Keydown(&game, &ev)) break; }
|
||||
/*! \brief Macro for drawing active gamestate. */
|
||||
#define DRAW_STATE(state, name) case state:\
|
||||
name ## _Draw(game); break;
|
||||
/*! \brief Macro for invoking logic function of active gamestate. */
|
||||
#define LOGIC_STATE(state, name) case state:\
|
||||
name ## _Logic(game); break;
|
||||
/*! \brief Macro for invoking pause function of active gamestate. */
|
||||
#define PAUSE_STATE(state, name) case state:\
|
||||
PrintConsole(game, "Pause %s...", #state); name ## _Pause(game); break;
|
||||
/*! \brief Macro for invoking resume function of active gamestate. */
|
||||
#define RESUME_STATE(state, name) case state:\
|
||||
PrintConsole(game, "Resume %s...", #state); name ## _Resume(game); break;
|
||||
|
||||
char* GetDataFilePath(char* filename) {
|
||||
|
||||
char *result = 0;
|
||||
|
||||
if (al_filename_exists(filename)) {
|
||||
return strdup(filename);
|
||||
}
|
||||
|
||||
char origfn[255] = "data/";
|
||||
strcat(origfn, filename);
|
||||
|
||||
if (al_filename_exists(origfn)) {
|
||||
return strdup(origfn);
|
||||
}
|
||||
|
||||
void TestPath(char* subpath) {
|
||||
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));
|
||||
if (al_filename_exists(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP))) {
|
||||
result = strdup(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
}
|
||||
al_destroy_path(tail);
|
||||
al_destroy_path(data);
|
||||
al_destroy_path(path);
|
||||
}
|
||||
TestPath("../share/superderpy/data/");
|
||||
TestPath("../data/");
|
||||
TestPath("../Resources/data/");
|
||||
TestPath("data/");
|
||||
|
||||
if (!result) {
|
||||
printf("FATAL: Could not find data file: %s!\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void PrintConsole(struct Game *game, char* format, ...) {
|
||||
va_list vl;
|
||||
va_start(vl, format);
|
||||
char text[255] = {};
|
||||
vsprintf(text, format, vl);
|
||||
va_end(vl);
|
||||
if (game->debug) { printf("%s\n", text); fflush(stdout); }
|
||||
ALLEGRO_BITMAP *con = al_create_bitmap(al_get_bitmap_width(game->console), al_get_bitmap_height(game->console));
|
||||
al_set_target_bitmap(con);
|
||||
al_clear_to_color(al_map_rgba(0,0,0,80));
|
||||
al_draw_bitmap_region(game->console, 0, al_get_bitmap_height(game->console)*0.2, al_get_bitmap_width(game->console), al_get_bitmap_height(game->console)*0.8, 0, 0, 0);
|
||||
al_draw_text(game->font_console, al_map_rgb(255,255,255), game->viewportWidth*0.005, al_get_bitmap_height(game->console)*0.81, ALLEGRO_ALIGN_LEFT, text);
|
||||
al_set_target_bitmap(game->console);
|
||||
al_clear_to_color(al_map_rgba(0,0,0,0));
|
||||
al_draw_bitmap(con, 0, 0, 0);
|
||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||
al_destroy_bitmap(con);
|
||||
}
|
||||
|
||||
void DrawConsole(struct Game *game) {
|
||||
if (game->showconsole) {
|
||||
al_draw_bitmap(game->console, 0, 0, 0);
|
||||
if (game->_priv.showconsole) {
|
||||
al_draw_bitmap(game->_priv.console, 0, 0, 0);
|
||||
double game_time = al_get_time();
|
||||
if(game_time - game->fps_count.old_time >= 1.0) {
|
||||
game->fps_count.fps = game->fps_count.frames_done / (game_time - game->fps_count.old_time);
|
||||
game->fps_count.frames_done = 0;
|
||||
game->fps_count.old_time = game_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] = { };
|
||||
sprintf(sfps, "%.0f", game->fps_count.fps);
|
||||
al_draw_text_with_shadow(game->font, al_map_rgb(255,255,255), game->viewportWidth*0.99, 0, ALLEGRO_ALIGN_RIGHT, sfps);
|
||||
sprintf(sfps, "%.0f", game->_priv.fps_count.fps);
|
||||
DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), game->viewport.width*0.99, 0, ALLEGRO_ALIGN_RIGHT, sfps);
|
||||
}
|
||||
game->fps_count.frames_done++;
|
||||
game->_priv.fps_count.frames_done++;
|
||||
}
|
||||
|
||||
void PreloadGameState(struct Game *game, void (*progress)(struct Game*, float)) {
|
||||
if (game->loadstate<1) {
|
||||
PrintConsole(game, "ERROR: Attempted to preload invalid gamestate %d! Loading GAMESTATE_MENU instead...", game->loadstate);
|
||||
game->loadstate = GAMESTATE_MENU;
|
||||
}
|
||||
if ((game->loadstate==GAMESTATE_MENU) && (game->menu.loaded)) {
|
||||
PrintConsole(game, "GAMESTATE_MENU already loaded, skipping...");
|
||||
return;
|
||||
}
|
||||
switch (game->loadstate) {
|
||||
PRELOAD_STATE(GAMESTATE_MENU, Menu)
|
||||
PRELOAD_STATE(GAMESTATE_LOADING, Loading)
|
||||
default:
|
||||
PrintConsole(game, "ERROR: Attempted to preload unknown gamestate %d!", game->loadstate);
|
||||
break;
|
||||
}
|
||||
PrintConsole(game, "finished");
|
||||
}
|
||||
|
||||
void UnloadGameState(struct Game *game) {
|
||||
switch (game->gamestate) {
|
||||
case GAMESTATE_MENU:
|
||||
if (game->shuttingdown) {
|
||||
PrintConsole(game, "Unload GAMESTATE_MENU..."); Menu_Unload(game);
|
||||
} else {
|
||||
PrintConsole(game, "Just stopping GAMESTATE_MENU..."); Menu_Stop(game);
|
||||
}
|
||||
break;
|
||||
UNLOAD_STATE(GAMESTATE_LOADING, Loading)
|
||||
default:
|
||||
PrintConsole(game, "ERROR: Attempted to unload unknown gamestate %d!", game->gamestate);
|
||||
break;
|
||||
}
|
||||
PrintConsole(game, "finished");
|
||||
}
|
||||
|
||||
void LoadGameState(struct Game *game) {
|
||||
game->gamestate = game->loadstate;
|
||||
game->loadstate = -1;
|
||||
switch (game->gamestate) {
|
||||
LOAD_STATE(GAMESTATE_MENU, Menu)
|
||||
LOAD_STATE(GAMESTATE_LOADING, Loading)
|
||||
default:
|
||||
PrintConsole(game, "ERROR: Attempted to load unknown gamestate %d!", game->loadstate);
|
||||
}
|
||||
PrintConsole(game, "finished");
|
||||
}
|
||||
|
||||
void DrawGameState(struct Game *game) {
|
||||
switch (game->gamestate) {
|
||||
DRAW_STATE(GAMESTATE_MENU, Menu)
|
||||
DRAW_STATE(GAMESTATE_LOADING, Loading)
|
||||
default:
|
||||
game->showconsole = true;
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
PrintConsole(game, "ERROR: Unknown gamestate %d reached! (5 sec sleep)", game->gamestate);
|
||||
DrawConsole(game);
|
||||
al_flip_display();
|
||||
al_rest(5.0);
|
||||
PrintConsole(game, "Returning to menu...");
|
||||
game->gamestate = GAMESTATE_LOADING;
|
||||
game->loadstate = GAMESTATE_MENU;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LogicGameState(struct Game *game) {
|
||||
switch (game->gamestate) {
|
||||
LOGIC_STATE(GAMESTATE_MENU, Menu)
|
||||
default:
|
||||
// not every gamestate needs to have logic function
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void PauseGameState(struct Game *game) {
|
||||
switch (game->loadstate) {
|
||||
// PAUSE_STATE(GAMESTATE_LEVEL, Level)
|
||||
default:
|
||||
// not every gamestate needs to have pause function
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ResumeGameState(struct Game *game) {
|
||||
switch (game->loadstate) {
|
||||
// RESUME_STATE(GAMESTATE_LEVEL, Level)
|
||||
default:
|
||||
// not every gamestate needs to have resume function
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void FadeGameState(struct Game *game, bool in) {
|
||||
ALLEGRO_BITMAP* bitmap = al_create_bitmap(game->viewportWidth, game->viewportHeight);
|
||||
al_set_target_bitmap(bitmap);
|
||||
void DrawGamestates(struct Game *game) {
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||
float fadeloop;
|
||||
if (in) {
|
||||
fadeloop = 255;
|
||||
} else {
|
||||
fadeloop = 0;
|
||||
}
|
||||
while ((in && fadeloop>=0) || (!in && fadeloop<255)) {
|
||||
ALLEGRO_EVENT ev;
|
||||
al_wait_for_event(game->event_queue, &ev);
|
||||
if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game->timer)) {
|
||||
LogicGameState(game);
|
||||
if (in) {
|
||||
fadeloop-=10;
|
||||
} else {
|
||||
fadeloop+=10;
|
||||
}
|
||||
}
|
||||
if (al_is_event_queue_empty(game->event_queue)) {
|
||||
DrawGameState(game);
|
||||
al_draw_tinted_bitmap(bitmap,al_map_rgba_f(1,1,1,fadeloop/255.0),0,0,0);
|
||||
DrawConsole(game);
|
||||
al_flip_display();
|
||||
}
|
||||
}
|
||||
al_destroy_bitmap(bitmap);
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
if (in) {
|
||||
DrawGameState(game);
|
||||
}
|
||||
}
|
||||
|
||||
/*! \brief Scales bitmap using software linear filtering method to current target. */
|
||||
void ScaleBitmap(ALLEGRO_BITMAP* source, int width, int height) {
|
||||
if ((al_get_bitmap_width(source)==width) && (al_get_bitmap_height(source)==height)) {
|
||||
al_draw_bitmap(source, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
int x, y;
|
||||
al_lock_bitmap(al_get_target_bitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
|
||||
al_lock_bitmap(source, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);
|
||||
|
||||
/* linear filtering code written by SiegeLord */
|
||||
|
||||
ALLEGRO_COLOR interpolate(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));
|
||||
}
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
float pixy = ((float)y / height) * ((float)al_get_bitmap_height(source) - 1);
|
||||
float pixy_f = floor(pixy);
|
||||
for (x = 0; x < width; x++) {
|
||||
float pixx = ((float)x / width) * ((float)al_get_bitmap_width(source) - 1);
|
||||
float pixx_f = floor(pixx);
|
||||
|
||||
ALLEGRO_COLOR a = al_get_pixel(source, pixx_f, pixy_f);
|
||||
ALLEGRO_COLOR b = al_get_pixel(source, pixx_f + 1, pixy_f);
|
||||
ALLEGRO_COLOR c = al_get_pixel(source, pixx_f, pixy_f + 1);
|
||||
ALLEGRO_COLOR d = al_get_pixel(source, pixx_f + 1, pixy_f + 1);
|
||||
|
||||
ALLEGRO_COLOR ab = interpolate(a, b, pixx - pixx_f);
|
||||
ALLEGRO_COLOR cd = interpolate(c, d, pixx - pixx_f);
|
||||
ALLEGRO_COLOR result = interpolate(ab, cd, pixy - pixy_f);
|
||||
|
||||
al_put_pixel(x, y, result);
|
||||
}
|
||||
}
|
||||
al_unlock_bitmap(al_get_target_bitmap());
|
||||
al_unlock_bitmap(source);
|
||||
void LogicGamestates(struct Game *game) {
|
||||
return;
|
||||
}
|
||||
|
||||
ALLEGRO_BITMAP* LoadScaledBitmap(char* filename, int width, int height) {
|
||||
bool memoryscale = !atoi(GetConfigOptionDefault("SuperDerpy", "GPU_scaling", "1"));
|
||||
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));
|
||||
char* origfn = GetDataFilePath(filename);
|
||||
void GenerateBitmap() {
|
||||
if (memoryscale) al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
|
||||
|
||||
source = al_load_bitmap( origfn );
|
||||
if (memoryscale) {
|
||||
al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
||||
ScaleBitmap(source, width, height);
|
||||
}
|
||||
else {
|
||||
al_draw_scaled_bitmap(source, 0, 0, al_get_bitmap_width(source), al_get_bitmap_height(source), 0, 0, width, height, 0);
|
||||
}
|
||||
/*al_save_bitmap(cachefn, target);
|
||||
PrintConsole(game, "Cache bitmap %s generated.", filename);*/
|
||||
al_destroy_bitmap(source);
|
||||
}
|
||||
|
||||
/*source = al_load_bitmap( cachefn );
|
||||
if (source) {
|
||||
if ((al_get_bitmap_width(source)!=width) || (al_get_bitmap_height(source)!=height)) {
|
||||
al_destroy_bitmap(source);*/
|
||||
GenerateBitmap();
|
||||
free(origfn);
|
||||
return target;
|
||||
/* }
|
||||
return source;
|
||||
} else GenerateBitmap();
|
||||
return target;*/
|
||||
}
|
||||
|
||||
|
||||
void SetupViewport(struct Game *game) {
|
||||
game->viewportWidth = al_get_display_width(game->display);
|
||||
game->viewportHeight = al_get_display_height(game->display);
|
||||
if (atoi(GetConfigOptionDefault("SuperDerpy", "letterbox", "0"))) {
|
||||
game->viewport.width = al_get_display_width(game->display);
|
||||
game->viewport.height = al_get_display_height(game->display);
|
||||
if (atoi(GetConfigOptionDefault(game, "SuperDerpy", "letterbox", "0"))) {
|
||||
float const aspectRatio = (float)1920 / (float)1080; // full HD
|
||||
int clipWidth = game->viewportWidth, clipHeight = game->viewportWidth / aspectRatio;
|
||||
int clipX = 0, clipY = (game->viewportHeight - clipHeight) / 2;
|
||||
int clipWidth = game->viewport.width, clipHeight = game->viewport.width / aspectRatio;
|
||||
int clipX = 0, clipY = (game->viewport.height - clipHeight) / 2;
|
||||
if (clipY <= 0) {
|
||||
clipHeight = game->viewportHeight;
|
||||
clipWidth = game->viewportHeight * aspectRatio;
|
||||
clipX = (game->viewportWidth - clipWidth) / 2;
|
||||
clipHeight = game->viewport.height;
|
||||
clipWidth = game->viewport.height * aspectRatio;
|
||||
clipX = (game->viewport.width - clipWidth) / 2;
|
||||
clipY = 0;
|
||||
}
|
||||
al_set_clipping_rectangle(clipX, clipY, clipWidth, clipHeight);
|
||||
|
||||
/*float scaleX = (float)clipWidth / (float)800,
|
||||
scaleY = (float)clipHeight / (float)450;*/
|
||||
ALLEGRO_TRANSFORM projection;
|
||||
al_build_transform(&projection, clipX, clipY, 1, 1, 0.0f);
|
||||
al_use_transform(&projection);
|
||||
game->viewportWidth = clipWidth;
|
||||
game->viewportHeight = clipHeight;
|
||||
} else if ((atoi(GetConfigOptionDefault("SuperDerpy", "rotate", "1"))) && (game->viewportHeight > game->viewportWidth)) {
|
||||
game->viewport.width = clipWidth;
|
||||
game->viewport.height = clipHeight;
|
||||
} else if ((atoi(GetConfigOptionDefault(game, "SuperDerpy", "rotate", "1"))) && (game->viewport.height > game->viewport.width)) {
|
||||
ALLEGRO_TRANSFORM projection;
|
||||
al_identity_transform(&projection);
|
||||
al_rotate_transform(&projection, 0.5*ALLEGRO_PI);
|
||||
al_translate_transform(&projection, game->viewportWidth, 0);
|
||||
al_translate_transform(&projection, game->viewport.width, 0);
|
||||
al_use_transform(&projection);
|
||||
int temp = game->viewportHeight;
|
||||
game->viewportHeight = game->viewportWidth;
|
||||
game->viewportWidth = temp;
|
||||
int temp = game->viewport.height;
|
||||
game->viewport.height = game->viewport.width;
|
||||
game->viewport.width = temp;
|
||||
}
|
||||
}
|
||||
|
||||
int Shared_Load(struct Game *game) {
|
||||
game->font = al_load_ttf_font(GetDataFilePath("fonts/ShadowsIntoLight.ttf"),game->viewportHeight*0.09,0 );
|
||||
if(!game->font) {
|
||||
int Console_Load(struct Game *game) {
|
||||
game->_priv.font = al_load_ttf_font(GetDataFilePath("fonts/ShadowsIntoLight.ttf"),game->viewport.height*0.09,0 );
|
||||
if(!game->_priv.font) {
|
||||
fprintf(stderr, "failed to load game font!\n");
|
||||
return -1;
|
||||
}
|
||||
game->font_console = al_load_ttf_font(GetDataFilePath("fonts/DejaVuSansMono.ttf"),game->viewportHeight*0.018,0 );
|
||||
if(!game->font_console) {
|
||||
game->_priv.font_console = al_load_ttf_font(GetDataFilePath("fonts/DejaVuSansMono.ttf"),game->viewport.height*0.018,0 );
|
||||
if(!game->_priv.font_console) {
|
||||
fprintf(stderr, "failed to load console font!\n");
|
||||
return -1;
|
||||
}
|
||||
game->console = al_create_bitmap(game->viewportWidth, game->viewportHeight*0.12);
|
||||
al_set_target_bitmap(game->console);
|
||||
game->_priv.console = al_create_bitmap(game->viewport.width, game->viewport.height*0.12);
|
||||
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));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Shared_Unload(struct Game *game) {
|
||||
al_destroy_font(game->font);
|
||||
al_destroy_font(game->font_console);
|
||||
al_destroy_bitmap(game->console);
|
||||
void Console_Unload(struct Game *game) {
|
||||
al_destroy_font(game->_priv.font);
|
||||
al_destroy_font(game->_priv.font_console);
|
||||
al_destroy_bitmap(game->_priv.console);
|
||||
}
|
||||
|
||||
void derp(int sig) {
|
||||
|
@ -424,23 +131,23 @@ int main(int argc, char **argv){
|
|||
return -1;
|
||||
}
|
||||
|
||||
InitConfig();
|
||||
|
||||
struct Game game;
|
||||
|
||||
game.fps_count.frames_done = 0;
|
||||
game.fps_count.fps = 0;
|
||||
game.fps_count.old_time = 0;
|
||||
InitConfig(&game);
|
||||
|
||||
game.fullscreen = atoi(GetConfigOptionDefault("SuperDerpy", "fullscreen", "1"));
|
||||
game.music = atoi(GetConfigOptionDefault("SuperDerpy", "music", "7"));
|
||||
game.voice = atoi(GetConfigOptionDefault("SuperDerpy", "voice", "10"));
|
||||
game.fx = atoi(GetConfigOptionDefault("SuperDerpy", "fx", "10"));
|
||||
game.debug = atoi(GetConfigOptionDefault("SuperDerpy", "debug", "0"));
|
||||
game.width = atoi(GetConfigOptionDefault("SuperDerpy", "width", "800"));
|
||||
if (game.width<320) game.width=320;
|
||||
game.height = atoi(GetConfigOptionDefault("SuperDerpy", "height", "450"));
|
||||
if (game.height<200) game.height=180;
|
||||
game._priv.fps_count.frames_done = 0;
|
||||
game._priv.fps_count.fps = 0;
|
||||
game._priv.fps_count.old_time = 0;
|
||||
|
||||
game.config.fullscreen = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fullscreen", "1"));
|
||||
game.config.music = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "music", "7"));
|
||||
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", "800"));
|
||||
if (game.config.width<320) game.config.width=320;
|
||||
game.config.height = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "height", "450"));
|
||||
if (game.config.height<180) game.config.height=180;
|
||||
|
||||
if(!al_init_image_addon()) {
|
||||
fprintf(stderr, "failed to initialize image addon!\n");
|
||||
|
@ -469,11 +176,6 @@ int main(int argc, char **argv){
|
|||
return -1;
|
||||
}
|
||||
|
||||
/* if (!al_reserve_samples(10)){
|
||||
fprintf(stderr, "failed to reserve samples!\n");
|
||||
return -1;
|
||||
}
|
||||
*/
|
||||
al_init_font_addon();
|
||||
|
||||
if(!al_init_ttf_addon()){
|
||||
|
@ -481,37 +183,38 @@ int main(int argc, char **argv){
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (game.fullscreen) al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW);
|
||||
if (game.config.fullscreen) al_set_new_display_flags(ALLEGRO_FULLSCREEN_WINDOW);
|
||||
else al_set_new_display_flags(ALLEGRO_WINDOWED);
|
||||
al_set_new_display_option(ALLEGRO_VSYNC, 2-atoi(GetConfigOptionDefault("SuperDerpy", "vsync", "1")), ALLEGRO_SUGGEST);
|
||||
al_set_new_display_option(ALLEGRO_OPENGL, atoi(GetConfigOptionDefault("SuperDerpy", "opengl", "1")), ALLEGRO_SUGGEST);
|
||||
al_set_new_display_option(ALLEGRO_VSYNC, 2-atoi(GetConfigOptionDefault(&game, "SuperDerpy", "vsync", "1")), ALLEGRO_SUGGEST);
|
||||
al_set_new_display_option(ALLEGRO_OPENGL, atoi(GetConfigOptionDefault(&game, "SuperDerpy", "opengl", "1")), ALLEGRO_SUGGEST);
|
||||
al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
|
||||
al_set_new_display_option(ALLEGRO_SAMPLES, 8, ALLEGRO_SUGGEST);
|
||||
|
||||
game.display = al_create_display(game.width, game.height);
|
||||
game.display = al_create_display(game.config.width, game.config.height);
|
||||
if(!game.display) {
|
||||
fprintf(stderr, "failed to create display!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath("icons/superderpy.png"));
|
||||
al_set_window_title(game.display, "Super Derpy: Muffin Attack");
|
||||
al_set_display_icon(game.display, icon);
|
||||
al_destroy_bitmap(icon);
|
||||
|
||||
if (game.fullscreen) al_hide_mouse_cursor(game.display);
|
||||
if (game.config.fullscreen) al_hide_mouse_cursor(game.display);
|
||||
al_inhibit_screensaver(true);
|
||||
|
||||
SetupViewport(&game);
|
||||
|
||||
al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR | ALLEGRO_MIN_LINEAR);
|
||||
|
||||
int ret = Shared_Load(&game);
|
||||
int ret = Console_Load(&game);
|
||||
if (ret!=0) return ret;
|
||||
|
||||
PrintConsole(&game, "Viewport %dx%d", game.viewportWidth, game.viewportHeight);
|
||||
PrintConsole(&game, "Viewport %dx%d", game.viewport.width, game.viewport.height);
|
||||
|
||||
game.event_queue = al_create_event_queue();
|
||||
if(!game.event_queue) {
|
||||
game._priv.event_queue = al_create_event_queue();
|
||||
if(!game._priv.event_queue) {
|
||||
fprintf(stderr, "failed to create event_queue!\n");
|
||||
al_destroy_display(game.display);
|
||||
return -1;
|
||||
|
@ -526,58 +229,66 @@ int main(int argc, char **argv){
|
|||
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.fx/10.0);
|
||||
al_set_mixer_gain(game.audio.music, game.music/10.0);
|
||||
al_set_mixer_gain(game.audio.voice, game.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);
|
||||
|
||||
al_register_event_source(game.event_queue, al_get_display_event_source(game.display));
|
||||
al_register_event_source(game.event_queue, al_get_keyboard_event_source());
|
||||
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_keyboard_event_source());
|
||||
|
||||
game.showconsole = game.debug;
|
||||
game._priv.showconsole = game.config.debug;
|
||||
|
||||
al_flip_display();
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
game.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer
|
||||
if(!game.timer) {
|
||||
game._priv.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer
|
||||
if(!game._priv.timer) {
|
||||
fprintf(stderr, "failed to create timer!\n");
|
||||
return -1;
|
||||
}
|
||||
al_register_event_source(game.event_queue, al_get_timer_event_source(game.timer));
|
||||
al_register_event_source(game._priv.event_queue, al_get_timer_event_source(game._priv.timer));
|
||||
al_wait_for_vsync();
|
||||
al_start_timer(game.timer);
|
||||
al_start_timer(game._priv.timer);
|
||||
|
||||
setlocale(LC_NUMERIC, "C"); /* FIXME? */
|
||||
setlocale(LC_NUMERIC, "C");
|
||||
|
||||
game.shuttingdown = false;
|
||||
game.menu.loaded = false;
|
||||
game.restart = false;
|
||||
game.loadstate = GAMESTATE_LOADING;
|
||||
PreloadGameState(&game, NULL);
|
||||
LoadGameState(&game);
|
||||
game.loadstate = GAMESTATE_MENU;
|
||||
|
||||
char* gamestate = strdup("menu"); // FIXME: don't hardcore gamestate
|
||||
|
||||
int c;
|
||||
while ((c = getopt (argc, argv, "l:s:")) != -1)
|
||||
switch (c) {
|
||||
case 'l':
|
||||
//game.level.input.current_level = optarg[0]-'0';
|
||||
game.loadstate = GAMESTATE_LEVEL;
|
||||
free(gamestate);
|
||||
gamestate = strdup("levelX");
|
||||
gamestate[5] = optarg[0];
|
||||
break;
|
||||
case 's':
|
||||
game.loadstate = optarg[0]-'0';
|
||||
free(gamestate);
|
||||
gamestate = strdup(optarg);
|
||||
break;
|
||||
}
|
||||
|
||||
LoadGamestate(&game, gamestate);
|
||||
StartGamestate(&game, gamestate);
|
||||
//free(gamestate);
|
||||
|
||||
while(1) {
|
||||
ALLEGRO_EVENT ev;
|
||||
if (al_is_event_queue_empty(game.event_queue)) {
|
||||
DrawGameState(&game);
|
||||
if (al_is_event_queue_empty(game._priv.event_queue)) {
|
||||
|
||||
// TODO: process gamestates
|
||||
DrawGamestates(&game);
|
||||
DrawConsole(&game);
|
||||
al_flip_display();
|
||||
|
||||
} else {
|
||||
al_wait_for_event(game.event_queue, &ev);
|
||||
if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game.timer)) {
|
||||
LogicGameState(&game);
|
||||
|
||||
al_wait_for_event(game._priv.event_queue, &ev);
|
||||
|
||||
if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game._priv.timer)) {
|
||||
LogicGamestates(&game);
|
||||
}
|
||||
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
||||
break;
|
||||
|
@ -585,34 +296,34 @@ int main(int argc, char **argv){
|
|||
else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
|
||||
/*PrintConsole(&game, "KEYCODE: %s", al_keycode_to_name(ev.keyboard.keycode));*/
|
||||
#ifdef ALLEGRO_MACOSX
|
||||
if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == 104)) {
|
||||
if (ev.keyboard.keycode == 104) { //TODO: report to upstream
|
||||
#else
|
||||
if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_TILDE)) {
|
||||
if (ev.keyboard.keycode == ALLEGRO_KEY_TILDE) {
|
||||
#endif
|
||||
game.showconsole = !game.showconsole;
|
||||
game._priv.showconsole = !game._priv.showconsole;
|
||||
}
|
||||
else if ((game.debug) && (ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) {
|
||||
else if ((game.config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) {
|
||||
int i;
|
||||
for (i=0; i<512; i++) {
|
||||
LogicGameState(&game);
|
||||
LogicGamestates(&game);
|
||||
}
|
||||
game.showconsole = true;
|
||||
game._priv.showconsole = true;
|
||||
PrintConsole(&game, "DEBUG: 512 frames skipped...");
|
||||
} else if ((game.debug) && (ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_F10)) {
|
||||
double speed = ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game.timer)); // inverting
|
||||
} else if ((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;
|
||||
al_set_timer_speed(game.timer, ALLEGRO_BPS_TO_SECS(speed));
|
||||
game.showconsole = true;
|
||||
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 ((game.debug) && (ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_F11)) {
|
||||
double speed = ALLEGRO_BPS_TO_SECS(al_get_timer_speed(game.timer)); // inverting
|
||||
} else if ((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;
|
||||
al_set_timer_speed(game.timer, ALLEGRO_BPS_TO_SECS(speed));
|
||||
game.showconsole = true;
|
||||
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 ((game.debug) && (ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_F12)) {
|
||||
} else if ((game.config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F12)) {
|
||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH);
|
||||
char filename[255] = { };
|
||||
sprintf(filename, "SuperDerpy_%ld_%ld.png", time(NULL), clock());
|
||||
|
@ -620,48 +331,54 @@ int main(int argc, char **argv){
|
|||
al_save_bitmap(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), al_get_backbuffer(game.display));
|
||||
PrintConsole(&game, "Screenshot stored in %s", al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
al_destroy_path(path);
|
||||
} else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
|
||||
break;
|
||||
}
|
||||
KEYDOWN_STATE(GAMESTATE_MENU, Menu)
|
||||
KEYDOWN_STATE(GAMESTATE_LOADING, Loading)
|
||||
else {
|
||||
game.showconsole = true;
|
||||
PrintConsole(&game, "ERROR: Keystroke in unknown (%d) gamestate! (5 sec sleep)", game.gamestate);
|
||||
// TODO: redirect keydown events to gamestates
|
||||
|
||||
//KEYDOWN_STATE(GAMESTATE_MENU, Menu)
|
||||
//KEYDOWN_STATE(GAMESTATE_LOADING, Loading)
|
||||
/*else {
|
||||
game._priv.showconsole = true;
|
||||
//PrintConsole(&game, "ERROR: Keystroke in unknown (%d) gamestate! (5 sec sleep)", game.gamestate);
|
||||
DrawConsole(&game);
|
||||
al_flip_display();
|
||||
al_rest(5.0);
|
||||
PrintConsole(&game, "Returning to menu...");
|
||||
game.gamestate = GAMESTATE_LOADING;
|
||||
game.loadstate = GAMESTATE_MENU;
|
||||
}
|
||||
} else if (game.gamestate == GAMESTATE_LEVEL) {
|
||||
//game.gamestate = GAMESTATE_LOADING;
|
||||
//game.loadstate = GAMESTATE_MENU;
|
||||
}*/
|
||||
//} else if (game.gamestate == GAMESTATE_LEVEL) {
|
||||
//Level_ProcessEvent(&game, &ev);
|
||||
}
|
||||
}
|
||||
}
|
||||
game.shuttingdown = true;
|
||||
UnloadGameState(&game);
|
||||
if (game.gamestate != GAMESTATE_LOADING) {
|
||||
game.gamestate = GAMESTATE_LOADING;
|
||||
UnloadGameState(&game);
|
||||
}
|
||||
|
||||
// FIXME: proper gamestates unload handling
|
||||
StopGamestate(&game, gamestate);
|
||||
UnloadGamestate(&game, gamestate);
|
||||
free(gamestate);
|
||||
// TODO: unload loading
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
PrintConsole(&game, "Shutting down...");
|
||||
DrawConsole(&game);
|
||||
al_flip_display();
|
||||
al_rest(0.1);
|
||||
al_destroy_timer(game.timer);
|
||||
Shared_Unload(&game);
|
||||
al_destroy_timer(game._priv.timer);
|
||||
Console_Unload(&game);
|
||||
al_destroy_display(game.display);
|
||||
al_destroy_event_queue(game.event_queue);
|
||||
al_destroy_event_queue(game._priv.event_queue);
|
||||
al_destroy_mixer(game.audio.fx);
|
||||
al_destroy_mixer(game.audio.music);
|
||||
al_destroy_mixer(game.audio.mixer);
|
||||
al_destroy_voice(game.audio.v);
|
||||
al_uninstall_audio();
|
||||
DeinitConfig();
|
||||
DeinitConfig(&game);
|
||||
al_shutdown_ttf_addon();
|
||||
al_shutdown_font_addon();
|
||||
al_uninstall_system();
|
||||
if (game.restart) {
|
||||
al_shutdown_ttf_addon();
|
||||
al_shutdown_font_addon();
|
||||
#ifdef ALLEGRO_MACOSX
|
||||
return _al_mangled_main(argc, argv);
|
||||
#else
|
||||
|
|
194
src/main.h
194
src/main.h
|
@ -29,112 +29,31 @@
|
|||
#include <allegro5/allegro_image.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include <allegro5/allegro_ttf.h>
|
||||
#include "allegro_utils.h"
|
||||
|
||||
/*! \brief Declares variables used by displaying progress bar on loading screen.
|
||||
* Takes number of loading steps as parameter.
|
||||
*/
|
||||
#define PROGRESS_INIT(a) float load_p = 0, load_a = a;
|
||||
/*! \brief Increments progress of loading. */
|
||||
#define PROGRESS if (progress) (*progress)(game, load_p+=1/load_a);
|
||||
|
||||
struct Game;
|
||||
|
||||
/*! \brief Enum of all available gamestates. */
|
||||
enum gamestate_enum {
|
||||
GAMESTATE_PAUSE,
|
||||
GAMESTATE_LOADING,
|
||||
GAMESTATE_MENU,
|
||||
GAMESTATE_ABOUT,
|
||||
GAMESTATE_INTRO,
|
||||
GAMESTATE_MAP,
|
||||
GAMESTATE_LEVEL,
|
||||
GAMESTATE_DISCLAIMER
|
||||
};
|
||||
|
||||
/*! \brief Enum of menu states in Menu and Pause game states. */
|
||||
enum menustate_enum {
|
||||
MENUSTATE_MAIN,
|
||||
MENUSTATE_OPTIONS,
|
||||
MENUSTATE_CONTROLS,
|
||||
MENUSTATE_VIDEO,
|
||||
MENUSTATE_PAUSE,
|
||||
MENUSTATE_AUDIO
|
||||
};
|
||||
|
||||
/*! \brief Resources used by Menu state. */
|
||||
struct Menu {
|
||||
ALLEGRO_BITMAP *image; /*!< Bitmap with lower portion of menu landscape. */
|
||||
ALLEGRO_BITMAP *cloud; /*!< Bitmap with bigger cloud. */
|
||||
ALLEGRO_BITMAP *cloud2; /*!< Bitmap with small cloud. */
|
||||
ALLEGRO_BITMAP *pie; /*!< Unscaled bitmap with pie. */
|
||||
ALLEGRO_BITMAP *pie_bitmap; /*!< Scaled and "rendered" bitmap with pies. */
|
||||
ALLEGRO_BITMAP *pinkcloud_bitmap; /*!< Scaled bitmap with pinkcloud and home. */
|
||||
ALLEGRO_BITMAP *pinkcloud; /*!< Unscaled bitmap with pinkcloud and home. */
|
||||
ALLEGRO_BITMAP *rain; /*!< Unscaled bitmap with rain drop. */
|
||||
ALLEGRO_BITMAP *rain_bitmap; /*!< Scaled and "rendered" bitmap with rain drops. */
|
||||
ALLEGRO_BITMAP *mountain; /*!< Flashing mountain in background bitmap. */
|
||||
ALLEGRO_BITMAP *logo; /*!< Logo displayed in the background. */
|
||||
ALLEGRO_BITMAP *logoblur; /*!< Prerendered blurred logo. */
|
||||
ALLEGRO_BITMAP *glass; /*!< Texture used for glass effect in the logo. */
|
||||
ALLEGRO_BITMAP *blurbg; /*!< Temporary bitmap used for blur effect in glass logo. */
|
||||
ALLEGRO_BITMAP *blurbg2; /*!< Temporary bitmap used for blur effect in glass logo. */
|
||||
float cloud_position; /*!< Position of bigger cloud. */
|
||||
float cloud2_position; /*!< Position of small cloud. */
|
||||
int mountain_position; /*!< Position of flashing mountain. */
|
||||
ALLEGRO_SAMPLE *sample; /*!< Background music sample. */
|
||||
ALLEGRO_SAMPLE *rain_sample; /*!< Rain sound sample. */
|
||||
ALLEGRO_SAMPLE *click_sample; /*!< Click sound sample. */
|
||||
ALLEGRO_SAMPLE_INSTANCE *music; /*!< Sample instance with background music. */
|
||||
ALLEGRO_SAMPLE_INSTANCE *rain_sound; /*!< Sample instance with rain sound. */
|
||||
ALLEGRO_SAMPLE_INSTANCE *click; /*!< Sample instance with click sound. */
|
||||
ALLEGRO_FONT *font_title; /*!< Font of "Super Derpy" text. */
|
||||
ALLEGRO_FONT *font_subtitle; /*!< Font of "Muffin Attack" text. */
|
||||
ALLEGRO_FONT *font; /*!< Font of standard menu item. */
|
||||
ALLEGRO_FONT *font_selected; /*!< Font of selected menu item. */
|
||||
int selected; /*!< Number of selected menu item. */
|
||||
enum menustate_enum menustate; /*!< Current menu page. */
|
||||
bool loaded; /*!< True if Menu state has been already loaded. */
|
||||
struct {
|
||||
bool fullscreen;
|
||||
int fps;
|
||||
int width;
|
||||
int height;
|
||||
} options; /*!< Options which can be changed in menu. */
|
||||
};
|
||||
|
||||
/*! \brief Resources used by Loading state. */
|
||||
struct Loading {
|
||||
ALLEGRO_BITMAP *loading_bitmap; /*!< Rendered loading bitmap. */
|
||||
ALLEGRO_BITMAP *image; /*!< Loading background. */
|
||||
};
|
||||
#include "gamestate.h"
|
||||
|
||||
struct Gamestate;
|
||||
|
||||
/*! \brief Main struct of the game. */
|
||||
struct Game {
|
||||
ALLEGRO_DISPLAY *display; /*!< Main Allegro display. */
|
||||
ALLEGRO_FONT *font; /*!< Main font used in game. */
|
||||
ALLEGRO_FONT *font_console; /*!< Font used in game console. */
|
||||
enum gamestate_enum gamestate; /*!< Current game state. */
|
||||
enum gamestate_enum loadstate; /*!< Game state to be loaded. */
|
||||
ALLEGRO_EVENT_QUEUE *event_queue; /*!< Main event queue. */
|
||||
ALLEGRO_TIMER *timer; /*!< Main LPS timer. */
|
||||
ALLEGRO_BITMAP *console; /*!< Bitmap with game console. */
|
||||
int viewportWidth; /*!< Actual available width of viewport. */
|
||||
int viewportHeight; /*!< Actual available height of viewport. */
|
||||
bool showconsole; /*!< If true, game console is rendered on screen. */
|
||||
int fx; /*!< Effects volume. */
|
||||
int music; /*!< Music volume. */
|
||||
int voice; /*!< Voice volume. */
|
||||
bool fullscreen; /*!< Fullscreen toggle. */
|
||||
bool debug; /*!< Toggles debug mode. */
|
||||
int fps; /*!< FPS limit */
|
||||
int width; /*!< Width of window as being set in configuration. */
|
||||
int height; /*!< Height of window as being set in configuration. */
|
||||
bool shuttingdown; /*!< If true then shut down of the game is pending. */
|
||||
bool restart; /*!< If true then restart of the game is pending. */
|
||||
struct Menu menu; /*!< Resources used by Menu state. */
|
||||
struct Loading loading; /*!< Resources used by Menu state. */
|
||||
|
||||
struct {
|
||||
int width; /*!< Actual available width of viewport. */
|
||||
int height; /*!< Actual available height of viewport. */
|
||||
} viewport;
|
||||
|
||||
struct {
|
||||
int fx; /*!< Effects volume. */
|
||||
int music; /*!< Music volume. */
|
||||
int voice; /*!< Voice volume. */
|
||||
bool fullscreen; /*!< Fullscreen toggle. */
|
||||
bool debug; /*!< Toggles debug mode. */
|
||||
int fps; /*!< FPS limit */
|
||||
int width; /*!< Width of window as being set in configuration. */
|
||||
int height; /*!< Height of window as being set in configuration. */
|
||||
ALLEGRO_CONFIG *config;
|
||||
} config;
|
||||
|
||||
struct {
|
||||
ALLEGRO_VOICE *v; /*!< Main voice used by the game. */
|
||||
ALLEGRO_MIXER *mixer; /*!< Main mixer of the game. */
|
||||
|
@ -142,60 +61,27 @@ struct Game {
|
|||
ALLEGRO_MIXER *voice; /*!< Voice mixer. */
|
||||
ALLEGRO_MIXER *fx; /*!< Effects mixer. */
|
||||
} audio; /*!< Audio resources. */
|
||||
|
||||
struct {
|
||||
double old_time, fps;
|
||||
int frames_done;
|
||||
} fps_count;
|
||||
struct Gamestate *gamestate; /*!< Current gamestate. */
|
||||
struct Gamestate *gamestate_list; /*!< List of known gamestates. */
|
||||
ALLEGRO_FONT *font; /*!< Main font used in game. */
|
||||
ALLEGRO_FONT *font_console; /*!< Font used in game console. */
|
||||
ALLEGRO_BITMAP *console; /*!< Bitmap with game console. */
|
||||
ALLEGRO_EVENT_QUEUE *event_queue; /*!< Main event queue. */
|
||||
ALLEGRO_TIMER *timer; /*!< Main LPS timer. */
|
||||
bool showconsole; /*!< If true, game console is rendered on screen. */
|
||||
|
||||
struct {
|
||||
double old_time, fps;
|
||||
int frames_done;
|
||||
} fps_count;
|
||||
|
||||
} _priv; /*!< Private resources. Do not use in gamestates! */
|
||||
|
||||
bool shuttingdown; /*!< If true then shut down of the game is pending. */
|
||||
bool restart; /*!< If true then restart of the game is pending. */
|
||||
|
||||
};
|
||||
|
||||
/*! \brief Preloads gamestate set in game->loadstate. */
|
||||
void PreloadGameState(struct Game *game, void (*progress)(struct Game*, float));
|
||||
|
||||
/*! \brief Unloads gamestate set in game->gamestate. */
|
||||
void UnloadGameState(struct Game *game);
|
||||
|
||||
/*! \brief Loads gamestate set in game->loadstate. */
|
||||
void LoadGameState(struct Game *game);
|
||||
|
||||
/*! \brief Pauses gamestate set in game->loadstate. */
|
||||
void PauseGameState(struct Game *game);
|
||||
|
||||
/*! \brief Resumes gamestate set in game->loadstate. */
|
||||
void ResumeGameState(struct Game *game);
|
||||
|
||||
/*! \brief Finds path for data file. */
|
||||
char* GetDataFilePath(char* filename);
|
||||
|
||||
/*! \brief Print some message on game console.
|
||||
*
|
||||
* Draws message on console bitmap, so it'll be displayed when calling DrawConsole.
|
||||
* 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, ...);
|
||||
|
||||
/*! \brief Draws console bitmap on screen. */
|
||||
void DrawConsole(struct Game *game);
|
||||
|
||||
/*! \brief Loads bitmap into memory and scales it with software linear filtering. */
|
||||
ALLEGRO_BITMAP* LoadScaledBitmap(char* filename, int width, int height);
|
||||
|
||||
/*! \brief Draws frame from current gamestate. */
|
||||
void DrawGameState(struct Game *game);
|
||||
|
||||
/*! \brief Processes logic of current gamestate. */
|
||||
void LogicGameState(struct Game *game);
|
||||
|
||||
/*! \brief Displays fade in or fade out animation on current gamestate. */
|
||||
void FadeGameState(struct Game *game, bool in);
|
||||
|
||||
/*! \brief Load shared resources. */
|
||||
int Shared_Load(struct Game *game);
|
||||
|
||||
/*! \brief Unload shared resources. */
|
||||
void Shared_Unload(struct Game *game);
|
||||
|
||||
/*! \brief Setups letterbox viewport if necessary. */
|
||||
void SetupViewport(struct Game *game);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#include <allegro5/allegro.h>
|
||||
#include "main.h"
|
||||
#include "utils.h"
|
||||
#include "timeline.h"
|
||||
|
||||
unsigned int lastid;
|
||||
|
@ -243,7 +243,7 @@ struct TM_Action* TM_AddBackgroundAction(bool (*func)(struct Game*, struct TM_Ac
|
|||
(*action->function)(game, action, TM_ACTIONSTATE_INIT);
|
||||
action->active = false;
|
||||
action->timer = al_create_timer(delay/1000.0);
|
||||
al_register_event_source(game->event_queue, al_get_timer_event_source(action->timer));
|
||||
al_register_event_source(game->_priv.event_queue, al_get_timer_event_source(action->timer));
|
||||
al_start_timer(action->timer);
|
||||
} else {
|
||||
PrintConsole(game, "Timeline Manager: background: init action (%d - %s)", action->id, action->name);
|
||||
|
@ -287,7 +287,7 @@ void TM_AddDelay(int delay) {
|
|||
PrintConsole(game, "Timeline Manager: queue: adding delay %d ms (%d)", delay, tmp->id);
|
||||
tmp->delay = delay;
|
||||
tmp->timer = al_create_timer(delay/1000.0);
|
||||
al_register_event_source(game->event_queue, al_get_timer_event_source(tmp->timer));
|
||||
al_register_event_source(game->_priv.event_queue, al_get_timer_event_source(tmp->timer));
|
||||
}
|
||||
|
||||
void TM_Destroy(void) {
|
||||
|
|
226
src/utils.c
Normal file
226
src/utils.c
Normal file
|
@ -0,0 +1,226 @@
|
|||
/*! \file allegro_utils.c
|
||||
* \brief Helper functions for Allegro.
|
||||
*/
|
||||
/*
|
||||
* 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 "stdio.h"
|
||||
#include "config.h"
|
||||
#include "math.h"
|
||||
#include "utils.h"
|
||||
|
||||
void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom) {
|
||||
ALLEGRO_VERTEX v[] = {
|
||||
{.x = x, .y = y, .z = 0, .color = top},
|
||||
{.x = x + w, .y = y, .z = 0, .color = top},
|
||||
{.x = x, .y = y + h, .z = 0, .color = bottom},
|
||||
{.x = x + w, .y = y + h, .z = 0, .color = bottom}};
|
||||
al_draw_prim(v, NULL, NULL, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
void DrawHorizontalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR left, ALLEGRO_COLOR right) {
|
||||
ALLEGRO_VERTEX v[] = {
|
||||
{.x = x, .y = y, .z = 0, .color = left},
|
||||
{.x = x + w, .y = y, .z = 0, .color = right},
|
||||
{.x = x, .y = y + h, .z = 0, .color = left},
|
||||
{.x = x + w, .y = y + h, .z = 0, .color = right}};
|
||||
al_draw_prim(v, NULL, NULL, 0, 4, ALLEGRO_PRIM_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void FadeGamestate(struct Game *game, bool in) {
|
||||
//TODO: reimplement
|
||||
/* ALLEGRO_BITMAP* bitmap = al_create_bitmap(game->viewportWidth, game->viewportHeight);
|
||||
al_set_target_bitmap(bitmap);
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||
float fadeloop;
|
||||
if (in) {
|
||||
fadeloop = 255;
|
||||
} else {
|
||||
fadeloop = 0;
|
||||
}
|
||||
while ((in && fadeloop>=0) || (!in && fadeloop<255)) {
|
||||
ALLEGRO_EVENT ev;
|
||||
al_wait_for_event(game->event_queue, &ev);
|
||||
if ((ev.type == ALLEGRO_EVENT_TIMER) && (ev.timer.source == game->timer)) {
|
||||
LogicGamestates(game);
|
||||
if (in) {
|
||||
fadeloop-=10;
|
||||
} else {
|
||||
fadeloop+=10;
|
||||
}
|
||||
}
|
||||
if (al_is_event_queue_empty(game->event_queue)) {
|
||||
DrawGamestates(game);
|
||||
al_draw_tinted_bitmap(bitmap,al_map_rgba_f(1,1,1,fadeloop/255.0),0,0,0);
|
||||
DrawConsole(game);
|
||||
al_flip_display();
|
||||
}
|
||||
}
|
||||
al_destroy_bitmap(bitmap);
|
||||
al_clear_to_color(al_map_rgb(0,0,0));
|
||||
if (in) {
|
||||
DrawGamestates(game);
|
||||
}*/
|
||||
}
|
||||
|
||||
/*! \brief Scales bitmap using software linear filtering method to current target. */
|
||||
void ScaleBitmap(ALLEGRO_BITMAP* source, int width, int height) {
|
||||
if ((al_get_bitmap_width(source)==width) && (al_get_bitmap_height(source)==height)) {
|
||||
al_draw_bitmap(source, 0, 0, 0);
|
||||
return;
|
||||
}
|
||||
int x, y;
|
||||
al_lock_bitmap(al_get_target_bitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
|
||||
al_lock_bitmap(source, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_READONLY);
|
||||
|
||||
/* linear filtering code written by SiegeLord */
|
||||
|
||||
ALLEGRO_COLOR interpolate(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));
|
||||
}
|
||||
|
||||
for (y = 0; y < height; y++) {
|
||||
float pixy = ((float)y / height) * ((float)al_get_bitmap_height(source) - 1);
|
||||
float pixy_f = floor(pixy);
|
||||
for (x = 0; x < width; x++) {
|
||||
float pixx = ((float)x / width) * ((float)al_get_bitmap_width(source) - 1);
|
||||
float pixx_f = floor(pixx);
|
||||
|
||||
ALLEGRO_COLOR a = al_get_pixel(source, pixx_f, pixy_f);
|
||||
ALLEGRO_COLOR b = al_get_pixel(source, pixx_f + 1, pixy_f);
|
||||
ALLEGRO_COLOR c = al_get_pixel(source, pixx_f, pixy_f + 1);
|
||||
ALLEGRO_COLOR d = al_get_pixel(source, pixx_f + 1, pixy_f + 1);
|
||||
|
||||
ALLEGRO_COLOR ab = interpolate(a, b, pixx - pixx_f);
|
||||
ALLEGRO_COLOR cd = interpolate(c, d, pixx - pixx_f);
|
||||
ALLEGRO_COLOR result = interpolate(ab, cd, pixy - pixy_f);
|
||||
|
||||
al_put_pixel(x, y, result);
|
||||
}
|
||||
}
|
||||
al_unlock_bitmap(al_get_target_bitmap());
|
||||
al_unlock_bitmap(source);
|
||||
}
|
||||
|
||||
ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, int height) {
|
||||
bool memoryscale = !atoi(GetConfigOptionDefault(game, "SuperDerpy", "GPU_scaling", "1"));
|
||||
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));
|
||||
char* origfn = GetDataFilePath(filename);
|
||||
void GenerateBitmap() {
|
||||
if (memoryscale) al_set_new_bitmap_flags(ALLEGRO_MEMORY_BITMAP);
|
||||
|
||||
source = al_load_bitmap( origfn );
|
||||
if (memoryscale) {
|
||||
al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
||||
ScaleBitmap(source, width, height);
|
||||
}
|
||||
else {
|
||||
al_draw_scaled_bitmap(source, 0, 0, al_get_bitmap_width(source), al_get_bitmap_height(source), 0, 0, width, height, 0);
|
||||
}
|
||||
/*al_save_bitmap(cachefn, target);
|
||||
PrintConsole(game, "Cache bitmap %s generated.", filename);*/
|
||||
al_destroy_bitmap(source);
|
||||
}
|
||||
|
||||
/*source = al_load_bitmap( cachefn );
|
||||
if (source) {
|
||||
if ((al_get_bitmap_width(source)!=width) || (al_get_bitmap_height(source)!=height)) {
|
||||
al_destroy_bitmap(source);*/
|
||||
GenerateBitmap();
|
||||
free(origfn);
|
||||
return target;
|
||||
/* }
|
||||
return source;
|
||||
} else GenerateBitmap();
|
||||
return target;*/
|
||||
}
|
||||
|
||||
|
||||
char* GetDataFilePath(char* filename) {
|
||||
|
||||
//TODO: support for current game
|
||||
|
||||
char *result = 0;
|
||||
|
||||
if (al_filename_exists(filename)) {
|
||||
return strdup(filename);
|
||||
}
|
||||
|
||||
char origfn[255] = "data/";
|
||||
strcat(origfn, filename);
|
||||
|
||||
if (al_filename_exists(origfn)) {
|
||||
return strdup(origfn);
|
||||
}
|
||||
|
||||
void TestPath(char* subpath) {
|
||||
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));
|
||||
if (al_filename_exists(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP))) {
|
||||
result = strdup(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||
}
|
||||
al_destroy_path(tail);
|
||||
al_destroy_path(data);
|
||||
al_destroy_path(path);
|
||||
}
|
||||
TestPath("../share/superderpy/data/");
|
||||
TestPath("../data/");
|
||||
TestPath("../Resources/data/");
|
||||
TestPath("data/");
|
||||
|
||||
if (!result) {
|
||||
printf("FATAL: Could not find data file: %s!\n", filename);
|
||||
exit(1);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void PrintConsole(struct Game *game, char* format, ...) {
|
||||
va_list vl;
|
||||
va_start(vl, format);
|
||||
char text[255] = {};
|
||||
vsprintf(text, format, vl);
|
||||
va_end(vl);
|
||||
if (game->config.debug) { printf("%s\n", text); fflush(stdout); }
|
||||
ALLEGRO_BITMAP *con = al_create_bitmap(al_get_bitmap_width(game->_priv.console), al_get_bitmap_height(game->_priv.console));
|
||||
al_set_target_bitmap(con);
|
||||
al_clear_to_color(al_map_rgba(0,0,0,80));
|
||||
al_draw_bitmap_region(game->_priv.console, 0, al_get_bitmap_height(game->_priv.console)*0.2, al_get_bitmap_width(game->_priv.console), al_get_bitmap_height(game->_priv.console)*0.8, 0, 0, 0);
|
||||
al_draw_text(game->_priv.font_console, al_map_rgb(255,255,255), game->viewport.width*0.005, al_get_bitmap_height(game->_priv.console)*0.81, ALLEGRO_ALIGN_LEFT, text);
|
||||
al_set_target_bitmap(game->_priv.console);
|
||||
al_clear_to_color(al_map_rgba(0,0,0,0));
|
||||
al_draw_bitmap(con, 0, 0, 0);
|
||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||
al_destroy_bitmap(con);
|
||||
}
|
|
@ -21,14 +21,32 @@
|
|||
#include <allegro5/allegro.h>
|
||||
#include <allegro5/allegro_primitives.h>
|
||||
#include <allegro5/allegro_font.h>
|
||||
#include "main.h"
|
||||
|
||||
/*! \brief Draws rectangle filled with vertical gradient. */
|
||||
void al_draw_vertical_gradient_rect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom);
|
||||
void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom);
|
||||
/*! \brief Draws rectangle filled with horizontal gradient. */
|
||||
void al_draw_horizontal_gradient_rect(float x, float y, float w, float h, ALLEGRO_COLOR left, ALLEGRO_COLOR right);
|
||||
void DrawHorizontalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR left, ALLEGRO_COLOR right);
|
||||
/*! \brief Draws text with shadow.
|
||||
*
|
||||
* 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 al_draw_text_with_shadow(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);
|
||||
|
||||
/*! \brief Loads bitmap into memory and scales it with software linear filtering. */
|
||||
ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, int height);
|
||||
|
||||
/*! \brief Displays fade in or fade out animation on current gamestate. */
|
||||
void FadeGameState(struct Game *game, bool in);
|
||||
|
||||
/*! \brief Finds path for data file. */
|
||||
char* GetDataFilePath(char* filename);
|
||||
|
||||
/*! \brief Print some message on game console.
|
||||
*
|
||||
* Draws message on console bitmap, so it'll be displayed when calling DrawConsole.
|
||||
* 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, ...);
|
Loading…
Reference in a new issue