mirror of
https://github.com/autc04/Retro68.git
synced 2024-09-30 01:57:08 +00:00
ConvertOBJ: sort modules to go easy on 16-bit relative references
This commit is contained in:
parent
5c968dc589
commit
c95a59f75e
@ -1,6 +1,7 @@
|
|||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include "BinaryIO.h"
|
#include "BinaryIO.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@ -66,6 +67,8 @@ struct Module
|
|||||||
unordered_map<uint32_t, vector<string>> labels;
|
unordered_map<uint32_t, vector<string>> labels;
|
||||||
unordered_map<uint32_t, Reloc> relocs;
|
unordered_map<uint32_t, Reloc> relocs;
|
||||||
|
|
||||||
|
std::vector<std::weak_ptr<Module>> nearrefs;
|
||||||
|
|
||||||
void write(std::ostream& out);
|
void write(std::ostream& out);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -137,12 +140,83 @@ void Module::write(std::ostream& out)
|
|||||||
out << "# ######\n\n";
|
out << "# ######\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void sortModules(std::vector<std::shared_ptr<Module>>& modules)
|
||||||
|
{
|
||||||
|
std::unordered_set<std::shared_ptr<Module>> unemitted;
|
||||||
|
for(auto& m : modules)
|
||||||
|
unemitted.insert(m);
|
||||||
|
|
||||||
|
std::unordered_map<std::string, std::shared_ptr<Module>> nameMap;
|
||||||
|
for(auto& m : modules)
|
||||||
|
for(auto& l : m->labels)
|
||||||
|
for(auto& str : l.second)
|
||||||
|
nameMap[str] = m;
|
||||||
|
|
||||||
|
|
||||||
|
for(auto& m : modules)
|
||||||
|
for(auto& r : m->relocs)
|
||||||
|
{
|
||||||
|
if(r.second.size != 2)
|
||||||
|
continue;
|
||||||
|
if(r.second.name2.empty())
|
||||||
|
{
|
||||||
|
std::shared_ptr<Module> m1;
|
||||||
|
m1 = nameMap.find(r.second.name1)->second;
|
||||||
|
m1->nearrefs.push_back(m);
|
||||||
|
m->nearrefs.push_back(m1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::shared_ptr<Module> m1;
|
||||||
|
m1 = nameMap.find(r.second.name1)->second;
|
||||||
|
std::shared_ptr<Module> m2;
|
||||||
|
m2 = nameMap.find(r.second.name2)->second;
|
||||||
|
m1->nearrefs.push_back(m2);
|
||||||
|
m2->nearrefs.push_back(m1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
std::vector<std::shared_ptr<Module>> sorted;
|
||||||
|
sorted.reserve(modules.size());
|
||||||
|
|
||||||
|
auto p = sorted.begin();
|
||||||
|
|
||||||
|
while(!unemitted.empty())
|
||||||
|
{
|
||||||
|
while(p != sorted.end())
|
||||||
|
{
|
||||||
|
for(auto& m2weak : (*p)->nearrefs)
|
||||||
|
{
|
||||||
|
if(std::shared_ptr<Module> m2 = m2weak.lock())
|
||||||
|
{
|
||||||
|
auto unemittedP = unemitted.find(m2);
|
||||||
|
if(unemittedP != unemitted.end())
|
||||||
|
{
|
||||||
|
sorted.push_back(m2);
|
||||||
|
unemitted.erase(unemittedP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
sorted.push_back(*unemitted.begin());
|
||||||
|
unemitted.erase(unemitted.begin());
|
||||||
|
}
|
||||||
|
|
||||||
|
sorted.swap(modules);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
std::ifstream in(argv[1]);
|
std::ifstream in(argv[1]);
|
||||||
|
|
||||||
unordered_map<int,string> stringDictionary;
|
unordered_map<int,string> stringDictionary;
|
||||||
std::unique_ptr<Module> module;
|
|
||||||
|
bool shouldSortModules = true;
|
||||||
|
|
||||||
|
std::shared_ptr<Module> module;
|
||||||
|
std::vector<std::shared_ptr<Module>> modules;
|
||||||
|
|
||||||
std::cout << "\t.text\n\t.align 2\n";
|
std::cout << "\t.text\n\t.align 2\n";
|
||||||
|
|
||||||
@ -206,12 +280,10 @@ int main(int argc, char* argv[])
|
|||||||
if(verbose)
|
if(verbose)
|
||||||
std::cerr << "Module " << name << "(" << segment << "), flags = " << flags << "\n";
|
std::cerr << "Module " << name << "(" << segment << "), flags = " << flags << "\n";
|
||||||
|
|
||||||
if(module)
|
|
||||||
module->write(std::cout);
|
|
||||||
|
|
||||||
module.reset(new Module());
|
module.reset(new Module());
|
||||||
module->name = name;
|
module->name = name;
|
||||||
module->labels[0].push_back(name);
|
module->labels[0].push_back(name);
|
||||||
|
modules.push_back(module);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case kContent:
|
case kContent:
|
||||||
@ -311,14 +383,15 @@ int main(int argc, char* argv[])
|
|||||||
case kLast:
|
case kLast:
|
||||||
byte(in);
|
byte(in);
|
||||||
endOfObject = true;
|
endOfObject = true;
|
||||||
if(module)
|
|
||||||
module->write(std::cout);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
std::cerr << "Unknown record (type " << recordType << ") at " << std::hex << in.tellg() << std::endl;
|
std::cerr << "Unknown record (type " << recordType << ") at " << std::hex << in.tellg() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(shouldSortModules)
|
||||||
|
sortModules(modules);
|
||||||
|
for(auto& m : modules)
|
||||||
|
m->write(std::cout);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user