diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0930688..d0a871c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -49,4 +49,4 @@ endif()
include_directories(${CMAKE_CURRENT_BINARY_DIR})
-add_subdirectory(src)
\ No newline at end of file
+add_subdirectory(src)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6d133ac..d80ab93 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -11,6 +11,7 @@ endif()
file(GLOB script2txt_src "script2txt/*")
add_executable(script2txt ${script2txt_src})
+target_link_libraries(script2txt common)
if (DATA_MANAGER_DIR)
diff --git a/src/common/common.h b/src/common/common.h
new file mode 100644
index 0000000..e0c9406
--- /dev/null
+++ b/src/common/common.h
@@ -0,0 +1,40 @@
+/*
+* AIM tools
+* Copyright (C) 2015 lzwdgc
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+template
+bool replace_all(T &str, const T &from, const T &to)
+{
+ bool replaced = false;
+ size_t start_pos = 0;
+ while ((start_pos = str.find(from, start_pos)) != T::npos)
+ {
+ str.replace(start_pos, from.length(), to);
+ start_pos += to.length();
+ replaced = true;
+ }
+ return replaced;
+}
+
+inline bool replace_all(std::string &str, const std::string &from, const std::string &to)
+{
+ return replace_all(str, from, to);
+}
diff --git a/src/script2txt/script.h b/src/script2txt/script.h
new file mode 100644
index 0000000..e8a9c3c
--- /dev/null
+++ b/src/script2txt/script.h
@@ -0,0 +1,135 @@
+/*
+* AIM script2txt
+* Copyright (C) 2015 lzwdgc
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+
+#include
+#include
+
+struct script
+{
+ uint32_t file_size;
+ uint32_t unk0;
+ uint32_t raw_text_size;
+ uint32_t unk1;
+ std::vector raw_text;
+ uint32_t array_len;
+ std::vector unk2;
+
+ //
+ std::vector lines;
+
+ void load(buffer &b)
+ {
+ READ(b, file_size);
+ READ(b, unk0);
+ READ(b, raw_text_size);
+ READ(b, unk1);
+ raw_text.resize(raw_text_size);
+ READ_N(b, raw_text[0], raw_text.size());
+ READ(b, array_len);
+ unk2.resize(array_len);
+ READ_N(b, unk2[0], unk2.size());
+
+ if (!b.eof())
+ {
+ std::stringstream ss;
+ ss << std::hex << b.index() << " != " << std::hex << b.size();
+ throw std::logic_error(ss.str());
+ }
+
+ fix_text();
+ beautify();
+ }
+
+ void fix_text()
+ {
+ std::string line;
+ for (size_t i = 0; i < raw_text.size(); i++)
+ {
+ if (raw_text[i] == 0)
+ {
+ lines.push_back(line);
+ line.clear();
+ }
+ else
+ line.push_back(raw_text[i]);
+ }
+ }
+
+ void beautify()
+ {
+ const std::string space = " ";
+ int brace_count = 0;
+ int proc_started = 0;
+ for (auto &line : lines)
+ {
+ if (brace_count > 0 || proc_started > 0)
+ {
+ auto space_count = brace_count + proc_started;
+ if (line == "}" ||
+ (brace_count == 0 && proc_started == 1 &&
+ line.find("END") != line.npos))
+ space_count--;
+ std::string s;
+ for (int i = 0; i < space_count; i++)
+ s += space;
+ line = s + line;
+ }
+ if (line.find("PROC") != line.npos &&
+ line.find("()") != line.npos)
+ {
+ proc_started++;
+ continue;
+ }
+ if (line.find("END") != line.npos && proc_started == 1)
+ {
+ proc_started--;
+ }
+ for (auto &c : line)
+ {
+ if (c == '{')
+ brace_count++;
+ else if (c == '}')
+ brace_count--;
+ if (brace_count < 0)
+ {
+ c = '\n';
+ brace_count++;
+ }
+ }
+ }
+ }
+
+ std::string get_text() const
+ {
+ std::string s;
+ for (auto &line : lines)
+ {
+ if (line != "\n")
+ s += line + "\n";
+ }
+ replace_all(s, "IF(", "IF (");
+ replace_all(s, "\nIF", "\n\nIF");
+ replace_all(s, "PROC", "PROC ");
+ replace_all(s, "END\nPROC", "END\n\nPROC");
+ return s;
+ }
+};
diff --git a/src/script2txt/script2txt.bat b/src/script2txt/script2txt.bat
new file mode 100644
index 0000000..60c0b7d
--- /dev/null
+++ b/src/script2txt/script2txt.bat
@@ -0,0 +1,2 @@
+@for /r %%v in (*.scr) do script2txt.exe "%%v"
+@for /r %%v in (*.QST) do script2txt.exe "%%v"
diff --git a/src/script2txt/script2txt.cpp b/src/script2txt/script2txt.cpp
index c2cdc74..3b025e3 100644
--- a/src/script2txt/script2txt.cpp
+++ b/src/script2txt/script2txt.cpp
@@ -16,47 +16,46 @@
* along with this program. If not, see .
*/
+#include
#include
#include
-using namespace std;
+#include "script.h"
+
+using std::cout;
+using std::string;
int main(int argc, char *argv[])
+try
{
if (argc != 2)
{
cout << "Usage:\n" << argv[0] << " script.scr";
return 1;
}
- string path = argv[1];
- FILE *f = fopen(path.c_str(), "rb");
- if (!f)
- {
- cout << "Cannot open the file: " << argv[1];
- return 2;
- }
- uint32_t size = 0;
- uint32_t dummy = 0;
- fread(&size, sizeof(uint32_t), 1, f);
- fread(&size, sizeof(uint32_t), 1, f);
- fread(&size, sizeof(uint32_t), 1, f);
- fread(&dummy, sizeof(uint32_t), 1, f);
- string buf(size, 0);
- fread(&buf[0], size, 1, f);
- fclose(f);
- path += ".txt";
- f = fopen(path.c_str(), "w");
- if (!f)
- {
- cout << "Cannot open the file: " << argv[1];
- return 3;
- }
- const char *ptr = &buf[0];
- while (ptr < &buf[0] + size)
- {
- fprintf(f, "%s\n", ptr);
- ptr += strlen(ptr) + 1;
- }
- fclose(f);
+
+ std::string filename = argv[1];
+
+ // read
+ buffer b(readFile(filename));
+ script s;
+ s.load(b);
+ auto str = s.get_text();
+
+ // write
+ filename += ".txt";
+ std::ofstream ofile(filename);
+ if (ofile)
+ ofile << str;
return 0;
-}
\ No newline at end of file
+}
+catch (std::exception &e)
+{
+ printf("error: %s\n", e.what());
+ return 1;
+}
+catch (...)
+{
+ printf("error: unknown exception\n");
+ return 1;
+}