Updated Music Disassembler to support more advanced parameters

hg-commit-id: 0aba4647e4f6
This commit is contained in:
KuroiIeWa5Da 2012-01-28 06:10:44 -06:00
parent 6fe067d939
commit 4256973472
6 changed files with 203 additions and 62 deletions

View file

@ -33,7 +33,7 @@ void Console::ErrorLn(const char* value)
}
// Higher
void Console::Ask(const char* question, char* answer)
/*void Console::Ask(const char* question, char* answer)
{
Print(question);
Get(answer);
@ -42,13 +42,4 @@ 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

@ -3,6 +3,7 @@
#include <iostream>
#include <string>
#include <sstream>
// Just a Console Utility Library
class Console
@ -19,11 +20,22 @@ public:
static void ErrorLn(const char* value);
// Higher
static void Ask(const char* question, char* answer);
static void Ask(const char* question, std::string& answer);
//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);
template<class T>
static void Ask(const char* question, T& answer, std::ios_base::fmtflags flags = std::ios_base::dec)
{
std::stringstream _tmpstr;
std::string _tmp;
Print(question);
Get(_tmp);
_tmpstr << _tmp;
_tmpstr.flags(flags);
_tmpstr >> answer;
}
};
#endif // CONSOLE_H

View file

@ -1,7 +1,7 @@
OBJECTS = main.o Jump.o Modulation.o Note.o Octave.o Parser.o Stop.o \
Tempo.o UnkCode.o UnkEB.o Velocity.o Volume.o Console.o AbstractData.o Call.o \
Duty.o
Duty.o args.o
CC = g++
CFLAGS = -std=c++0x
@ -27,8 +27,8 @@ AbstractData.o: AbstractData.h
Call.o: Call.h Call.cpp AbstractData.h
$(CC) $(CFLAGS) -c Call.cpp AbstractData.cpp
main.o: main.cpp Console.h Parser.h
$(CC) $(CFLAGS) -c main.cpp Console.cpp Parser.cpp
main.o: main.cpp Console.h Parser.h args.h
$(CC) $(CFLAGS) -c main.cpp Console.cpp Parser.cpp args.cpp
Jump.o: Jump.h AbstractData.h
$(CC) $(CFLAGS) -c Jump.cpp AbstractData.cpp
@ -60,6 +60,9 @@ Velocity.o: Velocity.h AbstractData.h
Volume.o: Volume.h AbstractData.h
$(CC) $(CFLAGS) -c Volume.cpp AbstractData.cpp
args.o: args.h
$(CC) $(CFLAGS) -c args.cpp
clean:
rm *.o
rm ../../extras/pokeredmusicdisasm.exe

View file

@ -0,0 +1,93 @@
#include <sstream>
#include "args.h"
using namespace std;
Args::Args(int _argc, char**& _argv)
{
argc = _argc;
for(int i = 0; i < _argc; i++)
{
argv.push_back(string(_argv[i]));
}
}
//template<class T>
/*export void Args::GetArg(unsigned int ind, T& var, ios_base::fmtflags flags)
{
string stream _tmpstr;
_tmpstr << flags;
_tmpstr << GetArgv(ind);
_tmpstr >> var;
}*/
int Args::GetArgs()
{
return argv.size();
}
string Args::GetArgv(int ind)
{
return argv[ind];
}
bool Args::IsLongOption(int ind) // Is that argument a --long-key=value
{
if(GetArgv(ind).substr(0, 2) == "--") return true;
else return false;
}
bool Args::IsShortOption(int ind, bool param2) // Is that argument a --long-key=value
{
if(param2)
{
if(GetArgv(ind).substr(0, 1) == "-" && // The argument must start with -
GetArgv(ind).substr(0, 2) != "--" && // The argument can't start with "--"
ind + 1 < GetArgs()) return true; // The second argument must exist
}
else
{
if(GetArgv(ind).substr(0, 1) == "-" && // The argument must start with -
GetArgv(ind).substr(0, 2) != "--") return true; // The argument can't start with "--"
}
return false;
}
string Args::GetKey(int ind) // Get the key, if not a key/value then returns the arg
{
if(IsLongOption(ind) && GetArgv(ind).find("=") != string::npos) return GetArgv(ind).substr(2, GetArgv(ind).find("=") - 2);
else if(IsShortOption(ind)) return GetArgv(ind).substr(1);
else return GetArgv(ind);
}
string Args::GetValue(int ind, bool param2) // Get the value , if not a key/value then returns the arg
{
if(IsLongOption(ind) && GetArgv(ind).find("=") != string::npos) return GetArgv(ind).substr(GetArgv(ind).find("=") + 1);
else if(IsShortOption(ind, param2))
{
if(param2) return GetArgv(ind + 1);
else return GetArgv(ind);
}
return GetArgv(ind);
}
int Args::SearchKeys(const char* str)
{
string needle = str;
string scr = "";
unsigned int pos = -1;
for(int i = 0; i < GetArgs(); i++)
{
scr = GetKey(i);
if(scr == needle)
{
pos = i;
break;
}
}
return pos;
}

View file

