Merge branch 'master' into extraspells

This commit is contained in:
Andrei "Akari" Alexeyev 2017-02-27 17:36:43 +02:00
commit 248210f575
61 changed files with 1648 additions and 761 deletions

4
.gitignore vendored
View file

@ -2,3 +2,7 @@ build/
winbuild/
osxbuild/
.ctagsdb
.*DS_Store
# autogenerated
*.out

View file

@ -16,7 +16,14 @@ add_subdirectory(src)
if(RELATIVE)
add_definitions(-DRELATIVE)
set(DATA_DIR "data")
if(APPLE)
set(RES_DIR "Taisei.app/Contents/Resources")
set(DATA_DIR "${RES_DIR}/data")
install(FILES "OSX-iconset.icns" DESTINATION "${RES_DIR}" RENAME "Taisei.icns")
else()
set(DATA_DIR "data")
endif()
install(FILES "story.txt" DESTINATION .)
else()

BIN
OSX-iconset.icns Normal file

Binary file not shown.

View file

@ -0,0 +1,20 @@
if("@TAISEI_OSX_LIB_ROOT@" STREQUAL "")
message(FATAL_ERROR "You must set TAISEI_OSX_LIB_ROOT, and possibly TAISEI_OSX_COMMAND_PREFIX, to use the install rule.")
endif()
execute_process(
COMMAND "@PROJECT_SOURCE_DIR@/scripts/osx-install-dylibs.sh"
"--iknowwhatimdoing"
"./Taisei.app/Contents/MacOS/Taisei"
"./Taisei.app/Contents/MacOS/dylibs"
"dylibs"
"@TAISEI_OSX_LIB_ROOT@"
"@TAISEI_OSX_COMMAND_PREFIX@"
WORKING_DIRECTORY "@CMAKE_INSTALL_PREFIX@"
RESULT_VARIABLE ERRCODE
)
if(NOT ERRCODE EQUAL 0)
message(FATAL_ERROR "OSX install script failed: ${ERRCODE}")
endif()

13
scripts/osx-gen-dmg.sh Executable file
View file

@ -0,0 +1,13 @@
#!/usr/bin/env bash
IN="$1"
OUT="$2"
if [[ -z "$IN" ]] || [[ -z "$OUT" ]] || [[ ! -d "$IN" ]]; then
>&2 echo "Usage: $0 <input_directory> <output.dmg>"
exit 1
fi
ln -sv /Applications "$IN/Applications" || exit 1
genisoimage -V Taisei -D -R -apple -no-pad -o "$OUT" "$IN" || exit $?
rm -v "$IN/Applications"

56
scripts/osx-install-dylibs.sh Executable file
View file

@ -0,0 +1,56 @@
#!/usr/bin/env bash
if [[ "$1" != "--iknowwhatimdoing" ]]; then
>&2 echo "This script should not be ran directly."
exit 1
fi
if [[ -z "$BASH_VERSINFO" ]] || [[ "$BASH_VERSINFO" -lt 4 ]]; then
>&2 echo "Your Bash version is too old. 4.0+ is required."
exit 1
fi
shift
EXE_PATH="$1"
DYLIB_PATH="$2"
DYLIB_REL_PATH="$3"
OSX_ROOT="$4"
OSX_CMD_PREFIX="$5"
mkdir -p "$DYLIB_PATH" || exit 2
[[ -f "$EXE_PATH" ]] || exit 3
[[ -d "$OSX_ROOT" ]] || exit 4
export PATH="$OSX_ROOT/bin:$PATH"
otool="${OSX_CMD_PREFIX}otool"
install_name_tool="${OSX_CMD_PREFIX}install_name_tool"
$otool --version
rm -vf "$DYLIB_PATH"/*.dylib
declare -A handled_libs
function handle_dylibs {
for lib in $($otool -L "$1" | sed -e '/:$/d' -e 's/[[:blank:]]*//' -e 's/[[:blank:]].*//' -e '/libSystem/d' -e '/.*\.dylib/!d' -e '/^\/usr\//d' | sort | uniq); do
libpath="$OSX_ROOT$lib"
libname="${lib##*/}"
$install_name_tool "$1" -change "$lib" "@executable_path/$DYLIB_REL_PATH/$libname" || exit 5
if [[ -n "${handled_libs[$libname]}" ]]; then
continue
fi
cp -v "$libpath" "$DYLIB_PATH/$libname" || exit 6
handled_libs[$libname]=1
handle_dylibs "$DYLIB_PATH/$libname"
done
$otool -L "$1"
}
handle_dylibs "$EXE_PATH"

View file

