Contact me to be added to this repository. Push the creations you make for D&D, and they will be displayed in a nice website. See the website for how to contribute.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

209 lines
5.3 KiB

#include "Map.h"
Tile tileIndex(int b, int g, int r) {
if(b == 255 && g == 255 && r == 255) {
return GRASS;
}
return WALL;
}
Quad::Quad() {
init(L_W,L_H);
}
void Quad::init(int w,int h) {
int i = 1;
while(i < w || i < h)
i <<= 1;
bound = {0,0,i,i};
data = WALL;
tl = tr = bl = br = NULL;
}
void Quad::boundstring() {
std::cout << "{" << bound.x << "," << bound.y << "," << bound.w << "," << bound.h << "}\n";
}
void Quad::free() {
//if(bound.w*bound.h == 1) {
// delete this;
// return;
//}
if(tl)
tl->free();
tl = NULL;
if(tr)
tr->free();
tr = NULL;
if(bl)
bl->free();
bl = NULL;
if(br)
br->free();
br = NULL;
delete this;
}
inline bool Quad::inbounds(int x, int y) {
return (x - bound.x >= 0) &&
(y - bound.y >= 0) &&
(x-bound.x < bound.w) &&
(y-bound.y < bound.h);
}
void Quad::insert(int x, int y, Tile t) {
//std::cout << "Insert called at " << x << "," << y << " on " << this << "\n";
if(!inbounds(x,y)) {
std::cout << "Not inbounds\n";
return;
}
if(bound.w*bound.h == 1) {
data = t;
//std::cout <<"Data is set to" << t << "\n";
return;
}
if(x-bound.x < bound.w/2) { //left
if(y - bound.y < bound.h/2) { //top
if(!tl) {
tl = new Quad();
tl->bound = {bound.x,bound.y,bound.w/2,bound.h/2};
}
tl->insert(x,y,t);
} else { //bottom
if(!bl) {
bl = new Quad();
bl->bound = {bound.x,bound.y+bound.h/2,bound.w/2,bound.h/2};
}
bl->insert(x,y,t);
}
} else { //right
if(y - bound.y < bound.h/2) { //top
if(!tr) {
tr = new Quad();
tr->bound = {bound.x+bound.w/2,bound.y,bound.w/2,bound.h/2};
}
tr->insert(x,y,t);
} else { //bottom
if(!br) {
br = new Quad();
br->bound = {bound.x+bound.w/2,bound.y+bound.h/2,bound.w/2,bound.h/2};
}
br->insert(x,y,t);
}
}
}
Tile Quad::lookup(int x, int y) {
if(bound.w*bound.h == 1) {
return data;
}
if(bound.x + bound.w/2 > x) { //left
if(bound.y + bound.h/2 > y) { //top
if(tl)
return tl->lookup(x,y);
} else { //bottom
if(bl)
return bl->lookup(x,y);
}
} else { //right
if(bound.y + bound.h/2 > y) {
if(tr)
return tr->lookup(x,y);
} else {
if(br)
return br->lookup(x,y);
}
}
return WALL;
}
void Quad::print(int spaces) {
for(int i = 0; i < spaces; ++i) {
std::cout << " ";
}
if(bound.w*bound.h == 1) {
std::cout << bound.x << "," << bound.y << ":" << data << "\n";
}
/*if(data == WALL)
std::cout << "WALL\n";
if(data == STONE)
std::cout << "STONE\n";
if(data == GRASS)
std::cout << "GRASS\n";*/
if(tl)
tl->print(spaces+2);
if(tr)
tr->print(spaces+2);
if(bl)
bl->print(spaces+2);
if(br)
br->print(spaces+2);
}
Map::Map() {
tiles = new Quad();
numTilesX = numTilesY = -1;
for(int i = 0; i < NUM_TILE_IDs; ++i) {
std::string filename = "assets/" + std::to_string(i) + ".png";
std::cout << "Loading texture " << filename << "\n";
textures[i].loadFromFile(filename);
}
}
Map::~Map() {
tiles->free();
delete tiles; //This destructor may seem excessive, but all three of these lines have a separate purpose.
tiles = NULL; //c'est la C++
}
void Map::loadFromFile(std::string fpath) {
cv::Mat image = cv::imread(fpath.c_str());
std::cout << "Image size - Width: " << image.cols << " Height: " << image.rows << "\n";
tiles->init(image.cols,image.rows);
for(int x = 0; x < image.cols; ++x) {
for(int y = 0; y < image.rows; ++y) {
cv::Vec3b pixel = image.at<cv::Vec3b>(y,x); //Transposed...
Tile t = tileIndex(pixel.val[0],pixel.val[1],pixel.val[2]);
//std::cout << "Tile at " << x << "," << y << " is " << t << "\n";
tiles->insert(x,y,t);
}
}
/* FILE* f = fopen(fpath.c_str(),"rb");
int w,h;
fread(&w,sizeof(int),1,f);
fread(&h,sizeof(int),1,f);
std::cout << "Width: " << w << " Height: " << h << "\n";
tiles->init(w,h);
std::cout << "Tiles init'd\n";
int t;
for(int i = 0; i < w*h; ++i) {
fread(&t,sizeof(int),1,f);
tiles->insert(i/w,i%w,static_cast<Tile>(t));
//std::cout << "Loading " << t << "\n";
}
fclose(f);*/
numTilesX = image.cols;
numTilesY = image.rows;
}
void Map::render(SDL_Rect camera) {
//std::cout << "Rendering map\n";
for(int x = camera.x/TILE_SIZE; x < 1+(camera.x + camera.w)/TILE_SIZE; ++x){
for(int y = camera.y/TILE_SIZE; y < 1+(camera.y + camera.h)/TILE_SIZE; ++y) {
Tile t = tiles->lookup(x,y);
//std::cout << "Tile at " << x << "," << y << " is " << t << "\n";
textures[t].render(x*TILE_SIZE - camera.x,y*TILE_SIZE - camera.y);
}
}
//exit(1);
}
void Map::print() {
tiles->print(0);
}