Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow archive format for all single-track file types. #74

Merged
merged 6 commits into from
Mar 27, 2024

Conversation

myQwil
Copy link
Contributor

@myQwil myQwil commented Nov 7, 2023

Rather than having RAR archives reserved specifically for SPC/RSN files, archives are now open to any single-track, or listable, file types. The archive's contents are scanned and an emulator is made for the first listable file type found.

Support has been implemented for RAR and ZIP. Both are optional, with RAR support being enabled with the presence of the UnRAR library, and ZIP support being enabled with the presence of the LibArchive library.

@sezero
Copy link
Contributor

sezero commented Nov 7, 2023

Unrar support removal: Oh yes :))

Play directory: IMHO, such features should be in a player, not library: Library should concern itself with format support / emulation and keep itself simple. (But it's just me and I'm not a maintainer here.)

gme/gme.cpp Show resolved Hide resolved
@myQwil myQwil force-pushed the listable branch 2 times, most recently from 9d34702 to 90e52f4 Compare November 7, 2023 15:47
gme/gme.exports Show resolved Hide resolved
@myQwil myQwil force-pushed the listable branch 2 times, most recently from 5287206 to 6ad61db Compare November 7, 2023 23:09
@myQwil myQwil changed the title WIP: Open directory's contents as a playlist, and a new approach to archives WIP: Allow archive format for all single-track file types. Nov 7, 2023
@Wohlstand Wohlstand mentioned this pull request Nov 8, 2023
4 tasks
@myQwil myQwil force-pushed the listable branch 2 times, most recently from 6f6eebd to a12fedf Compare November 9, 2023 07:18
@myQwil myQwil force-pushed the listable branch 2 times, most recently from 1425fe6 to 2763c4f Compare November 10, 2023 03:22
@myQwil myQwil changed the title WIP: Allow archive format for all single-track file types. Allow archive format for all single-track file types. Nov 10, 2023
@myQwil myQwil force-pushed the listable branch 2 times, most recently from 60f68cb to 3eaf0ed Compare November 10, 2023 17:49
@myQwil myQwil force-pushed the listable branch 2 times, most recently from fa19693 to 065a012 Compare November 25, 2023 07:34
gme/gme.h Outdated Show resolved Hide resolved
Allows for creating playlists of single-track file types.
@sezero
Copy link
Contributor

sezero commented Nov 25, 2023

My old compiler (gcc 4.9) emits the following warnings. Maybe you should use explicit initialization like when it was in library code.

In file included from /tmp/libgme/player/Music_Player.cpp:8:0:
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::ArcName' [-Wmissing-field-initializers]
  RARHeaderData head = {};
                        ^
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileName' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::Flags' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::PackSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::UnpSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::HostOS' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileCRC' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileTime' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::UnpVer' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::Method' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileAttr' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtBuf' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtBufSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtState' [-Wmissing-field-initializers]
In file included from /tmp/libgme/player/Archive_Reader.cpp:1:0:
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::ArcName' [-Wmissing-field-initializers]
  RARHeaderData head = {};
                        ^
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileName' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::Flags' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::PackSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::UnpSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::HostOS' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileCRC' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileTime' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::UnpVer' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::Method' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::FileAttr' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtBuf' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtBufSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.h:49:24: warning: missing initializer for member 'RARHeaderData::CmtState' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.cpp: In member function 'virtual const char* Rar_Reader::open(const char*, bool)':
/tmp/libgme/player/Archive_Reader.cpp:31:29: warning: missing initializer for member 'RAROpenArchiveData::ArcName' [-Wmissing-field-initializers]
  RAROpenArchiveData data = {};
                             ^
/tmp/libgme/player/Archive_Reader.cpp:31:29: warning: missing initializer for member 'RAROpenArchiveData::OpenMode' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.cpp:31:29: warning: missing initializer for member 'RAROpenArchiveData::OpenResult' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.cpp:31:29: warning: missing initializer for member 'RAROpenArchiveData::CmtBuf' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.cpp:31:29: warning: missing initializer for member 'RAROpenArchiveData::CmtBufSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.cpp:31:29: warning: missing initializer for member 'RAROpenArchiveData::CmtSize' [-Wmissing-field-initializers]
/tmp/libgme/player/Archive_Reader.cpp:31:29: warning: missing initializer for member 'RAROpenArchiveData::CmtState' [-Wmissing-field-initializers]

@sezero
Copy link
Contributor

sezero commented Nov 25, 2023

Configuration fails if SDL2 is not located:

CMake Warning at player/CMakeLists.txt:3 (find_package):
  By not providing "FindSDL2.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "SDL2", but
  CMake did not find one.

  Could not find a package configuration file provided by "SDL2" with any of
  the following names:

    SDL2Config.cmake
    sdl2-config.cmake

  Add the installation prefix of "SDL2" to CMAKE_PREFIX_PATH or set
  "SDL2_DIR" to a directory containing one of the above files.  If "SDL2"
  provides a separate development package or SDK, be sure it has been
  installed.


