Move global item collected-state, deadzone, and story flags into save file
Adds three new pieces of save-file state, all following the same shape: the save file is the single source of truth, not a separate live runtime copy that gets synced in/out. - globalitemstore.h/.c: per-global-entity-ID "collected" flags (savefile_t.globalItemCollected), so a global item entity's init callback can check whether it was already picked up in a prior session without needing to keep the entity itself alive to remember that. - Gamepad deadzone: removed input_t.deadzone entirely. The setting UI and every platform's actual deadzone-applying code (inputGetDeadzoneDolphin/ SDL2, previously hardcoded per-platform literals that the settings menu didn't actually affect) now read savefile_t.deadzone directly via saveGet(SAVE_ACTIVE_SLOT). Default lives in savefile.h (SAVE_DEADZONE_DEFAULT), stamped onto every slot in saveInit(). - Story flags: STORY_FLAG_VALUES (a live, codegen-initialized array) is replaced by savefile_t.storyFlags, read/written via the existing storyFlagGet()/storyFlagSet() call sites (now macros/functions over the active save file instead of a separate array). tools/story.py now generates STORY_FLAG_DEFAULTS (const) instead; storyFlagInitDefaults() stamps those onto a save the first time it's used (file->exists false), called from rpgInit(). Added SAVE_ACTIVE_SLOT (0) to savefile.h as the one shared "which slot is actually being played" constant, replacing three different local/implicit 0s (uigamemenu.c, rpg.c, and now the settings/input call sites). Verified round-trip on Linux (all three together in one save/load cycle); both Linux and PSP build clean.
This commit is contained in:
@@ -17,7 +17,6 @@ input_t INPUT;
|
|||||||
|
|
||||||
errorret_t inputInit(void) {
|
errorret_t inputInit(void) {
|
||||||
memoryZero(&INPUT, sizeof(input_t));
|
memoryZero(&INPUT, sizeof(input_t));
|
||||||
INPUT.deadzone = INPUT_DEADZONE_DEFAULT;
|
|
||||||
|
|
||||||
for(uint8_t i = 0; i < INPUT_ACTION_COUNT; i++) {
|
for(uint8_t i = 0; i < INPUT_ACTION_COUNT; i++) {
|
||||||
INPUT.actions[i].action = (inputaction_t)i;
|
INPUT.actions[i].action = (inputaction_t)i;
|
||||||
|
|||||||
@@ -12,15 +12,11 @@
|
|||||||
|
|
||||||
#define INPUT_LISTENER_PRESSED_MAX 16
|
#define INPUT_LISTENER_PRESSED_MAX 16
|
||||||
#define INPUT_LISTENER_RELEASED_MAX INPUT_LISTENER_PRESSED_MAX
|
#define INPUT_LISTENER_RELEASED_MAX INPUT_LISTENER_PRESSED_MAX
|
||||||
#define INPUT_DEADZONE_DEFAULT 0.1f
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
inputactiondata_t actions[INPUT_ACTION_COUNT];
|
inputactiondata_t actions[INPUT_ACTION_COUNT];
|
||||||
|
|
||||||
inputplatform_t platform;
|
inputplatform_t platform;
|
||||||
|
|
||||||
/** User-configured gamepad axis deadzone (0.0f to 1.0f). */
|
|
||||||
float_t deadzone;
|
|
||||||
} input_t;
|
} input_t;
|
||||||
|
|
||||||
extern input_t INPUT;
|
extern input_t INPUT;
|
||||||
|
|||||||
@@ -6,4 +6,5 @@
|
|||||||
# Sources
|
# Sources
|
||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
|
globalitemstore.c
|
||||||
)
|
)
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "globalitemstore.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
bool_t globalItemStoreIsCollected(
|
||||||
|
const savefile_t *file, const entityglobalid_t id
|
||||||
|
) {
|
||||||
|
assertNotNull(file, "Save file cannot be NULL");
|
||||||
|
assertTrue(id < SAVE_GLOBAL_ITEM_COUNT_MAX, "Global item ID out of range");
|
||||||
|
return file->globalItemCollected[id];
|
||||||
|
}
|
||||||
|
|
||||||
|
void globalItemStoreSetCollected(
|
||||||
|
savefile_t *file, const entityglobalid_t id, const bool_t collected
|
||||||
|
) {
|
||||||
|
assertNotNull(file, "Save file cannot be NULL");
|
||||||
|
assertTrue(id < SAVE_GLOBAL_ITEM_COUNT_MAX, "Global item ID out of range");
|
||||||
|
file->globalItemCollected[id] = collected;
|
||||||
|
}
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#include "error/error.h"
|
||||||
|
#include "save/savefile.h"
|
||||||
|
#include "rpg/entity/entity.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the global entity with the given ID has already been
|
||||||
|
* marked collected in the given save file's data - e.g. so a global item
|
||||||
|
* entity's init callback (see rpg/entity/global/entitygloballist.h) can
|
||||||
|
* skip spawning itself if the player already picked it up in a prior
|
||||||
|
* session, without needing to keep the entity itself alive to remember
|
||||||
|
* that (which would need render/collision special-casing - this doesn't).
|
||||||
|
*
|
||||||
|
* @param file The save file to check.
|
||||||
|
* @param id The global entity ID to check.
|
||||||
|
* @return True if already marked collected.
|
||||||
|
*/
|
||||||
|
bool_t globalItemStoreIsCollected(
|
||||||
|
const savefile_t *file, const entityglobalid_t id
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the global entity with the given ID as collected (or not) in the
|
||||||
|
* given save file's data. Does not itself write the save to disk - call
|
||||||
|
* saveWrite() separately once ready to persist it.
|
||||||
|
*
|
||||||
|
* @param file The save file to write into.
|
||||||
|
* @param id The global entity ID to mark.
|
||||||
|
* @param collected The new collected state.
|
||||||
|
*/
|
||||||
|
void globalItemStoreSetCollected(
|
||||||
|
savefile_t *file, const entityglobalid_t id, const bool_t collected
|
||||||
|
);
|
||||||
+8
-2
@@ -22,6 +22,7 @@
|
|||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
|
||||||
#include "ui/rpg/uiemoji.h"
|
#include "ui/rpg/uiemoji.h"
|
||||||
|
#include "rpg/story/storyflag.h"
|
||||||
|
|
||||||
static void rpgTestSaveComplete(errorret_t result, void *user) {
|
static void rpgTestSaveComplete(errorret_t result, void *user) {
|
||||||
if(errorIsNotOk(result)) errorCatch(errorPrint(result));
|
if(errorIsNotOk(result)) errorCatch(errorPrint(result));
|
||||||
@@ -31,6 +32,11 @@ errorret_t rpgInit(void) {
|
|||||||
memoryZero(ENTITIES, sizeof(ENTITIES));
|
memoryZero(ENTITIES, sizeof(ENTITIES));
|
||||||
memoryZero(MAP_AREAS, sizeof(MAP_AREAS));
|
memoryZero(MAP_AREAS, sizeof(MAP_AREAS));
|
||||||
|
|
||||||
|
// Must run before any code reads a story flag - stamps CSV-defined
|
||||||
|
// defaults onto the active save slot if it's never actually been
|
||||||
|
// loaded from disk yet.
|
||||||
|
storyFlagInitDefaults(saveGet(SAVE_ACTIVE_SLOT));
|
||||||
|
|
||||||
backpackInit();
|
backpackInit();
|
||||||
partyInit();
|
partyInit();
|
||||||
cutsceneSystemInit();
|
cutsceneSystemInit();
|
||||||
@@ -61,9 +67,9 @@ errorret_t rpgInit(void) {
|
|||||||
// header/version. Remove once there's an actual name-entry flow. On PSP
|
// header/version. Remove once there's an actual name-entry flow. On PSP
|
||||||
// this shows the real native save dialog every boot - expected while
|
// this shows the real native save dialog every boot - expected while
|
||||||
// testing that path, not something to ship as-is.
|
// testing that path, not something to ship as-is.
|
||||||
savefile_t *saveFile = saveGet(0);
|
savefile_t *saveFile = saveGet(SAVE_ACTIVE_SLOT);
|
||||||
stringCopy(saveFile->playerName, "Dusk", SAVE_PLAYER_NAME_MAX);
|
stringCopy(saveFile->playerName, "Dusk", SAVE_PLAYER_NAME_MAX);
|
||||||
saveWrite(0, rpgTestSaveComplete, NULL);
|
saveWrite(SAVE_ACTIVE_SLOT, rpgTestSaveComplete, NULL);
|
||||||
|
|
||||||
// All Good!
|
// All Good!
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -10,5 +10,17 @@
|
|||||||
|
|
||||||
void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value) {
|
void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value) {
|
||||||
assertTrue(flag > STORY_FLAG_NULL && flag < STORY_FLAG_COUNT, "Bad Flag");
|
assertTrue(flag > STORY_FLAG_NULL && flag < STORY_FLAG_COUNT, "Bad Flag");
|
||||||
STORY_FLAG_VALUES[flag] = value;
|
saveGet(SAVE_ACTIVE_SLOT)->storyFlags[flag] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void storyFlagInitDefaults(savefile_t *file) {
|
||||||
|
assertNotNull(file, "Save file cannot be NULL");
|
||||||
|
if(file->exists) return;
|
||||||
|
assertTrue(
|
||||||
|
STORY_FLAG_COUNT <= SAVE_STORY_FLAG_COUNT_MAX,
|
||||||
|
"Too many story flags for the save format - bump SAVE_STORY_FLAG_COUNT_MAX"
|
||||||
|
);
|
||||||
|
for(storyflag_t i = 0; i < STORY_FLAG_COUNT; i++) {
|
||||||
|
file->storyFlags[i] = STORY_FLAG_DEFAULTS[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -7,19 +7,34 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "rpg/story/storyflagvalue.h"
|
#include "rpg/story/storyflagvalue.h"
|
||||||
|
#include "save/save.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the value of a story flag.
|
* Gets the value of a story flag. Reads directly from the active save
|
||||||
|
* file (see SAVE_ACTIVE_SLOT) - flag values have no separate live copy.
|
||||||
*
|
*
|
||||||
* @param flag The story flag to get.
|
* @param flag The story flag to get.
|
||||||
* @return The value of the story flag.
|
* @return The value of the story flag.
|
||||||
*/
|
*/
|
||||||
#define storyFlagGet(flag) (STORY_FLAG_VALUES[(flag)])
|
#define storyFlagGet(flag) (saveGet(SAVE_ACTIVE_SLOT)->storyFlags[(flag)])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the value of a story flag.
|
* Sets the value of a story flag, directly in the active save file (see
|
||||||
|
* SAVE_ACTIVE_SLOT). Does not itself write the save to disk - call
|
||||||
|
* saveWrite() separately once ready to persist it.
|
||||||
*
|
*
|
||||||
* @param flag The story flag to set.
|
* @param flag The story flag to set.
|
||||||
* @param value The value to set the story flag to.
|
* @param value The value to set the story flag to.
|
||||||
*/
|
*/
|
||||||
void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value);
|
void storyFlagSet(const storyflag_t flag, const storyflagvalue_t value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stamps each story flag's CSV-defined default (STORY_FLAG_DEFAULTS) onto
|
||||||
|
* the given save file, but only if it hasn't actually been loaded from
|
||||||
|
* disk yet (file->exists is false) - otherwise leaves already-played
|
||||||
|
* progress alone. Call once, e.g. during rpgInit(), before any gameplay
|
||||||
|
* code reads a story flag.
|
||||||
|
*
|
||||||
|
* @param file The save file to stamp defaults onto.
|
||||||
|
*/
|
||||||
|
void storyFlagInitDefaults(savefile_t *file);
|
||||||
|
|||||||
@@ -16,6 +16,13 @@ save_t SAVE;
|
|||||||
errorret_t saveInit(void) {
|
errorret_t saveInit(void) {
|
||||||
memoryZero(&SAVE, sizeof(save_t));
|
memoryZero(&SAVE, sizeof(save_t));
|
||||||
|
|
||||||
|
// Establishes the default for a slot that hasn't actually been loaded
|
||||||
|
// from disk yet - saveLoad() overwrites this the moment a real file is
|
||||||
|
// found, so this only matters for a brand new save.
|
||||||
|
for(uint8_t i = 0; i < SAVE_FILE_COUNT_MAX; i++) {
|
||||||
|
SAVE.files[i].deadzone = SAVE_DEADZONE_DEFAULT;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef saveInitPlatform
|
#ifdef saveInitPlatform
|
||||||
// A missing/unreachable save medium is expected, recoverable state,
|
// A missing/unreachable save medium is expected, recoverable state,
|
||||||
// not a reason to fail booting the whole game - log it and carry on
|
// not a reason to fail booting the whole game - log it and carry on
|
||||||
|
|||||||
@@ -20,9 +20,44 @@
|
|||||||
/** Maximum number of independent save slots supported. */
|
/** Maximum number of independent save slots supported. */
|
||||||
#define SAVE_FILE_COUNT_MAX 3
|
#define SAVE_FILE_COUNT_MAX 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The save slot actually used for gameplay right now - there's no slot
|
||||||
|
* select/multi-save UX yet (SAVE_FILE_COUNT_MAX > 1 exists for later), so
|
||||||
|
* every part of the game that needs "the" save file (settings, the game
|
||||||
|
* menu's Save button, etc.) reads/writes this one slot.
|
||||||
|
*/
|
||||||
|
#define SAVE_ACTIVE_SLOT 0
|
||||||
|
|
||||||
/** Maximum length of a saved player name, including the null terminator. */
|
/** Maximum length of a saved player name, including the null terminator. */
|
||||||
#define SAVE_PLAYER_NAME_MAX 32
|
#define SAVE_PLAYER_NAME_MAX 32
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of global entities whose "collected" state can be
|
||||||
|
* tracked - see rpg/entity/global/globalitemstore.h. Bounded/fixed here
|
||||||
|
* rather than tied to ENTITY_GLOBAL_LIST_COUNT, since savefile.h is a
|
||||||
|
* leaf header with no dependency on the entity system (and no reason to
|
||||||
|
* take one just for a size constant).
|
||||||
|
*/
|
||||||
|
#define SAVE_GLOBAL_ITEM_COUNT_MAX 64
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default gamepad deadzone for a save slot that's never actually been
|
||||||
|
* loaded from disk yet (see saveInit(), which stamps this onto every
|
||||||
|
* slot up front) - defined here, rather than by the input system, since
|
||||||
|
* the save file is now the single source of truth for this value (see
|
||||||
|
* savefile_t.deadzone) - nothing else stores or defaults it.
|
||||||
|
*/
|
||||||
|
#define SAVE_DEADZONE_DEFAULT 0.1f
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maximum number of story flags the save format can hold - see
|
||||||
|
* rpg/story/storyflag.h. Bounded/fixed here (with real headroom over the
|
||||||
|
* current flag count) rather than tied to STORY_FLAG_COUNT, since
|
||||||
|
* savefile.h is a leaf header with no dependency on generated story
|
||||||
|
* content, matching SAVE_GLOBAL_ITEM_COUNT_MAX's reasoning.
|
||||||
|
*/
|
||||||
|
#define SAVE_STORY_FLAG_COUNT_MAX 128
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/** Magic header bytes read from the file; must equal SAVE_FILE_HEADER. */
|
/** Magic header bytes read from the file; must equal SAVE_FILE_HEADER. */
|
||||||
char_t header[SAVE_FILE_HEADER_SIZE];
|
char_t header[SAVE_FILE_HEADER_SIZE];
|
||||||
@@ -32,6 +67,20 @@ typedef struct {
|
|||||||
bool_t exists;
|
bool_t exists;
|
||||||
/** The player's saved name. */
|
/** The player's saved name. */
|
||||||
char_t playerName[SAVE_PLAYER_NAME_MAX];
|
char_t playerName[SAVE_PLAYER_NAME_MAX];
|
||||||
|
/** Per-global-ID "already collected" flags - see globalitemstore.h. */
|
||||||
|
bool_t globalItemCollected[SAVE_GLOBAL_ITEM_COUNT_MAX];
|
||||||
|
/**
|
||||||
|
* User-configured gamepad deadzone (0.0f-1.0f) - the save file is the
|
||||||
|
* only place this lives; read it directly via saveGet(SAVE_ACTIVE_SLOT)
|
||||||
|
* ->deadzone rather than caching it anywhere else.
|
||||||
|
*/
|
||||||
|
float_t deadzone;
|
||||||
|
/**
|
||||||
|
* Story flag values, indexed by storyflag_t - the save file is the only
|
||||||
|
* place these live; read/write via storyFlagGet()/storyFlagSet() (see
|
||||||
|
* rpg/story/storyflag.h), not directly.
|
||||||
|
*/
|
||||||
|
uint8_t storyFlags[SAVE_STORY_FLAG_COUNT_MAX];
|
||||||
} savefile_t;
|
} savefile_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -331,6 +331,13 @@ errorret_t saveFileLoad(savestream_t *stream, savefile_t *file) {
|
|||||||
saveFileReadHeader(stream, file->header);
|
saveFileReadHeader(stream, file->header);
|
||||||
saveFileReadVersion(stream, &file->version);
|
saveFileReadVersion(stream, &file->version);
|
||||||
saveFileReadString(stream, file->playerName, SAVE_PLAYER_NAME_MAX);
|
saveFileReadString(stream, file->playerName, SAVE_PLAYER_NAME_MAX);
|
||||||
|
for(size_t i = 0; i < SAVE_GLOBAL_ITEM_COUNT_MAX; i++) {
|
||||||
|
saveFileReadBool(stream, &file->globalItemCollected[i]);
|
||||||
|
}
|
||||||
|
saveFileReadFloat(stream, &file->deadzone);
|
||||||
|
for(size_t i = 0; i < SAVE_STORY_FLAG_COUNT_MAX; i++) {
|
||||||
|
saveFileReadUInt8(stream, &file->storyFlags[i]);
|
||||||
|
}
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,5 +345,12 @@ errorret_t saveFileWrite(savestream_t *stream, savefile_t *file) {
|
|||||||
saveFileWriteHeader(stream, file->header);
|
saveFileWriteHeader(stream, file->header);
|
||||||
saveFileWriteVersion(stream, &file->version);
|
saveFileWriteVersion(stream, &file->version);
|
||||||
saveFileWriteString(stream, file->playerName, SAVE_PLAYER_NAME_MAX);
|
saveFileWriteString(stream, file->playerName, SAVE_PLAYER_NAME_MAX);
|
||||||
|
for(size_t i = 0; i < SAVE_GLOBAL_ITEM_COUNT_MAX; i++) {
|
||||||
|
saveFileWriteBool(stream, &file->globalItemCollected[i]);
|
||||||
|
}
|
||||||
|
saveFileWriteFloat(stream, &file->deadzone);
|
||||||
|
for(size_t i = 0; i < SAVE_STORY_FLAG_COUNT_MAX; i++) {
|
||||||
|
saveFileWriteUInt8(stream, &file->storyFlags[i]);
|
||||||
|
}
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,10 +26,6 @@
|
|||||||
#define UI_GAME_MENU_INDEX_SETTINGS 2
|
#define UI_GAME_MENU_INDEX_SETTINGS 2
|
||||||
#define UI_GAME_MENU_INDEX_SAVE 3
|
#define UI_GAME_MENU_INDEX_SAVE 3
|
||||||
|
|
||||||
// Only one save slot is exposed through this menu for now - there is no
|
|
||||||
// slot-select UI yet, and SAVE_FILE_COUNT_MAX > 1 exists for later.
|
|
||||||
#define UI_GAME_MENU_SAVE_SLOT 0
|
|
||||||
|
|
||||||
static void uiGameMenuSaveWriteComplete(errorret_t result, void *user) {
|
static void uiGameMenuSaveWriteComplete(errorret_t result, void *user) {
|
||||||
if(errorIsNotOk(result)) {
|
if(errorIsNotOk(result)) {
|
||||||
// Generously sized - stringFormat asserts (crashes) rather than
|
// Generously sized - stringFormat asserts (crashes) rather than
|
||||||
@@ -53,7 +49,7 @@ static void uiGameMenuSaveCreateConfirmed(const bool_t confirmed, void *user) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
saveWrite(UI_GAME_MENU_SAVE_SLOT, uiGameMenuSaveWriteComplete, NULL);
|
saveWrite(SAVE_ACTIVE_SLOT, uiGameMenuSaveWriteComplete, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determines whether there's actually save data to overwrite (not just
|
// Determines whether there's actually save data to overwrite (not just
|
||||||
@@ -72,8 +68,8 @@ static void uiGameMenuSaveCheckComplete(errorret_t result, void *user) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(saveExists(UI_GAME_MENU_SAVE_SLOT)) {
|
if(saveExists(SAVE_ACTIVE_SLOT)) {
|
||||||
saveWrite(UI_GAME_MENU_SAVE_SLOT, uiGameMenuSaveWriteComplete, NULL);
|
saveWrite(SAVE_ACTIVE_SLOT, uiGameMenuSaveWriteComplete, NULL);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -91,7 +87,7 @@ static void uiGameMenuSave(void) {
|
|||||||
}
|
}
|
||||||
if(saveIsBusy()) return;// A save/load dialog (e.g. on PSP) is already up.
|
if(saveIsBusy()) return;// A save/load dialog (e.g. on PSP) is already up.
|
||||||
|
|
||||||
saveLoad(UI_GAME_MENU_SAVE_SLOT, uiGameMenuSaveCheckComplete, NULL);
|
saveLoad(SAVE_ACTIVE_SLOT, uiGameMenuSaveCheckComplete, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
uigamemenu_t UI_GAME_MENU;
|
uigamemenu_t UI_GAME_MENU;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "locale/localemanager.h"
|
#include "locale/localemanager.h"
|
||||||
#include "asset/loader/locale/assetlocaleloader.h"
|
#include "asset/loader/locale/assetlocaleloader.h"
|
||||||
#include "input/input.h"
|
#include "save/save.h"
|
||||||
|
|
||||||
void uiSettingsInputSelected(
|
void uiSettingsInputSelected(
|
||||||
const uimenu_t *menu,
|
const uimenu_t *menu,
|
||||||
@@ -39,7 +39,7 @@ errorret_t uiSettingsInputInit(uisettingsdata_t *data) {
|
|||||||
UI_SETTINGS_INPUT_LABEL_MAX
|
UI_SETTINGS_INPUT_LABEL_MAX
|
||||||
));
|
));
|
||||||
MENU_SLIDER_FLOAT(
|
MENU_SLIDER_FLOAT(
|
||||||
input->deadzoneLabel, INPUT_DEADZONE_DEFAULT, 0.0f, 1.0f, 0.05f
|
input->deadzoneLabel, SAVE_DEADZONE_DEFAULT, 0.0f, 1.0f, 0.05f
|
||||||
);
|
);
|
||||||
#else
|
#else
|
||||||
MENU_LABEL("No input settings yet");
|
MENU_LABEL("No input settings yet");
|
||||||
@@ -55,14 +55,14 @@ void uiSettingsInputLoad(void) {
|
|||||||
#ifdef DUSK_INPUT_GAMEPAD
|
#ifdef DUSK_INPUT_GAMEPAD
|
||||||
uiSliderSetFloat(
|
uiSliderSetFloat(
|
||||||
&UI_SETTINGS.data.input.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider,
|
&UI_SETTINGS.data.input.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider,
|
||||||
INPUT.deadzone
|
saveGet(SAVE_ACTIVE_SLOT)->deadzone
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void uiSettingsInputApply(void) {
|
void uiSettingsInputApply(void) {
|
||||||
#ifdef DUSK_INPUT_GAMEPAD
|
#ifdef DUSK_INPUT_GAMEPAD
|
||||||
INPUT.deadzone = uiSliderGetFloat(
|
saveGet(SAVE_ACTIVE_SLOT)->deadzone = uiSliderGetFloat(
|
||||||
&UI_SETTINGS.data.input.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider
|
&UI_SETTINGS.data.input.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
@@ -73,7 +73,7 @@ bool_t uiSettingsInputHasChanges(void) {
|
|||||||
#ifdef DUSK_INPUT_GAMEPAD
|
#ifdef DUSK_INPUT_GAMEPAD
|
||||||
if(uiSliderGetFloat(
|
if(uiSliderGetFloat(
|
||||||
&UI_SETTINGS.data.input.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider
|
&UI_SETTINGS.data.input.items[UI_SETTINGS_INPUT_INDEX_DEADZONE].slider
|
||||||
) != INPUT.deadzone) return true;
|
) != saveGet(SAVE_ACTIVE_SLOT)->deadzone) return true;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "log/log.h"
|
#include "log/log.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
#include "save/save.h"
|
||||||
|
|
||||||
inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
||||||
#ifdef DUSK_INPUT_GAMEPAD
|
#ifdef DUSK_INPUT_GAMEPAD
|
||||||
@@ -187,5 +188,5 @@ float_t inputButtonGetValueDolphin(const inputbutton_t button) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float_t inputGetDeadzoneDolphin(const inputbutton_t button) {
|
float_t inputGetDeadzoneDolphin(const inputbutton_t button) {
|
||||||
return 0.2f;
|
return saveGet(SAVE_ACTIVE_SLOT)->deadzone;
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
|
#include "save/save.h"
|
||||||
|
|
||||||
inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
||||||
#ifdef DUSK_INPUT_GAMEPAD
|
#ifdef DUSK_INPUT_GAMEPAD
|
||||||
@@ -547,5 +548,5 @@ errorret_t inputInitLinux(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
||||||
return 0.17f;
|
return saveGet(SAVE_ACTIVE_SLOT)->deadzone;
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
|
#include "save/save.h"
|
||||||
|
|
||||||
// #define INPUT_PSP_GAMEPAD_BUTTON_ACCEPT INPUT_SDL2_GAMEPAD_BUTTON_CUSTOM
|
// #define INPUT_PSP_GAMEPAD_BUTTON_ACCEPT INPUT_SDL2_GAMEPAD_BUTTON_CUSTOM
|
||||||
// #define INPUT_PSP_GAMEPAD_BUTTON_CANCEL INPUT_SDL2_GAMEPAD_BUTTON_CUSTOM
|
// #define INPUT_PSP_GAMEPAD_BUTTON_CANCEL INPUT_SDL2_GAMEPAD_BUTTON_CUSTOM
|
||||||
@@ -94,5 +95,5 @@ errorret_t inputInitPSP(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
||||||
return 0.2f;
|
return saveGet(SAVE_ACTIVE_SLOT)->deadzone;
|
||||||
}
|
}
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "input/input.h"
|
#include "input/input.h"
|
||||||
|
#include "save/save.h"
|
||||||
|
|
||||||
inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
||||||
{ .name = "triangle", {
|
{ .name = "triangle", {
|
||||||
@@ -83,5 +84,5 @@ inputbuttondata_t INPUT_BUTTON_DATA[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
float_t inputGetDeadzoneSDL2(const inputbutton_t button) {
|
||||||
return 0.17f;
|
return saveGet(SAVE_ACTIVE_SLOT)->deadzone;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-1
@@ -38,7 +38,11 @@ out += [
|
|||||||
" STORY_FLAG_COUNT",
|
" STORY_FLAG_COUNT",
|
||||||
"} storyflag_t;",
|
"} storyflag_t;",
|
||||||
"",
|
"",
|
||||||
"static storyflagvalue_t STORY_FLAG_VALUES[STORY_FLAG_COUNT] = {",
|
"// Stamped onto a save file's storyFlags the first time it's used (see",
|
||||||
|
"// storyFlagInitDefaults()) - not a live value array. Live flag state",
|
||||||
|
"// lives entirely in the save file (savefile_t.storyFlags), read/written",
|
||||||
|
"// via storyFlagGet()/storyFlagSet() - see storyflag.h.",
|
||||||
|
"static const storyflagvalue_t STORY_FLAG_DEFAULTS[STORY_FLAG_COUNT] = {",
|
||||||
]
|
]
|
||||||
for flag in flags:
|
for flag in flags:
|
||||||
out.append(f" [{flag_enum(flag['id'])}] = {flag['initial']},")
|
out.append(f" [{flag_enum(flag['id'])}] = {flag['initial']},")
|
||||||
|
|||||||
Reference in New Issue
Block a user