From 4d0797bc3a6ae0ea4b44e8b6463339d662f5d669 Mon Sep 17 00:00:00 2001 From: KuroiIeWa5Da Date: Mon, 23 Jan 2012 01:41:05 -0600 Subject: made changes in repo hg-commit-id: 1145e088ee27 --- music/pokeredmusicdisasm/Parser.cpp | 203 ++++++++++++++++++++++++++++++++++++ 1 file changed, 203 insertions(+) create mode 100644 music/pokeredmusicdisasm/Parser.cpp (limited to 'music/pokeredmusicdisasm/Parser.cpp') 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 +#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 -- cgit v1.3.1-sl0p