made changes in repo

hg-commit-id: 1145e088ee27
This commit is contained in:
KuroiIeWa5Da 2012-01-23 01:41:05 -06:00
parent 21caa525cc
commit 4d0797bc3a
30 changed files with 1748 additions and 0 deletions

View file

@ -24,3 +24,5 @@ pokered.sav
#for vim configuration
#url: http://www.vim.org/scripts/script.php?script_id=441
.lvimrc
*.exe

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}