← index
Codename.Quadtris/include/cmx_mxlvl.h
Source: Codename.Quadtris/include/cmx_mxlvl.h
#ifndef MXLVL_E_H_
#define MXLVL_E_H_
#include<string>
#include<sstream>
#include<fstream>
#include"cmx.h"

namespace lvl {


	enum BLOCK_TYPE { BLOCK_EMPTY=0, BLOCK_SOLID, BLOCK_HARMFUL, BLOCK_EXIT };

	struct Item {
		std::string value;
		std::string fname;
		int cx,cy,cw,ch;
		BLOCK_TYPE block_type;
		cmx::video::Surface *surface;
		Item(std::string value, std::string cfname, int x, int y, int w, int h, BLOCK_TYPE tileState) {
			cx = x;
			cy = y;
			cw = w;
			ch = h;
			this->value = value;
			fname = cfname;
			block_type = tileState;
		}
		Item() : value(""), fname(""), cx(0), cy(0), cw(0), ch(0)  {}
	};



	class Level {
	public:
		std::string name;
		int level_width, level_height, level_max_x, level_max_y;
		Level() : items(0),layers(0),offset_x(0), offset_y(0), block_width(16), block_height(16)  { }
		~Level() {
			if(items == 0) return;
			for(int z = 0; z < level_max_y; z++) {
				delete [] items[z];
			}
			delete [] items;

			if(layers == 0) return;
			for(int z = 0; z < level_max_y; z++) {
				delete [] layers[z];
			}
			delete [] layers;
		}

		struct temp {
			std::string fname;
			std::string value;
			int offset;
			temp(std::string f, std::string v, int o) {
				fname = f;
				value = v;
				offset = o;
			}

			temp() : fname(""), value(""), offset(0) {}
		};

		std::map<std::string, temp> files;

		int loadLevelGraphics(std::string path) {
			if(items == 0 || layers == 0) {
				std::cerr << "Error failure..\n";
				return 0;

			}
			unsigned int i = 0;
			for(i = 0; i < sprites.size(); i++) {
				files[sprites[i].fname].fname = sprites[i].fname;
				files[sprites[i].fname].value = sprites[i].value;
				files[sprites[i].fname].offset = i;
			}
			std::map<std::string, temp>::iterator it;
			for(it = files.begin(); it != files.end(); ++it) {
				std::ostringstream stream;
				stream << path << "/mxmap/img/" << it->first;
				int rt = surfaces[it->first].loadImage(stream.str());
				if(rt != 1) {
					std::cerr << "Error loading graphic: " << stream.str() << "\nAborting ...\n";
					return 0;
				} else std::cout << "Graphic: " << stream.str() << " has been loaded..\n";
			}
			{
				for(int i = 0; i < level_max_x; i++) {
					for(int z =0; z < level_max_y; z++) {
						if(items[i][z] != 0) {
								items[i][z]->surface = &surfaces[items[i][z]->fname];
						}

						if(layers[i][z] != 0)
							layers[i][z]->surface = &surfaces[layers[i][z]->fname];
					}
				}
			}
			std::cout << "successfully loaded level: " << name << "\n";
			return 1;
		}

		int loadLevelGraphics(std::map<std::string, void *> &data) {
			if(items == 0) {
				std::cerr << "Error failure..\n";
				return 0;

			}
			unsigned int i = 0;
			for(i = 0; i < sprites.size(); i++) {
				files[sprites[i].fname].fname = sprites[i].fname;
				files[sprites[i].fname].value = sprites[i].value;
				files[sprites[i].fname].offset = i;
			}
			std::map<std::string, temp>::iterator it;
			for(it = files.begin(); it != files.end(); ++it) {
				std::ostringstream stream;
				stream << "from resource: " << it->first << "\n";
				int rt = surfaces[it->first].loadImage(data[it->first], sizeof(data[it->first]));;
				if(rt != 1) {
					std::cerr << "Error loading graphic: " << stream.str() << "\nAborting ...\n";
					return 0;
				} else std::cout << "Graphic: " << stream.str() << " has been loaded..\n";
			}
			{
				for(int i = 0; i < level_max_x; i++) {
					for(int z =0; z < level_max_y; z++) {
						if(items[i][z] != 0) {
								items[i][z]->surface = &surfaces[items[i][z]->fname];
						}

						if(layers[i][z] != 0) {
							layers[i][z]->surface = &surfaces[layers[i][z]->fname];
						}
					}
				}
			}
			std::cout << "successfully loaded level: " << name << "\n";
			return 1;
		}

