mirror of
https://github.com/rodamaral/lsnes.git
synced 2025-04-02 10:42:15 -04:00
155 lines
4.3 KiB
C++
Executable file
155 lines
4.3 KiB
C++
Executable file
StateManager *stateManager = nullptr;
|
|
|
|
StateManager::StateManager() {
|
|
setTitle("State Manager");
|
|
setGeometry({ 128, 128, 600, 360 });
|
|
windowManager->append(this, "StateManager");
|
|
|
|
stateList.setHeaderText("Slot", "Description");
|
|
stateList.setHeaderVisible();
|
|
descLabel.setText("Description:");
|
|
loadButton.setText("Load");
|
|
saveButton.setText("Save");
|
|
eraseButton.setText("Erase");
|
|
|
|
append(layout);
|
|
layout.setMargin(5);
|
|
layout.append(stateList, { ~0, ~0 }, 5);
|
|
layout.append(descLayout, { ~0, 0 }, 5);
|
|
descLayout.append(descLabel, { 0, 0 }, 5);
|
|
descLayout.append(descEdit, { ~0, 0 }, 0);
|
|
layout.append(controlLayout, { ~0, 0 }, 0);
|
|
controlLayout.append(spacer, { ~0, 0 }, 0);
|
|
controlLayout.append(loadButton, { 80, 0 }, 5);
|
|
controlLayout.append(saveButton, { 80, 0 }, 5);
|
|
controlLayout.append(eraseButton, { 80, 0 }, 0);
|
|
|
|
for(unsigned n = 0; n < 32; n++) stateList.append(decimal<2>(n + 1), "(empty)");
|
|
stateList.autoSizeColumns();
|
|
|
|
synchronize();
|
|
|
|
stateList.onActivate = { &StateManager::slotLoad, this };
|
|
stateList.onChange = { &StateManager::synchronize, this };
|
|
descEdit.onChange = { &StateManager::slotSaveDescription, this };
|
|
loadButton.onActivate = { &StateManager::slotLoad, this };
|
|
saveButton.onActivate = { &StateManager::slotSave, this };
|
|
eraseButton.onActivate = { &StateManager::slotErase, this };
|
|
}
|
|
|
|
void StateManager::synchronize() {
|
|
layout.setEnabled(interface->cartridgeLoaded());
|
|
|
|
descEdit.setText("");
|
|
descEdit.setEnabled(false);
|
|
controlLayout.setEnabled(stateList.selected());
|
|
if(stateList.selected() == false) return;
|
|
|
|
if(slot[stateList.selection()].capacity() > 0) {
|
|
descEdit.setText(slotLoadDescription(stateList.selection()));
|
|
descEdit.setEnabled(true);
|
|
}
|
|
}
|
|
|
|
void StateManager::refresh() {
|
|
for(unsigned n = 0; n < 32; n++) {
|
|
stateList.modify(n, decimal<2>(n + 1), slotLoadDescription(n));
|
|
}
|
|
stateList.autoSizeColumns();
|
|
}
|
|
|
|
void StateManager::reset() {
|
|
for(unsigned n = 0; n < 32; n++) slot[n] = serializer();
|
|
synchronize();
|
|
refresh();
|
|
}
|
|
|
|
bool StateManager::load(const string &filename, unsigned revision) {
|
|
for(unsigned n = 0; n < 32; n++) slot[n] = serializer();
|
|
synchronize();
|
|
|
|
file fp;
|
|
if(fp.open(filename, file::mode::read) == false) return false;
|
|
|
|
if(fp.readl(4) == 0x31415342) {
|
|
if(fp.readl(4) == revision) { //'BSA1'
|
|
for(unsigned n = 0; n < 32; n++) {
|
|
if(fp.read() == false) continue;
|
|
unsigned size = fp.readl(4);
|
|
uint8_t *data = new uint8_t[size];
|
|
fp.read(data, size);
|
|
slot[n] = serializer(data, size);
|
|
delete[] data;
|
|
}
|
|
}
|
|
}
|
|
|
|
refresh();
|
|
return true;
|
|
}
|
|
|
|
bool StateManager::save(const string &filename, unsigned revision) {
|
|
bool hasSave = false;
|
|
for(unsigned n = 0; n < 32; n++) {
|
|
if(slot[n].capacity() > 0) hasSave = true;
|
|
}
|
|
|
|
if(hasSave == false) {
|
|
unlink(filename);
|
|
return true;
|
|
}
|
|
|
|
file fp;
|
|
if(fp.open(filename, file::mode::write) == false) return false;
|
|
|
|
fp.writel(0x31415342, 4); //'BSA1'
|
|
fp.writel(revision, 4);
|
|
for(unsigned n = 0; n < 32; n++) {
|
|
if(slot[n].capacity() == 0) {
|
|
fp.write(false);
|
|
} else {
|
|
fp.write(true);
|
|
fp.writel(slot[n].size(), 4);
|
|
fp.write(slot[n].data(), slot[n].size());
|
|
}
|
|
}
|
|
}
|
|
|
|
void StateManager::slotLoad() {
|
|
if(stateList.selected() == false) return;
|
|
serializer s(slot[stateList.selection()].data(), slot[stateList.selection()].capacity());
|
|
interface->unserialize(s);
|
|
}
|
|
|
|
void StateManager::slotSave() {
|
|
if(stateList.selected()) {
|
|
slot[stateList.selection()] = interface->serialize();
|
|
}
|
|
refresh();
|
|
synchronize();
|
|
descEdit.setFocused();
|
|
}
|
|
|
|
void StateManager::slotErase() {
|
|
if(stateList.selected()) {
|
|
slot[stateList.selection()] = serializer();
|
|
}
|
|
refresh();
|
|
synchronize();
|
|
}
|
|
|
|
string StateManager::slotLoadDescription(unsigned n) {
|
|
if(slot[n].capacity() == 0) return "(empty)";
|
|
char text[DescriptionLength];
|
|
strlcpy(text, (const char*)slot[n].data() + HeaderLength, DescriptionLength);
|
|
return text;
|
|
}
|
|
|
|
void StateManager::slotSaveDescription() {
|
|
if(stateList.selected() == false) return;
|
|
string text = descEdit.text();
|
|
if(slot[stateList.selection()].capacity() > 0) {
|
|
strlcpy((char*)slot[stateList.selection()].data() + HeaderLength, (const char*)text, DescriptionLength);
|
|
}
|
|
refresh();
|
|
}
|