-- ** SDL library not found, disabling player demo build
-- UnRAR library located, player demo will support the RAR file format
CMake Error at player/CMakeLists.txt:37 (target_compile_definitions):
  Cannot specify compile definitions for target "gme_player" which is not
  built by this project.


CMake Error at player/CMakeLists.txt:39 (target_compile_definitions):
  Cannot specify compile definitions for target "gme_player" which is not
  built by this project.


CMake Error at player/CMakeLists.txt:43 (target_include_directories):
  Cannot specify include directories for target "gme_player" which is not
  built by this project.


CMake Error at player/CMakeLists.txt:44 (target_link_libraries):
  Cannot specify link libraries for target "gme_player" which is not built by
  this project.


-- Configuring incomplete, errors occurred!

You should move unrar thingies within the SDL2_FOUND block, like the following: (indentation changes not included for clarity)

diff --git a/player/CMakeLists.txt b/player/CMakeLists.txt
index de6eae1..4f894ab 100644
--- a/player/CMakeLists.txt
+++ b/player/CMakeLists.txt
@@ -27,9 +27,6 @@ if(SDL2_FOUND)
     set_property(TARGET gme_player PROPERTY CXX_STANDARD 11)
     target_link_libraries(gme_player PRIVATE ${SDL2_LIBRARIES} gme::gme)
     # Is not to be installed though
-else()
-    message(STATUS "** SDL library not found, disabling player demo build")
-endif()
 
 if(GME_UNRAR)
   if(UNRAR_FOUND)
@@ -54,3 +51,6 @@ else()
   message(STATUS "RAR file format excluded")
 endif()
 
+else()
+    message(STATUS "** SDL library not found, disabling player demo build")
+endif()

@sezero
Copy link
Contributor

sezero commented Nov 25, 2023

My old compiler (gcc 4.9) emits the following warnings. Maybe you should use explicit initialization like when it was in library code.

The following makes it warning-free for me

diff --git a/player/Archive_Reader.cpp b/player/Archive_Reader.cpp
index 75e5a31..db888d9 100644
--- a/player/Archive_Reader.cpp
+++ b/player/Archive_Reader.cpp
@@ -28,7 +28,7 @@ blargg_err_t Rar_Reader::restart( RAROpenArchiveData* data )
 blargg_err_t Rar_Reader::open( const char* path, bool skip )
 {
 	blargg_err_t err;
-	RAROpenArchiveData data = {};
+	RAROpenArchiveData data = { NULL, RAR_OM_LIST, 0, NULL, 0, 0, 0 };
 	data.ArcName = (char *)path;
 
 	// determine space needed for the unpacked size and file count.
diff --git a/player/Archive_Reader.h b/player/Archive_Reader.h
index e385f36..bbc0f01 100644
--- a/player/Archive_Reader.h
+++ b/player/Archive_Reader.h
@@ -46,7 +46,7 @@ public:
 #endif
 
 class Rar_Reader : public Archive_Reader {
-	RARHeaderData head = {};
+	RARHeaderData head;
 	void* rar = nullptr;
 	void* bp = nullptr;
 	blargg_err_t restart( RAROpenArchiveData* );

@myQwil
Copy link
Contributor Author

myQwil commented Nov 25, 2023

I went with memset but other than that, the same changes were applied.

@sezero
Copy link
Contributor

sezero commented Nov 25, 2023

I went with memset but other than that, the same changes were applied.

OK

@sezero
Copy link
Contributor

sezero commented Nov 25, 2023

I'm OK with this (although I didn't valgrind it)

@@ -5,6 +5,8 @@
#include <string.h>
#include <ctype.h>
#include "SDL_rwops.h"
#include "Archive_Reader.h"
#include "Gme_File.h"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it a good idea to use library's private headers here?

As I understand it, you use it for gme_type_t_ details:
Are there no alternatives?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe a function could be added to gme.cpp to perform essentially the same check. i'll look into it

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe something like this? patch.txt

diff --git a/gme/gme.cpp b/gme/gme.cpp
index bb8b52a..6ffccaf 100644
--- a/gme/gme.cpp
+++ b/gme/gme.cpp
@@ -429,3 +429,16 @@ const char* gme_type_system( gme_type_t type )
 	assert( type );
 	return type->system;
 }
+
+int gme_type_trackcnt( gme_type_t type )
+{
+	assert( type );
+	return type->track_count;
+}
+
+int gme_type_same_ctor( gme_type_t a, gme_type_t b )
+{
+	assert( a );
+	assert( b );
+	return a->new_emu == b->new_emu;
+}
diff --git a/gme/gme.exports b/gme/gme.exports
index ea16df7..c9e9ed4 100644
--- a/gme/gme.exports
+++ b/gme/gme.exports
@@ -61,3 +61,5 @@ gme_vgz_type
 gme_disable_echo
 gme_set_fade_msecs
 gme_load_tracks
