mirror of
https://gitlab.com/dosowisko.net/libsuperderpy.git
synced 2025-03-04 09:11:27 +01:00
import Radio Edit codebase
This commit is contained in:
parent
e92e4b6bec
commit
46827594b4
16 changed files with 1368 additions and 668 deletions
|
@ -69,9 +69,9 @@
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
# use relative install prefix to avoid hardcoded install paths in cmake_install.cmake files
|
# use relative install prefix to avoid hardcoded install paths in cmake_install.cmake files
|
||||||
|
|
||||||
set(LIB_INSTALL_DIR "lib${LIB_SUFFIX}" ) # The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX})
|
set(LIB_INSTALL_DIR "bin" ) # The subdirectory relative to the install prefix where libraries will be installed (default is ${EXEC_INSTALL_PREFIX}/lib${LIB_SUFFIX})
|
||||||
|
|
||||||
set(EXEC_INSTALL_PREFIX "" ) # Base directory for executables and libraries
|
set(EXEC_INSTALL_PREFIX "${EXEC_INSTALL_PREFIX}" ) # Base directory for executables and libraries
|
||||||
set(SHARE_INSTALL_PREFIX "share" ) # Base directory for files which go to share/
|
set(SHARE_INSTALL_PREFIX "share" ) # Base directory for files which go to share/
|
||||||
set(BIN_INSTALL_DIR "bin" ) # The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin)
|
set(BIN_INSTALL_DIR "bin" ) # The install dir for executables (default ${EXEC_INSTALL_PREFIX}/bin)
|
||||||
set(SBIN_INSTALL_DIR "sbin" ) # The install dir for system executables (default ${EXEC_INSTALL_PREFIX}/sbin)
|
set(SBIN_INSTALL_DIR "sbin" ) # The install dir for system executables (default ${EXEC_INSTALL_PREFIX}/sbin)
|
||||||
|
|
|
@ -5,6 +5,10 @@ SET(SRC_LIST
|
||||||
gamestate.c
|
gamestate.c
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SET(EXECUTABLE_SRC_LIST
|
||||||
|
main.c
|
||||||
|
)
|
||||||
|
|
||||||
find_package(Allegro5 REQUIRED)
|
find_package(Allegro5 REQUIRED)
|
||||||
find_package(Allegro5Font REQUIRED)
|
find_package(Allegro5Font REQUIRED)
|
||||||
find_package(Allegro5TTF REQUIRED)
|
find_package(Allegro5TTF REQUIRED)
|
||||||
|
@ -17,42 +21,36 @@ if(APPLE)
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
if(MINGW)
|
if(MINGW)
|
||||||
# resource compilation for MinGW
|
# resource compilation for MinGW
|
||||||
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icon.o COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_SOURCE_DIR} -i${CMAKE_SOURCE_DIR}/data/icons/icon.rc -o ${CMAKE_CURRENT_BINARY_DIR}/icon.o )
|
add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/icon.o COMMAND ${CMAKE_RC_COMPILER} -I${CMAKE_SOURCE_DIR} -i${CMAKE_SOURCE_DIR}/data/icons/icon.rc -o ${CMAKE_CURRENT_BINARY_DIR}/icon.o )
|
||||||
set(SRC_LIST ${SRC_LIST} ${CMAKE_CURRENT_BINARY_DIR}/icon.o)
|
set(EXECUTABLE_SRC_LIST ${EXECUTABLE_SRC_LIST} ${CMAKE_CURRENT_BINARY_DIR}/icon.o)
|
||||||
set(LINK_FLAGS -Wl,-subsystem,windows)
|
set(LINK_FLAGS -Wl,-subsystem,windows)
|
||||||
endif(MINGW)
|
endif(MINGW)
|
||||||
|
|
||||||
SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/superderpy:\$ORIGIN/gamestates:\$ORIGIN/levels:\$ORIGIN:\$ORIGIN/../lib")
|
SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/radioedit:\$ORIGIN/gamestates:\$ORIGIN:\$ORIGIN/../lib:\$ORIGIN/lib:\$ORIGIN/bin")
|
||||||
|
|
||||||
#IF(${PACKAGE_BUILD})
|
|
||||||
# SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
|
|
||||||
# SET(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/superderpy:\$ORIGIN")
|
|
||||||
#ENDIF(${PACKAGE_BUILD})
|
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set(EXECUTABLE "SuperDerpy")
|
set(EXECUTABLE "RadioEdit")
|
||||||
else(APPLE)
|
else(APPLE)
|
||||||
set(EXECUTABLE "superderpy")
|
set(EXECUTABLE "radioedit")
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
|
||||||
add_library("libsuperderpy" SHARED ${SRC_LIST})
|
add_library("libsuperderpy-radioedit" SHARED ${SRC_LIST})
|
||||||
add_executable(${EXECUTABLE} WIN32 MACOSX_BUNDLE "main.c")
|
add_executable(${EXECUTABLE} WIN32 MACOSX_BUNDLE ${EXECUTABLE_SRC_LIST})
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES("libsuperderpy" PROPERTIES PREFIX "")
|
SET_TARGET_PROPERTIES("libsuperderpy-radioedit" 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})
|
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 dl libsuperderpy)
|
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 dl libsuperderpy-radioedit)
|
||||||
|
|
||||||
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)
|
target_link_libraries("libsuperderpy-radioedit" ${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)
|
if(ALLEGRO5_MAIN_FOUND)
|
||||||
target_link_libraries(${EXECUTABLE} ${ALLEGRO5_MAIN_LIBRARIES})
|
target_link_libraries(${EXECUTABLE} ${ALLEGRO5_MAIN_LIBRARIES})
|
||||||
endif(ALLEGRO5_MAIN_FOUND)
|
endif(ALLEGRO5_MAIN_FOUND)
|
||||||
|
|
||||||
add_subdirectory(gamestates)
|
add_subdirectory(gamestates)
|
||||||
add_subdirectory(levels)
|
|
||||||
|
|
||||||
install(TARGETS ${EXECUTABLE} DESTINATION ${BIN_INSTALL_DIR})
|
install(TARGETS ${EXECUTABLE} DESTINATION ${BIN_INSTALL_DIR})
|
||||||
install(TARGETS "libsuperderpy" DESTINATION ${LIB_INSTALL_DIR})
|
install(TARGETS "libsuperderpy-radioedit" DESTINATION ${LIB_INSTALL_DIR})
|
||||||
|
|
|
@ -26,33 +26,33 @@
|
||||||
struct Game;
|
struct Game;
|
||||||
|
|
||||||
struct Gamestate {
|
struct Gamestate {
|
||||||
char* name;
|
char* name;
|
||||||
void* handle;
|
void* handle;
|
||||||
bool loaded, pending_load;
|
bool loaded, pending_load;
|
||||||
bool started, pending_start;
|
bool started, pending_start;
|
||||||
bool showLoading;
|
bool showLoading;
|
||||||
bool paused;
|
bool paused;
|
||||||
bool fade; // TODO: or maybe should it be in API?
|
bool fade; // TODO: or maybe should it be in API?
|
||||||
unsigned char fade_counter;
|
unsigned char fade_counter;
|
||||||
char** after; // TODO: and this one too?
|
char** after; // TODO: and this one too?
|
||||||
struct Gamestate* next;
|
struct Gamestate* next;
|
||||||
void* data;
|
void* data;
|
||||||
struct {
|
struct {
|
||||||
void (*Gamestate_Draw)(struct Game *game, void* data);
|
void (*Gamestate_Draw)(struct Game *game, void* data);
|
||||||
void (*Gamestate_Logic)(struct Game *game, void* data);
|
void (*Gamestate_Logic)(struct Game *game, void* data);
|
||||||
|
|
||||||
void* (*Gamestate_Load)(struct Game *game, void (*progress)(struct Game *game));
|
void* (*Gamestate_Load)(struct Game *game, void (*progress)(struct Game *game));
|
||||||
void (*Gamestate_Start)(struct Game *game, void* data);
|
void (*Gamestate_Start)(struct Game *game, void* data);
|
||||||
void (*Gamestate_Pause)(struct Game *game, void* data);
|
void (*Gamestate_Pause)(struct Game *game, void* data);
|
||||||
void (*Gamestate_Resume)(struct Game *game, void* data);
|
void (*Gamestate_Resume)(struct Game *game, void* data);
|
||||||
void (*Gamestate_Stop)(struct Game *game, void* data);
|
void (*Gamestate_Stop)(struct Game *game, void* data);
|
||||||
void (*Gamestate_Unload)(struct Game *game, void* data);
|
void (*Gamestate_Unload)(struct Game *game, void* data);
|
||||||
|
|
||||||
void (*Gamestate_ProcessEvent)(struct Game *game, void* data, ALLEGRO_EVENT *ev);
|
void (*Gamestate_ProcessEvent)(struct Game *game, void* data, ALLEGRO_EVENT *ev);
|
||||||
void (*Gamestate_Reload)(struct Game *game, void* data);
|
void (*Gamestate_Reload)(struct Game *game, void* data);
|
||||||
|
|
||||||
int *Gamestate_ProgressCount;
|
int *Gamestate_ProgressCount;
|
||||||
} api;
|
} api;
|
||||||
};
|
};
|
||||||
|
|
||||||
void LoadGamestate(struct Game *game, const char* name);
|
void LoadGamestate(struct Game *game, const char* name);
|
||||||
|
|
|
@ -1,21 +1,16 @@
|
||||||
MACRO(GAMESTATE name)
|
MACRO(GAMESTATE name)
|
||||||
|
|
||||||
add_library("libsuperderpy-muffinattack-${name}" SHARED "${name}.c")
|
add_library("libsuperderpy-radioedit-${name}" SHARED "${name}.c")
|
||||||
|
|
||||||
SET_TARGET_PROPERTIES("libsuperderpy-muffinattack-${name}" PROPERTIES PREFIX "")
|
SET_TARGET_PROPERTIES("libsuperderpy-radioedit-${name}" PROPERTIES PREFIX "")
|
||||||
|
|
||||||
target_link_libraries("libsuperderpy-muffinattack-${name}" ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} m libsuperderpy)
|
target_link_libraries("libsuperderpy-radioedit-${name}" ${ALLEGRO5_LIBRARIES} ${ALLEGRO5_FONT_LIBRARIES} ${ALLEGRO5_TTF_LIBRARIES} ${ALLEGRO5_PRIMITIVES_LIBRARIES} ${ALLEGRO5_AUDIO_LIBRARIES} ${ALLEGRO5_ACODEC_LIBRARIES} ${ALLEGRO5_IMAGE_LIBRARIES} m libsuperderpy-radioedit)
|
||||||
|
|
||||||
install(TARGETS "libsuperderpy-muffinattack-${name}" DESTINATION ${LIB_INSTALL_DIR})
|
install(TARGETS "libsuperderpy-radioedit-${name}" DESTINATION ${LIB_INSTALL_DIR})
|
||||||
|
|
||||||
ENDMACRO()
|
ENDMACRO()
|
||||||
|
|
||||||
GAMESTATE("dosowisko")
|
GAMESTATE("dosowisko")
|
||||||
GAMESTATE("menu")
|
GAMESTATE("menu")
|
||||||
GAMESTATE("disclaimer")
|
|
||||||
GAMESTATE("intro")
|
|
||||||
GAMESTATE("map")
|
|
||||||
GAMESTATE("about")
|
|
||||||
#GAMESTATE("pause")
|
|
||||||
|
|
||||||
GAMESTATE("loading")
|
GAMESTATE("loading")
|
||||||
|
|
|
@ -106,18 +106,22 @@ void Gamestate_Draw(struct Game *game, struct dosowiskoResources* data) {
|
||||||
al_clear_to_color(al_map_rgba(0,0,0,0));
|
al_clear_to_color(al_map_rgba(0,0,0,0));
|
||||||
|
|
||||||
al_draw_text(data->font, al_map_rgba(255,255,255,10), game->viewport.width/2, game->viewport.height*0.4167, ALLEGRO_ALIGN_CENTRE, t);
|
al_draw_text(data->font, al_map_rgba(255,255,255,10), game->viewport.width/2, game->viewport.height*0.4167, ALLEGRO_ALIGN_CENTRE, t);
|
||||||
al_set_target_backbuffer(game->display);
|
|
||||||
|
|
||||||
al_clear_to_color(al_map_rgb(35, 31, 32));
|
|
||||||
|
|
||||||
double tg = tan(-data->tan/384.0 * ALLEGRO_PI - ALLEGRO_PI/2);
|
double tg = tan(-data->tan/384.0 * ALLEGRO_PI - ALLEGRO_PI/2);
|
||||||
|
|
||||||
int fade = data->fadeout ? 255 : data->fade;
|
int fade = data->fadeout ? 255 : data->fade;
|
||||||
|
|
||||||
|
al_set_target_bitmap(data->pixelator);
|
||||||
|
al_clear_to_color(al_map_rgb(35, 31, 32));
|
||||||
|
|
||||||
al_draw_tinted_scaled_bitmap(data->bitmap, al_map_rgba(fade, fade, fade, fade), 0, 0, al_get_bitmap_width(data->bitmap), al_get_bitmap_height(data->bitmap), -tg*al_get_bitmap_width(data->bitmap)*0.05, -tg*al_get_bitmap_height(data->bitmap)*0.05, al_get_bitmap_width(data->bitmap)+tg*0.1*al_get_bitmap_width(data->bitmap), al_get_bitmap_height(data->bitmap)+tg*0.1*al_get_bitmap_height(data->bitmap), 0);
|
al_draw_tinted_scaled_bitmap(data->bitmap, al_map_rgba(fade, fade, fade, fade), 0, 0, al_get_bitmap_width(data->bitmap), al_get_bitmap_height(data->bitmap), -tg*al_get_bitmap_width(data->bitmap)*0.05, -tg*al_get_bitmap_height(data->bitmap)*0.05, al_get_bitmap_width(data->bitmap)+tg*0.1*al_get_bitmap_width(data->bitmap), al_get_bitmap_height(data->bitmap)+tg*0.1*al_get_bitmap_height(data->bitmap), 0);
|
||||||
|
|
||||||
al_draw_bitmap(data->checkerboard, 0, 0, 0);
|
al_draw_bitmap(data->checkerboard, 0, 0, 0);
|
||||||
|
|
||||||
|
al_set_target_backbuffer(game->display);
|
||||||
|
|
||||||
|
al_draw_bitmap(data->pixelator, 0, 0, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,13 +159,14 @@ void* Gamestate_Load(struct Game *game, void (*progress)(struct Game*)) {
|
||||||
data->timeline = TM_Init(game, "main");
|
data->timeline = TM_Init(game, "main");
|
||||||
data->bitmap = al_create_bitmap(game->viewport.width, game->viewport.height);
|
data->bitmap = al_create_bitmap(game->viewport.width, game->viewport.height);
|
||||||
data->checkerboard = al_create_bitmap(game->viewport.width, game->viewport.height);
|
data->checkerboard = al_create_bitmap(game->viewport.width, game->viewport.height);
|
||||||
|
data->pixelator = al_create_bitmap(game->viewport.width, game->viewport.height);
|
||||||
|
|
||||||
al_set_target_bitmap(data->checkerboard);
|
al_set_target_bitmap(data->checkerboard);
|
||||||
al_lock_bitmap(data->checkerboard, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
|
al_lock_bitmap(data->checkerboard, ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
|
||||||
int x, y;
|
int x, y;
|
||||||
for (x = 0; x < al_get_bitmap_width(data->checkerboard); x=x+2) {
|
for (x = 0; x < al_get_bitmap_width(data->checkerboard); x=x+2) {
|
||||||
for (y = 0; y < al_get_bitmap_height(data->checkerboard); y=y+2) {
|
for (y = 0; y < al_get_bitmap_height(data->checkerboard); y=y+2) {
|
||||||
al_put_pixel(x, y, al_map_rgb(0,0,0));
|
al_put_pixel(x, y, al_map_rgba(0,0,0,64));
|
||||||
al_put_pixel(x+1, y, al_map_rgba(0,0,0,0));
|
al_put_pixel(x+1, y, al_map_rgba(0,0,0,0));
|
||||||
al_put_pixel(x, y+1, al_map_rgba(0,0,0,0));
|
al_put_pixel(x, y+1, al_map_rgba(0,0,0,0));
|
||||||
al_put_pixel(x+1, y+1, al_map_rgba(0,0,0,0));
|
al_put_pixel(x+1, y+1, al_map_rgba(0,0,0,0));
|
||||||
|
@ -211,6 +216,7 @@ void Gamestate_Unload(struct Game *game, struct dosowiskoResources* data) {
|
||||||
al_destroy_sample(data->key_sample);
|
al_destroy_sample(data->key_sample);
|
||||||
al_destroy_bitmap(data->bitmap);
|
al_destroy_bitmap(data->bitmap);
|
||||||
al_destroy_bitmap(data->checkerboard);
|
al_destroy_bitmap(data->checkerboard);
|
||||||
|
al_destroy_bitmap(data->pixelator);
|
||||||
TM_Destroy(data->timeline);
|
TM_Destroy(data->timeline);
|
||||||
free(data);
|
free(data);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ struct dosowiskoResources {
|
||||||
ALLEGRO_FONT *font;
|
ALLEGRO_FONT *font;
|
||||||
ALLEGRO_SAMPLE *sample, *kbd_sample, *key_sample;
|
ALLEGRO_SAMPLE *sample, *kbd_sample, *key_sample;
|
||||||
ALLEGRO_SAMPLE_INSTANCE *sound, *kbd, *key;
|
ALLEGRO_SAMPLE_INSTANCE *sound, *kbd, *key;
|
||||||
ALLEGRO_BITMAP *bitmap, *checkerboard;
|
ALLEGRO_BITMAP *bitmap, *checkerboard, *pixelator;
|
||||||
int pos, fade, tick, tan;
|
int pos, fade, tick, tan;
|
||||||
char text[255];
|
char text[255];
|
||||||
bool underscore, fadeout;
|
bool underscore, fadeout;
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
void Progress(struct Game *game, struct LoadingResources *data, float p) {
|
void Progress(struct Game *game, struct LoadingResources *data, float p) {
|
||||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||||
al_draw_bitmap(data->loading_bitmap,0,0,0);
|
al_draw_bitmap(data->loading_bitmap,0,0,0);
|
||||||
al_draw_filled_rectangle(0, game->viewport.height*0.985, p*game->viewport.width, game->viewport.height, al_map_rgba(255,255,255,255));
|
al_draw_filled_rectangle(0, game->viewport.height-1, p*game->viewport.width, game->viewport.height, al_map_rgba(128,128,128,128));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Draw(struct Game *game, struct LoadingResources *data, float p) {
|
void Draw(struct Game *game, struct LoadingResources *data, float p) {
|
||||||
|
@ -39,15 +39,10 @@ void* Load(struct Game *game) {
|
||||||
|
|
||||||
data->loading_bitmap = al_create_bitmap(game->viewport.width, game->viewport.height);
|
data->loading_bitmap = al_create_bitmap(game->viewport.width, game->viewport.height);
|
||||||
|
|
||||||
data->image = LoadScaledBitmap(game, "loading.png", game->viewport.height*2, game->viewport.height);
|
|
||||||
|
|
||||||
al_set_target_bitmap(data->loading_bitmap);
|
al_set_target_bitmap(data->loading_bitmap);
|
||||||
al_clear_to_color(al_map_rgb(193,225,218));
|
al_clear_to_color(al_map_rgb(0,0,0));
|
||||||
al_draw_bitmap(data->image, game->viewport.width-al_get_bitmap_width(data->image), 0, 0);
|
al_draw_filled_rectangle(0, game->viewport.height-1, game->viewport.width, game->viewport.height, al_map_rgba(32,32,32,32));
|
||||||
DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), game->viewport.width*0.0234, game->viewport.height*0.84, ALLEGRO_ALIGN_LEFT, "Loading...");
|
|
||||||
al_draw_filled_rectangle(0, game->viewport.height*0.985, game->viewport.width, game->viewport.height, al_map_rgba(128,128,128,128));
|
|
||||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||||
al_destroy_bitmap(data->image);
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,5 @@
|
||||||
|
|
||||||
/*! \brief Resources used by Loading state. */
|
/*! \brief Resources used by Loading state. */
|
||||||
struct LoadingResources {
|
struct LoadingResources {
|
||||||
ALLEGRO_BITMAP *loading_bitmap; /*!< Rendered loading bitmap. */
|
ALLEGRO_BITMAP *loading_bitmap; /*!< Rendered loading bitmap. */
|
||||||
ALLEGRO_BITMAP *image; /*!< Loading background. */
|
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -27,43 +27,69 @@
|
||||||
enum menustate_enum {
|
enum menustate_enum {
|
||||||
MENUSTATE_MAIN,
|
MENUSTATE_MAIN,
|
||||||
MENUSTATE_OPTIONS,
|
MENUSTATE_OPTIONS,
|
||||||
MENUSTATE_CONTROLS,
|
|
||||||
MENUSTATE_VIDEO,
|
MENUSTATE_VIDEO,
|
||||||
MENUSTATE_PAUSE,
|
MENUSTATE_AUDIO,
|
||||||
MENUSTATE_AUDIO
|
MENUSTATE_HIDDEN,
|
||||||
|
MENUSTATE_ABOUT,
|
||||||
|
MENUSTATE_LOST,
|
||||||
|
MENUSTATE_INTRO,
|
||||||
|
// FIXME: menustate abuse eeeeew
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Resources used by Menu state. */
|
/*! \brief Resources used by Menu state. */
|
||||||
struct MenuResources {
|
struct MenuResources {
|
||||||
ALLEGRO_BITMAP *image; /*!< Bitmap with lower portion of menu landscape. */
|
ALLEGRO_BITMAP *bg; /*!< Bitmap with lower portion of menu landscape. */
|
||||||
ALLEGRO_BITMAP *cloud; /*!< Bitmap with bigger cloud. */
|
ALLEGRO_BITMAP *cloud; /*!< Bitmap with bigger cloud. */
|
||||||
ALLEGRO_BITMAP *cloud2; /*!< Bitmap with small cloud. */
|
ALLEGRO_BITMAP *grass;
|
||||||
ALLEGRO_BITMAP *pie; /*!< Unscaled bitmap with pie. */
|
ALLEGRO_BITMAP *forest;
|
||||||
ALLEGRO_BITMAP *pie_bitmap; /*!< Scaled and "rendered" bitmap with pies. */
|
ALLEGRO_BITMAP *stage;
|
||||||
ALLEGRO_BITMAP *pinkcloud_bitmap; /*!< Scaled bitmap with pinkcloud and home. */
|
ALLEGRO_BITMAP *speaker;
|
||||||
ALLEGRO_BITMAP *pinkcloud; /*!< Unscaled bitmap with pinkcloud and home. */
|
ALLEGRO_BITMAP *lines;
|
||||||
ALLEGRO_BITMAP *rain; /*!< Unscaled bitmap with rain drop. */
|
ALLEGRO_BITMAP *cable;
|
||||||
ALLEGRO_BITMAP *rain_bitmap; /*!< Scaled and "rendered" bitmap with rain drops. */
|
ALLEGRO_BITMAP *light;
|
||||||
ALLEGRO_BITMAP *mountain; /*!< Flashing mountain in background bitmap. */
|
|
||||||
ALLEGRO_BITMAP *logo; /*!< Logo displayed in the background. */
|
ALLEGRO_BITMAP *marksmall;
|
||||||
ALLEGRO_BITMAP *logoblur; /*!< Prerendered blurred logo. */
|
ALLEGRO_BITMAP *markbig;
|
||||||
ALLEGRO_BITMAP *glass; /*!< Texture used for glass effect in the logo. */
|
int markx, marky;
|
||||||
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 badguySpeed;
|
||||||
|
|
||||||
|
ALLEGRO_SAMPLE *chord_samples[6];
|
||||||
|
ALLEGRO_SAMPLE_INSTANCE *chords[6];
|
||||||
|
// 0-2: low; 3-5: high
|
||||||
|
|
||||||
|
int usage;
|
||||||
|
int lightx, lighty, lightanim;
|
||||||
|
|
||||||
|
int soloready, soloanim, soloflash;
|
||||||
|
bool soloactive;
|
||||||
|
|
||||||
|
struct Badguy {
|
||||||
|
struct Character *character;
|
||||||
|
struct Badguy *next, *prev;
|
||||||
|
float speed;
|
||||||
|
bool melting;
|
||||||
|
} *badguys[4], *destroyQueue;
|
||||||
|
|
||||||
|
int timeTillNextBadguy, badguyRate;
|
||||||
|
|
||||||
|
struct Character *ego;
|
||||||
|
struct Character *cow;
|
||||||
|
struct Character *badguy;
|
||||||
|
struct Timeline *timeline;
|
||||||
float cloud_position; /*!< Position of bigger cloud. */
|
float cloud_position; /*!< Position of bigger cloud. */
|
||||||
float cloud2_position; /*!< Position of small cloud. */
|
ALLEGRO_SAMPLE *sample; /*!< Music sample. */
|
||||||
int mountain_position; /*!< Position of flashing mountain. */
|
|
||||||
float tint; /*!< Opacity 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 *click_sample; /*!< Click sound sample. */
|
||||||
ALLEGRO_SAMPLE_INSTANCE *music; /*!< Sample instance with background music. */
|
ALLEGRO_SAMPLE *quit_sample;
|
||||||
ALLEGRO_SAMPLE_INSTANCE *rain_sound; /*!< Sample instance with rain sound. */
|
ALLEGRO_SAMPLE *end_sample;
|
||||||
|
ALLEGRO_SAMPLE *solo_sample;
|
||||||
|
ALLEGRO_SAMPLE_INSTANCE *music; /*!< Sample instance with music sound. */
|
||||||
ALLEGRO_SAMPLE_INSTANCE *click; /*!< Sample instance with click sound. */
|
ALLEGRO_SAMPLE_INSTANCE *click; /*!< Sample instance with click sound. */
|
||||||
|
ALLEGRO_SAMPLE_INSTANCE *quit;
|
||||||
|
ALLEGRO_SAMPLE_INSTANCE *solo;
|
||||||
|
ALLEGRO_SAMPLE_INSTANCE *end;
|
||||||
ALLEGRO_FONT *font_title; /*!< Font of "Super Derpy" text. */
|
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; /*!< Font of standard menu item. */
|
||||||
ALLEGRO_FONT *font_selected; /*!< Font of selected menu item. */
|
|
||||||
int selected; /*!< Number of selected menu item. */
|
int selected; /*!< Number of selected menu item. */
|
||||||
enum menustate_enum menustate; /*!< Current menu page. */
|
enum menustate_enum menustate; /*!< Current menu page. */
|
||||||
struct {
|
struct {
|
||||||
|
@ -71,8 +97,17 @@ struct MenuResources {
|
||||||
int fps;
|
int fps;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
|
int resolution;
|
||||||
} options; /*!< Options which can be changed in menu. */
|
} options; /*!< Options which can be changed in menu. */
|
||||||
};
|
|
||||||
|
|
||||||
//void DrawMenuState(struct Game *game);
|
struct {
|
||||||
//void ChangeMenuState(struct Game *game, enum menustate_enum state);
|
int key;
|
||||||
|
bool shift;
|
||||||
|
int delay;
|
||||||
|
// workaround for random bogus UP/DOWN events
|
||||||
|
int lastkey;
|
||||||
|
int lastdelay;
|
||||||
|
} keys;
|
||||||
|
|
||||||
|
int score;
|
||||||
|
};
|
||||||
|
|
165
src/main.c
165
src/main.c
|
@ -35,23 +35,6 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
|
||||||
void DrawConsole(struct Game *game) {
|
|
||||||
if (game->_priv.showconsole) {
|
|
||||||
al_draw_bitmap(game->_priv.console, 0, 0, 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, al_map_rgb(255,255,255), game->viewport.width*0.99, 0, ALLEGRO_ALIGN_RIGHT, sfps);
|
|
||||||
}
|
|
||||||
game->_priv.fps_count.frames_done++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DrawGamestates(struct Game *game) {
|
void DrawGamestates(struct Game *game) {
|
||||||
al_set_target_backbuffer(game->display);
|
al_set_target_backbuffer(game->display);
|
||||||
al_clear_to_color(al_map_rgb(0,0,0));
|
al_clear_to_color(al_map_rgb(0,0,0));
|
||||||
|
@ -84,64 +67,8 @@ void EventGamestates(struct Game *game, ALLEGRO_EVENT *ev) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetupViewport(struct Game *game) {
|
|
||||||
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->viewport.width, clipHeight = game->viewport.width / aspectRatio;
|
|
||||||
int clipX = 0, clipY = (game->viewport.height - clipHeight) / 2;
|
|
||||||
if (clipY <= 0) {
|
|
||||||
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);
|
|
||||||
|
|
||||||
ALLEGRO_TRANSFORM projection;
|
|
||||||
al_build_transform(&projection, clipX, clipY, 1, 1, 0.0f);
|
|
||||||
al_use_transform(&projection);
|
|
||||||
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->viewport.width, 0);
|
|
||||||
al_use_transform(&projection);
|
|
||||||
int temp = game->viewport.height;
|
|
||||||
game->viewport.height = game->viewport.width;
|
|
||||||
game->viewport.width = temp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int 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"),game->viewport.height*0.018,0 );
|
|
||||||
if (game->viewport.height*0.022 >= 16) {
|
|
||||||
game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/PerfectDOSVGA437.ttf"),16,0 );
|
|
||||||
} else {
|
|
||||||
game->_priv.font_bsod = al_load_ttf_font(GetDataFilePath(game, "fonts/DejaVuSansMono.ttf"),game->viewport.height*0.022,0 );
|
|
||||||
}
|
|
||||||
game->_priv.font = al_load_ttf_font(GetDataFilePath(game, "fonts/ShadowsIntoLight.ttf"),game->viewport.height*0.09,0 );
|
|
||||||
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 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) {
|
void derp(int sig) {
|
||||||
write(STDERR_FILENO, "Segmentation fault\n", 19);
|
int __attribute__((unused)) n = write(STDERR_FILENO, "Segmentation fault\nI just don't know what went wrong!\n", 54);
|
||||||
write(STDERR_FILENO, "I just don't know what went wrong!\n", 35);
|
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,7 +78,7 @@ int main(int argc, char **argv){
|
||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
|
|
||||||
al_set_org_name("Super Derpy");
|
al_set_org_name("Super Derpy");
|
||||||
al_set_app_name("Muffin Attack");
|
al_set_app_name("Radio Edit");
|
||||||
|
|
||||||
if(!al_init()) {
|
if(!al_init()) {
|
||||||
fprintf(stderr, "failed to initialize allegro!\n");
|
fprintf(stderr, "failed to initialize allegro!\n");
|
||||||
|
@ -169,14 +96,14 @@ int main(int argc, char **argv){
|
||||||
game._priv.font_bsod = NULL;
|
game._priv.font_bsod = NULL;
|
||||||
game._priv.console = NULL;
|
game._priv.console = NULL;
|
||||||
|
|
||||||
game.config.fullscreen = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fullscreen", "1"));
|
game.config.fullscreen = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fullscreen", "0"));
|
||||||
game.config.music = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "music", "7"));
|
game.config.music = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "music", "10"));
|
||||||
game.config.voice = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "voice", "10"));
|
game.config.voice = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "voice", "10"));
|
||||||
game.config.fx = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fx", "10"));
|
game.config.fx = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "fx", "10"));
|
||||||
game.config.debug = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "debug", "0"));
|
game.config.debug = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "debug", "0"));
|
||||||
game.config.width = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "width", "800"));
|
game.config.width = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "width", "1280"));
|
||||||
if (game.config.width<320) game.config.width=320;
|
if (game.config.width<320) game.config.width=320;
|
||||||
game.config.height = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "height", "450"));
|
game.config.height = atoi(GetConfigOptionDefault(&game, "SuperDerpy", "height", "720"));
|
||||||
if (game.config.height<180) game.config.height=180;
|
if (game.config.height<180) game.config.height=180;
|
||||||
|
|
||||||
if(!al_init_image_addon()) {
|
if(!al_init_image_addon()) {
|
||||||
|
@ -217,6 +144,9 @@ int main(int argc, char **argv){
|
||||||
else al_set_new_display_flags(ALLEGRO_WINDOWED);
|
else al_set_new_display_flags(ALLEGRO_WINDOWED);
|
||||||
al_set_new_display_option(ALLEGRO_VSYNC, 2-atoi(GetConfigOptionDefault(&game, "SuperDerpy", "vsync", "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_OPENGL, atoi(GetConfigOptionDefault(&game, "SuperDerpy", "opengl", "1")), ALLEGRO_SUGGEST);
|
||||||
|
#ifdef ALLEGRO_WINDOWS
|
||||||
|
al_set_new_window_position(20, 40); // workaround nasty Windows bug with window being created off-screen
|
||||||
|
#endif
|
||||||
|
|
||||||
game.display = al_create_display(game.config.width, game.config.height);
|
game.display = al_create_display(game.config.width, game.config.height);
|
||||||
if(!game.display) {
|
if(!game.display) {
|
||||||
|
@ -226,20 +156,17 @@ int main(int argc, char **argv){
|
||||||
|
|
||||||
SetupViewport(&game);
|
SetupViewport(&game);
|
||||||
|
|
||||||
int ret = Console_Load(&game);
|
|
||||||
if (ret!=0) return ret;
|
|
||||||
|
|
||||||
PrintConsole(&game, "Viewport %dx%d", game.viewport.width, game.viewport.height);
|
PrintConsole(&game, "Viewport %dx%d", game.viewport.width, game.viewport.height);
|
||||||
|
|
||||||
ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(&game, "icons/superderpy.png"));
|
ALLEGRO_BITMAP *icon = al_load_bitmap(GetDataFilePath(&game, "icons/radioedit.png"));
|
||||||
al_set_window_title(game.display, "Super Derpy: Muffin Attack");
|
al_set_window_title(game.display, "Radio Edit");
|
||||||
al_set_display_icon(game.display, icon);
|
al_set_display_icon(game.display, icon);
|
||||||
al_destroy_bitmap(icon);
|
al_destroy_bitmap(icon);
|
||||||
|
|
||||||
if (game.config.fullscreen) al_hide_mouse_cursor(game.display);
|
if (game.config.fullscreen) al_hide_mouse_cursor(game.display);
|
||||||
al_inhibit_screensaver(true);
|
al_inhibit_screensaver(true);
|
||||||
|
|
||||||
al_set_new_bitmap_flags(ALLEGRO_MAG_LINEAR | ALLEGRO_MIN_LINEAR);
|
al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR);
|
||||||
|
|
||||||
game._priv.gamestates = NULL;
|
game._priv.gamestates = NULL;
|
||||||
|
|
||||||
|
@ -250,7 +177,7 @@ int main(int argc, char **argv){
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.audio.v = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
|
game.audio.v = al_create_voice(44100, ALLEGRO_AUDIO_DEPTH_INT16, ALLEGRO_CHANNEL_CONF_2);
|
||||||
game.audio.mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
|
game.audio.mixer = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
|
||||||
game.audio.fx = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
|
game.audio.fx = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
|
||||||
game.audio.music = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
|
game.audio.music = al_create_mixer(44100, ALLEGRO_AUDIO_DEPTH_FLOAT32, ALLEGRO_CHANNEL_CONF_2);
|
||||||
|
@ -268,15 +195,15 @@ int main(int argc, char **argv){
|
||||||
|
|
||||||
game._priv.showconsole = game.config.debug;
|
game._priv.showconsole = game.config.debug;
|
||||||
|
|
||||||
al_flip_display();
|
|
||||||
al_clear_to_color(al_map_rgb(0,0,0));
|
al_clear_to_color(al_map_rgb(0,0,0));
|
||||||
al_wait_for_vsync();
|
|
||||||
game._priv.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer
|
game._priv.timer = al_create_timer(ALLEGRO_BPS_TO_SECS(60)); // logic timer
|
||||||
if(!game._priv.timer) {
|
if(!game._priv.timer) {
|
||||||
FatalError(&game, true, "Failed to create logic timer.");
|
FatalError(&game, true, "Failed to create logic timer.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
al_register_event_source(game._priv.event_queue, al_get_timer_event_source(game._priv.timer));
|
al_register_event_source(game._priv.event_queue, al_get_timer_event_source(game._priv.timer));
|
||||||
|
|
||||||
|
al_flip_display();
|
||||||
al_start_timer(game._priv.timer);
|
al_start_timer(game._priv.timer);
|
||||||
|
|
||||||
setlocale(LC_NUMERIC, "C");
|
setlocale(LC_NUMERIC, "C");
|
||||||
|
@ -306,24 +233,20 @@ int main(int argc, char **argv){
|
||||||
free(gamestate);
|
free(gamestate);
|
||||||
|
|
||||||
char libname[1024] = {};
|
char libname[1024] = {};
|
||||||
snprintf(libname, 1024, "libsuperderpy-%s-loading.so", "muffinattack");
|
snprintf(libname, 1024, "libsuperderpy-%s-loading" LIBRARY_EXTENTION, "radioedit");
|
||||||
void *handle = dlopen(libname, RTLD_NOW);
|
void *handle = dlopen(libname, RTLD_NOW);
|
||||||
if (!handle) {
|
if (!handle) {
|
||||||
FatalError(&game, true, "Error while initializing loading screen %s", dlerror());
|
FatalError(&game, true, "Error while initializing loading screen %s", dlerror());
|
||||||
exit(1);
|
exit(1);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
void gs_error() {
|
#define GS_LOADINGERROR FatalError(&game, true, "Error on resolving loading symbol: %s", dlerror()); exit(1);
|
||||||
FatalError(&game, true, "Error on resolving loading symbol: %s", dlerror());
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(game._priv.loading.Draw = dlsym(handle, "Draw"))) { gs_error(); }
|
if (!(game._priv.loading.Draw = dlsym(handle, "Draw"))) { GS_LOADINGERROR; }
|
||||||
|
if (!(game._priv.loading.Load = dlsym(handle, "Load"))) { GS_LOADINGERROR; }
|
||||||
if (!(game._priv.loading.Load = dlsym(handle, "Load"))) { gs_error(); }
|
if (!(game._priv.loading.Start = dlsym(handle, "Start"))) { GS_LOADINGERROR; }
|
||||||
if (!(game._priv.loading.Start = dlsym(handle, "Start"))) { gs_error(); }
|
if (!(game._priv.loading.Stop = dlsym(handle, "Stop"))) { GS_LOADINGERROR; }
|
||||||
if (!(game._priv.loading.Stop = dlsym(handle, "Stop"))) { gs_error(); }
|
if (!(game._priv.loading.Unload = dlsym(handle, "Unload"))) { GS_LOADINGERROR; }
|
||||||
if (!(game._priv.loading.Unload = dlsym(handle, "Unload"))) { gs_error(); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
game._priv.loading.data = (*game._priv.loading.Load)(&game);
|
game._priv.loading.data = (*game._priv.loading.Load)(&game);
|
||||||
|
@ -370,7 +293,7 @@ int main(int argc, char **argv){
|
||||||
al_stop_timer(game._priv.timer);
|
al_stop_timer(game._priv.timer);
|
||||||
// TODO: take proper game name
|
// TODO: take proper game name
|
||||||
char libname[1024];
|
char libname[1024];
|
||||||
snprintf(libname, 1024, "libsuperderpy-%s-%s.so", "muffinattack", tmp->name);
|
snprintf(libname, 1024, "libsuperderpy-%s-%s" LIBRARY_EXTENTION, "radioedit", tmp->name);
|
||||||
tmp->handle = dlopen(libname,RTLD_NOW);
|
tmp->handle = dlopen(libname,RTLD_NOW);
|
||||||
if (!tmp->handle) {
|
if (!tmp->handle) {
|
||||||
//PrintConsole(&game, "Error while loading gamestate \"%s\": %s", tmp->name, dlerror());
|
//PrintConsole(&game, "Error while loading gamestate \"%s\": %s", tmp->name, dlerror());
|
||||||
|
@ -380,27 +303,22 @@ int main(int argc, char **argv){
|
||||||
tmp->pending_start = false;
|
tmp->pending_start = false;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
void gs_error() {
|
#define GS_ERROR FatalError(&game, false, "Error on resolving gamestate symbol: %s", dlerror()); tmp->pending_load = false; tmp->pending_start = false; tmp=tmp->next; continue;
|
||||||
FatalError(&game, true, "Error on resolving gamestate symbol: %s", dlerror());
|
|
||||||
tmp->pending_load = false;
|
|
||||||
tmp->pending_start = false;
|
|
||||||
tmp=tmp->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(tmp->api.Gamestate_Draw = dlsym(tmp->handle, "Gamestate_Draw"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Draw = dlsym(tmp->handle, "Gamestate_Draw"))) { GS_ERROR; }
|
||||||
if (!(tmp->api.Gamestate_Logic = dlsym(tmp->handle, "Gamestate_Logic"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Logic = dlsym(tmp->handle, "Gamestate_Logic"))) { GS_ERROR; }
|
||||||
|
|
||||||
if (!(tmp->api.Gamestate_Load = dlsym(tmp->handle, "Gamestate_Load"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Load = dlsym(tmp->handle, "Gamestate_Load"))) { GS_ERROR; }
|
||||||
if (!(tmp->api.Gamestate_Start = dlsym(tmp->handle, "Gamestate_Start"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Start = dlsym(tmp->handle, "Gamestate_Start"))) { GS_ERROR; }
|
||||||
if (!(tmp->api.Gamestate_Pause = dlsym(tmp->handle, "Gamestate_Pause"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Pause = dlsym(tmp->handle, "Gamestate_Pause"))) { GS_ERROR; }
|
||||||
if (!(tmp->api.Gamestate_Resume = dlsym(tmp->handle, "Gamestate_Resume"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Resume = dlsym(tmp->handle, "Gamestate_Resume"))) { GS_ERROR; }
|
||||||
if (!(tmp->api.Gamestate_Stop = dlsym(tmp->handle, "Gamestate_Stop"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Stop = dlsym(tmp->handle, "Gamestate_Stop"))) { GS_ERROR; }
|
||||||
if (!(tmp->api.Gamestate_Unload = dlsym(tmp->handle, "Gamestate_Unload"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Unload = dlsym(tmp->handle, "Gamestate_Unload"))) { GS_ERROR; }
|
||||||
|
|
||||||
if (!(tmp->api.Gamestate_ProcessEvent = dlsym(tmp->handle, "Gamestate_ProcessEvent"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_ProcessEvent = dlsym(tmp->handle, "Gamestate_ProcessEvent"))) { GS_ERROR; }
|
||||||
if (!(tmp->api.Gamestate_Reload = dlsym(tmp->handle, "Gamestate_Reload"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_Reload = dlsym(tmp->handle, "Gamestate_Reload"))) { GS_ERROR; }
|
||||||
|
|
||||||
if (!(tmp->api.Gamestate_ProgressCount = dlsym(tmp->handle, "Gamestate_ProgressCount"))) { gs_error(); continue; }
|
if (!(tmp->api.Gamestate_ProgressCount = dlsym(tmp->handle, "Gamestate_ProgressCount"))) { GS_ERROR; }
|
||||||
|
|
||||||
int p = 0;
|
int p = 0;
|
||||||
void progress(struct Game *game) {
|
void progress(struct Game *game) {
|
||||||
|
@ -420,7 +338,7 @@ int main(int argc, char **argv){
|
||||||
}
|
}
|
||||||
DrawConsole(&game);
|
DrawConsole(&game);
|
||||||
al_flip_display();
|
al_flip_display();
|
||||||
tmp->data = (*tmp->api.Gamestate_Load)(&game, &progress);
|
tmp->data = (*tmp->api.Gamestate_Load)(&game, &progress); // feel free to replace "progress" with empty function if you want to compile with clang
|
||||||
loaded++;
|
loaded++;
|
||||||
|
|
||||||
tmp->loaded = true;
|
tmp->loaded = true;
|
||||||
|
@ -471,11 +389,14 @@ int main(int argc, char **argv){
|
||||||
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#ifdef ALLEGRO_MACOSX
|
else if(ev.type == ALLEGRO_EVENT_DISPLAY_FOUND) {
|
||||||
|
SetupViewport(&game);
|
||||||
|
}
|
||||||
|
#ifdef ALLEGRO_MACOSX
|
||||||
else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == 104)) { //TODO: report to upstream
|
else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == 104)) { //TODO: report to upstream
|
||||||
#else
|
#else
|
||||||
else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_TILDE)) {
|
else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (ev.keyboard.keycode == ALLEGRO_KEY_TILDE)) {
|
||||||
#endif
|
#endif
|
||||||
game._priv.showconsole = !game._priv.showconsole;
|
game._priv.showconsole = !game._priv.showconsole;
|
||||||
}
|
}
|
||||||
else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game.config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) {
|
else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game.config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F1)) {
|
||||||
|
@ -502,7 +423,7 @@ int main(int argc, char **argv){
|
||||||
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game.config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F12)) {
|
} else if ((ev.type == ALLEGRO_EVENT_KEY_DOWN) && (game.config.debug) && (ev.keyboard.keycode == ALLEGRO_KEY_F12)) {
|
||||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH);
|
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_USER_DOCUMENTS_PATH);
|
||||||
char filename[255] = { };
|
char filename[255] = { };
|
||||||
snprintf(filename, 255, "SuperDerpy_%ld_%ld.png", time(NULL), clock());
|
snprintf(filename, 255, "RadioEdit_%ld_%ld.png", time(NULL), clock());
|
||||||
al_set_path_filename(path, filename);
|
al_set_path_filename(path, filename);
|
||||||
al_save_bitmap(al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP), al_get_backbuffer(game.display));
|
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));
|
PrintConsole(&game, "Screenshot stored in %s", al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
||||||
|
|
|
@ -35,6 +35,8 @@ struct Gamestate;
|
||||||
struct Game {
|
struct Game {
|
||||||
ALLEGRO_DISPLAY *display; /*!< Main Allegro display. */
|
ALLEGRO_DISPLAY *display; /*!< Main Allegro display. */
|
||||||
|
|
||||||
|
ALLEGRO_TRANSFORM projection;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
int width; /*!< Actual available width of viewport. */
|
int width; /*!< Actual available width of viewport. */
|
||||||
int height; /*!< Actual available height of viewport. */
|
int height; /*!< Actual available height of viewport. */
|
||||||
|
|
|
@ -226,6 +226,7 @@ struct TM_Action* TM_AddAction(struct Timeline* timeline, bool (*func)(struct Ga
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TM_Action* TM_AddBackgroundAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) {
|
struct TM_Action* TM_AddBackgroundAction(struct Timeline* timeline, bool (*func)(struct Game*, struct TM_Action*, enum TM_ActionState), struct TM_Arguments* args, int delay, char* name) {
|
||||||
|
// FIXME: some action wasn't freed!
|
||||||
struct TM_Action *action = malloc(sizeof(struct TM_Action));
|
struct TM_Action *action = malloc(sizeof(struct TM_Action));
|
||||||
if (timeline->background) {
|
if (timeline->background) {
|
||||||
struct TM_Action *pom = timeline->background;
|
struct TM_Action *pom = timeline->background;
|
||||||
|
@ -297,8 +298,9 @@ void TM_CleanQueue(struct Timeline* timeline) {
|
||||||
while (pom!=NULL) {
|
while (pom!=NULL) {
|
||||||
if (pom->active) {
|
if (pom->active) {
|
||||||
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
||||||
else {
|
if (pom->timer) {
|
||||||
if (pom->timer) al_destroy_timer(pom->timer);
|
al_stop_timer(pom->timer);
|
||||||
|
al_destroy_timer(pom->timer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TM_DestroyArgs(pom->arguments);
|
TM_DestroyArgs(pom->arguments);
|
||||||
|
@ -311,23 +313,25 @@ void TM_CleanQueue(struct Timeline* timeline) {
|
||||||
free(pom->name);
|
free(pom->name);
|
||||||
free(pom);
|
free(pom);
|
||||||
tmp2 = tmp;
|
tmp2 = tmp;
|
||||||
if (!tmp) pom=timeline->background->next;
|
if (!tmp) pom=timeline->queue->next;
|
||||||
else pom=tmp->next;
|
else pom=tmp->next;
|
||||||
tmp = tmp2;
|
tmp = tmp2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: it shouldn't be needed, but is. Debug!
|
||||||
|
timeline->queue = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TM_CleanBackgroundQueue(struct Timeline* timeline) {
|
void TM_CleanBackgroundQueue(struct Timeline* timeline) {
|
||||||
PrintConsole(timeline->game, "Timeline Manager[%s]: cleaning background queue", timeline->name);
|
PrintConsole(timeline->game, "Timeline Manager[%s]: cleaning background queue", timeline->name);
|
||||||
struct TM_Action *tmp, *tmp2, *pom = timeline->queue;
|
struct TM_Action *tmp, *tmp2, *pom = timeline->background;
|
||||||
tmp = NULL;
|
tmp = NULL;
|
||||||
pom=timeline->background;
|
|
||||||
while (pom!=NULL) {
|
while (pom!=NULL) {
|
||||||
if (pom->active) {
|
if (pom->active) {
|
||||||
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
if (*pom->function) (*pom->function)(timeline->game, pom, TM_ACTIONSTATE_DESTROY);
|
||||||
else {
|
if (pom->timer) {
|
||||||
if (pom->timer) al_destroy_timer(pom->timer);
|
al_stop_timer(pom->timer);
|
||||||
|
al_destroy_timer(pom->timer);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TM_DestroyArgs(pom->arguments);
|
TM_DestroyArgs(pom->arguments);
|
||||||
|
@ -345,6 +349,8 @@ void TM_CleanBackgroundQueue(struct Timeline* timeline) {
|
||||||
tmp = tmp2;
|
tmp = tmp2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// TODO: it shouldn't be needed, but is. Debug!
|
||||||
|
timeline->background = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TM_Destroy(struct Timeline* timeline) {
|
void TM_Destroy(struct Timeline* timeline) {
|
||||||
|
@ -363,6 +369,8 @@ struct TM_Arguments* TM_AddToArgs(struct TM_Arguments* args, int num, ...) {
|
||||||
struct TM_Arguments* tmp = args;
|
struct TM_Arguments* tmp = args;
|
||||||
for(i = 0; i < num; i++) {
|
for(i = 0; i < num; i++) {
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
|
//FIXME: on some occasions some arguments weren't freed. Check it out.
|
||||||
|
// TM_AddQueuedBackgroundAction? possibly not only.
|
||||||
tmp = malloc(sizeof(struct TM_Arguments));
|
tmp = malloc(sizeof(struct TM_Arguments));
|
||||||
tmp->value = va_arg(ap, void*);
|
tmp->value = va_arg(ap, void*);
|
||||||
tmp->next = NULL;
|
tmp->next = NULL;
|
||||||
|
|
|
@ -39,11 +39,11 @@ enum TM_ActionState {
|
||||||
|
|
||||||
/*! \brief Timeline structure. */
|
/*! \brief Timeline structure. */
|
||||||
struct Timeline {
|
struct Timeline {
|
||||||
struct TM_Action *queue; /*!< Main timeline queue. */
|
struct TM_Action *queue; /*!< Main timeline queue. */
|
||||||
struct TM_Action *background; /*!< Background queue. */
|
struct TM_Action *background; /*!< Background queue. */
|
||||||
char* name; /*!< Name of the timeline. */
|
char* name; /*!< Name of the timeline. */
|
||||||
unsigned int lastid; /*!< Last ID given to timeline action. */
|
unsigned int lastid; /*!< Last ID given to timeline action. */
|
||||||
struct Game* game; /*!< Reference to the game object. */
|
struct Game* game; /*!< Reference to the game object. */
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Arguments for TM_Action. */
|
/*! \brief Arguments for TM_Action. */
|
||||||
|
|
427
src/utils.c
427
src/utils.c
|
@ -20,11 +20,98 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <allegro5/allegro_primitives.h>
|
#include <allegro5/allegro_primitives.h>
|
||||||
|
#include <allegro5/allegro_ttf.h>
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
#include "string.h"
|
||||||
#include "math.h"
|
#include "math.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
|
|
||||||
|
char* strdup(const char *str) {
|
||||||
|
int n = strlen(str) + 1;
|
||||||
|
char *dup = malloc(n);
|
||||||
|
if (dup) { strcpy(dup, str); }
|
||||||
|
return dup;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawConsole(struct Game *game) {
|
||||||
|
if (game->_priv.showconsole) {
|
||||||
|
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);
|
||||||
|
al_use_transform(&game->projection);
|
||||||
|
|
||||||
|
DrawTextWithShadow(game->_priv.font, al_map_rgb(255,255,255), game->viewport.width*0.99, 0, ALLEGRO_ALIGN_RIGHT, sfps);
|
||||||
|
|
||||||
|
}
|
||||||
|
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,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);
|
||||||
|
game->_priv.font = al_load_ttf_font(GetDataFilePath(game, "fonts/MonkeyIsland.ttf"), 0 ,0 );
|
||||||
|
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);
|
||||||
|
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;
|
||||||
|
|
||||||
|
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) {
|
void DrawVerticalGradientRect(float x, float y, float w, float h, ALLEGRO_COLOR top, ALLEGRO_COLOR bottom) {
|
||||||
ALLEGRO_VERTEX v[] = {
|
ALLEGRO_VERTEX v[] = {
|
||||||
{.x = x, .y = y, .z = 0, .color = top},
|
{.x = x, .y = y, .z = 0, .color = top},
|
||||||
|
@ -48,41 +135,12 @@ void DrawTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float
|
||||||
al_draw_text(font, color, (int)x, (int)y, flags, text);
|
al_draw_text(font, color, (int)x, (int)y, flags, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FadeGamestate(struct Game *game, bool in) {
|
/* linear filtering code written by SiegeLord */
|
||||||
//TODO: reimplement
|
ALLEGRO_COLOR interpolate(ALLEGRO_COLOR c1, ALLEGRO_COLOR c2, float frac) {
|
||||||
/* ALLEGRO_BITMAP* bitmap = al_create_bitmap(game->viewportWidth, game->viewportHeight);
|
return al_map_rgba_f(c1.r + frac * (c2.r - c1.r),
|
||||||
al_set_target_bitmap(bitmap);
|
c1.g + frac * (c2.g - c1.g),
|
||||||
al_clear_to_color(al_map_rgb(0,0,0));
|
c1.b + frac * (c2.b - c1.b),
|
||||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
c1.a + frac * (c2.a - c1.a));
|
||||||
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. */
|
/*! \brief Scales bitmap using software linear filtering method to current target. */
|
||||||
|
@ -95,15 +153,6 @@ void ScaleBitmap(ALLEGRO_BITMAP* source, int width, int height) {
|
||||||
al_lock_bitmap(al_get_target_bitmap(), ALLEGRO_PIXEL_FORMAT_ANY, ALLEGRO_LOCK_WRITEONLY);
|
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);
|
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++) {
|
for (y = 0; y < height; y++) {
|
||||||
float pixy = ((float)y / height) * ((float)al_get_bitmap_height(source) - 1);
|
float pixy = ((float)y / height) * ((float)al_get_bitmap_height(source) - 1);
|
||||||
float pixy_f = floor(pixy);
|
float pixy_f = floor(pixy);
|
||||||
|
@ -133,33 +182,23 @@ ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, i
|
||||||
al_set_target_bitmap(target);
|
al_set_target_bitmap(target);
|
||||||
al_clear_to_color(al_map_rgba(0,0,0,0));
|
al_clear_to_color(al_map_rgba(0,0,0,0));
|
||||||
char* origfn = GetDataFilePath(game, filename);
|
char* origfn = GetDataFilePath(game, 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_MEMORY_BITMAP);
|
||||||
if (memoryscale) {
|
|
||||||
al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR | ALLEGRO_MAG_LINEAR);
|
source = al_load_bitmap( origfn );
|
||||||
ScaleBitmap(source, width, height);
|
if (memoryscale) {
|
||||||
}
|
al_set_new_bitmap_flags(ALLEGRO_MIN_LINEAR);
|
||||||
else {
|
ScaleBitmap(source, width, height);
|
||||||
al_draw_scaled_bitmap(source, 0, 0, al_get_bitmap_width(source), al_get_bitmap_height(source), 0, 0, width, height, 0);
|
}
|
||||||
}
|
else {
|
||||||
/*al_save_bitmap(cachefn, target);
|
al_draw_scaled_bitmap(source, 0, 0, al_get_bitmap_width(source), al_get_bitmap_height(source), 0, 0, width, height, 0);
|
||||||
PrintConsole(game, "Cache bitmap %s generated.", filename);*/
|
|
||||||
al_destroy_bitmap(source);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*source = al_load_bitmap( cachefn );
|
al_destroy_bitmap(source);
|
||||||
if (source) {
|
|
||||||
if ((al_get_bitmap_width(source)!=width) || (al_get_bitmap_height(source)!=height)) {
|
|
||||||
al_destroy_bitmap(source);*/
|
|
||||||
GenerateBitmap();
|
|
||||||
free(origfn);
|
free(origfn);
|
||||||
return target;
|
return target;
|
||||||
/* }
|
|
||||||
return source;
|
|
||||||
} else GenerateBitmap();
|
|
||||||
return target;*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void FatalError(struct Game *game, bool fatal, char* format, ...) {
|
void FatalError(struct Game *game, bool fatal, char* format, ...) {
|
||||||
|
@ -179,6 +218,10 @@ void FatalError(struct Game *game, bool fatal, char* format, ...) {
|
||||||
PrintConsole(game, text);
|
PrintConsole(game, text);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ALLEGRO_TRANSFORM trans;
|
||||||
|
al_identity_transform(&trans);
|
||||||
|
al_use_transform(&trans);
|
||||||
|
|
||||||
if (!game->_priv.font_bsod) {
|
if (!game->_priv.font_bsod) {
|
||||||
game->_priv.font_bsod = al_create_builtin_font();
|
game->_priv.font_bsod = al_create_builtin_font();
|
||||||
}
|
}
|
||||||
|
@ -186,7 +229,7 @@ void FatalError(struct Game *game, bool fatal, char* format, ...) {
|
||||||
al_set_target_backbuffer(game->display);
|
al_set_target_backbuffer(game->display);
|
||||||
al_clear_to_color(al_map_rgb(0,0,170));
|
al_clear_to_color(al_map_rgb(0,0,170));
|
||||||
al_flip_display();
|
al_flip_display();
|
||||||
al_rest(1.1);
|
al_rest(0.6);
|
||||||
|
|
||||||
bool done = false;
|
bool done = false;
|
||||||
while (!done) {
|
while (!done) {
|
||||||
|
@ -194,32 +237,32 @@ void FatalError(struct Game *game, bool fatal, char* format, ...) {
|
||||||
al_set_target_backbuffer(game->display);
|
al_set_target_backbuffer(game->display);
|
||||||
al_clear_to_color(al_map_rgb(0,0,170));
|
al_clear_to_color(al_map_rgb(0,0,170));
|
||||||
|
|
||||||
char *header = "SUPER DERPY";
|
char *header = "RADIO EDIT";
|
||||||
|
|
||||||
al_draw_filled_rectangle(game->viewport.width/2 - al_get_text_width(game->_priv.font_bsod, header)/2 - 4, (int)(game->viewport.height * 0.32), 4 + game->viewport.width/2 + al_get_text_width(game->_priv.font_bsod, header)/2, (int)(game->viewport.height * 0.32) + al_get_font_line_height(game->_priv.font_bsod), al_map_rgb(170,170,170));
|
al_draw_filled_rectangle(al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header)/2 - 4, (int)(al_get_display_height(game->display) * 0.32), 4 + al_get_display_width(game->display)/2 + al_get_text_width(game->_priv.font_bsod, header)/2, (int)(al_get_display_height(game->display) * 0.32) + al_get_font_line_height(game->_priv.font_bsod), al_map_rgb(170,170,170));
|
||||||
|
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(0, 0, 170), game->viewport.width/2, (int)(game->viewport.height * 0.32), ALLEGRO_ALIGN_CENTRE, header);
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(0, 0, 170), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32), ALLEGRO_ALIGN_CENTRE, header);
|
||||||
|
|
||||||
char *header2 = "A fatal exception 0xD3RP has occured at 0028:M00F11NZ in GST SD(01) +";
|
char *header2 = "A fatal exception 0xD3RP has occured at 0028:M00F11NZ in GST SD(01) +";
|
||||||
|
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2, (int)(game->viewport.height * 0.32+2*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, header2);
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+2*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, header2);
|
||||||
al_draw_textf(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(game->viewport.height * 0.32+3*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "%p and system just doesn't know what went wrong.", game);
|
al_draw_textf(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+3*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "%p and system just doesn't know what went wrong.", game);
|
||||||
|
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2, (int)(game->viewport.height * 0.32+5*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, text);
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+5*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, text);
|
||||||
|
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(game->viewport.height * 0.32+7*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to terminate this error.");
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+7*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to terminate this error.");
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(game->viewport.height * 0.32+8*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to destroy all muffins in the world.");
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+8*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Press any key to destroy all muffins in the world.");
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(game->viewport.height * 0.32+9*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Just kidding, please press any key anyway.");
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+9*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "* Just kidding, please press any key anyway.");
|
||||||
|
|
||||||
|
|
||||||
if (fatal) {
|
if (fatal) {
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(game->viewport.height * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "This is fatal error. My bad.");
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "This is fatal error. My bad.");
|
||||||
|
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2, (int)(game->viewport.height * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to quit _");
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to quit _");
|
||||||
} else {
|
} else {
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(game->viewport.height * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "Anything I can do to help?");
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2 - al_get_text_width(game->_priv.font_bsod, header2)/2, (int)(al_get_display_height(game->display) * 0.32+11*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_LEFT, "Anything I can do to help?");
|
||||||
|
|
||||||
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), game->viewport.width/2, (int)(game->viewport.height * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to continue _");
|
al_draw_text(game->_priv.font_bsod, al_map_rgb(255,255,255), al_get_display_width(game->display)/2, (int)(al_get_display_height(game->display) * 0.32+13*al_get_font_line_height(game->_priv.font_bsod)*1.25), ALLEGRO_ALIGN_CENTRE, "Press any key to continue _");
|
||||||
}
|
}
|
||||||
|
|
||||||
al_flip_display();
|
al_flip_display();
|
||||||
|
@ -235,12 +278,31 @@ void FatalError(struct Game *game, bool fatal, char* format, ...) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
al_use_transform(&game->projection);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TestPath(char* filename, char* subpath, char** result) {
|
||||||
|
if (*result) return; //already found
|
||||||
|
ALLEGRO_PATH *tail = al_create_path(filename);
|
||||||
|
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
|
||||||
|
ALLEGRO_PATH *data = al_create_path(subpath);
|
||||||
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* GetDataFilePath(struct Game *game, char* filename) {
|
char* GetDataFilePath(struct Game *game, char* filename) {
|
||||||
|
|
||||||
//TODO: support for current game
|
//TODO: support for current game
|
||||||
|
|
||||||
|
//FIXME: strdups result in memory leaks!
|
||||||
|
|
||||||
char *result = 0;
|
char *result = 0;
|
||||||
|
|
||||||
if (al_filename_exists(filename)) {
|
if (al_filename_exists(filename)) {
|
||||||
|
@ -254,24 +316,13 @@ char* GetDataFilePath(struct Game *game, char* filename) {
|
||||||
return strdup(origfn);
|
return strdup(origfn);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestPath(char* subpath) {
|
TestPath(filename, "data/", &result);
|
||||||
ALLEGRO_PATH *tail = al_create_path(filename);
|
TestPath(filename, "../share/radioedit/data/", &result);
|
||||||
ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH);
|
TestPath(filename, "../data/", &result);
|
||||||
ALLEGRO_PATH *data = al_create_path(subpath);
|
#ifdef ALLEGRO_MACOSX
|
||||||
al_join_paths(path, data);
|
TestPath(filename, "../Resources/data/", &result);
|
||||||
al_join_paths(path, tail);
|
TestPath(filename, "../Resources/gamestates/", &result);
|
||||||
//printf("Testing for %s\n", al_path_cstr(path, ALLEGRO_NATIVE_PATH_SEP));
|
#endif
|
||||||
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) {
|
if (!result) {
|
||||||
FatalError(game, true, "Could not find data file: %s!", filename);
|
FatalError(game, true, "Could not find data file: %s!", filename);
|
||||||
|
@ -280,7 +331,6 @@ char* GetDataFilePath(struct Game *game, char* filename) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PrintConsole(struct Game *game, char* format, ...) {
|
void PrintConsole(struct Game *game, char* format, ...) {
|
||||||
va_list vl;
|
va_list vl;
|
||||||
va_start(vl, format);
|
va_start(vl, format);
|
||||||
|
@ -288,6 +338,8 @@ void PrintConsole(struct Game *game, char* format, ...) {
|
||||||
vsnprintf(text, 1024, format, vl);
|
vsnprintf(text, 1024, format, vl);
|
||||||
va_end(vl);
|
va_end(vl);
|
||||||
if (game->config.debug) { printf("%s\n", text); fflush(stdout); }
|
if (game->config.debug) { printf("%s\n", text); fflush(stdout); }
|
||||||
|
if (!game->_priv.console) return;
|
||||||
|
if ((!game->config.debug) && (!game->_priv.showconsole)) return;
|
||||||
ALLEGRO_BITMAP *con = al_create_bitmap(al_get_bitmap_width(game->_priv.console), al_get_bitmap_height(game->_priv.console));
|
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_set_target_bitmap(con);
|
||||||
al_clear_to_color(al_map_rgba(0,0,0,80));
|
al_clear_to_color(al_map_rgba(0,0,0,80));
|
||||||
|
@ -299,3 +351,180 @@ void PrintConsole(struct Game *game, char* format, ...) {
|
||||||
al_set_target_bitmap(al_get_backbuffer(game->display));
|
al_set_target_bitmap(al_get_backbuffer(game->display));
|
||||||
al_destroy_bitmap(con);
|
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 tilt, int flags) {
|
||||||
|
if (character->dead) return;
|
||||||
|
al_draw_tinted_bitmap_region(character->spritesheet->bitmap, tilt, al_get_bitmap_width(character->bitmap)*(character->pos%character->spritesheet->cols),al_get_bitmap_height(character->bitmap)*(character->pos/character->spritesheet->cols),al_get_bitmap_width(character->bitmap), al_get_bitmap_height(character->bitmap), character->x, character->y, flags);
|
||||||
|
}
|
||||||
|
|
81
src/utils.h
81
src/utils.h
|
@ -22,6 +22,32 @@
|
||||||
#include <allegro5/allegro_font.h>
|
#include <allegro5/allegro_font.h>
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
|
#ifdef ALLEGRO_WINDOWS
|
||||||
|
#define LIBRARY_EXTENTION ".dll"
|
||||||
|
#else
|
||||||
|
#define LIBRARY_EXTENTION ".so"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// hacks for "pixelness"
|
||||||
|
#define al_draw_bitmap(a,b,c,d) al_draw_bitmap(a,(int)(b), (int)(c), d)
|
||||||
|
#define al_draw_scaled_bitmap(a,b,c,d,e,f,g,h,i,j) al_draw_scaled_bitmap(a,b,c,d,e,(int)(f), (int)(g), (int)(h), (int)(i), j)
|
||||||
|
//#define al_draw_tinted_scaled_bitmap(a,tint,b,c,d,e,f,g,h,i,j) al_draw_tinted_scaled_bitmap(a,tint,(int)(b),(int)(c),(int)(d),(int)(e),(int)(f), (int)(g), (int)(h), (int)(i), j)
|
||||||
|
#define al_draw_rotated_bitmap(a,b,c,d,e,f,g) al_draw_rotated_bitmap(a,(int)(b),(int)(c),(int)(d),(int)(e), f, g)
|
||||||
|
#define al_draw_bitmap_region(a, b, c, d, e, f, g, h) al_draw_bitmap_region(a,(int)(b),(int)(c),(int)(d),(int)(e),(int)(f), (int)(g), h)
|
||||||
|
#define al_draw_tinted_bitmap_region(a, tint, b, c, d, e, f, g, h) al_draw_tinted_bitmap_region(a,tint,(int)(b),(int)(c),(int)(d),(int)(e),(int)(f), (int)(g), h)
|
||||||
|
#define al_draw_tinted_rotated_bitmap(a,tint,b,c,d,e,f,g) al_draw_tinted_rotated_bitmap(a,tint,(int)(b),(int)(c),(int)(d),(int)(e), f, g)
|
||||||
|
//#define al_draw_filled_rectangle
|
||||||
|
//#define al_draw_prim()
|
||||||
|
#define al_load_ttf_font(a,b,c) al_load_ttf_font(a, (int)(b / 8)*8 == 0 ? 8 : (int)(b / 8)*8, c)
|
||||||
|
#define al_draw_text(a,b,c,d,e,f) al_draw_text(a, b, (int)(c), (int)(d), e, f)
|
||||||
|
|
||||||
|
char* strdup(const char *str);
|
||||||
|
|
||||||
|
void SetupViewport(struct Game *game);
|
||||||
|
void Console_Unload(struct Game *game);
|
||||||
|
void DrawConsole(struct Game *game);
|
||||||
|
|
||||||
/*! \brief Draws rectangle filled with vertical gradient. */
|
/*! \brief Draws rectangle filled with vertical gradient. */
|
||||||
void DrawVerticalGradientRect(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. */
|
/*! \brief Draws rectangle filled with horizontal gradient. */
|
||||||
|
@ -36,12 +62,11 @@ void DrawTextWithShadow(ALLEGRO_FONT *font, ALLEGRO_COLOR color, float x, float
|
||||||
/*! \brief Loads bitmap into memory and scales it with software linear filtering. */
|
/*! \brief Loads bitmap into memory and scales it with software linear filtering. */
|
||||||
ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, int height);
|
ALLEGRO_BITMAP* LoadScaledBitmap(struct Game *game, char* filename, int width, int height);
|
||||||
|
|
||||||
/*! \brief Displays fade in or fade out animation on current gamestate. */
|
|
||||||
void FadeGamestate(struct Game *game, bool in);
|
|
||||||
|
|
||||||
/*! \brief Finds path for data file. */
|
/*! \brief Finds path for data file. */
|
||||||
char* GetDataFilePath(struct Game *game, char* filename);
|
char* GetDataFilePath(struct Game *game, char* filename);
|
||||||
|
|
||||||
|
char* GetLibFilePath(struct Game *game, char* filename);
|
||||||
|
|
||||||
/*! \brief Print some message on game console.
|
/*! \brief Print some message on game console.
|
||||||
*
|
*
|
||||||
* Draws message on console bitmap, so it'll be displayed when calling DrawConsole.
|
* Draws message on console bitmap, so it'll be displayed when calling DrawConsole.
|
||||||
|
@ -51,3 +76,53 @@ char* GetDataFilePath(struct Game *game, char* filename);
|
||||||
void PrintConsole(struct Game *game, char* format, ...);
|
void PrintConsole(struct Game *game, char* format, ...);
|
||||||
|
|
||||||
void FatalError(struct Game *game, bool exit, char* format, ...);
|
void FatalError(struct Game *game, bool exit, char* format, ...);
|
||||||
|
|
||||||
|
/*! \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);
|
||||||
|
|
Loading…
Add table
Reference in a new issue