shithub: pokered

Download patch

ref: 42569734720d794a4f1cd93e456ee8347dec7135
parent: 6fe067d939ee51d96c62c6f38eb50058ba4f4a26
author: KuroiIeWa5Da <tyuki@adu.me>
date: Sat Jan 28 01:10:44 EST 2012

Updated Music Disassembler to support more advanced parameters

hg-commit-id: 0aba4647e4f6


--- a/music/pokeredmusicdisasm/Console.cpp
+++ b/music/pokeredmusicdisasm/Console.cpp
@@ -33,7 +33,7 @@
 }
 
 // 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 @@
 {
     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;
-}
+}*/
\ No newline at end of file
--- a/music/pokeredmusicdisasm/Console.h
+++ b/music/pokeredmusicdisasm/Console.h
@@ -3,6 +3,7 @@
 
 #include <iostream>
 #include <string>
+#include <sstream>
 
 // Just a Console Utility Library
 class Console
@@ -19,11 +20,22 @@
     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
--- a/music/pokeredmusicdisasm/Makefile
+++ b/music/pokeredmusicdisasm/Makefile
@@ -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 @@
 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 @@
 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
--- /dev/null
+++ b/music/pokeredmusicdisasm/args.cpp
@@ -1,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;
+}
\ No newline at end of file
--- /dev/null
+++ b/music/pokeredmusicdisasm/args.h
@@ -1,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
\ No newline at end of file
--- a/music/pokeredmusicdisasm/main.cpp
+++ b/music/pokeredmusicdisasm/main.cpp
@@ -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)
-	{
-		arg1 = argv[1];
-		arg2 = argv[2];
-	}
-	else if(argc == (_max_argc - 1))
-	{
-		arg1 = argv[1];
-		arg2 = defFileLoc;
-	}
+	// 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;
 
-	// Process any parameters
-	if(argc > _max_argc)
+	// 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 == "")
 	{
-		for(int i = _max_argc; i < argc; i++)
-		{
-			string tmpArgv = argv[i];
-			if(tmpArgv.substr(0, 7) == "--stop=") paramStopAddr = tmpArgv.substr(7);
-		}
+		Console::PrintLn("Filename can't be blank");
+		return 1;
 	}
 
-	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
+	// 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);
 
-	// Weird way of converting arg1 to an unsigned integer
-	Parser p(arg2);
+	// Does arg #1 exist
+	else if(a.GetArgs() >= 1 + 1) a.GetValueC<unsigned int>(1, offset, ios_base::hex | ios_base::uppercase);
 
-	stringstream arg1Conv;
-	unsigned int arg1ConvNum;
-	arg1Conv << arg1;
-	arg1Conv << hex;
-	arg1Conv >> arg1ConvNum;
+	// Ask the user
+	else Console::Ask<unsigned int>("Offset: ", offset, ios_base::hex | ios_base::uppercase);
 
-	if(paramStopAddr != "")
-	{
-		stringstream paramStopAddrConv;
-		unsigned int paramStopAddrNum = 0;
-		paramStopAddrConv.str("");
-		paramStopAddrConv << paramStopAddr;
-		paramStopAddrConv << hex;
-		paramStopAddrConv >> paramStopAddrNum;
-		p.SetStopAddress(paramStopAddrNum);
-	}
+	// 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"));
 
-	p.Parse(arg1ConvNum);
+	Parser p(filePath);
+	if(stop != 0) p.SetStopAddress(stop);
+	p.Parse(offset);
+
 	Console::PrintLn(p.GetParsedAsm().c_str());
 
-	return 0;
+	return 0; 
 }
\ No newline at end of file