diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-01-12 15:07:57 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-01-12 15:07:57 +0000 |
| commit | 99f0a47d6b03b005d0a7dae064cb6eb7cb4f60b5 (patch) | |
| tree | 6c453bff72668da6cc6f6e28621356004a06d441 /src/game/editor/ed_layer_tiles.cpp | |
| parent | 2aba180f8c1bfa2680b1f660148de1dc82b03298 (diff) | |
| download | zcatch-99f0a47d6b03b005d0a7dae064cb6eb7cb4f60b5.tar.gz zcatch-99f0a47d6b03b005d0a7dae064cb6eb7cb4f60b5.zip | |
first round of code cleanup
Diffstat (limited to 'src/game/editor/ed_layer_tiles.cpp')
| -rw-r--r-- | src/game/editor/ed_layer_tiles.cpp | 294 |
1 files changed, 294 insertions, 0 deletions
diff --git a/src/game/editor/ed_layer_tiles.cpp b/src/game/editor/ed_layer_tiles.cpp new file mode 100644 index 00000000..f697e56e --- /dev/null +++ b/src/game/editor/ed_layer_tiles.cpp @@ -0,0 +1,294 @@ +#include <game/client/gc_mapres_tilemap.h> +#include <game/g_math.h> +#include "editor.hpp" + +static void render_tilemap(TILE *tiles, int w, int h, float scale) +{ + //gfx_texture_set(img_get(tmap->image)); + float screen_x0, screen_y0, screen_x1, screen_y1; + gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1); + + // calculate the final pixelsize for the tiles + float tile_pixelsize = 1024/32.0f; + float final_tilesize = scale/(screen_x1-screen_x0) * gfx_screenwidth(); + float final_tilesize_scale = final_tilesize/tile_pixelsize; + + gfx_quads_begin(); + + int starty = (int)(screen_y0/scale)-1; + int startx = (int)(screen_x0/scale)-1; + int endy = (int)(screen_y1/scale)+1; + int endx = (int)(screen_x1/scale)+1; + + // adjust the texture shift according to mipmap level + float texsize = 1024.0f; + float frac = (1.25f/texsize) * (1/final_tilesize_scale); + float nudge = (0.5f/texsize) * (1/final_tilesize_scale); + + for(int y = starty; y < endy; y++) + for(int x = startx; x < endx; x++) + { + int mx = x; + int my = y; + if(mx<0) + continue; // mx = 0; + if(mx>=w) + continue; // mx = w-1; + if(my<0) + continue; // my = 0; + if(my>=h) + continue; // my = h-1; + + int c = mx + my*w; + + unsigned char index = tiles[c].index; + if(index) + { + unsigned char flags = tiles[c].flags; + int tx = index%16; + int ty = index/16; + int px0 = tx*(1024/16); + int py0 = ty*(1024/16); + int px1 = (tx+1)*(1024/16)-1; + int py1 = (ty+1)*(1024/16)-1; + + float u0 = nudge + px0/texsize+frac; + float v0 = nudge + py0/texsize+frac; + float u1 = nudge + px1/texsize-frac; + float v1 = nudge + py1/texsize-frac; + + if(flags&TILEFLAG_VFLIP) + { + float tmp = u0; + u0 = u1; + u1 = tmp; + } + + if(flags&TILEFLAG_HFLIP) + { + float tmp = v0; + v0 = v1; + v1 = tmp; + } + + gfx_quads_setsubset(u0,v0,u1,v1); + + gfx_quads_drawTL(x*scale, y*scale, scale, scale); + } + } + + gfx_quads_end(); +} + +LAYER_TILES::LAYER_TILES(int w, int h) +{ + type = LAYERTYPE_TILES; + type_name = "Tiles"; + width = w; + height = h; + image = -1; + tex_id = -1; + game = 0; + + tiles = new TILE[width*height]; + mem_zero(tiles, width*height*sizeof(TILE)); +} + +LAYER_TILES::~LAYER_TILES() +{ + delete [] tiles; +} + +void LAYER_TILES::make_palette() +{ + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].index = y*16+x; +} + +void LAYER_TILES::render() +{ + if(image >= 0 && image < editor.map.images.len()) + tex_id = editor.map.images[image]->tex_id; + gfx_texture_set(tex_id); + render_tilemap(tiles, width, height, 32.0f); +} + +int LAYER_TILES::convert_x(float x) const { return (int)(x/32.0f); } +int LAYER_TILES::convert_y(float y) const { return (int)(y/32.0f); } + +void LAYER_TILES::convert(RECT rect, RECTi *out) +{ + out->x = convert_x(rect.x); + out->y = convert_y(rect.y); + out->w = convert_x(rect.x+rect.w+31) - out->x; + out->h = convert_y(rect.y+rect.h+31) - out->y; +} + +void LAYER_TILES::snap(RECT *rect) +{ + RECTi out; + convert(*rect, &out); + rect->x = out.x*32.0f; + rect->y = out.y*32.0f; + rect->w = out.w*32.0f; + rect->h = out.h*32.0f; +} + +void LAYER_TILES::clamp(RECTi *rect) +{ + if(rect->x < 0) + { + rect->w += rect->x; + rect->x = 0; + } + + if(rect->y < 0) + { + rect->h += rect->y; + rect->y = 0; + } + + if(rect->x+rect->w > width) + rect->w = width-rect->x; + + if(rect->y+rect->h > height) + rect->h = height-rect->y; + + if(rect->h < 0) + rect->h = 0; + if(rect->w < 0) + rect->w = 0; +} + +void LAYER_TILES::brush_selecting(RECT rect) +{ + gfx_texture_set(-1); + gfx_quads_begin(); + gfx_setcolor(1,1,1,0.4f); + snap(&rect); + gfx_quads_drawTL(rect.x, rect.y, rect.w, rect.h); + gfx_quads_end(); + +} + +int LAYER_TILES::brush_grab(LAYERGROUP *brush, RECT rect) +{ + RECTi r; + convert(rect, &r); + clamp(&r); + + if(!r.w || !r.h) + return 0; + + // create new layers + LAYER_TILES *grabbed = new LAYER_TILES(r.w, r.h); + grabbed->tex_id = tex_id; + grabbed->image = image; + brush->add_layer(grabbed); + + // copy the tiles + for(int y = 0; y < r.h; y++) + for(int x = 0; x < r.w; x++) + grabbed->tiles[y*grabbed->width+x] = tiles[(r.y+y)*width+(r.x+x)]; + + return 1; +} + +void LAYER_TILES::brush_draw(LAYER *brush, float wx, float wy) +{ + // + LAYER_TILES *l = (LAYER_TILES *)brush; + int sx = convert_x(wx); + int sy = convert_y(wy); + + for(int y = 0; y < l->height; y++) + for(int x = 0; x < l->width; x++) + { + int fx = x+sx; + int fy = y+sy; + if(fx<0 || fx >= width || fy < 0 || fy >= height) + continue; + + tiles[fy*width+fx] = l->tiles[y*l->width+x]; + } +} + +void LAYER_TILES::brush_flip_x() +{ + for(int y = 0; y < height; y++) + for(int x = 0; x < width/2; x++) + { + TILE tmp = tiles[y*width+x]; + tiles[y*width+x] = tiles[y*width+x+width-1-x]; + tiles[y*width+x+width-1-x] = tmp; + } + + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].flags ^= TILEFLAG_VFLIP; +} + +void LAYER_TILES::brush_flip_y() +{ + for(int y = 0; y < height/2; y++) + for(int x = 0; x < width; x++) + { + TILE tmp = tiles[y*width+x]; + tiles[y*width+x] = tiles[(height-1-y)*width+x]; + tiles[(height-1-y)*width+x] = tmp; + } + + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].flags ^= TILEFLAG_HFLIP; +} + +void LAYER_TILES::resize(int new_w, int new_h) +{ + TILE *new_data = new TILE[new_w*new_h]; + mem_zero(new_data, new_w*new_h*sizeof(TILE)); + + // copy old data + for(int y = 0; y < min(new_h, height); y++) + mem_copy(&new_data[y*new_w], &tiles[y*width], min(width, new_w)*sizeof(TILE)); + + // replace old + delete [] tiles; + tiles = new_data; + width = new_w; + height = new_h; +} + + +void LAYER_TILES::render_properties(RECT *toolbox) +{ + if(editor.props != PROPS_LAYER) + return; + + enum + { + PROP_IMAGE=0, + PROP_WIDTH, + PROP_HEIGHT, + NUM_PROPS, + }; + + PROPERTY props[] = { + {"Image", image, PROPTYPE_INT_STEP, 0, 0}, + {"Width", width, PROPTYPE_INT_STEP, 1, 1000000000}, + {"Height", height, PROPTYPE_INT_STEP, 1, 1000000000}, + {0}, + }; + + static int ids[NUM_PROPS] = {0}; + int new_val = 0; + int prop = editor.do_properties(toolbox, props, ids, &new_val); + + if(prop == PROP_IMAGE) + image = new_val%editor.map.images.len(); + else if(prop == PROP_WIDTH && new_val > 1) + resize(new_val, height); + else if(prop == PROP_HEIGHT && new_val > 1) + resize(width, new_val); +} |