+gme_type_trackcnt
+gme_type_same_ctor
diff --git a/gme/gme.h b/gme/gme.h
index 89fa4d6..4e3c273 100644
--- a/gme/gme.h
+++ b/gme/gme.h
@@ -232,6 +232,14 @@ BLARGG_EXPORT gme_type_t const* gme_type_list();
 /* Name of game system for this music file type */
 BLARGG_EXPORT const char* gme_type_system( gme_type_t );
 
+/* Number of tracks for format
+ * @since 0.6.4 */
+BLARGG_EXPORT int gme_type_trackcnt( gme_type_t );
+
+/* Whether the formats use the same emulator creator
+ * @since 0.6.4 */
+BLARGG_EXPORT int gme_type_same_ctor( gme_type_t, gme_type_t );
+
 /* True if this music file type supports multiple tracks */
 BLARGG_EXPORT int gme_type_multitrack( gme_type_t );
 
diff --git a/player/Music_Player.cpp b/player/Music_Player.cpp
index 57521ff..4069430 100644
--- a/player/Music_Player.cpp
+++ b/player/Music_Player.cpp
@@ -6,7 +6,6 @@
 #include <ctype.h>
 #include "SDL_rwops.h"
 #include "Archive_Reader.h"
-#include "Gme_File.h"
 
 /* Copyright (C) 2005-2010 by Shay Green. Permission is hereby granted, free of
 charge, to any person obtaining a copy of this software module and associated
@@ -168,12 +167,12 @@ gme_err_t Music_Player::load_file(const char* path , bool by_mem)
 			{ // copy data and file sizes
 				gme_type_t t;
 				RETURN_ERR( in.read( bp ) );
-				if ( (t = gme_identify_extension( in.entry_name() ))
-				&& t->track_count == 1 )
+				if ((t = gme_identify_extension(in.entry_name())) != nullptr &&
+				    gme_type_trackcnt(t) == 1 )
 				{
 					if ( !emu_type )
 						emu_type = t;
-					if ( t->new_emu == emu_type->new_emu )
+					if ( gme_type_same_ctor(t, emu_type) )
 						bp += (sizes[n++] = in.entry_size());
 				}
 			}

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now, we can leave out the constructor comparison. That won't be useful until we can properly read .vgz files inside of an archive, if that ever ends up happening.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

Copy link
Contributor

@sezero sezero left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, this should be good. valgrind is happy too, so it's OK by me for 0.6.4 release.

@sezero sezero added this to the Release 0.6.4 milestone Nov 26, 2023
@sezero
Copy link
Contributor

sezero commented Mar 21, 2024

@Wohlstand : Will this get in ?

@Wohlstand
Copy link
Collaborator

Going to merge in this evening. I want to take a deeper look first.

@Wohlstand
Copy link
Collaborator

Wohlstand commented Mar 23, 2024

I tested out the thing, it works good, but, it can't open VGZ (GZ-compressed) files loaded via the gme_load_tracks call.

  • test.zip - works, all files are decompressed VGMs
  • test-vgz.zip - fails, all files are compressed VGZs

But, this is more problem of the gme_load_tracks() call and not of this thing. This thing works flawless! I going to check the code and I'll merge this soon.

EDIT: Okay, I see the gme_load_tracks() is a new thing here. And ye, if you want to read GZipped files like VGZ, you should decompress the memory block by Mem_File_Reader class which is already used here. I did a small attempt to fix the problem and I almost fixed it, but now I feel sleepy, so, I'll try some tomorrow by myself, but if you fix the ZIPped VGZs faster, I'll just test out that.

@Wohlstand
Copy link
Collaborator

Oh wait, I actually had an old copy of the PR state, now I refreshed it, and I see the libarchive support has gone 👀 Anyway, repacking these files into RAR, the problem is the same: VGM files gets played, but VGZ aren't.

@Wohlstand
Copy link
Collaborator

Updated tests:
test-rar-archives.zip

@myQwil
Copy link
Contributor Author

myQwil commented Mar 23, 2024

Sorry about that. I probably should have updated my first comment saying that some stuff had been taken out. If you got it to work with VGZ files, feel free to put libarchive support back in.

@sezero
Copy link
Contributor

sezero commented Mar 25, 2024

As far as I can see the purpose of this patch is supporting playback of rsn files (actually moving the existing rsn support from library side to player side), and not playback of vgz files embedded in rar archives. The latter should come later in a new patchset, in my opinion.

Copy link
Collaborator

@Wohlstand Wohlstand left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, I think, it's ready to merge, anything also can be tweaked later in any time then.

@Wohlstand Wohlstand merged commit c2c3157 into libgme:master Mar 27, 2024
9 checks passed
@mmontag
Copy link

mmontag commented Jul 1, 2024

Do I understand correctly that building RSN/RAR support is optional? Thank you for doing this.

@Wohlstand
Copy link
Collaborator

Do I understand correctly that building RSN/RAR support is optional? Thank you for doing this.

Absolutely!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants