summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.hgignore2
-rw-r--r--music.asm (renamed from music/music.asm)0
-rw-r--r--music/pokeredmusicdisasm/AbstractData.cpp37
-rw-r--r--music/pokeredmusicdisasm/AbstractData.h23
-rw-r--r--music/pokeredmusicdisasm/Call.cpp71
-rw-r--r--music/pokeredmusicdisasm/Call.h34
-rw-r--r--music/pokeredmusicdisasm/Console.cpp54
-rw-r--r--music/pokeredmusicdisasm/Console.h29
-rw-r--r--music/pokeredmusicdisasm/Duty.cpp93
-rw-r--r--music/pokeredmusicdisasm/Duty.h40
-rw-r--r--music/pokeredmusicdisasm/File.h26
-rw-r--r--music/pokeredmusicdisasm/Jump.cpp83
-rw-r--r--music/pokeredmusicdisasm/Jump.h33
-rw-r--r--music/pokeredmusicdisasm/Modulation.cpp96
-rw-r--r--music/pokeredmusicdisasm/Modulation.h37
-rw-r--r--music/pokeredmusicdisasm/Note.cpp174
-rw-r--r--music/pokeredmusicdisasm/Note.h73
-rw-r--r--music/pokeredmusicdisasm/Octave.cpp97
-rw-r--r--music/pokeredmusicdisasm/Octave.h43
-rw-r--r--music/pokeredmusicdisasm/Parser.cpp203
-rw-r--r--music/pokeredmusicdisasm/Parser.h72
-rw-r--r--music/pokeredmusicdisasm/Stop.cpp47
-rw-r--r--music/pokeredmusicdisasm/Stop.h21
-rw-r--r--music/pokeredmusicdisasm/Tempo.cpp80
-rw-r--r--music/pokeredmusicdisasm/Tempo.h32
-rw-r--r--music/pokeredmusicdisasm/Velocity.cpp82
-rw-r--r--music/pokeredmusicdisasm/Velocity.h32
-rw-r--r--music/pokeredmusicdisasm/Volume.cpp67
-rw-r--r--music/pokeredmusicdisasm/Volume.h28
-rw-r--r--music/pokeredmusicdisasm/main.cpp39
30 files changed, 1748 insertions, 0 deletions
diff --git a/.hgignore b/.hgignore
index a2d75556..4ae8e30e 100644
--- a/.hgignore
+++ b/.hgignore
@@ -24,3 +24,5 @@ pokered.sav
#for vim configuration
#url: http://www.vim.org/scripts/script.php?script_id=441
.lvimrc
+
+*.exe \ No newline at end of file
diff --git a/music/music.asm b/music.asm
index b48e862b..b48e862b 100644
--- a/music/music.asm
+++ b/music.asm
diff --git a/music/pokeredmusicdisasm/AbstractData.cpp b/music/pokeredmusicdisasm/AbstractData.cpp
new file mode 100644
index 00000000..542922fe
--- /dev/null
+++ b/music/pokeredmusicdisasm/AbstractData.cpp
@@ -0,0 +1,37 @@
+#include "AbstractData.h"
+using namespace std;
+
+AbstractData::AbstractData()
+{
+ error = false;
+}
+
+// This method must always return "" if true but can return
+// any other value for false
+string AbstractData::GenAsm()
+{
+ if(error) return ";#Error";
+ else return "";
+}
+
+bool AbstractData::IsValid(unsigned char* byte)
+{
+ return true;
+}
+
+bool AbstractData::Parse(unsigned char* byte)
+{
+ // If it's not valid, don't even bother parsing
+ if(!IsValid(byte)) return false;
+ return true;
+}
+
+unsigned int AbstractData::Arguments()
+{
+ return 0;
+}
+
+bool AbstractData::GetError()
+{
+ return error;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/AbstractData.h b/music/pokeredmusicdisasm/AbstractData.h
new file mode 100644
index 00000000..2a9fbbaf
--- /dev/null
+++ b/music/pokeredmusicdisasm/AbstractData.h
@@ -0,0 +1,23 @@
+#ifndef ABSTRACTDATA_H
+#define ABSTRACTDATA_H
+
+#include <string>
+
+// All information types inherit from here
+class AbstractData
+{
+public:
+ AbstractData();
+
+ virtual std::string GenAsm(); // Generate Assembly Output
+ virtual bool IsValid(unsigned char* byte); // Check for byte validity
+ virtual bool Parse(unsigned char* byte); // Parse Given Data
+ virtual unsigned int Arguments(); // Number of arguments taken
+
+ virtual bool GetError(); // Get Error (No Write, Error is read only)
+
+protected:
+ bool error; // Whether there's an error in parsing or not
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Call.cpp b/music/pokeredmusicdisasm/Call.cpp
new file mode 100644
index 00000000..bbc2c21e
--- /dev/null
+++ b/music/pokeredmusicdisasm/Call.cpp
@@ -0,0 +1,71 @@
+#include <sstream>
+#include "Call.h"
+using namespace std;
+
+Call::Call()
+{
+ error = false;
+ address = 0;
+}
+
+Call::Call(unsigned char* byte)
+{
+ Parse(byte);
+}
+
+Call::Call(unsigned short value, bool)
+{
+ SetAddress(value);
+}
+
+unsigned short Call::GetAddress()
+{
+ return address;
+}
+
+void Call::SetAddress(unsigned short value)
+{
+ address = value;
+}
+
+string Call::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return tmpRet;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_call" << " $" << hex << uppercase << address;
+ return tmpAsmOut.str();
+}
+
+bool Call::IsValid(unsigned char* byte)
+{
+ if(byte[0] == 0xFD)
+ {
+ error = false;
+ return true;
+ }
+ else
+ {
+ error = true;
+ return false;
+ }
+}
+
+bool Call::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ // Get Address
+ address = byte[2];
+ address <<= 8;
+ address |= byte[1];
+
+ return true;
+}
+
+unsigned int Call::Arguments()
+{
+ // 1 2-byte argument = 2 bytes
+ return 2;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Call.h b/music/pokeredmusicdisasm/Call.h
new file mode 100644
index 00000000..d6fd9c97
--- /dev/null
+++ b/music/pokeredmusicdisasm/Call.h
@@ -0,0 +1,34 @@
+#ifndef CALL_H
+#define CALL_H
+
+#include "AbstractData.h"
+
+// Represents 1 call
+class Call : public AbstractData
+{
+public:
+ // Constructors
+ Call(); // Default
+ Call(unsigned char* byte); // Parse Immidiately
+ Call(unsigned short value, bool); // Set value
+
+ // Direct Getter/Setter Functions
+ unsigned short GetAddress();
+ void SetAddress(unsigned short value);
+
+ // The standard re-implementations from AbstractData
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+private:
+ unsigned short address;
+};
+
+#endif
+
+// Rqandom Notes
+//ED Speed of song
+//EC Instrument
+//DC Volume \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Console.cpp b/music/pokeredmusicdisasm/Console.cpp
new file mode 100644
index 00000000..85623210
--- /dev/null
+++ b/music/pokeredmusicdisasm/Console.cpp
@@ -0,0 +1,54 @@
+#include "console.h"
+
+using namespace std;
+
+// Basic
+void Console::Get(char* value)
+{
+ cin >> value;
+}
+void Console::Get(string& value)
+{
+ cin >> value;
+}
+void Console::Print(const char* value)
+{
+ cout << value;
+}
+void Console::Error(const char* value)
+{
+ cerr << value;
+}
+
+// Upper-Basic
+void Console::PrintLn(const char* value)
+{
+ Print(value);
+ cout << endl;
+}
+void Console::ErrorLn(const char* value)
+{
+ Error(value);
+ cerr << endl;
+}
+
+// Higher
+void Console::Ask(const char* question, char* answer)
+{
+ Print(question);
+ Get(answer);
+}
+void Console::Ask(const char* question, string& answer)
+{
+ Print(question);
+ Get(answer);
+}
+
+// Better Error Handling
+int Console::atoi_ex(const char* input, bool supress)
+{
+ int convInp = atoi(input);
+ if((supress == false) && (convInp == 0))
+ PrintLn("Warning: the converted integer input is 0, this may not be what you intended");
+ return convInp;
+}
diff --git a/music/pokeredmusicdisasm/Console.h b/music/pokeredmusicdisasm/Console.h
new file mode 100644
index 00000000..c6fe1833
--- /dev/null
+++ b/music/pokeredmusicdisasm/Console.h
@@ -0,0 +1,29 @@
+#ifndef CONSOLE_H
+#define CONSOLE_H
+
+#include <iostream>
+#include <string>
+
+// Just a Console Utility Library
+class Console
+{
+public:
+ // Basic
+ static void Get(char* value);
+ static void Get(std::string& value);
+ static void Print(const char* value);
+ static void Error(const char* value);
+
+ // Upper-Basic
+ static void PrintLn(const char* value);
+ static void ErrorLn(const char* value);
+
+ // Higher
+ static void Ask(const char* question, char* answer);
+ static void Ask(const char* question, std::string& answer);
+
+ // Better Error Handling
+ static int atoi_ex(const char* input, bool supress = false);
+};
+
+#endif // CONSOLE_H
diff --git a/music/pokeredmusicdisasm/Duty.cpp b/music/pokeredmusicdisasm/Duty.cpp
new file mode 100644
index 00000000..0723074b
--- /dev/null
+++ b/music/pokeredmusicdisasm/Duty.cpp
@@ -0,0 +1,93 @@
+#include <sstream>
+#include "Duty.h"
+using namespace std;
+
+Duty::Duty()
+{
+ duty = 0;
+}
+
+Duty::Duty(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Duty::Duty(unsigned char value, bool) // Set value
+{
+ SetDuty(value);
+}
+
+unsigned char Duty::GetDuty()
+{
+ return duty;
+}
+
+void Duty::SetDuty(unsigned char value)
+{
+ // Clamp duty to 3 since that's the highest possible
+ duty = value;
+ if(duty >= 3) duty = 3;
+}
+
+// Byte 0 - The Command Code
+// Byte 1 - The Value
+bool Duty::IsValid(unsigned char* byte)
+{
+ if((byte[0] == 0xEC) &&
+ (byte[1] >= 0x0) &&
+ (byte[1] <= 0x3))
+ {
+ error = false; // Unblock assembling
+ return true;
+ }
+ else
+ {
+ error = true; // Block assembling
+ return false;
+ }
+}
+
+string Duty::GenAsm()
+{
+ string ret = AbstractData::GenAsm();
+ if(ret != "") return ret;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_duty " << LookupDutyString();
+ return tmpAsmOut.str();
+}
+
+bool Duty::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ duty = byte[1];
+ return true;
+}
+
+string Duty::LookupDutyString()
+{
+ // In case some error happens and the values doesn't match the list below
+ stringstream defTmp;
+
+ switch(duty)
+ {
+ case duty12_5:
+ return "duty12_5";
+ case duty25:
+ return "duty25";
+ case duty50:
+ return "duty50";
+ case duty75:
+ return "duty75";
+ default:
+ defTmp << "$" << uppercase << hex << (short)duty;
+ return defTmp.str();
+ }
+}
+
+unsigned int Duty::Arguments()
+{
+ //1 1-byte argument = 1
+ return 1;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Duty.h b/music/pokeredmusicdisasm/Duty.h
new file mode 100644
index 00000000..42c58dd7
--- /dev/null
+++ b/music/pokeredmusicdisasm/Duty.h
@@ -0,0 +1,40 @@
+#ifndef DUTY_H
+#define DUTY_H
+
+#include "AbstractData.h"
+
+//Represents 1 Duty data
+class Duty : public AbstractData
+{
+public:
+ // Constructors
+ Duty();
+ Duty(unsigned char* byte); // Parse Immidiately
+ Duty(unsigned char value, bool); // Set value
+
+ // Re-Implementations from Parent
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+ // Direct Getters and Setters
+ unsigned char GetDuty();
+ void SetDuty(unsigned char value);
+
+ // Custom Functions
+ std::string LookupDutyString();
+
+ const enum dutyList : unsigned char
+ {
+ duty12_5 = 0x0,
+ duty25 = 0x1,
+ duty50 = 0x2,
+ duty75 = 0x3
+ };
+
+private:
+ unsigned char duty;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/File.h b/music/pokeredmusicdisasm/File.h
new file mode 100644
index 00000000..de1e6998
--- /dev/null
+++ b/music/pokeredmusicdisasm/File.h
@@ -0,0 +1,26 @@
+#ifndef FILE_H
+#define FILE_H
+
+#include <string>
+#include <vector>
+#include <fstream>
+
+class File
+{
+public:
+ File();
+ File(std::string filename, unsigned int offset = 0, unsigned int length = 0);
+
+ string GetFileName();
+ void SetFilename(string value);
+
+private:
+ std::string filename;
+ std::vector<unsigned char> fileBuffer;
+ std::fstream fileHandle;
+
+ std::vector<unsigned char>::iterator start;
+ std::vector<unsigned char>::iterator cur;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Jump.cpp b/music/pokeredmusicdisasm/Jump.cpp
new file mode 100644
index 00000000..8b094996
--- /dev/null
+++ b/music/pokeredmusicdisasm/Jump.cpp
@@ -0,0 +1,83 @@
+#include <sstream>
+#include "Jump.h"
+using namespace std;
+
+Jump::Jump()
+{
+ address = 0x0000;
+ loop = 0;
+}
+
+Jump::Jump(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Jump::Jump(unsigned short value, unsigned char loop, bool) // Set value
+{
+ SetAddress(value);
+ SetLoop(loop);
+}
+
+unsigned short Jump::GetAddress()
+{
+ return address;
+}
+
+void Jump::SetAddress(unsigned short value)
+{
+ address = value;
+}
+
+unsigned char Jump::GetLoop()
+{
+ return loop;
+}
+
+void Jump::SetLoop(unsigned char value)
+{
+ loop = value;
+}
+
+string Jump::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return tmpRet;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_jump" << " " << (short)loop << ", $" << hex << uppercase << address;
+ return tmpAsmOut.str();
+}
+
+bool Jump::IsValid(unsigned char* byte)
+{
+ if(byte[0] == 0xFE)
+ {
+ error = false;
+ return true;
+ }
+ else
+ {
+ error = true;
+ return false;
+ }
+}
+
+bool Jump::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ loop = byte[1];
+
+ address = byte[3];
+ address <<= 8;
+ address |= byte[2];
+
+ return true;
+}
+
+unsigned int Jump::Arguments()
+{
+ // 1 1-byte command, 1 1-byte loop, 1 2-byte pointer = 4 bytes
+ return 3;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Jump.h b/music/pokeredmusicdisasm/Jump.h
new file mode 100644
index 00000000..64273fb7
--- /dev/null
+++ b/music/pokeredmusicdisasm/Jump.h
@@ -0,0 +1,33 @@
+#ifndef JUMP_H
+#define JUMP_H
+
+#include "AbstractData.h"
+
+// Represents 1 Jump Class
+class Jump : public AbstractData
+{
+public:
+ // Constructors
+ Jump(); // Default
+ Jump(unsigned char* byte); // Parse Immidiately
+ Jump(unsigned short value, unsigned char loop, bool); // Set value
+
+ // Direct Getter/Setter Functions
+ unsigned short GetAddress();
+ void SetAddress(unsigned short value);
+
+ unsigned char GetLoop();
+ void SetLoop(unsigned char value);
+
+ // The standard re-implementations from AbstractData
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+private:
+ unsigned short address;
+ unsigned char loop;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Modulation.cpp b/music/pokeredmusicdisasm/Modulation.cpp
new file mode 100644
index 00000000..61ccbf82
--- /dev/null
+++ b/music/pokeredmusicdisasm/Modulation.cpp
@@ -0,0 +1,96 @@
+#include <sstream>
+#include "Modulation.h"
+using namespace std;
+
+Modulation::Modulation()
+{
+ delay = 0;
+ depth = 0;
+ rate = 0;
+}
+
+Modulation::Modulation(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Modulation::Modulation(unsigned char delay, unsigned char depth, unsigned char rate, bool) // Set value
+{
+ SetDelay(delay);
+ SetDepth(depth);
+ SetRate(rate);
+}
+
+// Direct Getter/Setter Functions
+unsigned char Modulation::GetDelay()
+{
+ return delay;
+}
+
+void Modulation::SetDelay(unsigned char value)
+{
+ delay = value;
+}
+
+unsigned char Modulation::GetDepth()
+{
+ return depth;
+}
+
+void Modulation::SetDepth(unsigned char value)
+{
+ depth = value;
+}
+
+unsigned char Modulation::GetRate()
+{
+ return rate;
+}
+
+void Modulation::SetRate(unsigned char value)
+{
+ rate = value;
+}
+
+bool Modulation::IsValid(unsigned char* byte)
+{
+ if(byte[0] == 0xEA)
+ {
+ error = false; // Unblock assembling
+ return true;
+ }
+ else
+ {
+ error = true; // Block assembling
+ return false;
+ }
+}
+
+string Modulation::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return tmpRet;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_mod " << hex << (short)delay << ", " << (short)depth << ", " << (short)rate;
+ return tmpAsmOut.str();
+}
+
+bool Modulation::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ delay = byte[1];
+
+ depth = byte[2] & 0xF0;
+ depth >>= 4;
+
+ rate = byte[2] & 0x0F;
+ return true;
+}
+
+unsigned int Modulation::Arguments()
+{
+ // 2 1-byte arguments = 2
+ return 2;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Modulation.h b/music/pokeredmusicdisasm/Modulation.h
new file mode 100644
index 00000000..38c84791
--- /dev/null
+++ b/music/pokeredmusicdisasm/Modulation.h
@@ -0,0 +1,37 @@
+#ifndef MODULATION_H
+#define MODULATION_H
+
+#include "AbstractData.h"
+
+//Represents 1 modulation value
+class Modulation : public AbstractData
+{
+public:
+ // Constructors
+ Modulation();
+ Modulation(unsigned char* byte); // Parse Immidiately
+ Modulation(unsigned char delay, unsigned char depth, unsigned char rate, bool); // Set value
+
+ // Direct Getter/Setter Functions
+ unsigned char GetDelay();
+ void SetDelay(unsigned char value);
+
+ unsigned char GetDepth();
+ void SetDepth(unsigned char value);
+
+ unsigned char GetRate();
+ void SetRate(unsigned char value);
+
+ // Re-implemented
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+private:
+ unsigned char delay;
+ unsigned char depth;
+ unsigned char rate;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Note.cpp b/music/pokeredmusicdisasm/Note.cpp
new file mode 100644
index 00000000..0b62f1f9
--- /dev/null
+++ b/music/pokeredmusicdisasm/Note.cpp
@@ -0,0 +1,174 @@
+#include <sstream>
+#include "Note.h"
+
+using namespace std;
+
+Note::Note()
+{
+ pitch = 0x0;
+ delay = 0x0;
+}
+
+Note::Note(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Note::Note(unsigned char pitch, unsigned char delay,bool) // Set value
+{
+ SetPitch(pitch);
+ SetDelay(delay);
+}
+
+unsigned char Note::GetPitch()
+{
+ return pitch;
+}
+
+void Note::SetPitch(unsigned char value)
+{
+ pitch = value;
+}
+
+unsigned char Note::GetDelay()
+{
+ return delay;
+}
+
+void Note::SetDelay(unsigned char value)
+{
+ delay = value;
+}
+
+bool Note::IsValid(unsigned char* byte)
+{
+ // A Note is a byte that is between 0x00 and 0xCF
+ if((byte[0] >= 0x00) &&
+ (byte[0] <= 0xCF))
+ {
+ error = false; // Unblock assembling
+ return true;
+ }
+ else
+ {
+ error = true; // Block assembling
+ return false;
+ }
+}
+
+// Generates the assembly for this note
+string Note::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return tmpRet;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_note" << " " << LookupPitchStr() << ", " << LookupDelayStr();
+ return tmpAsmOut.str();
+}
+
+// Takes the raw byte and parses it's data, storing it
+bool Note::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ pitch = byte[0] & 0xF0;
+ pitch >>= 4;
+
+ delay = byte[0] & 0x0F;
+ return true;
+}
+
+// Fetches the asm string name for the pitch
+string Note::LookupPitchStr()
+{
+ // In case some error happens and the values doesn't match the list below
+ stringstream defTmp;
+
+ switch(pitch)
+ {
+ case noteC:
+ return "noteC";
+ case noteCS:
+ return "noteC#";
+ case noteD:
+ return "noteD";
+ case noteDS:
+ return "noteD#";
+ case noteE:
+ return "noteE";
+ case noteF:
+ return "noteF";
+ case noteFS:
+ return "noteF#";
+ case noteG:
+ return "noteG";
+ case noteGS:
+ return "noteG#";
+ case noteA:
+ return "noteA";
+ case noteAS:
+ return "noteA#";
+ case noteB:
+ return "noteB";
+ case noteRst:
+ return "noteRst";
+ default:
+ defTmp.setf(ios_base::uppercase | ios_base::hex);
+ defTmp << "$" << pitch;
+ return defTmp.str();
+ }
+}
+
+// Fetches the asm string name for the delay
+string Note::LookupDelayStr()
+{
+ // In case some error happens and the values doesn't match the list below
+ stringstream defTmp;
+
+ switch(delay)
+ {
+ case note16:
+ return "note16";
+ case note8:
+ return "note8";
+ case note8_16:
+ return "note8_16";
+ case note4:
+ return "note4";
+ case note4_16:
+ return "note4_16";
+ case note4_8:
+ return "note4_8";
+ case note4_8_16:
+ return "note4_8_16";
+ case note2:
+ return "note2";
+ case note2_16:
+ return "note2_16";
+ case note2_8:
+ return "note2_8";
+ case note2_8_16:
+ return "note2_8_16";
+ case note2_4:
+ return "note2_4";
+ case note2_4_16:
+ return "note2_4_16";
+ case note2_4_8:
+ return "note2_4_8";
+ case note2_4_8_16:
+ return "note2_4_8_16";
+ case note1:
+ return "note1";
+ default:
+ defTmp.setf(ios_base::uppercase | ios_base::hex);
+ defTmp << "$" << (short)pitch;
+ return defTmp.str();
+ }
+}
+
+unsigned int Note::Arguments()
+{
+ // No Arguments
+ return 0;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Note.h b/music/pokeredmusicdisasm/Note.h
new file mode 100644
index 00000000..73502683
--- /dev/null
+++ b/music/pokeredmusicdisasm/Note.h
@@ -0,0 +1,73 @@
+#ifndef NOTE_H
+#define NOTE_H
+
+#include "AbstractData.h"
+
+// Holds a single note
+class Note : public AbstractData
+{
+public:
+ // Constructors
+ Note();
+ Note(unsigned char* byte); // Parse Immidiately
+ Note(unsigned char pitch, unsigned char delay,bool); // Set value
+
+ // Reimplementations
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+ // Getters and Setters
+ unsigned char GetPitch();
+ void SetPitch(unsigned char value);
+
+ unsigned char GetDelay();
+ void SetDelay(unsigned char value);
+
+ // Specific Methods
+ std::string LookupPitchStr();
+ std::string LookupDelayStr();
+
+ const enum pitch_code : unsigned char
+ {
+ noteC = 0x0,
+ noteCS = 0x1,
+ noteD = 0x2,
+ noteDS = 0x3,
+ noteE = 0x4,
+ noteF = 0x5,
+ noteFS = 0x6,
+ noteG = 0x7,
+ noteGS = 0x8,
+ noteA = 0x9,
+ noteAS = 0xA,
+ noteB = 0xB,
+ noteRst = 0xC
+ };
+
+ const enum delay_code : unsigned char
+ {
+ note16 = 0x0,
+ note8 = 0x1,
+ note8_16 = 0x2,
+ note4 = 0x3,
+ note4_16 = 0x4,
+ note4_8 = 0x5,
+ note4_8_16 = 0x6,
+ note2 = 0x7,
+ note2_16 = 0x8,
+ note2_8 = 0x9,
+ note2_8_16 = 0xA,
+ note2_4 = 0xB,
+ note2_4_16 = 0xC,
+ note2_4_8 = 0xD,
+ note2_4_8_16 = 0xE,
+ note1 = 0xF
+ };
+private:
+ unsigned char pitch;
+ unsigned char delay;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Octave.cpp b/music/pokeredmusicdisasm/Octave.cpp
new file mode 100644
index 00000000..3da6609b
--- /dev/null
+++ b/music/pokeredmusicdisasm/Octave.cpp
@@ -0,0 +1,97 @@
+#include <sstream>
+#include "Octave.h"
+using namespace std;
+
+Octave::Octave()
+{
+ octave = 0;
+}
+
+Octave::Octave(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Octave::Octave(unsigned char octave, bool) // Set value
+{
+ SetOctave(octave);
+}
+
+unsigned char Octave::GetOctave()
+{
+ return octave;
+}
+
+void Octave::SetOctave(unsigned char value)
+{
+ octave = value;
+}
+
+bool Octave::IsValid(unsigned char* byte)
+{
+ if((byte[0] >= 0xE0) &&
+ (byte[0] <= 0xE7))
+ {
+ error = false; // Unblock assembling
+ return true;
+ }
+ else
+ {
+ error = true; // Block assembling
+ return false;
+ }
+}
+
+string Octave::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return tmpRet;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_octave" << " " << LookupOctString();
+ return tmpAsmOut.str();
+}
+
+bool Octave::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ octave = byte[0];
+ return true;
+}
+
+string Octave::LookupOctString()
+{
+ // In case some error happens and the values doesn't match the list below
+ stringstream defTmp;
+
+ switch(octave)
+ {
+ case oct0:
+ return "oct0";
+ case oct1:
+ return "oct1";
+ case oct2:
+ return "oct2";
+ case oct3:
+ return "oct3";
+ case oct4:
+ return "oct4";
+ case oct5:
+ return "oct5";
+ case oct6:
+ return "oct6";
+ case oct7:
+ return "oct7";
+ default:
+ defTmp.setf(ios_base::uppercase | ios_base::hex);
+ defTmp << "$" << (short)octave;
+ return defTmp.str();
+ }
+}
+
+unsigned int Octave::Arguments()
+{
+ // No Arguments
+ return 0;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Octave.h b/music/pokeredmusicdisasm/Octave.h
new file mode 100644
index 00000000..b0e5764e
--- /dev/null
+++ b/music/pokeredmusicdisasm/Octave.h
@@ -0,0 +1,43 @@
+#ifndef OCTAVE_H
+#define OCTAVE_H
+
+#include "AbstractData.h"
+
+//Represents 1 octave value
+class Octave : public AbstractData
+{
+public:
+ // Constructors
+ Octave();
+ Octave(unsigned char* byte); // Parse Immidiately
+ Octave(unsigned char octave, bool); // Set value
+
+ // Direct Getters / Setters
+ unsigned char GetOctave();
+ void SetOctave(unsigned char value);
+
+ // Overides
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+ std::string LookupOctString();
+
+ const enum OctaveCode : unsigned char
+ {
+ oct0 = 0xE7,
+ oct1 = 0xE6,
+ oct2 = 0xE5,
+ oct3 = 0xE4,
+ oct4 = 0xE3,
+ oct5 = 0xE2,
+ oct6 = 0xE1,
+ oct7 = 0xE0,
+ };
+
+private:
+ unsigned char octave;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Parser.cpp b/music/pokeredmusicdisasm/Parser.cpp
new file mode 100644
index 00000000..a548b015
--- /dev/null
+++ b/music/pokeredmusicdisasm/Parser.cpp
@@ -0,0 +1,203 @@
+#include <sstream>
+#include "Parser.h"
+using namespace std;
+
+// Constructors
+Parser::Parser()
+{
+ rawBytes = 0;
+ fileLength = 0;
+ filePos = 0;
+ stop = false;
+}
+
+Parser::Parser(std::string filename)
+{
+ rawBytes = 0;
+ fileLength = 0;
+ filePos = 0;
+ stop = false;
+
+ SetFilename(filename);
+}
+
+// Deconstructors
+Parser::~Parser()
+{
+ // Clear out temporary buffer
+ delete[] rawBytes;
+
+ // Clear out parsed buffer
+ for(unsigned int i = 0; i < parsedBytes.size(); i++)
+ {
+ delete parsedBytes[i];
+ }
+}
+
+// Getters / Setters
+string Parser::GetFilename()
+{
+ return filename;
+}
+
+void Parser::SetFilename(std::string value)
+{
+ filename = value;
+ Read();
+}
+
+string Parser::GetParsedAsm()
+{
+ string tmpStr;
+
+ for(unsigned int i = 0; i < parsedString.size(); i++)
+ {
+ tmpStr += parsedString[i] + "\n";
+ }
+
+ return tmpStr;
+}
+
+// File Operations
+// Absolutely no error checking at all - likely needs to be done at somepoint
+void Parser::Read()
+{
+ // open File
+ fstream tmpFile(filename, ios_base::in | ios_base::binary);
+
+ // Get Length
+ tmpFile.seekg(0, ios::end);
+ fileLength = tmpFile.tellg();
+ tmpFile.seekg(0, ios::beg);
+
+ // Allocate proper memory
+ rawBytes = new char[fileLength];
+
+ // Read filedata
+ tmpFile.read(rawBytes, fileLength);
+ tmpFile.close();
+}
+
+// Code Operations
+void Parser::Parse(unsigned int offset)
+{
+ filePos = offset;
+ ParseNext();
+}
+
+void Parser::ParseNext() // Parses the block immidiately following
+{
+ stringstream tmpStr;
+ unsigned char* rawBytesFixed = (unsigned char*)rawBytes;
+ stop = false;
+
+ // Smart generation
+ bool indent = false;
+ bool firstNonNote = false; // First byte wasn't a note or octacve switch, add ";Setup" comment
+ bool firstNote = false; // First note or octave
+
+ stringstream pos;
+ pos << "; " << hex << uppercase << (unsigned int)filePos;
+ parsedString.push_back(pos.str());
+
+ for(unsigned int i = filePos; (i <= fileLength) && (stop == false); i++)
+ {
+ // There's a way to make this block shorter but for now it does it's job
+ filePos = i;
+
+ // Check to see if it's the correct data type and if so then use it
+ if(tmpCall.IsValid(&rawBytesFixed[i])) // Should have made IsValid static
+ {
+ // Call data type
+
+ // Create data type then move the increment pointer further up as needed
+ parsedBytes.push_back(new Call(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpCall.Arguments(); // should have made Arguments static
+
+ Call* _tmp = (Call*)parsedBytes[parsedBytes.size() - 1];
+ }
+ else if(tmpDuty.IsValid(&rawBytesFixed[i]))
+ {
+ // Duty data type
+ parsedBytes.push_back(new Duty(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpDuty.Arguments();
+ }
+ else if(tmpJump.IsValid(&rawBytesFixed[i]))
+ {
+ // Jump data type
+ parsedBytes.push_back(new Jump(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpJump.Arguments();
+
+ Jump* _tmp = (Jump*)parsedBytes[parsedBytes.size() - 1];
+ }
+ else if(tmpModulation.IsValid(&rawBytesFixed[i]))
+ {
+ // Modulation data type
+ parsedBytes.push_back(new Modulation(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpModulation.Arguments();
+ }
+ else if(tmpNote.IsValid(&rawBytesFixed[i]))
+ {
+ // Note data type
+ parsedBytes.push_back(new Note(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpNote.Arguments();
+ }
+ else if(tmpOctave.IsValid(&rawBytesFixed[i]))
+ {
+ // Octave data type
+ parsedBytes.push_back(new Octave(&rawBytesFixed[i]));
+ parsedString.push_back("\n" + parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpOctave.Arguments();
+ }
+ else if(tmpStop.IsValid(&rawBytesFixed[i]))
+ {
+ // Stop data type
+ parsedBytes.push_back(new Stop(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpStop.Arguments();
+
+ stop = true; // Stop all further processing, we've reached the end of the song
+ }
+ else if(tmpTempo.IsValid(&rawBytesFixed[i]))
+ {
+ // Tempo data type
+ parsedBytes.push_back(new Tempo(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpTempo.Arguments();
+ }
+ else if(tmpVelocity.IsValid(&rawBytesFixed[i]))
+ {
+ // Velocity data type
+ parsedBytes.push_back(new Velocity(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpVelocity.Arguments();
+ }
+ else if(tmpVolume.IsValid(&rawBytesFixed[i]))
+ {
+ // Volume data type
+ parsedBytes.push_back(new Volume(&rawBytesFixed[i]));
+ parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
+ i += tmpVolume.Arguments();
+ }
+ else
+ {
+ // Unknown code
+ stringstream unkCode;
+ short tmpByte = (short)rawBytesFixed[i];
+ unkCode << "db $" << hex << uppercase << (short)rawBytesFixed[i];
+ parsedString.push_back(unkCode.str());
+ }
+ }
+
+ // Now record the postion we left off
+ pos.str("");
+ pos << "; " << hex << uppercase << (unsigned int)filePos;
+ parsedString.push_back(pos.str());
+
+ filePos += 1; // increment 1 for the start of the next possible song
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Parser.h b/music/pokeredmusicdisasm/Parser.h
new file mode 100644
index 00000000..9f7550c0
--- /dev/null
+++ b/music/pokeredmusicdisasm/Parser.h
@@ -0,0 +1,72 @@
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <fstream>
+#include <string>
+#include <vector>
+
+#include "AbstractData.h"
+#include "Call.h"
+#include "Console.h"
+#include "Duty.h"
+#include "Jump.h"
+#include "Modulation.h"
+#include "Note.h"
+#include "Octave.h"
+#include "Parser.h"
+#include "Stop.h"
+#include "Tempo.h"
+#include "Velocity.h"
+#include "Volume.h"
+
+// This is the final class, it takes all of the data types, abstract class, and helper functions and uses them
+// for parsing
+
+// the final decided plan was to read the whole file into memory (a rom isn't exactly a big memory breaker)
+class Parser
+{
+public:
+ // Constructors
+ Parser();
+ Parser(std::string filename);
+
+ // Deconstructors
+ ~Parser();
+
+ // Getters / Setters
+ std::string GetFilename();
+ void SetFilename(std::string value);
+
+ std::string GetParsedAsm();
+
+ // File Operations
+ void Read();
+
+ // Code Operations
+ void Parse(unsigned int offset);
+ void ParseNext(); // Parses the block immidiately following
+
+private:
+ std::string filename;
+ std::vector<AbstractData*> parsedBytes;
+ std::vector<std::string> parsedString;
+
+ char* rawBytes;
+ unsigned int fileLength;
+ unsigned int filePos;
+ bool stop;
+
+ // A lot of tmp classes
+ Call tmpCall;
+ Duty tmpDuty;
+ Jump tmpJump;
+ Modulation tmpModulation;
+ Note tmpNote;
+ Octave tmpOctave;
+ Stop tmpStop;
+ Tempo tmpTempo;
+ Velocity tmpVelocity;
+ Volume tmpVolume;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Stop.cpp b/music/pokeredmusicdisasm/Stop.cpp
new file mode 100644
index 00000000..c0a0a2ff
--- /dev/null
+++ b/music/pokeredmusicdisasm/Stop.cpp
@@ -0,0 +1,47 @@
+#include <sstream>
+#include "Stop.h"
+using namespace std;
+
+Stop::Stop()
+{}
+
+Stop::Stop(unsigned char* byte)
+{
+ Parse(byte);
+}
+
+bool Stop::IsValid(unsigned char* byte)
+{
+ if(byte[0] == 0xFF)
+ {
+ error = false; // Unblock assembling
+ return true;
+ }
+ else
+ {
+ error = true; // Block assembling
+ return false;
+ }
+}
+
+string Stop::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return false;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_end";
+ return tmpAsmOut.str();
+}
+
+bool Stop::Parse(unsigned char* byte)
+{
+ if(AbstractData::Parse(byte)) return false;
+ return true;
+}
+
+unsigned int Stop::Arguments()
+{
+ // No Arguments
+ return 0;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Stop.h b/music/pokeredmusicdisasm/Stop.h
new file mode 100644
index 00000000..f97a888b
--- /dev/null
+++ b/music/pokeredmusicdisasm/Stop.h
@@ -0,0 +1,21 @@
+#ifndef STOP_H
+#define STOP_H
+
+#include "AbstractData.h"
+
+//Represents 1 end music data
+class Stop : public AbstractData
+{
+public:
+ // Constructors
+ Stop();
+ Stop(unsigned char* byte); // Parse Immidiately
+
+ // Re-Implementations
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Tempo.cpp b/music/pokeredmusicdisasm/Tempo.cpp
new file mode 100644
index 00000000..b981579f
--- /dev/null
+++ b/music/pokeredmusicdisasm/Tempo.cpp
@@ -0,0 +1,80 @@
+#include <sstream>
+#include "Tempo.h"
+using namespace std;
+
+Tempo::Tempo()
+{
+ divider = 0;
+ modifier = 0;
+}
+
+Tempo::Tempo(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Tempo::Tempo(unsigned char divider, unsigned char modifier, bool) // Set value
+{
+ SetDivider(divider);
+ SetModifier(modifier);
+}
+
+unsigned char Tempo::GetDivider()
+{
+ return divider;
+}
+
+void Tempo::SetDivider(unsigned char value)
+{
+ divider = value;
+}
+
+unsigned char Tempo::Getmodifier()
+{
+ return modifier;
+}
+
+void Tempo::SetModifier(unsigned char value)
+{
+ modifier = value;
+}
+
+bool Tempo::IsValid(unsigned char* byte)
+{
+ if(byte[0] == 0xED)
+ {
+ error = false;
+ return true;
+ }
+ else
+ {
+ error = true;
+ return false;
+ }
+}
+
+string Tempo::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return false;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_tempo" << " " << (short)divider << ", " << (short)modifier;
+ return tmpAsmOut.str();
+}
+
+bool Tempo::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ divider = byte[1];
+ modifier = byte[2];
+
+ return true;
+}
+
+unsigned int Tempo::Arguments()
+{
+ // 2 1-byte arguments = 2
+ return 2;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Tempo.h b/music/pokeredmusicdisasm/Tempo.h
new file mode 100644
index 00000000..185c3a94
--- /dev/null
+++ b/music/pokeredmusicdisasm/Tempo.h
@@ -0,0 +1,32 @@
+#ifndef TEMPO_H
+#define TEMPO_H
+
+#include "AbstractData.h"
+
+class Tempo : public AbstractData
+{
+public:
+ // Constructors
+ Tempo();
+ Tempo(unsigned char* byte); // Parse Immidiately
+ Tempo(unsigned char divider, unsigned char modifier, bool); // Set value
+
+ // Direct Getters and Setters
+ unsigned char GetDivider();
+ void SetDivider(unsigned char value);
+
+ unsigned char Getmodifier();
+ void SetModifier(unsigned char value);
+
+ // Overides
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+private:
+ unsigned char divider;
+ unsigned char modifier;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Velocity.cpp b/music/pokeredmusicdisasm/Velocity.cpp
new file mode 100644
index 00000000..0000d4ba
--- /dev/null
+++ b/music/pokeredmusicdisasm/Velocity.cpp
@@ -0,0 +1,82 @@
+#include <sstream>
+#include "Velocity.h"
+using namespace std;
+
+Velocity::Velocity()
+{
+ velocity = 0;
+ length = 0;
+}
+
+Velocity::Velocity(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Velocity::Velocity(unsigned char velocity, unsigned char length, bool) // Set value
+{
+ SetVelocity(velocity);
+ SetLength(length);
+}
+
+// Direct Getters/Setters
+unsigned char Velocity::GetVelocity()
+{
+ return velocity;
+}
+
+void Velocity::SetVelocity(unsigned char value)
+{
+ velocity = value;
+}
+
+unsigned char Velocity::GetLength()
+{
+ return length;
+}
+
+void Velocity::SetLength(unsigned char value)
+{
+ length = value;
+}
+
+bool Velocity::IsValid(unsigned char* byte)
+{
+ if(byte[0] == 0xDC)
+ {
+ error = false;
+ return true;
+ }
+ else
+ {
+ error = true;
+ return false;
+ }
+}
+
+string Velocity::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return tmpRet;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_vel" << " " << (short)velocity << ", " << (short)length;
+ return tmpAsmOut.str();
+}
+
+bool Velocity::Parse(unsigned char* byte)
+{
+ if(!AbstractData::Parse(byte)) return false;
+
+ velocity = byte[1] & 0xF0;
+ velocity >>= 4;
+
+ length = byte[1] & 0x0F;
+ return true;
+}
+
+unsigned int Velocity::Arguments()
+{
+ // 1 1-byte argument
+ return 1;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Velocity.h b/music/pokeredmusicdisasm/Velocity.h
new file mode 100644
index 00000000..5f541b96
--- /dev/null
+++ b/music/pokeredmusicdisasm/Velocity.h
@@ -0,0 +1,32 @@
+#ifndef VELOCITY_H
+#define VELOCITY_H
+
+#include "AbstractData.h"
+
+class Velocity : public AbstractData
+{
+public:
+ // Constructors
+ Velocity();
+ Velocity(unsigned char* byte); // Parse Immidiately
+ Velocity(unsigned char velocity, unsigned char length, bool); // Set value
+
+ // Direct Getters/Setters
+ unsigned char GetVelocity();
+ void SetVelocity(unsigned char value);
+
+ unsigned char GetLength();
+ void SetLength(unsigned char value);
+
+ // Overides
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+private:
+ unsigned char velocity;
+ unsigned char length;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Volume.cpp b/music/pokeredmusicdisasm/Volume.cpp
new file mode 100644
index 00000000..3c717f0e
--- /dev/null
+++ b/music/pokeredmusicdisasm/Volume.cpp
@@ -0,0 +1,67 @@
+#include <sstream>
+#include "Volume.h"
+using namespace std;
+
+Volume::Volume()
+{
+ volume = 0;
+}
+
+Volume::Volume(unsigned char* byte) // Parse Immidiately
+{
+ Parse(byte);
+}
+
+Volume::Volume(unsigned char volume, bool) // Set value
+{
+ SetVolume(volume);
+}
+
+unsigned char Volume::GetVolume()
+{
+ return volume;
+}
+
+void Volume::SetVolume(unsigned char value)
+{
+ volume = value;
+}
+
+bool Volume::IsValid(unsigned char* byte)
+{
+ if(byte[0] == 0xF0)
+ {
+ error = false;
+ return true;
+ }
+ else
+ {
+ error = true;
+ return false;
+ }
+}
+
+string Volume::GenAsm()
+{
+ string tmpRet = AbstractData::GenAsm();
+ if(tmpRet != "") return false;
+
+ stringstream tmpAsmOut;
+ tmpAsmOut << "mus_volume" << " " << (short)volume;
+ return tmpAsmOut.str();
+}
+
+bool Volume::Parse(unsigned char* byte)
+{
+ // If it's not a Note, don't even bother parsing
+ if(!AbstractData::Parse(byte)) return false;
+
+ volume = byte[1];
+ return true;
+}
+
+unsigned int Volume::Arguments()
+{
+ // 1 1-byte argument = 1
+ return 1;
+} \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/Volume.h b/music/pokeredmusicdisasm/Volume.h
new file mode 100644
index 00000000..e716e910
--- /dev/null
+++ b/music/pokeredmusicdisasm/Volume.h
@@ -0,0 +1,28 @@
+#ifndef VOLUME_H
+#define VOLUME_H
+
+#include "AbstractData.h"
+
+class Volume : public AbstractData
+{
+public:
+ // Constructors
+ Volume();
+ Volume(unsigned char* byte); // Parse Immidiately
+ Volume(unsigned char volume, bool); // Set value
+
+ // Direct Getters / Setters
+ unsigned char GetVolume();
+ void SetVolume(unsigned char value);
+
+ // Re-implementations
+ virtual std::string GenAsm();
+ virtual bool IsValid(unsigned char* byte);
+ virtual bool Parse(unsigned char* byte);
+ virtual unsigned int Arguments();
+
+private:
+ unsigned char volume;
+};
+
+#endif \ No newline at end of file
diff --git a/music/pokeredmusicdisasm/main.cpp b/music/pokeredmusicdisasm/main.cpp
new file mode 100644
index 00000000..919fd719
--- /dev/null
+++ b/music/pokeredmusicdisasm/main.cpp
@@ -0,0 +1,39 @@
+#include "Console.h"
+#include "Parser.h"
+#include <sstream>
+#include <string>
+
+using namespace std;
+
+int main(int argc, char** argv)
+{
+ string arg1; // Offset
+ string arg2; // File
+
+ if(argc >= 3)
+ {
+ arg1 = argv[1];
+ arg2 = argv[2];
+ }
+ else if(argc == 2)
+ {
+ arg1 = argv[1];
+ arg2 = "../baserom.gbc";
+ }
+
+ if(arg1 == "") Console::Ask("What offset in the file in hex (0x----): ", arg1);
+ if(arg2 == "") Console::Ask("What file: ", arg2);
+
+ // Weird way of converting arg1 to an unsigned integer
+ stringstream arg1Conv;
+ unsigned int arg1ConvNum;
+ arg1Conv << arg1;
+ arg1Conv << hex;
+ arg1Conv >> arg1ConvNum;
+
+ Parser p(arg2);
+ p.Parse(arg1ConvNum);
+ Console::PrintLn(p.GetParsedAsm().c_str());
+
+ return 0;
+} \ No newline at end of file