Merge branch 'master' into extraspells
This commit is contained in:
commit
248210f575
61 changed files with 1648 additions and 761 deletions
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -2,3 +2,7 @@ build/
|
|||
winbuild/
|
||||
osxbuild/
|
||||
.ctagsdb
|
||||
.*DS_Store
|
||||
|
||||
# autogenerated
|
||||
*.out
|
||||
|
|
|
@ -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
BIN
OSX-iconset.icns
Normal file
Binary file not shown.
20
scripts/OSXInstallDylibs.cmake.in
Normal file
20
scripts/OSXInstallDylibs.cmake.in
Normal 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
13
scripts/osx-gen-dmg.sh
Executable 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
56
scripts/osx-install-dylibs.sh
Executable 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"
|
|
@ -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%%
|
||||
|
|
|
@ -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)
|
||||
|
|
22
src/boss.h
22
src/boss.h
|
@ -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
25
src/color.c
Normal 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
22
src/color.h
Normal 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
|
|
@ -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
31
src/difficulty.c
Normal 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
30
src/difficulty.h
Normal 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
|
|
@ -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) {
|
||||
|
|
25
src/global.c
25
src/global.c
|
@ -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);
|
||||
|
||||
|
|
12
src/global.h
12
src/global.h
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
34
src/main.c
34
src/main.c
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include "difficulty.h"
|
||||
#include "difficultyselect.h"
|
||||
#include "options.h"
|
||||
#include "common.h"
|
||||
#include "global.h"
|
|
@ -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"
|
||||
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#define TSRAND_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct RandomState {
|
||||
uint32_t w;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
473
src/stage.c
473
src/stage.c
|
@ -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);
|
||||
|
|
53
src/stage.h
53
src/stage.h
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
181
src/taiseigl.c
181
src/taiseigl.c
|
@ -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);
|
||||
}
|
||||
|
|
668
src/taiseigl.h
668
src/taiseigl.h
|
@ -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
|
||||
/*
|
||||
"""
|
||||
#*/
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
30
src/video.c
30
src/video.c
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue