First pass of actual saving
This commit is contained in:
@@ -21,7 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "system/system.h"
|
#include "system/system.h"
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "save/savemanager.h"\
|
#include "save/save.h"\
|
||||||
|
|
||||||
engine_t ENGINE;
|
engine_t ENGINE;
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ errorret_t engineInit(const int32_t argc, const char_t **argv) {
|
|||||||
errorChain(systemInit());
|
errorChain(systemInit());
|
||||||
errorChain(inputInit());
|
errorChain(inputInit());
|
||||||
errorChain(assetInit());
|
errorChain(assetInit());
|
||||||
errorChain(saveManagerInit());
|
errorChain(saveInit());
|
||||||
errorChain(localeManagerInit());
|
errorChain(localeManagerInit());
|
||||||
errorChain(displayInit());
|
errorChain(displayInit());
|
||||||
errorChain(uiInit());
|
errorChain(uiInit());
|
||||||
@@ -67,7 +67,7 @@ errorret_t engineUpdate(void) {
|
|||||||
#ifdef DUSK_NETWORK
|
#ifdef DUSK_NETWORK
|
||||||
errorChain(networkUpdate());
|
errorChain(networkUpdate());
|
||||||
#endif
|
#endif
|
||||||
errorChain(saveManagerUpdate());
|
errorChain(saveUpdate());
|
||||||
timeUpdate();
|
timeUpdate();
|
||||||
inputUpdate();
|
inputUpdate();
|
||||||
consoleUpdate();
|
consoleUpdate();
|
||||||
@@ -96,7 +96,7 @@ errorret_t engineDispose(void) {
|
|||||||
errorChain(uiDispose());
|
errorChain(uiDispose());
|
||||||
consoleDispose();
|
consoleDispose();
|
||||||
errorChain(displayDispose());
|
errorChain(displayDispose());
|
||||||
errorChain(saveManagerDispose());
|
errorChain(saveDispose());
|
||||||
errorChain(assetDispose());
|
errorChain(assetDispose());
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -6,9 +6,8 @@
|
|||||||
# Sources
|
# Sources
|
||||||
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
target_sources(${DUSK_LIBRARY_TARGET_NAME}
|
||||||
PUBLIC
|
PUBLIC
|
||||||
savemanager.c
|
save.c
|
||||||
savedevice.c
|
savedevice.c
|
||||||
saveslot.c
|
saveslot.c
|
||||||
savesettings.c
|
savesettings.c
|
||||||
savestatus.c
|
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,233 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2026 Dominic Masters
|
||||||
|
*
|
||||||
|
* This software is released under the MIT License.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "save.h"
|
||||||
|
#include "util/memory.h"
|
||||||
|
#include "assert/assert.h"
|
||||||
|
|
||||||
|
save_t SAVE;
|
||||||
|
|
||||||
|
errorret_t saveInit() {
|
||||||
|
memoryZero(&SAVE, sizeof(save_t));
|
||||||
|
|
||||||
|
SAVE.deviceCurrent = 0xFF;// No current device.
|
||||||
|
SAVE.slotCurrent = 0xFF;// No current slot.
|
||||||
|
|
||||||
|
// Initialize the slots and settings
|
||||||
|
saveSettingsInit(&SAVE.settings);
|
||||||
|
saveSlotInit(&SAVE.slot);
|
||||||
|
|
||||||
|
// Update caches to match default data.
|
||||||
|
for(uint8_t i = 0; i < SAVE_SLOT_COUNT; i++) {
|
||||||
|
SAVE.caches[i] = SAVE.slot.cachedData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start by initializing each of the save devices.
|
||||||
|
savedevice_t *device = &SAVE.devices[0];
|
||||||
|
do {
|
||||||
|
errorChain(saveDeviceInit(device));
|
||||||
|
} while(device++ < &SAVE.devices[SAVE_DEVICE_COUNT - 1]);
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t saveUpdate() {
|
||||||
|
assertIsMainThread("Invalid thread");
|
||||||
|
|
||||||
|
// Start by updating each device
|
||||||
|
savedevice_t *device = &SAVE.devices[0];
|
||||||
|
do {
|
||||||
|
saveDeviceUpdate(device);
|
||||||
|
} while(device++ < &SAVE.devices[SAVE_DEVICE_COUNT - 1]);
|
||||||
|
|
||||||
|
// We may be waiting for a device to become available
|
||||||
|
if(SAVE.findingAvailableDevice) {
|
||||||
|
assertNotNull(
|
||||||
|
SAVE.findAvailableCallback,
|
||||||
|
"Callback cannot be null while looking for devices"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Yes, we have a device available, fire the callback.
|
||||||
|
if(SAVE.deviceCurrent == 0xFF) {
|
||||||
|
// Are we still looking or did we fail to find anything?
|
||||||
|
if(SAVE.noAvailableDeviceFound) {
|
||||||
|
SAVE.findingAvailableDevice = false;
|
||||||
|
SAVE.findAvailableCallback(
|
||||||
|
NULL,
|
||||||
|
SAVE.findAvailableUser
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// Still searching
|
||||||
|
} else {
|
||||||
|
// Device was found, cache in the data.
|
||||||
|
errorChain(saveLoadSettings());
|
||||||
|
// Reset each slot and try load from file, updating cache along the way.
|
||||||
|
for(uint8_t i = 0; i < SAVE_SLOT_COUNT; i++) {
|
||||||
|
SAVE.slotCurrent = i;
|
||||||
|
saveSlotInit(&SAVE.slot);
|
||||||
|
errorChain(saveLoadSlot());// Load slot updates the cache.
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reset slot, implying no slot has been selected.
|
||||||
|
SAVE.slotCurrent = 0xFF;
|
||||||
|
|
||||||
|
SAVE.findingAvailableDevice = false;
|
||||||
|
SAVE.findAvailableCallback(
|
||||||
|
&SAVE.devices[SAVE.deviceCurrent],
|
||||||
|
SAVE.findAvailableUser
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveFindAvailableDevice(
|
||||||
|
savedevicestatecallback_t callback,
|
||||||
|
void *user
|
||||||
|
) {
|
||||||
|
assertIsMainThread("Invalid thread");
|
||||||
|
assertNotNull(callback, "Callback cannot be null");
|
||||||
|
assertFalse(
|
||||||
|
SAVE.findingAvailableDevice,
|
||||||
|
"Already finding an available device"
|
||||||
|
);
|
||||||
|
|
||||||
|
SAVE.findingAvailableDevice = true;
|
||||||
|
SAVE.findAvailableCallback = callback;
|
||||||
|
SAVE.findAvailableUser = user;
|
||||||
|
SAVE.noAvailableDeviceFound = false;
|
||||||
|
|
||||||
|
// Is there an available device marked already?
|
||||||
|
if(SAVE.deviceCurrent != 0xFF) {
|
||||||
|
// Yes, fire the callback next tick.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do we have an available device not yet marked as current?
|
||||||
|
savedevice_t *device = &SAVE.devices[0];
|
||||||
|
do {
|
||||||
|
if(device->state != SAVE_DEVICE_STATE_AVAILABLE) continue;
|
||||||
|
// Yes this device is available, set as current device.
|
||||||
|
SAVE.deviceCurrent = (uint8_t)(device - &SAVE.devices[0]);
|
||||||
|
return;// Next tick will fire the callback.
|
||||||
|
} while(device++ < &SAVE.devices[SAVE_DEVICE_COUNT - 1]);
|
||||||
|
|
||||||
|
// No currently available device, check them IN ORDER, starting at 0
|
||||||
|
savedevice_t *deviceToCheck = &SAVE.devices[0];
|
||||||
|
assertNotNull(deviceToCheck, "Device to check cannot be null");
|
||||||
|
saveDeviceCheckAvailability(
|
||||||
|
deviceToCheck,
|
||||||
|
saveOnDeviceAvailabilityChecked,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void saveOnDeviceAvailabilityChecked(savedevice_t *device, void *user) {
|
||||||
|
assertNotNull(device, "Device cannot be null");
|
||||||
|
assertTrue(
|
||||||
|
SAVE.findingAvailableDevice,
|
||||||
|
"Not currently finding an available device"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Did we already find a device?
|
||||||
|
if(SAVE.deviceCurrent != 0xFF) return;
|
||||||
|
|
||||||
|
// Is this device available?
|
||||||
|
if(device->state != SAVE_DEVICE_STATE_AVAILABLE) {
|
||||||
|
// Since it's unavailable we should tell the next device to check its
|
||||||
|
// availability. If there is no next device we give up.
|
||||||
|
savedevice_t *nextDevice = device + 1;
|
||||||
|
if(nextDevice >= &SAVE.devices[SAVE_DEVICE_COUNT]) {
|
||||||
|
// No more devices to check, we give up.
|
||||||
|
SAVE.noAvailableDeviceFound = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check the next device's availability.
|
||||||
|
saveDeviceCheckAvailability(
|
||||||
|
nextDevice,
|
||||||
|
saveOnDeviceAvailabilityChecked,
|
||||||
|
NULL
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Yes this device is available, set as current device and next tick will
|
||||||
|
// invoke callback
|
||||||
|
SAVE.deviceCurrent = (uint8_t)(device - &SAVE.devices[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t saveSaveSettings() {
|
||||||
|
assertTrue(SAVE.deviceCurrent != 0xFF, "No current device");
|
||||||
|
|
||||||
|
if(!SAVE.settingsDirty) errorOk();
|
||||||
|
|
||||||
|
errorChain(saveDeviceSettingsWrite(
|
||||||
|
&SAVE.devices[SAVE.deviceCurrent],
|
||||||
|
&SAVE.settings
|
||||||
|
));
|
||||||
|
|
||||||
|
SAVE.settingsDirty = false;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t saveLoadSettings() {
|
||||||
|
assertTrue(SAVE.deviceCurrent != 0xFF, "No current device");
|
||||||
|
|
||||||
|
errorChain(saveDeviceSettingsRead(
|
||||||
|
&SAVE.devices[SAVE.deviceCurrent],
|
||||||
|
&SAVE.settings
|
||||||
|
));
|
||||||
|
|
||||||
|
SAVE.settingsDirty = false;
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t saveSaveSlot() {
|
||||||
|
assertTrue(SAVE.deviceCurrent != 0xFF, "No current device");
|
||||||
|
assertTrue(SAVE.slotCurrent < SAVE_SLOT_COUNT, "Invalid slot index");
|
||||||
|
|
||||||
|
errorChain(saveDeviceSlotWrite(
|
||||||
|
&SAVE.devices[SAVE.deviceCurrent],
|
||||||
|
&SAVE.slot,
|
||||||
|
SAVE.slotCurrent
|
||||||
|
));
|
||||||
|
|
||||||
|
// Update cache
|
||||||
|
SAVE.caches[SAVE.slotCurrent] = SAVE.slot.cachedData;
|
||||||
|
SAVE.slotDirty = false;
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t saveLoadSlot() {
|
||||||
|
assertTrue(SAVE.deviceCurrent != 0xFF, "No current device");
|
||||||
|
assertTrue(SAVE.slotCurrent < SAVE_SLOT_COUNT, "Invalid slot index");
|
||||||
|
|
||||||
|
errorChain(saveDeviceSlotRead(
|
||||||
|
&SAVE.devices[SAVE.deviceCurrent],
|
||||||
|
&SAVE.slot,
|
||||||
|
SAVE.slotCurrent
|
||||||
|
));
|
||||||
|
|
||||||
|
// Update cache
|
||||||
|
SAVE.caches[SAVE.slotCurrent] = SAVE.slot.cachedData;
|
||||||
|
SAVE.slotDirty = false;
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
|
|
||||||
|
errorret_t saveDispose() {
|
||||||
|
// Dispose each device.
|
||||||
|
savedevice_t *device = &SAVE.devices[0];
|
||||||
|
do {
|
||||||
|
saveDeviceDispose(device);
|
||||||
|
} while(device++ < &SAVE.devices[SAVE_DEVICE_COUNT - 1]);
|
||||||
|
|
||||||
|
errorOk();
|
||||||
|
}
|
||||||
@@ -9,21 +9,17 @@
|
|||||||
#include "savedevice.h"
|
#include "savedevice.h"
|
||||||
#include "saveslot.h"
|
#include "saveslot.h"
|
||||||
#include "savesettings.h"
|
#include "savesettings.h"
|
||||||
#include "savestatus.h"
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// File state
|
// File state
|
||||||
savesettings_t settings;
|
savesettings_t settings;
|
||||||
|
saveslotcache_t caches[SAVE_SLOT_COUNT];
|
||||||
saveslot_t slot;
|
saveslot_t slot;
|
||||||
|
|
||||||
uint8_t slotCurrent;
|
uint8_t slotCurrent;
|
||||||
bool_t settingsDirty;
|
bool_t settingsDirty;
|
||||||
bool_t slotDirty;
|
bool_t slotDirty;
|
||||||
|
|
||||||
// Basic info about each save file on the current device, refreshed
|
|
||||||
// whenever the current device changes.
|
|
||||||
savestatus_t slotStatuses[SAVE_SLOT_COUNT];
|
|
||||||
|
|
||||||
// Device state
|
// Device state
|
||||||
savedevice_t devices[SAVE_DEVICE_COUNT];
|
savedevice_t devices[SAVE_DEVICE_COUNT];
|
||||||
uint8_t deviceCurrent;
|
uint8_t deviceCurrent;
|
||||||
@@ -31,34 +27,34 @@ typedef struct {
|
|||||||
bool_t noAvailableDeviceFound;
|
bool_t noAvailableDeviceFound;
|
||||||
savedevicestatecallback_t findAvailableCallback;
|
savedevicestatecallback_t findAvailableCallback;
|
||||||
void *findAvailableUser;
|
void *findAvailableUser;
|
||||||
} savemanager_t;
|
} save_t;
|
||||||
|
|
||||||
extern savemanager_t SAVE_MANAGER;
|
extern save_t SAVE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initializes the save manager, this does not do anything related to mounting
|
* Initializes the save system, this does not do anything related to mounting
|
||||||
* files, memory cards, etc, this is entirely prepping for that capability.
|
* files, memory cards, etc, this is entirely prepping for that capability.
|
||||||
*
|
*
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
*/
|
*/
|
||||||
errorret_t saveManagerInit();
|
errorret_t saveInit();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the save manager.
|
* Updates the save system.
|
||||||
*
|
*
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
*/
|
*/
|
||||||
errorret_t saveManagerUpdate();
|
errorret_t saveUpdate();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Requests the save manager to try and find an available device. This will fire
|
* Requests the save system to try and find an available device. This will fire
|
||||||
* the callback whenever an avaialble device is found, or will fire with a NULL
|
* the callback whenever an avaialble device is found, or will fire with a NULL
|
||||||
* save device if no available save devices are found.
|
* save device if no available save devices are found.
|
||||||
*
|
*
|
||||||
* @param callback The callback to fire when an available device is found.
|
* @param callback The callback to fire when an available device is found.
|
||||||
* @param user The user data to pass to the callback.
|
* @param user The user data to pass to the callback.
|
||||||
*/
|
*/
|
||||||
void saveManagerFindAvailableDevice(
|
void saveFindAvailableDevice(
|
||||||
savedevicestatecallback_t callback,
|
savedevicestatecallback_t callback,
|
||||||
void *user
|
void *user
|
||||||
);
|
);
|
||||||
@@ -69,73 +65,39 @@ void saveManagerFindAvailableDevice(
|
|||||||
* @param device The save device to fire the callback for.
|
* @param device The save device to fire the callback for.
|
||||||
* @param user Unused, present to match savedevicestatecallback_t.
|
* @param user Unused, present to match savedevicestatecallback_t.
|
||||||
*/
|
*/
|
||||||
void saveManagerOnDeviceAvailabilityChecked(savedevice_t *device, void *user);
|
void saveOnDeviceAvailabilityChecked(savedevice_t *device, void *user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the current settings to the current device.
|
* Saves the current settings to the current device.
|
||||||
*
|
*
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
*/
|
*/
|
||||||
errorret_t saveManagerSaveSettings();
|
errorret_t saveSaveSettings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the current settings from the current device.
|
* Loads the current settings from the current device.
|
||||||
*
|
*
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
*/
|
*/
|
||||||
errorret_t saveManagerLoadSettings();
|
errorret_t saveLoadSettings();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Saves the current slot to the current device, at the current slot index.
|
* Saves the current slot to the current device, at the current slot index.
|
||||||
*
|
*
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
*/
|
*/
|
||||||
errorret_t saveManagerSaveSlot();
|
errorret_t saveSaveSlot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the current slot from the current device, at the current slot index.
|
* Loads the current slot from the current device, at the current slot index.
|
||||||
*
|
*
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
*/
|
*/
|
||||||
errorret_t saveManagerLoadSlot();
|
errorret_t saveLoadSlot();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Walks every slot index on the current device and reads the basic, at-a-
|
* Disposes of the save system.
|
||||||
* glance information for each into SAVE_MANAGER.slotStatuses. This does not
|
|
||||||
* affect the currently loaded slot or the current slot index.
|
|
||||||
*
|
*
|
||||||
* @return Error state if any.
|
* @return Error state if any.
|
||||||
*/
|
*/
|
||||||
errorret_t saveManagerRefreshSlotStatuses();
|
errorret_t saveDispose();
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets the current slot index, and attempts to load that slot's data from
|
|
||||||
* the current device.
|
|
||||||
*
|
|
||||||
* @param slotIndex The slot index to make current.
|
|
||||||
* @return Error state if any.
|
|
||||||
*/
|
|
||||||
errorret_t saveManagerSetSlot(uint8_t slotIndex);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Saves both the current settings and the current slot to the current
|
|
||||||
* device.
|
|
||||||
*
|
|
||||||
* @return Error state if any.
|
|
||||||
*/
|
|
||||||
errorret_t saveManagerSave();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads both the current settings and the current slot from the current
|
|
||||||
* device.
|
|
||||||
*
|
|
||||||
* @return Error state if any.
|
|
||||||
*/
|
|
||||||
errorret_t saveManagerLoad();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Disposes of the save manager.
|
|
||||||
*
|
|
||||||
* @return Error state if any.
|
|
||||||
*/
|
|
||||||
errorret_t saveManagerDispose();
|
|
||||||
@@ -82,7 +82,7 @@ void saveDeviceCheckAvailability(
|
|||||||
errorret_t saveDeviceSlotWrite(
|
errorret_t saveDeviceSlotWrite(
|
||||||
savedevice_t *device,
|
savedevice_t *device,
|
||||||
saveslot_t *slot,
|
saveslot_t *slot,
|
||||||
uint8_t slotIndex
|
const uint8_t slotIndex
|
||||||
) {
|
) {
|
||||||
assertNotNull(device, "device cannot be null");
|
assertNotNull(device, "device cannot be null");
|
||||||
assertNotNull(slot, "slot cannot be null");
|
assertNotNull(slot, "slot cannot be null");
|
||||||
@@ -97,7 +97,7 @@ errorret_t saveDeviceSlotWrite(
|
|||||||
errorret_t saveDeviceSlotRead(
|
errorret_t saveDeviceSlotRead(
|
||||||
savedevice_t *device,
|
savedevice_t *device,
|
||||||
saveslot_t *slot,
|
saveslot_t *slot,
|
||||||
uint8_t slotIndex
|
const uint8_t slotIndex
|
||||||
) {
|
) {
|
||||||
assertNotNull(device, "device cannot be null");
|
assertNotNull(device, "device cannot be null");
|
||||||
assertNotNull(slot, "slot cannot be null");
|
assertNotNull(slot, "slot cannot be null");
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void saveDeviceCheckAvailability(
|
|||||||
errorret_t saveDeviceSlotWrite(
|
errorret_t saveDeviceSlotWrite(
|
||||||
savedevice_t *device,
|
savedevice_t *device,
|
||||||
saveslot_t *slot,
|
saveslot_t *slot,
|
||||||
uint8_t slotIndex
|
const uint8_t slotIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -99,7 +99,7 @@ errorret_t saveDeviceSlotWrite(
|
|||||||
errorret_t saveDeviceSlotRead(
|
errorret_t saveDeviceSlotRead(
|
||||||
savedevice_t *device,
|
savedevice_t *device,
|
||||||
saveslot_t *slot,
|
saveslot_t *slot,
|
||||||
uint8_t slotIndex
|
const uint8_t slotIndex
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,265 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "savemanager.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
|
|
||||||
savemanager_t SAVE_MANAGER;
|
|
||||||
|
|
||||||
errorret_t saveManagerInit() {
|
|
||||||
memoryZero(&SAVE_MANAGER, sizeof(savemanager_t));
|
|
||||||
|
|
||||||
SAVE_MANAGER.deviceCurrent = 0xFF;// No current device.
|
|
||||||
SAVE_MANAGER.slotCurrent = 0xFF;// No current slot.
|
|
||||||
|
|
||||||
// Initialize the default slot
|
|
||||||
saveSlotInit(&SAVE_MANAGER.slot);
|
|
||||||
|
|
||||||
// Initialize the default settings.
|
|
||||||
saveSettingsInit(&SAVE_MANAGER.settings);
|
|
||||||
|
|
||||||
// Initialize the default (not in use) status for each save file.
|
|
||||||
savestatus_t *status = &SAVE_MANAGER.slotStatuses[0];
|
|
||||||
do {
|
|
||||||
saveStatusInit(status);
|
|
||||||
} while(status++ < &SAVE_MANAGER.slotStatuses[SAVE_SLOT_COUNT - 1]);
|
|
||||||
|
|
||||||
// Start by initializing each of the save devices.
|
|
||||||
savedevice_t *device = &SAVE_MANAGER.devices[0];
|
|
||||||
do {
|
|
||||||
saveDeviceInit(device);
|
|
||||||
} while(device++ < &SAVE_MANAGER.devices[SAVE_DEVICE_COUNT - 1]);
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerUpdate() {
|
|
||||||
assertIsMainThread("Invalid thread");
|
|
||||||
|
|
||||||
// Start by updating each device
|
|
||||||
savedevice_t *device = &SAVE_MANAGER.devices[0];
|
|
||||||
do {
|
|
||||||
saveDeviceUpdate(device);
|
|
||||||
} while(device++ < &SAVE_MANAGER.devices[SAVE_DEVICE_COUNT - 1]);
|
|
||||||
|
|
||||||
// We may be waiting for a device to become available
|
|
||||||
if(SAVE_MANAGER.findingAvailableDevice) {
|
|
||||||
assertNotNull(
|
|
||||||
SAVE_MANAGER.findAvailableCallback,
|
|
||||||
"Callback cannot be null while looking for devices"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Yes, we have a device available, fire the callback.
|
|
||||||
if(SAVE_MANAGER.deviceCurrent == 0xFF) {
|
|
||||||
// Are we still looking or did we fail to find anything?
|
|
||||||
if(SAVE_MANAGER.noAvailableDeviceFound) {
|
|
||||||
SAVE_MANAGER.findingAvailableDevice = false;
|
|
||||||
SAVE_MANAGER.findAvailableCallback(
|
|
||||||
NULL,
|
|
||||||
SAVE_MANAGER.findAvailableUser
|
|
||||||
);
|
|
||||||
}
|
|
||||||
// Still searching
|
|
||||||
} else {
|
|
||||||
// Device was found!
|
|
||||||
SAVE_MANAGER.findingAvailableDevice = false;
|
|
||||||
SAVE_MANAGER.findAvailableCallback(
|
|
||||||
&SAVE_MANAGER.devices[SAVE_MANAGER.deviceCurrent],
|
|
||||||
SAVE_MANAGER.findAvailableUser
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveManagerFindAvailableDevice(
|
|
||||||
savedevicestatecallback_t callback,
|
|
||||||
void *user
|
|
||||||
) {
|
|
||||||
assertIsMainThread("Invalid thread");
|
|
||||||
assertNotNull(callback, "Callback cannot be null");
|
|
||||||
assertFalse(
|
|
||||||
SAVE_MANAGER.findingAvailableDevice,
|
|
||||||
"Already finding an available device"
|
|
||||||
);
|
|
||||||
|
|
||||||
SAVE_MANAGER.findingAvailableDevice = true;
|
|
||||||
SAVE_MANAGER.findAvailableCallback = callback;
|
|
||||||
SAVE_MANAGER.findAvailableUser = user;
|
|
||||||
SAVE_MANAGER.noAvailableDeviceFound = false;
|
|
||||||
|
|
||||||
// Is there an available device marked already?
|
|
||||||
if(SAVE_MANAGER.deviceCurrent != 0xFF) {
|
|
||||||
// Yes, fire the callback next tick.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do we have an available device not yet marked as current?
|
|
||||||
savedevice_t *device = &SAVE_MANAGER.devices[0];
|
|
||||||
do {
|
|
||||||
if(device->state != SAVE_DEVICE_STATE_AVAILABLE) continue;
|
|
||||||
// Yes this device is available, set as current device.
|
|
||||||
SAVE_MANAGER.deviceCurrent = (uint8_t)(device - &SAVE_MANAGER.devices[0]);
|
|
||||||
return;// Next tick will fire the callback.
|
|
||||||
} while(device++ < &SAVE_MANAGER.devices[SAVE_DEVICE_COUNT - 1]);
|
|
||||||
|
|
||||||
// No currently available device, check them IN ORDER, starting at 0
|
|
||||||
savedevice_t *deviceToCheck = &SAVE_MANAGER.devices[0];
|
|
||||||
assertNotNull(deviceToCheck, "Device to check cannot be null");
|
|
||||||
saveDeviceCheckAvailability(
|
|
||||||
deviceToCheck,
|
|
||||||
saveManagerOnDeviceAvailabilityChecked,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveManagerOnDeviceAvailabilityChecked(savedevice_t *device, void *user) {
|
|
||||||
assertNotNull(device, "Device cannot be null");
|
|
||||||
assertTrue(
|
|
||||||
SAVE_MANAGER.findingAvailableDevice,
|
|
||||||
"Not currently finding an available device"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Did we already find a device?
|
|
||||||
if(SAVE_MANAGER.deviceCurrent != 0xFF) return;
|
|
||||||
|
|
||||||
// Is this device available?
|
|
||||||
if(device->state != SAVE_DEVICE_STATE_AVAILABLE) {
|
|
||||||
// Since it's unavailable we should tell the next device to check its
|
|
||||||
// availability. If there is no next device we give up.
|
|
||||||
savedevice_t *nextDevice = device + 1;
|
|
||||||
if(nextDevice >= &SAVE_MANAGER.devices[SAVE_DEVICE_COUNT]) {
|
|
||||||
// No more devices to check, we give up.
|
|
||||||
SAVE_MANAGER.noAvailableDeviceFound = true;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the next device's availability.
|
|
||||||
saveDeviceCheckAvailability(
|
|
||||||
nextDevice,
|
|
||||||
saveManagerOnDeviceAvailabilityChecked,
|
|
||||||
NULL
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Yes this device is available, set as current device and next tick will
|
|
||||||
// invoke callback
|
|
||||||
SAVE_MANAGER.deviceCurrent = (uint8_t)(device - &SAVE_MANAGER.devices[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerSaveSettings() {
|
|
||||||
assertTrue(SAVE_MANAGER.deviceCurrent != 0xFF, "No current device");
|
|
||||||
|
|
||||||
if(!SAVE_MANAGER.settingsDirty) errorOk();
|
|
||||||
|
|
||||||
errorChain(saveDeviceSettingsWrite(
|
|
||||||
&SAVE_MANAGER.devices[SAVE_MANAGER.deviceCurrent],
|
|
||||||
&SAVE_MANAGER.settings
|
|
||||||
));
|
|
||||||
|
|
||||||
SAVE_MANAGER.settingsDirty = false;
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerLoadSettings() {
|
|
||||||
assertTrue(SAVE_MANAGER.deviceCurrent != 0xFF, "No current device");
|
|
||||||
|
|
||||||
errorChain(saveDeviceSettingsRead(
|
|
||||||
&SAVE_MANAGER.devices[SAVE_MANAGER.deviceCurrent],
|
|
||||||
&SAVE_MANAGER.settings
|
|
||||||
));
|
|
||||||
|
|
||||||
SAVE_MANAGER.settingsDirty = false;
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerSaveSlot() {
|
|
||||||
assertTrue(SAVE_MANAGER.deviceCurrent != 0xFF, "No current device");
|
|
||||||
assertTrue(SAVE_MANAGER.slotCurrent != 0xFF, "No current slot");
|
|
||||||
assertTrue(saveSlotInUse(&SAVE_MANAGER.slot), "Save slot is not valid");
|
|
||||||
|
|
||||||
if(!SAVE_MANAGER.slotDirty) errorOk();
|
|
||||||
|
|
||||||
errorChain(saveDeviceSlotWrite(
|
|
||||||
&SAVE_MANAGER.devices[SAVE_MANAGER.deviceCurrent],
|
|
||||||
&SAVE_MANAGER.slot,
|
|
||||||
SAVE_MANAGER.slotCurrent
|
|
||||||
));
|
|
||||||
|
|
||||||
SAVE_MANAGER.slotDirty = false;
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerLoadSlot() {
|
|
||||||
assertTrue(SAVE_MANAGER.deviceCurrent != 0xFF, "No current device");
|
|
||||||
assertTrue(SAVE_MANAGER.slotCurrent != 0xFF, "No current slot");
|
|
||||||
|
|
||||||
errorChain(saveDeviceSlotRead(
|
|
||||||
&SAVE_MANAGER.devices[SAVE_MANAGER.deviceCurrent],
|
|
||||||
&SAVE_MANAGER.slot,
|
|
||||||
SAVE_MANAGER.slotCurrent
|
|
||||||
));
|
|
||||||
|
|
||||||
SAVE_MANAGER.slotDirty = false;
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerRefreshSlotStatuses() {
|
|
||||||
assertTrue(SAVE_MANAGER.deviceCurrent != 0xFF, "No current device");
|
|
||||||
|
|
||||||
saveslot_t slot;
|
|
||||||
for(uint8_t i = 0; i < SAVE_SLOT_COUNT; i++) {
|
|
||||||
saveSlotInit(&slot);
|
|
||||||
|
|
||||||
errorChain(saveDeviceSlotRead(
|
|
||||||
&SAVE_MANAGER.devices[SAVE_MANAGER.deviceCurrent],
|
|
||||||
&slot,
|
|
||||||
i
|
|
||||||
));
|
|
||||||
|
|
||||||
saveStatusFromSlot(&SAVE_MANAGER.slotStatuses[i], &slot);
|
|
||||||
}
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerSetSlot(uint8_t slotIndex) {
|
|
||||||
assertTrue(slotIndex != 0xFF, "Slot index cannot be 0xFF");
|
|
||||||
SAVE_MANAGER.slotCurrent = slotIndex;
|
|
||||||
SAVE_MANAGER.slotDirty = true;
|
|
||||||
|
|
||||||
errorChain(saveManagerLoadSlot());
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerSave() {
|
|
||||||
errorChain(saveManagerSaveSettings());
|
|
||||||
errorChain(saveManagerSaveSlot());
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerLoad() {
|
|
||||||
errorChain(saveManagerLoadSettings());
|
|
||||||
errorChain(saveManagerLoadSlot());
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
|
|
||||||
errorret_t saveManagerDispose() {
|
|
||||||
// Dispose each device.
|
|
||||||
savedevice_t *device = &SAVE_MANAGER.devices[0];
|
|
||||||
do {
|
|
||||||
saveDeviceDispose(device);
|
|
||||||
} while(device++ < &SAVE_MANAGER.devices[SAVE_DEVICE_COUNT - 1]);
|
|
||||||
|
|
||||||
errorOk();
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
#include "util/memory.h"
|
#include "util/memory.h"
|
||||||
#include "savejson.h"
|
#include "savejson.h"
|
||||||
|
#include "time/time.h"
|
||||||
|
|
||||||
void saveSlotInit(saveslot_t *slot) {
|
void saveSlotInit(saveslot_t *slot) {
|
||||||
assertNotNull(slot, "Slot cannot be null");
|
assertNotNull(slot, "Slot cannot be null");
|
||||||
@@ -17,11 +18,16 @@ void saveSlotInit(saveslot_t *slot) {
|
|||||||
slot->version = 1;
|
slot->version = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool_t saveSlotInUse(saveslot_t *slot) {
|
bool_t saveSlotInUse(saveslotcache_t *slot) {
|
||||||
assertNotNull(slot, "Slot cannot be null");
|
assertNotNull(slot, "Slot cannot be null");
|
||||||
return slot->name[0] != '\0';
|
return slot->name[0] != '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool_t saveSlotHasSaved(saveslotcache_t *slot) {
|
||||||
|
assertNotNull(slot, "Slot cannot be null");
|
||||||
|
return slot->time.time != 0;
|
||||||
|
}
|
||||||
|
|
||||||
errorret_t saveSlotWriteJSON(
|
errorret_t saveSlotWriteJSON(
|
||||||
saveslot_t *slot,
|
saveslot_t *slot,
|
||||||
yyjson_mut_doc *doc,
|
yyjson_mut_doc *doc,
|
||||||
@@ -31,8 +37,12 @@ errorret_t saveSlotWriteJSON(
|
|||||||
assertNotNull(doc, "Doc cannot be null");
|
assertNotNull(doc, "Doc cannot be null");
|
||||||
assertNotNull(object, "Object cannot be null");
|
assertNotNull(object, "Object cannot be null");
|
||||||
|
|
||||||
writeString("name", slot->name);
|
// Update time
|
||||||
writeTime("time", slot->time);
|
slot->cachedData.time = timeGetEpoch();
|
||||||
|
|
||||||
|
writeString("name", slot->cachedData.name);
|
||||||
|
writeTime("time", slot->cachedData.time);
|
||||||
|
writeInt32("playerLevel", slot->cachedData.playerLevel);
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -43,8 +53,9 @@ errorret_t saveSlotReadJSON(saveslot_t *slot, yyjson_val *object) {
|
|||||||
|
|
||||||
char_t saveJsonStringBuffer[SAVE_JSON_STRING_BUFFER_SIZE];
|
char_t saveJsonStringBuffer[SAVE_JSON_STRING_BUFFER_SIZE];
|
||||||
|
|
||||||
readString("name", slot->name, "", SAVE_SLOT_NAME_LENGTH);
|
readString("name", slot->cachedData.name, "", SAVE_SLOT_NAME_LENGTH);
|
||||||
readTime("time", slot->time);
|
readTime("time", slot->cachedData.time);
|
||||||
|
readInt32("playerLevel", slot->cachedData.playerLevel, 1);
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
}
|
}
|
||||||
@@ -11,15 +11,20 @@
|
|||||||
#include "yyjson.h"
|
#include "yyjson.h"
|
||||||
|
|
||||||
#define SAVE_SLOT_NAME_LENGTH 8
|
#define SAVE_SLOT_NAME_LENGTH 8
|
||||||
#define SAVE_SLOT_COUNT 4
|
#define SAVE_SLOT_COUNT 3
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
typedef struct {
|
||||||
|
char_t name[SAVE_SLOT_NAME_LENGTH + 1];// 8 characters + null terminator
|
||||||
|
dusktimeepoch_t time;
|
||||||
|
int32_t playerLevel;
|
||||||
|
} saveslotcache_t;
|
||||||
|
|
||||||
typedef struct saveslot_s {
|
typedef struct saveslot_s {
|
||||||
uint8_t version;
|
uint8_t version;
|
||||||
uint8_t dataType;
|
uint8_t dataType;
|
||||||
|
|
||||||
char_t name[SAVE_SLOT_NAME_LENGTH + 1];// 8 characters + null terminator
|
saveslotcache_t cachedData;
|
||||||
dusktimeepoch_t time;
|
|
||||||
} saveslot_t;
|
} saveslot_t;
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
||||||
@@ -39,7 +44,15 @@ void saveSlotInit(saveslot_t *slot);
|
|||||||
* @param slot The save slot to check.
|
* @param slot The save slot to check.
|
||||||
* @return True if the save slot is in use, false otherwise.
|
* @return True if the save slot is in use, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool_t saveSlotInUse(saveslot_t *slot);
|
bool_t saveSlotInUse(saveslotcache_t *slot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not the given save slot has ever saved (has an epoc non 0)
|
||||||
|
*
|
||||||
|
* @param slot The save slot to check.
|
||||||
|
* @return True if the save slot has ever saved, false otherwise.
|
||||||
|
*/
|
||||||
|
bool_t saveSlotHasSaved(saveslotcache_t *slot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the given save slot out to the given JSON object.
|
* Writes the given save slot out to the given JSON object.
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "savestatus.h"
|
|
||||||
#include "assert/assert.h"
|
|
||||||
#include "util/memory.h"
|
|
||||||
#include "util/string.h"
|
|
||||||
|
|
||||||
void saveStatusInit(savestatus_t *status) {
|
|
||||||
assertNotNull(status, "Status cannot be null");
|
|
||||||
memoryZero(status, sizeof(savestatus_t));
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveStatusFromSlot(savestatus_t *status, saveslot_t *slot) {
|
|
||||||
assertNotNull(status, "Status cannot be null");
|
|
||||||
assertNotNull(slot, "Slot cannot be null");
|
|
||||||
|
|
||||||
status->inUse = saveSlotInUse(slot);
|
|
||||||
stringCopy(status->name, slot->name, SAVE_SLOT_NAME_LENGTH);
|
|
||||||
status->time = slot->time;
|
|
||||||
}
|
|
||||||
@@ -1,34 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2026 Dominic Masters
|
|
||||||
*
|
|
||||||
* This software is released under the MIT License.
|
|
||||||
* https://opensource.org/licenses/MIT
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#include "time/timeepoch.h"
|
|
||||||
#include "saveslot.h"
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
typedef struct savestatus_s {
|
|
||||||
bool_t inUse;
|
|
||||||
char_t name[SAVE_SLOT_NAME_LENGTH + 1];
|
|
||||||
dusktimeepoch_t time;
|
|
||||||
} savestatus_t;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inits the save status with the default (not in use) state.
|
|
||||||
*
|
|
||||||
* @param status The save status to init.
|
|
||||||
*/
|
|
||||||
void saveStatusInit(savestatus_t *status);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Populates the save status with the basic, at-a-glance information taken
|
|
||||||
* from a fully loaded save slot.
|
|
||||||
*
|
|
||||||
* @param status The save status to populate.
|
|
||||||
* @param slot The save slot to read the basic information from.
|
|
||||||
*/
|
|
||||||
void saveStatusFromSlot(savestatus_t *status, saveslot_t *slot);
|
|
||||||
@@ -11,7 +11,7 @@
|
|||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
|
||||||
#include "console/console.h"
|
#include "console/console.h"
|
||||||
#include "save/savemanager.h"
|
#include "save/save.h"
|
||||||
|
|
||||||
int32_t testData = 69;
|
int32_t testData = 69;
|
||||||
|
|
||||||
@@ -19,10 +19,20 @@ void testCallback(savedevice_t *device, void *user) {
|
|||||||
if(device == NULL) {
|
if(device == NULL) {
|
||||||
consolePrint("No save device found.");
|
consolePrint("No save device found.");
|
||||||
} else {
|
} else {
|
||||||
uint8_t index = (uint8_t)(device - &SAVE_MANAGER.devices[0]);
|
uint8_t index = (uint8_t)(device - &SAVE.devices[0]);
|
||||||
consolePrint(
|
consolePrint(
|
||||||
"Found save device %u: %s", (uint32_t)index, device->reasonKey
|
"Found save device %u: %s", (uint32_t)index, device->reasonKey
|
||||||
);
|
);
|
||||||
|
|
||||||
|
for(uint8_t i = 0; i < SAVE_SLOT_COUNT; i++) {
|
||||||
|
if(saveSlotInUse(&SAVE.caches[i])) {
|
||||||
|
consolePrint(
|
||||||
|
"Slot %u is in use: %s", (uint32_t)i, SAVE.caches[i].name
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
consolePrint("Slot %u is not in use.", (uint32_t)i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,7 +41,7 @@ errorret_t sceneInitialInit(scenedata_t *sceneData) {
|
|||||||
memoryZero(&sceneData->initial, sizeof(sceneinitial_t));
|
memoryZero(&sceneData->initial, sizeof(sceneinitial_t));
|
||||||
|
|
||||||
consolePrint("Going to find a save device.");
|
consolePrint("Going to find a save device.");
|
||||||
saveManagerFindAvailableDevice(
|
saveFindAvailableDevice(
|
||||||
testCallback,
|
testCallback,
|
||||||
&testData
|
&testData
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
#include "save/savedevice.h"
|
#include "save/savedevice.h"
|
||||||
#include "save/savedevicedolphincard.h"
|
#include "save/savedevicedolphincard.h"
|
||||||
#include "save/savemanager.h"
|
#include "save/save.h"
|
||||||
#include "assert/assert.h"
|
#include "assert/assert.h"
|
||||||
|
|
||||||
errorret_t saveDeviceDolphinCardInit(savedevice_t *device) {
|
errorret_t saveDeviceDolphinCardInit(savedevice_t *device) {
|
||||||
@@ -15,11 +15,11 @@ errorret_t saveDeviceDolphinCardInit(savedevice_t *device) {
|
|||||||
|
|
||||||
device->state = SAVE_DEVICE_STATE_UNKNOWN;
|
device->state = SAVE_DEVICE_STATE_UNKNOWN;
|
||||||
|
|
||||||
// Each savedevice_t in SAVE_MANAGER.devices maps to one physical memory
|
// Each savedevice_t in SAVE.devices maps to one physical memory
|
||||||
// card slot - device 0 is slot A, device 1 is slot B, determined by this
|
// card slot - device 0 is slot A, device 1 is slot B, determined by this
|
||||||
// device's position in that array (the same index math savemanager.c
|
// device's position in that array (the same index math save.c
|
||||||
// itself uses to identify a device).
|
// itself uses to identify a device).
|
||||||
uint8_t index = (uint8_t)(device - &SAVE_MANAGER.devices[0]);
|
uint8_t index = (uint8_t)(device - &SAVE.devices[0]);
|
||||||
device->platform.channel = index == 0 ? CARD_SLOTA : CARD_SLOTB;
|
device->platform.channel = index == 0 ? CARD_SLOTA : CARD_SLOTB;
|
||||||
|
|
||||||
errorOk();
|
errorOk();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
// Set from this device's index into SAVE_MANAGER.devices - device 0 is
|
// Set from this device's index into SAVE.devices - device 0 is
|
||||||
// CARD_SLOTA, device 1 is CARD_SLOTB.
|
// CARD_SLOTA, device 1 is CARD_SLOTB.
|
||||||
int32_t channel;
|
int32_t channel;
|
||||||
uint8_t cardBuffer[CARD_WORKAREA] __attribute__((aligned(32)));
|
uint8_t cardBuffer[CARD_WORKAREA] __attribute__((aligned(32)));
|
||||||
|
|||||||
@@ -8,12 +8,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "error/error.h"
|
#include "error/error.h"
|
||||||
|
|
||||||
// Saves live under $HOME/<SAVE_DEVICE_LINUX_DIRECTORY_NAME>, one JSON file
|
|
||||||
// per save slot plus a separate settings file.
|
|
||||||
#define SAVE_DEVICE_LINUX_DIRECTORY_NAME ".dusk/saves"
|
#define SAVE_DEVICE_LINUX_DIRECTORY_NAME ".dusk/saves"
|
||||||
#define SAVE_DEVICE_LINUX_SETTINGS_FILENAME "settings.json"
|
#define SAVE_DEVICE_LINUX_SETTINGS_FILENAME "settings.json"
|
||||||
#define SAVE_DEVICE_LINUX_SLOT_FILENAME_FORMAT "slot%u.json"
|
#define SAVE_DEVICE_LINUX_SLOT_FILENAME_FORMAT "slot%u.json"
|
||||||
#define SAVE_DEVICE_LINUX_PATH_MAX 512
|
#define SAVE_DEVICE_LINUX_PATH_MAX FILENAME_MAX
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *nothing;
|
void *nothing;
|
||||||
|
|||||||
Reference in New Issue
Block a user