#include "Interpreter.h"
+#include <climits>
#include <cstring>
#include <map>
#include <ostream>
Compiler::Compiler(const Interpreter &intp)
: intp(intp)
, cursor(0) {
- int headerSize(4 + (5 * sizeof(int)) + (intp.Values().size() * 2 * sizeof(int)));
+ int headerSize(sizeof(ObjectFileHeader) + (intp.Values().size() * sizeof(TypeOffset)));
- exportsOffset = headerSize + Remaining(headerSize, 16);
- int exportsSize(intp.ExportedIdentifiers().size() * sizeof(Export));
+ fileHeader.exportsBegin = headerSize + Remaining(headerSize, 16);
+ fileHeader.exportsEnd = fileHeader.exportsBegin + (intp.ExportedIdentifiers().size() * sizeof(Export));
- externalsOffset = exportsOffset + exportsSize + Remaining(exportsSize, 16);
- int externalsSize(intp.PostponedDefinitions().size() * sizeof(External));
+ fileHeader.externalsBegin = fileHeader.exportsEnd + Remaining(fileHeader.exportsEnd, 16);
+ fileHeader.externalsEnd = fileHeader.externalsBegin + (intp.PostponedDefinitions().size() * sizeof(External));
- exportStringsOffset = externalsOffset + externalsSize + Remaining(externalsSize, 16);
- int exportStringsSize(0);
+ fileHeader.exportStringsBegin = fileHeader.externalsEnd + Remaining(fileHeader.externalsEnd, 16);
+ fileHeader.exportStringsEnd = fileHeader.exportStringsBegin;
for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
- exportStringsSize += i->size() + 1;
+ fileHeader.exportStringsEnd += i->size() + 1;
}
- externalStringsOffset = exportStringsOffset + exportStringsSize + Remaining(exportStringsSize, 16);
- int externalStringsSize(0);
+ fileHeader.externalStringsBegin = fileHeader.exportStringsEnd + Remaining(fileHeader.exportStringsEnd, 16);
+ fileHeader.externalStringsEnd = fileHeader.externalStringsBegin;
for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
- externalStringsSize += std::strlen(i->identifier) + 1;
+ fileHeader.externalStringsEnd += std::strlen(i->identifier) + 1;
}
- imagesOffset = externalStringsOffset + externalStringsSize + Remaining(externalStringsSize, 16);
- int imagesSize(intp.Images().size() * sizeof(ImageProperties));
+ fileHeader.imagesBegin = fileHeader.externalStringsEnd + Remaining(fileHeader.externalStringsEnd, 16);
+ fileHeader.imagesEnd = fileHeader.imagesBegin + (intp.Images().size() * sizeof(ImageProperties));
for (map<string, SDL_Surface *>::const_iterator i(intp.Images().begin()), end(intp.Images().end()); i != end; ++i) {
- imagesSize += i->second->w * i->second->h * i->second->format->BytesPerPixel;
+ fileHeader.imagesEnd += i->second->w * i->second->h * i->second->format->BytesPerPixel;
}
- objectsOffset = imagesOffset + imagesSize + Remaining(imagesSize, 16);
- int objectsSize(0);
+ fileHeader.objectsBegin = fileHeader.imagesEnd + Remaining(fileHeader.imagesEnd, 16);
+ fileHeader.objectsEnd = fileHeader.objectsBegin;
for (map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
const TypeDescription &td(TypeDescription::Get(i->first));
- objectOffsets[i->first] = objectsOffset + objectsSize;
- objectsSize += td.Size() * i->second.size();
- objectsSize += Remaining(objectsSize, 16);
+ objectOffsets[i->first] = fileHeader.objectsEnd;
+ fileHeader.objectsEnd += td.Size() * i->second.size();
+ fileHeader.objectsEnd += Remaining(fileHeader.objectsEnd, 16);
}
}
void Compiler::WriteHeader(ostream &out) {
- Write(out, "L2O\n", 4);
- Write(out, reinterpret_cast<const char *>(&exportsOffset), sizeof(int));
- Write(out, reinterpret_cast<const char *>(&externalsOffset), sizeof(int));
- Write(out, reinterpret_cast<const char *>(&externalStringsOffset), sizeof(int));
- Write(out, reinterpret_cast<const char *>(&exportStringsOffset), sizeof(int));
- Write(out, reinterpret_cast<const char *>(&imagesOffset), sizeof(int));
- Write(out, reinterpret_cast<const char *>(&objectsOffset), sizeof(int));
+ Write(out, reinterpret_cast<const char *>(&fileHeader), sizeof(ObjectFileHeader));
for(map<int, vector<void *> >::const_iterator i(intp.Values().begin()), end(intp.Values().end()); i != end; ++i) {
- Write(out, reinterpret_cast<const char *>(&i->first), sizeof(int));
- int typeOffset(TypeOffset(i->first));
- Write(out, reinterpret_cast<const char *>(&typeOffset), sizeof(int));
+ TypeOffset to;
+ to.typeId = i->first;
+ to.begin = GetTypeOffset(i->first);
+ to.end = to.begin + (i->second.size() * TypeDescription::Get(i->first).Size());
+ Write(out, reinterpret_cast<const char *>(&to), sizeof(TypeOffset));
}
+ TypeOffset to;
+ to.typeId = 0;
+ to.begin = 0;
+ to.end = 0;
+ Write(out, reinterpret_cast<const char *>(&to), sizeof(TypeOffset));
}
void Compiler::WriteExports(ostream &out) {
- int nameOffset(externalStringsOffset);
+ int nameOffset(fileHeader.externalStringsBegin);
for (set<string>::const_iterator i(intp.ExportedIdentifiers().begin()), end(intp.ExportedIdentifiers().end()); i != end; ++i) {
const Interpreter::ParsedDefinition &dfn(intp.GetDefinition(*i));
Export exp;
}
void Compiler::WriteExternals(ostream &out) {
- int nameOffset(exportStringsOffset);
+ int nameOffset(fileHeader.exportStringsBegin);
for(vector<Interpreter::PostponedDefinition>::const_iterator i(intp.PostponedDefinitions().begin()), end(intp.PostponedDefinitions().end()); i != end; ++i) {
External ext;
ext.nameOffset = nameOffset;
ip.width = i->second->w;
ip.height = i->second->h;
ip.depth = i->second->format->BitsPerPixel;
+ ip.pitch = i->second->pitch;
ip.rmask = i->second->format->Rmask;
ip.gmask = i->second->format->Gmask;
ip.bmask = i->second->format->Bmask;
ip.amask = i->second->format->Amask;
Write(out, reinterpret_cast<char *>(&ip), sizeof(ImageProperties));
SDL_LockSurface(i->second);
- Write(out, reinterpret_cast<char *>(i->second->pixels), ip.width * ip.height * i->second->format->BytesPerPixel);
+ Write(out, reinterpret_cast<char *>(i->second->pixels), ip.width * ip.height * (ip.depth / CHAR_BIT + (ip.depth % CHAR_BIT ? 1 : 0)));
// TODO: store palette too?
SDL_UnlockSurface(i->second);
}
int Compiler::ObjectOffset(int typeId, int objectId) const {
const TypeDescription &td(TypeDescription::Get(typeId));
- return TypeOffset(typeId) + (td.Size() * objectId);
+ return GetTypeOffset(typeId) + (td.Size() * objectId);
}
-int Compiler::TypeOffset(int typeId) const {
+int Compiler::GetTypeOffset(int typeId) const {
return objectOffsets.at(typeId);
}