mirror of
https://github.com/autc04/Retro68.git
synced 2025-01-15 15:33:44 +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 <iostream>
|
||||
#include <unordered_map>
|
||||
#include <unordered_set>
|
||||
#include <string>
|
||||
#include "BinaryIO.h"
|
||||
#include <stdint.h>
|
||||
@ -66,6 +67,8 @@ struct Module
|
||||
unordered_map<uint32_t, vector<string>> labels;
|
||||
unordered_map<uint32_t, Reloc> relocs;
|
||||
|
||||
std::vector<std::weak_ptr<Module>> nearrefs;
|
||||
|
||||
void write(std::ostream& out);
|
||||
};
|
||||
|
||||
@ -137,12 +140,83 @@ void Module::write(std::ostream& out)
|
||||
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[])
|
||||
{
|
||||
std::ifstream in(argv[1]);
|
||||
|
||||
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";
|
||||
|
||||
@ -206,12 +280,10 @@ int main(int argc, char* argv[])
|
||||
if(verbose)
|
||||
std::cerr << "Module " << name << "(" << segment << "), flags = " << flags << "\n";
|
||||
|
||||
if(module)
|
||||
module->write(std::cout);
|
||||
|
||||
module.reset(new Module());
|
||||
module->name = name;
|
||||
module->labels[0].push_back(name);
|
||||
modules.push_back(module);
|
||||
}
|
||||
break;
|
||||
case kContent:
|
||||
@ -311,14 +383,15 @@ int main(int argc, char* argv[])
|
||||
case kLast:
|
||||
byte(in);
|
||||
endOfObject = true;
|
||||
if(module)
|
||||
module->write(std::cout);
|
||||
break;
|
||||
default:
|
||||
std::cerr << "Unknown record (type " << recordType << ") at " << std::hex << in.tellg() << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(shouldSortModules)
|
||||
sortModules(modules);
|
||||
for(auto& m : modules)
|
||||
m->write(std::cout);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user