mirror of
https://github.com/pret/pokered.git
synced 2024-10-23 15:08:23 +00:00
Merge music changes
hg-commit-id: 279fd0d79924
This commit is contained in:
commit
b42672a0a0
8 changed files with 1635 additions and 96 deletions
|
@ -10,12 +10,12 @@ public:
|
||||||
AbstractData();
|
AbstractData();
|
||||||
|
|
||||||
virtual std::string GenAsm(); // Generate Assembly Output
|
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 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)
|
virtual bool GetError(); // Get Error (No Write, Error is read only)
|
||||||
|
|
||||||
|
virtual bool IsValid(unsigned char* byte); // Check for byte validity
|
||||||
|
virtual unsigned int Arguments(); // Number of arguments taken
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool error; // Whether there's an error in parsing or not
|
bool error; // Whether there's an error in parsing or not
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@ Parser::Parser(std::string filename)
|
||||||
fileLength = 0;
|
fileLength = 0;
|
||||||
filePos = 0;
|
filePos = 0;
|
||||||
stop = false;
|
stop = false;
|
||||||
|
stopAddress = 0;
|
||||||
|
|
||||||
SetFilename(filename);
|
SetFilename(filename);
|
||||||
}
|
}
|
||||||
|
@ -63,7 +64,9 @@ string Parser::GetParsedAsm()
|
||||||
|
|
||||||
for(unsigned int i = 0; i < parsedString.size(); i++)
|
for(unsigned int i = 0; i < parsedString.size(); i++)
|
||||||
{
|
{
|
||||||
tmpStr += parsedString[i] + "\n";
|
// Ensure each line isn't already a new-line, this prevents double or tripple empty lines from piling up
|
||||||
|
if(parsedString[i] != "\n") tmpStr += parsedString[i] + "\n";
|
||||||
|
else tmpStr += parsedString[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
return tmpStr;
|
return tmpStr;
|
||||||
|
@ -87,6 +90,8 @@ void Parser::Read()
|
||||||
// Read filedata
|
// Read filedata
|
||||||
tmpFile.read(rawBytes, fileLength);
|
tmpFile.read(rawBytes, fileLength);
|
||||||
tmpFile.close();
|
tmpFile.close();
|
||||||
|
|
||||||
|
rawBytesFixed = (unsigned char*)rawBytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Code Operations
|
// Code Operations
|
||||||
|
@ -96,114 +101,165 @@ void Parser::Parse(unsigned int offset)
|
||||||
ParseNext();
|
ParseNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
bool Parser::ParseData(unsigned int& pos, bool reado)
|
||||||
|
{
|
||||||
|
// Create the class to use if correct and a dummy class for validating
|
||||||
|
T* tmpC = 0;
|
||||||
|
T dummy;
|
||||||
|
|
||||||
|
// If the bytes are this data type then create and save it
|
||||||
|
if(dummy.IsValid(&rawBytesFixed[pos]))
|
||||||
|
{
|
||||||
|
// Ensure this whole opperation isn't read-only (just peeking)
|
||||||
|
if(!reado)
|
||||||
|
{
|
||||||
|
// Initialize the class
|
||||||
|
tmpC = new T(&rawBytesFixed[pos]);
|
||||||
|
|
||||||
|
// Push it onto the stack and it's assembly generation onto the output class
|
||||||
|
parsedBytes.push_back(tmpC); //
|
||||||
|
parsedString.push_back(tmpC->GenAsm());
|
||||||
|
|
||||||
|
// If the class had any arguments, increment the counter that much forward
|
||||||
|
pos += tmpC->Arguments();
|
||||||
|
}
|
||||||
|
return true; // Let the code know this class was valid
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // Let the code know this class wasn't valid
|
||||||
|
}
|
||||||
|
|
||||||
void Parser::ParseNext() // Parses the block immidiately following
|
void Parser::ParseNext() // Parses the block immidiately following
|
||||||
{
|
{
|
||||||
stringstream tmpStr;
|
stringstream tmpStr;
|
||||||
unsigned char* rawBytesFixed = (unsigned char*)rawBytes;
|
|
||||||
stop = false;
|
stop = false;
|
||||||
|
|
||||||
// Smart generation
|
// Smart generation
|
||||||
bool indent = false;
|
bool firstNonNote = false; // (unused so far)First byte wasn't a note or octacve switch, add ";Setup" comment
|
||||||
bool firstNonNote = false; // First byte wasn't a note or octacve switch, add ";Setup" comment
|
bool firstNote = false; // (unused so far) First note or octave
|
||||||
bool firstNote = false; // First note or octave
|
unsigned char lDataType = DATA_NA;
|
||||||
|
|
||||||
stringstream pos;
|
stringstream pos;
|
||||||
pos << "; " << hex << uppercase << (unsigned int)filePos;
|
pos << "; " << hex << uppercase << (unsigned int)filePos;
|
||||||
parsedString.push_back(pos.str());
|
parsedString.push_back(pos.str());
|
||||||
|
|
||||||
|
unsigned int count = 1; // Counter for processed instructions
|
||||||
for(unsigned int i = filePos; (i <= fileLength) && (stop == false); i++)
|
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
|
// First peek to see what kind of data it is, then perform any pre and post setup
|
||||||
|
if(ParseData<Call>(i, true))
|
||||||
|
{
|
||||||
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
// Check to see if it's the correct data type and if so then use it
|
ParseData<Call>(i);
|
||||||
if(tmpCall.IsValid(&rawBytesFixed[i])) // Should have made IsValid static
|
lDataType = DATA_CALL;
|
||||||
|
}
|
||||||
|
else if(ParseData<Duty>(i, true))
|
||||||
{
|
{
|
||||||
// Call data type
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
// Create data type then move the increment pointer further up as needed
|
ParseData<Duty>(i);
|
||||||
parsedBytes.push_back(new Call(&rawBytesFixed[i]));
|
lDataType = DATA_DUTY;
|
||||||
parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
|
}
|
||||||
i += tmpCall.Arguments(); // should have made Arguments static
|
else if(ParseData<Jump>(i, true))
|
||||||
|
{
|
||||||
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
Call* _tmp = (Call*)parsedBytes[parsedBytes.size() - 1];
|
ParseData<Jump>(i);
|
||||||
|
lDataType = DATA_JUMP;
|
||||||
}
|
}
|
||||||
else if(tmpDuty.IsValid(&rawBytesFixed[i]))
|
else if(ParseData<Modulation>(i, true))
|
||||||
{
|
{
|
||||||
// Duty data type
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
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];
|
ParseData<Modulation>(i);
|
||||||
|
lDataType = DATA_MODULATION;
|
||||||
}
|
}
|
||||||
else if(tmpModulation.IsValid(&rawBytesFixed[i]))
|
else if(ParseData<Note>(i, true))
|
||||||
{
|
{
|
||||||
// Modulation data type
|
// Insert a newline after certain types
|
||||||
parsedBytes.push_back(new Modulation(&rawBytesFixed[i]));
|
if((lDataType == DATA_UNKCODE) ||
|
||||||
parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
|
(lDataType == DATA_UNKEB)) parsedString.push_back("\n");
|
||||||
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
|
// If the previous item was a rest note then insert a new line
|
||||||
}
|
else if(lDataType == DATA_NOTE)
|
||||||
else if(tmpTempo.IsValid(&rawBytesFixed[i]))
|
|
||||||
{
|
{
|
||||||
// Tempo data type
|
Note* _tmpNote = (Note*)parsedBytes[parsedBytes.size() - 1];
|
||||||
parsedBytes.push_back(new Tempo(&rawBytesFixed[i]));
|
if(_tmpNote->GetPitch() == _tmpNote->noteRst) parsedString.push_back("\n");
|
||||||
parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
|
|
||||||
i += tmpTempo.Arguments();
|
|
||||||
}
|
}
|
||||||
else if(tmpVelocity.IsValid(&rawBytesFixed[i]))
|
|
||||||
{
|
ParseData<Note>(i);
|
||||||
// Velocity data type
|
|
||||||
parsedBytes.push_back(new Velocity(&rawBytesFixed[i]));
|
// Further indent each note
|
||||||
parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
|
parsedString[parsedString.size() - 1] = "\t" + parsedString[parsedString.size() - 1];
|
||||||
i += tmpVelocity.Arguments();
|
lDataType = DATA_NOTE;
|
||||||
}
|
}
|
||||||
else if(tmpVolume.IsValid(&rawBytesFixed[i]))
|
else if(ParseData<Octave>(i, true))
|
||||||
{
|
{
|
||||||
// Volume data type
|
// Insert new-line if previous line isn't a newline
|
||||||
parsedBytes.push_back(new Volume(&rawBytesFixed[i]));
|
if(parsedString[parsedString.size() - 1] != "\n") parsedString.push_back("\n");
|
||||||
parsedString.push_back(parsedBytes[parsedBytes.size() - 1]->GenAsm());
|
|
||||||
i += tmpVolume.Arguments();
|
ParseData<Octave>(i);
|
||||||
|
lDataType = DATA_OCTAVE;
|
||||||
|
}
|
||||||
|
else if(ParseData<Tempo>(i, true))
|
||||||
|
{
|
||||||
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
|
ParseData<Tempo>(i);
|
||||||
|
lDataType = DATA_TEMPO;
|
||||||
|
}
|
||||||
|
else if(ParseData<Velocity>(i, true))
|
||||||
|
{
|
||||||
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
|
ParseData<Velocity>(i);
|
||||||
|
lDataType = DATA_VELOCITY;
|
||||||
|
}
|
||||||
|
else if(ParseData<Volume>(i, true))
|
||||||
|
{
|
||||||
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
|
ParseData<Volume>(i);
|
||||||
|
lDataType = DATA_VOLUME;
|
||||||
|
}
|
||||||
|
else if(ParseData<UnkEB>(i, true)) // The opcode is 0xEB which is unknown and takes a 1-byte argument
|
||||||
|
{
|
||||||
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
|
ParseData<UnkEB>(i);
|
||||||
|
lDataType = DATA_UNKEB;
|
||||||
|
}
|
||||||
|
else if(ParseData<Stop>(i, true))
|
||||||
|
{
|
||||||
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
|
|
||||||
|
ParseData<Stop>(i);
|
||||||
|
stop = true; // Raise the stop flag informing the parser to stop
|
||||||
|
lDataType = DATA_STOP;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Unknown code
|
if(lDataType == DATA_NOTE) parsedString.push_back("\n"); // Insert a newline after notes
|
||||||
stringstream unkCode;
|
|
||||||
short tmpByte = (short)rawBytesFixed[i];
|
ParseData<UnkCode>(i); // The opcode is unknown - process the raw byte and move on
|
||||||
unkCode << "db $" << hex << uppercase << (short)rawBytesFixed[i];
|
lDataType = DATA_UNKCODE;
|
||||||
parsedString.push_back(unkCode.str());
|
}
|
||||||
|
|
||||||
|
// Put everything tabbed over at least 1 time to fix some weird RGBDS bug by pre-pending a tab character
|
||||||
|
parsedString[parsedString.size() - 1] = "\t" + parsedString[parsedString.size() - 1];
|
||||||
|
|
||||||
|
// Append File Position in hexidecimal at end of line every 5 instructions
|
||||||
|
if((count % 5) == 0)
|
||||||
|
{
|
||||||
|
stringstream _tmpCount;
|
||||||
|
_tmpCount << hex << uppercase << i;
|
||||||
|
parsedString[parsedString.size() - 1] = parsedString[parsedString.size() - 1] + "; " + _tmpCount.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
filePos = i;
|
filePos = i;
|
||||||
|
count++;
|
||||||
|
|
||||||
// If the stop address parameter is set, break when we get there
|
// If the stop address parameter is set, break when we get there
|
||||||
if( (stopAddress != 0) && (i >= stopAddress) ) break;
|
if( (stopAddress != 0) && (i >= stopAddress) ) break;
|
||||||
|
|
|
@ -13,11 +13,12 @@
|
||||||
#include "Modulation.h"
|
#include "Modulation.h"
|
||||||
#include "Note.h"
|
#include "Note.h"
|
||||||
#include "Octave.h"
|
#include "Octave.h"
|
||||||
#include "Parser.h"
|
|
||||||
#include "Stop.h"
|
#include "Stop.h"
|
||||||
#include "Tempo.h"
|
#include "Tempo.h"
|
||||||
#include "Velocity.h"
|
#include "Velocity.h"
|
||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
#include "UnkCode.h"
|
||||||
|
#include "UnkEB.h"
|
||||||
|
|
||||||
// This is the final class, it takes all of the data types, abstract class, and helper functions and uses them
|
// This is the final class, it takes all of the data types, abstract class, and helper functions and uses them
|
||||||
// for parsing
|
// for parsing
|
||||||
|
@ -49,30 +50,40 @@ public:
|
||||||
void Parse(unsigned int offset);
|
void Parse(unsigned int offset);
|
||||||
void ParseNext(); // Parses the block immidiately following
|
void ParseNext(); // Parses the block immidiately following
|
||||||
|
|
||||||
|
// Templates
|
||||||
|
template<class T>
|
||||||
|
bool ParseData(unsigned int& pos, bool reado = false);
|
||||||
|
|
||||||
|
const enum dataType : unsigned char
|
||||||
|
{
|
||||||
|
DATA_NA,
|
||||||
|
DATA_CALL,
|
||||||
|
DATA_DUTY,
|
||||||
|
DATA_JUMP,
|
||||||
|
DATA_MODULATION,
|
||||||
|
DATA_NOTE,
|
||||||
|
DATA_OCTAVE,
|
||||||
|
DATA_STOP,
|
||||||
|
DATA_TEMPO,
|
||||||
|
DATA_UNKCODE,
|
||||||
|
DATA_UNKEB,
|
||||||
|
DATA_VELOCITY,
|
||||||
|
DATA_VOLUME
|
||||||
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string filename;
|
std::string filename;
|
||||||
std::vector<AbstractData*> parsedBytes;
|
std::vector<AbstractData*> parsedBytes;
|
||||||
std::vector<std::string> parsedString;
|
std::vector<std::string> parsedString;
|
||||||
|
|
||||||
char* rawBytes;
|
char* rawBytes;
|
||||||
|
unsigned char* rawBytesFixed;
|
||||||
unsigned int fileLength;
|
unsigned int fileLength;
|
||||||
unsigned int filePos;
|
unsigned int filePos;
|
||||||
bool stop;
|
bool stop;
|
||||||
|
|
||||||
// Optional Settings
|
// Optional Settings
|
||||||
unsigned int stopAddress;
|
unsigned int stopAddress;
|
||||||
|
|
||||||
// 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
|
#endif
|
67
music/pokeredmusicdisasm/UnkCode.cpp
Normal file
67
music/pokeredmusicdisasm/UnkCode.cpp
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "Call.h"
|
||||||
|
#include "Duty.h"
|
||||||
|
#include "Jump.h"
|
||||||
|
#include "Modulation.h"
|
||||||
|
#include "Note.h"
|
||||||
|
#include "Octave.h"
|
||||||
|
#include "Stop.h"
|
||||||
|
#include "Tempo.h"
|
||||||
|
#include "Velocity.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
#include "UnkCode.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
UnkCode::UnkCode()
|
||||||
|
{
|
||||||
|
code = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnkCode::UnkCode(unsigned char* byte)
|
||||||
|
{
|
||||||
|
code = 0;
|
||||||
|
Parse(byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnkCode::UnkCode(unsigned char code, bool)
|
||||||
|
{
|
||||||
|
SetCode(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters / Setters
|
||||||
|
unsigned char UnkCode::GetCode()
|
||||||
|
{
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnkCode::SetCode(unsigned char value)
|
||||||
|
{
|
||||||
|
code = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-implemented
|
||||||
|
string UnkCode::GenAsm()
|
||||||
|
{
|
||||||
|
stringstream tmpAsmOut;
|
||||||
|
tmpAsmOut << "db $" << hex << (short)code;
|
||||||
|
return tmpAsmOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnkCode::Parse(unsigned char* byte)
|
||||||
|
{
|
||||||
|
code = byte[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnkCode::IsValid(unsigned char* byte)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int UnkCode::Arguments()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
29
music/pokeredmusicdisasm/UnkCode.h
Normal file
29
music/pokeredmusicdisasm/UnkCode.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef UNKCODE_H
|
||||||
|
#define UNKCODE_H
|
||||||
|
|
||||||
|
#include "AbstractData.h"
|
||||||
|
|
||||||
|
// Represents an unknown opcode
|
||||||
|
class UnkCode : public AbstractData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
UnkCode();
|
||||||
|
UnkCode(unsigned char* byte); // Parse Immidiately
|
||||||
|
UnkCode(unsigned char code, bool); // Set Value
|
||||||
|
|
||||||
|
// Getters / Setters
|
||||||
|
unsigned char GetCode();
|
||||||
|
void SetCode(unsigned char value);
|
||||||
|
|
||||||
|
// Re-implemented
|
||||||
|
virtual std::string GenAsm();
|
||||||
|
virtual bool Parse(unsigned char* byte);
|
||||||
|
virtual bool IsValid(unsigned char* byte);
|
||||||
|
virtual unsigned int Arguments();
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned char code;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
69
music/pokeredmusicdisasm/UnkEB.cpp
Normal file
69
music/pokeredmusicdisasm/UnkEB.cpp
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "Call.h"
|
||||||
|
#include "Duty.h"
|
||||||
|
#include "Jump.h"
|
||||||
|
#include "Modulation.h"
|
||||||
|
#include "Note.h"
|
||||||
|
#include "Octave.h"
|
||||||
|
#include "Stop.h"
|
||||||
|
#include "Tempo.h"
|
||||||
|
#include "Velocity.h"
|
||||||
|
#include "Volume.h"
|
||||||
|
|
||||||
|
#include "UnkEB.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
UnkEB::UnkEB()
|
||||||
|
{
|
||||||
|
param = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnkEB::UnkEB(unsigned char* byte)
|
||||||
|
{
|
||||||
|
param = 0;
|
||||||
|
Parse(byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
UnkEB::UnkEB(unsigned char code, bool)
|
||||||
|
{
|
||||||
|
SetParam(code);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters / Setters
|
||||||
|
unsigned char UnkEB::GetParam()
|
||||||
|
{
|
||||||
|
return param;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UnkEB::SetParam(unsigned char value)
|
||||||
|
{
|
||||||
|
param = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Re-implemented
|
||||||
|
string UnkEB::GenAsm()
|
||||||
|
{
|
||||||
|
stringstream tmpAsmOut;
|
||||||
|
tmpAsmOut << hex << "db $" << (short)0xEB << ", $" << (short)param;
|
||||||
|
return tmpAsmOut.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnkEB::Parse(unsigned char* byte)
|
||||||
|
{
|
||||||
|
param = byte[1];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UnkEB::IsValid(unsigned char* byte)
|
||||||
|
{
|
||||||
|
if(byte[0] == 0xEB) return true;
|
||||||
|
else return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int UnkEB::Arguments()
|
||||||
|
{
|
||||||
|
// 1 1-Byte param
|
||||||
|
return 1;
|
||||||
|
}
|
29
music/pokeredmusicdisasm/UnkEB.h
Normal file
29
music/pokeredmusicdisasm/UnkEB.h
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef UNKEB_H
|
||||||
|
#define UNKEB_H
|
||||||
|
|
||||||
|
#include "AbstractData.h"
|
||||||
|
|
||||||
|
// Represents an unknown opcode
|
||||||
|
class UnkEB : public AbstractData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
// Constructors
|
||||||
|
UnkEB();
|
||||||
|
UnkEB(unsigned char* byte); // Parse Immidiately
|
||||||
|
UnkEB(unsigned char code, bool); // Set Value
|
||||||
|
|
||||||
|
// Getters / Setters
|
||||||
|
unsigned char GetParam();
|
||||||
|
void SetParam(unsigned char value);
|
||||||
|
|
||||||
|
// Re-implemented
|
||||||
|
virtual std::string GenAsm();
|
||||||
|
virtual bool Parse(unsigned char* byte);
|
||||||
|
virtual bool IsValid(unsigned char* byte);
|
||||||
|
virtual unsigned int Arguments();
|
||||||
|
|
||||||
|
private:
|
||||||
|
unsigned char param;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
Loading…
Reference in a new issue