/* Generate func. */ static int vips_tile_cache_gen( VipsRegion *or, void *seq, void *a, void *b, gboolean *stop ) { VipsRegion *in = (VipsRegion *) seq; VipsTileCache *cache = (VipsTileCache *) b; const int tw = cache->tile_width; const int th = cache->tile_height; VipsRect *r = &or->valid; /* Find top left of tiles we need. */ int xs = (r->left / tw) * tw; int ys = (r->top / th) * th; int x, y; g_mutex_lock( cache->lock ); VIPS_DEBUG_MSG( "vips_tile_cache_gen: " "left = %d, top = %d, width = %d, height = %d\n", r->left, r->top, r->width, r->height ); for( y = ys; y < VIPS_RECT_BOTTOM( r ); y += th ) for( x = xs; x < VIPS_RECT_RIGHT( r ); x += tw ) { Tile *tile; VipsRect tarea; VipsRect hit; if( !(tile = tile_find( cache, in, x, y )) ) { g_mutex_unlock( cache->lock ); return( -1 ); } /* The area of the tile. */ tarea.left = x; tarea.top = y; tarea.width = tw; tarea.height = th; /* The part of the tile that we need. */ vips_rect_intersectrect( &tarea, r, &hit ); copy_region( tile->region, or, &hit ); } g_mutex_unlock( cache->lock ); return( 0 ); }
/* Loop over the output region, filling with data from cache. */ static int tile_cache_fill( REGION *out, void *seq, void *a, void *b ) { REGION *in = (REGION *) seq; Read *read = (Read *) b; const int tw = read->tile_width; const int th = read->tile_height; Rect *r = &out->valid; /* Find top left of tiles we need. */ int xs = (r->left / tw) * tw; int ys = (r->top / th) * th; int x, y; g_mutex_lock( read->lock ); for( y = ys; y < IM_RECT_BOTTOM( r ); y += th ) for( x = xs; x < IM_RECT_RIGHT( r ); x += tw ) { Tile *tile; Rect tarea; Rect hit; if( !(tile = tile_find( read, in, x, y )) ) { g_mutex_unlock( read->lock ); return( -1 ); } /* The area of the tile. */ tarea.left = x; tarea.top = y; tarea.width = tw; tarea.height = th; /* The part of the tile that we need. */ im_rect_intersectrect( &tarea, r, &hit ); copy_region( tile->region, out, &hit ); } g_mutex_unlock( read->lock ); return( 0 ); }
/* * Replace or place a tile. */ widp wid_game_map_client_replace_tile (widp w, double x, double y, thingp t, tpp tp) { tree_rootp thing_tiles; const char *tilename; tilep tile; widp child; verify(w); /* * Grow tl and br to fit the template thing. Use the first tile. */ if (!tp) { tp = thing_tp(t); if (!tp) { ERR("no thing template to replace on client"); return (0); } } if ((x < 0) || (y < 0) || (x >= MAP_WIDTH) || (y >= MAP_WIDTH)) { LOG("client: thing template [%s] cannot be placed at %f %f", tp_short_name(tp), x, y); return (0); } thing_tiles = tp_get_tiles(tp); if (!thing_tiles) { ERR("thing template [%s] has no tiles", tp_short_name(tp)); return (0); } thing_tilep thing_tile; /* * Get a random tile to start with. */ thing_tile = (typeof(thing_tile)) thing_tile_random(thing_tiles); /* * Find the real tile that corresponds to this name. */ tilename = thing_tile_name(thing_tile); tile = tile_find(tilename); if (!tile) { ERR("tile name %s from thing %s not found on client", tilename, tp_short_name(tp)); return (0); } /* * Make a new thing. */ child = wid_new_square_button(wid_game_map_client_grid_container, "client map tile"); wid_set_mode(child, WID_MODE_NORMAL); wid_set_no_shape(child); /* * "paint" the thing. */ wid_game_map_client_set_thing_template(child, tp); if (!t) { t = thing_client_local_new(tp); } wid_set_thing(child, t); wid_set_tile(child, tile); double dx = 0; double dy = 0; /* * Does it appear as a different size on screen? */ double scale = tp_get_scale(tp); /* * So we have baby and bigger slimes. But alas this is visual only and has * no effect on hp on the server yet. */ if (thing_is_variable_size(t)) { scale += gaussrand(0.0, 0.05); } if (scale != 1.0) { wid_scaling_blit_to_pct_in(child, scale, scale, 500, 9999999); } if (thing_is_cloud_effect(t)) { /* * The epicenter needs to be where it was on the server as we do a * flood fill to see where the rest of the explosion goes. */ if (!t->is_epicenter) { dx = gaussrand(0.0, 0.5); dy = gaussrand(0.0, 0.5); } wid_fade_out(child, 1000); } thing_client_wid_update(t, x + dx, y + dy, false /* smooth */, true /* is new */); /* * Offset tall things */ if (scale != 1.0) { if (thing_is_blit_y_offset(t)) { wid_set_blit_y_offset(child, wid_get_height(child) * scale * -((scale - 1.0) / 2.0)); } } /* * If this is a pre-existing thing perhaps being recreated ona new level * then it will have a direction already. Update it. */ if (thing_is_animated(t)) { thing_animate(t); } /* * This adds it to the grid wid. */ #ifdef DEBUG_CLIENT_THING wid_update(child); char name[20]; sprintf(name, "%d",t->thing_id); wid_set_text(child,name); #endif /* * We've been told about the epicenter of an explsion, now emulate the * blast. */ if (t->is_epicenter && thing_is_cloud_effect(t) ) { if ((tp->id == THING_EXPLOSION1) || (tp->id == THING_EXPLOSION2) || (tp->id == THING_EXPLOSION3) || (tp->id == THING_EXPLOSION4) || (tp->id == THING_SMALL_EXPLOSION1) || (tp->id == THING_SMALL_EXPLOSION2) || (tp->id == THING_SMALL_EXPLOSION3) || (tp->id == THING_SMALL_EXPLOSION4) || (tp->id == THING_MED_EXPLOSION1) || (tp->id == THING_MED_EXPLOSION2) || (tp->id == THING_MED_EXPLOSION3) || (tp->id == THING_MED_EXPLOSION4) || (tp->id == THING_FIREBURST1) || (tp->id == THING_FIREBURST2) || (tp->id == THING_FIREBURST3) || (tp->id == THING_FIREBURST4) || (tp->id == THING_BOMB) || (tp->id == THING_POISON1) || (tp->id == THING_POISON2) || (tp->id == THING_CLOUDKILL1) || (tp->id == THING_CLOUDKILL2)) { level_place_explosion(client_level, 0, /* owner */ tp, t->x, t->y, t->x, t->y); } else { ERR("unknown explosion %s", thing_logname(t)); } } const char *sound = tp_sound_on_creation(tp); if (sound) { if (thing_is_cloud_effect(t)) { if (t->is_epicenter) { sound_play_at(sound, t->x, t->y); } } else { sound_play_at(sound, t->x, t->y); } } return (child); }
void cloud_tick (int display) { double w = game.video_gl_width; double h = game.video_gl_height; double cloud_w = w / 30.0; double cloud_h = w / 40.0; static double wind = 0.3; static tilep tile; if (!tile) { tile = tile_find("snow_mound5"); } fpoint tl, br; blit_init(); cloud *f; cloud *f_eo = clouds + nclouds; f = clouds; while (f < f_eo) { if (!f->active) { f->active = true; f->x = myrand() % (int)w; f->y = myrand() % (int)h; f->scale = gauss(1.5, 0.2); } double dw = cloud_w * (f->scale + 0.2); double dh = cloud_h * (f->scale + 0.2); tl.x = f->x - dw; tl.y = f->y - dh; br.x = f->x + dw; br.y = f->y + dh; color c = BLACK; c.a = 100.0; glcolor(c); tl.x += w / 20; tl.y += w / 12; br.x += w / 20; br.y += w / 12; if (display) { tile_blit_fat(0, tile, 0, &tl, &br); } f++; } f = clouds; while (f < f_eo) { double dw = cloud_w * f->scale; double dh = cloud_h * f->scale; tl.x = f->x - dw; tl.y = f->y - dh; br.x = f->x + dw; br.y = f->y + dh; f->x += wind; color c = WHITE; c.a = 150.0; glcolor(c); if (display) { tile_blit_fat(0, tile, 0, &tl, &br); } f++; } blit_flush(); cloud_move(false); }