forked from tsuki/openroller
Initial public source release
Split reusable rendering and format support into vectorail-core and vectorail-gc.
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace openroller::psp {
|
||||
|
||||
constexpr char kSongCatalogMagic[4] = {'O', 'R', 'P', 'C'};
|
||||
constexpr std::uint16_t kSongCatalogVersion = 1;
|
||||
constexpr std::uint32_t kMaximumCatalogSongs = 64;
|
||||
|
||||
struct SongCatalogHeader {
|
||||
char magic[4]{};
|
||||
std::uint16_t version = 0;
|
||||
std::uint16_t headerSize = 0;
|
||||
std::uint32_t fileSize = 0;
|
||||
std::uint32_t songCount = 0;
|
||||
std::uint32_t recordSize = 0;
|
||||
std::uint32_t reserved[3]{};
|
||||
};
|
||||
|
||||
struct SongCatalogRecord {
|
||||
char key[32]{};
|
||||
char title[64]{};
|
||||
char artist[48]{};
|
||||
char duration[8]{};
|
||||
char bpm[16]{};
|
||||
std::uint8_t genre = 0;
|
||||
std::uint8_t availableMask = 0;
|
||||
std::uint8_t ratings[4]{};
|
||||
std::uint8_t reserved[2]{};
|
||||
};
|
||||
|
||||
constexpr char kJacketMagic[4] = {'O', 'R', 'P', 'J'};
|
||||
constexpr std::uint16_t kJacketVersion = 1;
|
||||
|
||||
struct JacketHeader {
|
||||
char magic[4]{};
|
||||
std::uint16_t version = 0;
|
||||
std::uint16_t width = 0;
|
||||
std::uint16_t height = 0;
|
||||
std::uint16_t pixelFormat = 0; // 0 = PSP GU_PSM_4444
|
||||
std::uint32_t dataSize = 0;
|
||||
};
|
||||
|
||||
static_assert(sizeof(SongCatalogHeader) == 32);
|
||||
static_assert(sizeof(SongCatalogRecord) == 176);
|
||||
static_assert(sizeof(JacketHeader) == 16);
|
||||
|
||||
} // namespace openroller::psp
|
||||
@@ -0,0 +1,242 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace openroller::psp {
|
||||
|
||||
constexpr char kStagePackageMagic[4] = {'O', 'R', 'P', 'S'};
|
||||
constexpr std::uint16_t kStagePackageVersion = 4;
|
||||
|
||||
enum class PackageDifficulty : std::uint32_t {
|
||||
Easy = 0,
|
||||
Normal = 1,
|
||||
Hard = 2,
|
||||
Extra = 3,
|
||||
};
|
||||
|
||||
constexpr std::uint32_t kStageDifficultyMask = 0x3u;
|
||||
constexpr std::uint32_t kMaximumPackageBackgroundObjects = 1024u;
|
||||
|
||||
struct PackageSection {
|
||||
std::uint32_t offset = 0;
|
||||
std::uint32_t count = 0;
|
||||
};
|
||||
|
||||
struct PackageRange {
|
||||
std::uint32_t first = 0;
|
||||
std::uint32_t count = 0;
|
||||
};
|
||||
|
||||
// All package data is little-endian. Every section begins at a 16-byte
|
||||
// boundary so it can be read directly into PSP-friendly arrays.
|
||||
struct StagePackageHeader {
|
||||
char magic[4]{};
|
||||
std::uint16_t version = 0;
|
||||
std::uint16_t headerSize = 0;
|
||||
std::uint32_t fileSize = 0;
|
||||
std::uint32_t flags = 0;
|
||||
std::uint32_t durationMs = 0;
|
||||
std::uint32_t audioOffsetRaw = 0;
|
||||
float visualOffset = 0.0f;
|
||||
float greatMinimumTimeMs = 32.0f;
|
||||
float scratchEnableTimeMs = 250.0f;
|
||||
float beatEnableTimeMs = 200.0f;
|
||||
float backwardsDrawDistance = 0.0f;
|
||||
float forwardDrawDistance = 0.0f;
|
||||
std::uint32_t trackAheadRgba = 0;
|
||||
std::uint32_t trackBehindRgba = 0;
|
||||
PackageSection track;
|
||||
PackageSection notes;
|
||||
PackageSection cameras;
|
||||
PackageSection drawDistances;
|
||||
PackageSection backgroundColors;
|
||||
PackageSection backgroundModels;
|
||||
PackageSection backgroundVertices;
|
||||
PackageSection backgroundObjects;
|
||||
PackageSection visibilityKeys;
|
||||
PackageSection transformKeys;
|
||||
PackageSection objectColorKeys;
|
||||
PackageSection particles;
|
||||
PackageSection visualizer;
|
||||
PackageSection bpmChanges;
|
||||
};
|
||||
|
||||
struct PackageTrackPoint {
|
||||
std::uint32_t timeMs = 0;
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
};
|
||||
|
||||
enum PackageNoteFlags : std::uint8_t {
|
||||
kNoteTypeOverride = 1u << 0,
|
||||
kNoteFlag24 = 1u << 1,
|
||||
kNoteFlag37 = 1u << 2,
|
||||
kNoteFlag38 = 1u << 3,
|
||||
};
|
||||
|
||||
// This is the original note payload normalized to little-endian and with its
|
||||
// four single-byte flags packed into one byte. Unknown values are retained so
|
||||
// later reverse-engineering does not require rebuilding the source parser.
|
||||
struct PackageNote {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint8_t type = 0;
|
||||
std::uint8_t flags = 0;
|
||||
std::int16_t params16[9]{};
|
||||
float params25[3]{};
|
||||
float params39[4]{};
|
||||
std::uint32_t params55[3]{};
|
||||
float param67 = 0.0f;
|
||||
std::uint32_t param71 = 0;
|
||||
float params75[5]{};
|
||||
std::uint32_t param95 = 0;
|
||||
|
||||
// Values produced by the original BuildTimingDataSub path. Keeping these
|
||||
// in the host-built package avoids duplicating chart/config resolution on
|
||||
// the PSP and makes its runtime consume the same semantics as desktop.
|
||||
std::uint8_t effectiveType = 0;
|
||||
std::uint8_t reserved = 0;
|
||||
std::int16_t markEffectId = -1;
|
||||
float appearTimeMs = 0.0f;
|
||||
float endTimeMs = 0.0f;
|
||||
float directionVector[3]{};
|
||||
float beatDurationMs = 500.0f;
|
||||
float earlyTimingMs = 250.0f;
|
||||
float lateTimingMs = 250.0f;
|
||||
float missTimingMs = 250.0f;
|
||||
float muteTimingMs = 0.0f;
|
||||
float markerFadeEndTimeMs = 0.0f;
|
||||
std::uint32_t packedColor = 0xffffffffu;
|
||||
std::uint32_t merryCount = 0;
|
||||
};
|
||||
|
||||
struct PackageCameraPoint {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint8_t aMode = 0;
|
||||
std::uint8_t fMode = 0;
|
||||
std::uint8_t projectionType = 0;
|
||||
std::uint8_t reserved = 0;
|
||||
float distance = 0.0f;
|
||||
float rotationA[2]{};
|
||||
float originOffset[3]{};
|
||||
float fieldFar[3]{};
|
||||
float fieldNear[3]{};
|
||||
float rotationB = 0.0f;
|
||||
};
|
||||
|
||||
struct PackageDrawDistancePoint {
|
||||
std::uint32_t timeMs = 0;
|
||||
float distance = 0.0f;
|
||||
};
|
||||
|
||||
struct PackageBackgroundColorPoint {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint32_t topRightRgba = 0;
|
||||
std::uint32_t topLeftRgba = 0;
|
||||
std::uint32_t bottomRightRgba = 0;
|
||||
std::uint32_t bottomLeftRgba = 0;
|
||||
std::uint32_t flags = 0;
|
||||
};
|
||||
|
||||
struct PackageBackgroundModel {
|
||||
PackageRange triangles;
|
||||
PackageRange solidLines;
|
||||
PackageRange wireframeLines;
|
||||
};
|
||||
|
||||
struct PackageBackgroundVertex {
|
||||
float x = 0.0f;
|
||||
float y = 0.0f;
|
||||
float z = 0.0f;
|
||||
};
|
||||
|
||||
enum PackageBackgroundObjectFlags : std::uint32_t {
|
||||
kBackgroundObjectWireframe = 1u << 0,
|
||||
kBackgroundObjectFlashing = 1u << 1,
|
||||
kBackgroundObjectUnknown = 1u << 2,
|
||||
};
|
||||
|
||||
struct PackageBackgroundObject {
|
||||
std::uint32_t model = 0;
|
||||
std::int32_t parentIndex = -1;
|
||||
std::uint32_t flags = 0;
|
||||
std::uint32_t fragmentShader = 0;
|
||||
float position[3]{};
|
||||
float scale[3]{1.0f, 1.0f, 1.0f};
|
||||
float rotation[3]{};
|
||||
float color[4]{1.0f, 1.0f, 1.0f, 1.0f};
|
||||
PackageRange visibility;
|
||||
PackageRange movement;
|
||||
PackageRange scaling;
|
||||
PackageRange rotations;
|
||||
PackageRange colorChanges;
|
||||
};
|
||||
|
||||
enum PackageObjectKeyFlags : std::uint8_t {
|
||||
kObjectKeyLoop = 1u << 0,
|
||||
kObjectKeyInterpolate = 1u << 1,
|
||||
};
|
||||
|
||||
struct PackageVisibilityKey {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint8_t flags = 0;
|
||||
std::uint8_t visible = 0;
|
||||
std::uint16_t reserved = 0;
|
||||
};
|
||||
|
||||
struct PackageTransformKey {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint8_t flags = 0;
|
||||
std::uint8_t reserved[3]{};
|
||||
float value[3]{};
|
||||
};
|
||||
|
||||
struct PackageObjectColorKey {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint8_t flags = 0;
|
||||
std::uint8_t reserved[3]{};
|
||||
std::uint32_t rgba = 0;
|
||||
};
|
||||
|
||||
struct PackageParticlePoint {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint32_t enabled = 0;
|
||||
std::uint32_t shape = 0;
|
||||
std::uint32_t texture = 0;
|
||||
std::uint32_t rgba = 0;
|
||||
float velocity[3]{};
|
||||
float repeatMeasure = 0.0f;
|
||||
float lifespanMeasure = 0.0f;
|
||||
std::uint32_t groupShapeSize = 0;
|
||||
};
|
||||
|
||||
struct PackageVisualizerPoint {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint32_t type = 0;
|
||||
std::uint32_t rgba = 0;
|
||||
};
|
||||
|
||||
struct PackageBpmPoint {
|
||||
std::uint32_t timeMs = 0;
|
||||
std::uint32_t bpm = 120;
|
||||
};
|
||||
|
||||
static_assert(sizeof(PackageSection) == 8);
|
||||
static_assert(sizeof(PackageRange) == 8);
|
||||
static_assert(sizeof(StagePackageHeader) == 168);
|
||||
static_assert(sizeof(PackageTrackPoint) == 16);
|
||||
static_assert(sizeof(PackageNote) == 152);
|
||||
static_assert(sizeof(PackageCameraPoint) == 60);
|
||||
static_assert(sizeof(PackageDrawDistancePoint) == 8);
|
||||
static_assert(sizeof(PackageBackgroundColorPoint) == 24);
|
||||
static_assert(sizeof(PackageBackgroundModel) == 24);
|
||||
static_assert(sizeof(PackageBackgroundVertex) == 12);
|
||||
static_assert(sizeof(PackageBackgroundObject) == 108);
|
||||
static_assert(sizeof(PackageVisibilityKey) == 8);
|
||||
static_assert(sizeof(PackageTransformKey) == 20);
|
||||
static_assert(sizeof(PackageObjectColorKey) == 12);
|
||||
static_assert(sizeof(PackageParticlePoint) == 44);
|
||||
static_assert(sizeof(PackageVisualizerPoint) == 12);
|
||||
static_assert(sizeof(PackageBpmPoint) == 8);
|
||||
|
||||
} // namespace openroller::psp
|
||||
Reference in New Issue
Block a user