Пример #1
0
static texture_info * texture_update(sdl_window_info *window, const render_primitive *prim)
{
	sdl_info *sdl = (sdl_info *) window->dxdata;
	quad_setup_data setup;
	texture_info *texture;

	compute_setup(sdl, prim, &setup, prim->flags);

	texture = texture_find(sdl, prim, &setup);

	// if we didn't find one, create a new texture
	if (texture == NULL && prim->texture.base != NULL)
    {
        texture = texture_create(window, &prim->texture, &setup, prim->flags);
    }

    if (texture != NULL)
	{
		if (prim->texture.base != NULL && texture->texinfo.seqid != prim->texture.seqid)
		{
			texture->texinfo.seqid = prim->texture.seqid;
			// if we found it, but with a different seqid, copy the data
			texture_set_data(sdl, texture, &prim->texture, prim->flags);
		}

	}
    return texture;
}
Пример #2
0
/* ...buffer allocation from frontal camera (object detection engine) */
static int objdet_input_alloc(void *data, GstBuffer *buffer)
{
    app_data_t         *app = data;
    vsink_meta_t       *vmeta = gst_buffer_get_vsink_meta(buffer);
    int                 w = vmeta->width, h = vmeta->height;
    objdet_meta_t      *ometa;

    if (app->f_width)
    {
        /* ...verify buffer dimensions are valid */
        CHK_ERR(w == app->f_width && h == app->f_height, -EINVAL);
    }
    else
    {
        int     W = window_get_width(app->window);
        int     H = window_get_height(app->window);

        /* ...check dimensions are valid */
        CHK_ERR(w && h, -EINVAL);

        /* ...set buffer dimensions */
        app->f_width = w, app->f_height = h;

        /* ...initialize object detection engine */
        CHK_ERR(app->od = objdet_engine_init(&objdet_callback, app, w, h, __pixfmt_yuv_bpp(vmeta->format), app->od_cfg), -errno);

        /* ...create a viewport for data visualization */
        texture_scale_to_window(&app->view, app->window, w, h, &app->matrix);
        
        //texture_set_view_scale(&app->view, 0, 0, W, H, W, H, w, h);


        /* ...create transformation matrix */
        if (0)
        {
            cairo_matrix_t     *m = &app->matrix;
            
            m->xx = (double) W / w, m->xy = 0, m->x0 = 0;
            m->yx = 0, m->yy = (double) H / h, m->y0 = 0;
        }        
    }

    /* ...allocate texture to wrap the buffer */
    CHK_ERR(vmeta->priv = texture_create(w, h, vmeta->plane, vmeta->format), -errno);

    /* ...add custom buffer metadata */
    CHK_ERR(ometa = gst_buffer_add_objdet_meta(buffer), -(errno = ENOMEM));
    CHK_ERR(ometa->buf = texture_map(vmeta->priv, CL_MEM_READ_ONLY), -errno);
    GST_META_FLAG_SET(ometa, GST_META_FLAG_POOLED);

    /* ...add custom destructor to the buffer */
    gst_mini_object_weak_ref(GST_MINI_OBJECT(buffer), __destroy_od_texture, app);

    TRACE(INFO, _b("front-camera input buffer %p allocated (%p)"), buffer, ometa->buf);

    return 0;
}
Пример #3
0
RID VisualServer::texture_create_from_image(const Image& p_image,uint32_t p_flags) {

	RID texture = texture_create();
	texture_allocate(texture,p_image.get_width(), p_image.get_height(), p_image.get_format(), p_flags); //if it has mipmaps, use, else generate
	ERR_FAIL_COND_V(!texture.is_valid(),texture);

	texture_set_data(texture, p_image );
	
	return texture;
}
Пример #4
0
bool
texture_resize_capacity(Texture_data *data, const size_t size_hint)
{
  assert(data);
  assert(size_hint > data->size); // Will slice data

  // Create new data.
  Texture_data new_data;
  const bool created_new = texture_create(&new_data, size_hint);

  // Failed to resize.
  if(!created_new)
  {
    texture_destroy(&new_data);
    return false;
  }

  // Copy over data
  {
    memcpy(new_data.keys, data->keys, sizeof(uint32_t) * data->size);
    memcpy(new_data.field_name, data->field_name, sizeof(char) * data->size * 32);
    memcpy(new_data.field_texture, data->field_texture, sizeof(Ogl::Texture) * data->size * 1);
    memcpy(new_data.field_render_target, data->field_render_target, sizeof(Ogl::Frame_buffer) * data->size * 1);
  }

  // Swap ptrs
  {
    uint32_t *old_keys = data->keys;
    data->keys = new_data.keys;
    new_data.keys = old_keys;

    char *old_name = data->field_name;
    data->field_name = new_data.field_name;
    new_data.field_name = old_name;

    Ogl::Texture *old_texture = data->field_texture;
    data->field_texture = new_data.field_texture;
    new_data.field_texture = old_texture;

    Ogl::Frame_buffer *old_render_target = data->field_render_target;
    data->field_render_target = new_data.field_render_target;
    new_data.field_render_target = old_render_target;
  }

  // Set the Capacity
  {
    size_t *capacity = const_cast<size_t*>(&data->capacity);
    *capacity = new_data.capacity;
  }

  // Destroy new data
  texture_destroy(&new_data);

  return true;
}
Пример #5
0
void entity_particle_init(void) {
    if (!particle_created) {
        ent_particle_tex = texture_create("particles_sprite_sheet_x2_smooth.png");
        ent_particle_sprite = malloc(sizeof(sprite_t));
        ent_particle_sprite->count_x = 32;
        ent_particle_sprite->count_y = 11;
        ent_particle_sprite->pixs = 16*2;

        particle_created = true;
    }
}
Пример #6
0
void progressbar_create(progress_bar *bar,     
                       unsigned int x, unsigned int y,
                       unsigned int w, unsigned int h,
                       color border_topleft_color,
                       color border_bottomright_color,
                       color bg_color,
                       color int_topleft_color,
                       color int_bottomright_color,
                       color int_bg_color,
                       int orientation) {
    bar->x = x;
    bar->y = y;
    bar->w = w;
    bar->h = h;
    bar->orientation = orientation;
    bar->percentage = 100;
    bar->int_topleft_color = int_topleft_color;
    bar->int_bottomright_color = int_bottomright_color;
    bar->int_bg_color = int_bg_color;
    
    texture_create(&bar->block);
    texture_create(&bar->background);
    
    // Background,
    image tmp;
    image_create(&tmp, w, h);
    image_clear(&tmp, bg_color);
    image_rect_bevel(&tmp, 
                     0, 0, w-1, h-1, 
                     border_topleft_color, 
                     border_bottomright_color, 
                     border_bottomright_color, 
                     border_topleft_color);
    texture_init_from_img(&bar->background, &tmp);
    image_free(&tmp);
    
    // Bar
    progressbar_create_block(bar);
}
Пример #7
0
int animation_create(animation *ani, sd_animation *sdani, sd_palette *pal, int overlay, char *soundtable) {
    ani->sdani = sdani;
    array_create(&ani->sprites);
    ani->soundtable = soundtable;

    // Load textures
    sd_rgba_image *img = 0;
    for(int i = 0; i < sdani->frame_count; i++) {
        img = sd_sprite_image_decode(sdani->sprites[i]->img, pal, overlay);
        texture *tex = malloc(sizeof(texture));
        texture_create(tex, img->data, img->w, img->h);
        array_set(&ani->sprites, i, tex);
        sd_rgba_image_delete(img);
    }
    return 0;
}
Пример #8
0
void progressbar_create_block(progress_bar *bar) {
    float prog = bar->percentage / 100.0f;
    int w = bar->w * prog;
    if(w > 0) {
        image tmp;
        image_create(&tmp, w, bar->h);
        image_clear(&tmp, bar->int_bg_color);
        image_rect_bevel(&tmp, 
                         0, 0, w - 1, bar->h-1, 
                         bar->int_topleft_color, 
                         bar->int_bottomright_color, 
                         bar->int_bottomright_color, 
                         bar->int_topleft_color);
        texture_create(&bar->block);
        texture_init_from_img(&bar->block, &tmp);
        image_free(&tmp);
    }
}
Пример #9
0
/* ...input buffer allocation from surround-view camera set */
static int sview_input_alloc(void *data, GstBuffer *buffer)
{
    app_data_t         *app = data;
    vsink_meta_t       *vmeta = gst_buffer_get_vsink_meta(buffer);
    int                 w = vmeta->width, h = vmeta->height;

    /* ...make sure input buffer dimensions are valid */
    CHK_ERR(w == 1280 && h == 800, -EINVAL);

    /* ...allocate texture to wrap the buffer */
    CHK_ERR(vmeta->priv = texture_create(w, h, vmeta->plane, vmeta->format), -errno);

    /* ...add custom destructor to the buffer */
    gst_mini_object_weak_ref(GST_MINI_OBJECT(buffer), __destroy_sv_texture, app);

    TRACE(INFO, _b("input buffer %p allocated"), buffer);

    return 0;
}
Пример #10
0
RID VisualServer::get_white_texture() {

	if (white_texture.is_valid())
		return white_texture;

	DVector<uint8_t> wt;
	wt.resize(16*3);
	{
		DVector<uint8_t>::Write w =wt.write();
		for(int i=0;i<16*3;i++)
			w[i]=255;
	}
	Image white(4,4,0,Image::FORMAT_RGB,wt);
	white_texture=texture_create();
	texture_allocate(white_texture,4,4,Image::FORMAT_RGB);
	texture_set_data(white_texture,white);
	return white_texture;

}
Пример #11
0
int fbo_create(fbo *fbo, unsigned int w, unsigned int h) {
    // Texture and Renderbuffer object (RBO)
    rbo_create(&fbo->rbo, w, h);
    texture_create(&fbo->tex);
    texture_init(&fbo->tex, 0, w, h);
    
    // Create FBO
    glGenFramebuffers(1, &fbo->id);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo->id);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fbo->tex.id, 0);
    glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, fbo->rbo.id);
    
    // Make sure everything worked.
    int status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
    if(status != GL_FRAMEBUFFER_COMPLETE) {
        PERROR("Unable to create fbo: %s.", fbo_get_status(status));
        return 1;
    }
    return 0;
}
Пример #12
0
int font_load(font *font, const char* filename, unsigned int size) {
    sd_rgba_image *img;
    sd_font *sdfont;
    int pixsize;
    texture *tex;
    
    // Find vertical size
    switch(size) {
        case FONT_BIG: pixsize = 8; break;
        case FONT_SMALL: pixsize = 6; break;
        default:
            return 1;
    }
    
    // Open font file
    sdfont = sd_font_create();
    if(sd_font_load(sdfont, filename, pixsize)) {
        sd_font_delete(sdfont);
        return 2;
    }
    
    // Load into textures
    img = sd_rgba_image_create(pixsize, pixsize);
    for(int i = 0; i < 224; i++) {
        tex = malloc(sizeof(texture));
        sd_font_decode(sdfont, img, i, 0xFF, 0xFF, 0xFF);
        texture_create(tex);
        texture_init(tex, img->data, img->w, img->h);
        vector_append(&font->textures, &tex);
    }
    
    // Set font info vars
    font->w = pixsize;
    font->h = pixsize;
    font->size = size;
    
    // Free resources
    sd_rgba_image_delete(img);
    sd_font_delete(sdfont);
    return 0;
}
Пример #13
0
font_t font_create(const char* name)
{
	//todo: make this a task

	FOUNDATION_ASSERT(fs_is_file(name));
	stream_t* ttf_stream = fs_open_file(name, STREAM_IN|STREAM_BINARY);
	FOUNDATION_ASSERT(ttf_stream);
	const uint64_t ttf_stream_size = stream_size(ttf_stream);
	unsigned char* ttf_buffer = (unsigned char*) memory_allocate(ttf_stream_size, 4, MEMORY_TEMPORARY);
	unsigned char* ttf_bitmap = (unsigned char*) memory_allocate(MINT_FONT_BITMAPSIZE*MINT_FONT_BITMAPSIZE, 4, MEMORY_PERSISTENT);

	const uint64_t read = stream_read(ttf_stream, ttf_buffer, ttf_stream_size);
	FOUNDATION_ASSERT(read == ttf_stream_size);

	font_data_t data;
	stbtt_BakeFontBitmap(
		ttf_buffer,0, 32.0, 
		ttf_bitmap, 
		MINT_FONT_BITMAPSIZE, 
		MINT_FONT_BITMAPSIZE, 
		32,96, 
		data.cdata
	);

	TextureCreationInfo info;
	info.type = Texture2D;
	info.format = FormatR8;
	info.width = MINT_FONT_BITMAPSIZE;
	info.height = MINT_FONT_BITMAPSIZE;

	data.texture = texture_create(ttf_bitmap, info);

	array_push_memcpy(s_fontCtx.fonts, &data);

	memory_deallocate(ttf_bitmap);
	memory_deallocate(ttf_buffer);
	stream_deallocate(ttf_stream);

	return array_size(s_fontCtx.fonts)-1;
}
Пример #14
0
entity_t* entity_create_particle(void) {
    if (!particle_created) {
        ent_particle_tex = texture_create("particles_sprite_sheet_x2_smooth.png");
        ent_particle_sprite = malloc(sizeof(sprite_t));
        ent_particle_sprite->count_x = 32;
        ent_particle_sprite->count_y = 11;
        // ent_particle_sprite->pixs = 16*2;
        ent_particle_sprite->pixs = 32;

        particle_created = true;
    }
    entity_t* ent = malloc(sizeof(entity_t));
    ent->pos_x = 0.0;
    ent->pos_y = 0.0;
    ent->texture = ent_particle_tex;
    ent->sprite = ent_particle_sprite;
    ent->sprite_x = 0;
    ent->sprite_y = 0;
    glGenBuffers(1, &ent->tex_coord_buffer);

    return ent;
}
Пример #15
0
int melee_init(scene *scene) {
    char bitmap[51*36*4];
    memset(&bitmap, 255, 51*36*4);
    ticks = 0;
    pulsedir = 0;
    selection = 0;
    row_a = 0;
    column_a = 0;
    row_b = 0;
    column_b = 4;
    done_a = 0;
    done_b = 0;
    for(int i = 0; i < 10; i++) {
        players[i].sprite = scene->bk->anims[3]->animation->sprites[i];
        DEBUG("found sprite %d x %d at %d, %d", players[i].sprite->img->w, players[i].sprite->img->h, players[i].sprite->pos_x, players[i].sprite->pos_y);
        players_big[i].sprite = scene->bk->anims[4]->animation->sprites[i];

        int row = i / 5;
        int col = i % 5;
        sd_rgba_image * out = sub_sprite(scene->bk->anims[1]->animation->sprites[0], scene->bk->palettes[0], (62*col), (42*row), 51, 36);
        texture_create(&harportraits[i], out->data, 51, 36);
        sd_rgba_image_delete(out);
    }
    menu_background2_create(&feh, 90, 61);
    menu_background2_create(&bleh, 160, 43);
    texture_create(&select_hilight, bitmap, 51, 36);

    // set up the magic controller hooks
    if (scene->player1.ctrl->type == CTRL_TYPE_NETWORK) {
        controller_add_hook(scene->player2.ctrl, scene->player1.ctrl, scene->player1.ctrl->controller_hook);
    }

    if (scene->player2.ctrl->type == CTRL_TYPE_NETWORK) {
        controller_add_hook(scene->player1.ctrl, scene->player2.ctrl, scene->player2.ctrl->controller_hook);
    }


    const color bar_color = color_create(0, 190, 0, 255);
    const color bar_bg_color = color_create(80, 220, 80, 0);
    const color bar_border_color = color_create(0, 96, 0, 255);
    const color bar_top_left_border_color = color_create(0, 255, 0, 255);
    const color bar_bottom_right_border_color = color_create(0, 125, 0, 255);
    progressbar_create(&bar_power[0],     74, 12, 20*4, 8, bar_border_color, bar_border_color, bar_bg_color, bar_top_left_border_color, bar_bottom_right_border_color, bar_color, PROGRESSBAR_LEFT);
    progressbar_create(&bar_agility[0],   74, 30, 20*4, 8, bar_border_color, bar_border_color, bar_bg_color, bar_top_left_border_color, bar_bottom_right_border_color, bar_color, PROGRESSBAR_LEFT);
    progressbar_create(&bar_endurance[0], 74, 48, 20*4, 8, bar_border_color, bar_border_color, bar_bg_color, bar_top_left_border_color, bar_bottom_right_border_color, bar_color, PROGRESSBAR_LEFT);
    progressbar_create(&bar_power[1],     320-66-feh.w, 12, 20*4, 8, bar_border_color, bar_border_color, bar_bg_color, bar_top_left_border_color, bar_bottom_right_border_color, bar_color, PROGRESSBAR_LEFT);
    progressbar_create(&bar_agility[1],   320-66-feh.w, 30, 20*4, 8, bar_border_color, bar_border_color, bar_bg_color, bar_top_left_border_color, bar_bottom_right_border_color, bar_color, PROGRESSBAR_LEFT);
    progressbar_create(&bar_endurance[1], 320-66-feh.w, 48, 20*4, 8, bar_border_color, bar_border_color, bar_bg_color, bar_top_left_border_color, bar_bottom_right_border_color, bar_color, PROGRESSBAR_LEFT);
    for(int i = 0;i < 2;i++) {
        progressbar_set(&bar_power[i], 50);
        progressbar_set(&bar_agility[i], 50);
        progressbar_set(&bar_endurance[i], 50);
    }
    refresh_pilot_stats();

    memset(&harplayer_a, 0, sizeof(harplayer_a));
    memset(&harplayer_b, 0, sizeof(harplayer_b));

    // All done
    return 0;
}
Пример #16
0
panel panel_create(int width, int height, image font) {
    panel result = {width, height, font.width, font.height, NULL, NULL, 0, 0, 0, 0, 0};

    result.font = texture_create(font);
    result.foreground = malloc(4*width*height);
    result.background = malloc(4*width*height);

    // program and shader handles
    GLhandleARB vertex_shader, fragment_shader;

    int length;
    GLint shader_ok;

    // create and compiler vertex shader
    vertex_shader = glCreateShaderObjectARB(GL_VERTEX_SHADER_ARB);
    length = strlen(vertex_source);
    glShaderSourceARB(vertex_shader, 1, &vertex_source, &length);
    glCompileShaderARB(vertex_shader);
    glGetObjectParameterivARB(vertex_shader, GL_COMPILE_STATUS, &shader_ok);
    assert(shader_ok);

    // create and compiler fragment shader
    fragment_shader = glCreateShaderObjectARB(GL_FRAGMENT_SHADER_ARB);
    length = strlen(fragment_source);
    glShaderSourceARB(fragment_shader, 1, &fragment_source, &length);
    glCompileShaderARB(fragment_shader);
    glGetObjectParameterivARB(fragment_shader, GL_COMPILE_STATUS, &shader_ok);
    assert(shader_ok);

    // create program
    result.shader_program = glCreateProgramObjectARB();

    // attach shaders
    glAttachObjectARB(result.shader_program, vertex_shader);
    glAttachObjectARB(result.shader_program, fragment_shader);

    // link the program and check for errors
    glLinkProgramARB(result.shader_program);
    glGetObjectParameterivARB(result.shader_program, GL_LINK_STATUS, &shader_ok);
    assert(shader_ok);

    // we don't need these anymore
    glDeleteObjectARB(vertex_shader);
    glDeleteObjectARB(fragment_shader);

    // generate and bind the buffer object
    glGenBuffersARB(1, &result.vbo);
    glBindBufferARB(GL_ARRAY_BUFFER_ARB, result.vbo);

    // fill with data
    glBufferDataARB(GL_ARRAY_BUFFER_ARB, sizeof(GLfloat)*6*5, quad_data, GL_STATIC_DRAW_ARB);

    glActiveTexture(GL_TEXTURE1);
    glGenTextures(1, &result.fg_tex);
    glBindTexture(GL_TEXTURE_2D, result.fg_tex);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, result.width, result.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, result.foreground);

    glActiveTexture(GL_TEXTURE2);
    glGenTextures(1, &result.bg_tex);
    glBindTexture(GL_TEXTURE_2D, result.bg_tex);

    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, result.width, result.height, 0, GL_RGBA, GL_UNSIGNED_BYTE, result.background);

    glUseProgramObjectARB(result.shader_program);

    glUniform1iARB(glGetUniformLocationARB(result.shader_program, "font"), 0);
    glUniform1iARB(glGetUniformLocationARB(result.shader_program, "foreground"), 1);
    glUniform1iARB(glGetUniformLocationARB(result.shader_program, "background"), 2);
    glUniform2fARB(glGetUniformLocationARB(result.shader_program, "panel_size"), width, height);

    return result;
}
Пример #17
0
// Loads BK file etc.
int scene_load(scene *scene, unsigned int scene_id) {
    scene->bk = sd_bk_create();
    scene->loop = 1;
    scene->local = NULL;
    int ret = 0;
    
    // Load BK
    switch(scene_id) {
        case SCENE_INTRO:    ret = sd_bk_load(scene->bk, "resources/INTRO.BK");    break;
        case SCENE_MENU:     ret = sd_bk_load(scene->bk, "resources/MAIN.BK");     break;
        case SCENE_ARENA0:   ret = sd_bk_load(scene->bk, "resources/ARENA0.BK");   break;
        case SCENE_ARENA1:   ret = sd_bk_load(scene->bk, "resources/ARENA1.BK");   break;
        case SCENE_ARENA2:   ret = sd_bk_load(scene->bk, "resources/ARENA2.BK");   break;
        case SCENE_ARENA3:   ret = sd_bk_load(scene->bk, "resources/ARENA3.BK");   break;
        case SCENE_ARENA4:   ret = sd_bk_load(scene->bk, "resources/ARENA4.BK");   break;
        case SCENE_ARENA5:   ret = sd_bk_load(scene->bk, "resources/ARENA5.BK");   break;
        case SCENE_NEWSROOM: ret = sd_bk_load(scene->bk, "resources/NEWSROOM.BK"); break;
        case SCENE_END:      ret = sd_bk_load(scene->bk, "resources/END.BK");      break;
        case SCENE_END1:     ret = sd_bk_load(scene->bk, "resources/END1.BK");     break;
        case SCENE_END2:     ret = sd_bk_load(scene->bk, "resources/END2.BK");     break;
        case SCENE_CREDITS:  ret = sd_bk_load(scene->bk, "resources/CREDITS.BK");  break;
        case SCENE_MECHLAB:  ret = sd_bk_load(scene->bk, "resources/MECHLAB.BK");  break;
        case SCENE_MELEE:    ret = sd_bk_load(scene->bk, "resources/MELEE.BK");    break;
        case SCENE_VS:       ret = sd_bk_load(scene->bk, "resources/VS.BK");       break;
        case SCENE_NORTHAM:  ret = sd_bk_load(scene->bk, "resources/NORTH_AM.BK"); break;
        case SCENE_KATUSHAI: ret = sd_bk_load(scene->bk, "resources/KATUSHAI.BK"); break;
        case SCENE_WAR:      ret = sd_bk_load(scene->bk, "resources/WAR.BK");      break;
        case SCENE_WORLD:    ret = sd_bk_load(scene->bk, "resources/WORLD.BK");    break;
        default:
            sd_bk_delete(scene->bk);
            PERROR("Unknown scene_id!");
            return 1;
    }
    if(ret) {
        sd_bk_delete(scene->bk);
        PERROR("Unable to load BK file!");
        return 1;
    }

    scene->this_id = scene_id;
    scene->next_id = scene_id;

    // optional callback
    scene->post_init = NULL;
    
    // Load specific stuff
    switch(scene_id) {
        case SCENE_INTRO: intro_load(scene); break;
        case SCENE_MENU: mainmenu_load(scene); break;
        case SCENE_CREDITS: credits_load(scene); break;
        case SCENE_MELEE:
            fixup_palette(scene->bk->palettes[0]);
            melee_load(scene); break;
        case SCENE_VS:
            fixup_palette(scene->bk->palettes[0]);
            vs_load(scene); break;
        case SCENE_MECHLAB:
            mechlab_load(scene);
            break;
        case SCENE_ARENA0:
        case SCENE_ARENA1:
        case SCENE_ARENA2:
        case SCENE_ARENA3:
        case SCENE_ARENA4:
        case SCENE_ARENA5:
            fixup_palette(scene->bk->palettes[0]);
            arena_load(scene); 
            break;
            
        default: 
            scene->render = NULL;
            scene->event = NULL;
            scene->init = NULL;
            scene->deinit = NULL;
    }
    
    // Init scene
    if(scene->init != NULL) {
        if(scene->init(scene)) {
            sd_bk_delete(scene->bk);
            return 1;
        }
    }
    
    // Convert background
    sd_rgba_image *bg = sd_vga_image_decode(scene->bk->background, scene->bk->palettes[0], -1);
    texture_create(&scene->background, bg->data, bg->w, bg->h);
    sd_rgba_image_delete(bg);
    
    // Players list
    list_create(&scene->child_players);
    list_create(&scene->root_players);
    
    // Handle animations
    animation *ani;
    sd_bk_anim *bka;
    array_create(&scene->animations);
    for(unsigned int i = 0; i < 50; i++) {
        bka = scene->bk->anims[i];
        if(bka) {
            // Create animation + textures, etc.
            ani = malloc(sizeof(animation));
            animation_create(ani, bka->animation, scene->bk->palettes[0], -1, scene->bk->soundtable);
            array_set(&scene->animations, i, ani);
            
            // Start playback on those animations, that have load_on_start flag as true 
            // or if we are handling animation 25 of intro
            // TODO: Maybe make the exceptions a bit more generic or something ?
            // TODO check other probabilites here
            if(bka->load_on_start || bka->probability == 1 || (scene_id == SCENE_INTRO && i == 25)) {
                animationplayer player;
                player.x = ani->sdani->start_x;
                player.y = ani->sdani->start_y;
                animationplayer_create(&player, i, ani);
                player.userdata = scene;
                player.add_player = scene_add_ani_player;
                player.del_player = scene_set_ani_finished;
                list_append(&scene->root_players, &player, sizeof(animationplayer));
                DEBUG("Create animation %d @ x,y = %d,%d", i, player.x, player.y);
            }
        }
    }

    // run post init, if defined
    if(scene->post_init != NULL) {
        DEBUG("running post init");
        scene->post_init(scene);
    }

    // All done
    DEBUG("Scene %i loaded! Textures now using %d bytes of (v)ram!", scene_id, texturelist_get_bsize());
    return 0;
}