Files
dusk/src/dusklinux/save/savedevicelinux.c
T
YourWishesandClaude Sonnet 5 fdfdfa3a66 Fix the build after archiving rpg/ui/scene: drop their last live dependents
rpg/ui/scene moved to archive/ earlier left a handful of otherwise-generic
systems with dead references into them:
- asset/loader/chunk existed solely to load rpg overworld map chunks
  (tile_t, worldpos_t) - deleted outright, along with its
  ASSET_LOADER_TYPE_CHUNK entry in assetloader.c/h.
- save/slot wrapped party_t/storyflagval_t/map-name/cutscene-path, which is
  100% rpg save data - deleted outright (save.c/h, savedevice.c/h and the
  Linux save backend keep their generic settings/device-discovery logic,
  just lose the slot read/write pieces that only existed for it).
- locale/localemanager.c and test/CMakeLists.txt/test/save/* had a few
  stray includes and test cases that only existed for the now-gone code.

Also restores assets/locale/en_US.po (copied back from archive/assets/) -
locale init still needs a real locale file to boot into, even with the
asset-moving/archiving done separately.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-10-15 09:08:02 -05:00

155 lines
4.2 KiB
C

/**
* Copyright (c) 2026 Dominic Masters
*
* This software is released under the MIT License.
* https://opensource.org/licenses/MIT
*/
#include "save/savedevice.h"
#include "save/savedevicelinux.h"
#include "save/settings/savesettings.h"
#include "save/savejson.h"
#include "asset/asset.h"
#include "assert/assert.h"
#include "util/mkdirp.h"
#include "util/string.h"
errorret_t saveDeviceLinuxInit(savedevice_t *device) {
assertNotNull(device, "device cannot be null");
device->state = SAVE_DEVICE_STATE_UNKNOWN;
errorOk();
}
errorret_t saveDeviceLinuxUpdate(savedevice_t *device) {
assertNotNull(device, "device cannot be null");
assertIsMainThread("Invalid thread");
errorOk();
}
void saveDeviceLinuxCheckAvailability(savedevice_t *device) {
assertNotNull(device, "device cannot be null");
assertIsMainThread("Invalid thread");
assertTrue(
device->state == SAVE_DEVICE_STATE_CHECKING_AVAILABILITY,
"Device state incorrect?"
);
// Resolve the save directory - can't actually fail (just a
// stringFormat), unlike when this derived from $HOME, but this function
// returns void (via saveDeviceFireCallback below) rather than
// errorret_t, so there's no return-early errorChain to use here.
char_t directory[SAVE_DEVICE_LINUX_PATH_MAX];
errorret_t directoryResult = saveDeviceLinuxGetDirectory(
directory, sizeof(directory)
);
if(errorIsNotOk(directoryResult)) errorCatch(errorPrint(directoryResult));
// Mkdirp the save directory.
int mkdirpResult = mkdirp(directory, 0700);
if(mkdirpResult != 0) {
device->state = SAVE_DEVICE_STATE_UNAVAILABLE;
device->reasonKey = "save.linux.mkdirp_failed";
return saveDeviceFireCallback(device);
}
// The save device is available.
device->state = SAVE_DEVICE_STATE_AVAILABLE;
device->reasonKey = NULL;
saveDeviceFireCallback(device);
}
errorret_t saveDeviceLinuxGetDirectory(char_t *dest, const size_t destSize) {
assertNotNull(dest, "dest cannot be null");
stringFormat(
dest, destSize, "%s/%s",
ASSET.baseDirectory, SAVE_DEVICE_LINUX_SAVES_SUBDIR_NAME
);
errorOk();
}
errorret_t saveDeviceLinuxGetSettingsPath(
char_t *dest,
const size_t destSize
) {
assertNotNull(dest, "dest cannot be null");
char_t directory[SAVE_DEVICE_LINUX_PATH_MAX];
errorChain(saveDeviceLinuxGetDirectory(directory, sizeof(directory)));
stringFormat(
dest, destSize, "%s/%s", directory, SAVE_DEVICE_LINUX_SETTINGS_FILENAME
);
errorOk();
}
errorret_t saveDeviceLinuxSettingsWrite(
savedevice_t *device,
savesettings_t *settings
) {
assertNotNull(device, "device cannot be null");
assertNotNull(settings, "settings cannot be null");
char_t path[SAVE_DEVICE_LINUX_PATH_MAX];
errorChain(saveDeviceLinuxGetSettingsPath(path, sizeof(path)));
writeInit();
errorret_t writeResult = saveSettingsWriteJSON(settings, doc, object);
if(errorIsNotOk(writeResult)) {
yyjson_mut_doc_free(doc);
errorChain(writeResult);
}
yyjson_write_err writeErr;
bool_t written = yyjson_mut_write_file(path, doc, 0, NULL, &writeErr);
yyjson_mut_doc_free(doc);
if(!written) {
errorThrow(
"Failed to write save settings file: %s (%s)", path, writeErr.msg
);
}
errorOk();
}
errorret_t saveDeviceLinuxSettingsRead(
savedevice_t *device,
savesettings_t *settings
) {
assertNotNull(device, "device cannot be null");
assertNotNull(settings, "settings cannot be null");
char_t path[SAVE_DEVICE_LINUX_PATH_MAX];
errorChain(saveDeviceLinuxGetSettingsPath(path, sizeof(path)));
yyjson_read_err readErr;
yyjson_doc *jsonDoc = yyjson_read_file(path, 0, NULL, &readErr);
if(jsonDoc == NULL) {
// No settings file yet, leave settings as-is.
if(readErr.code == YYJSON_READ_ERROR_FILE_OPEN) errorOk();
errorThrow(
"Failed to parse save settings file: %s (%s)", path, readErr.msg
);
}
yyjson_val *object = yyjson_doc_get_root(jsonDoc);
if(object == NULL) {
yyjson_doc_free(jsonDoc);
errorThrow("Save settings file missing root object: %s", path);
}
errorret_t readResult = saveSettingsReadJSON(settings, object);
yyjson_doc_free(jsonDoc);
errorChain(readResult);
errorOk();
}
errorret_t saveDeviceLinuxDispose(savedevice_t *device) {
errorOk();
}