diff options
| author | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-03-29 11:44:03 +0000 |
|---|---|---|
| committer | Magnus Auvinen <magnus.auvinen@gmail.com> | 2008-03-29 11:44:03 +0000 |
| commit | 7a3874745ca370a799d95b5f86e85fcc8eadefbb (patch) | |
| tree | 16f1e28f2f499279496866a63cabf88e2f2ad6c4 | |
| parent | 171d6b1c206c0488b59d157bc266319bf4ab482b (diff) | |
| download | zcatch-7a3874745ca370a799d95b5f86e85fcc8eadefbb.tar.gz zcatch-7a3874745ca370a799d95b5f86e85fcc8eadefbb.zip | |
fixed loads of graphical optimizations
24 files changed, 384 insertions, 196 deletions
diff --git a/data/maps/ctf1.map b/data/maps/ctf1.map index 5e00a4e7..f41e903b 100644 --- a/data/maps/ctf1.map +++ b/data/maps/ctf1.map Binary files differdiff --git a/data/maps/ctf2.map b/data/maps/ctf2.map index 81705329..35abdc79 100644 --- a/data/maps/ctf2.map +++ b/data/maps/ctf2.map Binary files differdiff --git a/data/maps/dm1.map b/data/maps/dm1.map index 292d85a2..27877cba 100644 --- a/data/maps/dm1.map +++ b/data/maps/dm1.map Binary files differdiff --git a/data/maps/dm2.map b/data/maps/dm2.map index 8c68850d..e49cdb04 100644 --- a/data/maps/dm2.map +++ b/data/maps/dm2.map Binary files differdiff --git a/data/maps/dm6.map b/data/maps/dm6.map index 436b8a72..0cf170d0 100644 --- a/data/maps/dm6.map +++ b/data/maps/dm6.map Binary files differdiff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.c index a8da7457..72b5536f 100644 --- a/src/engine/client/ec_client.c +++ b/src/engine/client/ec_client.c @@ -585,7 +585,9 @@ const char *client_error_string() static void client_render() { - gfx_clear(0.0f,0.0f,0.0f); + if(config.gfx_clear) + gfx_clear(1,1,0); + modc_render(); client_debug_render(); } diff --git a/src/engine/client/ec_gfx.c b/src/engine/client/ec_gfx.c index 53fe1790..3efcdac7 100644 --- a/src/engine/client/ec_gfx.c +++ b/src/engine/client/ec_gfx.c @@ -88,7 +88,7 @@ static void flush() if(num_vertices == 0) return; - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glVertexPointer(3, GL_FLOAT, @@ -216,11 +216,14 @@ int gfx_init() glDisable(GL_DEPTH_TEST); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); -/* glAlphaFunc(GL_GREATER, 0); - glEnable(GL_ALPHA_TEST);*/ - - + + glAlphaFunc(GL_GREATER, 0); + glEnable(GL_ALPHA_TEST); + glDepthMask(0); + gfx_mask_op(MASK_NONE, 0); + /*glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);*/ + /* Set all z to -5.0f */ for (i = 0; i < vertex_buffer_size; i++) @@ -342,13 +345,21 @@ int gfx_unload_texture(int index) return 0; } +void gfx_blend_none() +{ + glDisable(GL_BLEND); +} + + void gfx_blend_normal() { + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); } void gfx_blend_additive() { + glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE); } @@ -636,24 +647,27 @@ void gfx_swap() { static PERFORMACE_INFO pscope = {"glfwSwapBuffers", 0}; perf_start(&pscope); - glFinish(); glfwSwapBuffers(); perf_end(); } - - { - static PERFORMACE_INFO pscope = {"glFlush", 0}; - perf_start(&pscope); - glFlush(); - perf_end(); - } + /* + if(inp_key_pressed('P')) { - static PERFORMACE_INFO pscope = {"glFinish", 0}; - perf_start(&pscope); - glFinish(); - perf_end(); - } + { + static PERFORMACE_INFO pscope = {"glFlush", 0}; + perf_start(&pscope); + glFlush(); + perf_end(); + } + + { + static PERFORMACE_INFO pscope = {"glFinish", 0}; + perf_start(&pscope); + glFinish(); + perf_end(); + } + }*/ { static PERFORMACE_INFO pscope = {"glfwPollEvents", 0}; diff --git a/src/engine/e_config_variables.h b/src/engine/e_config_variables.h index 773093dc..5e355492 100644 --- a/src/engine/e_config_variables.h +++ b/src/engine/e_config_variables.h @@ -34,6 +34,7 @@ MACRO_CONFIG_INT(gfx_screen_width, 800, 0, 0) MACRO_CONFIG_INT(gfx_screen_height, 600, 0, 0) MACRO_CONFIG_INT(gfx_fullscreen, 1, 0, 1) MACRO_CONFIG_INT(gfx_color_depth, 24, 16, 24) +MACRO_CONFIG_INT(gfx_clear, 0, 0, 1) MACRO_CONFIG_INT(gfx_vsync, 1, 0, 1) MACRO_CONFIG_INT(gfx_display_all_modes, 0, 0, 1) MACRO_CONFIG_INT(gfx_texture_compression, 0, 0, 1) diff --git a/src/engine/e_engine.c b/src/engine/e_engine.c index a9e0e86e..d356fd4b 100644 --- a/src/engine/e_engine.c +++ b/src/engine/e_engine.c @@ -300,7 +300,9 @@ void mastersrv_update() { /* we got a result from the lookup ready */ if(master_servers[i].lookup.result == 0) + { master_servers[i].addr = master_servers[i].lookup.addr; + } master_servers[i].lookup.state = STATE_PROCESSED; } @@ -311,6 +313,13 @@ void mastersrv_update() if(!needs_update) { + /* make sure to destroy the threads */ + for(i = 0; i < NUM_LOOKUP_THREADS; i++) + { + thread_destroy(master_servers[i].lookup.thread); + master_servers[i].lookup.thread = 0; + } + dbg_msg("engine/mastersrv", "saving addresses"); mastersrv_save(); } diff --git a/src/engine/e_if_gfx.h b/src/engine/e_if_gfx.h index 265d41d3..525633b4 100644 --- a/src/engine/e_if_gfx.h +++ b/src/engine/e_if_gfx.h @@ -455,7 +455,7 @@ void gfx_mapscreen(float tl_x, float tl_y, float br_x, float br_y); This is equal to glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA). See Also: - <gfx_blend_additive> + <gfx_blend_additive,gfx_blend_none> */ void gfx_blend_normal(); @@ -468,11 +468,24 @@ void gfx_blend_normal(); This is equal to glBlendFunc(GL_SRC_ALPHA, GL_ONE). See Also: - <gfx_blend_normal> + <gfx_blend_normal,gfx_blend_none> */ void gfx_blend_additive(); /* + Function: gfx_blend_none + Disables blending + + Remarks: + This must be used before calling <gfx_quads_begin>. + + See Also: + <gfx_blend_normal,gfx_blend_additive> +*/ +void gfx_blend_none(); + + +/* Function: gfx_setcolorvertex Sets the color of a vertex. diff --git a/src/engine/e_system.c b/src/engine/e_system.c index ef1ddda2..5075c062 100644 --- a/src/engine/e_system.c +++ b/src/engine/e_system.c @@ -330,6 +330,12 @@ void thread_wait(void *thread) void thread_destroy(void *thread) { +#if defined(CONF_FAMILY_UNIX) + void *r = 0; + pthread_join((pthread_t)thread, &r); +#else + /*#error not implemented*/ +#endif } void thread_yield() diff --git a/src/engine/server/es_register.c b/src/engine/server/es_register.c index 2d482359..fe8cd959 100644 --- a/src/engine/server/es_register.c +++ b/src/engine/server/es_register.c @@ -202,7 +202,7 @@ void register_update() register_first = 0; /* check if we should send new heartbeat again */ - if(now > register_state_start+freq*30) + if(now > register_state_start+freq) { if(register_count == 120) /* redo the whole process after 60 minutes to balance out the master servers */ register_new_state(REGISTERSTATE_START); diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp index 4fe312c5..6bc83af9 100644 --- a/src/game/client/gc_client.cpp +++ b/src/game/client/gc_client.cpp @@ -983,10 +983,7 @@ void render_game() // render the world float zoom = 1.0f; - if(inp_key_pressed('E')) - zoom = 0.5f; - - gfx_clear(0.65f,0.78f,0.9f); + if(spectate) render_world(mouse_pos.x, mouse_pos.y, zoom); else @@ -1485,7 +1482,12 @@ void render_game() float ramp = velocity_ramp(velspeed, tuning.velramp_start, tuning.velramp_range, tuning.velramp_curvature); char buf[512]; - str_format(buf, sizeof(buf), "%.0f\n%.0f\n%.2f\n%d %s", velspeed, velspeed*ramp, ramp, netobj_num_corrections(), netobj_corrected_on()); + str_format(buf, sizeof(buf), "%.0f\n%.0f\n%.2f\n%d %s\n%d %d", + velspeed, velspeed*ramp, ramp, + netobj_num_corrections(), netobj_corrected_on(), + netobjects.local_character->x, + netobjects.local_character->y + ); gfx_text(0, 150, 50, 12, buf, -1); } diff --git a/src/game/client/gc_render.cpp b/src/game/client/gc_render.cpp index 8cbc3b2e..33187f62 100644 --- a/src/game/client/gc_render.cpp +++ b/src/game/client/gc_render.cpp @@ -297,10 +297,26 @@ static void envelope_eval(float time_offset, int env, float *channels) void render_layers(float center_x, float center_y, int pass) { bool passed_gamelayer = false; + for(int g = 0; g < layers_num_groups(); g++) { MAPITEM_GROUP *group = layers_get_group(g); + if(group->version >= 2 && group->use_clipping) + { + // set clipping + float points[4]; + mapscreen_to_group(center_x, center_y, layers_game_group()); + gfx_getscreen(&points[0], &points[1], &points[2], &points[3]); + float x0 = (group->clip_x - points[0]) / (points[2]-points[0]); + float y0 = (group->clip_y - points[1]) / (points[3]-points[1]); + float x1 = ((group->clip_x+group->clip_w) - points[0]) / (points[2]-points[0]); + float y1 = ((group->clip_y+group->clip_h) - points[1]) / (points[3]-points[1]); + + gfx_clip_enable((int)(x0*gfx_screenwidth()), (int)(y0*gfx_screenheight()), + (int)((x1-x0)*gfx_screenwidth()), (int)((y1-y0)*gfx_screenheight())); + } + mapscreen_to_group(center_x, center_y, group); for(int l = 0; l < group->num_layers; l++) @@ -319,7 +335,9 @@ void render_layers(float center_x, float center_y, int pass) passed_gamelayer = 1; } - if(pass == 0) + if(pass == -1) + render = true; + else if(pass == 0) { if(passed_gamelayer) return; @@ -331,7 +349,7 @@ void render_layers(float center_x, float center_y, int pass) render = true; } - if(render) + if(render && !is_game_layer) { if(layer->type == LAYERTYPE_TILES) { @@ -340,8 +358,12 @@ void render_layers(float center_x, float center_y, int pass) gfx_texture_set(-1); else gfx_texture_set(img_get(tmap->image)); + TILE *tiles = (TILE *)map_get_data(tmap->data); - render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), 1); + gfx_blend_none(); + render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_OPAQUE); + gfx_blend_normal(); + render_tilemap(tiles, tmap->width, tmap->height, 32.0f, vec4(1,1,1,1), TILERENDERFLAG_EXTEND|LAYERRENDERFLAG_TRANSPARENT); } else if(layer->type == LAYERTYPE_QUADS) { @@ -350,11 +372,19 @@ void render_layers(float center_x, float center_y, int pass) gfx_texture_set(-1); else gfx_texture_set(img_get(qlayer->image)); + QUAD *quads = (QUAD *)map_get_data_swapped(qlayer->data); - render_quads(quads, qlayer->num_quads, envelope_eval); + + gfx_blend_none(); + render_quads(quads, qlayer->num_quads, envelope_eval, LAYERRENDERFLAG_OPAQUE); + gfx_blend_normal(); + render_quads(quads, qlayer->num_quads, envelope_eval, LAYERRENDERFLAG_TRANSPARENT); + } } } + + gfx_clip_disable(); } } @@ -464,10 +494,11 @@ static void render_players() // renders the complete game world void render_world(float center_x, float center_y, float zoom) -{ +{ // render background layers render_layers(center_x, center_y, 0); - + gfx_clip_disable(); + // render trails particle_render(PARTGROUP_PROJECTILE_TRAIL); @@ -486,81 +517,8 @@ void render_world(float center_x, float center_y, float zoom) // render foreground layers render_layers(center_x, center_y, 1); + gfx_clip_disable(); // render damage indications render_damage_indicators(); - - - - // render screen sizes - if(false) - { - gfx_texture_set(-1); - gfx_lines_begin(); - - float last_points[4]; - float start = 1.0f; //9.0f/16.0f; - float end = 16.0f/9.0f; - const int num_steps = 20; - for(int i = 0; i <= num_steps; i++) - { - float points[4]; - float aspect = start + (end-start)*(i/(float)num_steps); - - mapscreen_to_world( - center_x, center_y, - 1.0f, 1.0f, 0.0f, 0.0f, aspect, 1.0f, points); - - if(i == 0) - { - gfx_lines_draw(points[0], points[1], points[2], points[1]); - gfx_lines_draw(points[0], points[3], points[2], points[3]); - } - - if(i != 0) - { - gfx_lines_draw(points[0], points[1], last_points[0], last_points[1]); - gfx_lines_draw(points[2], points[1], last_points[2], last_points[1]); - gfx_lines_draw(points[0], points[3], last_points[0], last_points[3]); - gfx_lines_draw(points[2], points[3], last_points[2], last_points[3]); - } - - if(i == num_steps) - { - gfx_lines_draw(points[0], points[1], points[0], points[3]); - gfx_lines_draw(points[2], points[1], points[2], points[3]); - } - - mem_copy(last_points, points, sizeof(points)); - } - - if(1) - { - gfx_setcolor(1,0,0,1); - for(int i = 0; i < 2; i++) - { - float points[4]; - float aspects[] = {4.0f/3.0f, 16.0f/10.0f, 5.0f/4.0f, 16.0f/9.0f}; - float aspect = aspects[i]; - - mapscreen_to_world( - center_x, center_y, - 1.0f, 1.0f, 0.0f, 0.0f, aspect, 1.0f, points); - - RECT r; - r.x = points[0]; - r.y = points[1]; - r.w = points[2]-points[0]; - r.h = points[3]-points[1]; - - gfx_lines_draw(r.x, r.y, r.x+r.w, r.y); - gfx_lines_draw(r.x+r.w, r.y, r.x+r.w, r.y+r.h); - gfx_lines_draw(r.x+r.w, r.y+r.h, r.x, r.y+r.h); - gfx_lines_draw(r.x, r.y+r.h, r.x, r.y); - gfx_setcolor(0,1,0,1); - } - } - - gfx_lines_end(); - } } diff --git a/src/game/client/gc_render.h b/src/game/client/gc_render.h index 53b6510a..b3439e93 100644 --- a/src/game/client/gc_render.h +++ b/src/game/client/gc_render.h @@ -29,6 +29,11 @@ enum { SPRITE_FLAG_FLIP_Y=1, SPRITE_FLAG_FLIP_X=2, + + LAYERRENDERFLAG_OPAQUE=1, + LAYERRENDERFLAG_TRANSPARENT=2, + + TILERENDERFLAG_EXTEND=4, }; typedef struct sprite; @@ -66,7 +71,7 @@ void render_player( // map render methods (gc_render_map.cpp) void render_eval_envelope(ENVPOINT *points, int num_points, int channels, float time, float *result); -void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels)); +void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels), int flags); void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flags); // helpers diff --git a/src/game/client/gc_render_map.cpp b/src/game/client/gc_render_map.cpp index 8693ed18..2ad3ad94 100644 --- a/src/game/client/gc_render_map.cpp +++ b/src/game/client/gc_render_map.cpp @@ -75,7 +75,7 @@ static void rotate(POINT *center, POINT *point, float rotation) point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y); } -void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels)) +void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, int env, float *channels), int renderflags) { gfx_quads_begin(); float conv = 1/255.0f; @@ -83,6 +83,27 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in { QUAD *q = &quads[i]; + float r=1, g=1, b=1, a=1; + + if(q->color_env >= 0) + { + float channels[4]; + eval(q->color_env_offset/1000.0f, q->color_env, channels); + r = channels[0]; + g = channels[1]; + b = channels[2]; + a = channels[3]; + } + + bool opaque = false; + if(a < 0.01f || (q->colors[0].a < 0.01f && q->colors[1].a < 0.01f && q->colors[2].a < 0.01f && q->colors[3].a < 0.01f)) + opaque = true; + + if(opaque && !(renderflags&LAYERRENDERFLAG_OPAQUE)) + continue; + if(!opaque && !(renderflags&LAYERRENDERFLAG_TRANSPARENT)) + continue; + gfx_quads_setsubset_free( fx2f(q->texcoords[0].x), fx2f(q->texcoords[0].y), fx2f(q->texcoords[1].x), fx2f(q->texcoords[1].y), @@ -90,7 +111,6 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in fx2f(q->texcoords[3].x), fx2f(q->texcoords[3].y) ); - float r=1, g=1, b=1, a=1; float offset_x = 0; float offset_y = 0; float rot = 0; @@ -105,15 +125,6 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in rot = channels[2]/360.0f*pi*2; } - if(q->color_env >= 0) - { - float channels[4]; - eval(q->color_env_offset/1000.0f, q->color_env, channels); - r = channels[0]; - g = channels[1]; - b = channels[2]; - a = channels[3]; - } gfx_setcolorvertex(0, q->colors[0].r*conv*r, q->colors[0].g*conv*g, q->colors[0].b*conv*b, q->colors[0].a*conv*a); gfx_setcolorvertex(1, q->colors[1].r*conv*r, q->colors[1].g*conv*g, q->colors[1].b*conv*b, q->colors[1].a*conv*a); @@ -147,12 +158,12 @@ void render_quads(QUAD *quads, int num_quads, void (*eval)(float time_offset, in gfx_quads_end(); } - -void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flags) +void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int renderflags) { - //gfx_texture_set(img_get(tmap->image)); + //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); + //gfx_mapscreen(screen_x0-50, screen_y0-50, screen_x1+50, screen_y1+50); // calculate the final pixelsize for the tiles float tile_pixelsize = 1024/32.0f; @@ -178,7 +189,7 @@ void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flag int mx = x; int my = y; - if(flags) + if(renderflags&TILERENDERFLAG_EXTEND) { if(mx<0) mx = 0; @@ -207,39 +218,55 @@ void render_tilemap(TILE *tiles, int w, int h, float scale, vec4 color, int flag 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) + bool render = false; + if(flags&TILEFLAG_OPAQUE) { - float tmp = u0; - u0 = u1; - u1 = tmp; + if(renderflags&LAYERRENDERFLAG_OPAQUE) + render = true; } - - if(flags&TILEFLAG_HFLIP) + else { - float tmp = v0; - v0 = v1; - v1 = tmp; + if(renderflags&LAYERRENDERFLAG_TRANSPARENT) + render = true; } - gfx_quads_setsubset(u0,v0,u1,v1); + if(render) + { + + 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; + } - gfx_quads_drawTL(x*scale, y*scale, scale, scale); + 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); + } } - x += tiles[c].skip; } gfx_quads_end(); + gfx_mapscreen(screen_x0, screen_y0, screen_x1, screen_y1); } diff --git a/src/game/editor/ed_editor.cpp b/src/game/editor/ed_editor.cpp index 1e9a0de9..7ae46f0b 100644 --- a/src/game/editor/ed_editor.cpp +++ b/src/game/editor/ed_editor.cpp @@ -37,6 +37,12 @@ LAYERGROUP::LAYERGROUP() offset_y = 0; parallax_x = 100; parallax_y = 100; + + use_clipping = 0; + clip_x = 0; + clip_y = 0; + clip_w = 0; + clip_h = 0; } LAYERGROUP::~LAYERGROUP() @@ -75,6 +81,19 @@ void LAYERGROUP::render() { mapscreen(); + if(use_clipping) + { + float points[4]; + editor.map.game_group->mapping(points); + float x0 = (clip_x - points[0]) / (points[2]-points[0]); + float y0 = (clip_y - points[1]) / (points[3]-points[1]); + float x1 = ((clip_x+clip_w) - points[0]) / (points[2]-points[0]); + float y1 = ((clip_y+clip_h) - points[1]) / (points[3]-points[1]); + + gfx_clip_enable((int)(x0*gfx_screenwidth()), (int)(y0*gfx_screenheight()), + (int)((x1-x0)*gfx_screenwidth()), (int)((y1-y0)*gfx_screenheight())); + } + for(int i = 0; i < layers.len(); i++) { if(layers[i]->visible && layers[i] != editor.map.game_layer) @@ -83,6 +102,8 @@ void LAYERGROUP::render() layers[i]->render(); } } + + gfx_clip_disable(); } bool LAYERGROUP::is_empty() const { return layers.len() == 0; } @@ -116,7 +137,37 @@ int LAYERGROUP::swap_layers(int index0, int index1) if(index0 == index1) return index0; swap(layers[index0], layers[index1]); return index1; -} +} + +void IMAGE::analyse_tileflags() +{ + mem_zero(tileflags, sizeof(tileflags)); + + int tw = width/16; // tilesizes + int th = height/16; + unsigned char *pixeldata = (unsigned char *)data; + + int tile_id = 0; + for(int ty = 0; ty < 16; ty++) + for(int tx = 0; tx < 16; tx++, tile_id++) + { + bool opaque = true; + for(int x = 0; x < tw; x++) + for(int y = 0; y < th; y++) + { + int p = (ty*tw+y)*width + tx*tw+x; + if(pixeldata[p*4+3] < 250) + { + opaque = false; + break; + } + } + + if(opaque) + tileflags[tile_id] |= TILEFLAG_OPAQUE; + } + +} /******************************************************** OTHER @@ -777,11 +828,7 @@ static void do_quad_point(QUAD *q, int quad_index, int v) static void do_map_editor(RECT view, RECT toolbar) { - // do the toolbar - if(editor.gui_active) - do_toolbar(toolbar); - - ui_clip_enable(&view); + //ui_clip_enable(&view); bool show_picker = inp_key_pressed(KEY_SPACE) != 0; @@ -792,6 +839,7 @@ static void do_map_editor(RECT view, RECT toolbar) { if(editor.map.groups[g]->visible) editor.map.groups[g]->render(); + //ui_clip_enable(&view); } // render the game above everything else @@ -805,7 +853,7 @@ static void do_map_editor(RECT view, RECT toolbar) static void *editor_id = (void *)&editor_id; int inside = ui_mouse_inside(&view); - // fetch mouse position + // fetch mouse position float wx = ui_mouse_world_x(); float wy = ui_mouse_world_y(); float mx = ui_mouse_x(); @@ -1084,6 +1132,29 @@ static void do_map_editor(RECT view, RECT toolbar) } } } + + if(editor.get_selected_group() && editor.get_selected_group()->use_clipping) + { + LAYERGROUP *g = editor.map.game_group; + g->mapscreen(); + + gfx_texture_set(-1); + gfx_lines_begin(); + + RECT r; + r.x = editor.get_selected_group()->clip_x; + r.y = editor.get_selected_group()->clip_y; + r.w = editor.get_selected_group()->clip_w; + r.h = editor.get_selected_group()->clip_h; + + gfx_setcolor(1,0,0,1); + gfx_lines_draw(r.x, r.y, r.x+r.w, r.y); + gfx_lines_draw(r.x+r.w, r.y, r.x+r.w, r.y+r.h); + gfx_lines_draw(r.x+r.w, r.y+r.h, r.x, r.y+r.h); + gfx_lines_draw(r.x, r.y+r.h, r.x, r.y); + + gfx_lines_end(); + } // render screen sizes if(editor.proof_borders) @@ -1161,7 +1232,7 @@ static void do_map_editor(RECT view, RECT toolbar) } gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); - ui_clip_disable(); + //ui_clip_disable(); } @@ -1282,8 +1353,6 @@ static void render_layers(RECT toolbox, RECT toolbar, RECT view) { RECT layersbox = toolbox; - do_map_editor(view, toolbar); - if(!editor.gui_active) return; @@ -1317,7 +1386,7 @@ static void render_layers(RECT toolbox, RECT toolbar, RECT view) static int group_popup_id = 0; if(result == 2) - ui_invoke_popup_menu(&group_popup_id, 0, ui_mouse_x(), ui_mouse_y(), 120, 150, popup_group); + ui_invoke_popup_menu(&group_popup_id, 0, ui_mouse_x(), ui_mouse_y(), 120, 200, popup_group); } @@ -2163,12 +2232,27 @@ void EDITOR::render() ui_hsplit_t(&view, 16.0f, &toolbar, &view); ui_hsplit_b(&view, 16.0f, &view, &statusbar); - + if(editor.show_envelope_editor) + { + float size = 125.0f; + if(editor.show_envelope_editor == 2) + size *= 2.0f; + else if(editor.show_envelope_editor == 3) + size *= 3.0f; + ui_hsplit_b(&view, size, &view, &envelope_editor); + } + } + + // a little hack for now + if(editor.mode == MODE_LAYERS) + do_map_editor(view, toolbar); + + if(editor.gui_active) + { float brightness = 0.25f; - render_background(menubar, background_texture, 128.0f, brightness*0); ui_margin(&menubar, 2.0f, &menubar); - + render_background(toolbox, background_texture, 128.0f, brightness); ui_margin(&toolbox, 2.0f, &toolbox); @@ -2179,24 +2263,23 @@ void EDITOR::render() render_background(statusbar, background_texture, 128.0f, brightness); ui_margin(&statusbar, 2.0f, &statusbar); + // do the toolbar + if(editor.mode == MODE_LAYERS) + do_toolbar(toolbar); + if(editor.show_envelope_editor) { - float size = 125.0f; - if(editor.show_envelope_editor == 2) - size *= 2.0f; - else if(editor.show_envelope_editor == 3) - size *= 3.0f; - ui_hsplit_b(&view, size, &view, &envelope_editor); render_background(envelope_editor, background_texture, 128.0f, brightness); ui_margin(&envelope_editor, 2.0f, &envelope_editor); } } + if(editor.mode == MODE_LAYERS) render_layers(toolbox, toolbar, view); else if(editor.mode == MODE_IMAGES) render_images(toolbox, toolbar, view); - + gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); if(editor.gui_active) diff --git a/src/game/editor/ed_editor.hpp b/src/game/editor/ed_editor.hpp index e2fda9ef..23dbd382 100644 --- a/src/game/editor/ed_editor.hpp +++ b/src/game/editor/ed_editor.hpp @@ -177,6 +177,12 @@ public: int parallax_x; int parallax_y; + int use_clipping; + int clip_x; + int clip_y; + int clip_w; + int clip_h; + const char *name; bool game_group; bool visible; @@ -230,9 +236,12 @@ public: gfx_unload_texture(tex_id); } + void analyse_tileflags(); + int tex_id; int external; char name[128]; + unsigned char tileflags[256]; }; class MAP @@ -443,6 +452,8 @@ public: virtual void modify_image_index(INDEX_MODIFY_FUNC func); virtual void modify_envelope_index(INDEX_MODIFY_FUNC func); + + void prepare_for_save(); void get_size(float *w, float *h) { *w = width*32.0f; *h = height*32.0f; } diff --git a/src/game/editor/ed_io.cpp b/src/game/editor/ed_io.cpp index b805b0b5..3fd4fcac 100644 --- a/src/game/editor/ed_io.cpp +++ b/src/game/editor/ed_io.cpp @@ -214,6 +214,11 @@ int MAP::save(const char *filename) for(int i = 0; i < images.len(); i++) { IMAGE *img = images[i]; + + // analyse the image for when saving (should be done when we load the image) + // TODO! + img->analyse_tileflags(); + MAPITEM_IMAGE item; item.version = 1; @@ -234,12 +239,17 @@ int MAP::save(const char *filename) { LAYERGROUP *group = groups[g]; MAPITEM_GROUP gitem; - gitem.version = 1; + gitem.version = MAPITEM_GROUP::CURRENT_VERSION; gitem.parallax_x = group->parallax_x; gitem.parallax_y = group->parallax_y; gitem.offset_x = group->offset_x; gitem.offset_y = group->offset_y; + gitem.use_clipping = group->use_clipping; + gitem.clip_x = group->clip_x; + gitem.clip_y = group->clip_y; + gitem.clip_w = group->clip_w; + gitem.clip_h = group->clip_h; gitem.start_layer = layer_count; gitem.num_layers = 0; @@ -249,6 +259,8 @@ int MAP::save(const char *filename) { dbg_msg("editor", "saving tiles layer"); LAYER_TILES *layer = (LAYER_TILES *)group->layers[l]; + layer->prepare_for_save(); + MAPITEM_LAYER_TILEMAP item; item.version = 2; @@ -432,12 +444,25 @@ int MAP::load(const char *filename) for(int g = 0; g < num; g++) { MAPITEM_GROUP *gitem = (MAPITEM_GROUP *)datafile_get_item(df, start+g, 0, 0); + + if(gitem->version < 1 || gitem->version > MAPITEM_GROUP::CURRENT_VERSION) + continue; + LAYERGROUP *group = new_group(); group->parallax_x = gitem->parallax_x; group->parallax_y = gitem->parallax_y; group->offset_x = gitem->offset_x; group->offset_y = gitem->offset_y; + if(gitem->version >= 2) + { + group->use_clipping = gitem->use_clipping; + group->clip_x = gitem->clip_x; + group->clip_y = gitem->clip_y; + group->clip_w = gitem->clip_w; + group->clip_h = gitem->clip_h; + } + for(int l = 0; l < gitem->num_layers; l++) { LAYER *layer = 0; diff --git a/src/game/editor/ed_layer_quads.cpp b/src/game/editor/ed_layer_quads.cpp index bf203ebb..f3df3818 100644 --- a/src/game/editor/ed_layer_quads.cpp +++ b/src/game/editor/ed_layer_quads.cpp @@ -36,7 +36,7 @@ void LAYER_QUADS::render() if(image >= 0 && image < editor.map.images.len()) gfx_texture_set(editor.map.images[image]->tex_id); - render_quads(quads.getptr(), quads.len(), envelope_eval); + render_quads(quads.getptr(), quads.len(), envelope_eval, LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT); } QUAD *LAYER_QUADS::new_quad() diff --git a/src/game/editor/ed_layer_tiles.cpp b/src/game/editor/ed_layer_tiles.cpp index 555c26a3..18e3b695 100644 --- a/src/game/editor/ed_layer_tiles.cpp +++ b/src/game/editor/ed_layer_tiles.cpp @@ -22,6 +22,20 @@ LAYER_TILES::~LAYER_TILES() delete [] tiles; } +void LAYER_TILES::prepare_for_save() +{ + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].flags &= TILEFLAG_VFLIP|TILEFLAG_HFLIP; + + if(image != -1) + { + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].flags |= editor.map.images[image]->tileflags[tiles[y*width+x].index]; + } +} + void LAYER_TILES::make_palette() { for(int y = 0; y < height; y++) @@ -34,7 +48,7 @@ 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, vec4(1,1,1,1), 0); + render_tilemap(tiles, width, height, 32.0f, vec4(1,1,1,1), LAYERRENDERFLAG_OPAQUE|LAYERRENDERFLAG_TRANSPARENT); } int LAYER_TILES::convert_x(float x) const { return (int)(x/32.0f); } diff --git a/src/game/editor/ed_popups.cpp b/src/game/editor/ed_popups.cpp index bcd26092..813dfd50 100644 --- a/src/game/editor/ed_popups.cpp +++ b/src/game/editor/ed_popups.cpp @@ -115,6 +115,11 @@ int popup_group(RECT view) PROP_POS_Y, PROP_PARA_X, PROP_PARA_Y, + PROP_USE_CLIPPING, + PROP_CLIP_X, + PROP_CLIP_Y, + PROP_CLIP_W, + PROP_CLIP_H, NUM_PROPS, }; @@ -124,6 +129,12 @@ int popup_group(RECT view) {"Pos Y", -editor.map.groups[editor.selected_group]->offset_y, PROPTYPE_INT_SCROLL, -1000000, 1000000}, {"Para X", editor.map.groups[editor.selected_group]->parallax_x, PROPTYPE_INT_SCROLL, -1000000, 1000000}, {"Para Y", editor.map.groups[editor.selected_group]->parallax_y, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + + {"Use Clipping", editor.map.groups[editor.selected_group]->use_clipping, PROPTYPE_BOOL, 0, 1}, + {"Clip X", editor.map.groups[editor.selected_group]->clip_x, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Clip Y", editor.map.groups[editor.selected_group]->clip_y, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Clip W", editor.map.groups[editor.selected_group]->clip_w, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Clip H", editor.map.groups[editor.selected_group]->clip_h, PROPTYPE_INT_SCROLL, -1000000, 1000000}, {0}, }; @@ -141,14 +152,15 @@ int popup_group(RECT view) // these can not be changed on the game group if(!editor.get_selected_group()->game_group) { - if(prop == PROP_PARA_X) - editor.map.groups[editor.selected_group]->parallax_x = new_val; - else if(prop == PROP_PARA_Y) - editor.map.groups[editor.selected_group]->parallax_y = new_val; - else if(prop == PROP_POS_X) - editor.map.groups[editor.selected_group]->offset_x = -new_val; - else if(prop == PROP_POS_Y) - editor.map.groups[editor.selected_group]->offset_y = -new_val; + if(prop == PROP_PARA_X) editor.map.groups[editor.selected_group]->parallax_x = new_val; + else if(prop == PROP_PARA_Y) editor.map.groups[editor.selected_group]->parallax_y = new_val; + else if(prop == PROP_POS_X) editor.map.groups[editor.selected_group]->offset_x = -new_val; + else if(prop == PROP_POS_Y) editor.map.groups[editor.selected_group]->offset_y = -new_val; + else if(prop == PROP_USE_CLIPPING) editor.map.groups[editor.selected_group]->use_clipping = new_val; + else if(prop == PROP_CLIP_X) editor.map.groups[editor.selected_group]->clip_x = new_val; + else if(prop == PROP_CLIP_Y) editor.map.groups[editor.selected_group]->clip_y = new_val; + else if(prop == PROP_CLIP_W) editor.map.groups[editor.selected_group]->clip_w = new_val; + else if(prop == PROP_CLIP_H) editor.map.groups[editor.selected_group]->clip_h = new_val; } return 0; diff --git a/src/game/g_layers.cpp b/src/game/g_layers.cpp index 6614bc90..07ffec4b 100644 --- a/src/game/g_layers.cpp +++ b/src/game/g_layers.cpp @@ -12,31 +12,24 @@ static int layers_num = 0; void layers_init() { map_get_type(MAPITEMTYPE_GROUP, &groups_start, &groups_num); + map_get_type(MAPITEMTYPE_LAYER, &layers_start, &layers_num); + for(int g = 0; g < layers_num_groups(); g++) { - int p = 0; - map_get_type(MAPITEMTYPE_LAYER, &layers_start, &layers_num); - - for(int i = 0; i < layers_num; i++) + MAPITEM_GROUP *group = layers_get_group(g); + for(int l = 0; l < group->num_layers; l++) { - MAPITEM_LAYER *layer = (MAPITEM_LAYER *)map_get_item(layers_start+i, 0, 0); + MAPITEM_LAYER *layer = layers_get_layer(group->start_layer+l); + if(layer->type == LAYERTYPE_TILES) { MAPITEM_LAYER_TILEMAP *tilemap = (MAPITEM_LAYER_TILEMAP *)layer; - - if(p) - { - p--; - if(p == 0) - tilemap->flags |= 2; - } - if(tilemap->flags&1) { game_layer = tilemap; - p = 2; + game_group = group; } - } + } } } } diff --git a/src/game/g_mapitems.h b/src/game/g_mapitems.h index 3caa5303..8093435a 100644 --- a/src/game/g_mapitems.h +++ b/src/game/g_mapitems.h @@ -47,6 +47,7 @@ enum TILEFLAG_VFLIP=1, TILEFLAG_HFLIP=2, + TILEFLAG_OPAQUE=4, LAYERFLAG_DETAIL=1, @@ -81,7 +82,7 @@ typedef struct unsigned char index; unsigned char flags; unsigned char skip; - unsigned char reserved2; + unsigned char reserved; } TILE; typedef struct @@ -94,7 +95,7 @@ typedef struct int image_data; } MAPITEM_IMAGE; -typedef struct +struct MAPITEM_GROUP_v1 { int version; int offset_x; @@ -104,7 +105,19 @@ typedef struct int start_layer; int num_layers; -} MAPITEM_GROUP; +} ; + + +struct MAPITEM_GROUP : public MAPITEM_GROUP_v1 +{ + enum { CURRENT_VERSION=2 }; + + int use_clipping; + int clip_x; + int clip_y; + int clip_w; + int clip_h; +} ; typedef struct { |