#ifndef RC_TILELIB_H_INCLUDED #define RC_TILELIB_H_INCLUDED #ifdef RC_ANDROID #include "SDL.h" #else #include #endif // _IRR_ANDROID_PLATFORM_ #include "rc_tilemap.h" #include "rc_gfx_core.h" int rc_createTileSet(int img_id, int tile_w, int tile_h) { if(img_id < 0 || img_id >= rc_image.size()) return -1; if(!rc_image[img_id].image) return -1; rc_tileset_obj tset; tset.active = true; tset.img_id = img_id; tset.tile_width = tile_w; tset.tile_height = tile_h; int num_tiles = ((int)rc_image[img_id].image->getSize().Width / tile_w) * ((int)rc_image[img_id].image->getSize().Height / tile_h); tset.tiles.resize(num_tiles); for(int i = 0; i < tset.tiles.size(); i++) { tset.tiles[i].frames.push_back(i); tset.tiles[i].fps = 0; tset.tiles[i].frame_swap_time = 0; tset.tiles[i].frame_start_time = 0; } int tset_id = rc_tileset.size(); if(rc_deleted_tileset.size() > 0) { tset_id = rc_deleted_tileset[0]; rc_deleted_tileset.erase(rc_deleted_tileset.begin()); rc_tileset[tset_id] = tset; } else rc_tileset.push_back(tset); return tset_id; } void rc_setTileAnimationLength(int tileset, int base_tile, int num_frames) { if(tileset < 0 || tileset >= rc_tileset.size()) return; if(!rc_tileset[tileset].active) return; if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size()) return; rc_tileset[tileset].tiles[base_tile].frames.resize(num_frames); rc_tileset[tileset].tiles[base_tile].num_frames = num_frames; } int rc_getTileAnimationLength(int tileset, int base_tile) { if(tileset < 0 || tileset >= rc_tileset.size()) return 0; if(!rc_tileset[tileset].active) return 0; if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size()) return 0; return rc_tileset[tileset].tiles[base_tile].num_frames; } void rc_setTileAnimationFrame(int tileset, int base_tile, int anim_frame, int tile_frame) { if(tileset < 0 || tileset >= rc_tileset.size()) return; if(!rc_tileset[tileset].active) return; if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size()) return; rc_tileset[tileset].tiles[base_tile].frames[anim_frame] = tile_frame; } int rc_getTileAnimationFrame(int tileset, int base_tile, int anim_frame) { if(tileset < 0 || tileset >= rc_tileset.size()) return -1; if(!rc_tileset[tileset].active) return -1; if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size()) return -1; return rc_tileset[tileset].tiles[base_tile].frames[anim_frame]; } void rc_setTileAnimationSpeed(int tileset, int base_tile, double speed) { if(tileset < 0 || tileset >= rc_tileset.size()) return; if(!rc_tileset[tileset].active) return; if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size()) return; rc_tileset[tileset].tiles[base_tile].fps = speed; rc_tileset[tileset].tiles[base_tile].frame_swap_time = 1000/speed; } double rc_getTileAnimationSpeed(int tileset, int base_tile) { if(tileset < 0 || tileset >= rc_tileset.size()) return 0; if(!rc_tileset[tileset].active) return 0; if(base_tile < 0 || base_tile >= rc_tileset[tileset].tiles.size()) return 0; return rc_tileset[tileset].tiles[base_tile].fps; } //--------------------------------------TILEMAP----------------------------------------------- int rc_createTileMap(int tileset, int widthInTiles, int heightInTiles) { if(tileset < 0 || tileset >= rc_tileset.size()) return -1; if(!rc_tileset[tileset].active) return -1; rc_tilemap_obj tilemap; tilemap.active = true; tilemap.texture = NULL; tilemap.tileset = tileset; tilemap.num_tiles_across = widthInTiles; tilemap.num_tiles_down = heightInTiles; tilemap.rows.resize(heightInTiles); for(int i = 0; i < tilemap.rows.size(); i++) { tilemap.rows[i].tile.resize(widthInTiles); } int tm_id = rc_tilemap.size(); if(rc_deleted_tilemap.size() > 0) { tm_id = rc_deleted_tilemap[0]; rc_deleted_tilemap.erase(rc_deleted_tilemap.begin()); rc_tilemap[tm_id] = tilemap; } else rc_tilemap.push_back(tilemap); return tm_id; } void rc_setTileMapSize(int tilemap, int widthInTiles, int heightInTiles) { if(tilemap < 0 || tilemap >= rc_tilemap.size()) return; if(!rc_tilemap[tilemap].active) return; rc_tilemap[tilemap].num_tiles_across = widthInTiles; rc_tilemap[tilemap].num_tiles_down = heightInTiles; rc_tilemap[tilemap].rows.resize(heightInTiles); for(int i = 0; i < rc_tilemap[tilemap].rows.size(); i++) { rc_tilemap[tilemap].rows[i].tile.resize(widthInTiles); } } void rc_getTileMapSize(int tilemap, double* widthInTiles, double* heightInTiles) { if(tilemap < 0 || tilemap >= rc_tilemap.size()) return; if(!rc_tilemap[tilemap].active) return; *widthInTiles = rc_tilemap[tilemap].num_tiles_across; *heightInTiles = rc_tilemap[tilemap].num_tiles_down; } void rc_setTile(int tilemap, int tile, int x, int y) { if(tilemap < 0 || tilemap >= rc_tilemap.size()) return; if(!rc_tilemap[tilemap].active) return; int tileset = rc_tilemap[tilemap].tileset; //if tilemap exists, then its safe to assume tileset is in range since tilemap can't be created if its not if(!rc_tileset[tileset].active) return; int num_tset_tiles = rc_tileset[tileset].tiles.size(); if(tile < 0 || tile >= num_tset_tiles) return; if( (x < 0 || x >= rc_tilemap[tilemap].num_tiles_across) || (y < 0 || y >= rc_tilemap[tilemap].num_tiles_down) ) return; rc_tilemap[tilemap].rows[y].tile[x] = tile; } int rc_getTile(int tilemap, int x, int y) { if(tilemap < 0 || tilemap >= rc_tilemap.size()) return -1; if(!rc_tilemap[tilemap].active) return -1; if( (x < 0 || x >= rc_tilemap[tilemap].num_tiles_across) || (y < 0 || y >= rc_tilemap[tilemap].num_tiles_down) ) return -1; return rc_tilemap[tilemap].rows[y].tile[x]; } void rc_fillTile(int tilemap, int tile, int x, int y, int widthInTiles, int heightInTiles) { if(tilemap < 0 || tilemap >= rc_tilemap.size()) return; if(!rc_tilemap[tilemap].active) return; int tileset = rc_tilemap[tilemap].tileset; //if tilemap exists, then its safe to assume tileset is in range since tilemap can't be created if its not if(!rc_tileset[tileset].active) return; int num_tset_tiles = rc_tileset[tileset].tiles.size(); if(tile < 0 || tile >= num_tset_tiles) return; if( (x < 0 || x >= rc_tilemap[tilemap].num_tiles_across) || (y < 0 || y >= rc_tilemap[tilemap].num_tiles_down) ) return; if( ( (x+widthInTiles) < 0 || (x+widthInTiles) > rc_tilemap[tilemap].num_tiles_across) || ( (y+heightInTiles) < 0 || (y+heightInTiles) > rc_tilemap[tilemap].num_tiles_down) ) return; for(int iy = 0; iy < heightInTiles; iy++) for(int ix = 0; ix < widthInTiles; ix++) rc_tilemap[tilemap].rows[y+iy].tile[x+ix] = tile; } void getTileInTileset(int tileset, int tile, int* x, int* y) { int img_w = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Width; int img_h = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Height; int tile_w = rc_tileset[tileset].tile_width; int tile_h = rc_tileset[tileset].tile_height; int widthInTiles = img_w / tile_w; *x = (tile%widthInTiles) * tile_w; *y = (tile/widthInTiles) * tile_h; } int getNumTilesInTileset(int tileset) { int img_w = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Width; int img_h = rc_image[ rc_tileset[tileset].img_id ].image->getSize().Height; int tile_w = rc_tileset[tileset].tile_width; int tile_h = rc_tileset[tileset].tile_height; int widthInTiles = img_w / tile_w; int heightInTiles = img_h / tile_h; return (widthInTiles*heightInTiles); } void updateTileset(int tileset) { Uint32 current_time_ms = SDL_GetTicks(); for(int i = 0; i < rc_tileset[tileset].tiles.size(); i++) { if( (current_time_ms-rc_tileset[tileset].tiles[i].frame_start_time) >= rc_tileset[tileset].tiles[i].frame_swap_time ) { rc_tileset[tileset].tiles[i].current_frame++; if(rc_tileset[tileset].tiles[i].current_frame >= rc_tileset[tileset].tiles[i].num_frames) rc_tileset[tileset].tiles[i].current_frame = 0; rc_tileset[tileset].tiles[i].frame_start_time = current_time_ms; } } } void rc_drawTileMap(int tilemap, int x, int y, int w, int h, int offset_x, int offset_y) { if(tilemap < 0 || tilemap >= rc_tilemap.size()) return; if(!rc_tilemap[tilemap].active) return; if(rc_active_canvas < 0 || rc_active_canvas >= rc_canvas.size()) return; if(!rc_canvas[rc_active_canvas].type == RC_CANVAS_TYPE_2D) return; if(!rc_canvas[rc_active_canvas].texture) return; rc_tilemap[tilemap].texture = VideoDriver->addRenderTargetTexture(irr::core::dimension2d(w,h), "rt", ECF_A8R8G8B8); VideoDriver->setRenderTarget(rc_tilemap[tilemap].texture, true, true, irr::video::SColor(0,0,0,0)); int tileset = rc_tilemap[tilemap].tileset; updateTileset(tileset); int vp_widthInTiles = w/rc_tileset[tileset].tile_width; int vp_heightInTiles = h/rc_tileset[tileset].tile_height; int tset_img_id = rc_tileset[tileset].img_id; int src_w = rc_tileset[tileset].tile_width; int src_h = rc_tileset[tileset].tile_height; int tile_offset_x = offset_x / src_w; int tile_offset_y = offset_y / src_h; int screen_offset_x = 0 - (offset_x % src_w); int screen_offset_y = 0 - (offset_y % src_h); int num_tiles_in_tset = getNumTilesInTileset(tileset); for(int iy = 0; iy < vp_heightInTiles+1; iy++) { for(int ix = 0; ix < vp_widthInTiles+1; ix++) { int current_frame = 0; //TODO: ADD TIMING int map_x = tile_offset_x + ix; int map_y = tile_offset_y + iy; if(map_x < 0 || map_x >= rc_tilemap[tilemap].num_tiles_across || map_y < 0 || map_y >= rc_tilemap[tilemap].num_tiles_down) continue; int tile = rc_tilemap[tilemap].rows[map_y].tile[map_x]; if(tile < 0 || tile >= num_tiles_in_tset) continue; current_frame = rc_tileset[tileset].tiles[tile].current_frame; tile = rc_tileset[tileset].tiles[tile].frames[current_frame]; if(tile < 0 || tile >= num_tiles_in_tset) continue; int src_x = 0; int src_y = 0; getTileInTileset(tileset, tile, &src_x, &src_y); irr::core::rect sourceRect( irr::core::vector2d(src_x, src_y), irr::core::dimension2d(src_w, src_h)); irr::video::SColor color(rc_image[tset_img_id].alpha, rc_image[tset_img_id].color_mod.getRed(), rc_image[tset_img_id].color_mod.getGreen(), rc_image[tset_img_id].color_mod.getBlue()); int dst_x = screen_offset_x + (ix*src_w); int dst_y = screen_offset_y + (iy*src_h); irr::core::rect dest( irr::core::vector2d(dst_x, dst_y), irr::core::dimension2d(src_w, src_h)); VideoDriver->draw2DImage(rc_image[tset_img_id].image, dest, sourceRect, 0, 0, true); } } VideoDriver->setRenderTarget(rc_canvas[rc_active_canvas].texture, false, false); irr::core::rect sourceRect( irr::core::vector2d(0, 0), irr::core::dimension2d(w, h)); irr::core::rect dest( irr::core::vector2d(x, y), irr::core::dimension2d(w, h)); VideoDriver->draw2DImage(rc_tilemap[tilemap].texture, dest, sourceRect, 0, 0, false); VideoDriver->removeTexture(rc_tilemap[tilemap].texture); rc_tilemap[tilemap].texture = NULL; //draw2DImage(VideoDriver, rc_tilemap[tilemap].texture, src, pos,) } #endif // RC_TILELIB_H_INCLUDED