mirror of https://github.com/zeldaret/tmc.git
Fix clang warnings and remove remaining baserom references
This commit is contained in:
parent
74e416b578
commit
db763950bb
46
Makefile
46
Makefile
|
@ -272,49 +272,3 @@ demo_usa: ; @$(MAKE) GAME_VERSION=DEMO_USA
|
||||||
jp: ; @$(MAKE) GAME_VERSION=JP
|
jp: ; @$(MAKE) GAME_VERSION=JP
|
||||||
demo_jp: ; @$(MAKE) GAME_VERSION=DEMO_JP
|
demo_jp: ; @$(MAKE) GAME_VERSION=DEMO_JP
|
||||||
eu: ; @$(MAKE) GAME_VERSION=EU
|
eu: ; @$(MAKE) GAME_VERSION=EU
|
||||||
|
|
||||||
ifeq ($(GAME_VERSION), USA)
|
|
||||||
baserom.gba:
|
|
||||||
$(error "You need to provide a USA ROM as baserom.gba")
|
|
||||||
.PHONY: baserom_demo.gba baserom_jp.gba baserom_eu.gba baserom_demo_jp.gba
|
|
||||||
baserom_demo.gba:
|
|
||||||
baserom_jp.gba:
|
|
||||||
baserom_eu.gba:
|
|
||||||
baserom_demo_jp.gba:
|
|
||||||
endif
|
|
||||||
ifeq ($(GAME_VERSION), DEMO_USA)
|
|
||||||
baserom_demo.gba:
|
|
||||||
$(error "You need to provide a DEMO ROM as baserom_demo.gba")
|
|
||||||
.PHONY: baserom_jp.gba baserom_eu.gba baserom.gba baserom_demo_jp.gba
|
|
||||||
baserom.gba:
|
|
||||||
baserom_jp.gba:
|
|
||||||
baserom_eu.gba:
|
|
||||||
baserom_demo_jp.gba:
|
|
||||||
endif
|
|
||||||
ifeq ($(GAME_VERSION), JP)
|
|
||||||
baserom_jp.gba:
|
|
||||||
$(error "You need to provide a JP ROM as baserom_jp.gba")
|
|
||||||
.PHONY: baserom_demo.gba baserom_eu.gba baserom.gba baserom_demo_jp.gba
|
|
||||||
baserom.gba:
|
|
||||||
baserom_demo.gba:
|
|
||||||
baserom_eu.gba:
|
|
||||||
baserom_demo_jp.gba:
|
|
||||||
endif
|
|
||||||
ifeq ($(GAME_VERSION), DEMO_JP)
|
|
||||||
baserom_demo_jp.gba:
|
|
||||||
$(error "You need to provide a DEMO JP ROM as baserom_demo_jp.gba")
|
|
||||||
.PHONY: baserom_jp.gba baserom_eu.gba baserom.gba baserom_demo.gba
|
|
||||||
baserom.gba:
|
|
||||||
baserom_jp.gba:
|
|
||||||
baserom_eu.gba:
|
|
||||||
baserom_demo.gba:
|
|
||||||
endif
|
|
||||||
ifeq ($(GAME_VERSION), EU)
|
|
||||||
baserom_eu.gba:
|
|
||||||
$(error "You need to provide a EU ROM as baserom_eu.gba")
|
|
||||||
.PHONY: baserom_demo.gba baserom.gba baserom_jp.gba baserom_demo_jp.gba
|
|
||||||
baserom.gba:
|
|
||||||
baserom_jp.gba:
|
|
||||||
baserom_demo.gba:
|
|
||||||
baserom_demo_jp.gba:
|
|
||||||
endif
|
|
||||||
|
|
|
@ -21023,6 +21023,21 @@
|
||||||
"start": 752492,
|
"start": 752492,
|
||||||
"size": 8
|
"size": 8
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "data_080B7B74/gCollisionMtx.bin",
|
||||||
|
"start": 752500,
|
||||||
|
"size": 1210
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "data_080B7B74/gUnk_080B802E.bin",
|
||||||
|
"start": 753710,
|
||||||
|
"size": 8850
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "data_080B7B74/gUnk_080BA2C0.bin",
|
||||||
|
"start": 762560,
|
||||||
|
"size": 4064
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "data_080B7B74/gUnk_080B7B74_1_EU.bin",
|
"path": "data_080B7B74/gUnk_080B7B74_1_EU.bin",
|
||||||
"variants": [
|
"variants": [
|
||||||
|
@ -42724,6 +42739,36 @@
|
||||||
"start": 1164390,
|
"start": 1164390,
|
||||||
"size": 34
|
"size": 34
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "demo/save1.bin",
|
||||||
|
"starts": {
|
||||||
|
"DEMO_USA": 1171472
|
||||||
|
},
|
||||||
|
"size": 1280,
|
||||||
|
"variants": [
|
||||||
|
"DEMO_USA"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "demo/save2.bin",
|
||||||
|
"starts": {
|
||||||
|
"DEMO_USA": 1172752
|
||||||
|
},
|
||||||
|
"size": 1280,
|
||||||
|
"variants": [
|
||||||
|
"DEMO_USA"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "demo/save3.bin",
|
||||||
|
"starts": {
|
||||||
|
"DEMO_USA": 1174032
|
||||||
|
},
|
||||||
|
"size": 1280,
|
||||||
|
"variants": [
|
||||||
|
"DEMO_USA"
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"offsets": {
|
"offsets": {
|
||||||
"DEMO_USA": 2572,
|
"DEMO_USA": 2572,
|
||||||
|
@ -48401,6 +48446,12 @@
|
||||||
"size": 60,
|
"size": 60,
|
||||||
"type": "animation"
|
"type": "animation"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"path": "animations/gSpriteAnimations_TorchTrapProjectile_0_0.bin",
|
||||||
|
"start": 1221600,
|
||||||
|
"size": 20,
|
||||||
|
"type": "animation"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"path": "animations/gSpriteAnimations_TorchTrapProjectile_1_0.bin",
|
"path": "animations/gSpriteAnimations_TorchTrapProjectile_1_0.bin",
|
||||||
"start": 1221628,
|
"start": 1221628,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
gSpriteAnimations_TorchTrapProjectile_0_0:: @ 0812A3E0
|
gSpriteAnimations_TorchTrapProjectile_0_0:: @ 0812A3E0
|
||||||
.incbin "baserom.gba", 0x12A3E0, 0x0000014
|
.include "animations/gSpriteAnimations_TorchTrapProjectile_0_0.s"
|
||||||
|
|
||||||
gSpriteAnimations_TorchTrapProjectile_0:: @ 0812A3F4
|
gSpriteAnimations_TorchTrapProjectile_0:: @ 0812A3F4
|
||||||
.4byte gSpriteAnimations_TorchTrapProjectile_0_0
|
.4byte gSpriteAnimations_TorchTrapProjectile_0_0
|
||||||
|
|
|
@ -5,13 +5,13 @@
|
||||||
.align 2
|
.align 2
|
||||||
|
|
||||||
gCollisionMtx:: @ 080B7B74
|
gCollisionMtx:: @ 080B7B74
|
||||||
.incbin "baserom.gba", 0x0B7B74, 0x00004BA
|
.incbin "data_080B7B74/gCollisionMtx.bin"
|
||||||
|
|
||||||
gUnk_080B802E:: @ 080B802E
|
gUnk_080B802E:: @ 080B802E
|
||||||
.incbin "baserom.gba", 0x0B802E, 0x0002292
|
.incbin "data_080B7B74/gUnk_080B802E.bin"
|
||||||
|
|
||||||
gUnk_080BA2C0:: @ 080BA2C0
|
gUnk_080BA2C0:: @ 080BA2C0
|
||||||
.incbin "baserom.gba", 0x0BA2C0, 0x0000FE0
|
.incbin "data_080B7B74/gUnk_080BA2C0.bin"
|
||||||
|
|
||||||
gUnk_080BB2A0:: @ 080BB2A0
|
gUnk_080BB2A0:: @ 080BB2A0
|
||||||
.ifdef EU
|
.ifdef EU
|
||||||
|
|
|
@ -59,9 +59,9 @@ static SaveResult (*const sSaveHandlers[])(u32) = { HandleSaveInit, HandleSaveIn
|
||||||
#if defined(DEMO_USA) || defined(DEMO_JP)
|
#if defined(DEMO_USA) || defined(DEMO_JP)
|
||||||
|
|
||||||
#ifdef DEMO_USA
|
#ifdef DEMO_USA
|
||||||
asm("demoPointer1: .incbin \"baserom_demo.gba\", 0x11e010, 0x500");
|
asm("demoPointer1: .incbin \"demo/save1.bin\"");
|
||||||
asm("demoPointer2: .incbin \"baserom_demo.gba\", 0x11e510, 0x500");
|
asm("demoPointer2: .incbin \"demo/save2.bin\"");
|
||||||
asm("demoPointer3: .incbin \"baserom_demo.gba\", 0x11ea10, 0x500");
|
asm("demoPointer3: .incbin \"demo/save3.bin\"");
|
||||||
|
|
||||||
extern const u8 demoPointer1[];
|
extern const u8 demoPointer1[];
|
||||||
extern const u8 demoPointer2[];
|
extern const u8 demoPointer2[];
|
||||||
|
|
|
@ -44,20 +44,12 @@ void Seek(long offset);
|
||||||
|
|
||||||
std::vector<std::uint32_t> trackPointers;
|
std::vector<std::uint32_t> trackPointers;
|
||||||
|
|
||||||
/*const int FILE_OFFSET = 0x10000;
|
|
||||||
// const int START_OFFSET = 0x1c;
|
|
||||||
const int START_OFFSET = 0x2DE4;
|
|
||||||
const int REDUCE_POINTERS = 0;*/
|
|
||||||
|
|
||||||
const int FILE_OFFSET = 0;
|
|
||||||
const int START_OFFSET = 0xDE38F0;
|
|
||||||
const unsigned int REDUCE_POINTERS = 0x8000000;
|
const unsigned int REDUCE_POINTERS = 0x8000000;
|
||||||
|
|
||||||
extern int g_fileStartOffset; // TODO move to header
|
extern int g_fileStartOffset; // TODO move to header
|
||||||
|
|
||||||
void ReadAgbSong() {
|
void ReadAgbSong() {
|
||||||
|
Seek(g_fileStartOffset);
|
||||||
Seek(FILE_OFFSET + g_fileStartOffset);
|
|
||||||
|
|
||||||
int numTracks = ReadInt8();
|
int numTracks = ReadInt8();
|
||||||
int numBlocks = ReadInt8();
|
int numBlocks = ReadInt8();
|
||||||
|
@ -101,7 +93,6 @@ std::vector<std::vector<Event>> trackEvents;
|
||||||
std::vector<Event> metaEvents;
|
std::vector<Event> metaEvents;
|
||||||
|
|
||||||
int convertTime(int time) {
|
int convertTime(int time) {
|
||||||
// event.time = (24 * g_clocksPerBeat * event.time) / g_midiTimeDiv;
|
|
||||||
return ((float)time * g_midiTimeDiv) / (24 * g_clocksPerBeat);
|
return ((float)time * g_midiTimeDiv) / (24 * g_clocksPerBeat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,19 +103,13 @@ std::uint32_t GetCurrentPtr() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t PtrToFileAddr(std::uint32_t ptr) {
|
std::uint32_t PtrToFileAddr(std::uint32_t ptr) {
|
||||||
return ptr + FILE_OFFSET - REDUCE_POINTERS;
|
return ptr - REDUCE_POINTERS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertAtCorrectTimeFromEnd(std::vector<Event>& events, const Event& event) {
|
void insertAtCorrectTimeFromEnd(std::vector<Event>& events, const Event& event) {
|
||||||
// std::printf("time: %d\n", event.time);
|
|
||||||
for (auto it = events.rbegin(); it != events.rend(); it++) {
|
for (auto it = events.rbegin(); it != events.rend(); it++) {
|
||||||
if ((*it).time <= event.time) {
|
if ((*it).time <= event.time) {
|
||||||
events.insert(it.base(), event);
|
events.insert(it.base(), event);
|
||||||
|
|
||||||
/* for (const auto& event : events) {
|
|
||||||
std::printf("e: %X t: %d\n", (int)event.type, event.time);
|
|
||||||
}
|
|
||||||
std::cin.ignore();*/
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,15 +117,9 @@ void insertAtCorrectTimeFromEnd(std::vector<Event>& events, const Event& event)
|
||||||
}
|
}
|
||||||
|
|
||||||
void insertAtCorrectTimeFromStart(std::vector<Event>& events, const Event& event) {
|
void insertAtCorrectTimeFromStart(std::vector<Event>& events, const Event& event) {
|
||||||
// std::printf("time: %d\n", event.time);
|
|
||||||
for (auto it = events.begin(); it != events.end(); it++) {
|
for (auto it = events.begin(); it != events.end(); it++) {
|
||||||
if ((*it).time >= event.time) {
|
if ((*it).time >= event.time) {
|
||||||
events.insert(it, event);
|
events.insert(it, event);
|
||||||
|
|
||||||
/* for (const auto& event : events) {
|
|
||||||
std::printf("e: %X t: %d\n", (int)event.type, event.time);
|
|
||||||
}
|
|
||||||
std::cin.ignore();*/
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -149,9 +128,6 @@ void insertAtCorrectTimeFromStart(std::vector<Event>& events, const Event& event
|
||||||
|
|
||||||
void ReadAgbTracks() {
|
void ReadAgbTracks() {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int addedPadding = 8;
|
int addedPadding = 8;
|
||||||
|
|
||||||
// TODO configurable???
|
// TODO configurable???
|
||||||
|
@ -168,11 +144,10 @@ void ReadAgbTracks() {
|
||||||
for (uint32_t trackPointer : trackPointers) {
|
for (uint32_t trackPointer : trackPointers) {
|
||||||
|
|
||||||
std::vector<Event> events;
|
std::vector<Event> events;
|
||||||
count ++;
|
count++;
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("\n\ntrackPointer: %X -> %X %ld\n", trackPointer, trackPointer - REDUCE_POINTERS, count);
|
std::printf("\n\ntrackPointer: %X -> %X %ld\n", trackPointer, trackPointer - REDUCE_POINTERS, count);
|
||||||
|
|
||||||
|
|
||||||
// Search for loop in this trac
|
// Search for loop in this trac
|
||||||
bool hasLoop = false;
|
bool hasLoop = false;
|
||||||
std::uint32_t loopAddress = 0;
|
std::uint32_t loopAddress = 0;
|
||||||
|
@ -180,10 +155,12 @@ void ReadAgbTracks() {
|
||||||
int loopStartTime = 0;
|
int loopStartTime = 0;
|
||||||
|
|
||||||
unsigned int trackEnd =
|
unsigned int trackEnd =
|
||||||
(trackPointers.size() > count ? trackPointers[count] : (g_fileStartOffset + REDUCE_POINTERS)) ; // Use offset to header as end for last track
|
(trackPointers.size() > count
|
||||||
|
? trackPointers[count]
|
||||||
|
: (g_fileStartOffset + REDUCE_POINTERS)); // Use offset to header as end for last track
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("End of track: %X\n", trackEnd);
|
std::printf("End of track: %X\n", trackEnd);
|
||||||
Seek(FILE_OFFSET + trackEnd - REDUCE_POINTERS);
|
Seek(trackEnd - REDUCE_POINTERS);
|
||||||
|
|
||||||
// search for a few bytes whether there is a loop end
|
// search for a few bytes whether there is a loop end
|
||||||
for (int i = 5; i < 10 + addedPadding; i++) {
|
for (int i = 5; i < 10 + addedPadding; i++) {
|
||||||
|
@ -191,11 +168,11 @@ void ReadAgbTracks() {
|
||||||
// Ignore GOTOs from the previous track.
|
// Ignore GOTOs from the previous track.
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Seek(FILE_OFFSET + trackEnd - REDUCE_POINTERS -i);
|
Seek(trackEnd - REDUCE_POINTERS - i);
|
||||||
if (ReadInt8() == GOTO) {
|
if (ReadInt8() == GOTO) {
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("Has loop: %d\n", i);
|
std::printf("Has loop: %d\n", i);
|
||||||
loopAddress = lReadInt32() + FILE_OFFSET - REDUCE_POINTERS;
|
loopAddress = lReadInt32() - REDUCE_POINTERS;
|
||||||
if (loopAddress > 0x1000000) {
|
if (loopAddress > 0x1000000) {
|
||||||
// The 0xB1 was probably part of the pointer or something.
|
// The 0xB1 was probably part of the pointer or something.
|
||||||
continue;
|
continue;
|
||||||
|
@ -211,32 +188,17 @@ void ReadAgbTracks() {
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("Has loop: %d, %X\n", hasLoop, loopAddress);
|
std::printf("Has loop: %d, %X\n", hasLoop, loopAddress);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Read all track events
|
// Read all track events
|
||||||
|
Seek(trackPointer - REDUCE_POINTERS);
|
||||||
Seek(FILE_OFFSET + trackPointer - REDUCE_POINTERS);
|
|
||||||
|
|
||||||
int type = ReadInt8();
|
int type = ReadInt8();
|
||||||
// std::printf("type: %X\n", type);
|
|
||||||
|
|
||||||
// VOL?
|
// VOL?
|
||||||
if (type == VOL) {
|
if (type == VOL) {
|
||||||
// TODO extract to function and reuse below
|
|
||||||
|
|
||||||
int val = ReadInt8();
|
int val = ReadInt8();
|
||||||
|
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("ignore vol: %X\n", val);
|
std::printf("ignore vol: %X\n", val);
|
||||||
|
|
||||||
// TODO if this is a change to 127*mvl/mxv, there was no event in midi
|
|
||||||
/*std::printf("VOL: %X\n", val);
|
|
||||||
Event event;
|
|
||||||
event.type = EventType::Controller;
|
|
||||||
event.param1 = 0x7;
|
|
||||||
event.param2 = std::round((float)val * MXV / MVL); // TODO inverse "%u*%s_mvl/mxv", event.param2,
|
|
||||||
g_asmLabel.c_str()); events.push_back(event);*/
|
|
||||||
type = ReadInt8();
|
type = ReadInt8();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,7 +211,6 @@ void ReadAgbTracks() {
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("KEYSH: %d\n", keyShift);
|
std::printf("KEYSH: %d\n", keyShift);
|
||||||
// TODO initial shift is always 0? Or is this set as the whole key shift?
|
// TODO initial shift is always 0? Or is this set as the whole key shift?
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
std::printf("Error: initial type %X not implemented\n", type);
|
std::printf("Error: initial type %X not implemented\n", type);
|
||||||
return;
|
return;
|
||||||
|
@ -273,11 +234,10 @@ void ReadAgbTracks() {
|
||||||
int returnPtr = 0;
|
int returnPtr = 0;
|
||||||
|
|
||||||
while (!endOfTrack) {
|
while (!endOfTrack) {
|
||||||
// std::printf("type: %X\n", type);
|
if (hasLoop && !foundLoop && GetCurrentPtr() - 1 == loopAddress) {
|
||||||
if (hasLoop && !foundLoop && GetCurrentPtr()-1 == loopAddress) {
|
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("<<<< inserted loop start\n");
|
std::printf("<<<< inserted loop start\n");
|
||||||
//foundLoop = true;
|
// foundLoop = true;
|
||||||
loopStartTime = currentTime;
|
loopStartTime = currentTime;
|
||||||
Event event;
|
Event event;
|
||||||
event.time = loopStartTime;
|
event.time = loopStartTime;
|
||||||
|
@ -291,8 +251,6 @@ void ReadAgbTracks() {
|
||||||
// Repeat last command
|
// Repeat last command
|
||||||
Skip(-1);
|
Skip(-1);
|
||||||
type = lastCommand;
|
type = lastCommand;
|
||||||
// std::printf("%X ", type);
|
|
||||||
// std::printf("Repeat last command: %X\n", lastCommand);
|
|
||||||
if (g_verbose)
|
if (g_verbose)
|
||||||
std::printf("(repeat cmd) ");
|
std::printf("(repeat cmd) ");
|
||||||
} else {
|
} else {
|
||||||
|
@ -310,7 +268,6 @@ void ReadAgbTracks() {
|
||||||
Event event;
|
Event event;
|
||||||
event.time = currentTime;
|
event.time = currentTime;
|
||||||
event.type = EventType::Tempo;
|
event.type = EventType::Tempo;
|
||||||
// 60000000 / event.param2
|
|
||||||
event.param2 = 60000000 / (val * 2);
|
event.param2 = 60000000 / (val * 2);
|
||||||
metaEvents.push_back(event);
|
metaEvents.push_back(event);
|
||||||
|
|
||||||
|
@ -328,9 +285,7 @@ void ReadAgbTracks() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case VOL: {
|
case VOL: {
|
||||||
// const int MVL = 90; // TODO configurable per song?
|
|
||||||
const int MVL = 128;
|
const int MVL = 128;
|
||||||
|
|
||||||
const int MXV = 0x7F;
|
const int MXV = 0x7F;
|
||||||
|
|
||||||
int val = ReadInt8();
|
int val = ReadInt8();
|
||||||
|
@ -340,8 +295,7 @@ void ReadAgbTracks() {
|
||||||
event.time = currentTime;
|
event.time = currentTime;
|
||||||
event.type = EventType::Controller;
|
event.type = EventType::Controller;
|
||||||
event.param1 = 0x7;
|
event.param1 = 0x7;
|
||||||
event.param2 = std::ceil((float)val * MXV /
|
event.param2 = std::ceil((float)val * MXV / MVL);
|
||||||
MVL); // TODO inverse "%u*%s_mvl/mxv", event.param2, g_asmLabel.c_str());
|
|
||||||
events.push_back(event);
|
events.push_back(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -414,7 +368,6 @@ void ReadAgbTracks() {
|
||||||
|
|
||||||
// Already handled
|
// Already handled
|
||||||
loopEndTime = currentTime;
|
loopEndTime = currentTime;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EOT: {
|
case EOT: {
|
||||||
|
@ -601,7 +554,6 @@ void ReadAgbTracks() {
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
if (type >= 0x80 && type <= 0x80 + 48) {
|
if (type >= 0x80 && type <= 0x80 + 48) {
|
||||||
|
|
||||||
const int lenTbl[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
const int lenTbl[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||||
17, 18, 19, 20, 21, 22, 23, 24, 28, 30, 32, 36, 40, 42, 44, 48, 52,
|
17, 18, 19, 20, 21, 22, 23, 24, 28, 30, 32, 36, 40, 42, 44, 48, 52,
|
||||||
54, 56, 60, 64, 66, 68, 72, 76, 78, 80, 84, 88, 90, 92, 96 };
|
54, 56, 60, 64, 66, 68, 72, 76, 78, 80, 84, 88, 90, 92, 96 };
|
||||||
|
@ -613,65 +565,31 @@ void ReadAgbTracks() {
|
||||||
patternDuration += wait;
|
patternDuration += wait;
|
||||||
|
|
||||||
if (!currentlyPlayingNotes.empty()) {
|
if (!currentlyPlayingNotes.empty()) {
|
||||||
|
|
||||||
// std::printf("Testing... %d\n", (int)currentlyPlayingNotes.size());
|
|
||||||
for (auto it = currentlyPlayingNotes.begin(); it != currentlyPlayingNotes.end();) {
|
for (auto it = currentlyPlayingNotes.begin(); it != currentlyPlayingNotes.end();) {
|
||||||
Event& note = *it; // Modify the note in the list if we don't remove it now.
|
Event& note = *it; // Modify the note in the list if we don't remove it now.
|
||||||
note.time -= wait;
|
note.time -= wait;
|
||||||
if (note.time <= 0) {
|
if (note.time <= 0) {
|
||||||
|
|
||||||
/*if (note.time < 0) {
|
|
||||||
std::printf("<0: %d\n", note.time);
|
|
||||||
std::cin.ignore();
|
|
||||||
}*/
|
|
||||||
// note.time += currentTime; // Set to the global time the note was finished.
|
|
||||||
// TODO negative=
|
|
||||||
note.time += currentTime + wait;
|
note.time += currentTime + wait;
|
||||||
|
|
||||||
// std::printf("Note off at %d\n", note.time);
|
|
||||||
insertAtCorrectTimeFromEnd(events, note);
|
insertAtCorrectTimeFromEnd(events, note);
|
||||||
|
|
||||||
it = currentlyPlayingNotes.erase(it);
|
it = currentlyPlayingNotes.erase(it);
|
||||||
} else {
|
} else {
|
||||||
++it;
|
++it;
|
||||||
}
|
}
|
||||||
// // TODO handle multiple notes playing at the same time on the same track?
|
|
||||||
// if (wait >= currentlyPlayingNotes[0].time) {
|
|
||||||
// Event event = currentlyPlayingNotes[0];
|
|
||||||
// std::printf("Finished playing note\n");
|
|
||||||
// event.time = currentTime;
|
|
||||||
// events.push_back(event);
|
|
||||||
// currentlyPlayingNotes.pop_back();
|
|
||||||
// } else {
|
|
||||||
// currentlyPlayingNotes[0].time -= wait;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
// std::printf("Done... %d\n", (int)currentlyPlayingNotes.size());
|
|
||||||
}
|
}
|
||||||
currentTime += wait;
|
currentTime += wait;
|
||||||
|
|
||||||
/* if (wait > 0) {
|
|
||||||
Event event;
|
|
||||||
event.type = EventType::Wait;
|
|
||||||
event.time = currentTime+convertTime(wait);
|
|
||||||
events.push_back(event);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
} else if (type >= 0xD0 && type <= 0xD0 + 47) {
|
} else if (type >= 0xD0 && type <= 0xD0 + 47) {
|
||||||
|
|
||||||
// Handle note with a fixed length
|
// Handle note with a fixed length
|
||||||
int noteType = type;
|
int noteType = type;
|
||||||
int note = ReadInt8();
|
int note = ReadInt8();
|
||||||
int velocity = 0;
|
int velocity = 0;
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
|
||||||
bool usedLastNote = false;
|
bool usedLastNote = false;
|
||||||
bool usedLastVelocity = false;
|
bool usedLastVelocity = false;
|
||||||
if (note < 0x80) { // a valid note
|
if (note < 0x80) { // a valid note
|
||||||
lastNote = note;
|
lastNote = note;
|
||||||
velocity = ReadInt8();
|
velocity = ReadInt8();
|
||||||
if (velocity < 0x80) { // a valid velocity
|
if (velocity < 0x80) { // a valid velocity
|
||||||
// std::printf("Explicit velocity%d\n", velocity);
|
|
||||||
lastVelocity = velocity;
|
lastVelocity = velocity;
|
||||||
length = ReadInt8();
|
length = ReadInt8();
|
||||||
if (length < 0x80) { // a valid length
|
if (length < 0x80) { // a valid length
|
||||||
|
@ -681,7 +599,6 @@ void ReadAgbTracks() {
|
||||||
length = 0;
|
length = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// std::printf("Reusing last vel %d\n", lastVelocity);
|
|
||||||
type = velocity;
|
type = velocity;
|
||||||
velocity = lastVelocity;
|
velocity = lastVelocity;
|
||||||
usedLastVelocity = true;
|
usedLastVelocity = true;
|
||||||
|
@ -732,56 +649,12 @@ void ReadAgbTracks() {
|
||||||
}
|
}
|
||||||
std::printf("\n");
|
std::printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// std::printf("Wait before convert: %d\n", wait);
|
|
||||||
// std::printf("Wait after convert: %d\n", event.param2);
|
|
||||||
events.push_back(event);
|
events.push_back(event);
|
||||||
|
|
||||||
event.type = EventType::NoteOff;
|
event.type = EventType::NoteOff;
|
||||||
event.time = wait;
|
event.time = wait;
|
||||||
// std::printf("Should be off at %d...\n", currentTime+wait);
|
|
||||||
// std::printf("Note length: %d\n", wait);
|
|
||||||
// std::cin.ignore();
|
|
||||||
currentlyPlayingNotes.push_back(event);
|
currentlyPlayingNotes.push_back(event);
|
||||||
// event.param2 = wait;
|
|
||||||
|
|
||||||
/* int duration = wait; // event.param2;
|
|
||||||
|
|
||||||
if (!g_exactGateTime) { // && duration < 96)
|
|
||||||
// TODO inverse lut
|
|
||||||
std::printf("asdf\n");
|
|
||||||
for (size_t i = 0; i < 97; i++) {
|
|
||||||
if (g_noteDurationLUT[i] == duration) {
|
|
||||||
duration = i;
|
|
||||||
std::printf("test%d\n", (int)i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (duration == 1)
|
|
||||||
duration = 0;
|
|
||||||
|
|
||||||
// event.param2 = (duration * g_midiTimeDiv) /(24 * g_clocksPerBeat);
|
|
||||||
event.param2 = g_noteDurationInverseLUT[duration];
|
|
||||||
std::printf("Wait after convert: %d\n", event.param2);*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
event.param1 = g_noteVelocityLUT[event.param1];
|
|
||||||
|
|
||||||
std::uint32_t duration = (24 * g_clocksPerBeat * event.param2) / g_midiTimeDiv;
|
|
||||||
|
|
||||||
if (duration == 0)
|
|
||||||
duration = 1;
|
|
||||||
|
|
||||||
if (!g_exactGateTime && duration < 96)
|
|
||||||
duration = g_noteDurationLUT[duration];
|
|
||||||
|
|
||||||
event.param2 = duration;
|
|
||||||
*/
|
|
||||||
|
|
||||||
continue; // Next type was already read
|
continue; // Next type was already read
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
std::printf("ERROR: Unhandled type %X\n", type);
|
std::printf("ERROR: Unhandled type %X\n", type);
|
||||||
return;
|
return;
|
||||||
|
@ -789,8 +662,6 @@ void ReadAgbTracks() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO notes, waits,
|
// TODO notes, waits,
|
||||||
type = ReadInt8();
|
type = ReadInt8();
|
||||||
}
|
}
|
||||||
|
@ -816,30 +687,10 @@ void ReadAgbTracks() {
|
||||||
std::cin.ignore();
|
std::cin.ignore();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*if (foundLoop) {
|
|
||||||
// Place the loop begin event as the last event for that time on the meta events track.
|
|
||||||
// TODO this does not help as TEMPO events are not placed on the meta track?
|
|
||||||
|
|
||||||
Event event;
|
|
||||||
event.time = loopStartTime;
|
|
||||||
event.type = EventType::LoopBegin;
|
|
||||||
insertAtCorrectTimeFromEnd(events, event);
|
|
||||||
std::printf("--- Inserting loop at %d\n", loopStartTime);
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (hasLoop) {
|
if (hasLoop) {
|
||||||
Event event;
|
Event event;
|
||||||
event.type = EventType::LoopEnd;
|
event.type = EventType::LoopEnd;
|
||||||
event.time = loopEndTime;
|
event.time = loopEndTime;
|
||||||
// Place loop end at the end of the track that has the latest end.
|
|
||||||
/*for (const auto& events : trackEvents) {
|
|
||||||
int trackEnd = events.back().time;
|
|
||||||
if (trackEnd > event.time) {
|
|
||||||
event.time = trackEnd;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
// std::printf("####### loop End %d\n", event.time);
|
|
||||||
//events.push_back(event);
|
|
||||||
insertAtCorrectTimeFromEnd(events, event);
|
insertAtCorrectTimeFromEnd(events, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -853,8 +704,6 @@ void ReadAgbTracks() {
|
||||||
trackEvents.push_back(events);
|
trackEvents.push_back(events);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Insert manual time signature change event
|
// Insert manual time signature change event
|
||||||
for (const auto& change : timeSignatureChanges) {
|
for (const auto& change : timeSignatureChanges) {
|
||||||
bool inserted = false;
|
bool inserted = false;
|
||||||
|
@ -866,17 +715,14 @@ void ReadAgbTracks() {
|
||||||
for (size_t i = 0; i < metaEvents.size() - 1; i++) {
|
for (size_t i = 0; i < metaEvents.size() - 1; i++) {
|
||||||
int prevTime = metaEvents[i].time;
|
int prevTime = metaEvents[i].time;
|
||||||
int nextTime = metaEvents[i + 1].time;
|
int nextTime = metaEvents[i + 1].time;
|
||||||
//std::printf("%d < %d <= %d?\n", prevTime, event.time, nextTime);
|
|
||||||
if (event.time > prevTime && event.time <= nextTime) {
|
if (event.time > prevTime && event.time <= nextTime) {
|
||||||
//std::printf("axd%d\n", (int)metaEvents.size());
|
|
||||||
metaEvents.insert(metaEvents.begin() + i + 1, event);
|
metaEvents.insert(metaEvents.begin() + i + 1, event);
|
||||||
inserted = true;
|
inserted = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//std::printf("asd %d\n", (int)metaEvents.size());
|
|
||||||
if (!inserted) {
|
if (!inserted) {
|
||||||
metaEvents.push_back(event);
|
metaEvents.push_back(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,7 @@
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
|
||||||
// Reports an error diagnostic and terminates the program.
|
// Reports an error diagnostic and terminates the program.
|
||||||
[[noreturn]] void RaiseError(const char* format, ...)
|
[[noreturn]] void RaiseError(const char* format, ...) {
|
||||||
{
|
|
||||||
const int bufferSize = 1024;
|
const int bufferSize = 1024;
|
||||||
char buffer[bufferSize];
|
char buffer[bufferSize];
|
||||||
std::va_list args;
|
std::va_list args;
|
||||||
|
|
|
@ -49,60 +49,49 @@ int g_denominatorExp = 2;
|
||||||
bool g_verbose = false;
|
bool g_verbose = false;
|
||||||
std::vector<TimeSignatureChange> timeSignatureChanges;
|
std::vector<TimeSignatureChange> timeSignatureChanges;
|
||||||
|
|
||||||
|
[[noreturn]] static void PrintUsage() {
|
||||||
|
std::printf("Usage: AGB2MID baserom start_offset input_file output_file [options]\n"
|
||||||
[[noreturn]] static void PrintUsage()
|
"\n"
|
||||||
{
|
" baserom path to the baserom\n"
|
||||||
std::printf(
|
" start_offset offset to the sound header\n"
|
||||||
"Usage: AGB2MID baserom start_offset input_file output_file [options]\n"
|
" input_file filename(.s) for AGB file\n"
|
||||||
"\n"
|
" output_file filename(.mid) of MIDI file (default:input_file)\n"
|
||||||
" baserom path to the baserom\n"
|
"\n"
|
||||||
" start_offset offset to the sound header\n"
|
"options -L??? label for assembler (default:output_file)\n"
|
||||||
" input_file filename(.s) for AGB file\n"
|
" -V??? master volume (default:127)\n"
|
||||||
" output_file filename(.mid) of MIDI file (default:input_file)\n"
|
" -G??? voice group number (default:0)\n"
|
||||||
"\n"
|
" -P??? priority (default:0)\n"
|
||||||
"options -L??? label for assembler (default:output_file)\n"
|
" -R??? reverb (default:off)\n"
|
||||||
" -V??? master volume (default:127)\n"
|
" -X 48 clocks/beat (default:24 clocks/beat)\n"
|
||||||
" -G??? voice group number (default:0)\n"
|
" -E exact gate-time\n"
|
||||||
" -P??? priority (default:0)\n"
|
" -N no compression\n"
|
||||||
" -R??? reverb (default:off)\n"
|
" -n??? midi time nominator\n"
|
||||||
" -X 48 clocks/beat (default:24 clocks/beat)\n"
|
" -d??? midi time denominator\n"
|
||||||
" -E exact gate-time\n"
|
" -t ? ? ? time signature change\n"
|
||||||
" -N no compression\n"
|
" -v verbose\n");
|
||||||
" -n??? midi time nominator\n"
|
|
||||||
" -d??? midi time denominator\n"
|
|
||||||
" -t ? ? ? time signature change\n"
|
|
||||||
" -v verbose\n"
|
|
||||||
);
|
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string StripExtension(std::string s)
|
static std::string StripExtension(std::string s) {
|
||||||
{
|
|
||||||
std::size_t pos = s.find_last_of('.');
|
std::size_t pos = s.find_last_of('.');
|
||||||
|
|
||||||
if (pos > 0 && pos != std::string::npos)
|
if (pos > 0 && pos != std::string::npos) {
|
||||||
{
|
|
||||||
s = s.substr(0, pos);
|
s = s.substr(0, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string GetExtension(std::string s)
|
static std::string GetExtension(std::string s) {
|
||||||
{
|
|
||||||
std::size_t pos = s.find_last_of('.');
|
std::size_t pos = s.find_last_of('.');
|
||||||
|
|
||||||
if (pos > 0 && pos != std::string::npos)
|
if (pos > 0 && pos != std::string::npos) {
|
||||||
{
|
|
||||||
return s.substr(pos + 1);
|
return s.substr(pos + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string BaseName(std::string s)
|
static std::string BaseName(std::string s) {
|
||||||
{
|
|
||||||
std::size_t posAfterSlash = s.find_last_of("/\\");
|
std::size_t posAfterSlash = s.find_last_of("/\\");
|
||||||
|
|
||||||
if (posAfterSlash == std::string::npos)
|
if (posAfterSlash == std::string::npos)
|
||||||
|
@ -117,11 +106,10 @@ static std::string BaseName(std::string s)
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *GetArgument(int argc, char **argv, int& index)
|
static const char* GetArgument(int argc, char** argv, int& index) {
|
||||||
{
|
|
||||||
assert(index >= 0 && index < argc);
|
assert(index >= 0 && index < argc);
|
||||||
|
|
||||||
const char *option = argv[index];
|
const char* option = argv[index];
|
||||||
|
|
||||||
assert(option != nullptr);
|
assert(option != nullptr);
|
||||||
assert(option[0] == '-');
|
assert(option[0] == '-');
|
||||||
|
@ -131,144 +119,133 @@ static const char *GetArgument(int argc, char **argv, int& index)
|
||||||
return option + 2;
|
return option + 2;
|
||||||
|
|
||||||
// Otherwise, try to get the next arg.
|
// Otherwise, try to get the next arg.
|
||||||
if (index + 1 < argc)
|
if (index + 1 < argc) {
|
||||||
{
|
|
||||||
index++;
|
index++;
|
||||||
return argv[index];
|
return argv[index];
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv) {
|
||||||
{
|
|
||||||
std::string baseromPath;
|
std::string baseromPath;
|
||||||
std::string startOffset;
|
std::string startOffset;
|
||||||
std::string inputFilename;
|
std::string inputFilename;
|
||||||
std::string outputFilename;
|
std::string outputFilename;
|
||||||
|
|
||||||
for (int i = 1; i < argc; i++)
|
for (int i = 1; i < argc; i++) {
|
||||||
{
|
const char* option = argv[i];
|
||||||
const char *option = argv[i];
|
|
||||||
|
|
||||||
if (option[0] == '-' && option[1] != '\0')
|
if (option[0] == '-' && option[1] != '\0') {
|
||||||
{
|
const char* arg;
|
||||||
const char *arg;
|
|
||||||
|
|
||||||
switch (option[1])
|
switch (option[1]) {
|
||||||
{
|
case 'E':
|
||||||
case 'E':
|
g_exactGateTime = true;
|
||||||
g_exactGateTime = true;
|
break;
|
||||||
break;
|
case 'G':
|
||||||
case 'G':
|
arg = GetArgument(argc, argv, i);
|
||||||
arg = GetArgument(argc, argv, i);
|
if (arg == nullptr)
|
||||||
if (arg == nullptr)
|
PrintUsage();
|
||||||
PrintUsage();
|
g_voiceGroup = std::stoi(arg);
|
||||||
g_voiceGroup = std::stoi(arg);
|
break;
|
||||||
break;
|
case 'L':
|
||||||
case 'L':
|
arg = GetArgument(argc, argv, i);
|
||||||
arg = GetArgument(argc, argv, i);
|
if (arg == nullptr)
|
||||||
if (arg == nullptr)
|
PrintUsage();
|
||||||
PrintUsage();
|
g_asmLabel = arg;
|
||||||
g_asmLabel = arg;
|
break;
|
||||||
break;
|
case 'N':
|
||||||
case 'N':
|
g_compressionEnabled = false;
|
||||||
g_compressionEnabled = false;
|
break;
|
||||||
break;
|
case 'P':
|
||||||
case 'P':
|
arg = GetArgument(argc, argv, i);
|
||||||
arg = GetArgument(argc, argv, i);
|
if (arg == nullptr)
|
||||||
if (arg == nullptr)
|
PrintUsage();
|
||||||
PrintUsage();
|
g_priority = std::stoi(arg);
|
||||||
g_priority = std::stoi(arg);
|
break;
|
||||||
break;
|
case 'R':
|
||||||
case 'R':
|
arg = GetArgument(argc, argv, i);
|
||||||
arg = GetArgument(argc, argv, i);
|
if (arg == nullptr)
|
||||||
if (arg == nullptr)
|
PrintUsage();
|
||||||
PrintUsage();
|
g_reverb = std::stoi(arg);
|
||||||
g_reverb = std::stoi(arg);
|
break;
|
||||||
break;
|
case 'V':
|
||||||
case 'V':
|
arg = GetArgument(argc, argv, i);
|
||||||
arg = GetArgument(argc, argv, i);
|
if (arg == nullptr)
|
||||||
if (arg == nullptr)
|
PrintUsage();
|
||||||
PrintUsage();
|
g_masterVolume = std::stoi(arg);
|
||||||
g_masterVolume = std::stoi(arg);
|
break;
|
||||||
break;
|
case 'X':
|
||||||
case 'X':
|
g_clocksPerBeat = 2;
|
||||||
g_clocksPerBeat = 2;
|
break;
|
||||||
break;
|
case 'n':
|
||||||
case 'n':
|
arg = GetArgument(argc, argv, i);
|
||||||
arg = GetArgument(argc, argv, i);
|
if (arg == nullptr)
|
||||||
if (arg == nullptr)
|
PrintUsage();
|
||||||
PrintUsage();
|
g_nominator = std::stoi(arg);
|
||||||
g_nominator = std::stoi(arg);
|
break;
|
||||||
break;
|
case 'd': {
|
||||||
case 'd':
|
arg = GetArgument(argc, argv, i);
|
||||||
{
|
if (arg == nullptr)
|
||||||
arg = GetArgument(argc, argv, i);
|
PrintUsage();
|
||||||
if (arg == nullptr)
|
int denominator = std::stoi(arg);
|
||||||
PrintUsage();
|
if (denominator == 1) {
|
||||||
int denominator = std::stoi(arg);
|
g_denominatorExp = 0;
|
||||||
if (denominator == 1) {
|
} else if (denominator == 2) {
|
||||||
g_denominatorExp = 0;
|
g_denominatorExp = 1;
|
||||||
} else if (denominator == 2) {
|
} else if (denominator == 4) {
|
||||||
g_denominatorExp = 1;
|
g_denominatorExp = 2;
|
||||||
} else if (denominator == 4) {
|
} else if (denominator == 8) {
|
||||||
g_denominatorExp = 2;
|
g_denominatorExp = 3;
|
||||||
} else if (denominator == 8) {
|
} else if (denominator == 16) {
|
||||||
g_denominatorExp = 3;
|
g_denominatorExp = 4;
|
||||||
} else if (denominator == 16) {
|
} else if (denominator == 32) {
|
||||||
g_denominatorExp = 4;
|
g_denominatorExp = 5;
|
||||||
} else if (denominator == 32) {
|
} else {
|
||||||
g_denominatorExp = 5;
|
std::printf("ERROR: denominator %d\n", denominator);
|
||||||
} else {
|
exit(1);
|
||||||
std::printf("ERROR: denominator %d\n", denominator);
|
}
|
||||||
exit(1);
|
break;
|
||||||
}
|
}
|
||||||
break;
|
case 't': {
|
||||||
}
|
int nominator = std::stoi(argv[i + 1]);
|
||||||
case 't':
|
int denominator = std::stoi(argv[i + 2]);
|
||||||
{
|
if (denominator == 1) {
|
||||||
int nominator = std::stoi(argv[i+1]);
|
denominator = 0;
|
||||||
int denominator = std::stoi(argv[i+2]);
|
} else if (denominator == 2) {
|
||||||
if (denominator == 1) {
|
denominator = 1;
|
||||||
denominator = 0;
|
} else if (denominator == 4) {
|
||||||
} else if (denominator == 2) {
|
denominator = 2;
|
||||||
denominator = 1;
|
} else if (denominator == 8) {
|
||||||
} else if (denominator == 4) {
|
denominator = 3;
|
||||||
denominator = 2;
|
} else if (denominator == 16) {
|
||||||
} else if (denominator == 8) {
|
denominator = 4;
|
||||||
denominator = 3;
|
} else if (denominator == 32) {
|
||||||
} else if (denominator == 16) {
|
denominator = 5;
|
||||||
denominator = 4;
|
} else {
|
||||||
} else if (denominator == 32) {
|
std::printf("ERROR: denominator %d\n", denominator);
|
||||||
denominator = 5;
|
exit(1);
|
||||||
} else {
|
}
|
||||||
std::printf("ERROR: denominator %d\n", denominator);
|
int time = std::stoi(argv[i + 3]);
|
||||||
exit(1);
|
i += 3;
|
||||||
}
|
TimeSignatureChange change;
|
||||||
int time = std::stoi(argv[i+3]);
|
change.nominator = nominator;
|
||||||
i += 3;
|
change.denominator = denominator;
|
||||||
TimeSignatureChange change;
|
change.time = time;
|
||||||
change.nominator = nominator;
|
|
||||||
change.denominator = denominator;
|
|
||||||
change.time = time;
|
|
||||||
|
|
||||||
// TODO sort by time?
|
// TODO sort by time?
|
||||||
timeSignatureChanges.push_back(change);
|
timeSignatureChanges.push_back(change);
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case 'v': {
|
||||||
|
g_verbose = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
PrintUsage();
|
||||||
}
|
}
|
||||||
case 'v': {
|
} else {
|
||||||
g_verbose = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
PrintUsage();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (baseromPath.empty())
|
if (baseromPath.empty())
|
||||||
baseromPath = argv[i];
|
baseromPath = argv[i];
|
||||||
else if (startOffset.empty())
|
else if (startOffset.empty())
|
||||||
|
@ -285,16 +262,12 @@ int main(int argc, char** argv)
|
||||||
if (inputFilename.empty())
|
if (inputFilename.empty())
|
||||||
PrintUsage();
|
PrintUsage();
|
||||||
|
|
||||||
/*if (GetExtension(inputFilename) != "out") // TODO unify with baserom parameter?
|
|
||||||
RaiseError("input filename extension is not \"out\"");
|
|
||||||
*/
|
|
||||||
if (outputFilename.empty())
|
if (outputFilename.empty())
|
||||||
outputFilename = StripExtension(inputFilename) + ".mid";
|
outputFilename = StripExtension(inputFilename) + ".mid";
|
||||||
|
|
||||||
if (GetExtension(outputFilename) != "mid")
|
if (GetExtension(outputFilename) != "mid")
|
||||||
RaiseError("output filename extension is not \"mid\"");
|
RaiseError("output filename extension is not \"mid\"");
|
||||||
|
|
||||||
|
|
||||||
if (g_asmLabel.empty())
|
if (g_asmLabel.empty())
|
||||||
g_asmLabel = BaseName(outputFilename);
|
g_asmLabel = BaseName(outputFilename);
|
||||||
|
|
||||||
|
@ -310,16 +283,10 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
g_fileStartOffset = std::stoul(startOffset, nullptr, 16);
|
g_fileStartOffset = std::stoul(startOffset, nullptr, 16);
|
||||||
|
|
||||||
|
|
||||||
ReadAgbSong();
|
ReadAgbSong();
|
||||||
ReadAgbTracks();
|
ReadAgbTracks();
|
||||||
WriteMidiFile();
|
WriteMidiFile();
|
||||||
|
|
||||||
/*ReadMidiFileHeader();
|
|
||||||
PrintAgbHeader();
|
|
||||||
ReadMidiTracks();
|
|
||||||
PrintAgbFooter();*/
|
|
||||||
|
|
||||||
std::fclose(g_inputFile);
|
std::fclose(g_inputFile);
|
||||||
std::fclose(g_outputFile);
|
std::fclose(g_outputFile);
|
||||||
|
|
||||||
|
|
|
@ -222,76 +222,71 @@ void WriteTrack(int channelId, const std::vector<Event>& events) {
|
||||||
bool DEBUG = g_verbose && false;
|
bool DEBUG = g_verbose && false;
|
||||||
|
|
||||||
for (const auto& event : events) {
|
for (const auto& event : events) {
|
||||||
|
if (DEBUG) {
|
||||||
if (DEBUG) { std::printf("TIME: %d\n", event.time); }
|
std::printf("TIME: %d\n", event.time);
|
||||||
|
}
|
||||||
|
writeDeltaTime(data, event.time - currentTime);
|
||||||
/* if (event.type == EventType::Wait) { // Handle special wait event
|
|
||||||
waiting += event.time;
|
|
||||||
continue;
|
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
// TODO can remove type parameter if it is the same type as before?
|
|
||||||
|
|
||||||
// Delta time to previous event
|
|
||||||
// std::printf("delta Time: %d\n", event.time);
|
|
||||||
// TODO make sure currentTime <= event.time!!
|
|
||||||
writeDeltaTime(data, event.time - currentTime); // - previousTime);
|
|
||||||
currentTime = event.time;
|
currentTime = event.time;
|
||||||
// previousTime = event.time;
|
|
||||||
|
|
||||||
switch (event.type) {
|
switch (event.type) {
|
||||||
case EventType::InstrumentChange:
|
case EventType::InstrumentChange:
|
||||||
if (DEBUG) { std::printf("InstrumentChange\n");}
|
if (DEBUG) {
|
||||||
data.push_back(0xC0 + channelId); // type
|
std::printf("InstrumentChange\n");
|
||||||
data.push_back(event.param1); // instrument
|
}
|
||||||
|
data.push_back(0xC0 + channelId); // type
|
||||||
|
data.push_back(event.param1); // instrument
|
||||||
break;
|
break;
|
||||||
case EventType::Controller:
|
case EventType::Controller:
|
||||||
if (DEBUG) { std::printf("Controller\n");}
|
if (DEBUG) {
|
||||||
/*if (event.param1 == 7 && !firstVol) {
|
std::printf("Controller\n");
|
||||||
firstVol = true; // hack TODO
|
}
|
||||||
} else {*/
|
data.push_back(0xB0 + channelId); // type
|
||||||
data.push_back(0xB0 + channelId); // type
|
data.push_back(event.param1); // controller index
|
||||||
//}
|
data.push_back(event.param2); // value
|
||||||
data.push_back(event.param1); // controller index
|
|
||||||
data.push_back(event.param2); // value
|
|
||||||
break;
|
break;
|
||||||
case EventType::Note:
|
case EventType::Note:
|
||||||
if (DEBUG) { std::printf("Note\n");}
|
if (DEBUG) {
|
||||||
data.push_back(0x90 + channelId); // type
|
std::printf("Note\n");
|
||||||
data.push_back(event.note); // note
|
}
|
||||||
data.push_back(event.param1); // velocity
|
data.push_back(0x90 + channelId); // type
|
||||||
|
data.push_back(event.note); // note
|
||||||
|
data.push_back(event.param1); // velocity
|
||||||
break;
|
break;
|
||||||
case EventType::NoteOff:
|
case EventType::NoteOff:
|
||||||
if (DEBUG) { std::printf("NoteOff\n");}
|
if (DEBUG) {
|
||||||
|
std::printf("NoteOff\n");
|
||||||
|
}
|
||||||
// Wait and note_end
|
// Wait and note_end
|
||||||
data.push_back(0x80 + channelId); // type
|
data.push_back(0x80 + channelId); // type
|
||||||
data.push_back(event.note); // note
|
data.push_back(event.note); // note
|
||||||
data.push_back(0); // Ignored velocity
|
data.push_back(0); // Ignored velocity
|
||||||
break;
|
break;
|
||||||
case EventType::TimeSignature:
|
case EventType::TimeSignature: {
|
||||||
{
|
if (DEBUG) {
|
||||||
if (DEBUG) { std::printf("TimeSignature\n");}
|
std::printf("TimeSignature\n");
|
||||||
|
}
|
||||||
// One time meta event at the beginning of the meta track.
|
// One time meta event at the beginning of the meta track.
|
||||||
data.push_back(0xff); // meta
|
data.push_back(0xff); // meta
|
||||||
data.push_back(88); // TIME_SIGNATURE
|
data.push_back(88); // TIME_SIGNATURE
|
||||||
writeDeltaTime(data, 4); // m_length
|
writeDeltaTime(data, 4); // m_length
|
||||||
data.push_back(event.param1); // numerator
|
data.push_back(event.param1); // numerator
|
||||||
data.push_back(event.param2); // denominator
|
data.push_back(event.param2); // denominator
|
||||||
data.push_back(24 * g_clocksPerBeat); // clocksPerClick
|
data.push_back(24 * g_clocksPerBeat); // clocksPerClick
|
||||||
data.push_back(8); // 32ndPer4th
|
data.push_back(8); // 32ndPer4th
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case EventType::Tempo:
|
case EventType::Tempo:
|
||||||
if (DEBUG) { std::printf("Tempo\n");}
|
if (DEBUG) {
|
||||||
data.push_back(0xff); // meta
|
std::printf("Tempo\n");
|
||||||
data.push_back(81); // META_TEMPO
|
}
|
||||||
writeDeltaTime(data, 3); // only valid tempo size is 3
|
data.push_back(0xff); // meta
|
||||||
|
data.push_back(81); // META_TEMPO
|
||||||
|
writeDeltaTime(data, 3); // only valid tempo size is 3
|
||||||
writeInt24(data, event.param2); // usecPerQuarterNote
|
writeInt24(data, event.param2); // usecPerQuarterNote
|
||||||
break;
|
break;
|
||||||
case EventType::Extended:
|
case EventType::Extended:
|
||||||
if (DEBUG) { std::printf("Extended\n");}
|
if (DEBUG) {
|
||||||
|
std::printf("Extended\n");
|
||||||
|
}
|
||||||
if (event.note == 0x1d) {
|
if (event.note == 0x1d) {
|
||||||
// for some reason the first one is in a meta change?
|
// for some reason the first one is in a meta change?
|
||||||
data.push_back(0xb0);
|
data.push_back(0xb0);
|
||||||
|
@ -300,41 +295,47 @@ void WriteTrack(int channelId, const std::vector<Event>& events) {
|
||||||
data.push_back(event.param1);
|
data.push_back(event.param1);
|
||||||
|
|
||||||
writeDeltaTime(data, 0); // Next midi event
|
writeDeltaTime(data, 0); // Next midi event
|
||||||
data.push_back(0x1d); // TODO why twice 0x1d? event.note);
|
data.push_back(0x1d); // TODO why twice 0x1d? event.note);
|
||||||
data.push_back(event.param2);
|
data.push_back(event.param2);
|
||||||
break;
|
break;
|
||||||
case EventType::PitchBend:
|
case EventType::PitchBend:
|
||||||
if (DEBUG) { std::printf("PitchBend\n");}
|
if (DEBUG) {
|
||||||
|
std::printf("PitchBend\n");
|
||||||
|
}
|
||||||
data.push_back(0xe0 + channelId); // petch bend
|
data.push_back(0xe0 + channelId); // petch bend
|
||||||
data.push_back(0); // lsb
|
data.push_back(0); // lsb
|
||||||
data.push_back(event.param2);
|
data.push_back(event.param2);
|
||||||
break;
|
break;
|
||||||
case EventType::EndOfTrack:
|
case EventType::EndOfTrack:
|
||||||
if (DEBUG) { std::printf("EndOfTrack\n");}
|
if (DEBUG) {
|
||||||
|
std::printf("EndOfTrack\n");
|
||||||
|
}
|
||||||
// End of track
|
// End of track
|
||||||
data.push_back(0xff); // meta
|
data.push_back(0xff); // meta
|
||||||
data.push_back(47); // META_END_OF_TRACK
|
data.push_back(47); // META_END_OF_TRACK
|
||||||
writeDeltaTime(data, 0); // length
|
writeDeltaTime(data, 0); // length
|
||||||
break;
|
break;
|
||||||
case EventType::LoopBegin:
|
case EventType::LoopBegin:
|
||||||
if (DEBUG) { std::printf("LoopBegin\n");}
|
if (DEBUG) {
|
||||||
data.push_back(0xff); // meta
|
std::printf("LoopBegin\n");
|
||||||
data.push_back(0x6); // META_MARKER
|
}
|
||||||
data.push_back(0x1); // length
|
data.push_back(0xff); // meta
|
||||||
|
data.push_back(0x6); // META_MARKER
|
||||||
|
data.push_back(0x1); // length
|
||||||
data.push_back(0x5B); // [
|
data.push_back(0x5B); // [
|
||||||
break;
|
break;
|
||||||
case EventType::LoopEnd:
|
case EventType::LoopEnd:
|
||||||
if (DEBUG) { std::printf("LoopEnd\n");}
|
if (DEBUG) {
|
||||||
data.push_back(0xff); // meta
|
std::printf("LoopEnd\n");
|
||||||
data.push_back(0x6); // META_MARKER
|
}
|
||||||
data.push_back(0x1); // length
|
data.push_back(0xff); // meta
|
||||||
|
data.push_back(0x6); // META_MARKER
|
||||||
|
data.push_back(0x1); // length
|
||||||
data.push_back(0x5D); // ]
|
data.push_back(0x5D); // ]
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// MidiTrack header
|
// MidiTrack header
|
||||||
std::fprintf(g_outputFile, "MTrk");
|
std::fprintf(g_outputFile, "MTrk");
|
||||||
// length of track data
|
// length of track data
|
||||||
|
@ -355,19 +356,11 @@ void WriteMidiFile() {
|
||||||
// u16 midiTimeDiv (24 in example)
|
// u16 midiTimeDiv (24 in example)
|
||||||
WriteInt16(g_midiTimeDiv);
|
WriteInt16(g_midiTimeDiv);
|
||||||
|
|
||||||
|
|
||||||
// Add end of track to meta events
|
// Add end of track to meta events
|
||||||
Event event;
|
Event event;
|
||||||
event.type = EventType::EndOfTrack;
|
event.type = EventType::EndOfTrack;
|
||||||
/*event.time = 0;
|
// EndOfTrack event needs to be at the last meta event (can be earlier than the end of other tracks) for
|
||||||
// Place loop end at the end of the track that has the latest end.
|
// bgmVaatiMotif to work
|
||||||
for (const auto& events:trackEvents) {
|
|
||||||
int trackEnd = events.back().time;
|
|
||||||
if (trackEnd > event.time) {
|
|
||||||
event.time = trackEnd;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
// EndOfTrack event needs to be at the last meta event (can be earlier than the end of other tracks) for bgmVaatiMotif to work
|
|
||||||
event.time = metaEvents.back().time;
|
event.time = metaEvents.back().time;
|
||||||
metaEvents.push_back(event);
|
metaEvents.push_back(event);
|
||||||
|
|
||||||
|
|
|
@ -23,14 +23,9 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
enum class MidiFormat
|
enum class MidiFormat { SingleTrack, MultiTrack };
|
||||||
{
|
|
||||||
SingleTrack,
|
|
||||||
MultiTrack
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class EventType
|
enum class EventType {
|
||||||
{
|
|
||||||
EndOfTie = 0x01,
|
EndOfTie = 0x01,
|
||||||
Label = 0x11,
|
Label = 0x11,
|
||||||
LoopEnd = 0x12,
|
LoopEnd = 0x12,
|
||||||
|
@ -53,25 +48,19 @@ enum class EventType
|
||||||
NoteOff,
|
NoteOff,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Event
|
struct Event {
|
||||||
{
|
|
||||||
std::int32_t time = 0;
|
std::int32_t time = 0;
|
||||||
EventType type;
|
EventType type;
|
||||||
std::uint8_t note = 0;
|
std::uint8_t note = 0;
|
||||||
std::uint8_t param1 = 0;
|
std::uint8_t param1 = 0;
|
||||||
std::int32_t param2 = 0;
|
std::int32_t param2 = 0;
|
||||||
|
|
||||||
bool operator==(const Event& other)
|
bool operator==(const Event& other) {
|
||||||
{
|
return (time == other.time && type == other.type && note == other.note && param1 == other.param1 &&
|
||||||
return (time == other.time
|
param2 == other.param2);
|
||||||
&& type == other.type
|
|
||||||
&& note == other.note
|
|
||||||
&& param1 == other.param1
|
|
||||||
&& param2 == other.param2);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator!=(const Event& other)
|
bool operator!=(const Event& other) {
|
||||||
{
|
|
||||||
return !(*this == other);
|
return !(*this == other);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -81,8 +70,7 @@ void WriteMidiFile();
|
||||||
extern int g_midiChan;
|
extern int g_midiChan;
|
||||||
extern std::int32_t g_initialWait;
|
extern std::int32_t g_initialWait;
|
||||||
|
|
||||||
inline bool IsPatternBoundary(EventType type)
|
inline bool IsPatternBoundary(EventType type) {
|
||||||
{
|
|
||||||
return type == EventType::EndOfTrack || (int)type <= 0x17;
|
return type == EventType::EndOfTrack || (int)type <= 0x17;
|
||||||
}
|
}
|
||||||
extern std::int16_t g_midiTimeDiv;
|
extern std::int16_t g_midiTimeDiv;
|
||||||
|
|
|
@ -20,18 +20,17 @@
|
||||||
|
|
||||||
#include "tables.h"
|
#include "tables.h"
|
||||||
|
|
||||||
const int g_noteDurationLUT[] =
|
const int g_noteDurationLUT[] = {
|
||||||
{
|
0, // 0
|
||||||
0, // 0
|
1, // 1
|
||||||
1, // 1
|
2, // 2
|
||||||
2, // 2
|
3, // 3
|
||||||
3, // 3
|
4, // 4
|
||||||
4, // 4
|
5, // 5
|
||||||
5, // 5
|
6, // 6
|
||||||
6, // 6
|
7, // 7
|
||||||
7, // 7
|
8, // 8
|
||||||
8, // 8
|
9, // 9
|
||||||
9, // 9
|
|
||||||
10, // 10
|
10, // 10
|
||||||
11, // 11
|
11, // 11
|
||||||
12, // 12
|
12, // 12
|
||||||
|
@ -121,105 +120,104 @@ const int g_noteDurationLUT[] =
|
||||||
96, // 96
|
96, // 96
|
||||||
};
|
};
|
||||||
|
|
||||||
const int g_noteVelocityLUT[] =
|
const int g_noteVelocityLUT[] = {
|
||||||
{
|
0, // 0
|
||||||
0, // 0
|
4, // 1
|
||||||
4, // 1
|
4, // 2
|
||||||
4, // 2
|
4, // 3
|
||||||
4, // 3
|
4, // 4
|
||||||
4, // 4
|
8, // 5
|
||||||
8, // 5
|
8, // 6
|
||||||
8, // 6
|
8, // 7
|
||||||
8, // 7
|
8, // 8
|
||||||
8, // 8
|
12, // 9
|
||||||
12, // 9
|
12, // 10
|
||||||
12, // 10
|
12, // 11
|
||||||
12, // 11
|
12, // 12
|
||||||
12, // 12
|
16, // 13
|
||||||
16, // 13
|
16, // 14
|
||||||
16, // 14
|
16, // 15
|
||||||
16, // 15
|
16, // 16
|
||||||
16, // 16
|
20, // 17
|
||||||
20, // 17
|
20, // 18
|
||||||
20, // 18
|
20, // 19
|
||||||
20, // 19
|
20, // 20
|
||||||
20, // 20
|
24, // 21
|
||||||
24, // 21
|
24, // 22
|
||||||
24, // 22
|
24, // 23
|
||||||
24, // 23
|
24, // 24
|
||||||
24, // 24
|
28, // 25
|
||||||
28, // 25
|
28, // 26
|
||||||
28, // 26
|
28, // 27
|
||||||
28, // 27
|
28, // 28
|
||||||
28, // 28
|
32, // 29
|
||||||
32, // 29
|
32, // 30
|
||||||
32, // 30
|
32, // 31
|
||||||
32, // 31
|
32, // 32
|
||||||
32, // 32
|
36, // 33
|
||||||
36, // 33
|
36, // 34
|
||||||
36, // 34
|
36, // 35
|
||||||
36, // 35
|
36, // 36
|
||||||
36, // 36
|
40, // 37
|
||||||
40, // 37
|
40, // 38
|
||||||
40, // 38
|
40, // 39
|
||||||
40, // 39
|
40, // 40
|
||||||
40, // 40
|
44, // 41
|
||||||
44, // 41
|
44, // 42
|
||||||
44, // 42
|
44, // 43
|
||||||
44, // 43
|
44, // 44
|
||||||
44, // 44
|
48, // 45
|
||||||
48, // 45
|
48, // 46
|
||||||
48, // 46
|
48, // 47
|
||||||
48, // 47
|
48, // 48
|
||||||
48, // 48
|
52, // 49
|
||||||
52, // 49
|
52, // 50
|
||||||
52, // 50
|
52, // 51
|
||||||
52, // 51
|
52, // 52
|
||||||
52, // 52
|
56, // 53
|
||||||
56, // 53
|
56, // 54
|
||||||
56, // 54
|
56, // 55
|
||||||
56, // 55
|
56, // 56
|
||||||
56, // 56
|
60, // 57
|
||||||
60, // 57
|
60, // 58
|
||||||
60, // 58
|
60, // 59
|
||||||
60, // 59
|
60, // 60
|
||||||
60, // 60
|
64, // 61
|
||||||
64, // 61
|
64, // 62
|
||||||
64, // 62
|
64, // 63
|
||||||
64, // 63
|
64, // 64
|
||||||
64, // 64
|
68, // 65
|
||||||
68, // 65
|
68, // 66
|
||||||
68, // 66
|
68, // 67
|
||||||
68, // 67
|
68, // 68
|
||||||
68, // 68
|
72, // 69
|
||||||
72, // 69
|
72, // 70
|
||||||
72, // 70
|
72, // 71
|
||||||
72, // 71
|
72, // 72
|
||||||
72, // 72
|
76, // 73
|
||||||
76, // 73
|
76, // 74
|
||||||
76, // 74
|
76, // 75
|
||||||
76, // 75
|
76, // 76
|
||||||
76, // 76
|
80, // 77
|
||||||
80, // 77
|
80, // 78
|
||||||
80, // 78
|
80, // 79
|
||||||
80, // 79
|
80, // 80
|
||||||
80, // 80
|
84, // 81
|
||||||
84, // 81
|
84, // 82
|
||||||
84, // 82
|
84, // 83
|
||||||
84, // 83
|
84, // 84
|
||||||
84, // 84
|
88, // 85
|
||||||
88, // 85
|
88, // 86
|
||||||
88, // 86
|
88, // 87
|
||||||
88, // 87
|
88, // 88
|
||||||
88, // 88
|
92, // 89
|
||||||
92, // 89
|
92, // 90
|
||||||
92, // 90
|
92, // 91
|
||||||
92, // 91
|
92, // 92
|
||||||
92, // 92
|
96, // 93
|
||||||
96, // 93
|
96, // 94
|
||||||
96, // 94
|
96, // 95
|
||||||
96, // 95
|
96, // 96
|
||||||
96, // 96
|
|
||||||
100, // 97
|
100, // 97
|
||||||
100, // 98
|
100, // 98
|
||||||
100, // 99
|
100, // 99
|
||||||
|
@ -253,90 +251,17 @@ const int g_noteVelocityLUT[] =
|
||||||
127, // 127
|
127, // 127
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* g_noteTable[] =
|
const char* g_noteTable[] = {
|
||||||
{
|
"Cn%01u ", "Cs%01u ", "Dn%01u ", "Ds%01u ", "En%01u ", "Fn%01u ",
|
||||||
"Cn%01u ",
|
"Fs%01u ", "Gn%01u ", "Gs%01u ", "An%01u ", "As%01u ", "Bn%01u ",
|
||||||
"Cs%01u ",
|
|
||||||
"Dn%01u ",
|
|
||||||
"Ds%01u ",
|
|
||||||
"En%01u ",
|
|
||||||
"Fn%01u ",
|
|
||||||
"Fs%01u ",
|
|
||||||
"Gn%01u ",
|
|
||||||
"Gs%01u ",
|
|
||||||
"An%01u ",
|
|
||||||
"As%01u ",
|
|
||||||
"Bn%01u ",
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* g_minusNoteTable[] =
|
const char* g_minusNoteTable[] = {
|
||||||
{
|
"CnM%01u", "CsM%01u", "DnM%01u", "DsM%01u", "EnM%01u", "FnM%01u",
|
||||||
"CnM%01u",
|
"FsM%01u", "GnM%01u", "GsM%01u", "AnM%01u", "AsM%01u", "BnM%01u",
|
||||||
"CsM%01u",
|
|
||||||
"DnM%01u",
|
|
||||||
"DsM%01u",
|
|
||||||
"EnM%01u",
|
|
||||||
"FnM%01u",
|
|
||||||
"FsM%01u",
|
|
||||||
"GnM%01u",
|
|
||||||
"GsM%01u",
|
|
||||||
"AnM%01u",
|
|
||||||
"AsM%01u",
|
|
||||||
"BnM%01u",
|
|
||||||
};
|
|
||||||
|
|
||||||
const int g_noteIdLUT[] = {
|
|
||||||
0, //
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int g_noteDurationInverseLUT[] = {
|
const int g_noteDurationInverseLUT[] = {
|
||||||
0,
|
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
1,
|
28, 30, 32, 36, 40, 42, 44, 48, 52, 54, 56, 60, 64, 66, 68, 72, 76, 78, 80, 84, 88, 90, 92, 96,
|
||||||
2,
|
|
||||||
3,
|
|
||||||
4,
|
|
||||||
5,
|
|
||||||
6,
|
|
||||||
7,
|
|
||||||
8,
|
|
||||||
9,
|
|
||||||
10,
|
|
||||||
11,
|
|
||||||
12,
|
|
||||||
13,
|
|
||||||
14,
|
|
||||||
15,
|
|
||||||
16,
|
|
||||||
17,
|
|
||||||
18,
|
|
||||||
19,
|
|
||||||
20,
|
|
||||||
21,
|
|
||||||
22,
|
|
||||||
23,
|
|
||||||
24,
|
|
||||||
28,
|
|
||||||
30,
|
|
||||||
32,
|
|
||||||
36,
|
|
||||||
40,
|
|
||||||
42,
|
|
||||||
44,
|
|
||||||
48,
|
|
||||||
52,
|
|
||||||
54,
|
|
||||||
56,
|
|
||||||
60,
|
|
||||||
64,
|
|
||||||
66,
|
|
||||||
68,
|
|
||||||
72,
|
|
||||||
76,
|
|
||||||
78,
|
|
||||||
80,
|
|
||||||
84,
|
|
||||||
88,
|
|
||||||
90,
|
|
||||||
92,
|
|
||||||
96,
|
|
||||||
};
|
};
|
|
@ -1,9 +1,9 @@
|
||||||
|
|
||||||
CXX = g++
|
CXX = g++
|
||||||
CXXFLAGS = -O3 -Wall -Wextra -std=c++17
|
CXXFLAGS = -O3 -Wall -Wextra -Werror -std=c++17
|
||||||
#CXXFLAGS += -g # debug
|
#CXXFLAGS += -g # debug
|
||||||
|
|
||||||
BUILD_FOLDER=build
|
BUILD_FOLDER = build
|
||||||
|
|
||||||
SRCS = $(wildcard *.cpp)
|
SRCS = $(wildcard *.cpp)
|
||||||
SRCS += $(wildcard assets/*.cpp)
|
SRCS += $(wildcard assets/*.cpp)
|
||||||
|
|
|
@ -13,6 +13,8 @@ class BaseAsset {
|
||||||
: path(path), start(start), size(size), asset(asset) {
|
: path(path), start(start), size(size), asset(asset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual ~BaseAsset() = default;
|
||||||
|
|
||||||
void setup() {
|
void setup() {
|
||||||
// Cannot call virtual functions in constructor, so another function call is necessary
|
// Cannot call virtual functions in constructor, so another function call is necessary
|
||||||
assetPath = this->generateAssetPath();
|
assetPath = this->generateAssetPath();
|
||||||
|
|
|
@ -71,13 +71,13 @@ int main(int argc, char** argv) {
|
||||||
argCount--;
|
argCount--;
|
||||||
args++;
|
args++;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Unrecognized argument `" << args[0] << "`" << std::endl;
|
std::cerr << "Error: Unrecognized argument `" << args[0] << "`" << std::endl;
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argCount != 3) {
|
if (argCount != 3) {
|
||||||
std::cerr << "Not enough arguments. expected: 3, actual: " << argCount << std::endl;
|
std::cerr << "Error: Not enough arguments. expected: 3, actual: " << argCount << std::endl;
|
||||||
usage();
|
usage();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,18 +88,23 @@ int main(int argc, char** argv) {
|
||||||
} else if (strcmp(args[0], "build") == 0) {
|
} else if (strcmp(args[0], "build") == 0) {
|
||||||
gMode = BUILD;
|
gMode = BUILD;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Unsupported mode `" << args[0] << "`" << std::endl;
|
std::cerr << "Error: Unsupported mode `" << args[0] << "`" << std::endl;
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
gVariant = args[1];
|
gVariant = args[1];
|
||||||
if (gVariant != "USA" && gVariant != "EU" && gVariant != "JP" && gVariant != "DEMO_USA" && gVariant != "DEMO_JP") {
|
if (gVariant != "USA" && gVariant != "EU" && gVariant != "JP" && gVariant != "DEMO_USA" && gVariant != "DEMO_JP") {
|
||||||
std::cerr << "Unsupported variant `" << gVariant << "`" << std::endl;
|
std::cerr << "Error: Unsupported variant `" << gVariant << "`" << std::endl;
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
gAssetsFolder = args[2];
|
gAssetsFolder = args[2];
|
||||||
gBaseromPath = baseroms[gVariant];
|
gBaseromPath = baseroms[gVariant];
|
||||||
|
|
||||||
|
if (!std::filesystem::exists(gBaseromPath)) {
|
||||||
|
std::cerr << "Error: You need to provide a " << gVariant << " ROM as " << gBaseromPath << std::endl;
|
||||||
|
std::exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Read baserom.
|
// Read baserom.
|
||||||
std::ifstream file(gBaseromPath, std::ios::binary | std::ios::ate);
|
std::ifstream file(gBaseromPath, std::ios::binary | std::ios::ate);
|
||||||
std::streamsize size = file.tellg();
|
std::streamsize size = file.tellg();
|
||||||
|
@ -255,7 +260,7 @@ std::unique_ptr<BaseAsset> getAssetHandlerByType(const std::filesystem::path& pa
|
||||||
// Unknown binary asset
|
// Unknown binary asset
|
||||||
assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
|
assetHandler = std::make_unique<BaseAsset>(path, start, size, asset);
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Unimplemented asset type `" << type << "`" << std::endl;
|
std::cerr << "Error: Unimplemented asset type `" << type << "`" << std::endl;
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
assetHandler->setup();
|
assetHandler->setup();
|
||||||
|
|
|
@ -99,7 +99,7 @@ int main(int argc, char **argv)
|
||||||
std::string path(includeDir + incbin);
|
std::string path(includeDir + incbin);
|
||||||
if (CanOpenFile(path))
|
if (CanOpenFile(path))
|
||||||
{
|
{
|
||||||
dependencies.insert(path).second;
|
dependencies.insert(path);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,11 +28,11 @@ namespace {
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr const char *const ColorStrings[] = {
|
constexpr const char *const ColorStrings[] = {
|
||||||
[Color_White] = "White",
|
"White",
|
||||||
[Color_Red] = "Red",
|
"Red",
|
||||||
[Color_Green] = "Green",
|
"Green",
|
||||||
[Color_Blue] = "Blue",
|
"Blue",
|
||||||
[Color_Yellow] = "Yellow",
|
"Yellow",
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Input {
|
enum Input {
|
||||||
|
@ -52,17 +52,17 @@ namespace {
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr const char *const InputStrings[] = {
|
constexpr const char *const InputStrings[] = {
|
||||||
[Input_A] = "A",
|
"A",
|
||||||
[Input_B] = "B",
|
"B",
|
||||||
[Input_Left] = "Left",
|
"Left",
|
||||||
[Input_Right] = "Right",
|
"Right",
|
||||||
[Input_DUp] = "DUp",
|
"DUp",
|
||||||
[Input_DDown] = "DDown",
|
"DDown",
|
||||||
[Input_DLeft] = "DLeft",
|
"DLeft",
|
||||||
[Input_DRight] = "DRight",
|
"DRight",
|
||||||
[Input_Dpad] = "Dpad",
|
"Dpad",
|
||||||
[Input_Select] = "Select",
|
"Select",
|
||||||
[Input_Start] = "Start",
|
"Start",
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::map<u8, std::string> CharConvertArray = {
|
const std::map<u8, std::string> CharConvertArray = {
|
||||||
|
|
Loading…
Reference in New Issue