Skip to content
Permalink
Browse files

memoryCard: options window, ability to remove card from slot

  • Loading branch information
JaCzekanski committed Sep 6, 2019
1 parent 1a4bc86 commit 4a423d4f8507817a0a06427b54c04265b916f182
@@ -176,7 +176,7 @@ const json defaultConfig = {
}},
{"memoryCard", {
{"1", "data/memory/card1.mcr"},
{"2", nullptr}
{"2", ""}
}}
};
// clang-format on
@@ -7,6 +7,11 @@ MemoryCard::MemoryCard(int port) : AbstractDevice(Type::MemoryCard, port) { verb

uint8_t MemoryCard::handle(uint8_t byte) {
if (state == 0) command = Command::None;

if (!inserted) {
return 0xff;
}

if (verbose >= 3) printf("[MEMCARD] state %d\n", state);
if (command == Command::Read) return handleRead(byte);
if (command == Command::Write) return handleWrite(byte);
@@ -4,6 +4,7 @@

namespace peripherals {
struct MemoryCard : public AbstractDevice {
private:
enum class Command { Read, Write, ID, None };
enum class WriteStatus : uint8_t { Good = 'G', BadChecksum = 'N', BadSector = 0xff };
union Flag {
@@ -19,23 +20,23 @@ struct MemoryCard : public AbstractDevice {
Flag() : error(0), fresh(1), unknown(1) {}
};

int verbose = 0;
uint8_t handleRead(uint8_t byte);
uint8_t handleWrite(uint8_t byte);
uint8_t handleId(uint8_t byte);

int verbose;
Command command = Command::None;

Flag flag;
Reg16 address; // Read/Write address (in 128B blocks)
uint8_t checksum = 0;
WriteStatus writeStatus = WriteStatus::Good;

bool dirty = false;

public:
std::array<uint8_t, 128 * 1024> data;
bool inserted = true;
bool dirty = false;

MemoryCard(int port);
uint8_t handle(uint8_t byte) override;
uint8_t handleRead(uint8_t byte);
uint8_t handleWrite(uint8_t byte);
uint8_t handleId(uint8_t byte);
};
} // namespace peripherals
@@ -9,6 +9,7 @@
#include "debug/timers/timers.h"
#include "imgui/imgui_impl_sdl_gl3.h"
#include "options.h"
#include "options/memory_card/memory_card.h"
#include "platform/windows/input/key.h"
#include "version.h"

@@ -43,6 +44,8 @@ gui::debug::cdrom::Cdrom cdromDebug;
gui::debug::cpu::CPU cpuDebug;
gui::debug::timers::Timers timersDebug;

gui::options::memory_card::MemoryCard memoryCardOptions;

void aboutWindow() {
ImGui::Begin("About", &showAboutWindow);
ImGui::Text("Avocado %s", BUILD_STRING);
@@ -136,6 +139,7 @@ void renderImgui(System* sys) {
if (ImGui::MenuItem("Graphics", nullptr)) showGraphicsOptionsWindow = true;
if (ImGui::MenuItem("BIOS", nullptr)) showBiosWindow = true;
if (ImGui::MenuItem("Controller", nullptr)) showControllerSetupWindow = true;
ImGui::MenuItem("Memory Card", nullptr, &memoryCardOptions.memoryCardWindowOpen);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Help")) {
@@ -169,6 +173,8 @@ void renderImgui(System* sys) {
if (showBiosWindow) biosSelectionWindow();
if (showControllerSetupWindow) controllerSetupWindow();

memoryCardOptions.displayWindows(sys);

// Help
if (showAboutWindow) aboutWindow();
}
@@ -0,0 +1,43 @@
#include "memory_card.h"
#include <imgui.h>
#include <misc/cpp/imgui_stdlib.h>
#include "config.h"
#include "system.h"
#include "utils/string.h"

namespace gui::options::memory_card {
void MemoryCard::memoryCardWindow(System* sys) {
if (loadPaths) {
for (size_t i = 0; i < cardPaths.size(); i++) {
cardPaths[i] = config["memoryCard"][std::to_string(i + 1)];
}
loadPaths = false;
}
ImGui::Begin("MemoryCard", &memoryCardWindowOpen, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoCollapse);
ImGui::BeginTabBar("##memory_select");

for (size_t i = 0; i < sys->controller->card.size(); i++) {
if (ImGui::BeginTabItem(string_format("Slot %d", i + 1).c_str())) {
if (ImGui::InputText("Path", &cardPaths[i])) {
config["memoryCard"][std::to_string(i + 1)] = cardPaths[i];
}
// TODO: Reload contents on change?
// TODO: Check if card exists, override or reload?

bool inserted = sys->controller->card[i]->inserted;
if (ImGui::Checkbox("Inserted", &inserted)) {
sys->controller->card[0]->inserted = inserted;
}

ImGui::EndTabItem();
}
}

ImGui::EndTabBar();
ImGui::End();
}

void MemoryCard::displayWindows(System* sys) {
if (memoryCardWindowOpen) memoryCardWindow(sys);
}
} // namespace gui::options::memory_card
@@ -0,0 +1,17 @@
#pragma once
#include <array>
#include <string>

struct System;

namespace gui::options::memory_card {
class MemoryCard {
bool loadPaths = true;
std::array<std::string, 2> cardPaths;
void memoryCardWindow(System* sys);

public:
bool memoryCardWindowOpen = false;
void displayWindows(System* sys);
};
} // namespace gui::options::memory_card
@@ -149,14 +149,28 @@ std::unique_ptr<System> hardReset() {
printf("Using iso %s\n", iso.c_str());
}

std::string pathCard1 = config["memoryCard"]["1"];
if (!pathCard1.empty()) {
auto card1 = getFileContents(pathCard1);
if (!card1.empty()) {
std::copy_n(std::make_move_iterator(card1.begin()), card1.size(), sys->controller->card[0]->data.begin());
printf("[INFO] Loaded memory card 1 from %s\n", getFilenameExt(pathCard1).c_str());
auto loadMemoryCard = [&](int slot) {
assert(slot == 0 || slot == 1);
auto card = sys->controller->card[slot].get();

auto configEntry = config["memoryCard"][std::to_string(slot + 1)];
std::string pathCard = configEntry.is_null() ? "" : configEntry;

card->inserted = false;

if (!pathCard.empty()) {
auto cardData = getFileContents(pathCard);
if (!cardData.empty()) {
std::copy_n(std::make_move_iterator(cardData.begin()), cardData.size(), sys->controller->card[slot]->data.begin());
card->inserted = true;
printf("[INFO] Loaded memory card %d from %s\n", slot + 1, getFilenameExt(pathCard).c_str());
}
}
}
};

loadMemoryCard(0);
loadMemoryCard(1);

return sys;
}

@@ -362,13 +376,16 @@ int main(int argc, char** argv) {
bool frameLimitEnabled = true;
bool windowFocused = true;

bool forceRedraw = false;

SDL_Event event;
while (running && !exitProgram) {
bool newEvent = false;
if (sys->state != System::State::run) {
if (!forceRedraw && sys->state != System::State::run) {
SDL_WaitEvent(&event);
newEvent = true;
}
forceRedraw = false;

auto lockMouse = sys->state == System::State::run && inputManager->mouseLocked;
SDL_SetRelativeMouseMode((SDL_bool)lockMouse);
@@ -427,6 +444,10 @@ int main(int argc, char** argv) {
opengl.width = event.window.data1;
opengl.height = event.window.data2;
}

// Crude hack to force next frame after last event received (in paused mode)
// Fixes ImGui window drawing
forceRedraw = true;
}

if (doHardReset) {

0 comments on commit 4a423d4

Please sign in to comment.
You can’t perform that action at this time.