Skip to content

Commit

Permalink
#2 Allow starting the emulator without a game rom
Browse files Browse the repository at this point in the history
Previously a game would have to be passed on the command line, since it
was a required argument. This change enables to first open the program
and then select a game rom to run.
Passing roms on the command line is still supported.
  • Loading branch information
dariusarnold committed Mar 12, 2023
1 parent d78ee0a commit 80047db
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 25 deletions.
35 changes: 19 additions & 16 deletions src/game-boy-emulator/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,23 +100,26 @@ void Window::draw_frame() {
draw_menubar();

auto& options = m_emulator.get_options();
if (options.draw_debug_background) {
draw_background();
}
if (options.draw_debug_window) {
draw_window();
}
if (options.draw_debug_sprites) {
draw_sprites();
}
if (options.draw_info_window) {
draw_info();
}
if (options.draw_debug_tiles) {
draw_vram();
}
const auto& state = m_emulator.get_state();
if (state.rom_file_path.has_value()) {

draw_game();
if (options.draw_debug_background) {
draw_background();
}
if (options.draw_debug_window) {
draw_window();
}
if (options.draw_debug_sprites) {
draw_sprites();
}
if (options.draw_info_window) {
draw_info();
}
if (options.draw_debug_tiles) {
draw_vram();
}
draw_game();
}

// Rendering
ImVec4 clear_color = ImVec4(0.45f, 0.55f, 0.60f, 1.00f);
Expand Down
33 changes: 24 additions & 9 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

int main(int argc, char** argv) { // NOLINT
argparse::ArgumentParser program("game boy emulator");
program.add_argument("rom").help("Path to game ROM file to run.");
program.add_argument("--game").help("Path to game ROM file to run.");
program.add_argument("--boot").default_value("").help("Path to boot ROM file.");

spdlog::set_level(spdlog::level::info);
Expand All @@ -28,31 +28,46 @@ int main(int argc, char** argv) { // NOLINT
}

std::optional<std::filesystem::path> boot_rom_path;
std::optional<std::filesystem::path> game_rom_path;
if (program.is_used("boot")) {
boot_rom_path = std::filesystem::absolute(program.get("boot"));
}
auto rom_path = std::filesystem::absolute(program.get("rom"));
if (program.is_used("game")) {
game_rom_path = std::filesystem::absolute(program.get("game"));
}

Emulator emulator({});
if (boot_rom_path.has_value()) {
emulator.load_boot_game(boot_rom_path.value(), rom_path);
if (boot_rom_path.has_value() and game_rom_path.has_value()) {
emulator.load_boot_game(boot_rom_path.value(), game_rom_path.value());
} else if (game_rom_path.has_value()) {
emulator.load_game(game_rom_path.value());
} else {
emulator.load_game(rom_path);
// This means only a boot rom without a game was given
spdlog::error("Running boot rom without a game rom not supported.");
std::exit(1);
}

Window window(emulator);
emulator.set_draw_function([&]() { window.vblank_callback(); });

Audio audio(emulator);
if (audio.is_working()) {
emulator.set_audio_function([&](SampleFrame sample){audio.callback(sample);});
emulator.set_audio_function([&](SampleFrame sample) { audio.callback(sample); });
}

// Main loop
while (!window.is_done()) {
auto sucess = emulator.step();
if (!sucess) {
return EXIT_FAILURE;
const auto& state = emulator.get_state();
if (state.rom_file_path.has_value()) {
auto sucess = emulator.step();
if (!sucess) {
return EXIT_FAILURE;
}
} else {
// Normally the vblank interrupt would trigger this callback. But since we are in a
// state where no game is loaded and the emulator is not running, we have to call it
// manually for the UI to render
window.vblank_callback();
}
if (emulator.get_state().new_rom_file_path.has_value()) {
auto path = emulator.get_state().new_rom_file_path.value();
Expand Down

0 comments on commit 80047db

Please sign in to comment.