@ -0,0 +1,38 @@
#ifndef ARGS_H
#define ARGS_H
#include <string>
#include <vector>
#include <sstream>
class Args
{
public:
Args(int _argc, char**& _argv);
template<class T> // Get the argument automatically in any format that stringstream can output to
void GetValueC(int ind, T& var, std::ios_base::fmtflags flags = std::ios_base::dec, bool param2 = false)
{
std::stringstream _tmpstr;
_tmpstr << GetValue(ind, param2);
_tmpstr.flags(flags);
_tmpstr >> var;
}
int GetArgs(); // Get number of args
std::string GetArgv(int ind); // Get the arg based on true index
bool IsLongOption(int ind); // Is that argument a --long-key=value
bool IsShortOption(int ind, bool param2 = false); // Is that argument a --long-key=value
std::string GetKey(int ind); // Get the key, if not a key/value then returns the arg
std::string GetValue(int ind, bool param2 = false); // Get the value, if not a key/value then returns the arg
int SearchKeys(const char* str); // Return the index number of found key or -1 if not found
private:
int argc;
std::vector<std::string> argv;
};
#endif

View file

@ -1,69 +1,73 @@
#include "Console.h"
#include "Parser.h"
#include "args.h"
#include <sstream>
#include <string>
using namespace std;
/*
Usage:
pokeredmusicdisasm [<offset> [<file> | --]]
pokeredmusicdisasm [--offset=<offset> | -o <offset>] [--file=[<file> | --] | -f [<file> | --]] [--stop=<offset> | -s <offset>]
*/
int main(int argc, char** argv)
{
Args a(argc, argv);
const unsigned char parameters = 2;
const unsigned char self = 1;
const unsigned char _max_argc = parameters + self;
const string defFileLoc = "../baserom.gbc";
string arg1; // Offset
string arg2; // File or "--" (if "--" then the file is assumed)
string filePath = "";
unsigned int offset = 0;
unsigned int stop = 0;
string paramStopAddr;
// Get the file path, this can be set with -f filename, --file=filename, arg #2, or missing (missing means default)
// the filepath can contain the actual filename or -- to use the built-in path, if the path is not missing then it must be set (can't be blank)
// Does a -f or --file key exist
if(a.SearchKeys("f") != -1) filePath = a.GetValue(a.SearchKeys("f"), true);
else if(a.SearchKeys("file") != -1) filePath = a.GetValue(a.SearchKeys("file"));
if(argc >= _max_argc)
// BUG FIX: a short parameter can be either 1 or 2 parts so this causes the if statement below to load incorrect info if
// -f or --file isn't specified and the first argument is a short parameter "-x x"
else if((a.GetArgs() == (2 + 1)) && (a.IsShortOption(1, true))) filePath = defFileLoc;
// Does arg #2 exist
else if(a.GetArgs() >= 2 + 1) a.GetValueC<string>(2, filePath);
// Is there at least 1 arg (In that case it's missing and the default can be assumed)
else if(a.GetArgs() >= 1 + 1) filePath = defFileLoc;
// Ask the user
else Console::Ask("Filepath: ", filePath);
if(filePath == "--") filePath = defFileLoc;
else if(filePath == "")
{
arg1 = argv[1];
arg2 = argv[2];
}
else if(argc == (_max_argc - 1))
{
arg1 = argv[1];
arg2 = defFileLoc;
Console::PrintLn("Filename can't be blank");
return 1;
}
// Process any parameters
if(argc > _max_argc)
{
for(int i = _max_argc; i < argc; i++)
{
string tmpArgv = argv[i];
if(tmpArgv.substr(0, 7) == "--stop=") paramStopAddr = tmpArgv.substr(7);
}
}
// Get the offset, this can be set with -o <offset>, --offset=<offset>, or as arg #1
if(a.SearchKeys("o") != -1) a.GetValueC<unsigned int>(a.SearchKeys("o"), offset, ios_base::hex | ios_base::uppercase, true);
else if(a.SearchKeys("offset") != -1) a.GetValueC(a.SearchKeys("offset"), offset, ios_base::hex | ios_base::uppercase);
if(arg1 == "") Console::Ask("What offset in the file in hex (0x----): ", arg1);
if(arg2 == "") Console::Ask("What file: ", arg2);
if(arg2 == "--") arg2 = defFileLoc; // You can also put "--" for the default file location
// Does arg #1 exist
else if(a.GetArgs() >= 1 + 1) a.GetValueC<unsigned int>(1, offset, ios_base::hex | ios_base::uppercase);
// Weird way of converting arg1 to an unsigned integer
Parser p(arg2);
// Ask the user
else Console::Ask<unsigned int>("Offset: ", offset, ios_base::hex | ios_base::uppercase);
stringstream arg1Conv;
unsigned int arg1ConvNum;
arg1Conv << arg1;
arg1Conv << hex;
arg1Conv >> arg1ConvNum;
// Get the stop parameter, this can be set with -s <offset>, --stop=<offset> (it must be set via args)
if(a.SearchKeys("s") != -1) a.GetValueC<unsigned int>(a.SearchKeys("s"), offset, ios_base::hex | ios_base::uppercase, true);
else if(a.SearchKeys("stop") != -1) filePath = a.GetValue(a.SearchKeys("stop"));
if(paramStopAddr != "")
{
stringstream paramStopAddrConv;
unsigned int paramStopAddrNum = 0;
paramStopAddrConv.str("");
paramStopAddrConv << paramStopAddr;
paramStopAddrConv << hex;
paramStopAddrConv >> paramStopAddrNum;
p.SetStopAddress(paramStopAddrNum);
}
Parser p(filePath);
if(stop != 0) p.SetStopAddress(stop);
p.Parse(offset);
p.Parse(arg1ConvNum);
Console::PrintLn(p.GetParsedAsm().c_str());
return 0;
return 0;
}