Skip to content

Instantly share code, notes, and snippets.

@Green-Sky
Created September 4, 2017 20:13
Show Gist options
  • Save Green-Sky/917ebdc33913e400d0bebe78c7225d55 to your computer and use it in GitHub Desktop.
Save Green-Sky/917ebdc33913e400d0bebe78c7225d55 to your computer and use it in GitHub Desktop.
anno1602 island (.scp) parser v1
#include "island.hpp"
#include <cassert>
void printIsland(Island* i) {
for (uint8_t y = 0; y < i->dim_y; y++) {
for (uint8_t x = 0; x < i->dim_x; x++) {
short num = i->map[std::make_pair(x, y)].num;
if (num > 900 && num <= 1000)
std::cout << "FF";
else if (num > 1000 && num <= 1100)
std::cout << "SS";
else if (num > 1100 && num <= 1200)
std::cout << "MM";
else if (num > 1200 && num <= 1300)
std::cout << "WW";
else if (num > 1300 && num <= 1400)
std::cout << "TT";
else if ((num > 100 && num < 200) || (num > 1400 && num <= 3000))
std::cout << "LL";
else if (num == 0)
std::cout << " ";
else
std::cout << num << ' ';
}
std::cout << std::endl;
}
}
void printIslandOri(Island* i) {
for (uint8_t y = 0; y < i->dim_y; y++) {
for (uint8_t x = 0; x < i->dim_x; x++) {
int ori = i->map[std::make_pair(x, y)].ori;
std::cout << ori << ori;
}
std::cout << std::endl;
}
}
int main(void) {
{
Island* i_lit_5 = parseIsland("res/NOKLIMA/lit.scp"); assert(i_lit_5);
printIsland(i_lit_5);
Island* i_mit_5 = parseIsland("res/NOKLIMA/mit.scp"); assert(i_mit_5);
printIsland(i_mit_5);
Island* i_lit = parseIsland("res/NORD/lit.scp"); assert(i_lit);
printIsland(i_lit);
Island* i_lit00 = parseIsland("res/NORD/lit00.scp"); assert(i_lit00);
printIsland(i_lit00);
Island* i_lit05 = parseIsland("res/NORD/lit05.scp"); assert(i_lit05);
printIsland(i_lit05);
Island* i_lit09 = parseIsland("res/NORD/lit09.scp"); assert(i_lit09);
printIsland(i_lit09);
Island* i_med = parseIsland("res/NORD/med.scp"); assert(i_med);
printIsland(i_med);
}
{
Island* i_med = parseIsland("res/SUED/med.scp"); assert(i_med);
printIsland(i_med);
printIslandOri(i_med);
}
}
#pragma once
#include <iostream>
#include <fstream>
#include <cstring>
#include <map>
#include <utility>
enum INSEL_VER {
INSEL3,
INSEL4,
INSEL5
};
struct Tile {
short num;
uint8_t ori; // 0-3
};
struct Island {
Island(void) : dim_x(0), dim_y(0) {}
uint8_t dim_x, dim_y;
using pos_t = std::pair<uint8_t, uint8_t>;
std::map<pos_t, Tile> map;
};
void parseDim345(std::ifstream& f, Island* i) {
f.seekg(0x15);
i->dim_x = f.get();
i->dim_y = f.get();
}
// layout (bytes) :
// ---------------------------------
// |1 |2 |3 |4 |5 |6 |7 |8 |
// |num |x |y |(1)|???
//
// (1) (bits) :
// ---------------------------------
// |1 |2 |3 |4 |5 |6 |7 |8 |
// |??? |ori |
bool parseTile345(std::ifstream& f, Island* i) {
if (!f.good())
return false;
short num = 0;
num = (short)f.get() | ((short)f.get() << 8);
uint8_t x, y;
if (f.peek() >= i->dim_x) {
f.unget();
f.unget();
return false;
}
x = f.get();
if (f.peek() >= i->dim_y) {
f.unget();
f.unget();
f.unget();
return false;
}
y = f.get();
//std::cout << "num: " << num << std::endl;
//std::cout << "x: " << (int)x << " y: " << (int)y << std::endl;
i->map[std::make_pair(x, y)].num = num;
{
uint8_t c = f.get();
uint8_t ori = c & 0x3;
i->map[std::make_pair(x, y)].ori = ori;
}
// :'D
f.get();
f.get();
f.get();
return true;
}
Island* parseINSEL(std::ifstream& f, INSEL_VER v) {
Island* i = new Island();
parseDim345(f, i);
std::cout << "III island dim: " << (int)i->dim_x << "x" << (int)i->dim_y << std::endl;
switch (v) {
case INSEL3:
f.seekg(0x50);
break;
case INSEL4:
case INSEL5:
f.seekg(0x9c);
break;
default:
break;
}
while (parseTile345(f, i)) {}
// HIRSCH2
return i;
}
Island* parseIsland(std::ifstream& f) {
const char header[] = "INSEL";
char buff[6];
f.read(buff, 6);
if (std::memcmp(buff, header, 5) != 0) {
std::cerr << "EEE not a INSEL!" << std::endl;
return nullptr;
}
INSEL_VER v;
switch (buff[5]) {
case '3':
std::cout << "III opening as INSEL3." << std::endl;
v = INSEL3;
break;
case '4':
std::cout << "III opening as INSEL4." << std::endl;
v = INSEL4;
break;
case '5':
std::cout << "III opening as INSEL5." << std::endl;
v = INSEL5;
break;
default:
std::cerr << "EEE unsupported INSEL version (not 3, 4 or 5)" << std::endl;
return nullptr;
}
return parseINSEL(f, v);
}
Island* parseIsland(const std::string& filePath) {
std::ifstream f;
f.open(filePath, std::ios_base::in | std::ios_base::binary);
if (!f.is_open()) {
std::cerr << "EEE couldnt open \"" << filePath << "\"" << std::endl;
return nullptr;
}
return parseIsland(f);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment