Beispiel #1
0
/* 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 );
}
Beispiel #2
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);
}
Beispiel #4
0
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);
}