@ -1,6 +1,4 @@
%%VSHADER-HEAD%%
#version 120
#extension GL_EXT_draw_instanced : enable
uniform vec2 a0;
uniform vec2 a1;
@ -30,23 +28,23 @@ vec2 posrule(float t) {
void main(void) {
vec2 v = gl_Vertex.xy;
float t1 = gl_InstanceID-span/2;
float tail = span/1.9;
float s = -0.75/pow(tail,2)*(t1-tail)*(t1+tail);
vec2 pos = posrule(gl_InstanceID*0.5+timeshift);
vec2 d = pos - posrule(gl_InstanceID*0.5+timeshift-0.1);
float a = -angle(d);
mat2 m = mat2(cos(a), -sin(a), sin(a), cos(a));
v.x *= wq*1.5*length(d);
v.y *= hq*s;
gl_Position = gl_ModelViewProjectionMatrix*vec4(m*v+pos, 0.0, 1.0);
gl_TexCoord[0] = gl_MultiTexCoord0;
gl_TexCoord[0] = gl_MultiTexCoord0;
}
%%FSHADER-HEAD%%

View file

@ -1,6 +1,14 @@
find_package(PkgConfig REQUIRED)
find_package(OpenGL REQUIRED)
if(LINK_TO_LIBGL)
find_package(OpenGL REQUIRED)
add_definitions(-DLINK_TO_LIBGL)
# We didn't use anything from GLU except gluPerspective
# taiseigl now provides a simple replacement for it
list(FILTER OPENGL_LIBRARIES EXCLUDE REGEX ".*libGLU\\..*")
endif()
pkg_check_modules(SDL2 sdl2 REQUIRED)
pkg_check_modules(SDL2_TTF SDL2_ttf REQUIRED)
@ -38,6 +46,8 @@ set(SRCs
matrix.c
video.c
transition.c
color.c
difficulty.c
menu/menu.c
menu/mainmenu.c
menu/options.c
@ -46,7 +56,7 @@ set(SRCs
menu/ingamemenu.c
menu/gameovermenu.c
menu/savereplay.c
menu/difficulty.c
menu/difficultyselect.c
menu/charselect.c
menu/spellpractice.c
menu/common.c
@ -115,10 +125,17 @@ set(LIBs ${LIBs}
${SDL2_TTF_LIBRARIES}
${SDL2_MIXER_LIBRARIES}
${PNG_LIBRARIES}
${OPENGL_LIBRARIES}
${ZLIB_LIBRARIES}
${OPENGL_LIBRARIES}
m)
set(LIBDIRs
${SDL2_LIBRARY_DIRS}
${SDL2_TTF_LIBRARY_DIRS}
${PNG_LIBRARY_DIRS}
${ZLIB_LIBRARY_DIRS}
)
if(WIN32)
set(LIBs ${LIBs} -ldxguid -lwinmm)
@ -143,16 +160,11 @@ set(CMAKE_REQUIRED_INCLUDES ${INCs})
include_directories(${INCs})
check_symbol_exists(_POSIX_VERSION "unistd.h" POSIX)
check_symbol_exists(glDrawArraysInstanced "taiseigl.h" HAVE_glDrawArraysInstanced)
if(POSIX)
add_definitions(-D__POSIX__)
endif()
if(NOT HAVE_glDrawArraysInstanced)
add_definitions(-DGL_USE_ARB_DRAW_INSTANCED)
endif()
if (CMAKE_GENERATOR STREQUAL "Ninja" AND
((CMAKE_C_COMPILER_ID STREQUAL "GNU" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 4.9) OR
(CMAKE_C_COMPILER_ID STREQUAL "Clang" AND NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 3.5)))
@ -165,16 +177,31 @@ list(SORT SRCs)
list(REMOVE_DUPLICATES SRCs)
list(REMOVE_DUPLICATES LIBs)
link_directories(${LIBDIRs})
if(TAISEI_WIN32_CONSOLE)
list(REMOVE_ITEM LIBs -mwindows)
add_executable(taisei ${SRCs})
add_executable(taisei MACOSX_BUNDLE ${SRCs})
else()
add_executable(taisei WIN32 ${SRCs})
add_executable(taisei MACOSX_BUNDLE WIN32 ${SRCs})
endif()
target_link_libraries(taisei ${LIBs})
if(RELATIVE)
set(MACOSX_BUNDLE_BUNDLE_NAME "Taisei")
if(APPLE)
set_target_properties(taisei PROPERTIES
OUTPUT_NAME "Taisei"
MACOSX_BUNDLE_ICON_FILE "Taisei"
MACOSX_BUNDLE_BUNDLE_NAME "Taisei"
)
install(TARGETS taisei BUNDLE DESTINATION .)
set(OSX_INSTALLSCRIPT_PATH "${PROJECT_SOURCE_DIR}/scripts/OSXInstallDylibs.cmake")
configure_file("${OSX_INSTALLSCRIPT_PATH}.in" "${OSX_INSTALLSCRIPT_PATH}.out" @ONLY)
install(SCRIPT "${OSX_INSTALLSCRIPT_PATH}.out")
elseif(RELATIVE)
install(TARGETS taisei RUNTIME DESTINATION .)
else()
install(TARGETS taisei RUNTIME DESTINATION bin)

View file

@ -9,6 +9,7 @@
#define BOSS_H
#include "tscomplex.h"
#include "difficulty.h"
#include <resource/animation.h>
struct Boss;
@ -24,6 +25,26 @@ typedef enum AttackType {
} AttackType;
typedef struct AttackInfo {
/*
HOW TO SET UP THE IDMAP FOR DUMMIES
The idmap is used as a template to generate spellstage IDs in stage_init_array().
It looks like this:
{id_easy, id_normal, id_hard, id_lunatic}
Where each of those IDs are in range of 0-127, and are unique within each stage-specific AttackInfo array.
A special value of -1 can be used to not generate a spellstage for specific difficulties.
This is useful if your spell is only available on Hard and Lunatic, or has a difficulty-dependent name, etc.
IDs of AT_ExtraSpell attacks may overlap with those of other types.
Most importantly DO NOT CHANGE ENSTABILISHED IDs unless you absolutely must.
Doing so is going to break replays, progress files, and anything that stores stage IDs permanently.
Stage IDs are an internal detail invisible to the player, so they don't need to have any kind of fancy ordering.
*/
signed char idmap[NUM_SELECTABLE_DIFFICULTIES];
AttackType type;
char *name;
float timeout;
@ -32,7 +53,6 @@ typedef struct AttackInfo {
BossRule rule;
BossRule draw_rule;
// complex pos_spawn;
complex pos_dest;
} AttackInfo;

25
src/color.c Normal file
View file

@ -0,0 +1,25 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
#include <stdlib.h>
#include "color.h"
Color *rgba(float r, float g, float b, float a) {
Color *clr = malloc(sizeof(Color));
clr->r = r;
clr->g = g;
clr->b = b;
clr->a = a;
return clr;
}
Color *rgb(float r, float g, float b) {
return rgba(r, g, b, 1.0);
}

22
src/color.h Normal file
View file

@ -0,0 +1,22 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
#ifndef TSCOLOR_H
#define TSCOLOR_H
typedef struct {
float r;
float g;
float b;
float a;
} Color;
Color* rgba(float r, float g, float b, float a);
Color* rgb(float r, float g, float b);
#endif

View file

@ -214,7 +214,12 @@ void credits_draw(void) {
credits_draw_entry(&(credits.entries[i]));
glPopMatrix();
draw_transition();
draw_and_update_transition();
}
void credits_finish(void *arg) {
credits.end = 0;
set_transition(TransLoader, 0, FADE_TIME*10);
}
void credits_process(void) {
@ -233,7 +238,7 @@ void credits_process(void) {
}
if(global.frames == credits.end) {
set_transition(TransFadeWhite, CREDITS_FADEOUT, CREDITS_FADEOUT);
set_transition_callback(TransFadeWhite, CREDITS_FADEOUT, CREDITS_FADEOUT, credits_finish, NULL);
}
}
@ -251,7 +256,7 @@ void credits_free(void) {
void credits_loop(void) {
credits_init();
while(global.frames <= credits.end + CREDITS_FADEOUT) {
while(credits.end) {
handle_events(NULL, 0, NULL);
credits_process();
credits_draw();

31
src/difficulty.c Normal file
View file

@ -0,0 +1,31 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
#include "difficulty.h"
const char* difficulty_name(Difficulty diff) {
switch(diff) {
case D_Easy: return "Easy"; break;
case D_Normal: return "Normal"; break;
case D_Hard: return "Hard"; break;
case D_Lunatic: return "Lunatic"; break;
case D_Extra: return "Extra"; break;
default: return "Unknown"; break;
}
}
void difficulty_color(Color *c, Difficulty diff) {
switch(diff) {
case D_Easy: c->r = 0.5; c->g = 1.0; c->b = 0.5; break;
case D_Normal: c->r = 0.5; c->g = 0.5; c->b = 1.0; break;
case D_Hard: c->r = 1.0; c->g = 0.5; c->b = 0.5; break;
case D_Lunatic: c->r = 1.0; c->g = 0.5; c->b = 1.0; break;
case D_Extra: c->r = 0.5; c->g = 1.0; c->b = 1.0; break;
default: c->r = 0.5; c->g = 0.5; c->b = 0.5; break;
}
}

30
src/difficulty.h Normal file
View file

@ -0,0 +1,30 @@
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
* ---
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
* Copyright (C) 2012, Alexeyew Andrew <http://akari.thebadasschoobs.org/>
*/
#ifndef DIFFICULTY_H
#define DIFFICULTY_H
#include "color.h"
struct Color;
typedef enum {
D_Any = 0,
D_Easy,
D_Normal,
D_Hard,
D_Lunatic,
D_Extra // reserved for later
} Difficulty;
#define NUM_SELECTABLE_DIFFICULTIES D_Lunatic
const char* difficulty_name(Difficulty diff);
void difficulty_color(Color *c, Difficulty diff);
#endif

View file

@ -118,7 +118,7 @@ void ending_draw(Ending *e) {
draw_text(AL_Center, SCREEN_W/2, SCREEN_H/5*4, e->entries[e->pos].msg, _fonts.standard);
glColor4f(1,1,1,1);
draw_transition();
draw_and_update_transition();
}
void ending_loop(void) {

View file

@ -37,9 +37,6 @@ void init_global(void) {
memset(&resources, 0, sizeof(Resources));
printf("- fonts:\n");
init_fonts();
memset(&global.replay, 0, sizeof(Replay));
global.replaymode = REPLAY_RECORD;
@ -246,28 +243,6 @@ bool strendswith(const char *s, const char *e) {
return true;
}
char* difficulty_name(Difficulty diff) {
switch(diff) {
case D_Easy: return "Easy"; break;
case D_Normal: return "Normal"; break;
case D_Hard: return "Hard"; break;
case D_Lunatic: return "Lunatic"; break;
case D_Extra: return "Extra"; break;
default: return "Unknown"; break;
}
}
void difficulty_color(Color *c, Difficulty diff) {
switch(diff) {
case D_Easy: c->r = 0.5; c->g = 1.0; c->b = 0.5; break;
case D_Normal: c->r = 0.5; c->g = 0.5; c->b = 1.0; break;
case D_Hard: c->r = 1.0; c->g = 0.5; c->b = 0.5; break;
case D_Lunatic: c->r = 1.0; c->g = 0.5; c->b = 1.0; break;
case D_Extra: c->r = 0.5; c->g = 1.0; c->b = 1.0; break;
default: c->r = 0.5; c->g = 0.5; c->b = 0.5; break;
}
}
void stralloc(char **dest, const char *src) {
free(*dest);

View file

@ -23,6 +23,7 @@
#include "menu/menu.h"
#include "taiseigl.h"
#include "player.h"
#include "projectile.h"
#include "enemy.h"
@ -38,6 +39,8 @@
#include "replay.h"
#include "random.h"
#include "events.h"
#include "difficulty.h"
#include "color.h"
#include "taisei_err.h"
#include "rwops/all.h"
@ -81,8 +84,8 @@ enum {
GAMEOVER_DEFEAT = 1,
GAMEOVER_WIN,
GAMEOVER_ABORT,
GAMEOVER_REWATCH,
GAMEOVER_RESTART
GAMEOVER_RESTART,
GAMEOVER_TRANSITIONING = -1,
};
typedef struct {
@ -159,8 +162,6 @@ double clamp(double, double, double);
double approach(double v, double t, double d);
double psin(double);
bool strendswith(const char *s, const char *e);
char* difficulty_name(Difficulty diff);
void difficulty_color(Color *c, Difficulty diff);
void stralloc(char **dest, const char *src);
bool gamekeypressed(KeyIndex key);
int getenvint(const char *v);
@ -179,6 +180,9 @@ enum {
EV_CHECK_DESYNC, // replay-only
};
#undef strlcat
#undef strlcpy
#define strlcat SDL_strlcat
#define strlcpy SDL_strlcpy

View file

@ -147,7 +147,7 @@ void draw_lasers(int bgpass) {
if(bgpass != laser->in_background)
continue;
if(laser->shader && !config_get_int(CONFIG_NO_SHADER) && tgl_ext[TGLEXT_draw_instanced])
if(laser->shader && !config_get_int(CONFIG_NO_SHADER) && glext.draw_instanced)
draw_laser_curve_instanced(laser);
else
draw_laser_curve(laser);

View file

@ -13,27 +13,10 @@
#include "stage.h"
#include "menu/mainmenu.h"
#include "paths/native.h"
#include "taiseigl.h"
#include "gamepad.h"
#include "resource/bgm.h"
#include "progress.h"
void init_gl(void) {
load_gl_functions();
check_gl_extensions();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
init_quadvbo();
glClear(GL_COLOR_BUFFER_BIT);
}
void taisei_shutdown(void) {
config_save(CONFIG_FILE);
progress_save();
@ -101,7 +84,7 @@ int main(int argc, char **argv) {
if(argc >= 2 && argv[1] && !strcmp(argv[1], "dumpstages")) {
stage_init_array();
for(StageInfo *stg = stages; stg->loop; ++stg) {
for(StageInfo *stg = stages; stg->procs; ++stg) {
printf("%i %s: %s\n", stg->id, stg->title, stg->subtitle);
}
@ -143,19 +126,15 @@ int main(int argc, char **argv) {
config_load(CONFIG_FILE);
printf("initialize:\n");
if(SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0)
errx(-1, "Error initializing SDL: %s", SDL_GetError());
printf("-- SDL_Init\n");
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
init_global();
video_init();
printf("-- SDL viewport\n");
init_gl();
printf("-- GL\n");
printf("-- Video and OpenGL\n");
draw_loading_screen();
@ -167,8 +146,10 @@ int main(int argc, char **argv) {
init_sfx();
init_bgm();
load_resources();
printf("initialization complete.\n");
set_transition(TransLoader, 0, FADE_TIME*2);
printf("initialization complete.\n");
atexit(taisei_shutdown);
if(replay_path) {
@ -204,8 +185,7 @@ int main(int argc, char **argv) {
do {
global.game_over = 0;
init_player(&global.plr);
global.stage = stg;
stg->loop();
stage_loop(stg);
} while(global.game_over == GAMEOVER_RESTART);
return 0;

View file

@ -8,7 +8,7 @@
#include "global.h"
#include "menu.h"
#include "savereplay.h"
#include "difficulty.h"
#include "difficultyselect.h"
#include "charselect.h"
#include "ending.h"
#include "credits.h"
@ -48,12 +48,10 @@ troll:
troll2:
if(info) {
global.stage = info;
info->loop();
stage_loop(info);
} else {
for(int i = 0; stages[i].type == STAGE_STORY; ++i) {
global.stage = stages + i;
stages[i].loop();
for(StageInfo *s = stages; s->type == STAGE_STORY; ++s) {
stage_loop(s);
}
}

View file

@ -6,6 +6,7 @@
*/
#include "difficulty.h"
#include "difficultyselect.h"
#include "options.h"
#include "common.h"
#include "global.h"

View file

@ -5,8 +5,8 @@
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#ifndef DIFFICULTY_H
#define DIFFICULTY_H
#ifndef DIFFICULTYMENU_H
#define DIFFICULTYMENU_H
#include "menu.h"

View file

@ -49,7 +49,7 @@ void main_menu_update_spellpractice(void) {
MenuEntry *e = spell_practice_entry;
e->action = NULL;
for(StageInfo *stg = stages; stg->loop; ++stg) {
for(StageInfo *stg = stages; stg->procs; ++stg) {
if(stg->type == STAGE_SPELL) {
StageProgress *p = stage_get_progress_from_info(stg, D_Any, false);
if(p && p->unlocked) {
@ -62,7 +62,6 @@ void main_menu_update_spellpractice(void) {
void begin_main_menu(MenuData *m) {
start_bgm("bgm_menu");
set_transition(TransLoader, 0, FADE_TIME*2);
}
void create_main_menu(MenuData *m) {

View file

@ -158,7 +158,7 @@ int menu_loop(MenuData *menu) {
assert(menu->draw);
menu->draw(menu);
draw_transition();
draw_and_update_transition();
SDL_GL_SwapWindow(video.window);
frame_rate(&menu->lasttime);

View file

@ -26,7 +26,7 @@ void create_spell_menu(MenuData *m) {
m->flags = MF_Abortable;
m->transition = TransMenuDark;
for(StageInfo *stg = stages; stg->loop; ++stg) {
for(StageInfo *stg = stages; stg->procs; ++stg) {
if(stg->type != STAGE_SPELL) {
continue;
}

View file

@ -29,7 +29,7 @@ void create_stage_menu(MenuData *m) {
m->flags = MF_Abortable;
m->transition = TransMenuDark;
for(int i = 0; stages[i].loop; ++i) {
for(int i = 0; stages[i].procs; ++i) {
if(stages[i].difficulty < lastdiff || (stages[i].difficulty && !lastdiff)) {
add_menu_separator(m);
}

View file

@ -180,7 +180,7 @@ typedef struct cmd_writer_t {
static void progress_prepare_cmd_unlock_stages(size_t *bufsize, void **arg) {
int num_unlocked = 0;
for(StageInfo *stg = stages; stg->loop; ++stg) {
for(StageInfo *stg = stages; stg->procs; ++stg) {
StageProgress *p = stage_get_progress_from_info(stg, D_Any, false);
if(p && p->unlocked) {
++num_unlocked;
@ -205,7 +205,7 @@ static void progress_write_cmd_unlock_stages(SDL_RWops *vfile, void **arg) {
SDL_WriteU8(vfile, PCMD_UNLOCK_STAGES);
SDL_WriteLE16(vfile, num_unlocked * 2);
for(StageInfo *stg = stages; stg->loop; ++stg) {
for(StageInfo *stg = stages; stg->procs; ++stg) {
StageProgress *p = stage_get_progress_from_info(stg, D_Any, false);
if(p && p->unlocked) {
SDL_WriteLE16(vfile, stg->id);
@ -220,7 +220,7 @@ static void progress_write_cmd_unlock_stages(SDL_RWops *vfile, void **arg) {
static void progress_prepare_cmd_unlock_stages_with_difficulties(size_t *bufsize, void **arg) {
int num_unlocked = 0;
for(StageInfo *stg = stages; stg->loop; ++stg) {
for(StageInfo *stg = stages; stg->procs; ++stg) {
if(stg->difficulty)
continue;
@ -256,7 +256,7 @@ static void progress_write_cmd_unlock_stages_with_difficulties(SDL_RWops *vfile,
SDL_WriteU8(vfile, PCMD_UNLOCK_STAGES_WITH_DIFFICULTY);
SDL_WriteLE16(vfile, num_unlocked * 3);
for(StageInfo *stg = stages; stg->loop; ++stg) {
for(StageInfo *stg = stages; stg->procs; ++stg) {
if(stg->difficulty)
continue;
@ -325,7 +325,7 @@ static void progress_write(SDL_RWops *file) {
static void progress_unlock_all(void) {
StageInfo *stg;
for(stg = stages; stg->loop; ++stg) {
for(stg = stages; stg->procs; ++stg) {
for(Difficulty diff = D_Any; diff <= D_Lunatic; ++diff) {
StageProgress *p = stage_get_progress_from_info(stg, diff, true);
if(p) {

View file

@ -51,9 +51,6 @@ typedef struct Projectile {
int grazed;
} Projectile;
Color *rgba(float r, float g, float b, float a);
Color *rgb(float r, float g, float b);
#define create_particle3c(n,p,c,d,r,a1,a2,a3) create_particle4c(n,p,c,d,r,a1,a2,a3,0)
#define create_particle2c(n,p,c,d,r,a1,a2) create_particle4c(n,p,c,d,r,a1,a2,0,0)
#define create_particle1c(n,p,c,d,r,a1) create_particle4c(n,p,c,d,r,a1,0,0,0)

View file

@ -10,6 +10,7 @@
#define TSRAND_H
#include <stdint.h>
#include <stdbool.h>
typedef struct RandomState {
uint32_t w;

View file

@ -659,8 +659,7 @@ void replay_play(Replay *rpy, int firststage) {
continue;
}
global.stage = gstg;
gstg->loop();
stage_loop(gstg);
if(global.game_over == GAMEOVER_ABORT) {
break;

View file

@ -125,7 +125,7 @@ void load_resources(void) {
strcpy(path, get_prefix());
strcat(path, "shader/laser_snippets");
if(tgl_ext[TGLEXT_draw_instanced])
if(glext.draw_instanced)
load_shader_snippets(path, "laser_");
printf("init_fbo():\n");
@ -146,6 +146,13 @@ void load_resources(void) {
resources.state |= RS_ModelsLoaded;
}
if(!(resources.state & RS_FontsLoaded)) {
printf("- fonts:\n");
init_fonts();
resources.state |= RS_FontsLoaded;
}
free(path);
}

View file

@ -25,7 +25,8 @@ typedef enum ResourceState {
RS_SfxLoaded = 2,
RS_ShaderLoaded = 4,
RS_ModelsLoaded = 8,
RS_BgmLoaded = 16
RS_BgmLoaded = 16,
RS_FontsLoaded = 32,
} ResourceState;
struct Resources {

View file

@ -14,16 +14,44 @@
#include "list.h"
#include "taisei_err.h"
static char snippet_header_EXT_draw_instanced[] =
"#version 120\n"
"#extension GL_EXT_draw_instanced : enable\n"
;
static char snippet_header_ARB_draw_instanced[] =
"#version 120\n"
"#extension GL_ARB_draw_instanced : enable\n"
"#define gl_InstanceID gl_InstanceIDARB"
;
static char snippet_header_gl31[] =
"#version 140\n"
;
static char* get_snippet_header(void) {
if(glext.EXT_draw_instanced) {
return snippet_header_EXT_draw_instanced;
} else if(glext.ARB_draw_instanced) {
return snippet_header_ARB_draw_instanced;
} else {
// probably won't work
return snippet_header_gl31;
}
}
void print_info_log(GLuint shader) {
int len = 0, alen = 0;
glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &len);
if(len > 1) {
printf(" == GLSL Shader info log (shader %u) ==\n", shader);
char *log = malloc(len);
memset(log, 0, len);
glGetShaderInfoLog(shader, 256, &alen, log);
glGetShaderInfoLog(shader, len, &alen, log);
printf("%s\n", log);
free(log);
printf("\n == End of GLSL Shader info log (shader %u) ==\n", shader);
}
}
@ -32,11 +60,13 @@ void print_program_info_log(GLuint program) {
glGetProgramiv(program, GL_INFO_LOG_LENGTH, &len);
if(len > 1) {
printf(" == GLSL Program info log (program %u) ==\n", program);
char *log = malloc(len);
memset(log, 0, len);
glGetProgramInfoLog(program, 256, &alen, log);
glGetProgramInfoLog(program, len, &alen, log);
printf("%s\n", log);
free(log);
printf("\n == End of GLSL Program info log (program %u) ==\n", program);
}
}
@ -107,7 +137,6 @@ void load_shader_snippets(char *filename, char *prefix) {
if((vfoot == NULL) + (ffoot == NULL) != 1)
errx(-1, "Syntax Error: must contain exactly 1 FOOT section");
while((sec = strstr(sec, "%%"))) {
sec += 2;
@ -160,7 +189,7 @@ void load_shader_snippets(char *filename, char *prefix) {
strlcat(nbuf+prefixlen, name, nend-name+1);
nbuf[nend-name+prefixlen] = 0;
load_shader(vtext, ftext, nbuf, nend-name+prefixlen+1);
load_shader(get_snippet_header(), NULL, vtext, ftext, nbuf, nend-name+prefixlen+1);
printf("--- loaded snippet as shader '%s'\n", nbuf);
free(nbuf);
@ -197,7 +226,7 @@ void load_shader_file(char *filename) {
name = malloc(sz);
strlcpy(name, beg, sz);
load_shader(vtext, ftext, name, sz);
load_shader(NULL, NULL, vtext, ftext, name, sz);
printf("-- loaded '%s' as '%s'\n", filename, name);
@ -205,7 +234,7 @@ void load_shader_file(char *filename) {
free(text);
}
void load_shader(char *vtext, char *ftext, char *name, int nsize) {
void load_shader(char *vheader, char *fheader, char *vtext, char *ftext, char *name, int nsize) {
Shader *sha = create_element((void **)&resources.shaders, sizeof(Shader));
GLuint vshaderobj;
GLuint fshaderobj;
@ -214,10 +243,20 @@ void load_shader(char *vtext, char *ftext, char *name, int nsize) {
vshaderobj = glCreateShader(GL_VERTEX_SHADER);
fshaderobj = glCreateShader(GL_FRAGMENT_SHADER);
int s = -1;
if(!vheader) {
vheader = "";
}
glShaderSource(vshaderobj, 1, (const GLchar **)&vtext, &s);
glShaderSource(fshaderobj, 1, (const GLchar **)&ftext, &s);
if(!fheader) {
fheader = "";
}
GLchar *v_sources[] = { vheader, vtext };
GLchar *f_sources[] = { fheader, ftext };
GLint lengths[] = { -1, -1 };
glShaderSource(vshaderobj, 2, (const GLchar**)v_sources, lengths);
glShaderSource(fshaderobj, 2, (const GLchar**)f_sources, lengths);
glCompileShader(vshaderobj);
glCompileShader(fshaderobj);

View file

@ -37,7 +37,7 @@ typedef struct Shader {
void load_shader_snippets(char *filename, char *prefix);
void load_shader_file(char *filename);
void load_shader(char *vtext, char *ftext, char *name, int nsize);
void load_shader(char *vheader, char *fheader, char *vtext, char *ftext, char *name, int nsize);
Shader *get_shader(const char *name);
void delete_shaders(void);

View file

@ -15,20 +15,6 @@
#include "list.h"
#include "vbo.h"
Color *rgba(float r, float g, float b, float a) {
Color *clr = malloc(sizeof(Color));
clr->r = r;
clr->g = g;
clr->b = b;
clr->a = a;
return clr;
}
Color *rgb(float r, float g, float b) {
return rgba(r, g, b, 1.0);
}
Texture *get_tex(char *name) {
Texture *t, *res = NULL;
for(t = resources.textures; t; t = t->next) {

View file

@ -10,13 +10,7 @@
#include <SDL.h>
#include "taiseigl.h"
typedef struct {
float r;
float g;
float b;
float a;
} Color;
#include "color.h"
typedef struct Texture Texture;

View file

@ -5,7 +5,7 @@
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include <complex.h>
#include <assert.h>
#include "stage.h"
#include "tscomplex.h"
@ -21,286 +21,133 @@
#include "menu/gameovermenu.h"
#include "taisei_err.h"
StageInfo stages[] = {
//
// ids must be unique
// they don't necessarily have to be human-readable or ordered
// they're basically there just for replays, so don't change the already enstabilished ones unless you must
//
static size_t numstages = 0;
StageInfo *stages = NULL;
//
// Story stages
//
static void add_stage(uint16_t id, StageProcs *procs, StageType type, const char *title, const char *subtitle, AttackInfo *spell, Difficulty diff, Color *titleclr, Color *bosstitleclr) {
++numstages;
stages = realloc(stages, numstages * sizeof(StageInfo));
StageInfo *stg = stages + (numstages - 1);
memset(stg, 0, sizeof(StageInfo));
// id loop type title subtitle titleclr bosstitleclr spell difficulty
{1, stage1_loop, STAGE_STORY, "Stage 1", "Misty Lake", {1, 1, 1}, {1, 1, 1}, NULL, D_Any},
{2, stage2_loop, STAGE_STORY, "Stage 2", "Walk Along the Border", {1, 1, 1}, {1, 1, 1}, NULL, D_Any},
{3, stage3_loop, STAGE_STORY, "Stage 3", "Through the Tunnel of Light", {0, 0, 0}, {0, 0, 0}, NULL, D_Any},
{4, stage4_loop, STAGE_STORY, "Stage 4", "Forgotten Mansion", {0, 0, 0}, {1, 1, 1}, NULL, D_Any},
{5, stage5_loop, STAGE_STORY, "Stage 5", "Climbing the Tower of Babel", {1, 1, 1}, {1, 1, 1}, NULL, D_Any},
{6, stage6_loop, STAGE_STORY, "Stage 6", "Roof of the World", {1, 1, 1}, {1, 1, 1}, NULL, D_Any},
stg->id = id;
stg->procs = procs;
stg->type = type;
stralloc(&stg->title, title);
stralloc(&stg->subtitle, subtitle);
stg->spell = spell;
stg->difficulty = diff;
//
// Spell practice stages
//
// titles and subtitles for those are generated later by stage_init_array()
//
if(titleclr) {
memcpy(&stg->titleclr, titleclr, sizeof(Color));
}
#define S STAGE_SPELL_BIT
#define E (STAGE_SPELL_BIT | STAGE_EXTRASPELL_BIT)
if(bosstitleclr) {
memcpy(&stg->bosstitleclr, titleclr, sizeof(Color));
}
// Freeze Sign ~ Perfect Freeze
{S| 0, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Easy},
{S| 1, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Normal},
{S| 2, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Hard},
{S| 3, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Lunatic},
free(titleclr);
free(bosstitleclr);
// Freeze Sign ~ Crystal Rain
{S| 4, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Easy},
{S| 5, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Normal},
{S| 6, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Hard},
{S| 7, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Lunatic},
#ifdef DEBUG
if(title && subtitle) {
fprintf(stderr, "Added stage 0x%04x: %s: %s\n", id, title, subtitle);
}
#endif
}
// Doom Sign ~ Icicle Fall
{S| 8, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Easy},
{S| 9, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Normal},
{S| 10, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Hard},
{S| 11, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Lunatic},
static void end_stages() {
add_stage(0, NULL, 0, NULL, NULL, NULL, 0, NULL, NULL);
}
// Shard ~ Amulet of Harm
{S| 12, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Easy},
{S| 13, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Normal},
{S| 14, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Hard},
{S| 15, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Lunatic},
static void add_spellpractice_stages(int *spellnum, bool (*filter)(AttackInfo*), uint16_t spellbits) {
for(int i = 0 ;; ++i) {
StageInfo *s = stages + i;
// Lottery Sign ~ Bad Pick
{S| 16, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Easy},
{S| 17, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Normal},
{S| 18, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Hard},
{S| 19, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Lunatic},
if(s->type == STAGE_SPELL) {
break;
}
// Lottery Sign ~ Wheel of Fortune
{S| 20, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Easy},
{S| 21, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Normal},
{S| 22, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Hard},
{S| 23, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Lunatic},
for(AttackInfo *a = s->spell; a->rule; ++a) {
if(!filter(a)) {
continue;
}
// Venom Sign ~ Deadly Dance
{S| 24, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Easy},
{S| 25, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Normal},
{S| 26, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Hard},
{S| 27, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Lunatic},
for(Difficulty diff = D_Easy; diff < D_Easy + NUM_SELECTABLE_DIFFICULTIES; ++diff) {
if(a->idmap[diff - D_Easy] >= 0) {
uint16_t id = spellbits | a->idmap[diff - D_Easy] | (s->id << 8);
// Venom Sign ~ Acid Rain
{S| 28, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+1, D_Hard},
{S| 29, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+1, D_Lunatic},
char title[10];
const char *postfix = difficulty_name(diff);
// Firefly Sign ~ Moonlight Rocket
{S| 30, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Easy},
{S| 31, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Normal},
{S| 32, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Hard},
{S| 33, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Lunatic},
snprintf(title, sizeof(title), "Spell %d", ++(*spellnum));
// Light Source ~ Wriggle Night Ignite
{S| 34, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Easy},
{S| 35, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Normal},
{S| 36, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Hard},
{S| 37, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Lunatic},
char subtitle[strlen(postfix) + strlen(a->name) + 4];
strcpy(subtitle, a->name);
strcat(subtitle, " ~ ");
strcat(subtitle, postfix);
// Bug Sign ~ Phosphaenus Hemipterus
{S| 38, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Easy},
{S| 39, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Normal},
{S| 40, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Hard},
{S| 41, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Lunatic},
add_stage(id, s->procs->spellpractice_procs, STAGE_SPELL, title, subtitle, a, diff, NULL, NULL);
s = stages + i; // stages just got realloc'd, so we must update the pointer
}
}
}
}
}
// Bloodless ~ Gate of Walachia
{S| 42, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Easy},
{S| 43, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Normal},
{S| 44, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Hard},
{S| 45, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Lunatic},
static bool spellfilter_normal(AttackInfo *spell) {
return spell->type != AT_ExtraSpell;
}
// Bloodless ~ Dry Fountain
{S| 46, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+1, D_Easy},
{S| 47, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+1, D_Normal},
// Bloodless ~ Red Spike
{S| 48, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+2, D_Hard},
{S| 49, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+2, D_Lunatic},
// Limit ~ Animate Wall
{S| 50, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+3, D_Easy},
{S| 51, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+3, D_Normal},
// Summoning ~ Demon Wall
{S| 52, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+4, D_Hard},
{S| 53, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+4, D_Lunatic},
// Power Sign ~ Blow the Walls
{S| 54, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Easy},
{S| 55, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Normal},
{S| 56, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Hard},
{S| 57, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Lunatic},
// Fear Sign ~ Bloody Danmaku
{S| 58, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+6, D_Hard},
{S| 59, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+6, D_Lunatic},
// High Voltage ~ Atmospheric Discharge
{S| 60, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Easy},
{S| 61, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Normal},
{S| 62, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Hard},
{S| 63, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Lunatic},
// Charge Sign ~ Artificial Lightning
{S| 64, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Easy},
{S| 65, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Normal},
{S| 66, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Hard},
{S| 67, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Lunatic},
// Spark Sign ~ Natural Cathode
{S| 68, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Easy},
{S| 69, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Normal},
{S| 70, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Hard},
{S| 71, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Lunatic},
// Current Sign ~ Induction
{S| 72, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+3, D_Easy},
{S| 73, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+3, D_Normal},
{S| 74, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+3, D_Hard},
{S| 75, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+3, D_Lunatic},
// Newton Sign ~ 2.5 Laws of Movement
{S| 76, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Easy},
{S| 77, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Normal},
{S| 78, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Hard},
{S| 79, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Lunatic},
// Maxwell Sign ~ Wave Theory
{S| 80, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Easy},
{S| 81, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Normal},
{S| 82, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Hard},
{S| 83, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Lunatic},
// Eigenstate ~ Many-World Interpretation
{S| 84, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Easy},
{S| 85, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Normal},
{S| 86, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Hard},
{S| 87, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Lunatic},
// Ricci Sign ~ Space Time Curvature
{S| 88, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Easy},
{S| 89, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Normal},
{S| 90, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Hard},
{S| 91, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Lunatic},
// LHC ~ Higgs Boson Uncovered
{S| 92, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+4, D_Easy},
{S| 93, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+4, D_Normal},
{S| 94, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+4, D_Hard},
{S| 95, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+4, D_Lunatic},
// Tower of Truth ~ Theory of Everything
{S| 96, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Easy},
{S| 97, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Normal},
{S| 98, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Hard},
{S| 99, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Lunatic},
//
// Extra spells
//
// Frost Sign ~ Crystal Blizzard
{E| 0, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+3, D_Easy},
{E| 1, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+3, D_Normal},
{E| 2, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+3, D_Hard},
{E| 3, stage1_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+3, D_Lunatic},
// Lottery Sign ~ Monty Hall Danmaku
{E| 4, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+3, D_Easy},
{E| 5, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+3, D_Normal},
{E| 6, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+3, D_Hard},
{E| 7, stage2_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+3, D_Lunatic},
// Firefly Sign ~ Moonlight Wraith
{E| 8, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+5, D_Easy},
{E| 9, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+5, D_Normal},
{E| 10, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+5, D_Hard},
{E| 11, stage3_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+5, D_Lunatic},
// RESERVED
/*
{E| 12, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {1, 1, 1}, stage4_spells+7, D_Easy},
{E| 13, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {1, 1, 1}, stage4_spells+7, D_Normal},
{E| 14, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {1, 1, 1}, stage4_spells+7, D_Hard},
{E| 15, stage4_spellpractice_loop, STAGE_SPELL, NULL, NULL, {0, 0, 0}, {1, 1, 1}, stage4_spells+7, D_Lunatic},
*/
// Circuit Sign ~ Overload
{E| 16, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+4, D_Easy},
{E| 17, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+4, D_Normal},
{E| 18, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+4, D_Hard},
{E| 19, stage5_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+4, D_Lunatic},
// RESERVED
{E| 20, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+6, D_Easy},
{E| 21, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+6, D_Normal},
{E| 22, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+6, D_Hard},
{E| 23, stage6_spellpractice_loop, STAGE_SPELL, NULL, NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+6, D_Lunatic},
#undef E
#undef S
{0}
};
static bool spellfilter_extra(AttackInfo *spell) {
return spell->type == AT_ExtraSpell;
}
void stage_init_array(void) {
int spellnum = 0;
for(int i = 0; stages[i].loop; ++i) {
// we will allocate this later on demand
stages[i].progress = NULL;
// id procs type title subtitle spells diff titleclr bosstitleclr
add_stage(1, &stage1_procs, STAGE_STORY, "Stage 1", "Misty Lake", stage1_spells, D_Any, rgb(1, 1, 1), rgb(1, 1, 1));
add_stage(2, &stage2_procs, STAGE_STORY, "Stage 2", "Walk Along the Border", stage2_spells, D_Any, rgb(1, 1, 1), rgb(1, 1, 1));
add_stage(3, &stage3_procs, STAGE_STORY, "Stage 3", "Through the Tunnel of Light", stage3_spells, D_Any, rgb(0, 0, 0), rgb(0, 0, 0));
add_stage(4, &stage4_procs, STAGE_STORY, "Stage 4", "Forgotten Mansion", stage4_spells, D_Any, rgb(0, 0, 0), rgb(1, 1, 1));
add_stage(5, &stage5_procs, STAGE_STORY, "Stage 5", "Climbing the Tower of Babel", stage5_spells, D_Any, rgb(1, 1, 1), rgb(1, 1, 1));
add_stage(6, &stage6_procs, STAGE_STORY, "Stage 6", "Roof of the World", stage6_spells, D_Any, rgb(1, 1, 1), rgb(1, 1, 1));
if(stages[i].type == STAGE_SPELL) {
char *s, title[10], *postfix = difficulty_name(stages[i].difficulty);
// generate spellpractice stages
add_spellpractice_stages(&spellnum, spellfilter_normal, STAGE_SPELL_BIT);
add_spellpractice_stages(&spellnum, spellfilter_extra, STAGE_SPELL_BIT | STAGE_EXTRASPELL_BIT);
snprintf(title, sizeof(title), "Spell %d", ++spellnum);
stralloc(&stages[i].title, title);
stages[i].subtitle = s = malloc(strlen(postfix) + strlen(stages[i].spell->name) + 4);
strcpy(s, stages[i].spell->name);
strcat(s, " ~ ");
strcat(s, postfix);
}
end_stages();
#ifdef DEBUG
for(int i = 0; stages[i].procs; ++i) {
if(stages[i].type == STAGE_SPELL && !(stages[i].id & STAGE_SPELL_BIT)) {
errx(-1, "Spell stage has an ID without the spell bit set: %u", stages[i].id);
errx(-1, "Spell stage has an ID without the spell bit set: 0x%04x", stages[i].id);
}
for(int j = 0; stages[j].loop; ++j) {
for(int j = 0; stages[j].procs; ++j) {
if(i != j && stages[i].id == stages[j].id) {
errx(-1, "Duplicate ID in stages array: %u", stages[i].id);
errx(-1, "Duplicate ID 0x%04x in stages array, indices: %i, %i", stages[i].id, i, j);
}
}
#endif
}
#endif
}
void stage_free_array(void) {
for(StageInfo *stg = stages; stg->loop; ++stg) {
if(stg->type == STAGE_SPELL) {
free(stg->subtitle);
}
for(StageInfo *stg = stages; stg->procs; ++stg) {
free(stg->title);
free(stg->subtitle);
free(stg->progress);
}
free(stages);
}
// NOTE: This returns the stage BY ID, not by the array index!
StageInfo* stage_get(uint16_t n) {
for(StageInfo *stg = stages; stg->loop; ++stg)
for(StageInfo *stg = stages; stg->procs; ++stg)
if(stg->id == n)
return stg;
return NULL;
@ -310,7 +157,7 @@ StageInfo* stage_get_by_spellcard(AttackInfo *spell, Difficulty diff) {
if(!spell)
return NULL;
for(StageInfo *stg = stages; stg->loop; ++stg)
for(StageInfo *stg = stages; stg->procs; ++stg)
if(stg->spell == spell && stg->difficulty == diff)
return stg;
@ -354,7 +201,7 @@ StageProgress* stage_get_progress(uint16_t id, Difficulty diff, bool allocate) {
return stage_get_progress_from_info(stage_get(id), diff, allocate);
}
void stage_start(void) {
static void stage_start(StageInfo *stage) {
global.timer = 0;
global.frames = 0;
global.stageuiframes = 0;
@ -366,6 +213,11 @@ void stage_start(void) {
global.fps.fpstime = SDL_GetTicks();
prepare_player_for_next_stage(&global.plr);
if(stage->type == STAGE_SPELL) {
global.plr.lifes = 0;
global.plr.bombs = 0;
}
}
void stage_pause(void) {
@ -378,11 +230,20 @@ void stage_pause(void) {
void stage_gameover(void) {
MenuData menu;
save_bgm();
start_bgm("bgm_gameover");
create_gameover_menu(&menu);
bool interrupt_bgm = (global.stage->type != STAGE_SPELL);
if(interrupt_bgm) {
save_bgm();
start_bgm("bgm_gameover");
}
menu_loop(&menu);
restore_bgm();
if(interrupt_bgm) {
restore_bgm();
}
}
void stage_input_event(EventType type, int key, void *arg) {
@ -390,7 +251,7 @@ void stage_input_event(EventType type, int key, void *arg) {
case E_PlrKeyDown:
if(key == KEY_HAHAIWIN) {
#ifdef DEBUG
global.game_over = GAMEOVER_WIN;
stage_finish(GAMEOVER_WIN);
#endif
break;
}
@ -494,7 +355,8 @@ void stage_input(void) {
void draw_hud(void) {
draw_texture(SCREEN_W/2.0, SCREEN_H/2.0, "hud");
char buf[16], *diff;
char buf[16];
const char *diff;
int i;
glPushMatrix();
@ -583,12 +445,15 @@ void draw_hud(void) {
draw_texture(VIEWPORT_X+creal(global.boss->pos), 590, "boss_indicator");
}
void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int time) {
static void apply_bg_shaders(ShaderRule *shaderrules);
static void draw_stage_title(StageInfo *info);
static void stage_draw(StageInfo *stage) {
if(!config_get_int(CONFIG_NO_SHADER)) {
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[0].fbo);
glViewport(0,0,SCREEN_W,SCREEN_H);
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(-(VIEWPORT_X+VIEWPORT_W/2.0), -(VIEWPORT_Y+VIEWPORT_H/2.0),0);
@ -605,7 +470,7 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
global.nostagebg = true;
if(!global.nostagebg)
bgdraw();
stage->procs->draw();
glPopMatrix();
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -616,7 +481,7 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
glTranslatef(VIEWPORT_X,VIEWPORT_Y,0);
if(!config_get_int(CONFIG_NO_SHADER))
apply_bg_shaders(shaderrules);
apply_bg_shaders(stage->procs->shader_rules);
if(global.boss) {
glPushMatrix();
@ -654,7 +519,8 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
if(global.dialog)
draw_dialog(global.dialog);
draw_stage_title(info);
if(stage->type != STAGE_SPELL)
draw_stage_title(stage);
if(!config_get_int(CONFIG_NO_SHADER)) {
glBindFramebuffer(GL_FRAMEBUFFER, 0);
@ -678,17 +544,13 @@ void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int
glPopMatrix();
draw_hud();
draw_transition();
}
int apply_shaderrules(ShaderRule *shaderrules, int fbonum) {
int i;
static int apply_shaderrules(ShaderRule *shaderrules, int fbonum) {
if(!global.nostagebg) {
for(i = 0; shaderrules != NULL && shaderrules[i] != NULL; i++) {
for(ShaderRule *rule = shaderrules; *rule; ++rule) {
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[!fbonum].fbo);
shaderrules[i](fbonum);
(*rule)(fbonum);
fbonum = !fbonum;
}
}
@ -696,7 +558,7 @@ int apply_shaderrules(ShaderRule *shaderrules, int fbonum) {
return fbonum;
}
void apply_bg_shaders(ShaderRule *shaderrules) {
static void apply_bg_shaders(ShaderRule *shaderrules) {
int fbonum = 0;
if(global.boss && global.boss->current && global.boss->current->draw_rule) {
@ -769,7 +631,7 @@ void apply_bg_shaders(ShaderRule *shaderrules) {
}
}
void stage_logic(int time) {
static void stage_logic(void) {
player_logic(&global.plr);
process_enemies(&global.enemies);
@ -790,18 +652,12 @@ void stage_logic(int time) {
if(!global.dialog && !global.boss)
global.timer++;
if(global.timer == time - FADE_TIME ||
(
global.replaymode == REPLAY_PLAY &&
global.frames == global.replay_stage->events[global.replay_stage->numevents-1].frame - FADE_TIME
)
) {
set_transition(TransFadeBlack, FADE_TIME, FADE_TIME*2);
if(global.replaymode == REPLAY_PLAY &&
global.frames == global.replay_stage->events[global.replay_stage->numevents-1].frame - FADE_TIME &&
global.game_over != GAMEOVER_TRANSITIONING) {
stage_finish(GAMEOVER_DEFEAT);
}
if(time && global.timer >= time)
global.game_over = GAMEOVER_WIN;
// BGM handling
if(global.dialog && global.dialog->messages[global.dialog->pos].side == BGM) {
start_bgm(global.dialog->messages[global.dialog->pos].msg);
@ -809,7 +665,7 @@ void stage_logic(int time) {
}
}
void stage_end(void) {
static void stage_free(void) {
delete_enemies(&global.enemies);
delete_items();
delete_lasers();
@ -828,7 +684,25 @@ void stage_end(void) {
}
}
void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event, ShaderRule *shaderrules, int endtime, char *bgmname) {
static void stage_finalize(void *arg) {
global.game_over = (intptr_t)arg;
}
void stage_finish(int gameover) {
assert(global.game_over != GAMEOVER_TRANSITIONING);
global.game_over = GAMEOVER_TRANSITIONING;
set_transition_callback(TransFadeBlack, FADE_TIME, FADE_TIME*2, stage_finalize, (void*)(intptr_t)gameover);
}
void stage_loop(StageInfo *stage) {
assert(stage);
assert(stage->procs);
assert(stage->procs->begin);
assert(stage->procs->end);
assert(stage->procs->draw);
assert(stage->procs->event);
assert(stage->procs->shader_rules);
if(global.game_over == GAMEOVER_WIN) {
global.game_over = 0;
} else if(global.game_over) {
@ -836,16 +710,16 @@ void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event,
}
// I really want to separate all of the game state from the global struct sometime
StageInfo *info = global.stage;
global.stage = stage;
uint32_t seed = (uint32_t)time(0);
tsrand_switch(&global.rand_game);
tsrand_seed_p(&global.rand_game, seed);
stage_start();
stage_start(stage);
if(global.replaymode == REPLAY_RECORD) {
if(config_get_int(CONFIG_SAVE_RPY)) {
global.replay_stage = replay_create_stage(&global.replay, info, seed, global.diff, global.plr.points, &global.plr);
global.replay_stage = replay_create_stage(&global.replay, stage, seed, global.diff, global.plr.points, &global.plr);
// make sure our player state is consistent with what goes into the replay
init_player(&global.plr);
@ -855,11 +729,6 @@ void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event,
}
printf("Random seed: %u\n", seed);
if(info->type == STAGE_SPELL) {
global.plr.lifes = 0;
global.plr.bombs = 0;
}
} else {
if(!global.replay_stage) {
errx(-1, "Attemped to replay a NULL stage");
@ -890,27 +759,35 @@ void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event,
player_set_power(&global.plr, power);
start();
start_bgm(bgmname);
stage->procs->begin();
if(info->type == STAGE_SPELL) {
endtime = 0;
}
int transition_delay = 0;
while(global.game_over <= 0) {
if(!global.boss && !global.dialog)
event();
if(global.game_over != GAMEOVER_TRANSITIONING) {
if(!global.boss && !global.dialog) {
stage->procs->event();
}
if(!endtime && info->type == STAGE_SPELL && !global.boss) {
endtime = global.timer + 60;
if(stage->type == STAGE_SPELL && !global.boss) {
stage_finish(GAMEOVER_WIN);
transition_delay = 60;
}
}
((global.replaymode == REPLAY_PLAY) ? replay_input : stage_input)();
replay_stage_check_desync(global.replay_stage, global.frames, (tsrand() ^ global.plr.points) & 0xFFFF, global.replaymode);
stage_logic(endtime);
stage_logic();
if(transition_delay) {
--transition_delay;
}
if(global.frameskip && global.frames % global.frameskip) {
if(!transition_delay) {
update_transition();
}
continue;
}
@ -918,11 +795,14 @@ void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event,
tsrand_lock(&global.rand_game);
tsrand_switch(&global.rand_visual);
stage_draw(info, draw, shaderrules, endtime);
stage_draw(stage);
tsrand_unlock(&global.rand_game);
tsrand_switch(&global.rand_game);
// print_state_checksum();
draw_transition();
if(!transition_delay) {
update_transition();
}
SDL_GL_SwapWindow(video.window);
@ -937,13 +817,12 @@ void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event,
replay_stage_event(global.replay_stage, global.frames, EV_OVER, 0);
}
end();
stage_end();
stage->procs->end();
stage_free();
tsrand_switch(&global.rand_visual);
global.stage = NULL;
}
void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const char *text, TTF_Font *font, Color *color) {
static void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const char *text, TTF_Font *font, Color *color) {
int i;
float f = 0;
if(t < 30 || t > 220)
@ -974,7 +853,7 @@ void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const char *
glUseProgram(0);
}
void draw_stage_title(StageInfo *info) {
static void draw_stage_title(StageInfo *info) {
int t = global.stageuiframes;
draw_title(t, info, AL_Center, VIEWPORT_W/2, VIEWPORT_H/2-40, info->title, _fonts.mainmenu, &info->titleclr);

View file

@ -8,6 +8,12 @@
#ifndef STAGE_H
#define STAGE_H
#include <stdbool.h>
#include "projectile.h"
#include "boss.h"
#include "progress.h"
#include "difficulty.h"
/* taisei's strange macro language.
*
* sorry, I guess it is bad style, but I hardcode everything and in that case
@ -17,22 +23,6 @@
*
*/
#include <stdbool.h>
#include "projectile.h"
#include "boss.h"
#include "progress.h"
typedef enum {
D_Any = 0,
D_Easy,
D_Normal,
D_Hard,
D_Lunatic,
D_Extra // reserved for later
} Difficulty;
#define NUM_SELECTABLE_DIFFICULTIES D_Lunatic
#define TIMER(ptr) int *__timep = ptr; int _i = 0, _ni = 0; _i = _ni = _i;
#define AT(t) if(*__timep == t)
#define FROM_TO(start,end,step) _ni = _ni; _i = (*__timep - (start))/(step); if(*__timep >= (start) && *__timep <= (end) && !((*__timep - (start)) % (step)))
@ -43,7 +33,7 @@ typedef enum {
#define GO_AT(obj, start, end, vel) if(*__timep >= (start) && *__timep <= (end)) (obj)->pos += (vel);
#define GO_TO(obj, p, f) (obj)->pos += (f)*((p) - (obj)->pos);
typedef void (*StageRule)(void);
typedef void (*StageProc)(void);
typedef void (*ShaderRule)(int);
// two highest bits of uint16_t, WAY higher than the amount of spells in this game can ever possibly be
@ -56,27 +46,34 @@ typedef enum StageType {
STAGE_SPELL,
} StageType;
typedef struct StageInfo {
//
// don't reorder these!
//
typedef struct StageProcs StageProcs;
struct StageProcs {
StageProc begin;
StageProc end;
StageProc draw;
StageProc event;
ShaderRule *shader_rules;
StageProcs *spellpractice_procs;
};
typedef struct StageInfo {
uint16_t id; // must match type of ReplayStage.stage in replay.h
StageRule loop;
StageProcs *procs;
StageType type;
char *title;
char *subtitle;
Color titleclr;
Color bosstitleclr;
AttackInfo *spell;
Difficulty difficulty;
Color titleclr;
Color bosstitleclr;
// Do NOT access this directly!
// Use stage_get_progress or stage_get_progress_from_info, which will lazy-initialize it and pick the correct offset.
StageProgress *progress;
} StageInfo;
extern StageInfo stages[];
extern StageInfo *stages;
StageInfo* stage_get(uint16_t);
StageInfo* stage_get_by_spellcard(AttackInfo *spell, Difficulty diff);
@ -87,11 +84,9 @@ StageProgress* stage_get_progress_from_info(StageInfo *stage, Difficulty diff, b
void stage_init_array(void);
void stage_free_array(void);
void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event, ShaderRule *shaderrules, int endtime, char *bgmname);
void stage_loop(StageInfo *stage);
void stage_finish(int gameover);
void apply_bg_shaders(ShaderRule *shaderrules);
void draw_stage_title(StageInfo *info);
void draw_hud(void);
void stage_pause(void);

View file

@ -19,11 +19,21 @@ void cirno_icicle_fall(Boss*, int);
void cirno_pfreeze_bg(Boss*, int);
void cirno_crystal_blizzard(Boss*, int);
/*
* See the definition of AttackInfo in boss.h for information on how to set up the idmaps.
*/
AttackInfo stage1_spells[] = {
{AT_Spellcard, "Freeze Sign ~ Perfect Freeze", 32, 20000, cirno_perfect_freeze, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{AT_Spellcard, "Freeze Sign ~ Crystal Rain", 28, 28000, cirno_crystal_rain, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{AT_Spellcard, "Doom Sign ~ Icicle Fall", 35, 40000, cirno_icicle_fall, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{AT_ExtraSpell, "Frost Sign ~ Crystal Blizzard", 60, 40000, cirno_crystal_blizzard, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{{ 0, 1, 2, 3}, AT_Spellcard, "Freeze Sign ~ Perfect Freeze", 32, 20000,
cirno_perfect_freeze, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{{ 4, 5, 6, 7}, AT_Spellcard, "Freeze Sign ~ Crystal Rain", 28, 28000,
cirno_crystal_rain, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{{ 8, 9, 10, 11}, AT_Spellcard, "Doom Sign ~ Icicle Fall", 35, 40000,
cirno_icicle_fall, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{{ 0, 1, 2, 3}, AT_ExtraSpell, "Frost Sign ~ Crystal Blizzard", 60, 40000,
cirno_crystal_blizzard, cirno_pfreeze_bg, VIEWPORT_W/2.0+100.0*I},
{{0}}
};
Dialog *stage1_dialog(void) {
@ -631,6 +641,10 @@ int stage1_tritoss(Enemy *e, int t) {
void stage1_events(void) {
TIMER(&global.timer);
AT(0) {
start_bgm("bgm_stage1");
}
/*
// graze testing
AT(0) {
@ -726,6 +740,9 @@ void stage1_events(void) {
AT(5000)
global.boss = create_cirno();
AT(5200 - FADE_TIME) {
stage_finish(GAMEOVER_WIN);
}
}
void stage1_start(void) {
@ -742,11 +759,6 @@ void stage1_end(void) {
free_stage3d(&bgcontext);
}
void stage1_loop(void) {
ShaderRule list[] = { stage1_fog, NULL };
stage_loop(stage1_start, stage1_end, stage1_draw, stage1_events, list, 5200, "bgm_stage1");
}
void stage1_spellpractice_events(void) {
TIMER(&global.timer);
@ -755,10 +767,26 @@ void stage1_spellpractice_events(void) {
boss_add_attack_from_info(cirno, global.stage->spell, true);
start_attack(cirno, cirno->attacks);
global.boss = cirno;
start_bgm("bgm_stage1boss");
}
}
void stage1_spellpractice_loop(void) {
ShaderRule list[] = { stage1_fog, NULL };
stage_loop(stage1_start, stage1_end, stage1_draw, stage1_spellpractice_events, list, 0, "bgm_stage1boss");
}
ShaderRule stage1_shaders[] = { stage1_fog, NULL };
StageProcs stage1_procs = {
.begin = stage1_start,
.end = stage1_end,
.draw = stage1_draw,
.event = stage1_events,
.shader_rules = stage1_shaders,
.spellpractice_procs = &stage1_spell_procs,
};
StageProcs stage1_spell_procs = {
.begin = stage1_start,
.end = stage1_end,
.draw = stage1_draw,
.event = stage1_spellpractice_events,
.shader_rules = stage1_shaders,
};

View file

@ -8,11 +8,10 @@
#ifndef STAGE1_H
#define STAGE1_H
#include "boss.h"
void stage1_loop(void);
void stage1_spellpractice_loop(void);
#include "stage.h"
extern StageProcs stage1_procs;
extern StageProcs stage1_spell_procs;
extern AttackInfo stage1_spells[];
#endif

View file

@ -158,11 +158,6 @@ void stage2_draw(void) {
}
void stage2_loop(void) {
ShaderRule shaderrules[] = { stage2_fog, stage2_bloom, NULL };
stage_loop(stage2_start, stage2_end, stage2_draw, stage2_events, shaderrules, 5240, "bgm_stage2");
}
void stage2_spellpractice_events(void) {
TIMER(&global.timer);
@ -173,10 +168,26 @@ void stage2_spellpractice_events(void) {
boss_add_attack_from_info(hina, global.stage->spell, true);
start_attack(hina, hina->attacks);
global.boss = hina;
start_bgm("bgm_stage2boss");
}
}
void stage2_spellpractice_loop(void) {
ShaderRule shaderrules[] = { stage2_fog, stage2_bloom, NULL };
stage_loop(stage2_start, stage2_end, stage2_draw, stage2_spellpractice_events, shaderrules, 0, "bgm_stage2boss");
}
ShaderRule stage2_shaders[] = { stage2_fog, stage2_bloom, NULL };
StageProcs stage2_procs = {
.begin = stage2_start,
.end = stage2_end,
.draw = stage2_draw,
.event = stage2_events,
.shader_rules = stage2_shaders,
.spellpractice_procs = &stage2_spell_procs,
};
StageProcs stage2_spell_procs = {
.begin = stage2_start,
.end = stage2_end,
.draw = stage2_draw,
.event = stage2_spellpractice_events,
.shader_rules = stage2_shaders,
};

View file

@ -8,11 +8,10 @@
#ifndef STAGE2_H
#define STAGE2_H
#include "boss.h"
void stage2_loop(void);
void stage2_spellpractice_loop(void);
#include "stage.h"
extern StageProcs stage2_procs;
extern StageProcs stage2_spell_procs;
extern AttackInfo stage2_spells[];
#endif

View file

@ -16,11 +16,21 @@ void hina_bad_pick(Boss*, int);
void hina_wheel(Boss*, int);
void hina_monty(Boss*, int);
/*
* See the definition of AttackInfo in boss.h for information on how to set up the idmaps.
*/
AttackInfo stage2_spells[] = {
{AT_Spellcard, "Shard ~ Amulet of Harm", 26, 25000, hina_amulet, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Lottery Sign ~ Bad Pick", 30, 36000, hina_bad_pick, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Lottery Sign ~ Wheel of Fortune", 20, 36000, hina_wheel, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_ExtraSpell, "Lottery Sign ~ Monty Hall Danmaku", 60, 60000, hina_monty, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_Spellcard, "Shard ~ Amulet of Harm", 26, 25000,
hina_amulet, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 4, 5, 6, 7}, AT_Spellcard, "Lottery Sign ~ Bad Pick", 30, 36000,
hina_bad_pick, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 8, 9, 10, 11}, AT_Spellcard, "Lottery Sign ~ Wheel of Fortune", 20, 36000,
hina_wheel, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_ExtraSpell, "Lottery Sign ~ Monty Hall Danmaku", 60, 60000,
hina_monty, hina_spell_bg, BOSS_DEFAULT_GO_POS},
{{0}}
};
Dialog *stage2_dialog(void) {
@ -576,4 +586,8 @@ void stage2_events(void) {
AT(5180) {
global.dialog = stage2_post_dialog();
}
AT(5240 - FADE_TIME) {
stage_finish(GAMEOVER_WIN);
}
}

View file

@ -274,11 +274,6 @@ void stage3_draw(void) {
draw_stage3d(&bgcontext, 7000);
}
void stage3_loop(void) {
ShaderRule shaderrules[] = { stage3_fog, stage3_tunnel, NULL };
stage_loop(stage3_start, stage3_end, stage3_draw, stage3_events, shaderrules, 5700, "bgm_stage3");
}
void stage3_mid_spellbg(Boss*, int t);
void stage3_spellpractice_events(void) {
@ -295,10 +290,26 @@ void stage3_spellpractice_events(void) {
boss_add_attack_from_info(global.boss, global.stage->spell, true);
start_attack(global.boss, global.boss->attacks);
start_bgm("bgm_stage3boss");
}
}
void stage3_spellpractice_loop(void) {
ShaderRule shaderrules[] = { stage3_fog, stage3_tunnel, NULL };
stage_loop(stage3_start, stage3_end, stage3_draw, stage3_spellpractice_events, shaderrules, 0, "bgm_stage3boss");
}
ShaderRule stage3_shaders[] = { stage3_fog, stage3_tunnel, NULL };
StageProcs stage3_procs = {
.begin = stage3_start,
.end = stage3_end,
.draw = stage3_draw,
.event = stage3_events,
.shader_rules = stage3_shaders,
.spellpractice_procs = &stage3_spell_procs,
};
StageProcs stage3_spell_procs = {
.begin = stage3_start,
.end = stage3_end,
.draw = stage3_draw,
.event = stage3_spellpractice_events,
.shader_rules = stage3_shaders,
};

View file

@ -8,11 +8,10 @@
#ifndef STAGE3_H
#define STAGE3_H
#include "boss.h"
void stage3_loop(void);
void stage3_spellpractice_loop(void);
#include "stage.h"
extern StageProcs stage3_procs;
extern StageProcs stage3_spell_procs;
extern AttackInfo stage3_spells[];
#endif

View file

@ -20,13 +20,25 @@ void stage3_boss_a2(Boss*, int t);
void stage3_boss_a3(Boss*, int t);
void stage3_boss_extra(Boss*, int t);
/*
* See the definition of AttackInfo in boss.h for information on how to set up the idmaps.
*/
AttackInfo stage3_spells[] = {
{AT_Spellcard, "Venom Sign ~ Deadly Dance", 25, 25000, stage3_mid_a1, stage3_mid_spellbg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Venom Sign ~ Acid Rain", 20, 23000, stage3_mid_a2, stage3_mid_spellbg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Firefly Sign ~ Moonlight Rocket", 30, 20000, stage3_boss_a1, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Light Source ~ Wriggle Night Ignite", 25, 40000, stage3_boss_a2, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Bug Sign ~ Phosphaenus Hemipterus", 35, 30000, stage3_boss_a3, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{AT_ExtraSpell, "Firefly Sign ~ Moonlight Wraith", 60, 150000, stage3_boss_extra, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_Spellcard, "Venom Sign ~ Deadly Dance", 25, 25000,
stage3_mid_a1, stage3_mid_spellbg, BOSS_DEFAULT_GO_POS},
{{-1, -1, 4, 5}, AT_Spellcard, "Venom Sign ~ Acid Rain", 20, 23000,
stage3_mid_a2, stage3_mid_spellbg, BOSS_DEFAULT_GO_POS},
{{ 6, 7, 8, 9}, AT_Spellcard, "Firefly Sign ~ Moonlight Rocket", 30, 20000,
stage3_boss_a1, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{{10, 11, 12, 13}, AT_Spellcard, "Light Source ~ Wriggle Night Ignite", 25, 40000,
stage3_boss_a2, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{{14, 15, 16, 17}, AT_Spellcard, "Bug Sign ~ Phosphaenus Hemipterus", 35, 30000,
stage3_boss_a3, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_ExtraSpell, "Firefly Sign ~ Moonlight Wraith", 60, 150000,
stage3_boss_extra, stage3_boss_spellbg, BOSS_DEFAULT_GO_POS},
{{0}}
};
Dialog *stage3_dialog(void) {
@ -838,6 +850,10 @@ Boss* stage3_create_boss(void) {
void stage3_events(void) {
TIMER(&global.timer);
AT(0) {
start_bgm("bgm_stage2");
}
FROM_TO(160, 300, 10) {
tsrand_fill(3);
create_enemy1c(VIEWPORT_W/2 + 20 * anfrand(0) + (VIEWPORT_H/4 + 20 * anfrand(1))*I, 200, Swirl, stage3_enterswirl, I * 3 + anfrand(2) * 3);
@ -917,4 +933,8 @@ void stage3_events(void) {
AT(5300)
global.boss = stage3_create_boss();
AT(5700 - FADE_TIME) {
stage_finish(GAMEOVER_WIN);
}
}

View file

@ -229,11 +229,6 @@ void stage4_draw(void) {
bgcontext.cv[1] += 0.02;
}
void stage4_loop(void) {
ShaderRule shaderrules[] = { stage4_fog, NULL };
stage_loop(stage4_start, stage4_end, stage4_draw, stage4_events, shaderrules, 5550, "bgm_stage4");
}
void stage4_spellpractice_events(void) {
TIMER(&global.timer);
@ -242,10 +237,26 @@ void stage4_spellpractice_events(void) {
global.boss = create_boss("Kurumi", "kurumi", BOSS_DEFAULT_SPAWN_POS);
boss_add_attack_from_info(global.boss, global.stage->spell, true);
start_attack(global.boss, global.boss->attacks);
start_bgm("bgm_stage4boss");
}
}
void stage4_spellpractice_loop(void) {
ShaderRule shaderrules[] = { stage4_fog, NULL };
stage_loop(stage4_start, stage4_end, stage4_draw, stage4_spellpractice_events, shaderrules, 0, "bgm_stage4boss");
}
ShaderRule stage4_shaders[] = { stage4_fog, NULL };
StageProcs stage4_procs = {
.begin = stage4_start,
.end = stage4_end,
.draw = stage4_draw,
.event = stage4_events,
.shader_rules = stage4_shaders,
.spellpractice_procs = &stage4_spell_procs,
};
StageProcs stage4_spell_procs = {
.begin = stage4_start,
.end = stage4_end,
.draw = stage4_draw,
.event = stage4_spellpractice_events,
.shader_rules = stage4_shaders,
};

View file

@ -8,11 +8,10 @@
#ifndef STAGE4_H
#define STAGE4_H
#include "boss.h"
void stage4_loop(void);
void stage4_spellpractice_loop(void);
#include "stage.h"
extern StageProcs stage4_procs;
extern StageProcs stage4_spell_procs;
extern AttackInfo stage4_spells[];
#endif

View file

@ -18,14 +18,27 @@ void kurumi_aniwall(Boss*, int);
void kurumi_blowwall(Boss*, int);
void kurumi_danmaku(Boss*, int);
/*
* See the definition of AttackInfo in boss.h for information on how to set up the idmaps.
*/
AttackInfo stage4_spells[] = {
{AT_Spellcard, "Bloodless ~ Gate of Walachia", 25, 20000, kurumi_slaveburst, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Bloodless ~ Dry Fountain", 30, 30000, kurumi_redspike, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Bloodless ~ Red Spike", 30, 30000, kurumi_redspike, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Limit ~ Animate Wall", 30, 40000, kurumi_aniwall, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Summoning ~ Demon Wall", 30, 40000, kurumi_aniwall, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Power Sign ~ Blow the Walls", 30, 32000, kurumi_blowwall, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Fear Sign ~ Bloody Danmaku", 30, 32000, kurumi_danmaku, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_Spellcard, "Bloodless ~ Gate of Walachia", 25, 20000,
kurumi_slaveburst, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 4, 5, -1, -1}, AT_Spellcard, "Bloodless ~ Dry Fountain", 30, 30000,
kurumi_redspike, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{-1, -1, 6, 7}, AT_Spellcard, "Bloodless ~ Red Spike", 30, 30000,
kurumi_redspike, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 8, 9, -1, -1}, AT_Spellcard, "Limit ~ Animate Wall", 30, 40000,
kurumi_aniwall, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{-1, -1, 10, 11}, AT_Spellcard, "Summoning ~ Demon Wall", 30, 40000,
kurumi_aniwall, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{12, 13, 14, 15}, AT_Spellcard, "Power Sign ~ Blow the Walls", 30, 32000,
kurumi_blowwall, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{-1, -1, 16, 17}, AT_Spellcard, "Fear Sign ~ Bloody Danmaku", 30, 32000,
kurumi_danmaku, kurumi_spell_bg, BOSS_DEFAULT_GO_POS},
{{0}}
};
Dialog *stage4_dialog(void) {
@ -745,6 +758,10 @@ Boss *create_kurumi(void) {
void stage4_events(void) {
TIMER(&global.timer);
AT(0) {
start_bgm("bgm_stage4");
}
AT(70) {
create_enemy1c(VIEWPORT_H/4*3*I, 3000, BigFairy, stage4_splasher, 3-4.0*I);
create_enemy1c(VIEWPORT_W + VIEWPORT_H/4*3*I, 3000, BigFairy, stage4_splasher, -3-4.0*I);
@ -802,4 +819,8 @@ void stage4_events(void) {
AT(5400)
global.dialog = stage4_dialog_end();
AT(5550 - FADE_TIME) {
stage_finish(GAMEOVER_WIN);
}
}

View file

@ -128,10 +128,6 @@ void stage5_end(void) {
free_stage3d(&bgcontext);
}
void stage5_loop(void) {
stage_loop(stage5_start, stage5_end, stage5_draw, stage5_events, NULL, 5700, "bgm_stage5");
}
void stage5_spellpractice_events(void) {
TIMER(&global.timer);
@ -140,9 +136,26 @@ void stage5_spellpractice_events(void) {
global.boss = create_boss("Nagae Iku", "iku", BOSS_DEFAULT_SPAWN_POS);
boss_add_attack_from_info(global.boss, global.stage->spell, true);
start_attack(global.boss, global.boss->attacks);
start_bgm("bgm_stage5boss");
}
}
void stage5_spellpractice_loop(void) {
stage_loop(stage5_start, stage5_end, stage5_draw, stage5_spellpractice_events, NULL, 5700, "bgm_stage5boss");
}
ShaderRule stage5_shaders[] = { NULL };
StageProcs stage5_procs = {
.begin = stage5_start,
.end = stage5_end,
.draw = stage5_draw,
.event = stage5_events,
.shader_rules = stage5_shaders,
.spellpractice_procs = &stage5_spell_procs,
};
StageProcs stage5_spell_procs = {
.begin = stage5_start,
.end = stage5_end,
.draw = stage5_draw,
.event = stage5_spellpractice_events,
.shader_rules = stage5_shaders,
};

View file

@ -8,11 +8,10 @@
#ifndef STAGE5_H
#define STAGE5_H
#include "boss.h"
void stage5_loop(void);
void stage5_spellpractice_loop(void);
#include "stage.h"
extern StageProcs stage5_procs;
extern StageProcs stage5_spell_procs;
extern AttackInfo stage5_spells[];
#endif

View file

@ -17,12 +17,23 @@ void iku_cathode(Boss*, int);
void iku_induction(Boss*, int);
void iku_extra(Boss*, int);
/*
* See the definition of AttackInfo in boss.h for information on how to set up the idmaps.
*/
AttackInfo stage5_spells[] = {
{AT_Spellcard, "High Voltage ~ Atmospheric Discharge", 30, 30000, iku_atmospheric, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Charge Sign ~ Artificial Lightning", 30, 35000, iku_lightning, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Spark Sign ~ Natural Cathode", 30, 35000, iku_cathode, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Current Sign ~ Induction", 30, 35000, iku_induction, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{AT_ExtraSpell, "Circuit Sign ~ Overload", 60000, 150000, iku_extra, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_Spellcard, "High Voltage ~ Atmospheric Discharge", 30, 30000,
iku_atmospheric, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 4, 5, 6, 7}, AT_Spellcard, "Charge Sign ~ Artificial Lightning", 30, 35000,
iku_lightning, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 8, 9, 10, 11}, AT_Spellcard, "Spark Sign ~ Natural Cathode", 30, 35000,
iku_cathode, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{{12, 13, 14, 15}, AT_Spellcard, "Current Sign ~ Induction", 30, 35000,
iku_induction, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_ExtraSpell, "Circuit Sign ~ Overload", 60000, 150000,
iku_extra, iku_spell_bg, BOSS_DEFAULT_GO_POS},
{{0}}
};
Dialog *stage5_post_mid_dialog(void) {
@ -217,7 +228,7 @@ void iku_slave_draw(Enemy *e, int t) {
alpha *= 0.03;
create_particle3c("lightningball", e->pos, rgba(.1*alpha, .1*alpha, .6*alpha, 0.1*alpha), FadeAdd, enemy_flare, 50,offset*0.1,add_ref(e));
}
}
void iku_mid_intro(Boss *b, int t) {
@ -669,6 +680,10 @@ Boss *create_iku(void) {
void stage5_events(void) {
TIMER(&global.timer);
AT(0) {
start_bgm("bgm_stage5");
}
FROM_TO(60, 120, 10)
create_enemy1c(VIEWPORT_W+70.0*I+50*_i*I, 300, Fairy, stage5_greeter, -3);
@ -729,4 +744,8 @@ void stage5_events(void) {
AT(5320)
global.dialog = stage5_post_boss_dialog();
AT(5700 - FADE_TIME) {
stage_finish(GAMEOVER_WIN);
}
}

View file

@ -173,11 +173,6 @@ void stage6_end(void) {
free_stage3d(&bgcontext);
}
void stage6_loop(void) {
// ShaderRule shaderrules[] = { stage6_bloom, NULL };
stage_loop(stage6_start, stage6_end, stage6_draw, stage6_events, NULL, 3900, "bgm_stage6");
}
void elly_intro(Boss*, int);
void elly_unbound(Boss*, int);
@ -222,6 +217,8 @@ void stage6_spellpractice_events(void) {
boss_add_attack_from_info(global.boss, global.stage->spell, go);
start_attack(global.boss, global.boss->attacks);
start_bgm("bgm_stage6boss");
}
if(!global.boss) {
@ -229,7 +226,21 @@ void stage6_spellpractice_events(void) {
}
}
void stage6_spellpractice_loop(void) {
// ShaderRule shaderrules[] = { stage6_bloom, NULL };
stage_loop(stage6_start, stage6_end, stage6_draw, stage6_spellpractice_events, NULL, 3900, "bgm_stage6boss");
}
ShaderRule stage6_shaders[] = { NULL };
StageProcs stage6_procs = {
.begin = stage6_start,
.end = stage6_end,
.draw = stage6_draw,
.event = stage6_events,
.shader_rules = stage6_shaders,
.spellpractice_procs = &stage6_spell_procs,
};
StageProcs stage6_spell_procs = {
.begin = stage6_start,
.end = stage6_end,
.draw = stage6_draw,
.event = stage6_spellpractice_events,
.shader_rules = stage6_shaders,
};

View file

@ -8,12 +8,12 @@
#ifndef STAGE6_H
#define STAGE6_H
#include "boss.h"
void stage6_loop(void);
void stage6_spellpractice_loop(void);
void start_fall_over(void);
#include "stage.h"
extern StageProcs stage6_procs;
extern StageProcs stage6_spell_procs;
extern AttackInfo stage6_spells[];
void start_fall_over(void);
#endif

View file

@ -19,14 +19,27 @@ void elly_lhc(Boss*, int);
void elly_theory(Boss*, int);
void elly_curvature(Boss*, int);
/*
* See the definition of AttackInfo in boss.h for information on how to set up the idmaps.
*/
AttackInfo stage6_spells[] = {
{AT_Spellcard, "Newton Sign ~ 2.5 Laws of Movement", 60, 40000, elly_newton, elly_spellbg_classic, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Maxwell Sign ~ Wave Theory", 25, 22000, elly_maxwell, elly_spellbg_classic, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Eigenstate ~ Many-World Interpretation", 60, 30000, elly_eigenstate, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "Ricci Sign ~ Space Time Curvature", 50, 40000, elly_ricci, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{AT_Spellcard, "LHC ~ Higgs Boson Uncovered", 60, 50000, elly_lhc, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{AT_SurvivalSpell, "Tower of Truth ~ Theory of Everything", 70, 40000, elly_theory, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{AT_ExtraSpell, "Forgotten Universe ~ Curvature Domination", 40, 40000, elly_curvature, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_Spellcard, "Newton Sign ~ 2.5 Laws of Movement", 60, 40000,
elly_newton, elly_spellbg_classic, BOSS_DEFAULT_GO_POS},
{{ 4, 5, 6, 7}, AT_Spellcard, "Maxwell Sign ~ Wave Theory", 25, 22000,
elly_maxwell, elly_spellbg_classic, BOSS_DEFAULT_GO_POS},
{{ 8, 9, 10, 11}, AT_Spellcard, "Eigenstate ~ Many-World Interpretation", 60, 30000,
elly_eigenstate, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{{12, 13, 14, 15}, AT_Spellcard, "Ricci Sign ~ Space Time Curvature", 50, 40000,
elly_ricci, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{{16, 17, 18, 19}, AT_Spellcard, "LHC ~ Higgs Boson Uncovered", 60, 50000,
elly_lhc, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{{20, 21, 22, 23}, AT_SurvivalSpell, "Tower of Truth ~ Theory of Everything", 70, 40000,
elly_theory, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{{ 0, 1, 2, 3}, AT_ExtraSpell, "Forgotten Universe ~ Curvature Domination", 40, 40000,
elly_curvature, elly_spellbg_modern, BOSS_DEFAULT_GO_POS},
{{0}}
};
Dialog *stage6_dialog(void) {
@ -800,7 +813,7 @@ int curvature_bullet(Projectile *p, int t) {
if(t == EVENT_DEATH)
free_ref(p->args[1]);
return 1;
}
@ -812,9 +825,9 @@ int curvature_orbiter(Projectile *p, int t) {
p->args[2] = p->args[0]*I*w*cexp(I*t*w);
} else {
p->pos += p->args[2];
}
}
if(t == EVENT_DEATH)
free_ref(p->args[1]);
@ -829,7 +842,7 @@ static double saw(double t) {
int curvature_slave(Enemy *e, int t) {
e->args[0] = -(e->args[1] - global.plr.pos);
e->args[1] = global.plr.pos;
if(t % (2+(global.diff < D_Hard)) == 0) {
tsrand_fill(2);
complex pos = VIEWPORT_W*afrand(0)+I*VIEWPORT_H*afrand(1);
@ -868,7 +881,7 @@ void elly_curvature(Boss *b, int t) {
}
GO_TO(b, VIEWPORT_W/2+100*I+VIEWPORT_W/3*round(sin(t/200)), 0.04);
AT(EVENT_DEATH) {
killall(global.enemies);
}
@ -1063,8 +1076,9 @@ Boss *create_elly(void) {
void stage6_events(void) {
TIMER(&global.timer);
// AT(0)
// global.timer = 3800;
AT(0) {
start_bgm("bgm_stage6");
}
AT(100)
create_enemy1c(VIEWPORT_W/2, 6000, BigFairy, stage6_hacker, 2.0*I);
@ -1088,4 +1102,8 @@ void stage6_events(void) {
AT(3800)
global.boss = create_elly();
AT(3900 - FADE_TIME) {
stage_finish(GAMEOVER_WIN);
}
}

View file

@ -5,108 +5,123 @@
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
*/
#include <assert.h>
#include "global.h"
#define TAISEIGL_NO_EXT_ABSTRACTION
#include "taiseigl.h"
#undef TAISEIGL_NO_EXT_ABSTRACTION
#ifndef __APPLE__
#ifdef __WINDOWS__
// #include <GL/wgl.h>
#else
#include <GL/glx.h>
#endif
struct glext_s glext;
#ifndef LINK_TO_LIBGL
#define GLDEF(glname,tsname,typename) typename tsname;
GLDEFS
#undef GLDEF
#endif
#include <string.h>
#include <stdio.h>
typedef void (*tsglproc_ptr)();
int tgl_ext[_TGLEXT_COUNT];
#ifndef LINK_TO_LIBGL
static tsglproc_ptr get_proc_address(const char *name) {
void *addr = SDL_GL_GetProcAddress(name);
#ifndef __APPLE__
typedef void (*GLFuncPtr)(void);
GLFuncPtr get_proc_address(char *name) {
#ifdef __WINDOWS__
return (GLFuncPtr)wglGetProcAddress(name);
#else
return glXGetProcAddress((GLubyte *)name);
#endif
if(!addr) {
warnx("load_gl_functions(): SDL_GL_GetProcAddress(\"%s\") failed: %s", name, SDL_GetError());
}
// shut up a stupid warning about conversion between data pointers and function pointers
// yes, such a conversion is not allowed by the standard, but when several major APIs
// (POSIX and SDL to name a few) require casting void* to a function pointer, that says something.
return *(tsglproc_ptr*)&addr;
}
#endif
#ifdef GL_USE_ARB_DRAW_INSTANCED
#define DRAW_INSTANCED_EXT_NAME "GL_ARB_draw_instanced"
#else
#define DRAW_INSTANCED_EXT_NAME "GL_EXT_draw_instanced"
#endif
static void get_gl_version(char *major, char *minor) {
// the glGetIntegerv way only works in >=3.0 contexts, so...
const char *vstr = (const char*)glGetString(GL_VERSION);
const char *dot = strchr(vstr, '.');
*major = atoi(vstr);
*minor = atoi(dot+1);
}
void check_gl_extensions(void) {
int l;
char *ext = (char*)glGetString(GL_EXTENSIONS);
char *last, *pos;
get_gl_version(&glext.version.major, &glext.version.minor);
last = ext;
pos = ext;
while((pos = strchr(pos, ' '))) {
pos++;
const char *glslv = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
l = pos - last - 1;
if(!glslv) {
glslv = "None";
}
if(strncmp(last, "GL_EXT_draw_instanced", l) == 0)
tgl_ext[TGLEXT_draw_instanced] = 1;
printf("OpenGL version: %s\n", (const char*)glGetString(GL_VERSION));
printf("OpenGL vendor: %s\n", (const char*)glGetString(GL_VENDOR));
printf("OpenGL renderer: %s\n", (const char*)glGetString(GL_RENDERER));
printf("GLSL version: %s\n", glslv);
last = pos;
glext.draw_instanced = false;
glext.DrawArraysInstanced = NULL;
glext.EXT_draw_instanced = SDL_GL_ExtensionSupported("GL_EXT_draw_instanced");
glext.ARB_draw_instanced = SDL_GL_ExtensionSupported("GL_ARB_draw_instanced");
glext.draw_instanced = glext.EXT_draw_instanced;
if(glext.draw_instanced) {
glext.DrawArraysInstanced = tsglDrawArraysInstancedEXT;
if(!glext.DrawArraysInstanced) {
glext.draw_instanced = false;
}
}
if(!glext.draw_instanced) {
glext.draw_instanced = glext.ARB_draw_instanced;
if(glext.draw_instanced) {
glext.DrawArraysInstanced = tsglDrawArraysInstancedARB;
if(!glext.DrawArraysInstanced) {
glext.draw_instanced = false;
}
}
}
if(!glext.draw_instanced) {
warnx(
"glDrawArraysInstanced is not supported. "
"Your video driver is probably bad, or very old, or both. "
"Expect terrible performance."
);
}
}
void load_gl_functions(void) {
#ifdef __WINDOWS__
glActiveTexture = (PFNGLACTIVETEXTUREPROC)get_proc_address("glActiveTexture");
glBlendEquation = (PFNGLBLENDEQUATIONPROC)get_proc_address("glBlendEquation");
#endif
void load_gl_library(void) {
#ifndef LINK_TO_LIBGL
char *lib = getenv("TAISEI_LIBGL");
#ifndef __APPLE__
glBlendFuncSeparate = (PFNGLBLENDFUNCSEPARATEPROC)get_proc_address("glBlendFuncSeparate");
glDrawArraysInstanced = (PFNGLDRAWARRAYSINSTANCEDPROC)get_proc_address("glDrawArraysInstanced");
if(lib && !*lib) {
lib = NULL;
}
glBindFramebuffer = (PFNGLBINDFRAMEBUFFERPROC)get_proc_address("glBindFramebuffer");
glGenFramebuffers = (PFNGLGENFRAMEBUFFERSPROC)get_proc_address("glGenFramebuffers");
glFramebufferTexture2D = (PFNGLFRAMEBUFFERTEXTURE2DPROC)get_proc_address("glFramebufferTexture2D");
glDeleteFramebuffers = (PFNGLDELETEFRAMEBUFFERSPROC)get_proc_address("glDeleteFramebuffers");
glGenBuffers = (PFNGLGENBUFFERSPROC)get_proc_address("glGenBuffers");
glBindBuffer = (PFNGLBINDBUFFERPROC)get_proc_address("glBindBuffer");
glBufferData = (PFNGLBUFFERDATAPROC)get_proc_address("glBufferData");
glBufferSubData = (PFNGLBUFFERSUBDATAPROC)get_proc_address("glBufferSubData");
glDeleteBuffers = (PFNGLDELETEBUFFERSPROC)get_proc_address("glDeleteBuffers");
glCreateProgram = (PFNGLCREATEPROGRAMPROC)get_proc_address("glCreateProgram");
glLinkProgram = (PFNGLLINKPROGRAMPROC)get_proc_address("glLinkProgram");
glUseProgram = (PFNGLUSEPROGRAMPROC)get_proc_address("glUseProgram");
glGetProgramiv = (PFNGLGETPROGRAMIVPROC)get_proc_address("glGetProgramiv");
glGetProgramInfoLog = (PFNGLGETPROGRAMINFOLOGPROC)get_proc_address("glGetProgramInfoLog");
glDeleteProgram = (PFNGLDELETEPROGRAMPROC)get_proc_address("glDeleteProgram");
glCreateShader = (PFNGLCREATESHADERPROC)get_proc_address("glCreateShader");
glGetShaderiv = (PFNGLGETSHADERIVPROC)get_proc_address("glGetShaderiv");
glGetShaderInfoLog = (PFNGLGETSHADERINFOLOGPROC)get_proc_address("glGetShaderInfoLog");
glShaderSource = (PFNGLSHADERSOURCEPROC)get_proc_address("glShaderSource");
glCompileShader = (PFNGLCOMPILESHADERPROC)get_proc_address("glCompileShader");
glAttachShader = (PFNGLATTACHSHADERPROC)get_proc_address("glAttachShader");
glDeleteShader = (PFNGLDELETESHADERPROC)get_proc_address("glDeleteShader");
glGetActiveUniform = (PFNGLGETACTIVEUNIFORMPROC)get_proc_address("glGetActiveUniform");
glGetUniformLocation = (PFNGLGETUNIFORMLOCATIONPROC)get_proc_address("glGetUniformLocation");
glUniform1f = (PFNGLUNIFORM1FPROC)get_proc_address("glUniform1f");
glUniform2f = (PFNGLUNIFORM2FPROC)get_proc_address("glUniform2f");
glUniform3f = (PFNGLUNIFORM3FPROC)get_proc_address("glUniform3f");
glUniform4f = (PFNGLUNIFORM4FPROC)get_proc_address("glUniform4f");
glUniform1i = (PFNGLUNIFORM1IPROC)get_proc_address("glUniform1i");
glUniform2i = (PFNGLUNIFORM2IPROC)get_proc_address("glUniform2i");
glUniform3i = (PFNGLUNIFORM3IPROC)get_proc_address("glUniform3i");
glUniform4i = (PFNGLUNIFORM4IPROC)get_proc_address("glUniform4i");
glUniform2fv = (PFNGLUNIFORM2FVPROC)get_proc_address("glUniform2fv");
glUniform3fv = (PFNGLUNIFORM3FVPROC)get_proc_address("glUniform3fv");
glUniform4fv = (PFNGLUNIFORM4FVPROC)get_proc_address("glUniform4fv");
if(SDL_GL_LoadLibrary(lib) < 0) {
errx(-1, "load_gl_library(): SDL_GL_LoadLibrary() failed: %s", SDL_GetError());
return;
}
#endif
}
void load_gl_functions(void) {
#ifndef LINK_TO_LIBGL
#define GLDEF(glname,tsname,typename) tsname = (typename)get_proc_address(#glname);
GLDEFS
#undef GLDEF
#endif
}
void gluPerspective(GLdouble fovY, GLdouble aspect, GLdouble zNear, GLdouble zFar) {
GLdouble fW, fH;
fH = tan(fovY / 360 * M_PI) * zNear;
fW = fH * aspect;
glFrustum(-fW, fW, -fH, fH, zNear, zFar);
}

View file

@ -1,3 +1,87 @@
#if 0
#
# Run this file with python3 to update the defs.
# It automatically picks up all the gl* functions used in Taisei code and updates itself.
#
# You can force the script to pick up functions that are not directly called in the code here
force_funcs = [
'glDrawArraysInstancedEXT',
'glDrawArraysInstancedARB',
]
import sys, re
from pathlib import Path as P
thisfile = P(sys.argv[0])
srcdir = thisfile.parent
glfuncs = set()
try:
idir = sys.argv[1]
except IndexError:
idir = '/usr/include/SDL2'
glheaders = (
P('%s/SDL_opengl.h' % idir).read_text() +
P('%s/SDL_opengl_glext.h' % idir).read_text()
)
regex_glcall = re.compile(r'(gl[A-Z][a-zA-Z0-9]+)\(')
regex_glproto_template = r'(^GLAPI\s+([a-zA-Z_0-9\s]+?\**)\s*((?:GL)?APIENTRY)\s+%s\s*\(\s*(.*?)\s*\);)'
for src in srcdir.glob('**/*.c'):
for func in regex_glcall.findall(src.read_text()):
glfuncs.add(func)
glfuncs = sorted(list(glfuncs) + force_funcs)
typedefs = []
prototypes = []
for func in glfuncs:
try:
proto, rtype, callconv, params = re.findall(regex_glproto_template % func, glheaders, re.DOTALL|re.MULTILINE)[0]
except IndexError:
print("Function '%s' not found in the GL headers. Either it really does not exist, or this script is bugged. Please check the opengl headers in %s\nUpdate aborted." % (func, idir))
exit(1)
proto = re.sub(r'\s+', ' ', proto, re.DOTALL|re.MULTILINE)
params = ', '.join(re.split(r',\s*', params))
typename = 'ts%s_ptr' % func
typedef = 'typedef %s (%s *%s)(%s);' % (rtype, callconv, typename, params)
typedefs.append(typedef)
prototypes.append(proto)
text = thisfile.read_text()
subs = {
'gldefs': '#define GLDEFS \\\n' + ' \\\n'.join('GLDEF(%s, ts%s, ts%s_ptr)' % (f, f, f) for f in glfuncs),
'undefs': '\n'.join('#undef %s' % f for f in glfuncs),
'redefs': '\n'.join('#define %s ts%s' % (f, f) for f in glfuncs),
'reversedefs': '\n'.join('#define ts%s %s' % (f, f) for f in glfuncs),
'typedefs': '\n'.join(typedefs),
'protos': '\n'.join(prototypes),
}
for key, val in subs.items():
text = re.sub(
r'(// @BEGIN:%s@)(.*?)(// @END:%s@)' % (key, key),
r'\1\n%s\n\3' % val,
text,
flags=re.DOTALL|re.MULTILINE
)
thisfile.write_text(text)
#/*
"""
*/
#endif
/*
* This software is licensed under the terms of the MIT-License
* See COPYING for further information.
@ -9,86 +93,526 @@
#define TAISEIGL_H
#include <SDL_platform.h>
#include <SDL_opengl.h>
#include <SDL_opengl_glext.h>
#ifdef __APPLE__
#include <OpenGL/gl.h>
#include <OpenGL/glu.h>
#include <OpenGL/glext.h>
#else
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
#endif
enum {
TGLEXT_draw_instanced = 0,
_TGLEXT_COUNT
};
extern int tgl_ext[_TGLEXT_COUNT];
struct glext_s; // defined at the very bottom
extern struct glext_s glext;
void load_gl_library(void);
void load_gl_functions(void);
void check_gl_extensions(void);
#ifdef __WINDOWS__
PFNGLACTIVETEXTUREPROC glActiveTexture;
PFNGLBLENDEQUATIONPROC glBlendEquation;
#define gluPerspective tsgluPerspective
void gluPerspective(GLdouble fovY, GLdouble aspect, GLdouble zNear, GLdouble zFar);
#ifndef APIENTRY
#define APIENTRY
#endif
#ifndef __APPLE__
PFNGLBLENDFUNCSEPARATEPROC glBlendFuncSeparate;
PFNGLDRAWARRAYSINSTANCEDPROC glDrawArraysInstanced;
PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer;
PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers;
PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D;
PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers;
PFNGLGENBUFFERSPROC glGenBuffers;
PFNGLBINDBUFFERPROC glBindBuffer;
PFNGLBUFFERDATAPROC glBufferData;
PFNGLBUFFERSUBDATAPROC glBufferSubData;
PFNGLDELETEBUFFERSPROC glDeleteBuffers;
PFNGLCREATEPROGRAMPROC glCreateProgram;
PFNGLLINKPROGRAMPROC glLinkProgram;
PFNGLUSEPROGRAMPROC glUseProgram;
PFNGLGETPROGRAMIVPROC glGetProgramiv;
PFNGLGETPROGRAMINFOLOGPROC glGetProgramInfoLog;
PFNGLDELETEPROGRAMPROC glDeleteProgram;
PFNGLCREATESHADERPROC glCreateShader;
PFNGLGETSHADERIVPROC glGetShaderiv;
PFNGLGETSHADERINFOLOGPROC glGetShaderInfoLog;
PFNGLSHADERSOURCEPROC glShaderSource;
PFNGLCOMPILESHADERPROC glCompileShader;
PFNGLATTACHSHADERPROC glAttachShader;
PFNGLDELETESHADERPROC glDeleteShader;
PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform;
PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation;
PFNGLUNIFORM1FPROC glUniform1f;
PFNGLUNIFORM2FPROC glUniform2f;
PFNGLUNIFORM3FPROC glUniform3f;
PFNGLUNIFORM4FPROC glUniform4f;
PFNGLUNIFORM1IPROC glUniform1i;
PFNGLUNIFORM2IPROC glUniform2i;
PFNGLUNIFORM3IPROC glUniform3i;
PFNGLUNIFORM4IPROC glUniform4i;
PFNGLUNIFORM2FVPROC glUniform2fv;
PFNGLUNIFORM3FVPROC glUniform3fv;
PFNGLUNIFORM4FVPROC glUniform4fv;
#ifndef GLAPIENTRY
#define GLAPIENTRY
#endif
#ifdef GL_USE_ARB_DRAW_INSTANCED
/*
*
* From here on it's mostly generated code (by the embedded python script)
*
*/
// @BEGIN:typedefs@
typedef void (GLAPIENTRY *tsglActiveTexture_ptr)(GLenum texture);
typedef void (APIENTRY *tsglAttachShader_ptr)(GLuint program, GLuint shader);
typedef void (APIENTRY *tsglBindBuffer_ptr)(GLenum target, GLuint buffer);
typedef void (APIENTRY *tsglBindFramebuffer_ptr)(GLenum target, GLuint framebuffer);
typedef void (GLAPIENTRY *tsglBindTexture_ptr)(GLenum target, GLuint texture);
typedef void (GLAPIENTRY *tsglBlendEquation_ptr)(GLenum mode);
typedef void (GLAPIENTRY *tsglBlendFunc_ptr)(GLenum sfactor, GLenum dfactor);
typedef void (APIENTRY *tsglBlendFuncSeparate_ptr)(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
typedef void (APIENTRY *tsglBufferData_ptr)(GLenum target, GLsizeiptr size, const void *data, GLenum usage);
typedef void (APIENTRY *tsglBufferSubData_ptr)(GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
typedef void (GLAPIENTRY *tsglClear_ptr)(GLbitfield mask);
typedef void (GLAPIENTRY *tsglClearColor_ptr)(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha);
typedef void (GLAPIENTRY *tsglColor3f_ptr)(GLfloat red, GLfloat green, GLfloat blue);
typedef void (GLAPIENTRY *tsglColor4f_ptr)(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);
typedef void (GLAPIENTRY *tsglColor4fv_ptr)(const GLfloat *v);
typedef void (APIENTRY *tsglCompileShader_ptr)(GLuint shader);
typedef GLuint (APIENTRY *tsglCreateProgram_ptr)(void);
typedef GLuint (APIENTRY *tsglCreateShader_ptr)(GLenum type);
typedef void (GLAPIENTRY *tsglCullFace_ptr)(GLenum mode);
typedef void (APIENTRY *tsglDeleteBuffers_ptr)(GLsizei n, const GLuint *buffers);
typedef void (APIENTRY *tsglDeleteFramebuffers_ptr)(GLsizei n, const GLuint *framebuffers);
typedef void (APIENTRY *tsglDeleteProgram_ptr)(GLuint program);
typedef void (APIENTRY *tsglDeleteShader_ptr)(GLuint shader);
typedef void (GLAPIENTRY *tsglDeleteTextures_ptr)(GLsizei n, const GLuint *textures);
typedef void (GLAPIENTRY *tsglDepthFunc_ptr)(GLenum func);
typedef void (GLAPIENTRY *tsglDisable_ptr)(GLenum cap);
typedef void (GLAPIENTRY *tsglDrawArrays_ptr)(GLenum mode, GLint first, GLsizei count);
typedef void (APIENTRY *tsglDrawArraysInstanced_ptr)(GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
typedef void (APIENTRY *tsglDrawArraysInstancedARB_ptr)(GLenum mode, GLint first, GLsizei count, GLsizei primcount);
typedef void (APIENTRY *tsglDrawArraysInstancedEXT_ptr)(GLenum mode, GLint start, GLsizei count, GLsizei primcount);
typedef void (GLAPIENTRY *tsglDrawElements_ptr)(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices);
typedef void (GLAPIENTRY *tsglEnable_ptr)(GLenum cap);
typedef void (GLAPIENTRY *tsglEnableClientState_ptr)(GLenum cap);
typedef void (APIENTRY *tsglFramebufferTexture2D_ptr)(GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
typedef void (GLAPIENTRY *tsglFrustum_ptr)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
typedef void (APIENTRY *tsglGenBuffers_ptr)(GLsizei n, GLuint *buffers);
typedef void (APIENTRY *tsglGenFramebuffers_ptr)(GLsizei n, GLuint *framebuffers);
typedef void (GLAPIENTRY *tsglGenTextures_ptr)(GLsizei n, GLuint *textures);
typedef void (APIENTRY *tsglGetActiveUniform_ptr)(GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
typedef void (APIENTRY *tsglGetProgramInfoLog_ptr)(GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (APIENTRY *tsglGetProgramiv_ptr)(GLuint program, GLenum pname, GLint *params);
typedef void (APIENTRY *tsglGetShaderInfoLog_ptr)(GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
typedef void (APIENTRY *tsglGetShaderiv_ptr)(GLuint shader, GLenum pname, GLint *params);
typedef const GLubyte * (GLAPIENTRY *tsglGetString_ptr)(GLenum name);
typedef GLint (APIENTRY *tsglGetUniformLocation_ptr)(GLuint program, const GLchar *name);
typedef void (APIENTRY *tsglLinkProgram_ptr)(GLuint program);
typedef void (GLAPIENTRY *tsglLoadIdentity_ptr)(void);
typedef void (GLAPIENTRY *tsglMatrixMode_ptr)(GLenum mode);
typedef void (GLAPIENTRY *tsglNormalPointer_ptr)(GLenum type, GLsizei stride, const GLvoid *ptr);
typedef void (GLAPIENTRY *tsglOrtho_ptr)(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val);
typedef void (GLAPIENTRY *tsglPopMatrix_ptr)(void);
typedef void (GLAPIENTRY *tsglPushMatrix_ptr)(void);
typedef void (GLAPIENTRY *tsglReadBuffer_ptr)(GLenum mode);
typedef void (GLAPIENTRY *tsglReadPixels_ptr)(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels);
typedef void (GLAPIENTRY *tsglRotatef_ptr)(GLfloat angle, GLfloat x, GLfloat y, GLfloat z);
typedef void (GLAPIENTRY *tsglScalef_ptr)(GLfloat x, GLfloat y, GLfloat z);
typedef void (GLAPIENTRY *tsglScissor_ptr)(GLint x, GLint y, GLsizei width, GLsizei height);
typedef void (APIENTRY *tsglShaderSource_ptr)(GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
typedef void (GLAPIENTRY *tsglTexCoordPointer_ptr)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
typedef void (GLAPIENTRY *tsglTexImage2D_ptr)(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels);
typedef void (GLAPIENTRY *tsglTexParameterf_ptr)(GLenum target, GLenum pname, GLfloat param);
typedef void (GLAPIENTRY *tsglTexParameteri_ptr)(GLenum target, GLenum pname, GLint param);
typedef void (GLAPIENTRY *tsglTranslatef_ptr)(GLfloat x, GLfloat y, GLfloat z);
typedef void (APIENTRY *tsglUniform1f_ptr)(GLint location, GLfloat v0);
typedef void (APIENTRY *tsglUniform1i_ptr)(GLint location, GLint v0);
typedef void (APIENTRY *tsglUniform2f_ptr)(GLint location, GLfloat v0, GLfloat v1);
typedef void (APIENTRY *tsglUniform3f_ptr)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
typedef void (APIENTRY *tsglUniform3fv_ptr)(GLint location, GLsizei count, const GLfloat *value);
typedef void (APIENTRY *tsglUniform4f_ptr)(GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
typedef void (APIENTRY *tsglUniform4fv_ptr)(GLint location, GLsizei count, const GLfloat *value);
typedef void (APIENTRY *tsglUseProgram_ptr)(GLuint program);
typedef void (GLAPIENTRY *tsglVertexPointer_ptr)(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr);
typedef void (GLAPIENTRY *tsglViewport_ptr)(GLint x, GLint y, GLsizei width, GLsizei height);
// @END:typedefs@
// @BEGIN:undefs@
#undef glActiveTexture
#undef glAttachShader
#undef glBindBuffer
#undef glBindFramebuffer
#undef glBindTexture
#undef glBlendEquation
#undef glBlendFunc
#undef glBlendFuncSeparate
#undef glBufferData
#undef glBufferSubData
#undef glClear
#undef glClearColor
#undef glColor3f
#undef glColor4f
#undef glColor4fv
#undef glCompileShader
#undef glCreateProgram
#undef glCreateShader
#undef glCullFace
#undef glDeleteBuffers
#undef glDeleteFramebuffers
#undef glDeleteProgram
#undef glDeleteShader
#undef glDeleteTextures
#undef glDepthFunc
#undef glDisable
#undef glDrawArrays
#undef glDrawArraysInstanced
#undef glDrawArraysInstancedARB
#undef glDrawArraysInstancedEXT
#undef glDrawElements
#undef glEnable
#undef glEnableClientState
#undef glFramebufferTexture2D
#undef glFrustum
#undef glGenBuffers
#undef glGenFramebuffers
#undef glGenTextures
#undef glGetActiveUniform
#undef glGetProgramInfoLog
#undef glGetProgramiv
#undef glGetShaderInfoLog
#undef glGetShaderiv
#undef glGetString
#undef glGetUniformLocation
#undef glLinkProgram
#undef glLoadIdentity
#undef glMatrixMode
#undef glNormalPointer
#undef glOrtho
#undef glPopMatrix
#undef glPushMatrix
#undef glReadBuffer
#undef glReadPixels
#undef glRotatef
#undef glScalef
#undef glScissor
#undef glShaderSource
#undef glTexCoordPointer
#undef glTexImage2D
#undef glTexParameterf
#undef glTexParameteri
#undef glTranslatef
#undef glUniform1f
#undef glUniform1i
#undef glUniform2f
#undef glUniform3f
#undef glUniform3fv
#undef glUniform4f
#undef glUniform4fv
#undef glUseProgram
#undef glVertexPointer
#undef glViewport
// @END:undefs@
#ifndef LINK_TO_LIBGL
// @BEGIN:redefs@
#define glActiveTexture tsglActiveTexture
#define glAttachShader tsglAttachShader
#define glBindBuffer tsglBindBuffer
#define glBindFramebuffer tsglBindFramebuffer
#define glBindTexture tsglBindTexture
#define glBlendEquation tsglBlendEquation
#define glBlendFunc tsglBlendFunc
#define glBlendFuncSeparate tsglBlendFuncSeparate
#define glBufferData tsglBufferData
#define glBufferSubData tsglBufferSubData
#define glClear tsglClear
#define glClearColor tsglClearColor
#define glColor3f tsglColor3f
#define glColor4f tsglColor4f
#define glColor4fv tsglColor4fv
#define glCompileShader tsglCompileShader
#define glCreateProgram tsglCreateProgram
#define glCreateShader tsglCreateShader
#define glCullFace tsglCullFace
#define glDeleteBuffers tsglDeleteBuffers
#define glDeleteFramebuffers tsglDeleteFramebuffers
#define glDeleteProgram tsglDeleteProgram
#define glDeleteShader tsglDeleteShader
#define glDeleteTextures tsglDeleteTextures
#define glDepthFunc tsglDepthFunc
#define glDisable tsglDisable
#define glDrawArrays tsglDrawArrays
#define glDrawArraysInstanced tsglDrawArraysInstanced
#define glDrawArraysInstancedARB tsglDrawArraysInstancedARB
#define glDrawArraysInstancedEXT tsglDrawArraysInstancedEXT
#define glDrawElements tsglDrawElements
#define glEnable tsglEnable
#define glEnableClientState tsglEnableClientState
#define glFramebufferTexture2D tsglFramebufferTexture2D
#define glFrustum tsglFrustum
#define glGenBuffers tsglGenBuffers
#define glGenFramebuffers tsglGenFramebuffers
#define glGenTextures tsglGenTextures
#define glGetActiveUniform tsglGetActiveUniform
#define glGetProgramInfoLog tsglGetProgramInfoLog
#define glGetProgramiv tsglGetProgramiv
#define glGetShaderInfoLog tsglGetShaderInfoLog
#define glGetShaderiv tsglGetShaderiv
#define glGetString tsglGetString
#define glGetUniformLocation tsglGetUniformLocation
#define glLinkProgram tsglLinkProgram
#define glLoadIdentity tsglLoadIdentity
#define glMatrixMode tsglMatrixMode
#define glNormalPointer tsglNormalPointer
#define glOrtho tsglOrtho
#define glPopMatrix tsglPopMatrix
#define glPushMatrix tsglPushMatrix
#define glReadBuffer tsglReadBuffer
#define glReadPixels tsglReadPixels
#define glRotatef tsglRotatef
#define glScalef tsglScalef
#define glScissor tsglScissor
#define glShaderSource tsglShaderSource
#define glTexCoordPointer tsglTexCoordPointer
#define glTexImage2D tsglTexImage2D
#define glTexParameterf tsglTexParameterf
#define glTexParameteri tsglTexParameteri
#define glTranslatef tsglTranslatef
#define glUniform1f tsglUniform1f
#define glUniform1i tsglUniform1i
#define glUniform2f tsglUniform2f
#define glUniform3f tsglUniform3f
#define glUniform3fv tsglUniform3fv
#define glUniform4f tsglUniform4f
#define glUniform4fv tsglUniform4fv
#define glUseProgram tsglUseProgram
#define glVertexPointer tsglVertexPointer
#define glViewport tsglViewport
// @END:redefs@
#endif // !LINK_TO_LIBGL
#ifndef LINK_TO_LIBGL
// @BEGIN:gldefs@
#define GLDEFS \
GLDEF(glActiveTexture, tsglActiveTexture, tsglActiveTexture_ptr) \
GLDEF(glAttachShader, tsglAttachShader, tsglAttachShader_ptr) \
GLDEF(glBindBuffer, tsglBindBuffer, tsglBindBuffer_ptr) \
GLDEF(glBindFramebuffer, tsglBindFramebuffer, tsglBindFramebuffer_ptr) \
GLDEF(glBindTexture, tsglBindTexture, tsglBindTexture_ptr) \
GLDEF(glBlendEquation, tsglBlendEquation, tsglBlendEquation_ptr) \
GLDEF(glBlendFunc, tsglBlendFunc, tsglBlendFunc_ptr) \
GLDEF(glBlendFuncSeparate, tsglBlendFuncSeparate, tsglBlendFuncSeparate_ptr) \
GLDEF(glBufferData, tsglBufferData, tsglBufferData_ptr) \
GLDEF(glBufferSubData, tsglBufferSubData, tsglBufferSubData_ptr) \
GLDEF(glClear, tsglClear, tsglClear_ptr) \
GLDEF(glClearColor, tsglClearColor, tsglClearColor_ptr) \
GLDEF(glColor3f, tsglColor3f, tsglColor3f_ptr) \
GLDEF(glColor4f, tsglColor4f, tsglColor4f_ptr) \
GLDEF(glColor4fv, tsglColor4fv, tsglColor4fv_ptr) \
GLDEF(glCompileShader, tsglCompileShader, tsglCompileShader_ptr) \
GLDEF(glCreateProgram, tsglCreateProgram, tsglCreateProgram_ptr) \
GLDEF(glCreateShader, tsglCreateShader, tsglCreateShader_ptr) \
GLDEF(glCullFace, tsglCullFace, tsglCullFace_ptr) \
GLDEF(glDeleteBuffers, tsglDeleteBuffers, tsglDeleteBuffers_ptr) \
GLDEF(glDeleteFramebuffers, tsglDeleteFramebuffers, tsglDeleteFramebuffers_ptr) \
GLDEF(glDeleteProgram, tsglDeleteProgram, tsglDeleteProgram_ptr) \
GLDEF(glDeleteShader, tsglDeleteShader, tsglDeleteShader_ptr) \
GLDEF(glDeleteTextures, tsglDeleteTextures, tsglDeleteTextures_ptr) \
GLDEF(glDepthFunc, tsglDepthFunc, tsglDepthFunc_ptr) \
GLDEF(glDisable, tsglDisable, tsglDisable_ptr) \
GLDEF(glDrawArrays, tsglDrawArrays, tsglDrawArrays_ptr) \
GLDEF(glDrawArraysInstanced, tsglDrawArraysInstanced, tsglDrawArraysInstanced_ptr) \
GLDEF(glDrawArraysInstancedARB, tsglDrawArraysInstancedARB, tsglDrawArraysInstancedARB_ptr) \
GLDEF(glDrawArraysInstancedEXT, tsglDrawArraysInstancedEXT, tsglDrawArraysInstancedEXT_ptr) \
GLDEF(glDrawElements, tsglDrawElements, tsglDrawElements_ptr) \
GLDEF(glEnable, tsglEnable, tsglEnable_ptr) \
GLDEF(glEnableClientState, tsglEnableClientState, tsglEnableClientState_ptr) \
GLDEF(glFramebufferTexture2D, tsglFramebufferTexture2D, tsglFramebufferTexture2D_ptr) \
GLDEF(glFrustum, tsglFrustum, tsglFrustum_ptr) \
GLDEF(glGenBuffers, tsglGenBuffers, tsglGenBuffers_ptr) \
GLDEF(glGenFramebuffers, tsglGenFramebuffers, tsglGenFramebuffers_ptr) \
GLDEF(glGenTextures, tsglGenTextures, tsglGenTextures_ptr) \
GLDEF(glGetActiveUniform, tsglGetActiveUniform, tsglGetActiveUniform_ptr) \
GLDEF(glGetProgramInfoLog, tsglGetProgramInfoLog, tsglGetProgramInfoLog_ptr) \
GLDEF(glGetProgramiv, tsglGetProgramiv, tsglGetProgramiv_ptr) \
GLDEF(glGetShaderInfoLog, tsglGetShaderInfoLog, tsglGetShaderInfoLog_ptr) \
GLDEF(glGetShaderiv, tsglGetShaderiv, tsglGetShaderiv_ptr) \
GLDEF(glGetString, tsglGetString, tsglGetString_ptr) \
GLDEF(glGetUniformLocation, tsglGetUniformLocation, tsglGetUniformLocation_ptr) \
GLDEF(glLinkProgram, tsglLinkProgram, tsglLinkProgram_ptr) \
GLDEF(glLoadIdentity, tsglLoadIdentity, tsglLoadIdentity_ptr) \
GLDEF(glMatrixMode, tsglMatrixMode, tsglMatrixMode_ptr) \
GLDEF(glNormalPointer, tsglNormalPointer, tsglNormalPointer_ptr) \
GLDEF(glOrtho, tsglOrtho, tsglOrtho_ptr) \
GLDEF(glPopMatrix, tsglPopMatrix, tsglPopMatrix_ptr) \
GLDEF(glPushMatrix, tsglPushMatrix, tsglPushMatrix_ptr) \
GLDEF(glReadBuffer, tsglReadBuffer, tsglReadBuffer_ptr) \
GLDEF(glReadPixels, tsglReadPixels, tsglReadPixels_ptr) \
GLDEF(glRotatef, tsglRotatef, tsglRotatef_ptr) \
GLDEF(glScalef, tsglScalef, tsglScalef_ptr) \
GLDEF(glScissor, tsglScissor, tsglScissor_ptr) \
GLDEF(glShaderSource, tsglShaderSource, tsglShaderSource_ptr) \
GLDEF(glTexCoordPointer, tsglTexCoordPointer, tsglTexCoordPointer_ptr) \
GLDEF(glTexImage2D, tsglTexImage2D, tsglTexImage2D_ptr) \
GLDEF(glTexParameterf, tsglTexParameterf, tsglTexParameterf_ptr) \
GLDEF(glTexParameteri, tsglTexParameteri, tsglTexParameteri_ptr) \
GLDEF(glTranslatef, tsglTranslatef, tsglTranslatef_ptr) \
GLDEF(glUniform1f, tsglUniform1f, tsglUniform1f_ptr) \
GLDEF(glUniform1i, tsglUniform1i, tsglUniform1i_ptr) \
GLDEF(glUniform2f, tsglUniform2f, tsglUniform2f_ptr) \
GLDEF(glUniform3f, tsglUniform3f, tsglUniform3f_ptr) \
GLDEF(glUniform3fv, tsglUniform3fv, tsglUniform3fv_ptr) \
GLDEF(glUniform4f, tsglUniform4f, tsglUniform4f_ptr) \
GLDEF(glUniform4fv, tsglUniform4fv, tsglUniform4fv_ptr) \
GLDEF(glUseProgram, tsglUseProgram, tsglUseProgram_ptr) \
GLDEF(glVertexPointer, tsglVertexPointer, tsglVertexPointer_ptr) \
GLDEF(glViewport, tsglViewport, tsglViewport_ptr)
// @END:gldefs@
#define GLDEF(glname,tsname,typename) extern typename tsname;
GLDEFS
#undef GLDEF
#endif // !LINK_TO_LIBGL
#ifdef LINK_TO_LIBGL
// @BEGIN:protos@
GLAPI void GLAPIENTRY glActiveTexture( GLenum texture );
GLAPI void APIENTRY glAttachShader (GLuint program, GLuint shader);
GLAPI void APIENTRY glBindBuffer (GLenum target, GLuint buffer);
GLAPI void APIENTRY glBindFramebuffer (GLenum target, GLuint framebuffer);
GLAPI void GLAPIENTRY glBindTexture( GLenum target, GLuint texture );
GLAPI void GLAPIENTRY glBlendEquation( GLenum mode );
GLAPI void GLAPIENTRY glBlendFunc( GLenum sfactor, GLenum dfactor );
GLAPI void APIENTRY glBlendFuncSeparate (GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha);
GLAPI void APIENTRY glBufferData (GLenum target, GLsizeiptr size, const void *data, GLenum usage);
GLAPI void APIENTRY glBufferSubData (GLenum target, GLintptr offset, GLsizeiptr size, const void *data);
GLAPI void GLAPIENTRY glClear( GLbitfield mask );
GLAPI void GLAPIENTRY glClearColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha );
GLAPI void GLAPIENTRY glColor3f( GLfloat red, GLfloat green, GLfloat blue );
GLAPI void GLAPIENTRY glColor4f( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha );
GLAPI void GLAPIENTRY glColor4fv( const GLfloat *v );
GLAPI void APIENTRY glCompileShader (GLuint shader);
GLAPI GLuint APIENTRY glCreateProgram (void);
GLAPI GLuint APIENTRY glCreateShader (GLenum type);
GLAPI void GLAPIENTRY glCullFace( GLenum mode );
GLAPI void APIENTRY glDeleteBuffers (GLsizei n, const GLuint *buffers);
GLAPI void APIENTRY glDeleteFramebuffers (GLsizei n, const GLuint *framebuffers);
GLAPI void APIENTRY glDeleteProgram (GLuint program);
GLAPI void APIENTRY glDeleteShader (GLuint shader);
GLAPI void GLAPIENTRY glDeleteTextures( GLsizei n, const GLuint *textures);
GLAPI void GLAPIENTRY glDepthFunc( GLenum func );
GLAPI void GLAPIENTRY glDisable( GLenum cap );
GLAPI void GLAPIENTRY glDrawArrays( GLenum mode, GLint first, GLsizei count );
GLAPI void APIENTRY glDrawArraysInstanced (GLenum mode, GLint first, GLsizei count, GLsizei instancecount);
GLAPI void APIENTRY glDrawArraysInstancedARB (GLenum mode, GLint first, GLsizei count, GLsizei primcount);
GLAPI void APIENTRY glDrawArraysInstancedEXT (GLenum mode, GLint start, GLsizei count, GLsizei primcount);
GLAPI void GLAPIENTRY glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices );
GLAPI void GLAPIENTRY glEnable( GLenum cap );
GLAPI void GLAPIENTRY glEnableClientState( GLenum cap );
GLAPI void APIENTRY glFramebufferTexture2D (GLenum target, GLenum attachment, GLenum textarget, GLuint texture, GLint level);
GLAPI void GLAPIENTRY glFrustum( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val );
GLAPI void APIENTRY glGenBuffers (GLsizei n, GLuint *buffers);
GLAPI void APIENTRY glGenFramebuffers (GLsizei n, GLuint *framebuffers);
GLAPI void GLAPIENTRY glGenTextures( GLsizei n, GLuint *textures );
GLAPI void APIENTRY glGetActiveUniform (GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name);
GLAPI void APIENTRY glGetProgramInfoLog (GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
GLAPI void APIENTRY glGetProgramiv (GLuint program, GLenum pname, GLint *params);
GLAPI void APIENTRY glGetShaderInfoLog (GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog);
GLAPI void APIENTRY glGetShaderiv (GLuint shader, GLenum pname, GLint *params);
GLAPI const GLubyte * GLAPIENTRY glGetString( GLenum name );
GLAPI GLint APIENTRY glGetUniformLocation (GLuint program, const GLchar *name);
GLAPI void APIENTRY glLinkProgram (GLuint program);
GLAPI void GLAPIENTRY glLoadIdentity( void );
GLAPI void GLAPIENTRY glMatrixMode( GLenum mode );
GLAPI void GLAPIENTRY glNormalPointer( GLenum type, GLsizei stride, const GLvoid *ptr );
GLAPI void GLAPIENTRY glOrtho( GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble near_val, GLdouble far_val );
GLAPI void GLAPIENTRY glPopMatrix( void );
GLAPI void GLAPIENTRY glPushMatrix( void );
GLAPI void GLAPIENTRY glReadBuffer( GLenum mode );
GLAPI void GLAPIENTRY glReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, GLvoid *pixels );
GLAPI void GLAPIENTRY glRotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z );
GLAPI void GLAPIENTRY glScalef( GLfloat x, GLfloat y, GLfloat z );
GLAPI void GLAPIENTRY glScissor( GLint x, GLint y, GLsizei width, GLsizei height);
GLAPI void APIENTRY glShaderSource (GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length);
GLAPI void GLAPIENTRY glTexCoordPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr );
GLAPI void GLAPIENTRY glTexImage2D( GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels );
GLAPI void GLAPIENTRY glTexParameterf( GLenum target, GLenum pname, GLfloat param );
GLAPI void GLAPIENTRY glTexParameteri( GLenum target, GLenum pname, GLint param );
GLAPI void GLAPIENTRY glTranslatef( GLfloat x, GLfloat y, GLfloat z );
GLAPI void APIENTRY glUniform1f (GLint location, GLfloat v0);
GLAPI void APIENTRY glUniform1i (GLint location, GLint v0);
GLAPI void APIENTRY glUniform2f (GLint location, GLfloat v0, GLfloat v1);
GLAPI void APIENTRY glUniform3f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2);
GLAPI void APIENTRY glUniform3fv (GLint location, GLsizei count, const GLfloat *value);
GLAPI void APIENTRY glUniform4f (GLint location, GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3);
GLAPI void APIENTRY glUniform4fv (GLint location, GLsizei count, const GLfloat *value);
GLAPI void APIENTRY glUseProgram (GLuint program);
GLAPI void GLAPIENTRY glVertexPointer( GLint size, GLenum type, GLsizei stride, const GLvoid *ptr );
GLAPI void GLAPIENTRY glViewport( GLint x, GLint y, GLsizei width, GLsizei height );
// @END:protos@
// @BEGIN:reversedefs@
#define tsglActiveTexture glActiveTexture
#define tsglAttachShader glAttachShader
#define tsglBindBuffer glBindBuffer
#define tsglBindFramebuffer glBindFramebuffer
#define tsglBindTexture glBindTexture
#define tsglBlendEquation glBlendEquation
#define tsglBlendFunc glBlendFunc
#define tsglBlendFuncSeparate glBlendFuncSeparate
#define tsglBufferData glBufferData
#define tsglBufferSubData glBufferSubData
#define tsglClear glClear
#define tsglClearColor glClearColor
#define tsglColor3f glColor3f
#define tsglColor4f glColor4f
#define tsglColor4fv glColor4fv
#define tsglCompileShader glCompileShader
#define tsglCreateProgram glCreateProgram
#define tsglCreateShader glCreateShader
#define tsglCullFace glCullFace
#define tsglDeleteBuffers glDeleteBuffers
#define tsglDeleteFramebuffers glDeleteFramebuffers
#define tsglDeleteProgram glDeleteProgram
#define tsglDeleteShader glDeleteShader
#define tsglDeleteTextures glDeleteTextures
#define tsglDepthFunc glDepthFunc
#define tsglDisable glDisable
#define tsglDrawArrays glDrawArrays
#define tsglDrawArraysInstanced glDrawArraysInstanced
#define tsglDrawArraysInstancedARB glDrawArraysInstancedARB
#define tsglDrawArraysInstancedEXT glDrawArraysInstancedEXT
#define tsglDrawElements glDrawElements
#define tsglEnable glEnable
#define tsglEnableClientState glEnableClientState
#define tsglFramebufferTexture2D glFramebufferTexture2D
#define tsglFrustum glFrustum
#define tsglGenBuffers glGenBuffers
#define tsglGenFramebuffers glGenFramebuffers
#define tsglGenTextures glGenTextures
#define tsglGetActiveUniform glGetActiveUniform
#define tsglGetProgramInfoLog glGetProgramInfoLog
#define tsglGetProgramiv glGetProgramiv
#define tsglGetShaderInfoLog glGetShaderInfoLog
#define tsglGetShaderiv glGetShaderiv
#define tsglGetString glGetString
#define tsglGetUniformLocation glGetUniformLocation
#define tsglLinkProgram glLinkProgram
#define tsglLoadIdentity glLoadIdentity
#define tsglMatrixMode glMatrixMode
#define tsglNormalPointer glNormalPointer
#define tsglOrtho glOrtho
#define tsglPopMatrix glPopMatrix
#define tsglPushMatrix glPushMatrix
#define tsglReadBuffer glReadBuffer
#define tsglReadPixels glReadPixels
#define tsglRotatef glRotatef
#define tsglScalef glScalef
#define tsglScissor glScissor
#define tsglShaderSource glShaderSource
#define tsglTexCoordPointer glTexCoordPointer
#define tsglTexImage2D glTexImage2D
#define tsglTexParameterf glTexParameterf
#define tsglTexParameteri glTexParameteri
#define tsglTranslatef glTranslatef
#define tsglUniform1f glUniform1f
#define tsglUniform1i glUniform1i
#define tsglUniform2f glUniform2f
#define tsglUniform3f glUniform3f
#define tsglUniform3fv glUniform3fv
#define tsglUniform4f glUniform4f
#define tsglUniform4fv glUniform4fv
#define tsglUseProgram glUseProgram
#define tsglVertexPointer glVertexPointer
#define tsglViewport glViewport
// @END:reversedefs@
#endif // LINK_TO_LIBGL
struct glext_s {
struct {
char major;
char minor;
} version;
int draw_instanced: 1;
int EXT_draw_instanced: 1;
int ARB_draw_instanced: 1;
tsglDrawArraysInstanced_ptr DrawArraysInstanced;
};
#endif // !TAISEIGL_H
// Intentionally not guarded
#ifndef TAISEIGL_NO_EXT_ABSTRACTION
#undef glDrawArraysInstanced
#undef glDrawElementsInstanced
#define glDrawArraysInstanced (glext.DrawArraysInstanced)
#elif defined(LINK_TO_LIBGL)
#undef glDrawArraysInstanced
#endif // !TAISEIGL_NO_EXT_ABSTRACTION
#define glDrawArraysInstanced glDrawArraysInstancedARB
#define glDrawElementsInstanced glDrawElementsInstancedARB
#endif
#endif
// Don't even think about touching the construct below
/*
"""
#*/

View file

@ -11,37 +11,43 @@
Transition transition;
void TransFadeBlack(Transition *t) {
fade_out(t->fade);
void TransFadeBlack(double fade) {
fade_out(fade);
}
void TransFadeWhite(Transition *t) {
colorfill(1,1,1,t->fade);
void TransFadeWhite(double fade) {
colorfill(1, 1, 1, fade);
}
void TransLoader(Transition *t) {
glColor4f(1,1,1,t->fade);
draw_texture(SCREEN_W/2,SCREEN_H/2,"loading");
glColor4f(1,1,1,1);
void TransLoader(double fade) {
glColor4f(1, 1, 1, fade);
draw_texture(SCREEN_W/2, SCREEN_H/2, "loading");
glColor4f(1, 1, 1, 1);
}
void TransMenu(Transition *t) {
glColor4f(1,1,1,t->fade);
void TransMenu(double fade) {
glColor4f(1, 1, 1, fade);
draw_texture(SCREEN_W/2, SCREEN_H/2, "mainmenu/mainmenubg");
glColor4f(1, 1, 1, 1);
}
void TransMenuDark(Transition *t) {
glColor4f(0.3,0.3,0.3,t->fade);
void TransMenuDark(double fade) {
glColor4f(0.3, 0.3, 0.3, fade);
draw_texture(SCREEN_W/2, SCREEN_H/2, "mainmenu/mainmenubg");
glColor4f(1, 1, 1, 1);
}
void TransEmpty(Transition *t) { }
void TransEmpty(double fade) { }
static bool popq(void) {
if(transition.queued.rule) {
transition.rule2 = transition.rule;
transition.rule = transition.queued.rule;
if(transition.state == TRANS_IDLE || transition.rule2 == transition.rule) {
transition.rule2 = NULL;
}
transition.dur1 = transition.queued.dur1;
transition.dur2 = transition.queued.dur2;
transition.callback = transition.queued.callback;
@ -88,6 +94,7 @@ void set_transition_callback(TransitionRule rule, int dur1, int dur2, Transition
if(!initialized) {
popq();
initialized = true;
transition.rule2 = NULL;
}
if(transition.state == TRANS_IDLE || rule == transition.rule) {
@ -99,23 +106,44 @@ void set_transition(TransitionRule rule, int dur1, int dur2) {
set_transition_callback(rule, dur1, dur2, NULL, NULL);
}
void draw_transition(void) {
static bool check_transition(void) {
if(transition.state == TRANS_IDLE) {
return;
return false;
}
if(!transition.rule) {
transition.state = TRANS_IDLE;
return false;
}
return true;
}
void draw_transition(void) {
if(!check_transition()) {
return;
}
transition.rule(&transition);
transition.rule(transition.fade);
if(transition.rule2 && transition.rule2 != transition.rule) {
transition.rule2(transition.fade);
}
}
void update_transition(void) {
if(!check_transition()) {
return;
}
if(transition.state == TRANS_FADE_IN) {
transition.fade = approach(transition.fade, 1.0, 1.0/transition.dur1);
if(transition.fade == 1.0) {
transition.state = TRANS_FADE_OUT;
call_callback();
if(popq()) {
call_callback();
}
}
} else if(transition.state == TRANS_FADE_OUT) {
transition.fade = transition.dur2 ? approach(transition.fade, 0.0, 1.0/transition.dur2) : 0.0;
@ -126,3 +154,7 @@ void draw_transition(void) {
}
}
void draw_and_update_transition(void) {
draw_transition();
update_transition();
}

View file

@ -11,7 +11,7 @@
#include <stdbool.h>
typedef struct Transition Transition;
typedef void (*TransitionRule)(Transition *t);
typedef void (*TransitionRule)(double fade);
typedef void (*TransitionCallback)(void *a);
struct Transition {
@ -28,6 +28,7 @@ struct Transition {
} state;
TransitionRule rule;
TransitionRule rule2;
struct {
int dur1;
@ -40,15 +41,17 @@ struct Transition {
extern Transition transition;
void TransFadeBlack(Transition *t);
void TransFadeWhite(Transition *t);
void TransLoader(Transition *t);
void TransMenu(Transition *t);
void TransMenuDark(Transition *t);
void TransEmpty(Transition *t);
void TransFadeBlack(double fade);
void TransFadeWhite(double fade);
void TransLoader(double fade);
void TransMenu(double fade);
void TransMenuDark(double fade);
void TransEmpty(double fade);
void set_transition(TransitionRule rule, int dur1, int dur2);
void set_transition_callback(TransitionRule rule, int dur1, int dur2, TransitionCallback cb, void *arg);
void draw_transition(void);
void update_transition(void);
void draw_and_update_transition(void);
#endif

View file

@ -9,6 +9,9 @@
#include "global.h"
#include "video.h"
#include "taisei_err.h"
#include "taiseigl.h"
static bool libgl_loaded = false;
static VideoMode common_modes[] = {
{RESX, RESY},
@ -76,9 +79,32 @@ void video_update_vsync(void) {
}
}
static void video_init_gl(void) {
video.glcontext = SDL_GL_CreateContext(video.window);
load_gl_functions();
check_gl_extensions();
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
glEnable(GL_CULL_FACE);
glEnable(GL_BLEND);
init_quadvbo();
glClear(GL_COLOR_BUFFER_BIT);
}
static void _video_setmode(int w, int h, int fs, int fallback) {
Uint32 flags = SDL_WINDOW_OPENGL;
if(!libgl_loaded) {
load_gl_library();
libgl_loaded = true;
}
if(fs) {
flags |= SDL_WINDOW_FULLSCREEN;
} else {
@ -95,13 +121,15 @@ static void _video_setmode(int w, int h, int fs, int fallback) {
video.window = NULL;
}
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
video.window = SDL_CreateWindow(WINDOW_TITLE, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, w, h, flags);
if(video.window) {
if(video.glcontext) {
SDL_GL_MakeCurrent(video.window, video.glcontext);
} else {
video.glcontext = SDL_GL_CreateContext(video.window);
video_init_gl();
}
if(!video.glcontext) {