		void drawLevel(unsigned int *lvl_buf, int width, int height) {
			static int plot_x = (width-level_width)/2, plot_y=(height-level_height)/2;
			static int i = 0, z = 0;
			for(i = 0; i < (int)level_width/(int)block_width; ++i) {
				for(z = 0; z < int(level_height/block_height); ++z) {
					if(i+offset_x < level_max_x && z+offset_y < level_max_y && items[i+offset_x][z+offset_y] != 0) {
						lvl::Item *item=items[i+offset_x][z+offset_y];
						cmx::video::Surface *surf=items[i+offset_x][z+offset_y]->surface;
						cmx::Rect dst_rect((offset_x+i*block_width)+plot_x, (offset_y+z*block_height)+plot_y, block_width, block_height);
						cmx::Rect item_rect(item->cx, item->cy, item->cw, item->ch);
						cmx::video::copyImage(lvl_buf, *surf,cmx::system::width, dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
					}
				}
			}

			for(i = 0; i < (int)level_width/(int)block_width; ++i) {
					for(z = 0; z < int(level_height/block_height); ++z) {
						if(i+offset_x < level_max_x && z+offset_y < level_max_y && layers[i+offset_x][z+offset_y] != 0) {
							lvl::Item *item=layers[i+offset_x][z+offset_y];
							cmx::video::Surface *surf=layers[i+offset_x][z+offset_y]->surface;
							cmx::Rect dst_rect((offset_x+i*block_width)+plot_x, (offset_y+z*block_height)+plot_y, item->cw, item->ch);
							cmx::Rect item_rect(item->cx, item->cy, item->cw, item->ch);
							cmx::video::copyImage(lvl_buf, *surf,cmx::system::width, dst_rect.x, dst_rect.y, dst_rect.w, dst_rect.h);
					}
				}
			}
		}

		void drawLevel(cmx::video::Surface *surface) {
			static int plot_x = (surface->w-level_width)/2, plot_y=(surface->h-level_height)/2;
			static int i = 0, z = 0;
			for(i = 0; i < (int)level_width/(int)block_width; i++) {
				for(z = 0; z < int(level_height/block_height); z++) {
					if(i+offset_x < level_max_x && z+offset_y < level_max_y && items[i+offset_x][z+offset_y] != 0) {
						lvl::Item *item=items[i+offset_x][z+offset_y];
						cmx::video::Surface *surf=items[i+offset_x][z+offset_y]->surface;
						surface->copySurface(*surf, cmx::Rect(item->cx,item->cy, item->cw, item->ch),cmx::Rect((offset_x+i*block_width)+plot_x, (offset_y+z*block_height)+plot_y, block_width, block_height));
					}
				}
			}

			for(i = 0; i < (int)level_width/(int)block_width; i++) {
				for(z = 0; z < int(level_height/block_height); z++) {
					if(i+offset_x < level_max_x && z+offset_y < level_max_y && layers[i+offset_x][z+offset_y] != 0) {
						lvl::Item *item=layers[i+offset_x][z+offset_y];
						cmx::video::Surface *surf=layers[i+offset_x][z+offset_y]->surface;
						surface->copySurface(*surf, cmx::Rect(item->cx,item->cy, item->cw, item->ch),cmx::Rect((offset_x+i*block_width)+plot_x, (offset_y+z*block_height)+plot_y, item->cw, item->ch));
					}
				}
			}
		}

		enum DIRECTION { UP=0, DOWN=1, LEFT=2, RIGHT=3 };

		void scroll(DIRECTION dir) {
			switch(dir) {
			case UP:
				if(offset_y > 0) --offset_y;
				break;
			case DOWN:
				if(offset_y < level_max_y-(level_height/block_height)) ++offset_y;
				break;
			case LEFT:
				if(offset_x > 0) --offset_x;
				break;
			case RIGHT:
				if(offset_x < level_max_x-(level_height/block_width)) ++offset_x;
				break;
			}
		}
		std::vector<Item> sprites;
		std::map<std::string, cmx::video::Surface> surfaces;
		Item ***items;
		Item ***layers;
		int offset_x, offset_y, block_width, block_height;
	};
}

#endif