/* This file was generated by scramble.py. */
#line 1 "src/data.py"
#include "data.h"
#line 36
static LandSound * _sounds [DataCount];
#line 55
LandFont * font_small;
LandFont * font_menu;
#line 69
static LandList * blur_queue;
static LandList * rgba_queue_take;
static LandList * rgba_queue_done;
static LandLock * wait_lock;
static LandLock * mutex;
static int slow = 0;
static void _blur_thread(void * _);
static Data3DModel* _add_frames(str name, str pattern);
static void _loads(int id, str name);
static void _loadm(int id, str name);
#line 76
static void _blur_thread(void * _) {
    while (1) {
        land_thread_wait_lock(wait_lock);
        //print("working")
#line 82
        land_thread_lock(mutex);
        LandListItem * i = rgba_queue_take->first;
        land_list_remove_item(rgba_queue_take, i);
        land_thread_unlock(mutex);
#line 87
        Blur * b = i->data;
        if (b->shadows->needed) {
            int w = land_image_width(b->image);
            int h = land_image_height(b->image);
            land_image_blur_rgba(b->rgba, w, h, 3);
        }
        land_thread_lock(mutex);
        land_list_insert_item(rgba_queue_done, i);
        land_thread_unlock(mutex);
    }
}
//print("done")
void queue_blur(LandImage * image, Shadows * shadows) {
    shadows->submitted++;
    shadows->needed = 1;
    //print("queuing %p [%d x %d, %d, %d]", image, image.width, image.height,
    //    shadows.submitted, shadows.needed)
    Blur * b;
#line 104
    land_alloc(b);
    b->shadows = shadows;
    b->image = image;
    LandListItem * i = land_listitem_new(b);
    land_list_insert_item(blur_queue, i);
}
void data_check_blur(void) {
    if (slow) {
        slow--;
#line 112
        return ;
    }
    slow = 5;
#line 116
    if (blur_queue->first) {
        LandListItem * i = blur_queue->first;
        land_list_remove_item(blur_queue, i);
        Blur * b = i->data;
        //print("taking %p [%d x %d]", b.image, b.image.width, b.image.height)
        int w = land_image_width(b->image);
        int h = land_image_height(b->image);
        b->rgba = land_malloc(w * h * 4);
        land_image_get_rgba_data(b->image, b->rgba);
        land_thread_lock(mutex);
        land_list_insert_item(rgba_queue_take, i);
        land_thread_unlock(mutex);
        land_thread_trigger_lock(wait_lock);
    }
    if (rgba_queue_done->first) {
        land_thread_lock(mutex);
        LandListItem * i = rgba_queue_done->first;
        land_list_remove_item(rgba_queue_done, i);
        land_thread_unlock(mutex);
#line 136
        Blur * b = i->data;
        //print("applying %p [%d x %d, %d, %d]", b.image, b.image.width, b.image.height,
        //    b.shadows.submitted, b.shadows.needed)
        land_image_set_rgba_data(b->image, b->rgba);
        land_listitem_destroy(i);
        land_free(b->rgba);
#line 143
        b->shadows->submitted--;
        if (b->shadows->submitted == 0) {
            if (! b->shadows->needed) {
                shadows_maybe_destroy(b->shadows);
            }
        }
#line 148
        land_free(b);
    }
}
#line 150
static char * _status = NULL;
void data_status(str x) {
    if (! _status) {
        _status = land_strdup("");
    }
#line 154
    land_append(& _status, x);
    land_append(& _status, "\n");
    land_reset_transform();
    land_clear(0, 0, 0, 1);
    land_text_pos(land_display_width() / 2, land_display_height() / 2);
    land_color(1, 1, 1, 1);
    land_print_wordwrap_center(land_display_width(), land_display_height(), _status);
    land_flip();
    land_wait(0.250);
}
void data_init(void) {
    data_status("Loading... Please wait!");
#line 167
    blur_queue = land_list_new();
    rgba_queue_take = land_list_new();
    rgba_queue_done = land_list_new();
    wait_lock = land_thread_new_waitable_lock();
    mutex = land_thread_new_lock();
    land_thread_run(_blur_thread, NULL);
#line 174
    _loadm(DataMusic, "music");
    _loads(DataUnsheath, "unsheath");
    _loads(DataSword, "sword");
    _loads(DataDemon, "demon");
    _loads(DataMagicMissile, "magicmissile");
    _loads(DataFireball, "fireball");
    _loads(DataHeal, "heal");
    _loads(DataTroll, "troll");
    _loads(DataRat, "rat");
    _loads(DataBook, "book");
    _loads(DataDragon, "dragon");
    _loads(DataArrow, "arrow");
    _loads(DataSqueak, "squeak");
    _loads(DataSpell, "spell");
    _loads(DataNo, "no");
    _loads(DataDeath, "death");
    _loads(DataYell, "yell");
    _loads(DataRoar, "roar");
    _loads(DataRatGone, "ratgone");
    _loads(DataPotion, "potion");
    _loads(DataCoin, "coin");
    _loads(DataScroll, "scroll");
    _loads(DataPay, "pay");
    _loads(DataBuild, "build");
    _loads(DataWin, "win");
    _loads(DataTrollDie, "trolldie");
    _loads(DataEvil, "evil");
#line 202
    data_status("Feeding dragon... Please wait!");
}
static Data3DModel* _add_frames(str name, str pattern) {
    Data3DModel * k;
    land_alloc(k);
#line 208
    if (name) {
#line 208
        k->name = land_strdup(name);
    }
#line 209
    k->kid = land_array_count(game->kinds) + 1;
    land_array_add(game->kinds, k);
    if (name) {
        land_hash_insert(game->model_by_name, name, k);
    }
#line 213
    k->frames = land_array_new();
    k->markers = land_array_new();
#line 216
    bool star = land_contains(pattern, "*");
#line 218
    int frame = 1;
    while (1) {
        char * path = land_strdup(pattern);
        if (star) {
            char sframe [10];
            sprintf(sframe, "%04d", frame++);
            land_replace(& path, 0, "*", sframe);
        }
        LandObjFile * of = land_objfile_new_from_filename(path);
        if (of->error) {
            land_free(path);
            break;
        }
#line 230
        LandArray * tris;
        LandArray * markers = land_obj_markers(of);
        if (debug_no_models) {
            tris = land_array_new();
        }
#line 233
        else {
#line 235
            tris = land_obj_triangles(of);
        }
        k->height = 0;
        {
#line 238
            LandArrayIterator __iter0__ = LandArrayIterator_first(tris);
#line 238
            for (LandTriangles * t = LandArrayIterator_item(tris, &__iter0__); LandArrayIterator_next(tris, &__iter0__); t = LandArrayIterator_item(tris, &__iter0__)) {
#line 240
                land_triangles_shader(t, "shader", render.vertex_shader, render.fragment_shader);
                if (t->n < 3) {
                    print("WARNING: %s corrupted? only %d vertices!", path, t->n);
                }
                float y = land_triangles_get_max_y(t);
                if (y > k->height) {
                    k->height = y;
                }
            }
        }
#line 248
        land_array_add(k->frames, tris);
#line 250
        Data3DMarkers * m;
#line 250
        land_alloc(m);
        {
#line 251
            LandArrayIterator __iter0__ = LandArrayIterator_first(markers);
#line 251
            for (LandObjMarker * marker = LandArrayIterator_item(markers, &__iter0__); LandArrayIterator_next(markers, &__iter0__); marker = LandArrayIterator_item(markers, &__iter0__)) {
                if (land_equals(marker->name, "head")) {
                    m->head = marker->matrix;
                }
#line 254
                if (land_equals(marker->name, "main")) {
                    m->main = marker->matrix;
                }
#line 256
                if (land_equals(marker->name, "off")) {
                    m->off = marker->matrix;
                }
#line 258
                if (land_equals(marker->name, "neck")) {
                    m->neck = marker->matrix;
                }
            }
        }
#line 260
        land_array_add(k->markers, m);
#line 262
        land_free(path);
#line 264
        if (! star) {
            break;
        }
    }
#line 266
    if (land_array_count(k->frames) == 0) {
        print("ERROR: could not read %s", name);
    }
#line 268
    return k;
}
LandImage* data_start_shadow(void) {
    LandImage * image = land_image_new_flags(128, 128, LAND_IMAGE_DEPTH);
    land_set_image_display(image);
    land_clear_depth(1);
#line 275
    LandCamera * cam = land_camera_new();
    land_camera_change_freely(cam, pi / 2, 0, 0);
#line 278
    glEnable(GL_CULL_FACE);
    land_reset_transform();
    land_render_state(LAND_DEPTH_FUNCTION, LAND_LESS);
    Land4x4Matrix m = land_camera_matrix(cam);
    m = land_4x4_matrix_mul(m, land_4x4_matrix_translate(0, 0, - 4));
    //if land_csg_aabb_radius(mesh.aabb) > 5:
    //    m = land_4x4_matrix_mul(m, land_4x4_matrix_scale(.5, .5, .5))
#line 286
    float sw = 10;
    float sh = 10;
    Land4x4Matrix pm = land_4x4_matrix_orthographic(- sw / 2, - sh / 2, 30, sw / 2, sh / 2, - 30);
    pm = land_4x4_matrix_mul(pm, land_camera_matrix(cam));
    land_projection(pm);
#line 292
    return image;
}
void data_complete_shadow(LandImage * image) {
    land_unset_image_display();
}
LandTriangles* create_shadow_mesh(LandImage * image) {
    LandTriangles * t = land_triangles_new();
#line 300
    land_triangles_shader(t, "shader", render.vertex_shader, render.fragment_shader);
    land_triangles_texture(t, image);
#line 303
    float z = 0.1;
    float s = 5;
    float a = .5;
    land_add_vertex(t, - s, z, - s, 0, 0, a, a, a, a);
    land_add_vertex(t, s, z, s, 128, 128, a, a, a, a);
    land_add_vertex(t, s, z, - s, 128, 0, a, a, a, a);
#line 310
    land_add_vertex(t, - s, z, - s, 0, 0, a, a, a, a);
    land_add_vertex(t, - s, z, s, 0, 128, a, a, a, a);
    land_add_vertex(t, s, z, s, 128, 128, a, a, a, a);
#line 314
    return t;
}
Data3DModel* add_3d_model_frames(str name, float scale, bool moving) {
    if (! name) {
        return NULL;
    }
#line 319
    char * path = land_strdup("");
    land_append(& path, "obj/%s_*.obj.b", name);
    Data3DModel * model = _add_frames(name, path);
    model->scale = scale;
    land_free(path);
    model->moving = moving;
    if (moving) {
        model->shadows = shadows_new(model, NULL);
    }
#line 327
    return model;
}
Data3DModel* data_get_model(str name) {
    Data3DModel * k = land_hash_get(game->model_by_name, name);
    if (! k) {
        print("ERROR: no such kind %s", name);
    }
#line 333
    return k;
}
void data_reload_fonts(void) {
    double scale = land_scale_to_fit(1280, 720, 256);
    font_small = land_font_load("URWGothicBook.ttf", 12 * scale);
    land_font_scale(font_small, 1 / scale);
    font_menu = land_font_load("UnifrakturCook-Bold.ttf", 24 * scale);
    land_font_scale(font_menu, 1 / scale);
}
static void _loads(int id, str name) {
    char * s = land_strdup("sound/");
    land_concatenate(& s, name);
    land_concatenate(& s, ".ogg");
    LandSound * sound = land_sound_load(s);
    if (! sound || ! sound->loaded) {
        print("Could not load %s", s);
#line 348
        return ;
    }
    _sounds [id] = sound;
    land_free(s);
}
static void _loadm(int id, str name) {
    char * s = land_strdup("sound/");
    land_concatenate(& s, name);
    land_concatenate(& s, ".ogg");
    land_stream_music(land_stream_default(), s);
    land_stream_volume(land_stream_default(), 1);
    land_free(s);
}
void data_play(int sid) {
    land_sound_play(_sounds [sid], 1, 0, 1);
}
void data_play_vol(int sid, float vol) {
    land_sound_play(_sounds [sid], vol, 0, 1);
}
void data_playq(int sid) {
    data_playq_vol(sid, 1);
}
static int sound_queue_n [30];
static int sound_queue_sid [30] [200];
static float sound_queue_vol [30] [200];
#line 374
void data_playq_vol(int sid, float vol) {
    int qt = land_rand(0, 29);
    int n = sound_queue_n [qt]++;
    if (n == 200) {
        sound_queue_n [qt]--;
    }
#line 379
    sound_queue_sid [qt] [n] = sid;
    sound_queue_vol [qt] [n] = vol;
}
void play_queued_sounds(int qt) {
    if (qt < 0 || qt >= 30) {
#line 383
        return ;
    }
    int n = sound_queue_n [qt];
    for (int i = 0; i < n; i += 1) {
        data_play_vol(sound_queue_sid [qt] [i], sound_queue_vol [qt] [i]);
    }
#line 388
    sound_queue_n [qt] = 0;
}
/* This file was generated by scramble.py. */
