2010-10-12 10:55:23 +02:00
|
|
|
/*
|
2011-03-05 13:44:21 +01:00
|
|
|
* This software is licensed under the terms of the MIT-License
|
2017-02-10 23:05:22 +01:00
|
|
|
* See COPYING for further information.
|
2011-03-05 13:44:21 +01:00
|
|
|
* ---
|
|
|
|
* Copyright (C) 2011, Lukas Weber <laochailan@web.de>
|
2010-10-12 10:55:23 +02:00
|
|
|
*/
|
|
|
|
|
2017-02-07 19:34:55 +01:00
|
|
|
#include <complex.h>
|
|
|
|
|
2010-10-12 10:55:23 +02:00
|
|
|
#include "stage.h"
|
2017-02-07 19:34:55 +01:00
|
|
|
#include "tscomplex.h"
|
2010-10-12 10:55:23 +02:00
|
|
|
|
2012-07-14 19:46:03 +02:00
|
|
|
#include <time.h>
|
2010-10-12 10:55:23 +02:00
|
|
|
#include "global.h"
|
2012-07-28 22:53:53 +02:00
|
|
|
#include "video.h"
|
2017-01-24 14:40:57 +01:00
|
|
|
#include "resource/bgm.h"
|
2012-07-14 16:37:52 +02:00
|
|
|
#include "replay.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "player.h"
|
2011-06-13 18:48:36 +02:00
|
|
|
#include "menu/ingamemenu.h"
|
2012-08-17 20:58:23 +02:00
|
|
|
#include "menu/gameovermenu.h"
|
2012-08-14 21:34:04 +02:00
|
|
|
#include "taisei_err.h"
|
2010-10-12 10:55:23 +02:00
|
|
|
|
2017-02-03 16:56:36 +01:00
|
|
|
StageInfo stages[] = {
|
2017-02-10 11:39:42 +01:00
|
|
|
//
|
|
|
|
// 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
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
// Story stages
|
|
|
|
//
|
|
|
|
|
|
|
|
// 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},
|
|
|
|
|
|
|
|
//
|
|
|
|
// Spell practice stages
|
|
|
|
//
|
|
|
|
// subtitles for those are generated later by stage_init_array()
|
|
|
|
//
|
|
|
|
|
|
|
|
#define S STAGE_SPELL_BIT
|
|
|
|
// Freeze Sign ~ Perfect Freeze
|
|
|
|
{S| 0, stage1_spellpractice_loop, STAGE_SPELL, "Spell 1", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Easy},
|
|
|
|
{S| 1, stage1_spellpractice_loop, STAGE_SPELL, "Spell 2", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Normal},
|
|
|
|
{S| 2, stage1_spellpractice_loop, STAGE_SPELL, "Spell 3", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Hard},
|
|
|
|
{S| 3, stage1_spellpractice_loop, STAGE_SPELL, "Spell 4", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+0, D_Lunatic},
|
|
|
|
|
|
|
|
// Freeze Sign ~ Crystal Rain
|
|
|
|
{S| 4, stage1_spellpractice_loop, STAGE_SPELL, "Spell 5", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Easy},
|
|
|
|
{S| 5, stage1_spellpractice_loop, STAGE_SPELL, "Spell 6", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Normal},
|
|
|
|
{S| 6, stage1_spellpractice_loop, STAGE_SPELL, "Spell 7", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Hard},
|
|
|
|
{S| 7, stage1_spellpractice_loop, STAGE_SPELL, "Spell 8", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+1, D_Lunatic},
|
|
|
|
|
|
|
|
// Doom Sign ~ Icicle Fall
|
|
|
|
{S| 8, stage1_spellpractice_loop, STAGE_SPELL, "Spell 9", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Easy},
|
|
|
|
{S| 9, stage1_spellpractice_loop, STAGE_SPELL, "Spell 10", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Normal},
|
|
|
|
{S| 10, stage1_spellpractice_loop, STAGE_SPELL, "Spell 11", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Hard},
|
|
|
|
{S| 11, stage1_spellpractice_loop, STAGE_SPELL, "Spell 12", NULL, {1, 1, 1}, {1, 1, 1}, stage1_spells+2, D_Lunatic},
|
|
|
|
|
|
|
|
// Shard ~ Amulet of Harm
|
|
|
|
{S| 12, stage2_spellpractice_loop, STAGE_SPELL, "Spell 13", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Easy},
|
|
|
|
{S| 13, stage2_spellpractice_loop, STAGE_SPELL, "Spell 14", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Normal},
|
|
|
|
{S| 14, stage2_spellpractice_loop, STAGE_SPELL, "Spell 15", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Hard},
|
|
|
|
{S| 15, stage2_spellpractice_loop, STAGE_SPELL, "Spell 16", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+0, D_Lunatic},
|
|
|
|
|
|
|
|
// Lottery Sign ~ Bad Pick
|
|
|
|
{S| 16, stage2_spellpractice_loop, STAGE_SPELL, "Spell 17", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Easy},
|
|
|
|
{S| 17, stage2_spellpractice_loop, STAGE_SPELL, "Spell 18", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Normal},
|
|
|
|
{S| 18, stage2_spellpractice_loop, STAGE_SPELL, "Spell 19", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Hard},
|
|
|
|
{S| 19, stage2_spellpractice_loop, STAGE_SPELL, "Spell 20", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+1, D_Lunatic},
|
|
|
|
|
|
|
|
// Lottery Sign ~ Wheel of Fortune
|
|
|
|
{S| 20, stage2_spellpractice_loop, STAGE_SPELL, "Spell 21", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Easy},
|
|
|
|
{S| 21, stage2_spellpractice_loop, STAGE_SPELL, "Spell 22", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Normal},
|
|
|
|
{S| 22, stage2_spellpractice_loop, STAGE_SPELL, "Spell 23", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Hard},
|
|
|
|
{S| 23, stage2_spellpractice_loop, STAGE_SPELL, "Spell 24", NULL, {1, 1, 1}, {1, 1, 1}, stage2_spells+2, D_Lunatic},
|
|
|
|
|
|
|
|
// Venom Sign ~ Deadly Dance
|
|
|
|
{S| 24, stage3_spellpractice_loop, STAGE_SPELL, "Spell 25", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Easy},
|
|
|
|
{S| 25, stage3_spellpractice_loop, STAGE_SPELL, "Spell 26", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Normal},
|
|
|
|
{S| 26, stage3_spellpractice_loop, STAGE_SPELL, "Spell 27", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Hard},
|
|
|
|
{S| 27, stage3_spellpractice_loop, STAGE_SPELL, "Spell 28", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+0, D_Lunatic},
|
|
|
|
|
|
|
|
// Venom Sign ~ Acid Rain
|
|
|
|
{S| 28, stage3_spellpractice_loop, STAGE_SPELL, "Spell 29", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+1, D_Hard},
|
|
|
|
{S| 29, stage3_spellpractice_loop, STAGE_SPELL, "Spell 30", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+1, D_Lunatic},
|
|
|
|
|
|
|
|
// Firefly Sign ~ Moonlight Rocket
|
|
|
|
{S| 30, stage3_spellpractice_loop, STAGE_SPELL, "Spell 31", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Easy},
|
|
|
|
{S| 31, stage3_spellpractice_loop, STAGE_SPELL, "Spell 32", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Normal},
|
|
|
|
{S| 32, stage3_spellpractice_loop, STAGE_SPELL, "Spell 33", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Hard},
|
|
|
|
{S| 33, stage3_spellpractice_loop, STAGE_SPELL, "Spell 34", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+2, D_Lunatic},
|
|
|
|
|
|
|
|
// Light Source ~ Wriggle Night Ignite
|
|
|
|
{S| 34, stage3_spellpractice_loop, STAGE_SPELL, "Spell 35", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Easy},
|
|
|
|
{S| 35, stage3_spellpractice_loop, STAGE_SPELL, "Spell 36", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Normal},
|
|
|
|
{S| 36, stage3_spellpractice_loop, STAGE_SPELL, "Spell 37", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Hard},
|
|
|
|
{S| 37, stage3_spellpractice_loop, STAGE_SPELL, "Spell 38", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+3, D_Lunatic},
|
|
|
|
|
|
|
|
// Bug Sign ~ Phosphaenus Hemipterus
|
|
|
|
{S| 38, stage3_spellpractice_loop, STAGE_SPELL, "Spell 39", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Easy},
|
|
|
|
{S| 39, stage3_spellpractice_loop, STAGE_SPELL, "Spell 40", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Normal},
|
|
|
|
{S| 40, stage3_spellpractice_loop, STAGE_SPELL, "Spell 41", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Hard},
|
|
|
|
{S| 41, stage3_spellpractice_loop, STAGE_SPELL, "Spell 42", NULL, {0, 0, 0}, {0, 0, 0}, stage3_spells+4, D_Lunatic},
|
|
|
|
|
|
|
|
// Bloodless ~ Gate of Walachia
|
|
|
|
{S| 42, stage4_spellpractice_loop, STAGE_SPELL, "Spell 43", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Easy},
|
|
|
|
{S| 43, stage4_spellpractice_loop, STAGE_SPELL, "Spell 44", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Normal},
|
|
|
|
{S| 44, stage4_spellpractice_loop, STAGE_SPELL, "Spell 45", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Hard},
|
|
|
|
{S| 45, stage4_spellpractice_loop, STAGE_SPELL, "Spell 46", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+0, D_Lunatic},
|
|
|
|
|
|
|
|
// Bloodless ~ Dry Fountain
|
|
|
|
{S| 46, stage4_spellpractice_loop, STAGE_SPELL, "Spell 47", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+1, D_Easy},
|
|
|
|
{S| 47, stage4_spellpractice_loop, STAGE_SPELL, "Spell 48", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+1, D_Normal},
|
|
|
|
|
|
|
|
// Bloodless ~ Red Spike
|
|
|
|
{S| 48, stage4_spellpractice_loop, STAGE_SPELL, "Spell 49", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+2, D_Hard},
|
|
|
|
{S| 49, stage4_spellpractice_loop, STAGE_SPELL, "Spell 50", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+2, D_Lunatic},
|
|
|
|
|
|
|
|
// Limit ~ Animate Wall
|
|
|
|
{S| 50, stage4_spellpractice_loop, STAGE_SPELL, "Spell 51", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+3, D_Easy},
|
|
|
|
{S| 51, stage4_spellpractice_loop, STAGE_SPELL, "Spell 52", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+3, D_Normal},
|
|
|
|
|
|
|
|
// Summoning ~ Demon Wall
|
|
|
|
{S| 52, stage4_spellpractice_loop, STAGE_SPELL, "Spell 53", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+4, D_Hard},
|
|
|
|
{S| 53, stage4_spellpractice_loop, STAGE_SPELL, "Spell 54", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+4, D_Lunatic},
|
|
|
|
|
|
|
|
// Power Sign ~ Blow the Walls
|
|
|
|
{S| 54, stage4_spellpractice_loop, STAGE_SPELL, "Spell 55", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Easy},
|
|
|
|
{S| 55, stage4_spellpractice_loop, STAGE_SPELL, "Spell 56", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Normal},
|
|
|
|
{S| 56, stage4_spellpractice_loop, STAGE_SPELL, "Spell 57", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Hard},
|
|
|
|
{S| 57, stage4_spellpractice_loop, STAGE_SPELL, "Spell 58", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+5, D_Lunatic},
|
|
|
|
|
|
|
|
// Fear Sign ~ Bloody Danmaku
|
|
|
|
{S| 58, stage4_spellpractice_loop, STAGE_SPELL, "Spell 59", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+6, D_Hard},
|
|
|
|
{S| 59, stage4_spellpractice_loop, STAGE_SPELL, "Spell 60", NULL, {1, 1, 1}, {1, 1, 1}, stage4_spells+6, D_Lunatic},
|
|
|
|
|
|
|
|
// High Voltage ~ Atmospheric Discharge
|
|
|
|
{S| 60, stage5_spellpractice_loop, STAGE_SPELL, "Spell 61", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Easy},
|
|
|
|
{S| 61, stage5_spellpractice_loop, STAGE_SPELL, "Spell 62", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Normal},
|
|
|
|
{S| 62, stage5_spellpractice_loop, STAGE_SPELL, "Spell 63", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Hard},
|
|
|
|
{S| 63, stage5_spellpractice_loop, STAGE_SPELL, "Spell 64", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+0, D_Lunatic},
|
|
|
|
|
|
|
|
// Charge Sign ~ Artificial Lightning
|
|
|
|
{S| 64, stage5_spellpractice_loop, STAGE_SPELL, "Spell 65", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Easy},
|
|
|
|
{S| 65, stage5_spellpractice_loop, STAGE_SPELL, "Spell 66", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Normal},
|
|
|
|
{S| 66, stage5_spellpractice_loop, STAGE_SPELL, "Spell 67", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Hard},
|
|
|
|
{S| 67, stage5_spellpractice_loop, STAGE_SPELL, "Spell 68", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+1, D_Lunatic},
|
|
|
|
|
|
|
|
// Spark Sign ~ Natural Cathode
|
|
|
|
{S| 68, stage5_spellpractice_loop, STAGE_SPELL, "Spell 69", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Easy},
|
|
|
|
{S| 69, stage5_spellpractice_loop, STAGE_SPELL, "Spell 70", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Normal},
|
|
|
|
{S| 70, stage5_spellpractice_loop, STAGE_SPELL, "Spell 71", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Hard},
|
|
|
|
{S| 71, stage5_spellpractice_loop, STAGE_SPELL, "Spell 72", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+2, D_Lunatic},
|
|
|
|
|
|
|
|
// Current Sign ~ Induction
|
|
|
|
{S| 72, stage5_spellpractice_loop, STAGE_SPELL, "Spell 73", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+3, D_Easy},
|
|
|
|
{S| 73, stage5_spellpractice_loop, STAGE_SPELL, "Spell 74", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+3, D_Normal},
|
|
|
|
{S| 74, stage5_spellpractice_loop, STAGE_SPELL, "Spell 75", NULL, {1, 1, 1}, {1, 1, 1}, stage5_spells+3, D_Hard},
|
|
|
|
{S| 75, stage5_spellpractice_loop, STAGE_SPELL, "Spell 76", 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, "Spell 77", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Easy},
|
|
|
|
{S| 77, stage6_spellpractice_loop, STAGE_SPELL, "Spell 78", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Normal},
|
|
|
|
{S| 78, stage6_spellpractice_loop, STAGE_SPELL, "Spell 79", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Hard},
|
|
|
|
{S| 79, stage6_spellpractice_loop, STAGE_SPELL, "Spell 80", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+0, D_Lunatic},
|
|
|
|
|
|
|
|
// Maxwell Sign ~ Wave Theory
|
|
|
|
{S| 80, stage6_spellpractice_loop, STAGE_SPELL, "Spell 81", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Easy},
|
|
|
|
{S| 81, stage6_spellpractice_loop, STAGE_SPELL, "Spell 82", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Normal},
|
|
|
|
{S| 82, stage6_spellpractice_loop, STAGE_SPELL, "Spell 83", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Hard},
|
|
|
|
{S| 83, stage6_spellpractice_loop, STAGE_SPELL, "Spell 84", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+1, D_Lunatic},
|
|
|
|
|
|
|
|
// Eigenstate ~ Many-World Interpretation
|
|
|
|
{S| 84, stage6_spellpractice_loop, STAGE_SPELL, "Spell 85", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Easy},
|
|
|
|
{S| 85, stage6_spellpractice_loop, STAGE_SPELL, "Spell 86", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Normal},
|
|
|
|
{S| 86, stage6_spellpractice_loop, STAGE_SPELL, "Spell 87", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Hard},
|
|
|
|
{S| 87, stage6_spellpractice_loop, STAGE_SPELL, "Spell 88", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+2, D_Lunatic},
|
|
|
|
|
|
|
|
// Ricci Sign ~ Space Time Curvature
|
|
|
|
{S| 88, stage6_spellpractice_loop, STAGE_SPELL, "Spell 89", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Easy},
|
|
|
|
{S| 89, stage6_spellpractice_loop, STAGE_SPELL, "Spell 90", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Normal},
|
|
|
|
{S| 90, stage6_spellpractice_loop, STAGE_SPELL, "Spell 91", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Hard},
|
|
|
|
{S| 91, stage6_spellpractice_loop, STAGE_SPELL, "Spell 92", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+3, D_Lunatic},
|
|
|
|
|
|
|
|
// LHC ~ Higgs Boson Uncovered
|
|
|
|
{S| 92, stage6_spellpractice_loop, STAGE_SPELL, "Spell 93", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+4, D_Easy},
|
|
|
|
{S| 93, stage6_spellpractice_loop, STAGE_SPELL, "Spell 94", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+4, D_Normal},
|
|
|
|
{S| 94, stage6_spellpractice_loop, STAGE_SPELL, "Spell 95", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+4, D_Hard},
|
|
|
|
{S| 95, stage6_spellpractice_loop, STAGE_SPELL, "Spell 96", 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, "Spell 97", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Easy},
|
|
|
|
{S| 97, stage6_spellpractice_loop, STAGE_SPELL, "Spell 98", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Normal},
|
|
|
|
{S| 98, stage6_spellpractice_loop, STAGE_SPELL, "Spell 99", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Hard},
|
|
|
|
{S| 99, stage6_spellpractice_loop, STAGE_SPELL, "Spell 100", NULL, {1, 1, 1}, {1, 1, 1}, stage6_spells+5, D_Lunatic},
|
|
|
|
#undef S
|
2017-02-11 04:52:08 +01:00
|
|
|
|
|
|
|
{0}
|
2012-07-14 09:40:37 +02:00
|
|
|
};
|
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
void stage_init_array(void) {
|
|
|
|
for(int i = 0; stages[i].loop; ++i) {
|
2017-02-11 12:38:50 +01:00
|
|
|
// we will allocate this later on demand
|
|
|
|
stages[i].progress = NULL;
|
2017-02-11 10:52:37 +01:00
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
if(stages[i].type == STAGE_SPELL) {
|
|
|
|
char *s, *postfix = difficulty_name(stages[i].difficulty);
|
|
|
|
|
|
|
|
// note: never free()'d
|
|
|
|
stages[i].subtitle = s = malloc(strlen(postfix) + strlen(stages[i].spell->name) + 4);
|
|
|
|
strcpy(s, stages[i].spell->name);
|
|
|
|
strcat(s, " ~ ");
|
|
|
|
strcat(s, postfix);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
|
|
|
for(int j = 0; stages[j].loop; ++j) {
|
|
|
|
if(i != j && stages[i].id == stages[j].id) {
|
|
|
|
errx(-1, "Duplicate ID in stages array: %u", stages[i].id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-07-14 19:46:03 +02:00
|
|
|
// NOTE: This returns the stage BY ID, not by the array index!
|
2017-02-10 11:39:42 +01:00
|
|
|
StageInfo* stage_get(uint16_t n) {
|
|
|
|
for(StageInfo *stg = stages; stg->loop; ++stg)
|
|
|
|
if(stg->id == n)
|
|
|
|
return stg;
|
2012-07-14 09:40:37 +02:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-02-10 23:34:48 +01:00
|
|
|
StageInfo* stage_get_by_spellcard(AttackInfo *spell, Difficulty diff) {
|
|
|
|
if(!spell)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for(StageInfo *stg = stages; stg->loop; ++stg)
|
|
|
|
if(stg->spell == spell && stg->difficulty == diff)
|
|
|
|
return stg;
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-02-11 13:22:14 +01:00
|
|
|
StageProgress* stage_get_progress_from_info(StageInfo *stage, Difficulty diff, bool allocate) {
|
2017-02-11 12:38:50 +01:00
|
|
|
// D_Any stages will have a separate StageProgress for every selectable difficulty.
|
|
|
|
// Stages with a fixed difficulty setting (spellpractice, extra stage...) obviously get just one and the diff parameter is ignored.
|
|
|
|
|
|
|
|
// We never free anything we allocate here either. RAM's cheap right?
|
|
|
|
// This stuff must stay around until progress_save(), which happens on shutdown.
|
|
|
|
// So do NOT try to free any pointers this function returns, that will fuck everything up.
|
|
|
|
|
|
|
|
if(!stage) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool fixed_diff = (stage->difficulty != D_Any);
|
|
|
|
|
|
|
|
if(!fixed_diff && (diff < D_Easy || diff > D_Lunatic)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!stage->progress) {
|
2017-02-11 13:22:14 +01:00
|
|
|
if(!allocate) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2017-02-11 12:38:50 +01:00
|
|
|
size_t allocsize = sizeof(StageProgress) * (fixed_diff ? 1 : NUM_SELECTABLE_DIFFICULTIES);
|
|
|
|
stage->progress = malloc(allocsize);
|
|
|
|
memset(stage->progress, 0, allocsize);
|
|
|
|
#ifdef DEBUG
|
|
|
|
printf("stage_get_progress_from_info(): allocated %lu bytes for stage %u (%s: %s)\n", allocsize, stage->id, stage->title, stage->subtitle);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
return stage->progress + (fixed_diff ? 0 : diff - D_Easy);
|
|
|
|
}
|
|
|
|
|
2017-02-11 13:22:14 +01:00
|
|
|
StageProgress* stage_get_progress(uint16_t id, Difficulty diff, bool allocate) {
|
|
|
|
return stage_get_progress_from_info(stage_get(id), diff, allocate);
|
2017-02-11 12:38:50 +01:00
|
|
|
}
|
|
|
|
|
2012-08-10 22:08:51 +02:00
|
|
|
void stage_start(void) {
|
2011-05-08 13:48:25 +02:00
|
|
|
global.timer = 0;
|
2011-06-13 18:48:36 +02:00
|
|
|
global.frames = 0;
|
2017-02-10 11:39:42 +01:00
|
|
|
global.stageuiframes = 0;
|
2011-06-13 18:48:36 +02:00
|
|
|
global.game_over = 0;
|
2017-02-11 04:52:08 +01:00
|
|
|
global.nostagebg = false;
|
2012-08-07 17:01:26 +02:00
|
|
|
global.shake_view = 0;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-29 13:11:44 +02:00
|
|
|
global.fps.stagebg_fps = global.fps.show_fps = FPS;
|
2012-07-17 09:55:06 +02:00
|
|
|
global.fps.fpstime = SDL_GetTicks();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-15 17:09:09 +01:00
|
|
|
prepare_player_for_next_stage(&global.plr);
|
2010-10-12 10:55:23 +02:00
|
|
|
}
|
|
|
|
|
2012-08-17 20:58:23 +02:00
|
|
|
void stage_pause(void) {
|
2012-08-12 20:16:40 +02:00
|
|
|
MenuData menu;
|
2017-01-24 14:40:57 +01:00
|
|
|
stop_bgm();
|
2012-08-12 20:16:40 +02:00
|
|
|
create_ingame_menu(&menu);
|
|
|
|
ingame_menu_loop(&menu);
|
2017-01-24 14:40:57 +01:00
|
|
|
continue_bgm();
|
2012-07-14 16:37:52 +02:00
|
|
|
}
|
|
|
|
|
2012-08-17 20:58:23 +02:00
|
|
|
void stage_gameover(void) {
|
|
|
|
MenuData m;
|
2017-01-24 14:40:57 +01:00
|
|
|
save_bgm();
|
|
|
|
start_bgm("bgm_gameover");
|
2012-08-17 20:58:23 +02:00
|
|
|
create_gameover_menu(&m);
|
|
|
|
ingame_menu_loop(&m);
|
2017-01-24 14:40:57 +01:00
|
|
|
restore_bgm();
|
2012-08-17 20:58:23 +02:00
|
|
|
}
|
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
void stage_input_event(EventType type, int key, void *arg) {
|
|
|
|
switch(type) {
|
|
|
|
case E_PlrKeyDown:
|
2017-02-15 18:10:56 +01:00
|
|
|
if(key == KEY_HAHAIWIN) {
|
|
|
|
#ifdef DEBUG
|
|
|
|
global.game_over = GAMEOVER_WIN;
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
if(global.dialog && (key == KEY_SHOT || key == KEY_BOMB)) {
|
|
|
|
page_dialog(&global.dialog);
|
2017-02-10 00:24:19 +01:00
|
|
|
replay_stage_event(global.replay_stage, global.frames, EV_PRESS, key);
|
2012-08-13 17:50:28 +02:00
|
|
|
} else {
|
2017-02-11 02:56:34 +01:00
|
|
|
#ifndef DEBUG // no cheating for peasants
|
|
|
|
if(global.replaymode == REPLAY_RECORD && key == KEY_IDDQD)
|
|
|
|
break;
|
|
|
|
#endif
|
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
player_event(&global.plr, EV_PRESS, key);
|
2017-02-10 00:24:19 +01:00
|
|
|
replay_stage_event(global.replay_stage, global.frames, EV_PRESS, key);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-15 02:41:21 +02:00
|
|
|
if(key == KEY_SKIP && global.dialog) {
|
2017-02-11 04:52:08 +01:00
|
|
|
global.dialog->skip = true;
|
2012-08-15 02:41:21 +02:00
|
|
|
}
|
2012-08-13 17:50:28 +02:00
|
|
|
}
|
|
|
|
break;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
case E_PlrKeyUp:
|
|
|
|
player_event(&global.plr, EV_RELEASE, key);
|
2017-02-10 00:24:19 +01:00
|
|
|
replay_stage_event(global.replay_stage, global.frames, EV_RELEASE, key);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
if(key == KEY_SKIP && global.dialog)
|
2017-02-11 04:52:08 +01:00
|
|
|
global.dialog->skip = false;
|
2012-08-07 05:28:41 +02:00
|
|
|
break;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
case E_Pause:
|
2012-08-17 20:58:23 +02:00
|
|
|
stage_pause();
|
2012-08-13 17:50:28 +02:00
|
|
|
break;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-15 16:36:39 +02:00
|
|
|
case E_PlrAxisLR:
|
|
|
|
player_event(&global.plr, EV_AXIS_LR, key);
|
2017-02-10 00:24:19 +01:00
|
|
|
replay_stage_event(global.replay_stage, global.frames, EV_AXIS_LR, key);
|
2012-08-15 16:36:39 +02:00
|
|
|
break;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-15 16:36:39 +02:00
|
|
|
case E_PlrAxisUD:
|
|
|
|
player_event(&global.plr, EV_AXIS_UD, key);
|
2017-02-10 00:24:19 +01:00
|
|
|
replay_stage_event(global.replay_stage, global.frames, EV_AXIS_UD, key);
|
2012-08-15 16:36:39 +02:00
|
|
|
break;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
default: break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void stage_replay_event(EventType type, int state, void *arg) {
|
|
|
|
if(type == E_Pause)
|
2012-08-17 20:58:23 +02:00
|
|
|
stage_pause();
|
2012-08-13 17:50:28 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void replay_input(void) {
|
2017-02-10 00:24:19 +01:00
|
|
|
ReplayStage *s = global.replay_stage;
|
2012-07-14 19:46:03 +02:00
|
|
|
int i;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-13 17:50:28 +02:00
|
|
|
handle_events(stage_replay_event, EF_Game, NULL);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-09 05:06:46 +01:00
|
|
|
for(i = s->playpos; i < s->numevents; ++i) {
|
2012-08-07 05:28:41 +02:00
|
|
|
ReplayEvent *e = &(s->events[i]);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-29 15:35:40 +02:00
|
|
|
if(e->frame != global.frames)
|
|
|
|
break;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-29 15:35:40 +02:00
|
|
|
switch(e->type) {
|
2012-07-14 19:46:03 +02:00
|
|
|
case EV_OVER:
|
2012-08-04 06:37:59 +02:00
|
|
|
global.game_over = GAMEOVER_DEFEAT;
|
2012-07-14 19:46:03 +02:00
|
|
|
break;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-14 19:46:03 +02:00
|
|
|
default:
|
2017-02-05 03:04:31 +01:00
|
|
|
if(global.dialog && e->type == EV_PRESS && (e->value == KEY_SHOT || e->value == KEY_BOMB))
|
2012-07-14 19:46:03 +02:00
|
|
|
page_dialog(&global.dialog);
|
2017-02-05 03:58:27 +01:00
|
|
|
else if(global.dialog && (e->type == EV_PRESS || e->type == EV_RELEASE) && e->value == KEY_SKIP)
|
2012-07-30 16:26:04 +02:00
|
|
|
global.dialog->skip = (e->type == EV_PRESS);
|
2017-02-05 03:58:27 +01:00
|
|
|
else if(e->type == EV_CHECK_DESYNC)
|
2017-02-10 00:24:19 +01:00
|
|
|
s->desync_check = e->value;
|
2012-07-14 19:46:03 +02:00
|
|
|
else
|
2017-02-05 03:04:31 +01:00
|
|
|
player_event(&global.plr, e->type, (int16_t)e->value);
|
2012-07-14 19:46:03 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-07 05:28:41 +02:00
|
|
|
s->playpos = i;
|
2012-07-14 19:46:03 +02:00
|
|
|
player_applymovement(&global.plr);
|
|
|
|
}
|
|
|
|
|
2012-08-10 22:08:51 +02:00
|
|
|
void stage_input(void) {
|
2012-08-13 17:50:28 +02:00
|
|
|
handle_events(stage_input_event, EF_Game, NULL);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-30 16:26:04 +02:00
|
|
|
// workaround
|
2012-08-17 20:58:23 +02:00
|
|
|
if(global.dialog && global.dialog->skip && !gamekeypressed(KEY_SKIP)) {
|
2017-02-11 04:52:08 +01:00
|
|
|
global.dialog->skip = false;
|
2017-02-10 00:24:19 +01:00
|
|
|
replay_stage_event(global.replay_stage, global.frames, EV_RELEASE, KEY_SKIP);
|
2012-07-30 16:26:04 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
player_applymovement(&global.plr);
|
2012-08-17 20:58:23 +02:00
|
|
|
player_input_workaround(&global.plr);
|
2010-10-12 10:55:23 +02:00
|
|
|
}
|
|
|
|
|
2012-08-10 22:08:51 +02:00
|
|
|
void draw_hud(void) {
|
2017-02-10 23:05:22 +01:00
|
|
|
draw_texture(SCREEN_W/2.0, SCREEN_H/2.0, "hud");
|
|
|
|
|
2012-08-07 16:57:22 +02:00
|
|
|
char buf[16], *diff;
|
2011-03-23 12:26:30 +01:00
|
|
|
int i;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-03-23 12:26:30 +01:00
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef(615,0,0);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-07 16:57:22 +02:00
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef((SCREEN_W - 615) * 0.25, 20, 0);
|
|
|
|
glScalef(0.6, 0.6, 0);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
Color clr;
|
|
|
|
difficulty_color(&clr, global.diff);
|
|
|
|
glColor4f(clr.r, clr.g, clr.b, 0.7f);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-07 16:57:22 +02:00
|
|
|
diff = difficulty_name(global.diff);
|
|
|
|
draw_text(AL_Center, 1, 1, diff, _fonts.mainmenu);
|
|
|
|
draw_text(AL_Center, 2, 2, diff, _fonts.mainmenu);
|
|
|
|
glColor4f(1,1,1,1);
|
|
|
|
draw_text(AL_Center, 0, 0, diff, _fonts.mainmenu);
|
|
|
|
glPopMatrix();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-10 22:26:46 +01:00
|
|
|
if(global.stage->type == STAGE_SPELL) {
|
|
|
|
glColor4f(1, 1, 1, 0.7);
|
|
|
|
draw_text(AL_Left, -6, 167, "N/A", _fonts.standard);
|
|
|
|
draw_text(AL_Left, -6, 200, "N/A", _fonts.standard);
|
|
|
|
glColor4f(1, 1, 1, 1.0);
|
|
|
|
} else {
|
|
|
|
for(i = 0; i < global.plr.lifes; i++)
|
|
|
|
draw_texture(16*i,167, "star");
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-10 22:26:46 +01:00
|
|
|
for(i = 0; i < global.plr.bombs; i++)
|
|
|
|
draw_texture(16*i,200, "star");
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-08 20:59:43 +01:00
|
|
|
sprintf(buf, "%.2f", global.plr.power / 100.0);
|
2011-06-24 12:35:03 +02:00
|
|
|
draw_text(AL_Center, 10, 236, buf, _fonts.standard);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-13 19:10:41 +02:00
|
|
|
sprintf(buf, "%i", global.plr.graze);
|
|
|
|
draw_text(AL_Left, -5, 270, buf, _fonts.standard);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-15 18:34:47 +01:00
|
|
|
sprintf(buf, "%i", global.plr.points);
|
2011-06-24 12:35:03 +02:00
|
|
|
draw_text(AL_Center, 13, 49, buf, _fonts.standard);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-11 02:24:47 +01:00
|
|
|
if(global.plr.iddqd) {
|
|
|
|
draw_text(AL_Left, -70, 475, "GOD MODE", _fonts.mainmenu);
|
|
|
|
}
|
|
|
|
|
2011-03-23 12:26:30 +01:00
|
|
|
glPopMatrix();
|
2012-08-03 23:29:27 +02:00
|
|
|
|
|
|
|
#ifdef DEBUG
|
2012-07-17 17:34:18 +02:00
|
|
|
sprintf(buf, "%i fps / %i stgframes", global.fps.show_fps, global.timer);
|
2012-08-03 23:29:27 +02:00
|
|
|
#else
|
2011-06-13 18:48:36 +02:00
|
|
|
sprintf(buf, "%i fps", global.fps.show_fps);
|
2012-08-03 23:29:27 +02:00
|
|
|
#endif
|
2017-02-10 23:05:22 +01:00
|
|
|
draw_text(AL_Right, SCREEN_W, SCREEN_H-20, buf, _fonts.standard);
|
|
|
|
|
2011-08-27 15:56:02 +02:00
|
|
|
if(global.boss)
|
|
|
|
draw_texture(VIEWPORT_X+creal(global.boss->pos), 590, "boss_indicator");
|
2010-10-12 10:55:23 +02:00
|
|
|
}
|
|
|
|
|
2012-07-27 12:18:21 +02:00
|
|
|
void stage_draw(StageInfo *info, StageRule bgdraw, ShaderRule *shaderrules, int time) {
|
2017-02-06 00:15:18 +01:00
|
|
|
|
2017-02-17 17:03:49 +01:00
|
|
|
if(!config_get_int(CONFIG_NO_SHADER)) {
|
2012-01-06 21:52:55 +01:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[0].fbo);
|
2012-08-12 20:16:40 +02:00
|
|
|
glViewport(0,0,SCREEN_W,SCREEN_H);
|
2012-07-20 21:24:12 +02:00
|
|
|
}
|
2012-01-06 21:52:55 +01:00
|
|
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
2017-02-10 23:05:22 +01:00
|
|
|
glPushMatrix();
|
2012-01-06 21:52:55 +01:00
|
|
|
glTranslatef(-(VIEWPORT_X+VIEWPORT_W/2.0), -(VIEWPORT_Y+VIEWPORT_H/2.0),0);
|
|
|
|
glEnable(GL_DEPTH_TEST);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-17 17:03:49 +01:00
|
|
|
if(config_get_int(CONFIG_NO_STAGEBG) == 2 && global.fps.stagebg_fps < config_get_int(CONFIG_NO_STAGEBG_FPSLIMIT)
|
2012-07-14 07:45:14 +02:00
|
|
|
&& !global.nostagebg) {
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-14 07:45:14 +02:00
|
|
|
printf("stage_draw(): !- Stage background has been switched off due to low frame rate. You can change that in the options.\n");
|
2017-02-11 04:52:08 +01:00
|
|
|
global.nostagebg = true;
|
2012-07-14 07:45:14 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-17 17:03:49 +01:00
|
|
|
if(config_get_int(CONFIG_NO_STAGEBG) == 1)
|
2017-02-11 04:52:08 +01:00
|
|
|
global.nostagebg = true;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
if(!global.nostagebg)
|
2012-01-06 21:52:55 +01:00
|
|
|
bgdraw();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
|
|
|
glPopMatrix();
|
2012-01-06 21:52:55 +01:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-06-24 12:35:03 +02:00
|
|
|
set_ortho();
|
2011-08-23 17:37:14 +02:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef(VIEWPORT_X,VIEWPORT_Y,0);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-17 17:03:49 +01:00
|
|
|
if(!config_get_int(CONFIG_NO_SHADER))
|
2012-08-12 20:16:40 +02:00
|
|
|
apply_bg_shaders(shaderrules);
|
|
|
|
|
|
|
|
if(global.boss) {
|
2012-07-16 17:47:06 +02:00
|
|
|
glPushMatrix();
|
2012-08-12 20:16:40 +02:00
|
|
|
glTranslatef(creal(global.boss->pos), cimag(global.boss->pos), 0);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
if(!(global.frames % 5)) {
|
2016-12-19 15:17:09 +01:00
|
|
|
complex offset = (frand()-0.5)*50 + (frand()-0.5)*20.0I;
|
|
|
|
create_particle3c("boss_shadow", -20.0I, rgba(0.2,0.35,0.5,0.5), EnemyFlareShrink, enemy_flare, 50, (-100.0I-offset)/(50.0+frand()*10), add_ref(global.boss));
|
2011-08-26 15:19:14 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
glRotatef(global.frames*4.0, 0, 0, -1);
|
|
|
|
float f = 0.8+0.1*sin(global.frames/8.0);
|
|
|
|
glScalef(f,f,f);
|
|
|
|
draw_texture(0,0,"boss_circle");
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-16 17:47:06 +02:00
|
|
|
glPopMatrix();
|
2011-05-09 13:42:02 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
player_draw(&global.plr);
|
|
|
|
|
2017-02-06 00:15:18 +01:00
|
|
|
draw_items();
|
2012-08-12 20:16:40 +02:00
|
|
|
draw_projectiles(global.projs);
|
2017-02-06 00:15:18 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
draw_projectiles(global.particles);
|
|
|
|
draw_enemies(global.enemies);
|
|
|
|
draw_lasers();
|
2017-02-06 00:15:18 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
if(global.boss)
|
|
|
|
draw_boss(global.boss);
|
|
|
|
|
2017-01-24 15:47:50 +01:00
|
|
|
if(global.dialog)
|
2012-08-12 20:16:40 +02:00
|
|
|
draw_dialog(global.dialog);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
draw_stage_title(info);
|
2017-02-06 00:15:18 +01:00
|
|
|
|
2017-02-17 17:03:49 +01:00
|
|
|
if(!config_get_int(CONFIG_NO_SHADER)) {
|
2012-08-12 20:16:40 +02:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
2017-02-04 04:58:55 +01:00
|
|
|
video_set_viewport();
|
2012-07-16 17:47:06 +02:00
|
|
|
glPushMatrix();
|
2012-08-12 20:16:40 +02:00
|
|
|
if(global.shake_view)
|
|
|
|
glTranslatef(global.shake_view*sin(global.frames),global.shake_view*sin(global.frames+3),0);
|
|
|
|
|
|
|
|
draw_fbo_viewport(&resources.fsec);
|
|
|
|
|
2012-07-16 17:47:06 +02:00
|
|
|
glPopMatrix();
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-12 20:16:40 +02:00
|
|
|
glPopMatrix();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-16 17:47:06 +02:00
|
|
|
draw_hud();
|
2012-08-14 17:56:53 +02:00
|
|
|
draw_transition();
|
2011-06-13 18:48:36 +02:00
|
|
|
}
|
|
|
|
|
2012-07-19 19:03:23 +02:00
|
|
|
int apply_shaderrules(ShaderRule *shaderrules, int fbonum) {
|
|
|
|
int i;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-19 19:03:23 +02:00
|
|
|
if(!global.nostagebg) {
|
|
|
|
for(i = 0; shaderrules != NULL && shaderrules[i] != NULL; i++) {
|
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[!fbonum].fbo);
|
|
|
|
shaderrules[i](fbonum);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-19 19:03:23 +02:00
|
|
|
fbonum = !fbonum;
|
|
|
|
}
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-19 19:03:23 +02:00
|
|
|
return fbonum;
|
|
|
|
}
|
|
|
|
|
2012-01-06 21:52:55 +01:00
|
|
|
void apply_bg_shaders(ShaderRule *shaderrules) {
|
|
|
|
int fbonum = 0;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-08-23 17:37:14 +02:00
|
|
|
if(global.boss && global.boss->current && global.boss->current->draw_rule) {
|
2012-07-19 19:03:23 +02:00
|
|
|
if(global.frames - global.boss->current->starttime <= 0)
|
|
|
|
fbonum = apply_shaderrules(shaderrules, fbonum);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-01-06 21:52:55 +01:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, resources.fbg[0].fbo);
|
2011-08-23 17:37:14 +02:00
|
|
|
global.boss->current->draw_rule(global.boss, global.frames - global.boss->current->starttime);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-08-26 15:19:14 +02:00
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef(creal(global.boss->pos), cimag(global.boss->pos), 0);
|
|
|
|
glRotatef(global.frames*7.0, 0, 0, -1);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-08-26 15:19:14 +02:00
|
|
|
int t;
|
|
|
|
if((t = global.frames - global.boss->current->starttime) < 0) {
|
|
|
|
float f = 1.0 - t/(float)ATTACK_START_DELAY;
|
|
|
|
glScalef(f,f,f);
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-08-26 15:19:14 +02:00
|
|
|
draw_texture(0,0,"boss_spellcircle0");
|
|
|
|
glPopMatrix();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-12-25 08:18:03 +01:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
2012-07-19 19:03:23 +02:00
|
|
|
} else
|
|
|
|
fbonum = apply_shaderrules(shaderrules, fbonum);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-12-25 08:18:03 +01:00
|
|
|
glBindFramebuffer(GL_FRAMEBUFFER, resources.fsec.fbo);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-04-25 19:40:21 +02:00
|
|
|
if(global.boss) { // Boss background shader
|
2012-04-05 16:27:18 +02:00
|
|
|
Shader *shader = get_shader("boss_zoom");
|
|
|
|
glUseProgram(shader->prog);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-08-23 17:37:14 +02:00
|
|
|
complex fpos = VIEWPORT_H*I + conj(global.boss->pos) + (VIEWPORT_X + VIEWPORT_Y*I);
|
|
|
|
complex pos = fpos + 15*cexp(I*global.frames/4.5);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-04-05 16:27:18 +02:00
|
|
|
glUniform2f(uniloc(shader, "blur_orig"),
|
2012-01-06 21:52:55 +01:00
|
|
|
creal(pos)/resources.fbg[fbonum].nw, cimag(pos)/resources.fbg[fbonum].nh);
|
2012-04-05 16:27:18 +02:00
|
|
|
glUniform2f(uniloc(shader, "fix_orig"),
|
2012-01-06 21:52:55 +01:00
|
|
|
creal(fpos)/resources.fbg[fbonum].nw, cimag(fpos)/resources.fbg[fbonum].nh);
|
2012-04-05 16:27:18 +02:00
|
|
|
glUniform1f(uniloc(shader, "blur_rad"), 0.2+0.025*sin(global.frames/15.0));
|
|
|
|
glUniform1f(uniloc(shader, "rad"), 0.24);
|
|
|
|
glUniform1f(uniloc(shader, "ratio"), (float)resources.fbg[fbonum].nh/resources.fbg[fbonum].nw);
|
2012-07-18 15:02:26 +02:00
|
|
|
if(global.boss->zoomcolor)
|
2012-08-12 17:28:43 +02:00
|
|
|
glUniform4fv(uniloc(shader, "color"), 1, (float *)global.boss->zoomcolor);
|
2012-07-18 15:02:26 +02:00
|
|
|
else
|
|
|
|
glUniform4f(uniloc(shader, "color"), 0.1, 0.2, 0.3, 1);
|
2011-04-25 19:40:21 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-01-06 21:52:55 +01:00
|
|
|
draw_fbo_viewport(&resources.fbg[fbonum]);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-12-25 08:18:03 +01:00
|
|
|
glUseProgram(0);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-07-05 15:20:19 +02:00
|
|
|
if(global.frames - global.plr.recovery < 0) {
|
|
|
|
float t = BOMB_RECOVERY - global.plr.recovery + global.frames;
|
|
|
|
float fade = 1;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-07-05 15:20:19 +02:00
|
|
|
if(t < BOMB_RECOVERY/6)
|
|
|
|
fade = t/BOMB_RECOVERY*6;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-07-05 15:20:19 +02:00
|
|
|
if(t > BOMB_RECOVERY/4*3)
|
|
|
|
fade = 1-t/BOMB_RECOVERY*4 + 3;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-07-05 15:20:19 +02:00
|
|
|
glPushMatrix();
|
|
|
|
glTranslatef(-30,-30,0);
|
|
|
|
fade_out(fade*0.6);
|
|
|
|
glPopMatrix();
|
|
|
|
}
|
2011-04-25 19:40:21 +02:00
|
|
|
}
|
|
|
|
|
2012-08-14 21:34:04 +02:00
|
|
|
void stage_logic(int time) {
|
2010-10-12 10:55:23 +02:00
|
|
|
player_logic(&global.plr);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-04-26 12:04:45 +02:00
|
|
|
process_enemies(&global.enemies);
|
2017-02-11 04:52:08 +01:00
|
|
|
process_projectiles(&global.projs, true);
|
2011-04-29 10:26:37 +02:00
|
|
|
process_items();
|
2011-04-24 15:39:17 +02:00
|
|
|
process_lasers();
|
2017-02-11 04:52:08 +01:00
|
|
|
process_projectiles(&global.particles, false);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-08-23 17:37:14 +02:00
|
|
|
if(global.boss && !global.dialog) {
|
2011-04-08 18:59:03 +02:00
|
|
|
process_boss(global.boss);
|
2011-05-09 13:42:02 +02:00
|
|
|
if(global.boss->dmg > global.boss->attacks[global.boss->acount-1].dmglimit)
|
|
|
|
boss_death(&global.boss);
|
2011-04-08 18:59:03 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-30 16:26:04 +02:00
|
|
|
if(global.dialog && global.dialog->skip && global.frames - global.dialog->page_time > 3)
|
|
|
|
page_dialog(&global.dialog);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2010-10-12 10:55:23 +02:00
|
|
|
global.frames++;
|
2017-02-10 11:39:42 +01:00
|
|
|
global.stageuiframes++;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-14 19:46:03 +02:00
|
|
|
if(!global.dialog && !global.boss)
|
|
|
|
global.timer++;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-10 00:24:19 +01:00
|
|
|
if(global.timer == time - FADE_TIME ||
|
|
|
|
(
|
|
|
|
global.replaymode == REPLAY_PLAY &&
|
|
|
|
global.frames == global.replay_stage->events[global.replay_stage->numevents-1].frame - FADE_TIME
|
|
|
|
)
|
|
|
|
) {
|
2012-08-14 17:56:53 +02:00
|
|
|
set_transition(TransFadeBlack, FADE_TIME, FADE_TIME*2);
|
2017-02-10 00:24:19 +01:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
if(time && global.timer >= time)
|
2012-01-06 21:52:55 +01:00
|
|
|
global.game_over = GAMEOVER_WIN;
|
2017-02-05 23:02:29 +01:00
|
|
|
|
|
|
|
// BGM handling
|
2017-02-10 00:24:19 +01:00
|
|
|
if(global.dialog && global.dialog->messages[global.dialog->pos].side == BGM) {
|
2017-02-05 23:02:29 +01:00
|
|
|
start_bgm(global.dialog->messages[global.dialog->pos].msg);
|
|
|
|
page_dialog(&global.dialog);
|
|
|
|
}
|
2010-10-12 10:55:23 +02:00
|
|
|
}
|
|
|
|
|
2012-08-10 22:08:51 +02:00
|
|
|
void stage_end(void) {
|
2011-04-26 22:39:50 +02:00
|
|
|
delete_enemies(&global.enemies);
|
2011-04-29 10:26:37 +02:00
|
|
|
delete_items();
|
2011-04-26 22:47:13 +02:00
|
|
|
delete_lasers();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-07 17:07:29 +02:00
|
|
|
delete_projectiles(&global.projs);
|
|
|
|
delete_projectiles(&global.particles);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-06-13 18:48:36 +02:00
|
|
|
if(global.dialog) {
|
|
|
|
delete_dialog(global.dialog);
|
|
|
|
global.dialog = NULL;
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-06-13 18:48:36 +02:00
|
|
|
if(global.boss) {
|
|
|
|
free_boss(global.boss);
|
|
|
|
global.boss = NULL;
|
|
|
|
}
|
2010-10-12 10:55:23 +02:00
|
|
|
}
|
2011-06-25 12:41:40 +02:00
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
void stage_loop(StageRule start, StageRule end, StageRule draw, StageRule event, ShaderRule *shaderrules, int endtime) {
|
2012-01-06 21:52:55 +01:00
|
|
|
if(global.game_over == GAMEOVER_WIN) {
|
|
|
|
global.game_over = 0;
|
|
|
|
} else if(global.game_over) {
|
|
|
|
return;
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
// I really want to separate all of the game state from the global struct sometime
|
|
|
|
StageInfo *info = global.stage;
|
|
|
|
|
2017-02-05 02:25:17 +01:00
|
|
|
uint32_t seed = (uint32_t)time(0);
|
2012-08-07 02:45:38 +02:00
|
|
|
tsrand_switch(&global.rand_game);
|
2012-07-27 19:11:45 +02:00
|
|
|
tsrand_seed_p(&global.rand_game, seed);
|
2012-08-07 02:45:38 +02:00
|
|
|
stage_start();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-14 19:46:03 +02:00
|
|
|
if(global.replaymode == REPLAY_RECORD) {
|
2017-02-17 17:03:49 +01:00
|
|
|
if(config_get_int(CONFIG_SAVE_RPY)) {
|
2017-02-15 18:34:47 +01:00
|
|
|
global.replay_stage = replay_create_stage(&global.replay, info, 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);
|
|
|
|
replay_stage_sync_player_state(global.replay_stage, &global.plr);
|
2017-02-10 00:24:19 +01:00
|
|
|
} else {
|
|
|
|
global.replay_stage = NULL;
|
|
|
|
}
|
|
|
|
|
2017-02-05 02:25:17 +01:00
|
|
|
printf("Random seed: %u\n", seed);
|
2017-02-10 22:26:46 +01:00
|
|
|
|
|
|
|
if(info->type == STAGE_SPELL) {
|
2017-02-12 05:30:25 +01:00
|
|
|
global.plr.lifes = 0;
|
2017-02-10 22:26:46 +01:00
|
|
|
global.plr.bombs = 0;
|
|
|
|
}
|
2012-07-14 19:46:03 +02:00
|
|
|
} else {
|
2017-02-10 00:24:19 +01:00
|
|
|
if(!global.replay_stage) {
|
|
|
|
errx(-1, "Attemped to replay a NULL stage");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReplayStage *stg = global.replay_stage;
|
2017-02-09 05:06:46 +01:00
|
|
|
printf("REPLAY_PLAY mode: %d events, stage: \"%s\"\n", stg->numevents, stage_get(stg->stage)->title);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-07 05:28:41 +02:00
|
|
|
tsrand_seed_p(&global.rand_game, stg->seed);
|
2017-02-05 02:25:17 +01:00
|
|
|
printf("Random seed: %u\n", stg->seed);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-15 18:34:47 +01:00
|
|
|
global.diff = stg->diff;
|
|
|
|
init_player(&global.plr);
|
|
|
|
replay_stage_sync_player_state(stg, &global.plr);
|
2012-08-07 05:28:41 +02:00
|
|
|
stg->playpos = 0;
|
2012-07-14 19:46:03 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-07 11:24:14 +02:00
|
|
|
Enemy *e = global.plr.slaves, *tmp;
|
2017-02-08 20:59:43 +01:00
|
|
|
short power = global.plr.power;
|
2012-08-06 23:49:16 +02:00
|
|
|
global.plr.power = -1;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-07 11:24:14 +02:00
|
|
|
while(e != 0) {
|
|
|
|
tmp = e;
|
|
|
|
e = e->next;
|
|
|
|
delete_enemy(&global.plr.slaves, tmp);
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-08-06 23:49:16 +02:00
|
|
|
player_set_power(&global.plr, power);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-06-25 12:41:40 +02:00
|
|
|
start();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
if(info->type == STAGE_SPELL) {
|
|
|
|
endtime = 0;
|
|
|
|
}
|
|
|
|
|
2011-06-25 12:41:40 +02:00
|
|
|
while(global.game_over <= 0) {
|
2012-08-12 20:16:40 +02:00
|
|
|
if(!global.boss && !global.dialog)
|
2011-08-23 17:37:14 +02:00
|
|
|
event();
|
2017-02-05 03:58:27 +01:00
|
|
|
|
2017-02-10 11:39:42 +01:00
|
|
|
if(!endtime && info->type == STAGE_SPELL && !global.boss) {
|
|
|
|
endtime = global.timer + 60;
|
|
|
|
}
|
|
|
|
|
|
|
|
((global.replaymode == REPLAY_PLAY) ? replay_input : stage_input)();
|
2017-02-15 18:34:47 +01:00
|
|
|
replay_stage_check_desync(global.replay_stage, global.frames, (tsrand() ^ global.plr.points) & 0xFFFF, global.replaymode);
|
2017-02-05 03:58:27 +01:00
|
|
|
|
2012-07-14 08:34:34 +02:00
|
|
|
stage_logic(endtime);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-05 19:25:18 +01:00
|
|
|
if(global.frameskip && global.frames % global.frameskip) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2012-07-14 08:34:34 +02:00
|
|
|
calc_fps(&global.fps);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-05 21:16:50 +01:00
|
|
|
tsrand_lock(&global.rand_game);
|
2012-07-27 19:11:45 +02:00
|
|
|
tsrand_switch(&global.rand_visual);
|
|
|
|
stage_draw(info, draw, shaderrules, endtime);
|
2017-02-05 21:16:50 +01:00
|
|
|
tsrand_unlock(&global.rand_game);
|
2012-07-27 19:11:45 +02:00
|
|
|
tsrand_switch(&global.rand_game);
|
2017-02-05 21:16:50 +01:00
|
|
|
|
2012-08-09 16:38:37 +02:00
|
|
|
// print_state_checksum();
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-04 03:56:40 +01:00
|
|
|
SDL_GL_SwapWindow(video.window);
|
2017-02-05 19:28:53 +01:00
|
|
|
|
|
|
|
if(global.replaymode == REPLAY_PLAY && gamekeypressed(KEY_SKIP)) {
|
|
|
|
global.lasttime = SDL_GetTicks();
|
|
|
|
} else {
|
|
|
|
frame_rate(&global.lasttime);
|
|
|
|
}
|
2011-06-25 12:41:40 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-16 17:47:06 +02:00
|
|
|
if(global.replaymode == REPLAY_RECORD) {
|
2017-02-10 00:24:19 +01:00
|
|
|
replay_stage_event(global.replay_stage, global.frames, EV_OVER, 0);
|
2012-07-16 17:47:06 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2011-06-25 12:41:40 +02:00
|
|
|
end();
|
|
|
|
stage_end();
|
2012-07-27 19:11:45 +02:00
|
|
|
tsrand_switch(&global.rand_visual);
|
2017-02-10 11:39:42 +01:00
|
|
|
global.stage = NULL;
|
2011-06-25 12:41:40 +02:00
|
|
|
}
|
2012-07-14 19:46:03 +02:00
|
|
|
|
2017-02-03 16:56:36 +01:00
|
|
|
void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const char *text, TTF_Font *font, Color *color) {
|
2012-07-27 12:18:21 +02:00
|
|
|
int i;
|
|
|
|
float f = 0;
|
2017-01-24 15:35:23 +01:00
|
|
|
if(t < 30 || t > 220)
|
|
|
|
return;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-27 12:18:21 +02:00
|
|
|
if((i = abs(t-135)) >= 50) {
|
|
|
|
i -= 50;
|
2017-02-10 23:05:22 +01:00
|
|
|
f = 1/35.0*i;
|
2012-07-27 12:18:21 +02:00
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-17 17:03:49 +01:00
|
|
|
if(!config_get_int(CONFIG_NO_SHADER)) {
|
2012-07-28 23:41:53 +02:00
|
|
|
Shader *sha = get_shader("stagetitle");
|
|
|
|
glUseProgram(sha->prog);
|
|
|
|
glUniform1i(uniloc(sha, "trans"), 1);
|
|
|
|
glUniform1f(uniloc(sha, "t"), 1.0-f);
|
2017-02-03 16:56:36 +01:00
|
|
|
glUniform3fv(uniloc(sha, "color"), 1, (float *)color);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-28 23:41:53 +02:00
|
|
|
glActiveTexture(GL_TEXTURE0 + 1);
|
|
|
|
glBindTexture(GL_TEXTURE_2D, get_tex("titletransition")->gltex);
|
|
|
|
glActiveTexture(GL_TEXTURE0);
|
|
|
|
} else {
|
|
|
|
glColor4f(info->titleclr.r,info->titleclr.g,info->titleclr.b,1.0-f);
|
|
|
|
}
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-01-24 14:40:57 +01:00
|
|
|
draw_text(al, x, y, text, font);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2012-07-27 12:18:21 +02:00
|
|
|
glColor4f(1,1,1,1);
|
2012-07-28 23:41:53 +02:00
|
|
|
glUseProgram(0);
|
2012-07-13 22:42:35 +02:00
|
|
|
}
|
2017-01-24 14:40:57 +01:00
|
|
|
|
|
|
|
void draw_stage_title(StageInfo *info) {
|
2017-02-10 11:39:42 +01:00
|
|
|
int t = global.stageuiframes;
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-02-03 16:56:36 +01:00
|
|
|
draw_title(t, info, AL_Center, VIEWPORT_W/2, VIEWPORT_H/2-40, info->title, _fonts.mainmenu, &info->titleclr);
|
|
|
|
draw_title(t, info, AL_Center, VIEWPORT_W/2, VIEWPORT_H/2, info->subtitle, _fonts.standard, &info->titleclr);
|
2017-02-10 23:05:22 +01:00
|
|
|
|
2017-01-24 14:40:57 +01:00
|
|
|
if ((current_bgm.title != NULL) && (current_bgm.started_at >= 0))
|
|
|
|
{
|
2017-02-03 16:56:36 +01:00
|
|
|
draw_title(t - current_bgm.started_at, info, AL_Right, VIEWPORT_W-15, VIEWPORT_H-35, current_bgm.title, _fonts.standard,
|
|
|
|
current_bgm.isboss ? &info->bosstitleclr : &info->titleclr);
|
2017-01-24 14:40:57 +01:00
|
|
|
}
|
|
|
|
}
|