Whitespace: change line endings to LF everywhere

This commit is contained in:
Dominic Szablewski
2023-09-04 17:34:29 +02:00
parent a829166082
commit 0594285013
26 changed files with 6344 additions and 6344 deletions
+174 -174
View File
@@ -1,174 +1,174 @@
#include "../mem.h"
#include "../utils.h"
#include "../types.h"
#include "../render.h"
#include "../system.h"
#include "object.h"
#include "track.h"
#include "ship.h"
#include "weapon.h"
#include "droid.h"
#include "camera.h"
void camera_init(camera_t *camera, section_t *section) {
camera->section = section;
for (int i = 0; i < 10; i++) {
camera->section = camera->section->next;
}
camera->position = camera->section->center;
camera->velocity = vec3(0, 0, 0);
camera->angle = vec3(0, 0, 0);
camera->angular_velocity = vec3(0, 0, 0);
camera->has_initial_section = false;
}
vec3_t camera_forward(camera_t *camera) {
float sx = sin(camera->angle.x);
float cx = cos(camera->angle.x);
float sy = sin(camera->angle.y);
float cy = cos(camera->angle.y);
return vec3(-(sy * cx), -sx, (cy * cx));
}
void camera_update(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->last_position = camera->position;
(camera->update_func)(camera, ship, droid);
camera->real_velocity = vec3_mulf(vec3_sub(camera->position, camera->last_position), 1.0/system_tick());
}
void camera_update_race_external(camera_t *camera, ship_t *ship, droid_t *droid) {
vec3_t pos = vec3_sub(ship->position, vec3_mulf(ship->dir_forward, 1024));
pos.y -= 200;
camera->section = track_nearest_section(pos, camera->section, NULL);
section_t *next = camera->section->next;
vec3_t target = vec3_project_to_ray(pos, next->center, camera->section->center);
vec3_t diff_from_center = vec3_sub(pos, target);
vec3_t acc = diff_from_center;
acc.y += vec3_len(diff_from_center) * 0.5;
camera->velocity = vec3_sub(camera->velocity, vec3_mulf(acc, 0.015625 * 30 * system_tick()));
camera->velocity = vec3_sub(camera->velocity, vec3_mulf(camera->velocity, 0.125 * 30 * system_tick()));
pos = vec3_add(pos, camera->velocity);
camera->position = pos;
camera->angle = vec3(ship->angle.x, ship->angle.y, 0);
}
void camera_update_race_internal(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->section = ship->section;
camera->position = ship_cockpit(ship);
camera->angle = vec3(ship->angle.x, ship->angle.y, ship->angle.z);
}
void camera_update_race_intro(camera_t *camera, ship_t *ship, droid_t *droid) {
// Set to final position
vec3_t pos = vec3_sub(ship->position, vec3_mulf(ship->dir_forward, 0.25 * 4096));
pos.x += sin(( (ship->update_timer - UPDATE_TIME_RACE_VIEW) * 30 * 3.0 * M_PI * 2) / 4096.0) * 4096;
pos.y -= (2 * (ship->update_timer - UPDATE_TIME_RACE_VIEW) * 30) + 200;
pos.z += sin(( (ship->update_timer - UPDATE_TIME_RACE_VIEW) * 30 * 3.0 * M_PI * 2) / 4096.0) * 4096;
if (!camera->has_initial_section) {
camera->section = ship->section;
camera->has_initial_section = true;
}
else {
camera->section = track_nearest_section(pos, camera->section, NULL);
}
camera->position = pos;
camera->angle.z = 0;
camera->angle.x = ship->angle.x * 0.5;
vec3_t target = vec3_sub(ship->position, pos);
camera->angle.y = -atan2(target.x, target.z);
if (ship->update_timer <= UPDATE_TIME_RACE_VIEW) {
flags_add(ship->flags, SHIP_VIEW_INTERNAL);
camera->update_func = camera_update_race_internal;
}
}
void camera_update_attract_circle(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->update_timer -= system_tick();
if (camera->update_timer <= 0) {
camera->update_func = camera_update_attract_random;
}
// FIXME: not exactly sure what I'm doing here. The PSX version behaves
// differently.
camera->section = ship->section;
camera->position.x = ship->position.x + sin(ship->angle.y) * 512;
camera->position.y = ship->position.y + ((ship->angle.x * 512 / (M_PI * 2)) - 200);
camera->position.z = ship->position.z - cos(ship->angle.y) * 512;
camera->position.x += sin(camera->update_timer * 0.25) * 512;
camera->position.y -= 400;
camera->position.z += cos(camera->update_timer * 0.25) * 512;
camera->position = vec3_sub(camera->position, vec3_mulf(ship->dir_up, 256));
vec3_t target = vec3_sub(ship->position, camera->position);
float height = sqrt(target.x * target.x + target.z * target.z);
camera->angle.x = -atan2(target.y, height);
camera->angle.y = -atan2(target.x, target.z);
}
void camera_update_rescue(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->position = vec3_add(camera->section->center, vec3(300, -1500, 300));
vec3_t target = vec3_sub(droid->position, camera->position);
float height = sqrt(target.x * target.x + target.z * target.z);
camera->angle.x = -atan2(target.y, height);
camera->angle.y = -atan2(target.x, target.z);
}
void camera_update_attract_internal(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->update_timer -= system_tick();
if (camera->update_timer <= 0) {
camera->update_func = camera_update_attract_random;
}
camera->section = ship->section;
camera->position = ship_cockpit(ship);
camera->angle = vec3(ship->angle.x, ship->angle.y, 0); // No roll
}
void camera_update_static_follow(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->update_timer -= system_tick();
if (camera->update_timer <= 0) {
camera->update_func = camera_update_attract_random;
}
vec3_t target = vec3_sub(ship->position, camera->position);
float height = sqrt(target.x * target.x + target.z * target.z);
camera->angle.x = -atan2(target.y, height);
camera->angle.y = -atan2(target.x, target.z);
}
void camera_update_attract_random(camera_t *camera, ship_t *ship, droid_t *droid) {
flags_rm(ship->flags, SHIP_VIEW_INTERNAL);
if (rand() % 2) {
camera->update_func = camera_update_attract_circle;
camera->update_timer = 5;
}
else {
camera->update_func = camera_update_static_follow;
camera->update_timer = 5;
section_t *section = ship->section->next;
for (int i = 0; i < 10; i++) {
section = section->next;
}
camera->section = section;
camera->position = section->center;
camera->position.y -= 500;
}
(camera->update_func)(camera, ship, droid);
}
#include "../mem.h"
#include "../utils.h"
#include "../types.h"
#include "../render.h"
#include "../system.h"
#include "object.h"
#include "track.h"
#include "ship.h"
#include "weapon.h"
#include "droid.h"
#include "camera.h"
void camera_init(camera_t *camera, section_t *section) {
camera->section = section;
for (int i = 0; i < 10; i++) {
camera->section = camera->section->next;
}
camera->position = camera->section->center;
camera->velocity = vec3(0, 0, 0);
camera->angle = vec3(0, 0, 0);
camera->angular_velocity = vec3(0, 0, 0);
camera->has_initial_section = false;
}
vec3_t camera_forward(camera_t *camera) {
float sx = sin(camera->angle.x);
float cx = cos(camera->angle.x);
float sy = sin(camera->angle.y);
float cy = cos(camera->angle.y);
return vec3(-(sy * cx), -sx, (cy * cx));
}
void camera_update(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->last_position = camera->position;
(camera->update_func)(camera, ship, droid);
camera->real_velocity = vec3_mulf(vec3_sub(camera->position, camera->last_position), 1.0/system_tick());
}
void camera_update_race_external(camera_t *camera, ship_t *ship, droid_t *droid) {
vec3_t pos = vec3_sub(ship->position, vec3_mulf(ship->dir_forward, 1024));
pos.y -= 200;
camera->section = track_nearest_section(pos, camera->section, NULL);
section_t *next = camera->section->next;
vec3_t target = vec3_project_to_ray(pos, next->center, camera->section->center);
vec3_t diff_from_center = vec3_sub(pos, target);
vec3_t acc = diff_from_center;
acc.y += vec3_len(diff_from_center) * 0.5;
camera->velocity = vec3_sub(camera->velocity, vec3_mulf(acc, 0.015625 * 30 * system_tick()));
camera->velocity = vec3_sub(camera->velocity, vec3_mulf(camera->velocity, 0.125 * 30 * system_tick()));
pos = vec3_add(pos, camera->velocity);
camera->position = pos;
camera->angle = vec3(ship->angle.x, ship->angle.y, 0);
}
void camera_update_race_internal(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->section = ship->section;
camera->position = ship_cockpit(ship);
camera->angle = vec3(ship->angle.x, ship->angle.y, ship->angle.z);
}
void camera_update_race_intro(camera_t *camera, ship_t *ship, droid_t *droid) {
// Set to final position
vec3_t pos = vec3_sub(ship->position, vec3_mulf(ship->dir_forward, 0.25 * 4096));
pos.x += sin(( (ship->update_timer - UPDATE_TIME_RACE_VIEW) * 30 * 3.0 * M_PI * 2) / 4096.0) * 4096;
pos.y -= (2 * (ship->update_timer - UPDATE_TIME_RACE_VIEW) * 30) + 200;
pos.z += sin(( (ship->update_timer - UPDATE_TIME_RACE_VIEW) * 30 * 3.0 * M_PI * 2) / 4096.0) * 4096;
if (!camera->has_initial_section) {
camera->section = ship->section;
camera->has_initial_section = true;
}
else {
camera->section = track_nearest_section(pos, camera->section, NULL);
}
camera->position = pos;
camera->angle.z = 0;
camera->angle.x = ship->angle.x * 0.5;
vec3_t target = vec3_sub(ship->position, pos);
camera->angle.y = -atan2(target.x, target.z);
if (ship->update_timer <= UPDATE_TIME_RACE_VIEW) {
flags_add(ship->flags, SHIP_VIEW_INTERNAL);
camera->update_func = camera_update_race_internal;
}
}
void camera_update_attract_circle(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->update_timer -= system_tick();
if (camera->update_timer <= 0) {
camera->update_func = camera_update_attract_random;
}
// FIXME: not exactly sure what I'm doing here. The PSX version behaves
// differently.
camera->section = ship->section;
camera->position.x = ship->position.x + sin(ship->angle.y) * 512;
camera->position.y = ship->position.y + ((ship->angle.x * 512 / (M_PI * 2)) - 200);
camera->position.z = ship->position.z - cos(ship->angle.y) * 512;
camera->position.x += sin(camera->update_timer * 0.25) * 512;
camera->position.y -= 400;
camera->position.z += cos(camera->update_timer * 0.25) * 512;
camera->position = vec3_sub(camera->position, vec3_mulf(ship->dir_up, 256));
vec3_t target = vec3_sub(ship->position, camera->position);
float height = sqrt(target.x * target.x + target.z * target.z);
camera->angle.x = -atan2(target.y, height);
camera->angle.y = -atan2(target.x, target.z);
}
void camera_update_rescue(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->position = vec3_add(camera->section->center, vec3(300, -1500, 300));
vec3_t target = vec3_sub(droid->position, camera->position);
float height = sqrt(target.x * target.x + target.z * target.z);
camera->angle.x = -atan2(target.y, height);
camera->angle.y = -atan2(target.x, target.z);
}
void camera_update_attract_internal(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->update_timer -= system_tick();
if (camera->update_timer <= 0) {
camera->update_func = camera_update_attract_random;
}
camera->section = ship->section;
camera->position = ship_cockpit(ship);
camera->angle = vec3(ship->angle.x, ship->angle.y, 0); // No roll
}
void camera_update_static_follow(camera_t *camera, ship_t *ship, droid_t *droid) {
camera->update_timer -= system_tick();
if (camera->update_timer <= 0) {
camera->update_func = camera_update_attract_random;
}
vec3_t target = vec3_sub(ship->position, camera->position);
float height = sqrt(target.x * target.x + target.z * target.z);
camera->angle.x = -atan2(target.y, height);
camera->angle.y = -atan2(target.x, target.z);
}
void camera_update_attract_random(camera_t *camera, ship_t *ship, droid_t *droid) {
flags_rm(ship->flags, SHIP_VIEW_INTERNAL);
if (rand() % 2) {
camera->update_func = camera_update_attract_circle;
camera->update_timer = 5;
}
else {
camera->update_func = camera_update_static_follow;
camera->update_timer = 5;
section_t *section = ship->section->next;
for (int i = 0; i < 10; i++) {
section = section->next;
}
camera->section = section;
camera->position = section->center;
camera->position.y -= 500;
}
(camera->update_func)(camera, ship, droid);
}
+32 -32
View File
@@ -1,32 +1,32 @@
#ifndef CAMERA_H
#define CAMERA_H
#include "../types.h"
#include "droid.h"
typedef struct camera_t {
vec3_t position;
vec3_t velocity;
vec3_t angle;
vec3_t angular_velocity;
vec3_t last_position;
vec3_t real_velocity;
section_t *section;
bool has_initial_section;
float update_timer;
void (*update_func)(struct camera_t *, ship_t *, droid_t *);
} camera_t;
void camera_init(camera_t *camera, section_t *section);
vec3_t camera_forward(camera_t *camera);
void camera_update(camera_t *camera, ship_t *ship, droid_t *droid);
void camera_update_race_external(camera_t *, ship_t *camShip, droid_t *);
void camera_update_race_internal(camera_t *, ship_t *camShip, droid_t *);
void camera_update_race_intro(camera_t *, ship_t *camShip, droid_t *);
void camera_update_attract_circle(camera_t *, ship_t *camShip, droid_t *);
void camera_update_attract_internal(camera_t *, ship_t *camShip, droid_t *);
void camera_update_static_follow(camera_t *, ship_t *camShip, droid_t *);
void camera_update_attract_random(camera_t *, ship_t *camShip, droid_t *);
void camera_update_rescue(camera_t *, ship_t *camShip, droid_t *);
#endif
#ifndef CAMERA_H
#define CAMERA_H
#include "../types.h"
#include "droid.h"
typedef struct camera_t {
vec3_t position;
vec3_t velocity;
vec3_t angle;
vec3_t angular_velocity;
vec3_t last_position;
vec3_t real_velocity;
section_t *section;
bool has_initial_section;
float update_timer;
void (*update_func)(struct camera_t *, ship_t *, droid_t *);
} camera_t;
void camera_init(camera_t *camera, section_t *section);
vec3_t camera_forward(camera_t *camera);
void camera_update(camera_t *camera, ship_t *ship, droid_t *droid);
void camera_update_race_external(camera_t *, ship_t *camShip, droid_t *);
void camera_update_race_internal(camera_t *, ship_t *camShip, droid_t *);
void camera_update_race_intro(camera_t *, ship_t *camShip, droid_t *);
void camera_update_attract_circle(camera_t *, ship_t *camShip, droid_t *);
void camera_update_attract_internal(camera_t *, ship_t *camShip, droid_t *);
void camera_update_static_follow(camera_t *, ship_t *camShip, droid_t *);
void camera_update_attract_random(camera_t *, ship_t *camShip, droid_t *);
void camera_update_rescue(camera_t *, ship_t *camShip, droid_t *);
#endif
+260 -260
View File
File diff suppressed because it is too large Load Diff
+39 -39
View File
@@ -1,39 +1,39 @@
#ifndef DROID_H
#define DROID_H
#include "../types.h"
#include "track.h"
#include "ship.h"
#include "sfx.h"
#define DROID_UPDATE_TIME_INITIAL (800 * (1.0/30.0))
#define DROID_UPDATE_TIME_INTRO_1 (770 * (1.0/30.0))
#define DROID_UPDATE_TIME_INTRO_2 (710 * (1.0/30.0))
#define DROID_UPDATE_TIME_INTRO_3 (400 * (1.0/30.0))
typedef struct droid_t {
section_t *section;
vec3_t position;
vec3_t velocity;
vec3_t acceleration;
vec3_t angle;
vec3_t angular_velocity;
bool siren_started;
float cycle_timer;
float update_timer;
void (*update_func)(struct droid_t *, ship_t *);
mat4_t mat;
Object *model;
sfx_t *sfx_tractor;
} droid_t;
void droid_draw(droid_t *droid);
void droid_load(void);
void droid_init(droid_t *droid, ship_t *ship);
void droid_update(droid_t *droid, ship_t *ship);
void droid_update_intro(droid_t *droid, ship_t *ship);
void droid_update_idle(droid_t *droid, ship_t *ship);
void droid_update_rescue(droid_t *droid, ship_t *ship);
#endif
#ifndef DROID_H
#define DROID_H
#include "../types.h"
#include "track.h"
#include "ship.h"
#include "sfx.h"
#define DROID_UPDATE_TIME_INITIAL (800 * (1.0/30.0))
#define DROID_UPDATE_TIME_INTRO_1 (770 * (1.0/30.0))
#define DROID_UPDATE_TIME_INTRO_2 (710 * (1.0/30.0))
#define DROID_UPDATE_TIME_INTRO_3 (400 * (1.0/30.0))
typedef struct droid_t {
section_t *section;
vec3_t position;
vec3_t velocity;
vec3_t acceleration;
vec3_t angle;
vec3_t angular_velocity;
bool siren_started;
float cycle_timer;
float update_timer;
void (*update_func)(struct droid_t *, ship_t *);
mat4_t mat;
Object *model;
sfx_t *sfx_tractor;
} droid_t;
void droid_draw(droid_t *droid);
void droid_load(void);
void droid_init(droid_t *droid, ship_t *ship);
void droid_update(droid_t *droid, ship_t *ship);
void droid_update_intro(droid_t *droid, ship_t *ship);
void droid_update_idle(droid_t *droid, ship_t *ship);
void droid_update_rescue(droid_t *droid, ship_t *ship);
#endif
+647 -647
View File
File diff suppressed because it is too large Load Diff
+270 -270
View File
File diff suppressed because it is too large Load Diff
+253 -253
View File
File diff suppressed because it is too large Load Diff
+9 -9
View File
@@ -1,9 +1,9 @@
#ifndef HUD_H
#define HUD_H
#include "ship.h"
void hud_load(void);
void hud_draw(ship_t *ship);
#endif
#ifndef HUD_H
#define HUD_H
#include "ship.h"
void hud_load(void);
void hud_draw(ship_t *ship);
#endif
+322 -322
View File
File diff suppressed because it is too large Load Diff
+33 -33
View File
@@ -1,34 +1,34 @@
#ifndef INIT_H
#define INIT_H
#include "../types.h"
typedef struct {
uint16_t start;
uint16_t len;
} texture_list_t;
#define texture_list_empty() ((texture_list_t){0, 0})
typedef struct {
uint32_t width;
uint32_t height;
rgba_t *pixels;
} image_t;
typedef struct {
uint32_t len;
uint8_t *entries[];
} cmp_t;
image_t *image_alloc(uint32_t width, uint32_t height);
void image_copy(image_t *src, image_t *dst, uint32_t sx, uint32_t sy, uint32_t sw, uint32_t sh, uint32_t dx, uint32_t dy);
image_t *image_load_from_bytes(uint8_t *bytes, bool transparent);
cmp_t *image_load_compressed(char *name);
uint16_t image_get_texture(char *name);
uint16_t image_get_texture_semi_trans(char *name);
texture_list_t image_get_compressed_textures(char *name);
uint16_t texture_from_list(texture_list_t tl, uint16_t index);
#ifndef INIT_H
#define INIT_H
#include "../types.h"
typedef struct {
uint16_t start;
uint16_t len;
} texture_list_t;
#define texture_list_empty() ((texture_list_t){0, 0})
typedef struct {
uint32_t width;
uint32_t height;
rgba_t *pixels;
} image_t;
typedef struct {
uint32_t len;
uint8_t *entries[];
} cmp_t;
image_t *image_alloc(uint32_t width, uint32_t height);
void image_copy(image_t *src, image_t *dst, uint32_t sx, uint32_t sy, uint32_t sw, uint32_t sh, uint32_t dx, uint32_t dy);
image_t *image_load_from_bytes(uint8_t *bytes, bool transparent);
cmp_t *image_load_compressed(char *name);
uint16_t image_get_texture(char *name);
uint16_t image_get_texture_semi_trans(char *name);
texture_list_t image_get_compressed_textures(char *name);
uint16_t texture_from_list(texture_list_t tl, uint16_t index);
#endif
+486 -486
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -1,13 +1,13 @@
#ifndef PAUSE_MENU_H
#define PAUSE_MENU_H
#include "menu.h"
void ingame_menus_load(void);
menu_t *pause_menu_init(void);
menu_t *game_over_menu_init(void);
menu_t *race_stats_menu_init(void);
menu_t *text_scroll_menu_init(char * const *lines, int len);
#endif
#ifndef PAUSE_MENU_H
#define PAUSE_MENU_H
#include "menu.h"
void ingame_menus_load(void);
menu_t *pause_menu_init(void);
menu_t *game_over_menu_init(void);
menu_t *race_stats_menu_init(void);
menu_t *text_scroll_menu_init(char * const *lines, int len);
#endif
+541 -541
View File
File diff suppressed because it is too large Load Diff
+7 -7
View File
@@ -1,7 +1,7 @@
#ifndef MAIN_MENU_H
#define MAIN_MENU_H
void main_menu_init(void);
void main_menu_update(void);
#endif
#ifndef MAIN_MENU_H
#define MAIN_MENU_H
void main_menu_init(void);
void main_menu_update(void);
#endif
+245 -245
View File
@@ -1,245 +1,245 @@
#include "../system.h"
#include "../input.h"
#include "../utils.h"
#include "game.h"
#include "menu.h"
#include "ui.h"
#include "sfx.h"
bool blink(void) {
// blink 30 times per second
return fmod(system_cycle_time(), 1.0/15.0) < 1.0/30.0;
}
void menu_reset(menu_t *menu) {
menu->index = -1;
}
menu_page_t *menu_push(menu_t *menu, char *title, void(*draw_func)(menu_t *, int)) {
error_if(menu->index >= MENU_PAGES_MAX-1, "MENU_PAGES_MAX exceeded");
menu_page_t *page = &menu->pages[++menu->index];
page->layout_flags = MENU_VERTICAL | MENU_ALIGN_CENTER;
page->block_width = 320;
page->title = title;
page->subtitle = NULL;
page->draw_func = draw_func;
page->entries_len = 0;
page->index = 0;
page->title_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
page->items_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
return page;
}
menu_page_t *menu_confirm(menu_t *menu, char *title, char *subtitle, char *yes, char *no, void(*confirm_func)(menu_t *, int)) {
error_if(menu->index >= MENU_PAGES_MAX-1, "MENU_PAGES_MAX exceeded");
menu_page_t *page = &menu->pages[++menu->index];
page->layout_flags = MENU_HORIZONTAL;
page->title = title;
page->subtitle = subtitle;
page->draw_func = NULL;
page->entries_len = 0;
menu_page_add_button(page, 1, yes, confirm_func);
menu_page_add_button(page, 0, no, confirm_func);
page->index = 1;
page->title_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
page->items_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
return page;
}
void menu_pop(menu_t *menu) {
if (menu->index == 0) {
return;
}
menu->index--;
}
void menu_page_add_button(menu_page_t *page, int data, char *text, void(*select_func)(menu_t *, int)) {
error_if(page->entries_len >= MENU_ENTRIES_MAX-1, "MENU_ENTRIES_MAX exceeded");
menu_entry_t *entry = &page->entries[page->entries_len++];
entry->data = data;
entry->text = text;
entry->select_func = select_func;
entry->type = MENU_ENTRY_BUTTON;
}
void menu_page_add_toggle(menu_page_t *page, int data, char *text, const char **options, int len, void(*select_func)(menu_t *, int)) {
error_if(page->entries_len >= MENU_ENTRIES_MAX-1, "MENU_ENTRIES_MAX exceeded");
menu_entry_t *entry = &page->entries[page->entries_len++];
entry->data = data;
entry->text = text;
entry->select_func = select_func;
entry->type = MENU_ENTRY_TOGGLE;
entry->options = options;
entry->options_len = len;
}
void menu_update(menu_t *menu) {
render_set_view_2d();
error_if(menu->index < 0, "Attempt to update menu without a page");
menu_page_t *page = &menu->pages[menu->index];
// Handle menu entry selecting
int last_index = page->index;
int selected_data = 0;
if (page->entries_len > 0) {
if (flags_is(page->layout_flags, MENU_HORIZONTAL)) {
if (input_pressed(A_MENU_LEFT)) {
page->index--;
}
else if (input_pressed(A_MENU_RIGHT)) {
page->index++;
}
}
else {
if (input_pressed(A_MENU_UP)) {
page->index--;
}
if (input_pressed(A_MENU_DOWN)) {
page->index++;
}
}
if (page->index >= page->entries_len) {
page->index = 0;
}
if (page->index < 0) {
page->index = page->entries_len - 1;
}
if (last_index != page->index) {
sfx_play(SFX_MENU_MOVE);
}
selected_data = page->entries[page->index].data;
}
if (page->draw_func) {
page->draw_func(menu, selected_data);
}
render_set_view_2d();
// Draw Horizontal (confirm)
if (flags_is(page->layout_flags, MENU_HORIZONTAL)) {
vec2i_t pos = vec2i(0, -20);
ui_draw_text_centered(page->title, ui_scaled_pos(page->title_anchor, pos), UI_SIZE_8, UI_COLOR_DEFAULT);
if (page->subtitle) {
pos.y += 12;
ui_draw_text_centered(page->subtitle, ui_scaled_pos(page->title_anchor, pos), UI_SIZE_8, UI_COLOR_DEFAULT);
}
pos.y += 16;
page = &menu->pages[menu->index];
pos.x = -50;
for (int i = 0; i < page->entries_len; i++) {
menu_entry_t *entry = &page->entries[i];
rgba_t text_color;
if (i == page->index && blink()) {
text_color = UI_COLOR_ACCENT;
}
else {
text_color = UI_COLOR_DEFAULT;
}
ui_draw_text_centered(entry->text, ui_scaled_pos(page->items_anchor, pos), UI_SIZE_16, text_color);
pos.x = 60;
}
}
// Draw Vertical
else {
vec2i_t title_pos, items_pos;
if (flags_not(page->layout_flags, MENU_FIXED)) {
int height = 20 + page->entries_len * 12;
title_pos = vec2i(0, -height/2);
items_pos = vec2i(0, -height/2 + 20);
}
else {
title_pos = page->title_pos;
items_pos = page->items_pos;
}
if (flags_is(page->layout_flags, MENU_ALIGN_CENTER)) {
ui_draw_text_centered(page->title, ui_scaled_pos(page->title_anchor, title_pos), UI_SIZE_12, UI_COLOR_ACCENT);
}
else {
ui_draw_text(page->title, ui_scaled_pos(page->title_anchor, title_pos), UI_SIZE_12, UI_COLOR_ACCENT);
}
page = &menu->pages[menu->index];
for (int i = 0; i < page->entries_len; i++) {
menu_entry_t *entry = &page->entries[i];
rgba_t text_color;
if (i == page->index && blink()) {
text_color = UI_COLOR_ACCENT;
}
else {
text_color = UI_COLOR_DEFAULT;
}
if (flags_is(page->layout_flags, MENU_ALIGN_CENTER)) {
ui_draw_text_centered(entry->text, ui_scaled_pos(page->items_anchor, items_pos), UI_SIZE_8, text_color);
}
else {
ui_draw_text(entry->text, ui_scaled_pos(page->items_anchor, items_pos), UI_SIZE_8, text_color);
}
if (entry->type == MENU_ENTRY_TOGGLE) {
vec2i_t toggle_pos = items_pos;
toggle_pos.x += page->block_width - ui_text_width(entry->options[entry->data], UI_SIZE_8);
ui_draw_text(entry->options[entry->data], ui_scaled_pos(page->items_anchor, toggle_pos), UI_SIZE_8, text_color);
}
items_pos.y += 12;
}
}
// Handle back buttons
if (input_pressed(A_MENU_BACK) || input_pressed(A_MENU_QUIT)) {
if (menu->index != 0) {
menu_pop(menu);
sfx_play(SFX_MENU_SELECT);
}
return;
}
if (page->entries_len == 0) {
return;
}
// Handle toggle entries
menu_entry_t *entry = &page->entries[page->index];
if (entry->type == MENU_ENTRY_TOGGLE) {
if (input_pressed(A_MENU_LEFT)) {
sfx_play(SFX_MENU_SELECT);
entry->data--;
if (entry->data < 0) {
entry->data = entry->options_len-1;
}
if (entry->select_func) {
entry->select_func(menu, entry->data);
}
}
else if (input_pressed(A_MENU_RIGHT) || input_pressed(A_MENU_SELECT) || input_pressed(A_MENU_START)) {
sfx_play(SFX_MENU_SELECT);
entry->data = (entry->data + 1) % entry->options_len;
if (entry->select_func) {
entry->select_func(menu, entry->data);
}
}
}
// Handle buttons
else {
if (input_pressed(A_MENU_SELECT) || input_pressed(A_MENU_START)) {
if (entry->select_func) {
sfx_play(SFX_MENU_SELECT);
if (entry->type == MENU_ENTRY_TOGGLE) {
entry->data = (entry->data + 1) % entry->options_len;
}
entry->select_func(menu, entry->data);
}
}
}
}
#include "../system.h"
#include "../input.h"
#include "../utils.h"
#include "game.h"
#include "menu.h"
#include "ui.h"
#include "sfx.h"
bool blink(void) {
// blink 30 times per second
return fmod(system_cycle_time(), 1.0/15.0) < 1.0/30.0;
}
void menu_reset(menu_t *menu) {
menu->index = -1;
}
menu_page_t *menu_push(menu_t *menu, char *title, void(*draw_func)(menu_t *, int)) {
error_if(menu->index >= MENU_PAGES_MAX-1, "MENU_PAGES_MAX exceeded");
menu_page_t *page = &menu->pages[++menu->index];
page->layout_flags = MENU_VERTICAL | MENU_ALIGN_CENTER;
page->block_width = 320;
page->title = title;
page->subtitle = NULL;
page->draw_func = draw_func;
page->entries_len = 0;
page->index = 0;
page->title_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
page->items_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
return page;
}
menu_page_t *menu_confirm(menu_t *menu, char *title, char *subtitle, char *yes, char *no, void(*confirm_func)(menu_t *, int)) {
error_if(menu->index >= MENU_PAGES_MAX-1, "MENU_PAGES_MAX exceeded");
menu_page_t *page = &menu->pages[++menu->index];
page->layout_flags = MENU_HORIZONTAL;
page->title = title;
page->subtitle = subtitle;
page->draw_func = NULL;
page->entries_len = 0;
menu_page_add_button(page, 1, yes, confirm_func);
menu_page_add_button(page, 0, no, confirm_func);
page->index = 1;
page->title_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
page->items_anchor = UI_POS_MIDDLE | UI_POS_CENTER;
return page;
}
void menu_pop(menu_t *menu) {
if (menu->index == 0) {
return;
}
menu->index--;
}
void menu_page_add_button(menu_page_t *page, int data, char *text, void(*select_func)(menu_t *, int)) {
error_if(page->entries_len >= MENU_ENTRIES_MAX-1, "MENU_ENTRIES_MAX exceeded");
menu_entry_t *entry = &page->entries[page->entries_len++];
entry->data = data;
entry->text = text;
entry->select_func = select_func;
entry->type = MENU_ENTRY_BUTTON;
}
void menu_page_add_toggle(menu_page_t *page, int data, char *text, const char **options, int len, void(*select_func)(menu_t *, int)) {
error_if(page->entries_len >= MENU_ENTRIES_MAX-1, "MENU_ENTRIES_MAX exceeded");
menu_entry_t *entry = &page->entries[page->entries_len++];
entry->data = data;
entry->text = text;
entry->select_func = select_func;
entry->type = MENU_ENTRY_TOGGLE;
entry->options = options;
entry->options_len = len;
}
void menu_update(menu_t *menu) {
render_set_view_2d();
error_if(menu->index < 0, "Attempt to update menu without a page");
menu_page_t *page = &menu->pages[menu->index];
// Handle menu entry selecting
int last_index = page->index;
int selected_data = 0;
if (page->entries_len > 0) {
if (flags_is(page->layout_flags, MENU_HORIZONTAL)) {
if (input_pressed(A_MENU_LEFT)) {
page->index--;
}
else if (input_pressed(A_MENU_RIGHT)) {
page->index++;
}
}
else {
if (input_pressed(A_MENU_UP)) {
page->index--;
}
if (input_pressed(A_MENU_DOWN)) {
page->index++;
}
}
if (page->index >= page->entries_len) {
page->index = 0;
}
if (page->index < 0) {
page->index = page->entries_len - 1;
}
if (last_index != page->index) {
sfx_play(SFX_MENU_MOVE);
}
selected_data = page->entries[page->index].data;
}
if (page->draw_func) {
page->draw_func(menu, selected_data);
}
render_set_view_2d();
// Draw Horizontal (confirm)
if (flags_is(page->layout_flags, MENU_HORIZONTAL)) {
vec2i_t pos = vec2i(0, -20);
ui_draw_text_centered(page->title, ui_scaled_pos(page->title_anchor, pos), UI_SIZE_8, UI_COLOR_DEFAULT);
if (page->subtitle) {
pos.y += 12;
ui_draw_text_centered(page->subtitle, ui_scaled_pos(page->title_anchor, pos), UI_SIZE_8, UI_COLOR_DEFAULT);
}
pos.y += 16;
page = &menu->pages[menu->index];
pos.x = -50;
for (int i = 0; i < page->entries_len; i++) {
menu_entry_t *entry = &page->entries[i];
rgba_t text_color;
if (i == page->index && blink()) {
text_color = UI_COLOR_ACCENT;
}
else {
text_color = UI_COLOR_DEFAULT;
}
ui_draw_text_centered(entry->text, ui_scaled_pos(page->items_anchor, pos), UI_SIZE_16, text_color);
pos.x = 60;
}
}
// Draw Vertical
else {
vec2i_t title_pos, items_pos;
if (flags_not(page->layout_flags, MENU_FIXED)) {
int height = 20 + page->entries_len * 12;
title_pos = vec2i(0, -height/2);
items_pos = vec2i(0, -height/2 + 20);
}
else {
title_pos = page->title_pos;
items_pos = page->items_pos;
}
if (flags_is(page->layout_flags, MENU_ALIGN_CENTER)) {
ui_draw_text_centered(page->title, ui_scaled_pos(page->title_anchor, title_pos), UI_SIZE_12, UI_COLOR_ACCENT);
}
else {
ui_draw_text(page->title, ui_scaled_pos(page->title_anchor, title_pos), UI_SIZE_12, UI_COLOR_ACCENT);
}
page = &menu->pages[menu->index];
for (int i = 0; i < page->entries_len; i++) {
menu_entry_t *entry = &page->entries[i];
rgba_t text_color;
if (i == page->index && blink()) {
text_color = UI_COLOR_ACCENT;
}
else {
text_color = UI_COLOR_DEFAULT;
}
if (flags_is(page->layout_flags, MENU_ALIGN_CENTER)) {
ui_draw_text_centered(entry->text, ui_scaled_pos(page->items_anchor, items_pos), UI_SIZE_8, text_color);
}
else {
ui_draw_text(entry->text, ui_scaled_pos(page->items_anchor, items_pos), UI_SIZE_8, text_color);
}
if (entry->type == MENU_ENTRY_TOGGLE) {
vec2i_t toggle_pos = items_pos;
toggle_pos.x += page->block_width - ui_text_width(entry->options[entry->data], UI_SIZE_8);
ui_draw_text(entry->options[entry->data], ui_scaled_pos(page->items_anchor, toggle_pos), UI_SIZE_8, text_color);
}
items_pos.y += 12;
}
}
// Handle back buttons
if (input_pressed(A_MENU_BACK) || input_pressed(A_MENU_QUIT)) {
if (menu->index != 0) {
menu_pop(menu);
sfx_play(SFX_MENU_SELECT);
}
return;
}
if (page->entries_len == 0) {
return;
}
// Handle toggle entries
menu_entry_t *entry = &page->entries[page->index];
if (entry->type == MENU_ENTRY_TOGGLE) {
if (input_pressed(A_MENU_LEFT)) {
sfx_play(SFX_MENU_SELECT);
entry->data--;
if (entry->data < 0) {
entry->data = entry->options_len-1;
}
if (entry->select_func) {
entry->select_func(menu, entry->data);
}
}
else if (input_pressed(A_MENU_RIGHT) || input_pressed(A_MENU_SELECT) || input_pressed(A_MENU_START)) {
sfx_play(SFX_MENU_SELECT);
entry->data = (entry->data + 1) % entry->options_len;
if (entry->select_func) {
entry->select_func(menu, entry->data);
}
}
}
// Handle buttons
else {
if (input_pressed(A_MENU_SELECT) || input_pressed(A_MENU_START)) {
if (entry->select_func) {
sfx_play(SFX_MENU_SELECT);
if (entry->type == MENU_ENTRY_TOGGLE) {
entry->data = (entry->data + 1) % entry->options_len;
}
entry->select_func(menu, entry->data);
}
}
}
}
+65 -65
View File
@@ -1,65 +1,65 @@
#ifndef MENU_H
#define MENU_H
#include "../types.h"
#include "ui.h"
#define MENU_PAGES_MAX 8
#define MENU_ENTRIES_MAX 16
typedef enum {
MENU_ENTRY_BUTTON,
MENU_ENTRY_TOGGLE
} menu_entry_type_t;
typedef enum {
MENU_VERTICAL = (1<<0),
MENU_HORIZONTAL = (1<<1),
MENU_FIXED = (1<<2),
MENU_ALIGN_CENTER = (1<<3),
MENU_ALIGN_BLOCK = (1<<4)
} menu_page_layout_t;
typedef struct menu_t menu_t;
typedef struct menu_page_t menu_page_t;
typedef struct menu_entry_t menu_entry_t;
typedef struct menu_entry_options_t menu_entry_options_t;
struct menu_entry_t {
menu_entry_type_t type;
int data;
char *text;
void (*select_func)(menu_t *, int);
const char **options;
int options_len;
};
struct menu_page_t {
char *title, *subtitle;
menu_page_layout_t layout_flags;
void (*draw_func)(menu_t *, int);
menu_entry_t entries[MENU_ENTRIES_MAX];
int entries_len;
int index;
int block_width;
vec2i_t title_pos;
ui_pos_t title_anchor;
vec2i_t items_pos;
ui_pos_t items_anchor;
};
struct menu_t {
menu_page_t pages[MENU_PAGES_MAX];
int index;
};
void menu_reset(menu_t *menu);
menu_page_t *menu_push(menu_t *menu, char *title, void(*draw_func)(menu_t *, int));
menu_page_t *menu_confirm(menu_t *menu, char *title, char *subtitle, char *yes, char *no, void(*confirm_func)(menu_t *, int));
void menu_pop(menu_t *menu);
void menu_page_add_button(menu_page_t *page, int data, char *text, void(*select_func)(menu_t *, int));
void menu_page_add_toggle(menu_page_t *page, int data, char *text, const char **options, int len, void(*select_func)(menu_t *, int));
void menu_update(menu_t *menu);
#endif
#ifndef MENU_H
#define MENU_H
#include "../types.h"
#include "ui.h"
#define MENU_PAGES_MAX 8
#define MENU_ENTRIES_MAX 16
typedef enum {
MENU_ENTRY_BUTTON,
MENU_ENTRY_TOGGLE
} menu_entry_type_t;
typedef enum {
MENU_VERTICAL = (1<<0),
MENU_HORIZONTAL = (1<<1),
MENU_FIXED = (1<<2),
MENU_ALIGN_CENTER = (1<<3),
MENU_ALIGN_BLOCK = (1<<4)
} menu_page_layout_t;
typedef struct menu_t menu_t;
typedef struct menu_page_t menu_page_t;
typedef struct menu_entry_t menu_entry_t;
typedef struct menu_entry_options_t menu_entry_options_t;
struct menu_entry_t {
menu_entry_type_t type;
int data;
char *text;
void (*select_func)(menu_t *, int);
const char **options;
int options_len;
};
struct menu_page_t {
char *title, *subtitle;
menu_page_layout_t layout_flags;
void (*draw_func)(menu_t *, int);
menu_entry_t entries[MENU_ENTRIES_MAX];
int entries_len;
int index;
int block_width;
vec2i_t title_pos;
ui_pos_t title_anchor;
vec2i_t items_pos;
ui_pos_t items_anchor;
};
struct menu_t {
menu_page_t pages[MENU_PAGES_MAX];
int index;
};
void menu_reset(menu_t *menu);
menu_page_t *menu_push(menu_t *menu, char *title, void(*draw_func)(menu_t *, int));
menu_page_t *menu_confirm(menu_t *menu, char *title, char *subtitle, char *yes, char *no, void(*confirm_func)(menu_t *, int));
void menu_pop(menu_t *menu);
void menu_page_add_button(menu_page_t *page, int data, char *text, void(*select_func)(menu_t *, int));
void menu_page_add_toggle(menu_page_t *page, int data, char *text, const char **options, int len, void(*select_func)(menu_t *, int));
void menu_update(menu_t *menu);
#endif
+782 -782
View File
File diff suppressed because it is too large Load Diff
+383 -383
View File
File diff suppressed because it is too large Load Diff
+279 -279
View File
File diff suppressed because it is too large Load Diff
+14 -14
View File
@@ -1,14 +1,14 @@
#ifndef RACE_H
#define RACE_H
void race_init(void);
void race_update(void);
void race_start(void);
void race_restart(void);
void race_pause(void);
void race_unpause(void);
void race_end(void);
void race_next(void);
void race_release_control(void);
#endif
#ifndef RACE_H
#define RACE_H
void race_init(void);
void race_update(void);
void race_start(void);
void race_restart(void);
void race_pause(void);
void race_unpause(void);
void race_end(void);
void race_next(void);
void race_release_control(void);
#endif

Some files were not shown because too many files have changed in this diff Show More