Skip to content

Commit

Permalink
Add support for loading embedded games into an archive.
Browse files Browse the repository at this point in the history
  • Loading branch information
Arignir committed Jan 2, 2024
1 parent 50e833b commit 2ef5df5
Show file tree
Hide file tree
Showing 16 changed files with 122 additions and 32 deletions.
12 changes: 7 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ jobs:
- name: Install Dependencies
uses: msys2/setup-msys2@v2
with:
install: make mingw-w64-x86_64-meson mingw-w64-x86_64-ninja mingw-w64-x86_64-pkg-config mingw-w64-x86_64-gcc mingw-w64-x86_64-SDL2 mingw-w64-x86_64-glew
install: make mingw-w64-x86_64-meson mingw-w64-x86_64-ninja mingw-w64-x86_64-pkg-config mingw-w64-x86_64-gcc mingw-w64-x86_64-SDL2 mingw-w64-x86_64-glew mingw-w64-x86_64-cmake mingw-w64-x86_64-libarchive
- name: Build Hades
run: |
meson build -Dstatic_executable=true
meson --buildtype=release build -Dstatic_executable=true
cd build
ninja
- name: Test Hades
Expand All @@ -41,9 +41,11 @@ jobs:
submodules: recursive
- name: Install Dependencies
run: |
brew install meson ninja sdl2 glew create-dmg
brew install meson ninja sdl2 glew libarchive create-dmg
- name: Build Hades
run: |
export PKG_CONFIG_PATH=/usr/local/opt/libarchive/lib/pkgconfig
rm -rf /tmp/build/
mkdir -p /tmp/build/Hades.app
Expand Down Expand Up @@ -137,10 +139,10 @@ jobs:
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y meson ninja-build libsdl2-dev libglew-dev libgtk-3-dev
sudo apt-get install -y meson ninja-build libsdl2-dev libglew-dev libgtk-3-dev libarchive-dev
- name: Build Hades
run: |
meson build --werror
meson --buildtype=release build --werror
cd build
ninja
- name: Test Hades
Expand Down
4 changes: 3 additions & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
[submodule "external/cimgui"]
path = external/cimgui
url = https://github.com/cimgui/cimgui.git
branch = Lib_Only
[submodule "external/stb"]
path = external/stb
url = https://github.com/nothings/stb.git
Expand All @@ -11,3 +10,6 @@
[submodule "external/mjson"]
path = external/mjson
url = https://github.com/cesanta/mjson.git
[submodule "subprojects/libarchive"]
path = subprojects/libarchive
url = https://github.com/libarchive/libarchive.git
3 changes: 0 additions & 3 deletions include/app/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@

#pragma once

#define SDL_MAIN_HANDLED
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#if WITH_DEBUGGER
#include <capstone/capstone.h>
#endif
Expand Down
2 changes: 2 additions & 0 deletions meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ project(
default_options: ['c_std=gnu17', 'cpp_std=c++11', 'buildtype=release'],
)

cmake = import('cmake')

