momento/src/main.c

241 lines
5.8 KiB
C
Raw Normal View History

2021-03-28 19:35:07 +02:00
/* SPDX-License-Identifier: GPL-3.0-or-later */
/* Copyright (C) 2021 KikooDX */
2021-03-29 17:27:03 +02:00
#include "conf.h"
2021-04-12 10:59:46 +02:00
#include "game_state.h"
#include "input.h"
2021-03-28 19:35:07 +02:00
#include "level.h"
#include "levelselection.h"
2021-04-20 12:49:55 +02:00
#include "mainmenu.h"
#include "particles.h"
#include "player.h"
2021-04-12 10:59:46 +02:00
#include "titlescreen.h"
2021-04-09 15:11:00 +02:00
#include "transition.h"
2021-04-20 12:49:55 +02:00
#include "zxcolors.h"
2021-03-29 17:27:03 +02:00
#include <gint/clock.h>
2021-03-28 19:35:07 +02:00
#include <gint/display.h>
#include <gint/gint.h>
#include <gint/keyboard.h>
2021-03-29 17:27:03 +02:00
#include <gint/timer.h>
#define PANIC(msg) \
do { \
2021-04-20 12:49:55 +02:00
dclear(ZX_BLACK); \
dprint_opt(DWIDTH / 2, DHEIGHT / 2, ZX_RED, C_NONE, \
DTEXT_CENTER, DTEXT_MIDDLE, "ERROR: %s", msg); \
dupdate(); \
getkey(); \
return 0; \
2021-04-09 15:11:00 +02:00
} while (0);
#define LOAD_LEVEL() \
do { \
gint_switch(level_load); \
if (fatal_error == -1) \
PANIC(fatal_error_msg); \
particles_init(); \
player = player_init(); \
2021-04-09 15:11:00 +02:00
} while (0);
2021-03-28 19:35:07 +02:00
extern struct Level level;
extern int level_id;
2021-03-29 17:27:03 +02:00
extern int fatal_error;
extern char *fatal_error_msg;
2021-04-13 01:08:15 +02:00
extern const font_t font_main;
2021-04-27 00:52:03 +02:00
static int callback(volatile int *arg);
2021-03-28 19:35:07 +02:00
int
main(void)
2021-03-28 19:35:07 +02:00
{
2021-03-29 17:27:03 +02:00
int i;
int timer;
2021-04-01 01:39:45 +02:00
int player_return_code;
2021-04-27 00:52:03 +02:00
int frameskip = 0;
int toskip = 0;
/* int level_pack_beaten; */
2021-04-09 15:11:00 +02:00
enum TransitionMode transition_previous_mode;
2021-04-19 01:30:10 +02:00
enum GameState game_state = TitleScreen;
2021-03-29 17:27:03 +02:00
volatile int has_ticked = 1;
struct Player player;
struct Input input = input_init();
2021-04-12 10:59:46 +02:00
struct TitleScreen titlescreen = titlescreen_init();
struct LevelSelection levelselection = levelselection_init();
2021-04-20 12:49:55 +02:00
struct MainMenu mainmenu = mainmenu_init();
struct Transition transition =
2021-04-20 12:49:55 +02:00
transition_init(0.0, ZX_BLACK, TransitionNone);
particles_init();
2021-04-12 10:59:46 +02:00
2021-04-13 01:08:15 +02:00
/* set font */
dfont(&font_main);
2021-03-28 19:35:07 +02:00
/* load level */
level_id = 0;
gint_switch(level_load);
2021-03-29 17:27:03 +02:00
if (fatal_error == -1)
PANIC(fatal_error_msg);
/* timer setup */
timer =
2021-04-27 00:52:03 +02:00
timer_setup(TIMER_ANY, 1000000 / TARGET_FPS, callback, &has_ticked);
2021-03-29 17:27:03 +02:00
if (timer == -1)
PANIC("timer_setup failed");
timer_start(timer);
2021-03-28 19:35:07 +02:00
/* initialize the player (has to be done after level loading */
player = player_init();
2021-03-29 17:27:03 +02:00
/* main game loop */
while (!keydown(KEY_EXIT)) {
2021-04-27 00:52:03 +02:00
/* skip render frames */
i = 1 + frameskip;
toskip = frameskip;
while (i-- > 0) {
2021-04-27 00:52:03 +02:00
/* frameskip adjustement */
if (has_ticked - 1 > frameskip)
frameskip = has_ticked - 1;
2021-03-29 17:27:03 +02:00
/* speed limiter */
while (!has_ticked)
sleep();
2021-04-27 00:52:03 +02:00
while (has_ticked)
has_ticked = 0;
2021-04-12 10:59:46 +02:00
2021-03-29 17:27:03 +02:00
/* update */
input_update(&input);
2021-04-12 10:59:46 +02:00
switch (game_state) {
case TitleScreen:
if (titlescreen_update(&titlescreen, input))
2021-04-18 00:44:01 +02:00
game_state = MainMenu;
2021-04-12 10:59:46 +02:00
break;
case MainMenu:
2021-04-20 12:49:55 +02:00
if (mainmenu_update(&mainmenu, input))
game_state = LevelSelection;
2021-04-12 10:59:46 +02:00
break;
case LevelSelection:
if (levelselection_update(&levelselection,
input)) {
game_state = Playing;
2021-04-20 00:40:12 +02:00
/* set level according to
* selected pack */
level_id = levelselection.pack_cursor *
LVL_PER_PACK;
2021-04-20 00:40:12 +02:00
LOAD_LEVEL();
}
2021-04-12 10:59:46 +02:00
break;
case Playing:
if (transition.mode == TransitionNone) {
particles_update();
player_return_code =
player_update(&player, input);
2021-04-12 10:59:46 +02:00
switch (player_return_code) {
case -1:
game_state = GamePause;
break;
2021-04-12 10:59:46 +02:00
case 1:
level_id += 1;
transition = transition_init(
2021-04-20 12:49:55 +02:00
H_TRANS_SPD, ZX_BLUE,
TransitionHOut);
2021-04-12 10:59:46 +02:00
break;
case 2:
transition = transition_init(
2021-04-20 12:49:55 +02:00
V_TRANS_SPD, ZX_RED,
TransitionVOut);
2021-04-12 10:59:46 +02:00
break;
default:
break;
}
2021-04-09 15:11:00 +02:00
}
2021-04-12 10:59:46 +02:00
transition_previous_mode =
transition_update(&transition);
if (transition_previous_mode !=
transition.mode &&
transition_previous_mode !=
TransitionNone) {
switch (transition_previous_mode) {
2021-04-12 10:59:46 +02:00
case TransitionNone:
break;
case TransitionHIn:
break;
case TransitionHOut:
2021-04-18 00:44:01 +02:00
/* end level pack */
if (level_id % 4 == 0) {
game_state = PackDone;
/* level_pack_beaten =
level_id / 4; */
2021-04-18 00:44:01 +02:00
}
2021-04-12 10:59:46 +02:00
LOAD_LEVEL();
transition = transition_init(
transition.speed,
transition.color,
TransitionHIn);
2021-04-12 10:59:46 +02:00
break;
case TransitionVIn:
break;
case TransitionVOut:
LOAD_LEVEL();
transition = transition_init(
transition.speed,
transition.color,
TransitionVIn);
2021-04-12 10:59:46 +02:00
break;
default:
break;
}
2021-04-09 15:11:00 +02:00
}
2021-04-12 10:59:46 +02:00
break;
case GamePause:
game_state = Playing;
break;
2021-04-18 00:44:01 +02:00
case PackDone:
game_state = LevelSelection;
break;
2021-04-12 10:59:46 +02:00
default:
PANIC("missing game_state case (update)");
2021-04-12 10:59:46 +02:00
break;
2021-04-01 01:39:45 +02:00
}
2021-03-29 17:27:03 +02:00
}
/* draw */
2021-04-20 12:49:55 +02:00
dclear(ZX_BLACK);
switch (game_state) {
case TitleScreen:
titlescreen_draw(titlescreen);
break;
case MainMenu:
2021-04-20 12:49:55 +02:00
mainmenu_draw(mainmenu);
break;
case LevelSelection:
levelselection_draw(levelselection);
break;
case Playing:
level_draw();
particles_draw();
2021-04-27 00:52:03 +02:00
trail_draw();
player_draw(player);
transition_draw(transition);
break;
case GamePause:
break;
case PackDone:
break;
default:
PANIC("missing game_state case (draw)");
break;
}
dupdate();
2021-03-29 17:27:03 +02:00
}
2021-03-28 19:35:07 +02:00
2021-03-29 17:27:03 +02:00
timer_stop(timer);
2021-03-28 19:35:07 +02:00
return 1;
}
2021-03-29 17:27:03 +02:00
static int
callback(volatile int *arg)
2021-03-29 17:27:03 +02:00
{
2021-04-27 00:52:03 +02:00
*arg += 1;
2021-03-29 17:27:03 +02:00
return 0;
}