Initial public source release

Split reusable rendering and format support into vectorail-core and vectorail-gc.
This commit is contained in:
2026-08-02 17:05:27 +02:00
commit 831d96e562
109 changed files with 20558 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
Version PARSE_VER = Version::GC4;
struct Item {
u32 id;
string texture;
string unk2; // Name?
u8 unk3;
string descriptionJP;
string descriptionEN;
};
u16 itemCount @ 0x00;
Item items[itemCount] @ 0x02 [[inline]];
+32
View File
@@ -0,0 +1,32 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
Version PARSE_VER = Version::GC4;
struct Message {
u32 id;
string texture;
string unk1;
u8 unk2;
string unk3; // Contents
string unk4; // Contents
bool unk5;
bool unk6;
};
u16 messageCount @ 0x00;
Message messages[messageCount] @ 0x02 [[inline]];
+46
View File
@@ -0,0 +1,46 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
Version PARSE_VER = Version::GC4;
struct Navigator {
u32 id;
string texture; // /data/2d_boost/navigator/<name>.dds
string unk2;
string unk3;
string unk4;
string unk5;
string unk6;
string unk7;
string unk8;
string unk9;
string unk10;
u8 unk11;
u8 unk12;
u8 unk13;
u8 unk14;
u32 unk15;
u32 unk16;
u8 unk17;
u8 unk18;
u8 unk19;
string descriptionJP;
string descriptionEN;
};
u16 navigatorCount @ 0x00;
Navigator navigators[navigatorCount] @ 0x02 [[inline]];
+47
View File
@@ -0,0 +1,47 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
Version PARSE_VER = Version::GC4;
struct Player {
u32 id;
string texture; // /data/2d_boost/avatar/<name>.dds
string unk2;
string unk3;
string unk4;
string unk5;
string unk6;
string unk7;
u8 unk8;
string unk9; // /data/model/<name> - pngs only
string unk10; // /data/model/<name> - uvb/tumo files
string unk11; // /data/model/<name> - tusc/efcb2 files
u32 unk12;
u32 unk13;
u8 unk14;
u32 unk15;
u32 unk16;
u32 unk17;
u32 unk18;
u8 unk19;
string descriptionJP;
string descriptionEN;
u32 unk22;
};
u16 playerCount @ 0x00;
Player players[playerCount] @ 0x02 [[inline]];
+35
View File
@@ -0,0 +1,35 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
Version PARSE_VER = Version::GC4;
struct SE {
u32 id;
string texture;
string unk2; // Name long?
string unk3; // Name short?
string unk4;
string se_name1; // /data/sound/<name>.wav
string se_name2;
string se_name3;
u8 unk8;
string descriptionJP;
string descriptionEN;
};
u16 seCount @ 0x00;
SE ses[seCount] @ 0x02 [[inline]];
+31
View File
@@ -0,0 +1,31 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
Version PARSE_VER = Version::GC4;
struct Skin {
u32 id;
string texture;
string unk2;
string skinFolder;
u8 unk4;
string descriptionJP;
string descriptionEN;
};
u16 skinCount @ 0x00;
Skin skins[skinCount] @ 0x02 [[inline]];
+197
View File
@@ -0,0 +1,197 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
enum Genre_New : u8 {
GENRE_UNKNOWN = 0,
GENRE_ANIME_POP,
GENRE_VOCALOID,
GENRE_OTOGE,
GENRE_GAME,
GENRE_VARIETY,
GENRE_ORIGINAL,
GENRE_TOUHOU
};
enum Genre_GC2 : u8 {
GENRE_GC2_UNKNOWN = 0,
GENRE_GC2_POPS,
GENRE_GC2_VOCALOID,
GENRE_GC2_GAME,
GENRE_GC2_VARIETY,
GENRE_GC2_ORIGINAL,
GENRE_GC2_ANIME,
GENRE_GC2_TOUHOU
};
enum Genre_GC1 : u8 {
GENRE_GC1_UNKNOWN = 0,
GENRE_GC1_ANIME_POP,
GENRE_GC1_VOCALOID,
GENRE_GC1_GAME, // Rhythm games and touhou are merged into this in GC1
GENRE_GC1_VARIETY,
GENRE_GC1_ORIGINAL
};
enum SKIN : u8 {
SKIN_NONE = 0,
SKIN_BASIC,
SKIN_FLOWER,
SKIN_FIREWORKS,
SKIN_MARBLES,
SKIN_MIDCENTURY,
SKIN_INFINITYGENE,
SKIN_MOLECULE,
SKIN_BUTTERFLY,
SKIN_PAISLEY,
SKIN_8BIT,
SKIN_BRIGHTNESS,
SKIN_HOLOGRAM,
SKIN_HEAVEN,
SKIN_SNOW,
SKIN_FEATHER,
SKIN_NOTE,
SKIN_STAR,
SKIN_HORROR,
SKIN_HEART,
SKIN_SYNCHRONICA
};
enum SongFlag : u8 {
NONE = 0,
TUTORIAL = 1,
GC1_CREDITS = 2,
SHOW_CATEGORY = 3,
GC2_CREDITS = 4,
TUTORIAL_JP = 5,
TUTORIAL_EN_RV = 6,
TUTORIAL_EN_GC = 7,
GC3_CREDITS = 8,
GC3EX_CREDITS = 9,
GC4_CREDITS = 10,
};
struct Song {
u32 id;
string name;
string ident;
string artist;
if (PARSE_VER >= Version::GC2)
string extraInfo;
string yomigana;
if (PARSE_VER <= Version::GC1EX)
Genre_GC1 genre;
else if (PARSE_VER == Version::GC2)
Genre_GC2 genre;
else
Genre_New genre;
string duration;
u8 diffSimple;
u8 diffNormal;
u8 diffHard;
if (PARSE_VER > Version::GC1) u8 diffExtra;
string bpm;
if (PARSE_VER == Version::GC1) {
u32 unk1; // TODO: Maybe look what this is?
} else if (PARSE_VER == Version::GC1EX) {
// TODO: for 1EX one of these needs to have [4] otherise shit gets fucked
u8 bgmVolume[4];
u8 shotVolume;
} else {
u8 bgmVolume[4];
u8 shotVolume[4];
}
if (PARSE_VER <= Version::GC1EX) u32 unk2;
if (PARSE_VER >= Version::GC2) {
u16 unk3;
u16 unk4;
}
u32 previewSeekStartMillis;
u32 previewSeekEndMillis;
SKIN defaultSkin;
SongFlag specialFlags; // TODO: Implement the enum
string bgmFilePrefix;
// TODO: Rework this a bit
if (PARSE_VER == Version::GC1) {
string stageFilenameSimple;
string stageFilenameNormal;
string stageFilenameHard;
string bgmFilenameSuffixSimple;
string bgmFilenameSuffixNormal;
string bgmFilenameSuffixHard;
} else if (PARSE_VER == Version::GC1EX) {
if (id != 999) {
string shotFilenameSuffixSimple;
string shotFilenameSuffixNormal;
string shotFilenameSuffixHard;
string shotFilenameSuffixExtra;
}
string stageFilenameSimple;
string stageFilenameNormal;
string stageFilenameHard;
string stageFilenameExtra;
string bgmFilenameSuffixSimple;
string bgmFilenameSuffixNormal;
string bgmFilenameSuffixHard;
string bgmFilenameSuffixExtra;
} else {
string bgmFilenameSuffixSimple;
string bgmFilenameSuffixNormal;
string bgmFilenameSuffixHard;
string bgmFilenameSuffixExtra;
string shotFilenameSuffixSimple;
string shotFilenameSuffixNormal;
string shotFilenameSuffixHard;
string shotFilenameSuffixExtra;
string stageFilenameSimple;
string stageFilenameNormal;
string stageFilenameHard;
string stageFilenameExtra;
}
if (PARSE_VER >= Version::GC2) {
string stageRegionSuffix;
u32 judgeDelay; // TODO: Confirm
}
if (PARSE_VER == Version::GC1EX) u8 musicPanelCost;
u8 unlockable; // definitely a bool, seems to dictate whether server unlocks work
u8 songEnabled;
u8 unk7;
if (PARSE_VER == Version::GC4) u8 isRecommended;
} [[format("song_formatter")]];
fn song_formatter(ref Song s) {
return std::format("{} {}: ({})", s.id, s.ident, s.name);
};
Version PARSE_VER = Version::GC1EX;
u16 songCount @ 0x00;
Song songs[songCount] @ 0x02 [[inline]];
+40
View File
@@ -0,0 +1,40 @@
#pragma endian big
import std.io;
import std.string;
using string = std::string::SizedString<u8> [[format("string_formatter")]];
fn string_formatter(ref string s) {
return std::format("\"{:s}\"", s);
};
enum Version : u8 {
GC1 = 1,
GC1EX = 2,
GC2 = 3,
GC3 = 4,
GC4 = 5,
};
Version PARSE_VER = Version::GC4;
struct Title {
u32 id;
string texture;
string textureSuffixEn;
string textJP;
string textEN;
u8 unk5;
string descriptionJP;
string descriptionEN;
string unk6; // Also descriptions, maybe for next title?
string unk7; // ^
u8 unk8;
u8 unk9;
u8 unk10;
u8 unk11;
u8 unk12;
u8 unk13;
};
u16 titleCount @ 0x00;
Title titles[titleCount] @ 0x02 [[inline]];