incdir = include_directories('include', 'source')
cflags = [
'-fms-extensions',
Expand Down
3 changes: 0 additions & 3 deletions source/app/bindings.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
**
\******************************************************************************/

#define SDL_MAIN_HANDLED
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#include <SDL2/SDL.h>
#include <cimgui.h>
#include <cimgui_impl.h>
Expand Down
101 changes: 100 additions & 1 deletion source/app/emulator.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#define _GNU_SOURCE
#define STB_IMAGE_WRITE_IMPLEMENTATION

#include <archive.h>
#include <archive_entry.h>
#include <stb_image_write.h>
#include <errno.h>
#include "app/app.h"
Expand Down Expand Up @@ -262,6 +264,94 @@ app_emulator_configure_bios(
return (false);
}

static
bool
app_emulator_configure_rom_archive(
struct app *app,
char const *archive_path
) {
struct archive *archive;
struct archive_entry *entry;
int err;
bool game_found;

logln(HS_INFO, "Path given identified as an archived.");

game_found = false;
archive = archive_read_new();
hs_assert(archive);

archive_read_support_filter_all(archive);
archive_read_support_format_all(archive);

err = archive_read_open_filename(archive, archive_path, 4096);
if (err != ARCHIVE_OK) {
app_new_notification(
app,
UI_NOTIFICATION_ERROR,
"Failed to open the path as an archive: %s.",
archive_path,
archive_error_string(archive)
);
return (true);
}

while (archive_read_next_header(archive, &entry) == ARCHIVE_OK) {
char const *entry_name;
char const *ext;

entry_name = archive_entry_pathname(entry);
ext = strrchr(entry_name, '.');
if (ext && !strcmp(ext, ".gba")) {
size_t file_len;
ssize_t read_len;
void *data;

file_len = 0;
data = NULL;
do {
data = realloc(data, file_len + 4096);
hs_assert(data);

read_len = archive_read_data(archive, data + file_len, 4096);
if (read_len < 0) {
app_new_notification(
app,
UI_NOTIFICATION_ERROR,
"Failed to archive's entry %s: %s.",
entry_name,
archive_error_string(archive)
);
free(data);
goto cleanup;
}
file_len += read_len;
} while (read_len > 0);

game_found = true;

app->emulation.launch_config->rom.data = data;
app->emulation.launch_config->rom.size = file_len;

goto cleanup;
}

archive_read_data_skip(archive);
}

app_new_notification(
app,
UI_NOTIFICATION_ERROR,
"No valid GBA game found in the archive.",
archive_path,
archive_error_string(archive)
);

cleanup:
archive_read_free(archive);
return (!game_found);
}

static
bool
app_emulator_configure_rom(
Expand Down Expand Up @@ -387,21 +477,28 @@ app_emulator_configure(
struct message_reset event;
char *backup_path;
char *extension;
bool is_archive;
size_t basename_len;
size_t i;
uint8_t *code;

app_emulator_unconfigure(app);

logln(HS_INFO, "Loading game at \"%s%s%s\".", g_light_green, rom_path, g_reset);

app->emulation.launch_config = calloc(1, sizeof(struct launch_config));
hs_assert(app->emulation.launch_config);

extension = strrchr(rom_path, '.');

// We consider anything that isn't ending with `.gba` or `.bin` as an archive.
// XXX: Should we build a hard-coded list instead?
if (extension) {
basename_len = extension - rom_path;
is_archive = (bool)(strcmp(extension, ".gba") && strcmp(extension, ".bin"));
} else {
basename_len = strlen(rom_path);
is_archive = false;
}

for (i = 0; i < MAX_QUICKSAVES; ++i) {
Expand All @@ -426,7 +523,7 @@ app_emulator_configure(
);

if (app_emulator_configure_bios(app)
|| app_emulator_configure_rom(app, rom_path)
|| (is_archive ? app_emulator_configure_rom_archive(app, rom_path) : app_emulator_configure_rom(app, rom_path))
|| app_emulator_configure_backup(app, backup_path)
) {
app_emulator_unconfigure(app);
Expand Down Expand Up @@ -502,6 +599,8 @@ app_emulator_configure(

app_config_push_recent_rom(app, rom_path);

logln(HS_INFO, "Game successfully loaded.");

return (false);
}

Expand Down
4 changes: 0 additions & 4 deletions source/app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
**
\******************************************************************************/

#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#include <GL/glew.h>

#include <cimgui.h>
#include <cimgui_impl.h>

#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>

#ifdef _MSC_VER
Expand Down
11 changes: 8 additions & 3 deletions source/app/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
##
################################################################################

libapp_extra_cflags = [
'-DCIMGUI_DEFINE_ENUMS_AND_STRUCTS',
'-DSDL_MAIN_HANDLED',
]
libapp_extra_deps = []

###############################
Expand Down Expand Up @@ -45,7 +49,7 @@ if get_option('with_debugger')
dependency('capstone', required: true, static: get_option('static_executable')),
],
include_directories: [incdir, imgui_inc],
c_args: cflags,
c_args: cflags + libapp_extra_cflags,
link_args: ldflags,
)

Expand Down Expand Up @@ -74,11 +78,12 @@ libapp = static_library(
'emulator.c',
'bindings.c',
'main.c',
dependencies: [
dependencies: imgui_dep + [
dependency('threads', required: true, static: get_option('static_executable')),
dependency('libarchive', required: true, static: get_option('static_executable')),
],
link_with: [libgba, imgui, nfde, mjson] + libapp_extra_deps,
include_directories: [incdir, imgui_inc, nfde_inc, mjson_inc, stb_inc],
c_args: cflags,
c_args: cflags + libapp_extra_cflags,
link_args: ldflags,
)
3 changes: 0 additions & 3 deletions source/app/sdl/event.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@
**
\******************************************************************************/

#define SDL_MAIN_HANDLED
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#include <SDL2/SDL.h>
#include <cimgui.h>
#include <cimgui_impl.h>
Expand Down
1 change: 0 additions & 1 deletion source/app/sdl/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
**
\******************************************************************************/

#define SDL_MAIN_HANDLED
#include <SDL2/SDL.h>
#include <stdio.h>
#include "app/app.h"
Expand Down
5 changes: 1 addition & 4 deletions source/app/sdl/video.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@
**
\******************************************************************************/

#define SDL_MAIN_HANDLED
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#include <errno.h>
#include <GL/glew.h>
#include <cimgui.h>
#include <cimgui_impl.h>
#include <nfd.h>
#include <errno.h>
#include "hades.h"
#include "app/app.h"
#include "gba/gba.h"
Expand Down
1 change: 0 additions & 1 deletion source/app/windows/game.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
\******************************************************************************/

#define _GNU_SOURCE
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#include <cimgui.h>
#include "hades.h"
Expand Down
1 change: 0 additions & 1 deletion source/app/windows/keybinds.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
**
\******************************************************************************/

#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS
#include <cimgui.h>
#include "hades.h"
#include "app/app.h"
Expand Down
1 change: 0 additions & 1 deletion source/app/windows/menubar.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
\******************************************************************************/

#define _GNU_SOURCE
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#include <string.h>
#include <cimgui.h>
Expand Down
1 change: 0 additions & 1 deletion source/app/windows/notif.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
\******************************************************************************/

#define _GNU_SOURCE
#define CIMGUI_DEFINE_ENUMS_AND_STRUCTS

#include <cimgui.h>
#include "hades.h"
Expand Down
1 change: 1 addition & 0 deletions subprojects/libarchive
Submodule libarchive added at 6468cd

0 comments on commit 2ef5df5

Please sign in to comment.