+[Background]
+id = 100
+flags = 0
+pos.x = 0
+pos.y = 0
+:RenderComponent
+layer = -1
+color.r = 1
+color.g = 1
+color.b = 1
+color.a = 1
+
[Wall]
id = 10
flags = 2
[Player]
id = 12
flags = 2
-pos.x = 318.3422
-pos.y = 217.0257
+pos.x = 312.5422
+pos.y = 271.0389
size.x = 16.0000
-size.y = 16.0000
+size.y = 32.0000
:MovementComponent
controls.up = 87
controls.down = 83
controls.interact = 70
controls.pick_up = 71
facing = 3
+velocity.x = -0.4420
+velocity.y = 0.4767
:PlayerComponent
holding = 0
:RenderComponent
-layer = 0
+layer = 10
color.r = 0.0000
color.g = 1.0000
color.b = 0.0000
item = "beer"
max_timeout = 2.0000
-[Patron]
-id = 22
-flags = 3
-pos.x = 392.0000
-pos.y = 408.0000
-size.x = 16.0000
-size.y = 16.0000
-:RenderComponent
-layer = 5
-color.r = 1.0000
-color.g = 0.0000
-color.b = 0.0000
-color.a = 1.0000
-:PatronComponent
-state = 0
-order_item = "beer"
-order_show_animation = 0.0000
-holding = 0
-consume_timeout = 0.0000
-
[Wall]
id = 25
flags = 2
color.a = 1.0000
[Wall]
-id = 26
+id = 27
flags = 2
-pos.x = 424.0000
-pos.y = 592.0000
-size.x = 816.0000
-size.y = 32.0000
+pos.x = 8.0000
+pos.y = 312.0000
+size.x = 16.0000
+size.y = 592.0000
:RenderComponent
layer = 0
color.r = 1.0000
color.a = 1.0000
[Wall]
-id = 27
+id = 28
flags = 2
-pos.x = 8.0000
+pos.x = 792.0000
pos.y = 312.0000
size.x = 16.0000
size.y = 592.0000
color.b = 1.0000
color.a = 1.0000
-[Wall]
-id = 28
+[Furniture]
+id = 30
+flags = 2
+pos.x = 136.0000
+pos.y = 336.0000
+size.x = 16.0000
+size.y = 32.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
+:FurnitureComponent
+furniture_type = 0
+taken = true
+sprite.sheet = "./assets/images/spritesheet.png"
+sprite.pos.x = 32.0000
+sprite.pos.y = 32.0000
+sprite.size.x = 16.0000
+sprite.size.y = 32.0000
+sprite.color.r = 1.0000
+sprite.color.g = 1.0000
+sprite.color.b = 1.0000
+sprite.color.a = 1.0000
+
+[Furniture]
+id = 31
flags = 2
-pos.x = 800.0000
-pos.y = 296.0000
+pos.x = 184.0000
+pos.y = 336.0000
+size.x = 16.0000
+size.y = 32.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
+:FurnitureComponent
+furniture_type = 0
+taken = false
+sprite.sheet = "./assets/images/spritesheet.png"
+sprite.pos.x = 48.0000
+sprite.pos.y = 32.0000
+sprite.size.x = -16.0000
+sprite.size.y = 32.0000
+sprite.color.r = 1.0000
+sprite.color.g = 1.0000
+sprite.color.b = 1.0000
+sprite.color.a = 1.0000
+
+[Furniture]
+id = 32
+flags = 2
+pos.x = 160.0000
+pos.y = 336.0000
size.x = 32.0000
-size.y = 560.0000
+size.y = 32.0000
:RenderComponent
layer = 0
color.r = 1.0000
color.g = 1.0000
color.b = 1.0000
color.a = 1.0000
+:FurnitureComponent
+furniture_type = 1
+taken = false
+sprite.sheet = "./assets/images/spritesheet.png"
+sprite.pos.x = 48.0000
+sprite.pos.y = 32.0000
+sprite.size.x = 32.0000
+sprite.size.y = 32.0000
+sprite.color.r = 1.0000
+sprite.color.g = 1.0000
+sprite.color.b = 1.0000
+sprite.color.a = 1.0000
[Furniture]
-id = 30
+id = 40
flags = 2
pos.x = 136.0000
pos.y = 256.0000
color.a = 1.0000
:FurnitureComponent
furniture_type = 0
-taken = false
+taken = true
sprite.sheet = "./assets/images/spritesheet.png"
sprite.pos.x = 32.0000
sprite.pos.y = 32.0000
sprite.color.a = 1.0000
[Furniture]
-id = 31
+id = 41
flags = 2
pos.x = 184.0000
pos.y = 256.0000
sprite.color.a = 1.0000
[Furniture]
-id = 32
+id = 42
flags = 2
pos.x = 160.0000
pos.y = 256.0000
sprite.color.b = 1.0000
sprite.color.a = 1.0000
+[Wall]
+id = 35
+flags = 2
+pos.x = 192.0000
+pos.y = 592.0000
+size.x = 352.0000
+size.y = 32.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
+
+[Wall]
+id = 36
+flags = 2
+pos.x = 608.0000
+pos.y = 592.0000
+size.x = 352.0000
+size.y = 32.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
+
+[Wall]
+id = 37
+flags = 2
+pos.x = 140.0000
+pos.y = -142.0000
+size.x = 16.0000
+size.y = 16.0000
+:RenderComponent
+layer = 0
+color.r = 1.0000
+color.g = 1.0000
+color.b = 1.0000
+color.a = 1.0000
+
[Tap]
id = 14
flags = 3
item = "beer"
max_timeout = 2.0000
+[Patron]
+id = 22
+flags = 3
+pos.x = 319.2968
+pos.y = 422.7386
+size.x = 16.0000
+size.y = 32.0000
+:RenderComponent
+layer = 5
+color.r = 1.0000
+color.g = 0.0000
+color.b = 0.0000
+color.a = 1.0000
+:PatronComponent
+state = 0
+seat = 30
+order_item = "beer"
+order_show_animation = 0.0000
+holding = 0
+consume_timeout = 0.0000
+
#load_all "./entity/components"
#load_all "./entity/schematics"
#load_all "./gfx"
+#load_all "./sfx"
#load_all "./utils"
#load "stb_image"
#load "modules/opengles/module"
#load "modules/glfw3/module"
+#load "modules/openal/module"
// This should dynamic...
item.pos = this.pos;
item.size = .{16, 16};
+ // if only item.flags.Carryable = false was possible...
+ item.flags = ~~ (cast(u32) item.flags & ~(cast(u32) Entity_Flags.Carryable));
(item->get(ItemComponent)).item = dispenser_comp.item;
scene->add(item);
if interactor->has(PlayerComponent) {
patron.state = .Waiting_For_Order;
patron.order_show_animation = 1.0f;
+
+ Audio_Manager.play_sound("./assets/sounds/prompt-1.wav");
}
}
r.y += 2;
r.w -= 4;
r.h -= 4;
- immediate_set_color(.{1, 1, 1});
+ immediate_set_color(.{0.9, 0.9, 0.9});
immediate_rectangle(r.x, r.y, r.w, r.h);
r.x += 2;
render :: (use this: ^Entity) {
rect := Entity.get_rect(this);
+ rect.y -= rect.h;
+ rect.h *= 2;
immediate_subimage(^Spritesheet, rect.x, rect.y, rect.w, rect.h, 0*16, 4*16, 16, 16);
}
for scene.entities {
if Entity.get_rect(it) |> Rect.contains(mouse_pos) {
selected_entity_id = it.id;
- break;
+ // break;
}
}
query :: entity_manager_query;
query_by_flags :: entity_manager_query_by_flags;
+ count_by_component :: entity_manager_count_by_component;
+
query_by_component :: entity_manager_query_by_component;
create_component :: entity_manager_create_component;
create_and_add :: entity_manager_create_and_add;
raw_free(entity_allocator, ent);
}
+entity_manager_count_by_component :: (use this: ^Entity_Manager, comp_type: type_expr) -> u32 {
+ count := 0;
+ for entities {
+ if it->has(comp_type) {
+ count += 1;
+ }
+ }
+
+ return count;
+}
+
entity_manager_query :: (use this: ^Entity_Manager, area: Rect) -> [] ^Entity {
ents: [..] ^Entity;
for entities {
--- /dev/null
+
+use package core
+
+Background :: struct {
+ #struct_tag Entity_Schematic.{
+ (scene) => {
+ this := scene->make();
+ this.pos = .{0, 0};
+ this.size = .{0, 0};
+
+ scene->create_and_add(this, RenderComponent) {
+ comp.func = Background.render;
+ }
+
+ queue_assets(^Background.assets);
+ load_assets();
+
+ return this;
+ }
+ }
+
+ render :: (this: ^Entity) {
+ size :: 10000.0f
+ immediate_set_color(.{1, 1, 1});
+ immediate_subimage(^assets.texture, this.pos.x, this.pos.y, size, size, 0, 0, size, size);
+ }
+
+ #persist assets: struct {
+ #tag "./assets/images/background.png"
+ #tag Texture_Wrap.Repeat
+ texture: Texture;
+ }
+}
\ No newline at end of file
this.size = .{32, 32};
this.flags |= .Solid;
+ scene->create_and_add(this, SizeComponent) {
+ comp.func = (use this: ^Entity) => Rect.{pos.x - size.x / 2, pos.y, size.x, size.y / 2};
+ }
+
scene->create_and_add(this, MovementComponent) {
comp.controls = controls;
}
Spritesheet: Texture;
game_init :: () {
+ Audio_Manager.init();
+
scene_canvas = canvas_make(800, 600);
// This process of queueing the asset bucket should
#local quick_save_file := "scenes/quick_save_new.scene";
game_update :: (dt: f32) {
+ Audio_Manager.tick();
+
if is_key_just_up(GLFW_KEY_F8) {
debug_log(.Info, "Saving to '{}'.", quick_save_file);
scene->save_to_file(quick_save_file);
--- /dev/null
+
+use package core
+use package openal
+
+Sound :: struct {
+ buffer: u32;
+}
+
+Audio_Manager :: struct {
+ init :: () {
+ map.init(^loaded_sounds);
+
+ alGetError();
+ device = alcOpenDevice(null);
+ audio_context = alcCreateContext(device, null);
+ alcMakeContextCurrent(audio_context);
+
+ if alGetError() != AL_NO_ERROR {
+ debug_log(.Critical, "Error creating audio context!!");
+ }
+ }
+
+ deinit :: () {
+ alcMakeContextCurrent(~~ cast(u64) 0);
+ alcDestroyContext(audio_context);
+ alcCloseDevice(device);
+ }
+
+ get_sound :: (path: str) -> Sound {
+ if loaded_sounds->has(path) {
+ return loaded_sounds[path];
+ }
+
+ wav_file := load_wav_file(path);
+
+ alGetError();
+
+ buffer: u32;
+ alGenBuffers(1, ^buffer);
+ if alGetError() != AL_NO_ERROR {
+ debug_log(.Error, "Error creating audio buffer!");
+ return .{0};
+ }
+
+ al_format: u32;
+ switch wav_file.format {
+ case .Mono8 do al_format = AL_FORMAT_MONO8;
+ case .Mono16 do al_format = AL_FORMAT_MONO16;
+ case .Stereo8 do al_format = AL_FORMAT_STEREO8;
+ case .Stereo16 do al_format = AL_FORMAT_STEREO16;
+ }
+
+ alBufferData(buffer, al_format, wav_file.data.data, wav_file.data.count, wav_file.sample_rate);
+ memory.free_slice(^wav_file.loaded_file_data);
+
+ map.put(^loaded_sounds, path, .{ buffer });
+ return .{ buffer };
+ }
+
+ play_sound :: (path: str, volume := 1.0f) {
+ sound := get_sound(path);
+
+ source: u32;
+ alGenSources(1, ^source);
+ alSourcef(source, AL_PITCH, 1);
+ alSourcef(source, AL_GAIN, volume);
+ alSource3f(source, AL_POSITION, 0, 0, 0);
+ alSource3f(source, AL_VELOCITY, 0, 0, 0);
+ alSourcei(source, AL_LOOPING, AL_FALSE);
+
+ alSourcei(source, AL_BUFFER, sound.buffer);
+ alSourcePlay(source);
+ playing_sounds << source;
+ }
+
+ tick :: () {
+ while i := 0; i < playing_sounds.count {
+ defer i += 1;
+
+ state: i32;
+ alGetSourcei(playing_sounds[i], AL_SOURCE_STATE, ^state);
+ if state != AL_PLAYING {
+ array.fast_delete(^playing_sounds, i);
+ i -= 1;
+ }
+ }
+ }
+}
+
+
+
+#local {
+ device: ALCdevice;
+ audio_context: ALCcontext;
+
+ loaded_sounds: Map(str, Sound);
+ playing_sounds: [..] u32; // List of sources
+}
\ No newline at end of file
--- /dev/null
+
+use package core
+
+WAV_File :: struct {
+ Format :: enum {
+ Invalid;
+ Mono8;
+ Stereo8;
+ Mono16;
+ Stereo16;
+ }
+
+ format: Format;
+ sample_rate: u32;
+ data: [] u8;
+
+ loaded_file_data: [] u8;
+}
+
+//
+// This greedily loads the whole file
+load_wav_file :: (path: str) -> WAV_File {
+ wav_file: WAV_File;
+ wav_file.format = .Invalid;
+
+ data := os.get_contents(path);
+ if data.data == null do return wav_file;
+ wav_file.loaded_file_data = data;
+
+ pos := 0;
+ if read_data(4) != "RIFF" do return wav_file;
+ read_data(4); // Not sure what this is suppose to be...
+ if read_data(4) != "WAVE" do return wav_file;
+
+ while true {
+ header_name := read_data(4);
+ header_size := *cast(^u32) read_data(4).data;
+
+ if header_name == "fmt " {
+ fmt := read_data(2);
+ channels := *cast(^u16) read_data(2).data;
+ sample_rate := *cast(^u32) read_data(4).data;
+ sr_bps_c_8 := *cast(^u32) read_data(4).data;
+ read_data(2);
+ bits_per_sample := *cast(^u16) read_data(2).data;
+
+ wav_file.sample_rate = sample_rate;
+
+ if channels == 1 && bits_per_sample == 8 do wav_file.format = .Mono8;
+ if channels == 1 && bits_per_sample == 16 do wav_file.format = .Mono16;
+ if channels == 2 && bits_per_sample == 8 do wav_file.format = .Stereo8;
+ if channels == 2 && bits_per_sample == 16 do wav_file.format = .Stereo16;
+ }
+
+ if header_name == "data" {
+ wav_file.data = data;
+ break;
+ }
+ }
+
+ return wav_file;
+
+ read_data :: macro (n: u32) -> str {
+ defer pos += n;
+ return data[pos .. pos+n];
+ }
+}
+
+
+#if false {
+main :: (args) => {
+ dev := alcOpenDevice(null);
+ defer alcCloseDevice(dev);
+
+ con := alcCreateContext(dev, null);
+ alcMakeContextCurrent(con);
+ defer {
+ alcMakeContextCurrent(~~ cast(u64) 0);
+ alcDestroyContext(con);
+ }
+
+ alGetError();
+ buf: u32;
+ alGenBuffers(1, ^buf);
+ defer alDeleteBuffers(1, ^buf);
+ if error := alGetError(); error != AL_NO_ERROR {
+ printf("AL ERROR: {}\n", error);
+ return;
+ }
+
+ sample_rate := 44100;
+
+/*
+ wav_data := memory.make_slice(i16, sample_rate * 5);
+ for i: wav_data.count {
+ sample := math.sin((math.PI * 2.0f * ~~i * 263.2f) / ~~sample_rate) * 32768;
+ sample *= 1 - cast(f32) i / ~~wav_data.count;
+ wav_data[i] = cast(i16) cast(i32) (sample);
+ }
+ */
+
+ wav_file_contents := os.get_contents("/home/brendan/test.wav");
+ wav_data := extract_wav_file_data(wav_file_contents);
+
+ alBufferData(buf, AL_FORMAT_STEREO16, wav_data.data, wav_data.count, sample_rate);
+
+ alListener3f(AL_POSITION, 0, 0, 0);
+ alListener3f(AL_VELOCITY, 0, 0, 0);
+ alListenerfv(AL_ORIENTATION, ~~ f32.[0, 0, 1, 0, 1, 0]);
+
+ source: u32;
+ alGenSources(1, ^source);
+ defer alDeleteSources(1, ^source);
+ alSourcef(source, AL_PITCH, 1);
+ alSourcef(source, AL_GAIN, 0.7);
+ alSource3f(source, AL_POSITION, 0, 0, 0);
+ alSource3f(source, AL_VELOCITY, 0, 0, 0);
+ alSourcei(source, AL_LOOPING, AL_FALSE);
+
+ alSourcei(source, AL_BUFFER, buf);
+ alSourcePlay(source);
+
+ state: i32;
+ while true {
+ os.sleep(1000);
+ alGetSourcei(source, AL_SOURCE_STATE, ^state);
+ if state != AL_PLAYING do break;
+ }
+}
+}
\ No newline at end of file