aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoriamcheeseman <[hidden email]>2026-02-03 22:25:00 -0500
committeriamcheeseman <[hidden email]>2026-02-03 22:25:00 -0500
commit3d1d31538d30a7f161f9f2b6d5e075ec69d3b860 (patch)
tree8b0deceb38c288dbef361bb4f77bb681b5566525
parent1c605da3ff8dc4295d2f9a85f5b7c8891ca84464 (diff)
ditch raylib (icky, and for loser BEGINNERS)
-rwxr-xr-xsrc.binbin0 -> 841400 bytes
-rw-r--r--src/assets.odin12
-rw-r--r--src/draw.odin151
-rw-r--r--src/fw/fw.odin114
-rw-r--r--src/fw/input.odin76
-rw-r--r--src/fw/keys.odin140
-rw-r--r--src/fw/opengl.odin363
-rw-r--r--src/fw/renderer.odin390
-rw-r--r--src/fw/shader.frag16
-rw-r--r--src/fw/shader.vert18
-rw-r--r--src/input.odin72
-rw-r--r--src/main.odin205
-rw-r--r--src/math.odin4
-rw-r--r--src/phys/world.odin4
-rw-r--r--src/platform.odin10
-rw-r--r--src/player.odin28
-rw-r--r--src/prop.odin41
-rw-r--r--src/resources.odin24
-rw-r--r--src/rope.odin14
-rw-r--r--src/sprite.odin20
-rw-r--r--src/tail.odin17
-rw-r--r--src/upgrade_pickup.odin5
-rw-r--r--src/verlet.odin4
-rw-r--r--src/world.odin22
24 files changed, 1321 insertions, 429 deletions
diff --git a/src.bin b/src.bin
new file mode 100755
index 0000000..6503854
--- /dev/null
+++ b/src.bin
Binary files differ
diff --git a/src/assets.odin b/src/assets.odin
index ada8a36..dd506a3 100644
--- a/src/assets.odin
+++ b/src/assets.odin
@@ -71,15 +71,15 @@ images: [Image_Id]Image_Resource = {
animations: [Animation_Id]Animation_Resource = {
.None = {frame_count=1, frame_durations={100}, tags={}},
- .Player = {frame_count = 23, frame_durations = {100, 100, 100, 100, 100, 100, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 100}, tags = {"jump_up"={from = 14, to = 15}, "jump_down"={from = 17, to = 18}, "jump_trans"={from = 16, to = 16}, "sleep"={from = 19, to = 22}, "run"={from = 6, to = 13}, "idle"={from = 0, to = 5}}},
+ .Player = {frame_count = 23, frame_durations = {100, 100, 100, 100, 100, 100, 75, 75, 75, 75, 75, 75, 75, 75, 100, 100, 100, 100, 100, 100, 100, 100, 100}, tags = {"jump_trans"={from = 16, to = 16}, "jump_down"={from = 17, to = 18}, "idle"={from = 0, to = 5}, "sleep"={from = 19, to = 22}, "jump_up"={from = 14, to = 15}, "run"={from = 6, to = 13}}},
}
rooms: [Room_Id]Room_Resource = {
- .Carrabassett0 = {width=40, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 19, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 16, 19, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 19, 31, 19, 19, 19, 31, 19, 31, 19, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 31, 31, 31, 19, 19, 31, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 20, 20, 18, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 19, 31, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 18, 9, 9, 20, 9, 9, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 41, 9, 20, 20, 20, 18, 20, 20, 9, 20, 9, 20, 9, 20, 20, 9, 9, 18, 6, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 17, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 43, 9, 9, 20, 20, 9, 39, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 5, 20, 20, 18, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 20, 9, 20, 18, 20, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 53, pos = {194, 200}, size = {26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {352, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {412, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {364, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {172, 200}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {224, 200}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {220, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {296, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {340, 76}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {416, 60}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {492, 76}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {432, 76}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {352, 92}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {236, 108}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {80, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {528, 100}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {472, 88}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {512, 96}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {60, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {44, 148}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {24, 180}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {148, 96}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {260, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {164, 88}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {128, 100}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {20, 280}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {304, 200}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {260, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {284, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {132, 248}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {96, 248}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {64, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {116, 248}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {300, 200}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {448, 232}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {540, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {612, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {576, 152}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {556, 124}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {572, 136}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {588, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {580, 132}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {504, 80}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {424, 68}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {248, 100}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {484, 232}, size = {-26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {400, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {412, 156}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {436, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {487, 185}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_0.png", "node_length"=2}}, {type = .Rope, tile_id = nil, pos = {217, 153}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/small_lamp.png", "node_length"=2}}, {type = .Rope, tile_id = nil, pos = {515, 110}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=20, "image"="res/img/windchimes_0.png", "node_length"=5}}, {type = .Player_Spawn, tile_id = nil, pos = {240, 200}, size = {0, 0}, parallax = {0, 0}, properties = {}}, {type = .Collision, tile_id = nil, pos = {0, 0}, size = {48, 48}, parallax = {0, 0}, properties = {}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
- .Carrabassett1 = {width=20, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 17, 0, 0, 0, 16, 19, 28, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 17, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 38, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 28, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 43, 9, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 18, 20, 20, 40, 40, 40, 40, 40, 43, 9, 9, 9, 9, 9, 9, 18, 9, 18, 18, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 49, pos = {92, 296}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {144, 296}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {180, 296}, size = {-26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {116, 296}, size = {26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {127, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {181, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {224, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {252, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {292, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {48, 280}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {80, 104}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {88, 100}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {100, 96}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {108, 88}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {116, 88}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {96, 96}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {192, 76}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {272, 128}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {244, 100}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {228, 72}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {264, 104}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {284, 128}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {40, 108}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {56, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {68, 108}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {24, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {272, 280}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {24, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {139, 249}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_1.png", "node_length"=2}}, {type = .Rope, tile_id = nil, pos = {183, 249}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_1.png", "node_length"=2}}, {type = .Rope, tile_id = nil, pos = {134, 48}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/windchimes_0.png", "node_length"=7}}, {type = .Rope, tile_id = nil, pos = {232, 47}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/windchimes_0.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {70, 59}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/windchimes_1.png", "node_length"=10}}, {type = .Rope, tile_id = nil, pos = {174, 32}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/windchimes_1.png", "node_length"=10}}, {type = .Rope, tile_id = nil, pos = {269, 72}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/windchimes_1.png", "node_length"=10}}, {type = .Rope, tile_id = nil, pos = {206, 30}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/windchimes_0.png", "node_length"=8}}, {type = .Rope, tile_id = nil, pos = {115, 45}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/small_lamp.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {91, 61}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/small_lamp.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {191, 31}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/small_lamp.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {286, 86}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/small_lamp.png", "node_length"=5}}, {type = .Upgrade, tile_id = nil, pos = {160, 240}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/dash_pickup.qoi", "type"=0}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
- .Carrabassett2 = {width=20, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 8, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 10, 31, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 20, 42, 0, 0, 0, 10, 19, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 19, 28, 38, 18, 6, 0, 0, 0, 0, 10, 19, 28, 40, 40, 40, 40, 40, 27, 17, 0, 0, 10, 28, 40, 38, 20, 42, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 17, 0, 0, 0, 0, 16, 19, 31, 19, 17, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 39, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 18, 9, 9, 39, 40, 40, 40, 40, 40, 40, 20, 9, 18, 9, 9, 9, 20, 20, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 45, pos = {4, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {32, 104}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {128, 72}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {212, 104}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {104, 124}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {116, 140}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {180, 136}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {36, 152}, size = {26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {84, 152}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {88, 72}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {120, 88}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {56, 56}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {128, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {20, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {40, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {52, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {58, 105}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_1.png", "node_length"=2}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
- .Carrabassett3 = {width=20, height=40, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 19, 31, 19, 19, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 19, 31, 17, 0, 0, 0, 0, 0, 16, 19, 28, 40, 40, 40, 40, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 19, 28, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 28, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 20, 9, 39, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 18, 9, 18, 39, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 41, 20, 20, 18, 18, 39, 40, 40, 40, 40, 40, 21, 28, 40, 40, 32, 0, 0, 0, 0, 10, 31, 31, 19, 19, 28, 40, 40, 40, 40, 27, 17, 7, 40, 40, 43, 42, 0, 0, 0, 0, 0, 0, 0, 0, 10, 19, 19, 19, 31, 17, 0, 7, 40, 40, 40, 38, 18, 18, 20, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 38, 20, 20, 18, 6, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 6, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 43, 6, 0, 0, 0, 0, 0, 7, 40, 40, 21, 28, 40, 21, 31, 28, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 7, 40, 40, 32, 16, 19, 17, 0, 16, 19, 19, 31, 28, 40, 38, 9, 20, 6, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16, 19, 31, 19, 19, 17, 0, 0, 7, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 20, 18, 9, 9, 18, 20, 39, 40, 40, 43, 6, 0, 0, 0, 0, 0, 41, 20, 20, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 42, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 20, 20, 42, 0, 10, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 19, 19, 28, 40, 8, 0, 0, 0, 10, 31, 19, 31, 28, 40, 40, 40, 40, 40, 40, 32, 0, 0, 10, 19, 17, 0, 0, 0, 0, 0, 0, 0, 16, 31, 31, 31, 19, 31, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 38, 9, 9, 9, 20, 20, 18, 18, 9, 9, 42, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 5, 20, 20, 9, 9, 18, 40, 40, 40, 21, 31, 31, 19, 31, 31, 19, 19, 17, 0, 5, 39, 40, 40, 40, 40, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 28, 40, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 41, 20, 18, 20, 39, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 6, 0, 0, 0, 0, 41, 9, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 43, 6, 0, 0, 41, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 49, pos = {132, 616}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {32, 488}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {204, 328}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {260, 168}, size = {-32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {228, 184}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {108, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {160, 200}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {108, 264}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {168, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {284, 376}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {216, 376}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {184, 376}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {140, 392}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {232, 376}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {156, 392}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {128, 200}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {44, 248}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {252, 504}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {284, 504}, size = {-32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {236, 504}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {24, 472}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {84, 348}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {176, 252}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {280, 236}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {236, 264}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {28, 144}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {132, 56}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {84, 72}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {224, 68}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {252, 88}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {156, 60}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {132, 80}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {108, 364}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {100, 380}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {36, 356}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {92, 356}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {180, 476}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {72, 552}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {36, 576}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {48, 548}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {56, 556}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {68, 552}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {88, 540}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {132, 540}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {108, 556}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {208, 460}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {136, 344}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {56, 344}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {20, 332}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {204, 364}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {188, 248}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {148, 232}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {136, 228}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {120, 44}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {144, 60}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {168, 52}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {180, 44}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {52, 76}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {104, 520}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/small_lamp.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {200, 440}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/small_lamp.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {108, 40}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=9, "image"="res/img/windchimes_1.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {176, 24}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=15, "image"="res/img/windchimes_0.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {244, 40}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=8, "image"="res/img/windchimes_1.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {68, 48}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_0.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {144, 24}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=12, "image"="res/img/windchimes_0.png", "node_length"=5}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
- .Carrabassett4 = {width=20, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 19, 19, 17, 0, 10, 31, 19, 31, 28, 40, 40, 40, 40, 40, 40, 40, 21, 31, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 19, 31, 19, 28, 40, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 5, 18, 9, 20, 9, 20, 20, 9, 9, 39, 40, 40, 18, 9, 20, 18, 20, 9, 9, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 45, pos = {52, 184}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {68, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {156, 160}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {192, 167}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {264, 184}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {200, 188}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {228, 196}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {108, 168}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {60, 176}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {124, 152}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {88, 156}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {164, 160}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {208, 184}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {220, 188}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {240, 184}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {252, 172}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {148, 280}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {244, 280}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {28, 296}, size = {-32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {280, 268}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {208, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {80, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {112, 296}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {184, 280}, size = {-26, 55}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {84, 136}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=10, "image"="res/img/windchimes_0.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {151, 120}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=10, "image"="res/img/windchimes_0.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {113, 133}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_1.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {201, 136}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_0.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {233, 144}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=12, "image"="res/img/windchimes_1.png", "node_length"=5}}, {type = .Rope, tile_id = nil, pos = {188, 233}, size = {0, 0}, parallax = {0, 0}, properties = {"length"=6, "image"="res/img/windchimes_0.png", "node_length"=2}}, {type = .Prop, tile_id = 52, pos = {228, 280}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {64, 296}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Upgrade, tile_id = nil, pos = {160, 241}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/double_jump_pickup.qoi", "type"=1}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
+ .Carrabassett0 = {width=40, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 19, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 16, 19, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 19, 31, 19, 19, 19, 31, 19, 31, 19, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 31, 31, 31, 19, 19, 31, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 20, 20, 18, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 19, 31, 19, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 18, 9, 9, 20, 9, 9, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 41, 9, 20, 20, 20, 18, 20, 20, 9, 20, 9, 20, 9, 20, 20, 9, 9, 18, 6, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 17, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 43, 9, 9, 20, 20, 9, 39, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 5, 20, 20, 18, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 20, 9, 20, 18, 20, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 53, pos = {194, 200}, size = {26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {352, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {412, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {364, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {172, 200}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {224, 200}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {220, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {296, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {340, 76}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {416, 60}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {492, 76}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {432, 76}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {352, 92}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {236, 108}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {80, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {528, 100}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {472, 88}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {512, 96}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {60, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {44, 148}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {24, 180}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {148, 96}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {260, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {164, 88}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {128, 100}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {20, 280}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {304, 200}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {260, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {284, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {132, 248}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {96, 248}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {64, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {116, 248}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {300, 200}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {448, 232}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {540, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {612, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {576, 152}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {556, 124}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {572, 136}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {588, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {580, 132}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {504, 80}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {424, 68}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {248, 100}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {484, 232}, size = {-26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {400, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {412, 156}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {436, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {487, 185}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=2, "length"=6}}, {type = .Rope, tile_id = nil, pos = {217, 153}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/small_lamp.png", "node_length"=2, "length"=6}}, {type = .Rope, tile_id = nil, pos = {515, 110}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=20}}, {type = .Player_Spawn, tile_id = nil, pos = {240, 200}, size = {0, 0}, parallax = {0, 0}, properties = {}}, {type = .Collision, tile_id = nil, pos = {0, 0}, size = {48, 48}, parallax = {0, 0}, properties = {}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
+ .Carrabassett1 = {width=20, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 31, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 17, 0, 0, 0, 16, 19, 28, 40, 40, 40, 40, 40, 40, 40, 27, 31, 31, 17, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 40, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 38, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 28, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 43, 9, 9, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 18, 20, 20, 40, 40, 40, 40, 40, 43, 9, 9, 9, 9, 9, 9, 18, 9, 18, 18, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 49, pos = {92, 296}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {144, 296}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {180, 296}, size = {-26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {116, 296}, size = {26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {127, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {181, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {224, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {252, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {292, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {48, 280}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {80, 104}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {88, 100}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {100, 96}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {108, 88}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {116, 88}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {96, 96}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {192, 76}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {272, 128}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {244, 100}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {228, 72}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {264, 104}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {284, 128}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {40, 108}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {56, 92}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {68, 108}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {24, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {272, 280}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {24, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {139, 249}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=2, "length"=6}}, {type = .Rope, tile_id = nil, pos = {183, 249}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=2, "length"=6}}, {type = .Rope, tile_id = nil, pos = {134, 48}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=7, "length"=15}}, {type = .Rope, tile_id = nil, pos = {232, 47}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=15}}, {type = .Rope, tile_id = nil, pos = {70, 59}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=10, "length"=15}}, {type = .Rope, tile_id = nil, pos = {174, 32}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=10, "length"=15}}, {type = .Rope, tile_id = nil, pos = {269, 72}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=10, "length"=15}}, {type = .Rope, tile_id = nil, pos = {206, 30}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=8, "length"=15}}, {type = .Rope, tile_id = nil, pos = {115, 45}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/small_lamp.png", "node_length"=5, "length"=15}}, {type = .Rope, tile_id = nil, pos = {91, 61}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/small_lamp.png", "node_length"=5, "length"=15}}, {type = .Rope, tile_id = nil, pos = {191, 31}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/small_lamp.png", "node_length"=5, "length"=15}}, {type = .Rope, tile_id = nil, pos = {286, 86}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/small_lamp.png", "node_length"=5, "length"=15}}, {type = .Upgrade, tile_id = nil, pos = {160, 240}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/dash_pickup.qoi", "type"=0}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
+ .Carrabassett2 = {width=20, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 8, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 10, 31, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 20, 42, 0, 0, 0, 10, 19, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 27, 31, 19, 28, 38, 18, 6, 0, 0, 0, 0, 10, 19, 28, 40, 40, 40, 40, 40, 27, 17, 0, 0, 10, 28, 40, 38, 20, 42, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 17, 0, 0, 0, 0, 16, 19, 31, 19, 17, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 39, 40, 40, 40, 40, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 18, 9, 9, 39, 40, 40, 40, 40, 40, 40, 20, 9, 18, 9, 9, 9, 20, 20, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 45, pos = {4, 124}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {32, 104}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {128, 72}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {212, 104}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {104, 124}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {116, 140}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {180, 136}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {36, 152}, size = {26, 55}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {84, 152}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {88, 72}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {120, 88}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {56, 56}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {128, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {20, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {40, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {52, 152}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {58, 105}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=2, "length"=6}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
+ .Carrabassett3 = {width=20, height=40, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 19, 31, 19, 19, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 19, 31, 17, 0, 0, 0, 0, 0, 16, 19, 28, 40, 40, 40, 40, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 19, 28, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 28, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 20, 9, 39, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 18, 9, 18, 39, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 41, 20, 20, 18, 18, 39, 40, 40, 40, 40, 40, 21, 28, 40, 40, 32, 0, 0, 0, 0, 10, 31, 31, 19, 19, 28, 40, 40, 40, 40, 27, 17, 7, 40, 40, 43, 42, 0, 0, 0, 0, 0, 0, 0, 0, 10, 19, 19, 19, 31, 17, 0, 7, 40, 40, 40, 38, 18, 18, 20, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 38, 20, 20, 18, 6, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 6, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 43, 6, 0, 0, 0, 0, 0, 7, 40, 40, 21, 28, 40, 21, 31, 28, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 7, 40, 40, 32, 16, 19, 17, 0, 16, 19, 19, 31, 28, 40, 38, 9, 20, 6, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 16, 19, 31, 19, 19, 17, 0, 0, 7, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 20, 18, 9, 9, 18, 20, 39, 40, 40, 43, 6, 0, 0, 0, 0, 0, 41, 20, 20, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 42, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 20, 20, 42, 0, 10, 19, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 27, 19, 19, 28, 40, 8, 0, 0, 0, 10, 31, 19, 31, 28, 40, 40, 40, 40, 40, 40, 32, 0, 0, 10, 19, 17, 0, 0, 0, 0, 0, 0, 0, 16, 31, 31, 31, 19, 31, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 38, 9, 9, 9, 20, 20, 18, 18, 9, 9, 42, 0, 0, 0, 0, 0, 0, 0, 0, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 8, 0, 0, 5, 20, 20, 9, 9, 18, 40, 40, 40, 21, 31, 31, 19, 31, 31, 19, 19, 17, 0, 5, 39, 40, 40, 40, 40, 40, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 28, 40, 40, 40, 40, 40, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 41, 20, 18, 20, 39, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 38, 6, 0, 0, 0, 0, 41, 9, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 43, 6, 0, 0, 41, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 49, pos = {132, 616}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {32, 488}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {204, 328}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {260, 168}, size = {-32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {228, 184}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {108, 200}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {160, 200}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {108, 264}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {168, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {284, 376}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {216, 376}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {184, 376}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {140, 392}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {232, 376}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {156, 392}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {128, 200}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {44, 248}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {252, 504}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {284, 504}, size = {-32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {236, 504}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {24, 472}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {84, 348}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {176, 252}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {280, 236}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {236, 264}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {28, 144}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {132, 56}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {84, 72}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {224, 68}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {252, 88}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {156, 60}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {132, 80}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {108, 364}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {100, 380}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {36, 356}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {92, 356}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {180, 476}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {72, 552}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {36, 576}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {48, 548}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {56, 556}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {68, 552}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {88, 540}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {132, 540}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {108, 556}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {208, 460}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {136, 344}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {56, 344}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {20, 332}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {204, 364}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {188, 248}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {148, 232}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {136, 228}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {120, 44}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {144, 60}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {168, 52}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {180, 44}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {52, 76}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {104, 520}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/small_lamp.png", "node_length"=5, "length"=6}}, {type = .Rope, tile_id = nil, pos = {200, 440}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/small_lamp.png", "node_length"=5, "length"=6}}, {type = .Rope, tile_id = nil, pos = {108, 40}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=5, "length"=9}}, {type = .Rope, tile_id = nil, pos = {176, 24}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=15}}, {type = .Rope, tile_id = nil, pos = {244, 40}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=5, "length"=8}}, {type = .Rope, tile_id = nil, pos = {68, 48}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=6}}, {type = .Rope, tile_id = nil, pos = {144, 24}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=12}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
+ .Carrabassett4 = {width=20, height=20, tile_width=16, tile_height=16, layers={{40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 28, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 21, 31, 19, 19, 17, 0, 10, 31, 19, 31, 28, 40, 40, 40, 40, 40, 40, 40, 21, 31, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 19, 31, 19, 28, 40, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 21, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 40, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 27, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 39, 40, 0, 0, 0, 0, 0, 0, 0, 0, 5, 18, 9, 20, 9, 20, 20, 9, 9, 39, 40, 40, 18, 9, 20, 18, 20, 9, 9, 9, 39, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40}}, objects={{type = .Prop, tile_id = 45, pos = {52, 184}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {68, 172}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {156, 160}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {192, 167}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {264, 184}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {200, 188}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {228, 196}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 45, pos = {108, 168}, size = {14, 38}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {60, 176}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {124, 152}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {88, 156}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {164, 160}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {208, 184}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {220, 188}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {240, 184}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 47, pos = {252, 172}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 46, pos = {148, 280}, size = {29, 14}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {244, 280}, size = {32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 49, pos = {28, 296}, size = {-32, 19}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {280, 268}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {208, 280}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {80, 296}, size = {16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 51, pos = {112, 296}, size = {-16, 18}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 53, pos = {184, 280}, size = {-26, 55}, parallax = {0, 0}, properties = {}}, {type = .Rope, tile_id = nil, pos = {84, 136}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=10}}, {type = .Rope, tile_id = nil, pos = {151, 120}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=10}}, {type = .Rope, tile_id = nil, pos = {113, 133}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=5, "length"=6}}, {type = .Rope, tile_id = nil, pos = {201, 136}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=5, "length"=6}}, {type = .Rope, tile_id = nil, pos = {233, 144}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_1.png", "node_length"=5, "length"=12}}, {type = .Rope, tile_id = nil, pos = {188, 233}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/windchimes_0.png", "node_length"=2, "length"=6}}, {type = .Prop, tile_id = 52, pos = {228, 280}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Prop, tile_id = 52, pos = {64, 296}, size = {14, 22}, parallax = {0, 0}, properties = {}}, {type = .Upgrade, tile_id = nil, pos = {160, 241}, size = {0, 0}, parallax = {0, 0}, properties = {"image"="res/img/double_jump_pickup.qoi", "type"=1}}, }, background_color=Color{0, 0, 0, 1}, background_images={} },
}
tiles: []Tile_Resource = {
diff --git a/src/draw.odin b/src/draw.odin
deleted file mode 100644
index 0c21c80..0000000
--- a/src/draw.odin
+++ /dev/null
@@ -1,151 +0,0 @@
-package demonchime
-
-import "core:c"
-import "core:math"
-import "core:math/linalg"
-
-import rl "vendor:raylib"
-import rlgl "vendor:raylib/rlgl"
-
-Color :: [4]f32
-
-SCREEN_WIDTH :: 320
-SCREEN_HEIGHT :: 320
-SCREEN_SIZE :: Vec2{SCREEN_WIDTH, SCREEN_HEIGHT}
-
-// @(default_calling_convention = "c")
-// foreign lib {
-// DrawTexturePoly :: proc(texture: rl.Texture2D, center: rl.Vector2, points: [^]rl.Vector2, textcoords: [^]rl.Vector2, point_count: c.int, color: Color) --- // Draw a regular polygon (Vector version)
-// }
-
-renderer: struct {
- screen: rl.RenderTexture2D,
- tint: Color,
-}
-
-@(private = "file")
-_color_to_rl :: proc(col: Color) -> rl.Color {
- return rl.Color {
- u8(col.r * 255),
- u8(col.g * 255),
- u8(col.b * 255),
- u8(col.a * 255),
- }
-}
-
-init_draw :: proc() {
- renderer.screen = rl.LoadRenderTexture(SCREEN_WIDTH, SCREEN_HEIGHT)
- renderer.tint = Color{1, 1, 1, 1}
-}
-
-deinit_draw :: proc() {
- rl.UnloadRenderTexture(renderer.screen)
-}
-
-draw_new_frame :: proc() {
- rl.BeginTextureMode(renderer.screen)
- rl.ClearBackground(rl.BLACK)
- // rl.ClearBackground(rl.GRAY)
-}
-
-draw_end_frame :: proc() {
- rl.EndTextureMode()
-
- rl.BeginDrawing()
- {
- rl.ClearBackground(_color_to_rl(Color{0, 0, 0, 1}))
- scale := math.min(
- f32(rl.GetScreenWidth()) / f32(SCREEN_WIDTH),
- f32(rl.GetScreenHeight()) / f32(SCREEN_HEIGHT),
- )
- screen_start := Vec2 {
- (f32(rl.GetScreenWidth()) - (SCREEN_WIDTH * scale)) / 2,
- (f32(rl.GetScreenHeight()) - (SCREEN_HEIGHT * scale)) / 2,
- }
-
- draw_texture(
- renderer.screen.texture,
- screen_start,
- scale = Vec2{scale, -scale},
- )
- }
- rl.EndDrawing()
-}
-
-draw_circle :: proc(pos: Vec2, rad: f32) {
- rl.DrawCircle(i32(pos.x), i32(pos.y), rad, _color_to_rl(renderer.tint))
-}
-
-draw_rect :: proc(rect: Rect) {
- assert(rect.size.x > 0 && rect.size.y > 0)
-
- rl.DrawRectangle(
- c.int(rect.start.x),
- c.int(rect.start.y),
- c.int(rect.size.x),
- c.int(rect.size.y),
- _color_to_rl(renderer.tint),
- )
-}
-
-draw_linerect :: proc(rect: Rect) {
- assert(rect.size.x > 0 && rect.size.y > 0)
-
- rl.DrawRectangleLines(
- c.int(rect.start.x),
- c.int(rect.start.y),
- c.int(rect.size.x),
- c.int(rect.size.y),
- _color_to_rl(renderer.tint),
- )
-}
-
-draw_texture :: proc {
- draw_texture_full,
- draw_texture_quad,
-}
-
-draw_texture_quad :: proc(
- img: rl.Texture2D,
- quad: Rect,
- position: Vec2,
- offset := Vec2{0, 0},
- rotation: f32 = 0,
- scale := Vec2{1, 1},
-) {
- quad := quad
- if scale.x < 0 {
- quad.size.x *= -1
- }
- if scale.y < 0 {
- quad.size.y *= -1
- }
-
- position := linalg.round(position)
-
- rl.DrawTexturePro(
- img,
- transmute(rl.Rectangle)quad,
- rl.Rectangle {
- position.x,
- position.y,
- quad.size.x * scale.x,
- quad.size.y * scale.y,
- },
- offset,
- math.round(rotation / 5) * 5,
- _color_to_rl(renderer.tint),
- )
-}
-
-draw_texture_full :: proc(
- img: rl.Texture2D,
- position: Vec2,
- offset := Vec2{0, 0},
- rotation: f32 = 0,
- scale := Vec2{1, 1},
-) {
- size := Vec2{f32(img.width), f32(img.height)}
-
- draw_texture_quad(img, Rect{Vec2{0, 0}, size}, position, offset, rotation, scale)
-}
diff --git a/src/fw/fw.odin b/src/fw/fw.odin
new file mode 100644
index 0000000..86a3e3a
--- /dev/null
+++ b/src/fw/fw.odin
@@ -0,0 +1,114 @@
+package fw
+
+import "core:log"
+
+import "vendor:glfw"
+
+Vec2 :: [2]f32
+Vec2i :: [2]i32
+Vec3 :: [3]f32
+Vec4 :: [4]f32
+Color :: [4]f32
+Mat4 :: matrix[4, 4]f32
+
+Rect :: struct {
+ start: Vec2,
+ size: Vec2,
+}
+
+Config :: struct {
+ win_name: cstring,
+ win_size: Vec2i,
+ screen_size: Vec2i,
+ renderer_backend: Renderer_Backend,
+}
+
+@(private) window: glfw.WindowHandle
+@(private) last_frame: f64
+@(private) dt: f64
+
+rgba8 :: proc(r: u8, g: u8, b: u8, a: u8 = 255) -> Color {
+ return Color{
+ f32(r) / 255,
+ f32(g) / 255,
+ f32(b) / 255,
+ f32(a) / 255,
+ }
+}
+
+init :: proc(config: Config) {
+ if !glfw.Init() {
+ panic("could not init glfw window")
+ }
+
+ glfw.WindowHint(glfw.CONTEXT_VERSION_MAJOR, 3)
+ glfw.WindowHint(glfw.CONTEXT_VERSION_MINOR, 3)
+ glfw.WindowHint(glfw.RESIZABLE, false)
+ glfw.WindowHint(glfw.OPENGL_PROFILE, glfw.OPENGL_CORE_PROFILE)
+
+ window = glfw.CreateWindow(
+ config.win_size.x,
+ config.win_size.y,
+ config.win_name,
+ nil,
+ nil,
+ )
+
+ if window == nil {
+ panic("could not create glfw window")
+ }
+
+ glfw.SwapInterval(1)
+
+ _renderer_init(config)
+}
+
+deinit :: proc() {
+ _renderer_deinit()
+
+ glfw.DestroyWindow(window)
+ glfw.Terminate()
+}
+
+next_frame :: proc() -> bool {
+ // End the previous frame
+ if can_flush() {
+ flush_batch(&renderer.draw_call)
+ new_batch(renderer.white_1x1.handle, .None, false)
+ }
+
+ renderer.vt.end_frame()
+ new_batch(renderer.white_1x1.handle, .None, false)
+
+ renderer.draw_calls_count = renderer._draw_call_counter
+ renderer._draw_call_counter = 0
+
+ glfw.SwapBuffers(window)
+ glfw.PollEvents()
+ _update_input()
+
+ // log.debugf("Draw calls: %v", renderer.draw_calls_count)
+
+ // Begin next frame
+
+ time := get_time()
+ dt = time - last_frame
+ last_frame = time
+
+ renderer.vt.clear({0, 0, 0, 1})
+
+ renderer.vt.start_frame()
+ renderer.vt.clear(renderer.bg_col)
+
+ return !bool(glfw.WindowShouldClose(window))
+}
+
+@(require_results)
+get_time :: #force_inline proc() -> f64 {
+ return glfw.GetTime()
+}
+
+@(require_results)
+get_delta_time :: #force_inline proc() -> f64 {
+ return dt
+}
diff --git a/src/fw/input.odin b/src/fw/input.odin
new file mode 100644
index 0000000..a3cbe25
--- /dev/null
+++ b/src/fw/input.odin
@@ -0,0 +1,76 @@
+package fw
+
+import "core:c"
+import "vendor:glfw"
+
+Keyboard_Input :: union {
+ Key,
+ Mouse_Button,
+}
+
+Controller_Input :: union {
+}
+
+Keybind :: struct {
+ input: Keyboard_Input,
+ pressed: bool,
+ just_pressed: bool,
+}
+
+key_down_last_frame: #sparse [Key]bool
+key_just_down: #sparse [Key]bool
+
+mouse_down_last_frame: #sparse [Mouse_Button]bool
+mouse_just_down: #sparse [Mouse_Button]bool
+
+@(private)
+_update_input :: proc() {
+ for key in Key {
+ status := glfw.GetKey(window, c.int(key))
+ key_pressed := status == glfw.PRESS
+ key_just_down[key] = key_pressed && !key_down_last_frame[key]
+
+ key_down_last_frame[key] = key_pressed
+ }
+
+ for mb in Mouse_Button {
+ status := glfw.GetMouseButton(window, c.int(mb))
+ mouse_pressed := status == glfw.PRESS
+ mouse_just_down[mb] = mouse_pressed && !mouse_down_last_frame[mb]
+
+ mouse_down_last_frame[mb] = mouse_pressed
+ }
+}
+
+is_keybind_down :: proc(keybind: Keybind) -> bool {
+ switch val in keybind.input {
+ case Key:
+ return glfw.GetKey(window, c.int(val)) == glfw.PRESS
+ case Mouse_Button:
+ return glfw.GetMouseButton(window, c.int(val)) == glfw.PRESS
+ }
+
+ assert(false)
+ return false
+}
+
+is_keybind_just_down :: proc(keybind: Keybind) -> bool {
+ switch val in keybind.input {
+ case Key: return key_just_down[val]
+ case Mouse_Button: return mouse_just_down[val]
+ }
+
+ assert(false)
+ return false
+}
+
+get_mouse_pos :: proc() -> (mouse_pos: Vec2) {
+ w_width, w_height := glfw.GetWindowSize(window)
+ mx, my := glfw.GetCursorPos(window)
+
+ mouse_pos = Vec2{f32(mx), f32(mx)}
+ mouse_pos /= Vec2{f32(w_width), f32(w_height)}
+ mouse_pos *= Vec2{f32(framebuf.color.size.x), f32(framebuf.color.size.y)}
+ // mouse_pos += state.camera.target
+ return
+}
diff --git a/src/fw/keys.odin b/src/fw/keys.odin
new file mode 100644
index 0000000..180cb4b
--- /dev/null
+++ b/src/fw/keys.odin
@@ -0,0 +1,140 @@
+package fw
+
+Mouse_Button :: enum {
+ B1 = 0,
+ B2 = 1,
+ B3 = 2,
+ B4 = 3,
+ B5 = 4,
+ B6 = 5,
+ B7 = 6,
+ B8 = 7,
+ Last = B8,
+ Left = B1,
+ Right = B2,
+ Middle = B3,
+}
+
+Key :: enum {
+ Space = 32,
+ Apostrophe = 39,
+ Comma = 44,
+ Minus = 45,
+ Period = 46,
+ Slash = 47,
+ Semicolon = 59,
+ Equal = 61,
+ Left_Bracket = 91,
+ Backslash = 92,
+ Right_Bracket = 93,
+ Grave_Accent = 96,
+ World_1 = 161,
+ World_2 = 162,
+ N0 = 48,
+ N1 = 49,
+ N2 = 50,
+ N3 = 51,
+ N4 = 52,
+ N5 = 53,
+ N6 = 54,
+ N7 = 55,
+ N8 = 56,
+ N9 = 57,
+ A = 65,
+ B = 66,
+ C = 67,
+ D = 68,
+ E = 69,
+ F = 70,
+ G = 71,
+ H = 72,
+ I = 73,
+ J = 74,
+ K = 75,
+ L = 76,
+ M = 77,
+ N = 78,
+ O = 79,
+ P = 80,
+ Q = 81,
+ R = 82,
+ S = 83,
+ T = 84,
+ U = 85,
+ V = 86,
+ W = 87,
+ X = 88,
+ Y = 89,
+ Z = 90,
+ Escape = 256,
+ Enter = 257,
+ Tab = 258,
+ Backspace = 259,
+ Insert = 260,
+ Delete = 261,
+ Right = 262,
+ Left = 263,
+ Down = 264,
+ Up = 265,
+ Page_Up = 266,
+ Page_Down = 267,
+ Home = 268,
+ End = 269,
+ Caps_Lock = 280,
+ Scroll_Lock = 281,
+ Num_Lock = 282,
+ Print_Screen = 283,
+ Pause = 284,
+ F1 = 290,
+ F2 = 291,
+ F3 = 292,
+ F4 = 293,
+ F5 = 294,
+ F6 = 295,
+ F7 = 296,
+ F8 = 297,
+ F9 = 298,
+ F10 = 299,
+ F11 = 300,
+ F12 = 301,
+ F13 = 302,
+ F14 = 303,
+ F15 = 304,
+ F16 = 305,
+ F17 = 306,
+ F18 = 307,
+ F19 = 308,
+ F20 = 309,
+ F21 = 310,
+ F22 = 311,
+ F23 = 312,
+ F24 = 313,
+ F25 = 314,
+ Kp_0 = 320,
+ Kp_1 = 321,
+ Kp_2 = 322,
+ Kp_3 = 323,
+ Kp_4 = 324,
+ Kp_5 = 325,
+ Kp_6 = 326,
+ Kp_7 = 327,
+ Kp_8 = 328,
+ Kp_9 = 329,
+ Kp_Decimal = 330,
+ Kp_Divide = 331,
+ Kp_Multiply = 332,
+ Kp_Subtract = 333,
+ Kp_Add = 334,
+ Kp_Enter = 335,
+ Kp_Equal = 336,
+ Left_Shift = 340,
+ Left_Control = 341,
+ Left_Alt = 342,
+ Left_Super = 343,
+ Right_Shift = 344,
+ Right_Control = 345,
+ Right_Alt = 346,
+ Right_Super = 347,
+ Menu = 348,
+ Last = Menu,
+}
diff --git a/src/fw/opengl.odin b/src/fw/opengl.odin
new file mode 100644
index 0000000..ab2bb81
--- /dev/null
+++ b/src/fw/opengl.odin
@@ -0,0 +1,363 @@
+package fw
+
+import "base:runtime"
+
+import "core:log"
+import "core:fmt"
+import "core:math/linalg"
+import "core:os"
+
+import "vendor:glfw"
+import gl "vendor:OpenGL"
+
+@(private)
+enum_conv: map[All_Enums]u32
+
+vert_shader_src := string(#load("shader.vert"))
+frag_shader_src := string(#load("shader.frag"))
+
+vao: u32
+vbo: u32
+ebo: u32
+
+framebuf: struct {
+ handle: u32,
+ color: Texture, // so we can reuse pre-existing draw procs
+ depth: u32,
+}
+shader_program: u32
+
+projection_loc: i32
+view_loc: i32
+tex0_loc: i32
+
+// @(private)
+// _gl_debug_message :: proc "c" (
+// source: u32,
+// type: u32,
+// id: u32,
+// severity: u32,
+// length: i32,
+// message: cstring,
+// userParam: rawptr,
+// ) {
+// context = runtime.default_context()
+// switch severity {
+// case gl.DEBUG_SEVERITY_HIGH: fmt.print("[HIGH]")
+// case gl.DEBUG_SEVERITY_MEDIUM: fmt.print("[MEDIUM]")
+// case gl.DEBUG_SEVERITY_LOW: fmt.print("[LOW]")
+// case gl.DEBUG_SEVERITY_NOTIFICATION: fmt.print("[NOTIF]")
+// }
+// fmt.printfln(" OpenGL %v: %v", id, message)
+// }
+
+@(private)
+_init_vertex_buffer_and_array :: proc(vao: u32, vbo: u32, ebo: u32) {
+ gl.BindVertexArray(vao)
+
+ gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
+ gl.BufferData(gl.ARRAY_BUFFER, 0, nil, gl.DYNAMIC_DRAW)
+
+ gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
+ gl.BufferData(gl.ELEMENT_ARRAY_BUFFER, 0, nil, gl.DYNAMIC_DRAW)
+
+ stride := i32(size_of(Vertex))
+
+ gl.EnableVertexAttribArray(0)
+ gl.VertexAttribPointer(0, 3, gl.FLOAT, false, stride, offset_of(Vertex, pos))
+
+ gl.EnableVertexAttribArray(1)
+ gl.VertexAttribPointer(1, 2, gl.FLOAT, false, stride, offset_of(Vertex, uv))
+
+ gl.EnableVertexAttribArray(2)
+ gl.VertexAttribPointer(
+ 2,
+ 4,
+ gl.FLOAT,
+ false,
+ stride,
+ offset_of(Vertex, color),
+ )
+}
+
+@(private)
+_gl_load_shader :: proc(src: string, type: u32) -> u32 {
+ shader := gl.CreateShader(type)
+ csrc := cstring(raw_data(src))
+ src_len := i32(len(src))
+ gl.ShaderSource(shader, 1, &csrc, &src_len)
+ gl.CompileShader(shader)
+
+ status: i32
+ gl.GetShaderiv(shader, gl.COMPILE_STATUS, &status)
+ if status == 0 {
+ gl.DeleteShader(shader)
+ return 0
+ }
+
+ return shader
+}
+
+@(private)
+_gl_load_shader_program :: proc(vert_src: string, frag_src: string) -> u32 {
+ vert_shader := _gl_load_shader(vert_src, gl.VERTEX_SHADER)
+ defer gl.DeleteShader(vert_shader)
+ frag_shader := _gl_load_shader(frag_src, gl.FRAGMENT_SHADER)
+ defer gl.DeleteShader(frag_shader)
+
+ program := gl.CreateProgram()
+ gl.AttachShader(program, vert_shader)
+ gl.AttachShader(program, frag_shader)
+ gl.LinkProgram(program)
+
+ status: i32
+ gl.GetProgramiv(program, gl.LINK_STATUS, &status)
+ if status == 0 {
+ gl.DeleteProgram(program)
+ return 0
+ }
+
+ return program
+}
+
+gl_init :: proc() {
+ glfw.MakeContextCurrent(window)
+
+ gl.load_up_to(3, 3, glfw.gl_set_proc_address)
+
+ gl.Enable(gl.DEPTH_TEST)
+ gl.DepthFunc(gl.LEQUAL)
+
+ // gl.Enable(gl.BLEND);
+ // gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
+
+ renderer.vt.start_frame = gl_start_frame
+ renderer.vt.end_frame = gl_end_frame
+ renderer.vt.draw = gl_draw
+ renderer.vt.clear = gl_clear
+ renderer.vt.init_texture = gl_init_texture
+ renderer.vt.destroy_texture = gl_destroy_texture
+ renderer.vt.init_screen = gl_init_screen
+
+ enum_conv[Vertex_Mode.None] = gl.TRIANGLES
+ enum_conv[Vertex_Mode.Triangles] = gl.TRIANGLES
+ enum_conv[Vertex_Mode.Triangle_Fan] = gl.TRIANGLE_FAN
+ enum_conv[Vertex_Mode.Triangle_Strip] = gl.TRIANGLE_STRIP
+ enum_conv[Vertex_Mode.Lines] = gl.LINES
+ enum_conv[Vertex_Mode.Line_Strip] = gl.LINE_STRIP
+ enum_conv[Vertex_Mode.Line_Loop] = gl.LINE_LOOP
+ enum_conv[Vertex_Mode.Points] = gl.POINTS
+
+ gl.PixelStorei(gl.UNPACK_ALIGNMENT, 1);
+
+ gl.GenBuffers(1, &vbo)
+ gl.GenBuffers(1, &ebo)
+ gl.GenVertexArrays(1, &vao)
+ _init_vertex_buffer_and_array(vao, vbo, ebo)
+
+ shader_program = _gl_load_shader_program(vert_shader_src, frag_shader_src)
+ projection_loc = gl.GetUniformLocation(shader_program, "projection")
+ view_loc = gl.GetUniformLocation(shader_program, "view")
+ tex0_loc = gl.GetUniformLocation(shader_program, "tex0")
+}
+
+gl_deinit :: proc() {
+ delete(enum_conv)
+
+ destroy_texture(framebuf.color)
+ gl.DeleteRenderbuffers(1, &framebuf.depth)
+ gl.DeleteFramebuffers(1, &framebuf.handle)
+
+ gl.DeleteProgram(shader_program)
+
+ gl.DeleteBuffers(1, &vbo)
+ gl.DeleteVertexArrays(1, &vao)
+}
+
+gl_start_frame :: proc() {
+ gl.BindFramebuffer(gl.FRAMEBUFFER, framebuf.handle)
+ gl.Viewport(0, 0, framebuf.color.size.x, framebuf.color.size.y)
+ renderer.projection = linalg.matrix_ortho3d(
+ f32(0), f32(framebuf.color.size.x),
+ f32(framebuf.color.size.y), 0,
+ -1, 1,
+ )
+}
+
+gl_end_frame :: proc() {
+ gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
+
+ w_width, w_height := glfw.GetWindowSize(window)
+
+ gl.Viewport(0, 0, w_width, w_height)
+
+ renderer.projection = linalg.matrix_ortho3d(
+ f32(0), f32(w_width),
+ 0, f32(w_height),
+ -1, 1,
+ )
+
+ draw_rect({0, 0}, {f32(w_width), f32(w_height)}, tex = framebuf.color)
+ flush_batch(&renderer.draw_call)
+}
+
+gl_draw :: proc(draw_call: Draw_Call) {
+ draw_call := draw_call
+
+ gl.UseProgram(shader_program)
+
+ gl.ActiveTexture(gl.TEXTURE0)
+ gl.BindTexture(gl.TEXTURE_2D, draw_call.tex)
+
+ gl.Uniform1i(tex0_loc, 0)
+ gl.UniformMatrix4fv(
+ projection_loc,
+ 1,
+ false,
+ transmute([^]f32)(&draw_call.projection),
+ )
+ gl.UniformMatrix4fv(view_loc, 1, false, transmute([^]f32)(&draw_call.view))
+
+ gl.BindBuffer(gl.ARRAY_BUFFER, vbo)
+ gl.BufferData(
+ gl.ARRAY_BUFFER,
+ size_of(Vertex) * len(draw_call.vertices),
+ raw_data(draw_call.vertices),
+ gl.DYNAMIC_DRAW,
+ )
+
+ gl.BindVertexArray(vao)
+
+ if !draw_call.indexed {
+ gl.DrawArrays(
+ enum_conv[draw_call.vertex_mode],
+ 0,
+ i32(len(draw_call.vertices)),
+ )
+ } else {
+ gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, ebo)
+ gl.BufferData(
+ gl.ELEMENT_ARRAY_BUFFER,
+ size_of(Index) * len(draw_call.indices),
+ raw_data(draw_call.indices),
+ gl.DYNAMIC_DRAW,
+ )
+
+ gl.DrawElements(
+ enum_conv[draw_call.vertex_mode],
+ i32(len(draw_call.indices)),
+ gl.UNSIGNED_SHORT,
+ nil,
+ )
+ gl.BindBuffer(gl.ELEMENT_ARRAY_BUFFER, 0)
+ }
+
+ gl.BindBuffer(gl.ARRAY_BUFFER, 0)
+ gl.BindVertexArray(0)
+}
+
+gl_clear :: proc(col: Color) {
+ gl.ClearColor(col.r, col.g, col.b, col.a)
+ gl.Clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
+}
+
+gl_init_texture :: proc(
+ texture: ^Texture,
+ data: []u8,
+ channels: i32,
+) {
+ tex: u32
+ gl.GenTextures(1, &tex)
+
+ format := gl.RGBA
+ switch channels {
+ case 3: format = gl.RGB
+ case 4: format = gl.RGBA
+ case: panic("Unsupported amount of channels. Must be either 3 or 4.")
+ }
+
+ gl.BindTexture(gl.TEXTURE_2D, tex)
+ gl.TexImage2D(
+ gl.TEXTURE_2D,
+ 0,
+ i32(format),
+ texture.size.x,
+ texture.size.y,
+ 0,
+ u32(format),
+ gl.UNSIGNED_BYTE,
+ raw_data(data),
+ )
+
+ gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
+ gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
+
+ gl.GenerateMipmap(gl.TEXTURE_2D)
+
+ texture.handle = tex
+}
+
+gl_destroy_texture :: proc(texture: Texture_Handle) {
+ texture := texture
+ gl.DeleteTextures(1, &texture)
+}
+
+gl_init_screen :: proc(screen_size: Vec2i) {
+ assert(screen_size.x * screen_size.y > 0)
+
+ gl.GenFramebuffers(1, &framebuf.handle)
+ gl.BindFramebuffer(gl.FRAMEBUFFER, framebuf.handle)
+
+ color_tex: u32
+ gl.GenTextures(1, &color_tex)
+ gl.BindTexture(gl.TEXTURE_2D, color_tex)
+
+ gl.TexImage2D(
+ gl.TEXTURE_2D,
+ 0,
+ gl.RGB,
+ screen_size.x,
+ screen_size.y,
+ 0,
+ gl.RGB,
+ gl.UNSIGNED_BYTE,
+ nil,
+ )
+ gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)
+ gl.TexParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
+
+ gl.FramebufferTexture2D(
+ gl.FRAMEBUFFER,
+ gl.COLOR_ATTACHMENT0,
+ gl.TEXTURE_2D,
+ color_tex,
+ 0,
+ )
+
+ framebuf.color = Texture {
+ handle = color_tex,
+ size = screen_size,
+ }
+
+ gl.GenRenderbuffers(1, &framebuf.depth)
+ gl.BindRenderbuffer(gl.RENDERBUFFER, framebuf.depth)
+ gl.RenderbufferStorage(
+ gl.RENDERBUFFER,
+ gl.DEPTH_COMPONENT32F,
+ screen_size.x,
+ screen_size.y,
+ );
+ gl.FramebufferRenderbuffer(
+ gl.FRAMEBUFFER,
+ gl.DEPTH_ATTACHMENT,
+ gl.RENDERBUFFER,
+ framebuf.depth,
+ );
+
+ if gl.CheckFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE {
+ log.fatal("[OPENGL] Framebuffer could not be completed")
+ os.exit(1)
+ }
+
+ gl.BindFramebuffer(gl.FRAMEBUFFER, 0)
+}
diff --git a/src/fw/renderer.odin b/src/fw/renderer.odin
new file mode 100644
index 0000000..082a0d3
--- /dev/null
+++ b/src/fw/renderer.odin
@@ -0,0 +1,390 @@
+package fw
+
+import "core:log"
+import "core:image"
+import "core:math"
+import "core:math/linalg"
+import "core:math/linalg/glsl"
+
+Index :: u16
+
+Renderer_Backend :: enum {
+ OpenGL,
+}
+
+Vertex_Mode :: enum {
+ None,
+ Triangles,
+ Triangle_Strip,
+ Triangle_Fan,
+ Lines,
+ Line_Strip,
+ Line_Loop,
+ Points,
+}
+
+Blend_Mode :: enum {
+ Alpha,
+ Additive,
+}
+
+@(private)
+All_Enums :: union {
+ Vertex_Mode,
+}
+
+VTable :: struct {
+ start_frame: proc(),
+ end_frame: proc(),
+ draw: proc(Draw_Call),
+ clear: proc(Color),
+ init_texture: proc(
+ texture: ^Texture,
+ data: []u8,
+ channels: i32,
+ ),
+ destroy_texture: proc(texture: Texture_Handle),
+ init_screen: proc(screen_size: Vec2i),
+}
+
+Texture_Handle :: u32
+
+Texture :: struct {
+ handle: Texture_Handle, // for opengl, this is just the actual handle. for
+ // others, it can be an index to the real handle.
+ size: Vec2i,
+}
+
+Vertex :: struct {
+ pos: Vec3,
+ uv: Vec2,
+ color: Vec4,
+}
+
+Draw_Call :: struct {
+ tex: Texture_Handle,
+ vertex_mode: Vertex_Mode,
+ model_mat: [dynamic]Mat4,
+ vertices: [dynamic]Vertex,
+ indices: [dynamic]Index,
+
+ projection: Mat4,
+ view: Mat4,
+
+ indexed: bool,
+}
+
+renderer: struct {
+ draw_call: Draw_Call,
+ backend: Renderer_Backend,
+ bg_col: Color,
+ white_1x1: Texture,
+ projection: Mat4,
+ view: Mat4,
+
+ draw_calls_count: i32,
+ _draw_call_counter: i32,
+
+ vt: VTable,
+} = {}
+
+@(private)
+_renderer_init :: proc(config: Config) {
+ renderer.bg_col = Color{0.2, 0.2, 0.2, 1}
+
+ renderer.projection = linalg.matrix_ortho3d(f32(0), 800, 800, 0, 0, 1)
+ renderer.view = linalg.identity(Mat4)
+
+ renderer.backend = config.renderer_backend
+
+ switch config.renderer_backend{
+ case .OpenGL: gl_init()
+ }
+
+ white_1x1_data := []u8{255, 255, 255}
+ renderer.white_1x1 = create_texture(white_1x1_data, {1, 1}, 3)
+
+ renderer.vt.init_screen(config.screen_size)
+}
+
+@(private)
+_renderer_deinit :: proc() {
+ destroy_texture(renderer.white_1x1)
+
+ switch renderer.backend {
+ case .OpenGL: gl_deinit()
+ }
+}
+
+flush_batch :: proc(draw_call: ^Draw_Call) {
+ renderer.vt.draw(draw_call^)
+ renderer._draw_call_counter += 1
+}
+
+new_batch :: proc(
+ tex: Texture_Handle,
+ vertex_mode: Vertex_Mode,
+ indexed: bool,
+) {
+ renderer.draw_call.tex = tex
+ renderer.draw_call.vertex_mode = vertex_mode
+ renderer.draw_call.indexed = indexed
+ renderer.draw_call.projection = renderer.projection
+ renderer.draw_call.view = renderer.view
+
+ clear(&renderer.draw_call.vertices)
+ clear(&renderer.draw_call.indices)
+}
+
+@(private="file")
+_add_vertex :: #force_inline proc(v: Vertex) {
+ append(&renderer.draw_call.vertices, v)
+}
+
+@(private="file")
+_add_index :: #force_inline proc(i: u16, start: Index) {
+ append(&renderer.draw_call.indices, start + i)
+}
+
+can_flush :: proc() -> bool {
+ return renderer.draw_call.vertex_mode != .None &&
+ len(renderer.draw_call.vertices) != 0 &&
+ len(renderer.draw_call.indices) != 0
+}
+
+try_batch_calls :: proc(
+ tex: Texture_Handle,
+ vertex_mode: Vertex_Mode,
+ indexed: bool,
+) {
+ cant_flush := !can_flush()
+ if cant_flush {
+ new_batch(tex, vertex_mode, indexed)
+ return
+ }
+
+ can_batch := tex == renderer.draw_call.tex &&
+ vertex_mode == renderer.draw_call.vertex_mode &&
+ indexed == renderer.draw_call.indexed
+ if !can_batch {
+ flush_batch(&renderer.draw_call)
+ new_batch(tex, vertex_mode, indexed)
+ }
+}
+
+create_texture_from_image :: #force_inline proc(img: ^image.Image) -> Texture {
+ return create_texture(
+ img.pixels.buf[:],
+ {i32(img.width), i32(img.height)},
+ i32(img.channels),
+ )
+}
+
+create_texture :: proc(data: []u8, size: Vec2i, channels: i32) -> Texture {
+ texture := Texture{
+ size = size,
+ }
+ renderer.vt.init_texture(&texture, data, channels)
+ return texture
+}
+
+destroy_texture :: proc(texture: Texture) {
+ renderer.vt.destroy_texture(texture.handle)
+}
+
+draw_line :: proc(
+ start: Vec2,
+ end: Vec2,
+ depth: f32 = 0,
+ color := Color{1, 1, 1, 1},
+) {
+ try_batch_calls(renderer.white_1x1.handle, .Lines, true)
+
+ reserve(&renderer.draw_call.vertices, len(renderer.draw_call.vertices) + 2)
+ reserve(&renderer.draw_call.indices, len(renderer.draw_call.indices) + 2)
+
+ start_idx := Index(len(renderer.draw_call.vertices))
+
+ _add_vertex(Vertex{{start.x, start.y, depth}, {0.5, 0.5}, color})
+ _add_vertex(Vertex{{end.x, end.y, depth}, {0.5, 0.5}, color})
+
+ _add_index(start_idx, 0)
+ _add_index(start_idx, 1)
+}
+
+draw_rect :: proc(
+ pos: Vec2,
+ size: Vec2,
+ depth: f32 = 0,
+ color := Color{1, 1, 1, 1},
+ tex := renderer.white_1x1,
+ lines := false,
+) {
+ try_batch_calls(tex.handle, .Triangles if !lines else .Lines, true)
+
+ depth := depth
+
+ if depth < -1 || depth > 1 {
+ log.warnf(
+ "Depth is out of range (%v). It will be clamped to -1..1.",
+ depth
+ )
+ depth = math.clamp(depth, -1, 1)
+ }
+
+ pos := linalg.round(pos)
+
+ tl := Vertex{{pos.x, pos.y, depth}, {0, 0}, color}
+ tr := Vertex{{pos.x + size.x, pos.y, depth}, {1, 0}, color}
+ bl := Vertex{{pos.x, pos.y + size.y, depth}, {0, 1}, color}
+ br := Vertex{{pos.x + size.x, pos.y + size.y, depth}, {1, 1}, color}
+
+ start := Index(len(renderer.draw_call.vertices))
+
+ reserve(&renderer.draw_call.vertices, len(renderer.draw_call.vertices) + 4)
+ _add_vertex(tl)
+ _add_vertex(tr)
+ _add_vertex(bl)
+ _add_vertex(br)
+
+
+ if lines {
+ reserve(&renderer.draw_call.indices, len(renderer.draw_call.indices) + 8)
+
+ _add_index(start, 0)
+ _add_index(start, 1)
+ _add_index(start, 1)
+ _add_index(start, 3)
+ _add_index(start, 3)
+ _add_index(start, 2)
+ _add_index(start, 2)
+ _add_index(start, 0)
+ } else {
+ reserve(&renderer.draw_call.indices, len(renderer.draw_call.indices) + 6)
+
+ _add_index(start, 0)
+ _add_index(start, 1)
+ _add_index(start, 2)
+ _add_index(start, 2)
+ _add_index(start, 1)
+ _add_index(start, 3)
+ }
+}
+
+draw_tex :: proc(
+ tex: Texture,
+ pos: Vec2,
+ depth: f32 = 0,
+ scale := Vec2{1, 1},
+ offset := Vec2{0, 0},
+ color := Color{1, 1, 1, 1}
+) {
+ draw_rect(
+ pos = pos - offset,
+ size = Vec2{f32(tex.size.x), f32(tex.size.y)} * scale,
+ depth = depth,
+ tex = tex,
+ color = color,
+ )
+}
+
+draw_tile :: proc(
+ tex: Texture,
+ pos: Vec2,
+ rect: Rect,
+ depth: f32 = 0,
+ color := Color{1, 1, 1, 1}
+) {
+ pos := linalg.round(pos)
+
+ tex_size := Vec2{f32(tex.size.x), f32(tex.size.y)}
+
+ uv_start := rect.start / tex_size
+ uv_end := (rect.start + rect.size) / tex_size
+
+ size := rect.size
+ tl := Vertex{{pos.x, pos.y, depth}, {uv_start.x, uv_start.y}, color}
+ tr := Vertex{{pos.x + size.x, pos.y, depth}, {uv_end.x, uv_start.y}, color}
+ bl := Vertex{{pos.x, pos.y + size.y, depth}, {uv_start.x, uv_end.y}, color}
+ br := Vertex{{pos.x + size.x, pos.y + size.y, depth}, {uv_end.x, uv_end.y}, color}
+
+ try_batch_calls(tex.handle, .Triangles, true)
+
+ reserve(&renderer.draw_call.indices, len(renderer.draw_call.indices) + 6)
+ reserve(&renderer.draw_call.vertices, len(renderer.draw_call.vertices) + 4)
+
+ start := Index(len(renderer.draw_call.vertices))
+
+ _add_vertex(tl)
+ _add_vertex(tr)
+ _add_vertex(bl)
+ _add_vertex(br)
+
+ _add_index(start, 0)
+ _add_index(start, 1)
+ _add_index(start, 2)
+ _add_index(start, 2)
+ _add_index(start, 1)
+ _add_index(start, 3)
+}
+
+draw_tex_ex :: proc(
+ tex: Texture,
+ pos: Vec2,
+ depth: f32 = 0,
+ rot: f32 = 0,
+ scale := Vec2{1, 1},
+ offset := Vec2{0, 0},
+ shear := Vec2{0, 0},
+ rect: Maybe(Rect) = nil,
+ color := Color{1, 1, 1, 1}
+) {
+ tex_size := Vec2{f32(tex.size.x), f32(tex.size.y)}
+ rect := rect.? or_else Rect{{0, 0}, tex_size}
+
+ pos := linalg.round(pos)
+
+ pos_m: Mat4 = linalg.matrix4_translate(Vec3{pos.x, pos.y, 0})
+ rotation_m: Mat4 = linalg.matrix4_rotate(rot, Vec3{0, 0, 1})
+ scale_m: Mat4 = linalg.matrix4_scale(Vec3{scale.x, scale.y, 0})
+ offset_m: Mat4 = linalg.matrix4_translate(-Vec3{offset.x, offset.y, 0})
+ shear_m: Mat4 = linalg.identity(Mat4)
+ shear_m[1,0] = shear.y
+ shear_m[0,1] = shear.x
+
+ model := linalg.transpose(pos_m * rotation_m * scale_m * shear_m * offset_m)
+
+ size := rect.size
+
+ tl_pos := Vec4{0, 0, 0, 1} * model
+ tr_pos := Vec4{size.x, 0, 0, 1} * model
+ bl_pos := Vec4{0, size.y, 0, 1} * model
+ br_pos := Vec4{size.x, size.y, 0, 1} * model
+
+ uv_start := rect.start / tex_size
+ uv_end := (rect.start + rect.size) / tex_size
+
+ tl := Vertex{{tl_pos.x, tl_pos.y, depth}, {uv_start.x, uv_start.y}, color}
+ tr := Vertex{{tr_pos.x, tr_pos.y, depth}, {uv_end.x, uv_start.y}, color}
+ bl := Vertex{{bl_pos.x, bl_pos.y, depth}, {uv_start.x, uv_end.y}, color}
+ br := Vertex{{br_pos.x, br_pos.y, depth}, {uv_end.x, uv_end.y}, color}
+
+ try_batch_calls(tex.handle, .Triangles, true)
+
+ reserve(&renderer.draw_call.indices, len(renderer.draw_call.indices) + 6)
+ reserve(&renderer.draw_call.vertices, len(renderer.draw_call.vertices) + 4)
+
+ start := Index(len(renderer.draw_call.vertices))
+
+ _add_vertex(tl)
+ _add_vertex(tr)
+ _add_vertex(bl)
+ _add_vertex(br)
+
+ _add_index(start, 0)
+ _add_index(start, 1)
+ _add_index(start, 2)
+ _add_index(start, 2)
+ _add_index(start, 1)
+ _add_index(start, 3)
+}
diff --git a/src/fw/shader.frag b/src/fw/shader.frag
new file mode 100644
index 0000000..fdc8796
--- /dev/null
+++ b/src/fw/shader.frag
@@ -0,0 +1,16 @@
+#version 430 core
+
+in vec2 f_uv;
+in vec4 f_col;
+
+out vec4 final_color;
+
+uniform sampler2D tex0;
+
+void main() {
+ vec4 color = texture(tex0, f_uv) * f_col;
+ if (color.a <= 0.5) {
+ discard;
+ }
+ final_color = color;
+}
diff --git a/src/fw/shader.vert b/src/fw/shader.vert
new file mode 100644
index 0000000..6bf4e24
--- /dev/null
+++ b/src/fw/shader.vert
@@ -0,0 +1,18 @@
+#version 430 core
+
+layout (location = 0) in vec3 v_pos;
+layout (location = 1) in vec2 v_uv;
+layout (location = 2) in vec4 v_col;
+
+out vec2 f_uv;
+out vec4 f_col;
+
+uniform mat4 projection;
+uniform mat4 view;
+
+void main() {
+ gl_Position = projection * view * vec4(v_pos, 1.0);
+
+ f_uv = v_uv;
+ f_col = v_col;
+}
diff --git a/src/input.odin b/src/input.odin
index 8326564..ee90fcd 100644
--- a/src/input.odin
+++ b/src/input.odin
@@ -1,67 +1,25 @@
package demonchime
-import rl "vendor:raylib"
-
-KeyboardInput :: union {
- rl.KeyboardKey,
- rl.MouseButton,
-}
-
-ControllerInput :: union {
-}
-
-Keybind :: struct {
- input: KeyboardInput,
- pressed: bool,
- just_pressed: bool,
-}
+import fw "fw"
actions: struct {
- move_left: Keybind,
- move_right: Keybind,
- jump: Keybind,
- dash: Keybind,
- shoot: Keybind,
- toggle_debug_mode: Keybind,
+ move_left: fw.Keybind,
+ move_right: fw.Keybind,
+ jump: fw.Keybind,
+ dash: fw.Keybind,
+ shoot: fw.Keybind,
+ toggle_debug_mode: fw.Keybind,
+ toggle_fullscreen: fw.Keybind,
+ exit: fw.Keybind,
}
init_keybinds :: proc() {
actions.move_left.input = .A
actions.move_right.input = .D
- actions.jump.input = .SPACE
- actions.dash.input = .LEFT_SHIFT
- actions.shoot.input = rl.MouseButton.LEFT
- actions.toggle_debug_mode.input = .GRAVE
-}
-
-is_keybind_down :: proc(keybind: Keybind) -> bool {
- switch val in keybind.input {
- case rl.KeyboardKey:
- return rl.IsKeyDown(val)
- case rl.MouseButton:
- return rl.IsMouseButtonDown(val)
- }
-
- assert(false)
- return false
-}
-
-is_keybind_just_down :: proc(keybind: Keybind) -> bool {
- switch val in keybind.input {
- case rl.KeyboardKey:
- return rl.IsKeyPressed(val)
- case rl.MouseButton:
- return rl.IsMouseButtonPressed(val)
- }
-
- assert(false)
- return false
-}
-
-get_mouse_pos :: proc() -> (mouse_pos: Vec2) {
- mouse_pos = Vec2{f32(rl.GetMouseX()), f32(rl.GetMouseY())}
- mouse_pos /= Vec2{f32(rl.GetScreenWidth()), f32(rl.GetScreenHeight())}
- mouse_pos *= SCREEN_SIZE
- mouse_pos += state.camera.target
- return
+ actions.jump.input = .Space
+ actions.dash.input = .Left_Shift
+ actions.shoot.input = fw.Mouse_Button.Left
+ actions.toggle_debug_mode.input = .T
+ actions.toggle_fullscreen.input = .F11
+ actions.exit.input = .Escape
}
diff --git a/src/main.odin b/src/main.odin
index a0c2fcb..20ea221 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -6,30 +6,32 @@ import "core:c"
import "core:c/libc"
import "core:fmt"
import "core:log"
-import "core:mem"
import "core:math"
import "core:math/linalg"
-
-import rl "vendor:raylib"
+import "core:mem"
import "phys"
+import "fw"
-Vec2 :: [2]f32
-
-Rect :: struct {
- start: Vec2,
- size: Vec2,
-}
+Vec2 :: fw.Vec2
+Vec2i :: fw.Vec2i
+Color :: fw.Color
+Rect :: fw.Rect
ROOM_FADE_SIZE :: 8
FIXED_UPDATE_RATE :: 1.0/60
+SCREEN_WIDTH :: 256
+SCREEN_HEIGHT :: 256
+SCREEN_SIZE :: Vec2{SCREEN_WIDTH, SCREEN_HEIGHT}
+SCREEN_SIZE_INT :: Vec2i{SCREEN_WIDTH, SCREEN_HEIGHT}
+
state: struct {
debug_mode: bool,
camera_target: Vec2,
last_fixed_update: f64,
- camera: rl.Camera2D,
+ // camera: rl.Camera2D,
prop_list: Entity_List(Prop),
wiggle_prop_list: Entity_List(Wiggle_Prop),
platform_list: Entity_List(Platform),
@@ -39,46 +41,33 @@ state: struct {
logger: log.Logger
-raylib_log :: proc "c" (
- msg_type: rl.TraceLogLevel,
- fmt: cstring,
- args: ^c.va_list,
-) {
- context = runtime.default_context()
- context.logger = logger
-
- msg_bytes: [1028]u8
- libc.vsnprintf(raw_data(msg_bytes[:]), 1028, fmt, args)
-
- msg := string(msg_bytes[:])
-
- #partial switch msg_type {
- case .DEBUG: log.debug(msg)
- case .INFO: log.info(msg)
- case .WARNING: log.warn(msg)
- case .ERROR: log.error(msg)
- case .FATAL: log.fatal(msg)
- }
-}
-
init :: proc() {
- state.camera.zoom = 1
+ fw.init({
+ win_name = "Demonchime",
+ win_size = SCREEN_SIZE_INT * 3,
+ screen_size = SCREEN_SIZE_INT,
+ renderer_backend = .OpenGL,
+ })
init_keybinds()
- init_draw()
init_player()
open_room(.Carrabassett0)
}
frame :: proc() {
- if is_keybind_just_down(actions.toggle_debug_mode) {
+ if fw.is_keybind_just_down(actions.toggle_debug_mode) {
state.debug_mode = !state.debug_mode
}
- dt := rl.GetFrameTime()
+ if fw.is_keybind_just_down(actions.toggle_fullscreen) {
+ // rl.ToggleBorderlessWindowed()
+ // rl.ToggleFullscreen()
+ }
- if rl.GetTime() - state.last_fixed_update > FIXED_UPDATE_RATE {
- state.last_fixed_update = rl.GetTime()
+ dt := f32(fw.get_delta_time())
+
+ if fw.get_time() - state.last_fixed_update > FIXED_UPDATE_RATE {
+ state.last_fixed_update = fw.get_time()
for cb in fixed_update_callbacks {
cb(FIXED_UPDATE_RATE)
}
@@ -88,24 +77,21 @@ frame :: proc() {
cb(dt)
}
- state.camera.target = dt_lerp(
- state.camera.target,
- state.camera_target,
- CAMERA_ACCEL,
- )
-
- draw_new_frame()
-
- cam := state.camera
- cam.target = linalg.round(cam.target)
- rl.BeginMode2D(cam)
+ // state.camera.target = dt_lerp(
+ // state.camera.target,
+ // state.camera_target,
+ // CAMERA_ACCEL,
+ // )
- renderer.tint = get_room(current_room.id).background_color
- draw_rect({
+ // cam := state.camera
+ // cam.target = linalg.round(cam.target)
+ // rl.BeginMode2D(cam)
+
+ fw.draw_rect(
{0, 0},
{f32(current_room.width), f32(current_room.height)},
- })
- renderer.tint = {1, 1, 1, 1}
+ color = get_room(current_room.id).background_color,
+ )
for cb in draw_callbacks {
cb()
@@ -113,66 +99,63 @@ frame :: proc() {
draw_room(current_room.id)
- rl.DrawRectangleGradientH(
- 0,
- 0,
- ROOM_FADE_SIZE,
- current_room.height,
- rl.BLACK,
- rl.BLANK,
- )
- rl.DrawRectangleGradientH(
- current_room.width - ROOM_FADE_SIZE,
- 0,
- ROOM_FADE_SIZE,
- current_room.height,
- rl.BLANK,
- rl.BLACK,
- )
- rl.DrawRectangleGradientV(
- 0,
- 0,
- current_room.width,
- ROOM_FADE_SIZE,
- rl.BLACK,
- rl.BLANK,
- )
- rl.DrawRectangleGradientV(
- 0,
- current_room.height - ROOM_FADE_SIZE,
- current_room.width,
- ROOM_FADE_SIZE,
- rl.BLANK,
- rl.BLACK,
- )
+ // rl.DrawRectangleGradientH(
+ // 0,
+ // 0,
+ // ROOM_FADE_SIZE,
+ // current_room.height,
+ // rl.BLACK,
+ // rl.BLANK,
+ // )
+ // rl.DrawRectangleGradientH(
+ // current_room.width - ROOM_FADE_SIZE,
+ // 0,
+ // ROOM_FADE_SIZE,
+ // current_room.height,
+ // rl.BLANK,
+ // rl.BLACK,
+ // )
+ // rl.DrawRectangleGradientV(
+ // 0,
+ // 0,
+ // current_room.width,
+ // ROOM_FADE_SIZE,
+ // rl.BLACK,
+ // rl.BLANK,
+ // )
+ // rl.DrawRectangleGradientV(
+ // 0,
+ // current_room.height - ROOM_FADE_SIZE,
+ // current_room.width,
+ // ROOM_FADE_SIZE,
+ // rl.BLANK,
+ // rl.BLACK,
+ // )
if state.debug_mode {
// Draw all collisions
body_it: int
- renderer.tint = {1, 0.25, 0.5, 0.25}
+ color := Color{1, 0.25, 0.5, 0.25}
for body in phys.iterate_bodies(&body_it) {
rect := phys.get_rect(body)
rect.start += phys.get_position(body)
- draw_linerect(transmute(Rect)rect)
- draw_rect(transmute(Rect)rect)
+ fw.draw_rect(rect.start, rect.size, color = color, lines = true)
+ fw.draw_rect(rect.start, rect.size, color = color)
}
- renderer.tint = {1, 1, 1, 1}
- }
-
- rl.EndMode2D()
-
- fps_text := fmt.caprintf(
- "FPS: %v",
- rl.GetFPS(),
- allocator = context.temp_allocator,
- )
- rl.DrawText(fps_text, 5, 5, 8, rl.GREEN)
-
- if state.debug_mode {
- rl.DrawText("Debug Mode", 5, 5 + 8, 8, rl.YELLOW)
}
- draw_end_frame()
+ // rl.EndMode2D()
+ //
+ // fps_text := fmt.caprintf(
+ // "FPS: %v",
+ // rl.GetFPS(),
+ // allocator = context.temp_allocator,
+ // )
+ // rl.DrawText(fps_text, 5, 5, 8, rl.GREEN)
+ //
+ // if state.debug_mode {
+ // rl.DrawText("Debug Mode", 5, 5 + 8, 8, rl.YELLOW)
+ // }
}
cleanup :: proc() {
@@ -186,6 +169,8 @@ cleanup :: proc() {
delete_entity_list(state.rope_list)
phys.destroy_world()
+
+ fw.deinit()
}
main :: proc() {
@@ -222,18 +207,14 @@ main :: proc() {
context.logger = logger
defer log.destroy_console_logger(logger)
- rl.SetTraceLogCallback(raylib_log)
-
- rl.InitWindow(SCREEN_WIDTH * 3, SCREEN_HEIGHT * 3, "Demonchime")
- rl.SetWindowState({.WINDOW_RESIZABLE})
-
- rl.SetTargetFPS(240)
-
init()
- for !rl.WindowShouldClose() {
+ for fw.next_frame() {
frame()
- free_all(context.temp_allocator)
+
+ if fw.is_keybind_just_down(actions.exit) {
+ break
+ }
}
cleanup()
diff --git a/src/math.odin b/src/math.odin
index 0cd2a27..131da63 100644
--- a/src/math.odin
+++ b/src/math.odin
@@ -3,7 +3,7 @@ package demonchime
import "core:math"
import "core:math/linalg"
-import rl "vendor:raylib"
+import "fw"
dt_lerp :: proc {
dt_lerp_f32,
@@ -11,7 +11,7 @@ dt_lerp :: proc {
}
dt_lerp_f32 :: proc(a: f32, b: f32, t: f32) -> f32 {
- dt := rl.GetFrameTime()
+ dt := f32(fw.get_delta_time())
return math.lerp(b, a, math.pow(0.5, dt * t))
}
diff --git a/src/phys/world.odin b/src/phys/world.odin
index 70309b5..5207622 100644
--- a/src/phys/world.odin
+++ b/src/phys/world.odin
@@ -4,7 +4,7 @@ import "core:log"
import "core:math"
import "core:math/linalg"
-import rl "vendor:raylib"
+import "../fw"
BIN_COUNT :: 2056
BIN_SIZE :: 64
@@ -191,7 +191,7 @@ get_colliding_bodies :: proc(
}
update_body :: proc(h: Body_Handle) {
- dt := rl.GetFrameTime()
+ dt := f32(fw.get_delta_time())
b := _get_body(h)
diff --git a/src/platform.odin b/src/platform.odin
index a974811..38ce950 100644
--- a/src/platform.odin
+++ b/src/platform.odin
@@ -1,5 +1,6 @@
package demonchime
+import "fw"
import "phys"
Platform :: struct {
@@ -8,18 +9,17 @@ Platform :: struct {
}
make_platform :: proc(rect: Rect) -> (Entity_Handle, ^Platform) {
- body := phys.make_body(transmute(phys.Rect)rect)
- return make_entity(&state.platform_list, Platform{body = body})
+ handle := phys.make_body(transmute(phys.Rect)rect)
+ return make_entity(&state.platform_list, Platform{body = handle})
}
draw_platforms :: proc() {
iter := iter_entity_list(state.platform_list)
- renderer.tint = {1, 0, 0, 0.25}
+ color := Color{1, 0, 0, 0.25}
for p in entity_list_iter(&iter) {
rect := phys.get_rect(p.body)
- draw_rect(cast(Rect)rect)
+ fw.draw_rect(rect.start, rect.size, color = color)
}
- renderer.tint = {1, 1, 1, 1}
}
clear_platforms :: proc() {
diff --git a/src/player.odin b/src/player.odin
index c87d2a6..5b0dd01 100644
--- a/src/player.odin
+++ b/src/player.odin
@@ -4,9 +4,8 @@ import "core:math"
import "core:math/linalg"
import "core:log"
-import rl "vendor:raylib"
-
import "phys"
+import "fw"
Player_State :: enum {
Default,
@@ -72,10 +71,10 @@ _get_input_dir :: proc() -> f32 {
input: f32
- if is_keybind_down(actions.move_left) {
+ if fw.is_keybind_down(actions.move_left) {
input -= 1
}
- if is_keybind_down(actions.move_right) {
+ if fw.is_keybind_down(actions.move_right) {
input += 1
}
@@ -92,12 +91,12 @@ _default_state :: proc(dt: f32) {
set_sprite_active_tag(&player.sprite, "idle")
}
- if is_keybind_just_down(actions.jump) {
+ if fw.is_keybind_just_down(actions.jump) {
player.jump_buffer = PLAYER_JUMP_BUFFERING
}
if player.owns_dash &&
- is_keybind_just_down(actions.dash) &&
+ fw.is_keybind_just_down(actions.dash) &&
player.dash_cooldown <= 0 {
_enter_dash()
return
@@ -122,9 +121,9 @@ _default_state :: proc(dt: f32) {
}
}
- rel_mouse_pos := get_mouse_pos() - pos
+ rel_mouse_pos := fw.get_mouse_pos() - pos
- if is_keybind_just_down(actions.shoot) {
+ if fw.is_keybind_just_down(actions.shoot) {
mouse_dir := linalg.normalize0(rel_mouse_pos + {0, PLAYER_GUN_HEIGHT})
bullet_pos := pos
@@ -157,7 +156,7 @@ _default_state :: proc(dt: f32) {
}
if .Down not_in collisions &&
- !is_keybind_down(actions.jump) &&
+ !fw.is_keybind_down(actions.jump) &&
vel.y < PLAYER_JUMP_RELEASE_CUT {
vel.y = PLAYER_JUMP_RELEASE_CUT
}
@@ -257,8 +256,8 @@ _change_rooms :: proc() {
}
new_cam_pos := _get_camera_target_pos()
- state.camera.target += diff
- state.camera_target += diff
+ // state.camera.target += diff
+ // state.camera_target += diff
}
}
@@ -274,11 +273,8 @@ update_player :: proc(dt: f32) {
update_sprite(&player.sprite, dt)
- mouse_dir := linalg.normalize0(get_mouse_pos() - player.gun.sprite.pos)
- player.gun.sprite.rotation = math.atan2(
- mouse_dir.y,
- mouse_dir.x,
- ) * math.DEG_PER_RAD
+ mouse_dir := linalg.normalize0(fw.get_mouse_pos() - player.gun.sprite.pos)
+ player.gun.sprite.rotation = math.atan2(mouse_dir.y, mouse_dir.x)
player.gun.sprite.pos = pos - Vec2{0, PLAYER_GUN_HEIGHT}
player.gun.sprite.pos += -mouse_dir * player.gun.kickback
diff --git a/src/prop.odin b/src/prop.odin
index 34d4559..35e16e8 100644
--- a/src/prop.odin
+++ b/src/prop.odin
@@ -3,8 +3,7 @@ package demonchime
import "core:math/linalg"
import "core:log"
-import rl "vendor:raylib"
-
+import "fw"
import "phys"
Prop :: struct {
@@ -22,7 +21,7 @@ draw_props :: proc() {
iter := iter_entity_list(state.prop_list)
for p in entity_list_iter(&iter) {
image := get_image(p.image_id)
- draw_texture(
+ fw.draw_tex(
image,
p.pos,
scale = p.scale,
@@ -36,8 +35,8 @@ Wiggle_Prop :: struct {
pos: Vec2,
scale: Vec2,
offset: Vec2,
- rotation: f32,
- rotation_factor: f32,
+ shear: f32,
+ shear_factor: f32,
}
make_wiggle_prop :: proc(prop: Wiggle_Prop) -> (Entity_Handle, ^Wiggle_Prop) {
@@ -52,23 +51,23 @@ update_wiggle_props :: proc(dt: f32) {
image := get_image(p.image_id)
dist := linalg.length(p.pos - player_pos)
- dist = f32(max(image.width, image.height)) - dist
+ dist = f32(max(image.size.x, image.size.y)) - dist
if dist < 0 {
dist = 0
}
- p.rotation = player_vel.x / PLAYER_SPEED * dist * p.rotation_factor
+ p.shear = player_vel.x / PLAYER_SPEED * dist * p.shear_factor
}
}
draw_wiggle_props :: proc() {
iter := iter_entity_list(state.wiggle_prop_list)
for p in entity_list_iter(&iter) {
- draw_texture_full(
+ fw.draw_tex_ex(
get_image(p.image_id),
p.pos,
- p.offset,
- p.rotation,
- p.scale,
+ offset = p.offset,
+ // rot = p.rotation,
+ shear = Vec2{-p.shear, 0},
)
}
}
@@ -95,7 +94,7 @@ object_spawner_prop :: proc(obj: Object_Resource) {
tile := tiles[tile_id]
img := get_image(tile.image)
- pos := obj.pos - Vec2{0, f32(img.height)}
+ pos := obj.pos - Vec2{0, f32(img.size.y)}
scale := Vec2{1, 1}
if obj.size.x < 0 {
scale.x = -1
@@ -114,14 +113,14 @@ object_spawner_prop :: proc(obj: Object_Resource) {
.Windchimes_0,
.Windchimes_1:
offset := linalg.round(Vec2{
- f32(img.width) * 0.5,
+ f32(img.size.x) * 0.5,
0,
})
- rotation_factor: f32 = 1
+ shear_factor: f32 = 1
#partial switch tile.image {
case .Carrabasset_Vines_0:
- rotation_factor = 0.25
+ shear_factor = 0.1
}
make_wiggle_prop(Wiggle_Prop{
@@ -129,18 +128,18 @@ object_spawner_prop :: proc(obj: Object_Resource) {
pos = pos + offset,
scale = scale,
offset = offset,
- rotation_factor = -rotation_factor,
+ shear_factor = -shear_factor,
})
case .Carrabassett_Small_Bush_0, .Carrabassett_Big_Bush_0:
offset := linalg.round(Vec2{
- f32(img.width) * 0.5,
- f32(img.height),
+ f32(img.size.x) * 0.5,
+ f32(img.size.y),
})
- rotation_factor: f32 = 1
+ shear_factor: f32 = 0.01
#partial switch tile.image {
case .Carrabassett_Big_Bush_0:
- rotation_factor = 0.25
+ shear_factor = 0.01
}
make_wiggle_prop(Wiggle_Prop{
@@ -148,7 +147,7 @@ object_spawner_prop :: proc(obj: Object_Resource) {
pos = pos + offset,
scale = scale,
offset = offset,
- rotation_factor = rotation_factor,
+ shear_factor = shear_factor,
})
case:
make_prop(Prop{
diff --git a/src/resources.odin b/src/resources.odin
index 1bd567e..22fed57 100644
--- a/src/resources.odin
+++ b/src/resources.odin
@@ -1,8 +1,10 @@
package demonchime
+import "core:image"
+import "core:image/qoi"
import "core:log"
-import rl "vendor:raylib"
+import "fw"
Tiled_Property :: union {
string,
@@ -12,7 +14,7 @@ Tiled_Property :: union {
}
Image_Resource :: struct {
- texture: rl.Texture2D,
+ texture: fw.Texture,
anim: Animation_Id,
data: []u8,
}
@@ -73,21 +75,15 @@ Room_Position_Resource :: struct {
height: i32,
}
-get_image :: proc(id: Image_Id) -> rl.Texture2D {
+get_image :: proc(id: Image_Id) -> fw.Texture {
img_res := &images[id]
- if !rl.IsTextureValid(img_res.texture) {
- rl_img := rl.LoadImageFromMemory(
- ".qoi",
- raw_data(img_res.data),
- i32(len(img_res.data)),
- )
- if !rl.IsImageValid(rl_img) {
- log.warnf("Could not load asset %v", id)
- }
+ if img_res.texture.handle == 0 {
+ img, qoi_err := qoi.load_from_bytes(img_res.data)
+ defer image.destroy(img)
- img_res.texture = rl.LoadTextureFromImage(rl_img)
- rl.UnloadImage(rl_img)
+ img_res.texture = fw.create_texture_from_image(img)
+ log.debug(img_res.texture.size)
}
return img_res.texture
diff --git a/src/rope.odin b/src/rope.odin
index b321dab..7e2cbe1 100644
--- a/src/rope.odin
+++ b/src/rope.odin
@@ -4,7 +4,7 @@ import "core:log"
import "core:math"
import "core:math/linalg"
-import rl "vendor:raylib"
+import "fw"
Rope :: struct {
handle: Entity_Handle,
@@ -25,10 +25,10 @@ draw_ropes :: proc() {
for i in 0..<len(rope.verlet.nodes) - 1 {
cur := rope.verlet.nodes[i]
nex := rope.verlet.nodes[i + 1]
- rl.DrawLineV(
+ fw.draw_line(
linalg.round(cur.pos),
linalg.round(nex.pos),
- rl.Color{76, 62, 36, 255},
+ color = fw.rgba8(76, 62, 36),
)
}
@@ -36,14 +36,14 @@ draw_ropes :: proc() {
b := rope.verlet.nodes[len(rope.verlet.nodes) - 2]
dir := b.pos - a.pos
- rotation := math.atan2(dir.y, dir.x) * math.DEG_PER_RAD + 90
+ rotation := math.atan2(dir.y, dir.x) + math.PI / 2
img := get_image(rope.hanging_id)
- draw_texture(
+ fw.draw_tex_ex(
img,
a.pos,
- offset = linalg.round(Vec2{f32(img.width) * 0.5, 0}),
- rotation = rotation,
+ offset = linalg.round(Vec2{f32(img.size.x) * 0.5, 0}),
+ rot = rotation,
)
}
}
diff --git a/src/sprite.odin b/src/sprite.odin
index 09b68ae..e93a3b1 100644
--- a/src/sprite.odin
+++ b/src/sprite.odin
@@ -3,10 +3,10 @@ package demonchime
import "core:log"
import "core:math/linalg"
-import rl "vendor:raylib"
+import "fw"
Sprite :: struct {
- image: rl.Texture2D,
+ image: fw.Texture,
anim_id: Animation_Id,
current_tag: Tag_Resource,
frame_time: f32,
@@ -36,8 +36,8 @@ init_sprite :: proc(
anim := animations[sprite.anim_id]
- sprite.width = i32(f32(sprite.image.width) / f32(anim.frame_count))
- sprite.height = i32(sprite.image.height)
+ sprite.width = i32(f32(sprite.image.size.x) / f32(anim.frame_count))
+ sprite.height = i32(sprite.image.size.y)
sprite.scale = Vec2{1, 1}
@@ -87,12 +87,14 @@ draw_sprite :: proc(sprite: Sprite) {
{f32(sprite.width), f32(sprite.height)},
}
- draw_texture(
+ log.debug(sprite.width, sprite.height)
+
+ fw.draw_tex_ex(
sprite.image,
- rect,
sprite.pos,
- sprite.offset,
- sprite.rotation,
- sprite.scale,
+ rect = rect,
+ offset = sprite.offset,
+ rot = sprite.rotation,
+ scale = sprite.scale,
)
}
diff --git a/src/tail.odin b/src/tail.odin
index 2184444..ca2f32e 100644
--- a/src/tail.odin
+++ b/src/tail.odin
@@ -3,6 +3,8 @@ package demonchime
import "core:math"
import "core:math/linalg"
+import "fw"
+
Tail :: struct($N: int) {
points: [N]Vec2,
point_max_dist: f32,
@@ -29,12 +31,15 @@ set_tail_position :: proc(tail: ^Tail($N), pos: Vec2, dt: f32) {
draw_tail :: proc(tail: Tail($N)) {
for point, i in tail.points {
- renderer.tint = linalg.lerp(
- tail.color_start,
- tail.color_end,
- f32(i)/len(tail.points),
+ size := Vec2{tail.point_rad*2, tail.point_rad*2}
+ fw.draw_rect(
+ point - size * 0.5,
+ size,
+ color = linalg.lerp(
+ tail.color_start,
+ tail.color_end,
+ f32(i)/len(tail.points),
+ ),
)
- draw_circle(point, tail.point_rad)
}
- renderer.tint = {1, 1, 1, 1}
}
diff --git a/src/upgrade_pickup.odin b/src/upgrade_pickup.odin
index 4cc5240..1b066d1 100644
--- a/src/upgrade_pickup.odin
+++ b/src/upgrade_pickup.odin
@@ -3,6 +3,7 @@ package demonchime
import "core:math/linalg"
import "core:log"
+import "fw"
import "phys"
Upgrade_Type :: enum {
@@ -34,10 +35,10 @@ draw_upgrade :: proc() {
tex := get_image(upgrade.image_id)
- draw_texture(
+ fw.draw_tex(
tex,
upgrade.pos,
- offset = linalg.round(Vec2{f32(tex.width), f32(tex.height)} * 0.5)
+ offset = linalg.round(Vec2{f32(tex.size.x), f32(tex.size.y)} * 0.5)
)
}
diff --git a/src/verlet.odin b/src/verlet.odin
index 7373630..0336bef 100644
--- a/src/verlet.odin
+++ b/src/verlet.odin
@@ -3,8 +3,7 @@ package demonchime
import "core:math"
import "core:math/linalg"
-import rl "vendor:raylib"
-
+import "fw"
import "phys"
VERLET_STEPS :: 8
@@ -44,7 +43,6 @@ update_verlet_node :: proc(node: ^Verlet_Node) {
if player_dist < VERLET_MIN_DIST_TO_PLAYER {
dir := linalg.normalize(node.pos - player_pos)
node.accel += dir * 1000
- // node.pos = player_pos + dir * VERLET_MIN_DIST_TO_PLAYER
}
prev_pos := node.pos
diff --git a/src/world.odin b/src/world.odin
index 9456534..d333a44 100644
--- a/src/world.odin
+++ b/src/world.odin
@@ -2,7 +2,7 @@ package demonchime
import "core:log"
-import rl "vendor:raylib"
+import "fw"
Object_Spawner :: proc(Object_Resource)
Room_Change_Callback :: proc(Room_Id)
@@ -100,23 +100,13 @@ open_room :: proc(id: Room_Id) -> bool {
draw_room :: proc(id: Room_Id) {
draw_tile :: proc(x: i32, y: i32, tile_id: u32) {
tile := tiles[tile_id]
- rl.DrawTexturePro(
+ fw.draw_tile(
get_image(tile.image),
- rl.Rectangle {
- x = f32(tile.rect.start.x),
- y = f32(tile.rect.start.y),
- width = f32(tile.rect.size.x),
- height = f32(tile.rect.size.y),
+ Vec2{f32(x), f32(y)},
+ Rect{
+ {f32(tile.rect.start.x), f32(tile.rect.start.y)},
+ {f32(tile.rect.size.x), f32(tile.rect.size.y)},
},
- rl.Rectangle {
- x = f32(x),
- y = f32(y),
- width = f32(tile.rect.size.x),
- height = f32(tile.rect.size.y),
- },
- {0, 0},
- 0,
- rl.WHITE,
)
}