diff --git a/src/staembed.c b/src/staembed.c index 186c2803..2f493812 100644 --- a/src/staembed.c +++ b/src/staembed.c @@ -1,6908 +1 @@ #include "tophat.h" -const char *th_em_modulesrc[] = { -"\n" -"import (\n" -"\t\"th.um\"\n" -"\t\"atlas.um\"\n" -")\n" -"\n" -"//~~struct Anim\n" -"// Anim allows you to animate between individual frames of an atlas.\n" -"type Anim* = struct {\n" -"\t// the source atlas\n" -"\tatl: atlas.Atlas\n" -"\t// the first cell of the animation\n" -"\tmin: int\n" -"\t// the last cell of the animation\n" -"\tmax: int\n" -"\tfps: real32\n" -"\t// offset in time\n" -"\toffset: int\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mk\n" -"// `Anim` constructor\n" -"fn mk*(atl: atlas.Atlas, fps: int, min: int = 0, max: int = -1 /* len(atl) - 1 */, offset: int = -1 /* th.time */): Anim {\n" -"//~~\n" -"\tif !atl.i.validate() {\n" -"\t\tth.__error(\"invalid atlas image\")\n" -"\t}\n" -"\n" -"\ta := Anim{}\n" -"\n" -"\ta.atl = atl\n" -"\ta.fps = fps\n" -"\ta.min = min\n" -"\tif max == -1 {\n" -"\t\ta.max = trunc(atl.dm.x * atl.dm.y) - 1\n" -"\t} else {\n" -"\t\ta.max = max\n" -"\t}\n" -"\n" -"\tif offset == -1 {\n" -"\t\ta.offset = th.time\n" -"\t} else {\n" -"\t\ta.offset = offset\n" -"\t}\n" -"\n" -"\treturn a\n" -"}\n" -"\n" -"//~~fn Anim.animate\n" -"// Crops the base atlas to the cell that should be visible at `time`.\n" -"fn (anm: ^Anim) animate*(time: int) {\n" -"//~~\n" -"\tif anm.fps == 0 || anm.max == 0 {\n" -"\t\t\treturn\n" -"\t}\n" -"\n" -"\tn := (round(real(time-anm.offset)/round((1000.0/anm.fps))) % anm.max) + anm.min\n" -"\n" -"\tanm.atl.cropSource(anm.atl.coords(n))\n" -"}\n" -"\n" -"//~~fn Anim.framesPlayed\n" -"// Returns how many frames were played at `time`.\n" -"fn (anm: ^Anim) framesPlayed*(time: int): int {\n" -"//~~\n" -"\treturn trunc((time - anm.offset) / 1000.0 * anm.fps)\n" -"}\n" -"", -"//~~\n" -"// Module for audio loading and playback.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~opaque Sound\n" -"// Represents an instance of a playable sound. It is an opaque structure.\n" -"type Sound* = struct { _: ^struct{} }\n" -"//~~\n" -"\n" -"var pool: []^Sound\n" -"\n" -"type LoadFlag = uint32\n" -"const (\n" -"\t// Streams the audio, only saving 2 seconds into memory.\n" -"\tLoadFlagStream* = LoadFlag(1)\n" -"\t// Loads the sound in async. Use `audio.waitForLoad` to wait for the\n" -"\t// sounds to load.\n" -"\tLoadFlagAsync* = LoadFlag(4)\n" -")\n" -"\n" -"fn umth_sound_load(path: str, flags: uint32): ^struct{}\n" -"//~~fn load\n" -"// Loads a sounds at path, if there is an error, the underlying pointer\n" -"// will be `NULL` and `validate` will return false.\n" -"fn load*(path: str, flags: LoadFlag = 0): Sound {\n" -"//~~\n" -"\treturn Sound{umth_sound_load(path, flags)}\n" -"}\n" -"\n" -"//~~fn Sound.validate\n" -"// Returns `true` if `s` loaded correctly.\n" -"fn (s: ^Sound) validate*(): bool {\n" -"//~~\n" -"\treturn s._ != null\n" -"}\n" -"\n" -"fn umth_sound_copy(s: Sound): ^struct{}\n" -"//~~fn Sound.copy\n" -"// Copies the sound. This will create another sound which can be configured\n" -"// and played independently from the original sound.\n" -"fn (s: ^Sound) copy*(): Sound {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"Cannot copy invalid sound.\")\n" -"\t}\n" -"\n" -"\treturn Sound{umth_sound_copy(s^)}\n" -"}\n" -"\n" -"fn umth_sound_is_playing(s: Sound): bool\n" -"//~~fn Sound.isPlaying\n" -"// Returns true if the sound is still playing.\n" -"fn (s: ^Sound) isPlaying*(): bool {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\treturn umth_sound_is_playing(s^)\n" -"}\n" -"\n" -"fn umth_sound_play(s: Sound)\n" -"//~~fn Sound.play\n" -"// Plays the sound.\n" -"fn (s: ^Sound) play*() {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_play(s^)\n" -"}\n" -"\n" -"//~~fn Sound.start\n" -"// The start function allows you to play a single sound multiple times.\n" -"// It will create a copy and return a pointer to it, so you can controll it\n" -"// while it is playing. The returned pointer can be discarded.\n" -"fn (s: ^Sound) start*(): ^Sound {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tcpy := new(Sound)\n" -"\tcpy ^= s.copy()\n" -"\tcpy.play()\n" -"\n" -"\tpool = append(pool, cpy)\n" -"\n" -"\treturn cpy\n" -"}\n" -"\n" -"fn umth_sound_stop(s: Sound)\n" -"//~~fn Sound.stop\n" -"// Stops the sound, but keeps the progress. If you want to start from the\n" -"// begginning, use `audio.Sound.seekToFrame(0)`.\n" -"fn (s: ^Sound) stop*() {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_stop(s^)\n" -"}\n" -"\n" -"fn umth_sound_set_volume(s: Sound, vol: real32)\n" -"//~~fn Sound.setVol\n" -"// Sets the volume as a multiplier of the base volume.\n" -"fn (s: ^Sound) setVol*(vol: real32) {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_set_volume(s^, vol)\n" -"}\n" -"\n" -"fn umth_sound_set_pan(s: Sound, pan: real32)\n" -"//~~fn Sound.setPan\n" -"// Sets the pan of the sound.\n" -"fn (s: ^Sound) setPan*(pan: real32) {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_set_pan(s^, pan)\n" -"}\n" -"\n" -"fn umth_sound_set_pitch(s: Sound, pitch: real32)\n" -"//~~fn Sound.setPitch\n" -"// Sets the pitch of the sound.\n" -"fn (s: ^Sound) setPitch*(pitch: real32) {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_set_pitch(s^, pitch)\n" -"}\n" -"\n" -"fn umth_sound_set_looping(s: Sound, looping: bool)\n" -"//~~fn Sound.setLooping\n" -"// Sets whether the sound will loop upon finishing.\n" -"fn (s: ^Sound) setLooping*(looping: bool) {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_set_looping(s^, looping)\n" -"}\n" -"\n" -"fn umth_sound_seek_to_frame(s: Sound, frame: uint)\n" -"//~~fn Sound.seekToFrame\n" -"// Seeks to a specified PCM frame.\n" -"fn (s: ^Sound) seekToFrame*(frame: uint) {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_seek_to_frame(s^, frame)\n" -"}\n" -"\n" -"fn umth_sound_frame_count(s: Sound): uint\n" -"//~~fn Sound.frameCount\n" -"// Returns length of the sound in PCM frames.\n" -"fn (s: ^Sound) frameCount*(): uint {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\treturn umth_sound_frame_count(s^)\n" -"}\n" -"\n" -"fn umth_sound_length_ms(s: Sound): uint\n" -"//~~fn Sound.lengthMs\n" -"// Returns length of the sound in ms.\n" -"fn (s: ^Sound) lengthMs*(): uint {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\treturn umth_sound_length_ms(s^)\n" -"}\n" -"\n" -"fn umth_sound_set_start_time_ms(s: Sound, t: uint)\n" -"//~~fn Sound.setStartTimeMs\n" -"fn (s: ^Sound) setStartTimeMs*(t: uint) {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_set_start_time_ms(s^, t)\n" -"}\n" -"\n" -"fn umth_sound_set_stop_time_ms(s: Sound, t: uint)\n" -"//~~fn Sound.setStopTimeMs\n" -"fn (s: ^Sound) setStopTimeMs*(t: uint) {\n" -"//~~\n" -"\tif !s.validate() {\n" -"\t\tth.__error(\"invalid sound\")\n" -"\t}\n" -"\n" -"\tumth_sound_set_stop_time_ms(s^, t)\n" -"}\n" -"\n" -"// **INTERNAL**\n" -"fn __setup*() {\n" -"\tpool = []^Sound{}\n" -"}\n" -"\n" -"// **INTERNAL**\n" -"fn __cycle*() {\n" -"\tfor i:=0; i >= 0 && i < len(pool); i++ {\n" -"\t\tif !pool[i].isPlaying() {\n" -"\t\t\tpool = delete(pool, i)\n" -"\t\t\ti--\n" -"\t\t}\n" -"\t}\n" -"}\n" -"", -"//~~\n" -"// A CSV parser, which also works for similar formats. It doesn\'t support\n" -"// quotes, but you can escape characters using a backslash.\n" -"//~~\n" -"\n" -"//~~fn parse\n" -"// Parses input into a 2d string array.\n" -"fn parse*(inp: str, sep: char = \',\'): [][]str {\n" -"//~~\n" -"\tout := [][]str{}\n" -"\trow := []str{}\n" -"\tstart := 0\n" -"\tacc := \"\"\n" -"\tl := len(inp)\n" -"\tskipnext := false\n" -"\n" -"\tfor i,c in inp {\n" -"\t\tif skipnext { skipnext = false; continue }\n" -"\n" -"\t\tif c == \'\\\\\' {\n" -"\t\t\tacc += slice(inp, start, i)\n" -"\t\t\tstart = i + 1\n" -"\t\t\tskipnext = true\n" -"\t\t} else if c == \'\\r\' {\n" -"\t\t\tacc += slice(inp, start, i)\n" -"\t\t\tstart = i + 1\n" -"\t\t} else if c == \'\\n\' {\n" -"\t\t\tacc += slice(inp, start, i)\n" -"\t\t\tstart = i + 1\n" -"\n" -"\t\t\trow = append(row, acc)\n" -"\t\t\tout = append(out, row)\n" -"\n" -"\t\t\tacc = \"\"\n" -"\t\t\trow = []str{}\n" -"\n" -"\t\t} else if c == sep {\n" -"\t\t\tacc += slice(inp, start, i)\n" -"\t\t\tstart = i + 1\n" -"\n" -"\t\t\trow = append(row, acc)\n" -"\t\t\tacc = \"\"\n" -"\t\t}\n" -"\t}\n" -"\n" -"\tif start < l {\n" -"\t\trow = append(row, acc + slice(inp, start, l))\n" -"\t}\n" -"\n" -"\tif len(row) > 0 {\n" -"\t\tout = append(out, row)\n" -"\t}\n" -"\n" -"\treturn out\n" -"}\n" -"\n" -"fn escapeStr(s: str, sep: char): str {\n" -"\to := \"\"\n" -"\n" -"\tfor i,c in s {\n" -"\t\tif c == sep || c == \'\\n\' || c == \'\\\\\' {\n" -"\t\t\to += \"\\\\\"\n" -"\t\t}\n" -"\t\to += str(c)\n" -"\t}\n" -"\n" -"\treturn o\n" -"}\n" -"\n" -"//~~fn encode\n" -"// Converts 2d array to csv string.\n" -"fn encode*(inp: [][]str, sep: char = \',\'): str {\n" -"//~~\n" -"\to := \"\"\n" -"\n" -"\tfor i in inp {\n" -"\t\tfor j in inp[i] {\n" -"\t\t\to += escapeStr(inp[i][j], sep)\n" -"\t\t\tif j < len(inp[i]) - 1 { o += sep }\n" -"\t\t}\n" -"\t\to += \"\\n\"\n" -"\t}\n" -"\n" -"\treturn o\n" -"}\n" -"\n" -"", -"\n" -"import (\n" -"\t\"rect.um\"\n" -"\t\"image.um\"\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~struct Ent\n" -"// Entity is the main game object. It features drawing and collisions.\n" -"// Every entity has an image used for drawing and a rectangle used\n" -"// for collisions. It also has a transform used for transforming it\'s image\n" -"// and rectangle.\n" -"type Ent* = struct {\n" -"\t// used as a collider, used as backup when invalid image is supplied\n" -"\tr: rect.Rect\n" -"\t// used in drawing\n" -"\ti: image.Image\n" -"\t// used to transform and translate the image and rect\n" -"\tt: th.Transform\n" -"\t// used as a color of the rect and a color filter for the image\n" -"\tc: uint32\n" -"}\n" -"//~~\n" -"\n" -"//~~struct Coll\n" -"// Value returned by get coll. It contains a position where the collision\n" -"// happened and the index of the entity involved in said collision.\n" -"type Coll* = struct {\n" -"\tindex: th.uu\n" -"\tpos: th.Vf2\n" -"}\n" -"//~~\n" -"\n" -"fn umth_ent_draw(e: ^Ent)\n" -"//~~fn Ent.draw\n" -"// Draws the entity onto the screen.\n" -"fn (e: ^Ent) draw*() {\n" -"//~~\n" -"\tumth_ent_draw(e)\n" -"}\n" -"\n" -"//~~fn mk\n" -"// ent\'s constructor\n" -"fn mk*(img: image.Image = image.Image{}, t: th.Transform = th.Transform{ s: th.Vf2{1, 1} }): Ent {\n" -"//~~\n" -"\tvar e: Ent\n" -"\te.i = img\n" -"\te.t = t\n" -"\tif img.validate() {\n" -"\t\tdm := img.getDims()\n" -"\t\te.r.w = dm.x\n" -"\t\te.r.h = dm.y\n" -"\t}\n" -"\te.c = th.white\n" -"\n" -"\tif t.s.x == 0 && t.s.y == 0 {\n" -"\t\tt.s = th.Vf2{ 1, 1 }\n" -"\t}\n" -"\n" -"\treturn e\n" -"}\n" -"\n" -"fn umth_ent_getcoll(coll: ^Coll, collC: ^int, maxCount: th.uu, count: int32,\n" -"\te: ^Ent, s: ^^Ent)\n" -"//~~fn Ent.getColl\n" -"// Checks collisions of e with entities in s. Checks at max maxColl collisions.\n" -"// If s contains e, the collision won\'t be returned.\n" -"fn (e: ^Ent) getColl*(s: []^Ent, maxColls: th.uu): []Coll {\n" -"//~~\n" -"\tif len(s) == 0 {\n" -"\t\treturn []Coll{}\n" -"\t}\n" -"\n" -"\tif maxColls > len(s) {\n" -"\t\tmaxColls = len(s)\n" -"\t}\n" -"\n" -"\tif maxColls == 0 {\n" -"\t\tmaxColls = 1\n" -"\t}\n" -"\n" -"\tcolls := make([]Coll, maxColls)\n" -"\tcount := 0\n" -"\tumth_ent_getcoll(&colls[0], &count, maxColls, len(s), e, &s[0])\n" -"\n" -"\treturn slice(colls, 0, count)\n" -"}\n" -"\n" -"//~~fn Ent.animate\n" -"// Animates the entity\'s image with one of the `anim` array. Won\'t begin on\n" -"// the first frame. If you want that, use anim.Anim.\n" -"fn (e: ^Ent) animate*(fps: int, frames: ^[]image.Image, t: int) {\n" -"//~~\n" -"\tif len(frames^) == 0 {\n" -"\t\treturn\n" -"\t}\t\n" -"\n" -"\te.i = frames^[(round(real(t)/(1000/fps)) % len(frames^))]\n" -"}\n" -"\n" -"", -"import (\n" -"\t\"rect.um\"\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~opaque Image\n" -"// Represents a drawable image. It is an opaque structure.\n" -"// Images support a color filter. It is applied by multiplying the color\n" -"// of each pixel with the filter.\n" -"type Image* = struct{ _: ^struct{} }\n" -"//~~\n" -"\n" -"//~~opaque RenderTarget\n" -"// An image you can render to.\n" -"type RenderTarget* = struct { _: ^struct{} }\n" -"//~~\n" -"\n" -"fn umth_image_create_render_target(ret: ^RenderTarget, width: int, height: int, filter: int)\n" -"//~~fn createRenderTarget\n" -"// Creates a render target you can draw to, like to a window.\n" -"// Filter specifies specfifies filtering for resulting image.\n" -"// Image can be retrieved via `toImage`.\n" -"fn createRenderTarget*(size: th.Vf2, filter: int): RenderTarget {\n" -"//~~\n" -"\trt := RenderTarget{}\n" -"\tumth_image_create_render_target(&rt, trunc(size.x), trunc(size.y), filter)\n" -"\treturn rt\n" -"}\n" -"\n" -"fn umth_image_render_target_begin(rt: RenderTarget)\n" -"//~~fn RenderTarget.end\n" -"// Begins the render target rendering pass.\n" -"fn (rt: ^RenderTarget) begin*() {\n" -"//~~\n" -"\tumth_image_render_target_begin(rt^)\n" -"}\n" -"\n" -"fn umth_image_render_target_end(rt: RenderTarget, wp: th.Vf2)\n" -"//~~fn RenderTarget.end\n" -"// Ends the render target rendering pass.\n" -"fn (rt: ^RenderTarget) end*(wp: th.Vf2) {\n" -"//~~\n" -"\tumth_image_render_target_end(rt^, wp)\n" -"}\n" -"\n" -"fn umth_image_render_target_to_image(ret: ^Image, rt: RenderTarget)\n" -"//~~fn RenderTarget.toImage\n" -"// Returns the image of the render target.\n" -"// Do not call `setfilter` on the resulting image.\n" -"fn (rt: ^RenderTarget) toImage*(): Image {\n" -"//~~\n" -"\timg := Image{}\n" -"\tumth_image_render_target_to_image(&img, rt^)\n" -"\treturn img\n" -"}\n" -"\n" -"fn umth_image_load(ret: ^Image, path: str)\n" -"//~~fn load\n" -"// Loads an image at path.\n" -"fn load*(path: str): Image {\n" -"//~~\n" -"\timg := Image{}\n" -"\tumth_image_load(&img, path)\n" -"\treturn img\n" -"}\n" -"\n" -"//~~fn Image.validate\n" -"// Returns true, if i\'s handle points to an image.\n" -"fn (i: ^Image) validate*(): bool {\n" -"//~~\n" -"\treturn i._ != null\n" -"}\n" -"\n" -"fn umth_image_flipv(i: Image, f: bool)\n" -"//~~fn Image.flipv\n" -"// Flips image on it\'s vertical axis.\n" -"fn (i: ^Image) flipv*(flip: bool) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_flipv(i^, flip)\n" -"}\n" -"\n" -"fn umth_image_fliph(i: Image, f: bool)\n" -"//~~fn Image.fliph\n" -"// Flips image on it\'s horizontal axis.\n" -"fn (i: ^Image) fliph*(flip: bool) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_fliph(i^, flip)\n" -"}\n" -"\n" -"fn umth_image_draw(img: Image, t: ^th.Transform, color: uint32)\n" -"//~~fn Image.draw\n" -"// Draws the image in screen coordinates. It transforms it with t and\n" -"// applies color as a color filter.\n" -"fn (i: ^Image) draw*(t: th.Transform, color: uint32 = th.white) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_draw(i^, &t, color)\n" -"}\n" -"\n" -"fn umth_image_draw_nine_patch(img: Image, outer, inner, dest: ^rect.Rect,\n" -"\tcolor: uint32, scale: real)\n" -"//~~fn Image.drawNinepatch\n" -"// Draws \"nine-patch\" image.\n" -"// `outer` specifies the texture coordinates of the outer rect of source image,\n" -"// `inner` specifies coordinates of inner rect of source image, positioned relative to `outer`.\n" -"// You can tint with `color`.\n" -"// ![](img/ninepatch.png)\n" -"fn (i: ^Image) drawNinepatch*(outer, inner, dest: rect.Rect, color: uint32 = th.white, scale: real = 1.0) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_draw_nine_patch(i^, &outer, &inner, &dest, color, scale)\n" -"}\n" -"\n" -"fn umth_image_draw_on_quad(img: Image, color: uint32, q: th.Quad)\n" -"//~~fn Image.drawOnQuad\n" -"// Draws the image on top of a quad with corners of the image positioned\n" -"// on the verticies of the quad.\n" -"fn (i: ^Image) drawOnQuad*(q: th.Quad, color: uint32 = th.white) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_draw_on_quad(i^, color, q)\n" -"}\n" -"\n" -"fn umth_image_get_dims(dm: ^th.Vf2, i: Image)\n" -"//~~fn Image.getDims\n" -"// Returns width and heigth.\n" -"fn (i: ^Image) getDims*(): th.Vf2 {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tout := th.Vf2{}\n" -"\tumth_image_get_dims(&out, i^)\n" -"\n" -"\treturn out\n" -"}\n" -"\n" -"fn umth_image_crop(img: Image, tl, br: th.Vf2)\n" -"//~~fn Image.crop\n" -"// Crops an image. Coordinates are between 0, 0 (top left) and\n" -"// 1, 1 (bottom right)\n" -"fn (i: ^Image) crop*(tl, br: th.Vf2) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_crop(i^, tl, br)\n" -"}\n" -"\n" -"//~~fn Image.cropPx\n" -"// Same as `Image.crop`, but the positions are in pixels.\n" -"fn (i: ^Image) cropPx*(tr, br: th.Vf2) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tdm := i.getDims()\n" -"\tumth_image_crop(i^, tr.div(dm), br.div(dm))\n" -"}\n" -"\n" -"//~~fn Image.cropRect\n" -"// Same as `Image.crop`, but uses a rect instead of two positions.\n" -"fn (i: ^Image) cropRect*(r: rect.Rect) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_crop(i^, r.getPos(), r.getEnd())\n" -"}\n" -"\n" -"fn umth_image_crop_quad(img: Image, q: ^th.Quad)\n" -"//~~fn Image.cropQuad\n" -"// Crop an image using a quad.\n" -"fn (i: ^Image) cropQuad*(q: th.Quad) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_crop_quad(i^, &q)\n" -"}\n" -"\n" -"fn umth_image_get_crop_quad(img: Image, q: ^th.Quad)\n" -"//~~fn Image.getCropQuad\n" -"// Crop an image using a quad.\n" -"fn (i: ^Image) getCropQuad*(): th.Quad {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tvar (q: th.Quad)\n" -"\tumth_image_get_crop_quad(i^, &q)\n" -"\treturn q\n" -"}\n" -"\n" -"fn umth_image_from_data(ret: ^Image, data: ^uint32, dm: th.Vf2)\n" -"//~~fn mk\n" -"// Creates an image from raw data.\n" -"fn mk*(data: []uint32, dm: th.Vf2): Image {\n" -"//~~\n" -"\timg := Image{}\n" -"\tumth_image_from_data(&img, &data[0], dm)\n" -"\n" -"\treturn img\n" -"}\n" -"\n" -"fn umth_image_copy(ret: ^Image, data: Image)\n" -"//~~fn Image.copy\n" -"// Copies image into a new one.\n" -"fn (i: ^Image) copy*(): Image {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\timg := Image{}\n" -"\tumth_image_copy(&img, i^)\n" -"\n" -"\treturn img\n" -"}\n" -"\n" -"fn umth_image_set_filter(data: Image, filter: int)\n" -"//~~fn Image.setfilter\n" -"// Sets a mag/min filter. 0 is nearest, others are linear.\n" -"// This function will regenerate the texture. This means it shouldn\'t be\n" -"// used in a loop.\n" -"// https://learnopengl.com/img/getting-started/texture_filtering.png\n" -"// left is nearest, right is linear.\n" -"fn (i: ^Image) setfilter*(filter: int) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tumth_image_set_filter(i^, filter)\n" -"}\n" -"\n" -"fn umth_image_update_data(img: Image, data: ^uint32, dm: th.Vf2)\n" -"//~~fn Image.setData\n" -"// Updates the image data. dm are the dimensions of the new image.\n" -"// The new image doesn\'t have to be the same size as the old one.\n" -"fn (i: ^Image) setData*(data: []uint32, dm: th.Vf2) {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tif dm.x * dm.y != len(data) {\n" -"\t\terror(sprintf(\"setData: incorrect dimensions: %v\" + \"!= %v\", dm.x * dm.y, len(data)))\n" -"\t}\n" -"\n" -"\tif len(data) == 0 {\n" -"\t\terror(\"setData: can\'t set empty image\")\n" -"\t}\n" -"\n" -"\tumth_image_update_data(i^, &data[0], dm)\n" -"}\n" -"\n" -"fn umth_image_get_data(img: Image, data: ^uint32)\n" -"//~~fn Image.getData\n" -"// Gets the image data. This downloads the data from the GPU on **each call**.\n" -"// Don\'t use in performance critical sections.\n" -"fn (i: ^Image) getData*(): []uint32 {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"image is invalid\")\n" -"\t}\t\n" -"\n" -"\tbuf := make([]uint32, trunc(i.getDims().x * i.getDims().y))\n" -"\tif len(buf) == 0 {\n" -"\t\treturn buf\n" -"\t}\n" -"\n" -"\tumth_image_get_data(i^, &buf[0])\n" -"\n" -"\treturn buf\n" -"}\n" -"", -"//~~\n" -"// Module for getting keyboard and mouse input.\n" -"// is* functions return info based on a us QWERTY layout. They are supposed to\n" -"// be used for game controls. For text input use getStr.\n" -"//~~\n" -"\n" -"import (\n" -" \"rect.um\"\n" -" \"th.um\"\n" -" \"window.um\"\n" -")\n" -"\n" -"//~~Keycode constants\n" -"const (\n" -" mouse1* = 1 // NOTE: mouse 2 and 3 key codes are swapped\n" -" mouse2* = 3 // because sokol uses 3 for middle mouse\n" -" mouse3* = 2 // button.\n" -"\n" -" key_ctrl* = 16\n" -" key_shift* = 17\n" -" key_alt* = 18\n" -"\n" -" key_space* = 32\n" -" key_apostrophe* = 39 /* \' */\n" -" key_comma* = 44 /* , */\n" -" key_minus* = 45 /* - */\n" -" key_dot* = 46 /* . */\n" -" key_slash* = 47 /* / */\n" -" key_0* = 48\n" -" key_1* = 49\n" -" key_2* = 50\n" -" key_3* = 51\n" -" key_4* = 52\n" -" key_5* = 53\n" -" key_6* = 54\n" -" key_7* = 55\n" -" key_8* = 56\n" -" key_9* = 57\n" -" key_semicolon* = 59 /* ; */\n" -" key_equal* = 61 /* = */\n" -" key_a* = 65\n" -" key_b* = 66\n" -" key_c* = 67\n" -" key_d* = 68\n" -" key_e* = 69\n" -" key_f* = 70\n" -" key_g* = 71\n" -" key_h* = 72\n" -" key_i* = 73\n" -" key_j* = 74\n" -" key_k* = 75\n" -" key_l* = 76\n" -" key_m* = 77\n" -" key_n* = 78\n" -" key_o* = 79\n" -" key_p* = 80\n" -" key_q* = 81\n" -" key_r* = 82\n" -" key_s* = 83\n" -" key_t* = 84\n" -" key_u* = 85\n" -" key_v* = 86\n" -" key_w* = 87\n" -" key_x* = 88\n" -" key_y* = 89\n" -" key_z* = 90\n" -" key_left_bracket* = 91 /* [ */\n" -" key_backslash* = 92 /* \\ */\n" -" key_right_bracket* = 93 /* ] */\n" -" key_grave_accent* = 96 /* ` */\n" -" key_world_1* = 161 /* non-US #1 */\n" -" key_world_2* = 162 /* non-US #2 */\n" -" key_escape* = 256\n" -" key_enter* = 257\n" -" key_tab* = 258\n" -" key_backspace* = 259\n" -" key_insert* = 260\n" -" key_delete* = 261\n" -" key_right* = 262\n" -" key_left* = 263\n" -" key_down* = 264\n" -" key_up* = 265\n" -" key_page_up* = 266\n" -" key_page_down* = 267\n" -" key_home* = 268\n" -" key_end* = 269\n" -" key_caps_lock* = 280\n" -" key_scroll_lock* = 281\n" -" key_num_lock* = 282\n" -" key_print_screen* = 283\n" -" key_pause* = 284\n" -"\tkey_fn* = 289\n" -" key_fn1* = 290\n" -" key_fn2* = 291\n" -" key_fn3* = 292\n" -" key_fn4* = 293\n" -" key_fn5* = 294\n" -" key_fn6* = 295\n" -" key_fn7* = 296\n" -" key_fn8* = 297\n" -" key_fn9* = 298\n" -" key_fn10* = 299\n" -" key_fn11* = 300\n" -" key_fn12* = 301\n" -" key_fn13* = 302\n" -" key_fn14* = 303\n" -" key_fn15* = 304\n" -" key_fn16* = 305\n" -" key_fn17* = 306\n" -" key_fn18* = 307\n" -" key_fn19* = 308\n" -" key_fn20* = 309\n" -" key_fn21* = 310\n" -" key_fn22* = 311\n" -" key_fn23* = 312\n" -" key_fn24* = 313\n" -" key_fn25* = 314\n" -" key_kp_0* = 320\n" -" key_kp_1* = 321\n" -" key_kp_2* = 322\n" -" key_kp_3* = 323\n" -" key_kp_4* = 324\n" -" key_kp_5* = 325\n" -" key_kp_6* = 326\n" -" key_kp_7* = 327\n" -" key_kp_8* = 328\n" -" key_kp_9* = 329\n" -" key_kp_decimal* = 330\n" -" key_kp_divide* = 331\n" -" key_kp_multiply* = 332\n" -" key_kp_subtract* = 333\n" -" key_kp_add* = 334\n" -" key_kp_enter* = 335\n" -" key_kp_equal* = 336\n" -" key_left_shift* = 340\n" -" key_left_control* = 341\n" -" key_left_alt* = 342\n" -" key_left_super* = 343\n" -" key_right_shift* = 344\n" -" key_right_control* = 345\n" -" key_right_alt* = 346\n" -" key_right_super* = 347\n" -" key_menu* = 348\n" -")\n" -"//~~\n" -"\n" -"\n" -"fn toupper(c: char): int {\n" -" if c >= \'a\' && c <= \'z\' {\n" -" return int(c) - 32;\n" -" }\n" -" return int(c);\n" -"}\n" -"\n" -"fn umth_input_get_mouse(out: ^th.Vf2)\n" -"//~~fn getMousePos\n" -"// Returns the position of mouse cursor in relation to the screen.\n" -"fn getMousePos*(): th.Vf2 {\n" -"//~~\n" -"\tout := th.Vf2{}\n" -"\tumth_input_get_mouse(&out)\n" -"\treturn out\n" -"}\n" -"\n" -"//~~fn getGlobalMousePos\n" -"// Returns the position of mouse cursor in relation to cam.\n" -"fn getGlobalMousePos*(): th.Vf2 {\n" -"//~~\n" -"\treturn getMousePos().add(window.getViewportOffset())\n" -"}\n" -"\n" -"fn umth_input_is_pressed(keycode: int32): int32\n" -"//~~fn isPressed\n" -"// Returns true if key is pressed. Either use codes defined in the file above,\n" -"// or pass lower case char/number.\n" -"fn isPressed*(code: int): bool {\n" -"//~~\n" -"\tval := bool(umth_input_is_pressed(code))\n" -"\treturn val\n" -"}\n" -"\n" -"//~~fn isPressedc\n" -"// Like `isPressed`, but you can pass char as the code.\n" -"fn isPressedc*(code: char): bool {\n" -"//~~\n" -"\treturn isPressed(toupper(code))\n" -"}\n" -"\n" -"fn umth_input_is_just_pressed(key: int32): int32\n" -"//~~fn isJustPressed\n" -"// Returns, whether code was just pressed this loop.\n" -"fn isJustPressed*(code: int): bool {\n" -"//~~\n" -"\treturn bool(umth_input_is_just_pressed(code))\n" -"}\n" -"\n" -"//~~fn isJustPressedc\n" -"// Like `isJustPressed`, but you can pass char as the code.\n" -"fn isJustPressedc*(code: char): bool {\n" -"//~~\n" -"\treturn isJustPressed(toupper(code))\n" -"}\n" -"\n" -"fn umth_input_is_pressed_repeat(key: int32): int32\n" -"//~~fn isPressedRepeat\n" -"// Returns, whether code was just pressed this loop, with key repeat.\n" -"fn isPressedRepeat*(code: int): bool {\n" -"//~~\n" -" return bool(umth_input_is_pressed_repeat(code))\n" -"}\n" -"\n" -"//~~fn isPressedRepeatc\n" -"// Like `isPressedRepeat`, but you can pass char as the code.\n" -"fn isPressedRepeatc*(code: char): bool {\n" -"//~~\n" -" return isPressedRepeat(toupper(code))\n" -"}\n" -"\n" -"\n" -"fn umth_input_is_just_released(key: int32): int32\n" -"//~~fn isJustReleased\n" -"// Returns true if a key was just released.\n" -"fn isJustReleased*(code: int): bool {\n" -"//~~\n" -"\treturn bool(umth_input_is_just_released(code))\n" -"}\n" -"//~~fn isJustReleasedc\n" -"// Like `isJustReleased`, but you can pass char as the code.\n" -"fn isJustReleasedc*(code: char): bool {\n" -"//~~\n" -"\treturn isJustReleased(toupper(code))\n" -"}\n" -"\n" -"fn umth_input_clear*(code: int)\n" -"//~~fn clear\n" -"// Clears both the pressed and justPressed state of a code.\n" -"fn clear*(code: int) {\n" -"//~~\n" -"\tumth_input_clear(code)\n" -"}\n" -"\n" -"//~~fn clearc\n" -"// Like `clear`, but you can pass char as the code.\n" -"fn clearc*(code: char) {\n" -"//~~\n" -" umth_input_clear(toupper(code))\n" -"}\n" -"\n" -"fn umth_input_get_str(): str\n" -"//~~fn getStr\n" -"// Returns a string entered by the user in the last cycle.\n" -"fn getStr*(): str {\n" -"//~~\n" -"\treturn umth_input_get_str()\n" -"}\n" -"\n" -"fn umth_input_get_mouse_delta(o: ^th.Vf2)\n" -"//~~fn getMouseDelta\n" -"// Returns the difference between mouse positions in the last cycle. Will work\n" -"// even if `window.freezeCursor` is enabled.\n" -"fn getMouseDelta*(): th.Vf2 {\n" -"//~~\n" -"\to := th.Vf2{}\n" -"\tumth_input_get_mouse_delta(&o)\n" -"\treturn o\n" -"}\n" -"\n" -"fn umth_input_get_mouse_scroll(x, y: ^th.fu)\n" -"//~~fn getMouseScroll\n" -"// Returns the scroll wheel value\n" -"fn getMouseScroll*(): th.Vf2 {\n" -"//~~\n" -" var x, y: th.fu\n" -" umth_input_get_mouse_scroll(&x, &y)\n" -" return th.Vf2{x, y}\n" -"}", -"//~~\n" -"// Misc functions.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"th.um\"\n" -"\t\"std.um\"\n" -")\n" -"\n" -"//~~fn readall\n" -"// Reads file content into a string.\n" -"fn readall*(path: str): str {\n" -"//~~\n" -"\tf := std.fopen(path, \"r\")\n" -"\tconst blockSize = 16\n" -"\tres := \"\"\n" -"\n" -"\tfor ok := true; ok {\n" -"\t var buff: [blockSize + 1]char\n" -"\t ok = std.fread(f, ^[blockSize]char(&buff)) == 1\n" -"\t res += str([]char(buff))\n" -"\t}\n" -"\n" -"\tstd.fclose(f)\n" -"\treturn res\n" -"}\n" -"\n" -"//~~fn stepify\n" -"// Snaps a value to step.\n" -"fn stepify*(val, step: th.fu): th.fu {\n" -"//~~\n" -"\tif step != 0 {\n" -"\t\tval = floor(val / step + 0.5) * step\n" -"\t}\n" -"\treturn val\n" -"}\n" -"\n" -"//~~fn maxf\n" -"fn maxf*(a, b: th.fu): th.fu {\n" -"//~~\n" -"\tif a > b { return a }\n" -"\treturn b\n" -"}\n" -"\n" -"//~~fn minf\n" -"fn minf*(a, b: th.fu): th.fu {\n" -"//~~\n" -"\tif a > b { return b }\n" -"\treturn a\n" -"}\n" -"", -"//~~\n" -"// Canvas library allowing for drawing basic shapes. Coordinates are based on\n" -"// the screen.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"misc.um\"\n" -"\t\"rect.um\"\n" -"\t\"th.um\"\n" -")\n" -"\n" -"fn umth_canvas_draw_text(text: str, pos: th.Vf2, color: uint32, size: th.fu)\n" -"//~~fn drawText\n" -"// Draws a basic pixel text. Only ascii is supported.\n" -"fn drawText*(text: str, pos: th.Vf2, color: uint32, size: th.fu) {\n" -"//~~\n" -"\tumth_canvas_draw_text(text, pos, color, size)\n" -"}\n" -"\n" -"//~~fn textSize\n" -"// Returns the size of text taken by an equivalent drawText call.\n" -"fn textSize*(text: str, scale: th.fu): th.Vf2 {\n" -"//~~\n" -"\tvar w, maxw, h: int\n" -"\tw = 0\n" -"\tmaxw = 0\n" -"\th = 1\n" -"\n" -"\tfor i in text {\n" -"\t\tif text[i] == \"\\n\" {\n" -"\t\t\th += 1\n" -"\t\t\tif w > maxw {\n" -"\t\t\t\tmaxw = w\n" -"\t\t\t}\n" -"\n" -"\t\t\tcontinue\n" -"\t\t}\n" -"\n" -"\t\tw++\n" -"\t}\n" -"\n" -"\tif w > maxw {\n" -"\t\tmaxw = w\n" -"\t}\n" -"\n" -"\treturn th.Vf2{maxw * scale * 6 - scale, h * 6 * scale}\n" -"}\n" -"\n" -"fn umth_canvas_draw_rect(color: uint32, r: rect.Rect)\n" -"//~~fn drawRect\n" -"// Draws a Rectangle.\n" -"fn drawRect*(color: uint32, r: rect.Rect) {\n" -"//~~\n" -"\tumth_canvas_draw_rect(color, r)\n" -"}\n" -"\n" -"fn umth_canvas_draw_line(color: uint32, b, e: th.Vf2, thickness: th.fu)\n" -"//~~fn drawLine\n" -"// Draws a line.\n" -"fn drawLine*(color: uint32, b, e: th.Vf2, thickness: th.fu) {\n" -"//~~\n" -"\tumth_canvas_draw_line(color, b, e, thickness)\n" -"}\n" -"\n" -"//~~fn drawRectLines\n" -"// Draws rect border.\n" -"fn drawRectLines*(color: uint32, r: rect.Rect, thickness: real32 = 1.0) {\n" -"//~~\n" -" // top\n" -" drawLine(color, th.Vf2{r.x-1, r.y}, th.Vf2{r.x+r.w, r.y}, thickness)\n" -" // bottom\n" -" drawLine(color, th.Vf2{r.x, r.y+r.h}, th.Vf2{r.x+r.w, r.y+r.h}, thickness)\n" -" // left\n" -" drawLine(color, th.Vf2{r.x, r.y}, th.Vf2{r.x, r.y+r.h}, thickness)\n" -" // right\n" -" drawLine(color, th.Vf2{r.x+r.w, r.y}, th.Vf2{r.x+r.w, r.y+r.h}, thickness)\n" -"}\n" -"\n" -"fn umth_canvas_draw_quad(color: uint32, q: ^th.Quad)\n" -"//~~fn drawQuad\n" -"// Draws a convex quad.\n" -"fn drawQuad*(color: uint32, q: th.Quad) {\n" -"//~~\n" -"\tumth_canvas_draw_quad(color, &q)\n" -"}\n" -"\n" -"var scissor: []rect.Rect\n" -"\n" -"fn umth_canvas_begin_scissor_rect(x, y, w, h: real)\n" -"fn umth_canvas_end_scissor()\n" -"\n" -"fn rectDiff(a, b: rect.Rect): rect.Rect {\n" -"\tx := misc.maxf(a.x, b.x);\n" -"\ty := misc.maxf(a.y, b.y);\n" -"\treturn rect.Rect{\n" -"\t\tx,y, \n" -"\t\tmisc.minf(a.x + a.w, b.x + b.w) - x,\n" -"\t\tmisc.minf(a.y + a.h, b.y + b.h) - y};\n" -"}\n" -"\n" -"//~~fn beginScissorRect\n" -"// Disable rendering outside of rect `r`\n" -"fn beginScissorRect*(r: rect.Rect, debug: bool = false) {\n" -"//~~\n" -"\tr2 := r\n" -"\tif len(scissor) == 0 {\n" -"\t\tscissor = { r }\n" -"\t} else {\n" -"\t\ts := scissor[len(scissor) - 1]\n" -"\t\tr2 = rectDiff(s, r)\n" -"\t\tscissor = append(scissor, r2)\n" -"\t}\n" -"\n" -"\tif debug {\n" -"\t\tdrawRectLines(th.red, r2, 0.1) \n" -"\t}\n" -"\t\n" -"\tumth_canvas_begin_scissor_rect(r2.x, r2.y, r2.w, r2.h)\n" -"}\n" -"\n" -"//~~fn endScissor\n" -"// Stops cropping\n" -"fn endScissor*() {\n" -"//~~\n" -"\tif len(scissor) > 0 {\n" -"\t\tscissor = delete(scissor, len(scissor) - 1)\n" -"\t\tif len(scissor) > 0 {\n" -"\t\t\tlast := scissor[len(scissor)-1]\n" -"\t\t\tumth_canvas_begin_scissor_rect(last.x, last.y, last.w, last.h)\n" -"\t\t} else {\n" -"\t\t\tumth_canvas_end_scissor();\n" -"\t\t}\n" -"\t}\n" -"\t\n" -"}\n" -"", -"\n" -"import (\n" -"\t\"th.um\"\n" -"\t\"ent.um\"\n" -"\t\"rect.um\"\n" -"\t\"canvas.um\"\n" -"\t\"tilemap.um\"\n" -")\n" -"\n" -"//~~struct Ray\n" -"// Ray is a line specified by an origin, length and a rotation.\n" -"type Ray* = struct {\n" -"\tpos: th.Vf2\n" -"\tl: th.fu // length\n" -"\tr: th.fu // rotation\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mk\n" -"// Ray constructor\n" -"fn mk*(pos: th.Vf2, l: th.fu, r: th.fu = 0.0): Ray {\n" -"//~~\n" -"\treturn Ray{pos, l, r}\n" -"}\n" -"\n" -"fn umth_ray_getcoll(colls: ^ent.Coll, count: ^int, maxCount,\n" -"\tsceneLen: int, r: ^Ray, scene: ^^ent.Ent)\n" -"//~~fn Ray.getColl\n" -"// Checks the ray\'s collisions with a scene of ents. Similar to\n" -"// `ent.Ent.getColl`\n" -"fn (r: ^Ray) getColl*(s: []^ent.Ent, maxColls: th.uu): []ent.Coll {\n" -"//~~\n" -"\tif len(s) == 0 {\n" -"\t\treturn []ent.Coll{}\n" -"\t}\n" -"\n" -"\tif maxColls > len(s) {\n" -"\t\tmaxColls = len(s)\n" -"\t}\n" -"\n" -"\tcolls := make([]ent.Coll, maxColls)\n" -"\tcount := 0\n" -"\tumth_ray_getcoll(&colls[0], &count, maxColls, len(s), r, &s[0])\n" -"\treturn slice(colls, 0, count)\n" -"}\n" -"\n" -"fn umth_ray_get_tilemap_coll(r: ^Ray, t: ^tilemap.Tilemap, ic: ^th.Vf2): bool\n" -"//~~fn Ray.getTilemapColl\n" -"// Gets ray\'s collision to a tilemap.\n" -"fn (r: ^Ray) getTilemapColl*(t: tilemap.Tilemap, ic: ^th.Vf2): bool {\n" -"//~~\n" -"\treturn umth_ray_get_tilemap_coll(r, &t, ic)\n" -"}\n" -"\n" -"//~~fn Ray.getEnd\n" -"// Returns the other point of the ray.\n" -"fn (r: ^Ray) getEnd*(): th.Vf2 {\n" -"//~~\n" -"\treturn r.pos.add(th.Vf2{ 0, r.l }.rotated(th.Vf2{}, r.r))\n" -"}\n" -"\n" -"//~~fn Ray.draw\n" -"// Draws the ray to the screen.\n" -"fn (r: ^Ray) draw*(color: uint32, thickness: th.fu) {\n" -"//~~\n" -"\tcanvas.drawLine(color, r.pos, r.getEnd(), thickness)\n" -"}\n" -"", -"\n" -"import (\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~struct Rect\n" -"// A set of points representing a rectangle.\n" -"type Rect* = struct {\n" -"\tx, y, w, h: th.fu\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mk\n" -"fn mk*(x, y, w, h: th.fu): Rect {\n" -"//~~\n" -"\tvar r: Rect\n" -"\n" -"\tr.x = x\n" -"\tr.y = y\n" -"\tr.w = w\n" -"\tr.h = h\n" -"\n" -"\treturn r\n" -"}\n" -"\n" -"//~~fn mk\n" -"// Creates a rect from two Vf2s - the position and the dimensions.\n" -"fn fromVf2*(p: th.Vf2, dm: th.Vf2): Rect {\n" -"//~~\n" -"\treturn mk(p.x, p.y, dm.x, dm.y)\n" -"}\n" -"\n" -"//~~fn Rect.getPos\n" -"fn (r: ^Rect) getPos*(): th.Vf2 {\n" -"//~~\n" -"\treturn th.Vf2{r.x, r.y}\n" -"}\n" -"\n" -"//~~fn Rect.getDims\n" -"fn (r: ^Rect) getDims*(): th.Vf2 {\n" -"//~~\n" -"\treturn th.Vf2{r.w, r.h}\n" -"}\n" -"\n" -"//~~fn Rect.getEnd\n" -"// returns where the second point of the rectangle lies.\n" -"fn (r: ^Rect) getEnd*(): th.Vf2 {\n" -"//~~\n" -"\treturn th.Vf2{r.x+r.w, r.y+r.h}\n" -"}\n" -"\n" -"fn umth_transform_rect(ret: ^th.Quad, r: ^Rect, t: ^th.Transform)\n" -"//~~fn Rect.transformed\n" -"// Transforms a rect into a quad.\n" -"// Order:\n" -"// \t1. scale\n" -"// \t2. rotation\n" -"// \t3. position\n" -"fn (r: ^Rect) transformed*(t: th.Transform): th.Quad {\n" -"//~~\n" -"\tvar ret: th.Quad\n" -"\tumth_transform_rect(&ret, r, &t)\n" -"\n" -"\treturn ret\n" -"}\n" -"\n" -"//~~fn Rect.shrink\n" -"// Shrink the rectangle by `p` pixels from all sides.\n" -"fn (r: ^Rect) shrink*(p: th.Vf2): Rect {\n" -"//~~\n" -"\treturn Rect{ r.x + p.x, r.y + p.y, r.w - 2*p.x, r.h - 2*p.y }\n" -"}\n" -"\n" -"//~~fn Rect.shift\n" -"// Shift the rectangle by `p` pixels.\n" -"fn (r: ^Rect) shift*(p: th.Vf2): Rect {\n" -"//~~\n" -"\treturn Rect{ r.x + p.x, r.y + p.y, r.w, r.h }\n" -"}\n" -"\n" -"//~~fn Rect.scale\n" -"// Multiply the dimensions by `p`\n" -"fn (r: ^Rect) scale*(p: th.Vf2): Rect {\n" -"//~~\n" -"\treturn Rect{ r.x, r.y, r.w * p.x, r.h * p.y }\n" -"}\n" -"\n" -"//~~fn Rect.center\n" -"// Returns the position, which is the center of the rect.\n" -"fn (r: ^Rect) center*(): th.Vf2 {\n" -"//~~\n" -"\treturn r.getPos().add(r.getDims().divf(2))\n" -"}\n" -"\n" -"//~~fn Rect.centerWithinRect\n" -"// Centers `child` with the rect `r`.\n" -"fn (r: ^Rect) centerWithinRect*(child: Rect): Rect {\n" -"//~~\n" -"\tchild.x = r.x + (r.w - child.w)/2\n" -"\tchild.y = r.y + (r.h - child.h)/2\n" -"\treturn child\n" -"}\n" -"\n" -"", -"//~~\n" -"// Tilemaps allow for easy level construction and fast collisions. You can even\n" -"// use them for some games instead of entities (tetris comes to mind)\n" -"//~~\n" -"\n" -"import (\n" -"\t\"th.um\"\n" -"\t\"rect.um\"\n" -"\t\"ent.um\"\n" -"\t\"atlas.um\"\n" -")\n" -"\n" -"//~~Direction constants used for autotile\n" -"const (\n" -"\ttop* = 1\n" -"\tright* = 2\n" -"\tbot* = 4\n" -"\tleft* = 8\n" -")\n" -"//~~\n" -"\n" -"//~~struct Tilemap\n" -"// Tilemap struct\n" -"type Tilemap* = struct {\n" -"\tatlas: atlas.Atlas\n" -"\tpos: th.Vf2\n" -"\tw: th.uu // width of tilemap\n" -"\tcells: []th.uu // all cells (this will draw the tile in tiles with number in cells - 1)\n" -"\tcollMask: []bool // if true, the tile collides\n" -"\tscale: th.fu\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mk\n" -"fn mk*(cells: []th.uu, w: th.uu, at: atlas.Atlas, scale: th.fu = 1): Tilemap {\n" -"//~~\n" -"\tif !at.i.validate() {\n" -"\t\tth.__error(\"invalid atlas\")\n" -"\t}\t\n" -"\n" -"\tt := Tilemap{}\n" -"\tt.cells = cells\n" -"\tt.w = w\n" -"\tt.atlas = at\n" -"\tt.collMask = make([]bool, 10) // TODO\n" -"\tt.scale = scale\n" -"\n" -"\treturn t\n" -"}\n" -"\n" -"//~~fn Tilemap.edit\n" -"// Sets tile at [x, y] to tile.\n" -"fn (t: ^Tilemap) edit*(x, y, tile: int) {\n" -"//~~\n" -"\tt.cells[y*t.w + x] = tile\n" -"}\n" -"\n" -"fn umth_tilemap_draw(ct: ^Tilemap)\n" -"//~~fn Tilemap.draw\n" -"// Draws the tilemap.\n" -"fn (t: ^Tilemap) draw*() {\n" -"//~~\n" -"\tif len(t.cells) == 0 { return }\n" -"\n" -"\tumth_tilemap_draw(t)\n" -"}\n" -"\n" -"fn umth_tilemap_getcoll(pos: ^th.Vf2, vert: ^th.Vf2, t: ^Tilemap, e: ^ent.Ent): int32\n" -"//~~fn Tilemap.getColl\n" -"// Checks whether `e` collides with any of the tiles in `t`, which are in the\n" -"// collmask.\n" -"//\n" -"// * `ic`[out] - the position where a collision occured\n" -"// * `pos`[out] - coordinates of a tile where a collision occured\n" -"//\n" -"// Note: While there may be multiple collisions with a tilemap, this function\n" -"// will only return one.\n" -"fn (t: ^Tilemap) getColl*(e: ent.Ent, ic: ^th.Vf2, pos: ^th.Vf2): bool {\n" -"//~~\n" -"\tif len(t.cells) == 0 { return false }\n" -"\n" -"\t_ := th.Vf2{}\n" -"\tif ic == null { ic = &_ }\n" -"\tif pos == null { pos = &_ }\n" -"\n" -"\tc := umth_tilemap_getcoll(pos, ic, t, &e)\n" -"\n" -"\treturn bool(c)\n" -"}\n" -"\n" -"fn umth_tilemap_autotile(tgt: ^th.uu, w, h: th.uu, src, cfg: ^th.uu, tile: th.uu)\n" -"//~~fn Tilemap.autotile\n" -"// Autotile turns all `tile` tiles in `src` into tiles in `tileCfg`, so they\n" -"// follow up correctly. `tileCfg` is an array of 16 tiles. They are placed in\n" -"// a way where OR of all the places where the tile continues (top, right bot,\n" -"// right). The constants for them are defined in this file. Example:\n" -"// tileCfg[top | bot] = 21\n" -"// top | bot would look something like this: |\n" -"fn (t: ^Tilemap) autotile*(src, tileCfg: []th.uu, tile: th.uu) {\n" -"//~~\n" -"\tif len(tileCfg) < 16 {\n" -"\t\terror(\"autotile: tileCfg len isn\'t 16\'\")\n" -"\t}\n" -"\n" -"\tumth_tilemap_autotile(&t.cells[0], t.w, len(t.cells)/t.w, &src[0], &tileCfg[0], tile)\n" -"}\n" -"", -"\n" -"import (\n" -"\t\"audio.um\"\n" -"\t\"canvas.um\"\n" -"\t\"image.um\"\n" -"\t\"placeholders.um\"\n" -"\t\"rect.um\"\n" -"\t\"signal.um\"\n" -"\t\"std.um\"\n" -"\t\"th.um\"\n" -")\n" -"\n" -"var (\n" -"\tstart, clockOffset: real\n" -"\tfpsLimit: int = 60\n" -")\n" -"\n" -"//~~Cursor types\n" -"const (\n" -"\tcursorDefault* = 0\t\t// Default system cursor\n" -"\tcursorArrow*\t\t\t// Normal cursor; Arrow cursor\n" -"\tcursorIBeam*\t\t\t// \'I\' text cursor; I-Beam\n" -"\tcursorCrosshair*\t\t// \'+\' cursor; Select region cursor\n" -"\tcursorFinger*\t\t\t// Index finger pointing cursor; Click cursor\n" -"\tcursorSizeEW*\t\t\t// \'<->\' cursor; Resize width cursor; Resize horizontally cursor; East-West resize cursor\n" -"\tcursorSizeNS*\t\t\t// Resize height cursor; Resize vertically cursor; North-South resize cursor\n" -"\tcursorSizeNWSE*\t\t\t// Resize width and height from the right side cursor; Northwest-Southeast resize cursor\n" -"\tcursorSizeSWNE*\t\t\t// Resize width and height from the left side cursor; Southwest-Northeast resize cursor\n" -"\tcursorSizeAll*\t\t\t// Resize all cursor; Move cursor\n" -"\tcursorNo*\t\t\t// \'(/)\' cursor; Disabled cursor; Disallowed cursor\n" -"\tcursorCount_*\n" -")\n" -"//~~\n" -"\n" -"//~~Window dimensions\n" -"var (\n" -"\tw*, h*: int32\n" -")\n" -"//~~\n" -"\n" -"//~~Viewport size\n" -"var wp*: th.Vf2\n" -"//~~\n" -"\n" -"//~~signal OnFrame\n" -"var onFrame*: signal.Signal\n" -"//~~\n" -"//~~signal OnDestroy\n" -"var onDestroy*: signal.Signal\n" -"//~~\n" -"\n" -"fn umth_window_setup(title: str, w, h: int)\n" -"fn umth_window_get_dimensions(w, h: ^int32)\n" -"\n" -"fn umth_window_set_viewport(dm: th.Vf2)\n" -"//~~fn setViewport\n" -"// Sets the dimensions of the viewport. The dimensions are saved in the `wp`\n" -"// variable.\n" -"//\n" -"// `dm`\n" -"// : dimension of the viewport\n" -"fn setViewport*(dm: th.Vf2) {\n" -"//~~\n" -"\twp = dm\n" -"\tumth_window_set_viewport(dm)\n" -"}\n" -"\n" -"fn setIcon*(img: image.Image)\n" -"\n" -"fn umth_window_is_dpi_enabled(): bool\n" -"\n" -"//~~fn isDpiEnabled\n" -"// Returns true if DPI awareness was enabled\n" -"fn isDpiEnabled*(): bool {\n" -"//~~\n" -"\treturn umth_window_is_dpi_enabled()\n" -"}\n" -"\n" -"fn umth_window_get_dpi_scale(): th.fu\n" -"\n" -"//~~fn getDpiScaleFactor\n" -"// Returns the DPI scaling of the current window.\n" -"// If `dpiAware` was not enabled in window setup, this function will return 1.0 (default scaling).\n" -"fn getDpiScaleFactor*(): th.fu {\n" -"//~~\n" -"\treturn umth_window_get_dpi_scale()\n" -"}\n" -"\n" -"// 0 = other/unknown\n" -"// 2 = linux\n" -"// 3 = windows\n" -"// 4 = macos (unsupported currently)\n" -"// 5 = emscripten\n" -"fn umth_window_get_platform_id(): int\n" -"\n" -"//~~fn setup\n" -"// Sets up the engine and opens a window.\n" -"fn setup*(title: str = \"tophat game\", width: int = 400, height: int32 = 400) {\n" -"//~~\n" -"\tw, h = width, height\n" -"\tumth_window_setup(title, width, height)\n" -"\n" -"\tth.platform = umth_window_get_platform_id()\n" -"\n" -"\taudio.__setup()\n" -"\tplaceholders.__setup()\n" -"\n" -"\tsetIcon(placeholders.icon)\n" -"\n" -"\tclockOffset = std.clock() * 1000\n" -"\tstart = std.clock() * 1000\n" -"\n" -"\tsetViewport(th.Vf2{width, height})\n" -"}\n" -"\n" -"//~~fn cycle\n" -"// Cycle needs to be called every cycle for the window to work. If the window\n" -"// was closed, it returns false.\n" -"fn cycle(delta: real) {\n" -"//~~\n" -"\tumth_window_set_viewport(wp)\n" -"\n" -"\tth.delta = trunc(delta*1000.0)\n" -"\tif th.delta == 0 {\n" -"\t\tth.delta = 1\n" -"\t}\n" -"\n" -"\tstart = std.clock()*1000\n" -"\tth.time = round(start - clockOffset)\n" -"\n" -"\tumth_window_get_dimensions(&w, &h)\n" -"\n" -"\taudio.__cycle()\n" -"\tcanvas.drawRect(th.white, rect.mk(0, 0, wp.x, wp.y))\n" -"}\n" -"\n" -"fn setViewportOffset*(s: th.Vf2)\n" -"fn getViewportOffset*(): th.Vf2\n" -"\n" -"fn drawClear() {\n" -"\tof := getViewportOffset()\n" -"\tsetViewportOffset({})\n" -"\tcanvas.drawRect(th.black, rect.mk(-4 * wp.x, 0, 4 * wp.x, wp.y))\n" -"\tcanvas.drawRect(th.black, rect.mk(0, -4 * wp.y, wp.x, 4 * wp.y))\n" -"\tcanvas.drawRect(th.black, rect.mk(wp.x, 0, 4 * wp.x, wp.y))\n" -"\tcanvas.drawRect(th.black, rect.mk(0, wp.y, wp.x, 4 * wp.y))\n" -"\tsetViewportOffset(of)\n" -"}\n" -"\n" -"fn umth_frame_callback*(delta: real) {\n" -"\tcycle(delta)\n" -"\tonFrame.emit(null)\n" -"\tdrawClear()\n" -"}\n" -"\n" -"fn umth_destroy_callback*() {\n" -" onDestroy.emit(null)\n" -"}\n" -"\n" -"fn umth_window_set_fullscreen(fullscreen: bool)\n" -"fn umth_window_get_fullscreen(): bool\n" -"\n" -"//~~fn setFullscreen\n" -"// Makes window go full screen\n" -"fn setFullscreen*(fullscreen: bool) {\n" -"//~~\n" -"\tumth_window_set_fullscreen(fullscreen)\n" -"}\n" -"\n" -"//~~fn isFullscreen\n" -"// Returns true if window is fullscreen\n" -"fn isFullscreen*(): bool {\n" -"//~~\n" -"\treturn umth_window_get_fullscreen()\n" -"}\n" -"\n" -"//~~fn getDims\n" -"// Returns dimensions of the window in screen pixels.\n" -"fn getDims*(): th.Vf2 {\n" -"//~~\n" -"\treturn th.Vf2{w, h}\n" -"}\n" -"\n" -"fn umth_window_set_target_fps(fps: int)\n" -"\n" -"//~~fn setTargetFps\n" -"// Sets the fps limit.\n" -"//\n" -"// `fps`\n" -"// : amount of fps the limit should be set to\n" -"//\n" -"fn setTargetFps*(fps: int) {\n" -"//~~\n" -"\tfpsLimit = fps\n" -"\tumth_window_set_target_fps(fps)\n" -"}\n" -"\n" -"fn umth_window_set_dims(dm: th.Vf2)\n" -"//~~fn setDims\n" -"// Sets the dimensions of the window.\n" -"//\n" -"// `dm`\n" -"// : the target dimensions in screen pixels\n" -"fn setDims*(dm: th.Vf2) {\n" -"//~~\n" -"\tumth_window_set_dims(dm)\n" -"}\n" -"\n" -"fn umth_window_set_icon(img: image.Image)\n" -"//~~fn setIcon\n" -"// Sets the window icon.\n" -"fn setIcon*(img: image.Image) {\n" -"//~~\n" -"\tif !img.validate() {\n" -"\t\tth.__error(\"invalid image\")\n" -"\t}\t\n" -"\n" -"\tumth_window_set_icon(img)\n" -"}\n" -"\n" -"fn umth_window_show_cursor(show: bool)\n" -"//~~fn showCursor\n" -"// Show or hide the cursor, linux only.\n" -"fn showCursor*(show: bool) {\n" -"//~~\n" -"\tumth_window_show_cursor(show)\n" -"}\n" -"\n" -"fn umth_window_freeze_cursor(freeze: bool)\n" -"//~~fn freezeCursor\n" -"// Freezes the cursor in place. `input.getMouseDelta` will still report mouse\n" -"// movements. The cursor will be automatically hidden.\n" -"fn freezeCursor*(freeze: bool) {\n" -"//~~\n" -"\tshowCursor(freeze)\n" -"\tumth_window_freeze_cursor(freeze)\n" -"}\n" -"\n" -"fn umth_window_set_cursor(cursor: int)\n" -"//~~fn setCursor\n" -"// Allows you to set the displaying cursor. Refer to the cursors section for available cursors.\n" -"fn setCursor*(cursor: int) {\n" -"//~~\n" -"\tumth_window_set_cursor(cursor);\n" -"}\n" -"\n" -"\n" -"fn umth_window_quit()\n" -"//~~fn quit\n" -"// Exits the application. Use this instead of umka\'s default `exit`.\n" -"fn quit*() {\n" -"//~~\n" -"\tumth_window_quit()\n" -"}\n" -"\n" -"fn umth_window_set_clipboard(s: str)\n" -"//~~fn setClipboard\n" -"// Puts a string to the system clipboard.\n" -"fn setClipboard*(s: str) {\n" -"//~~\n" -"\tumth_window_set_clipboard(s)\n" -"}\n" -"\n" -"fn umth_window_get_clipboard(s: ^char)\n" -"//~~fn getClipboard\n" -"// Gets a string from the system clipboard.\n" -"fn getClipboard*(): str {\n" -"//~~\n" -"\tbuf := make([]char, 8192)\n" -"\tumth_window_get_clipboard(&buf[0])\n" -"\treturn str(buf)\n" -"}\n" -"\n" -"fn umth_window_set_viewport_shift(s: th.Vf2)\n" -"//~~fn setViewportOffset\n" -"// Sets the offset of the viewport.\n" -"fn setViewportOffset*(s: th.Vf2) {\n" -"//~~\n" -"\tumth_window_set_viewport_shift(s)\n" -"}\n" -"\n" -"fn umth_window_get_viewport_shift(s: ^th.Vf2)\n" -"//~~fn getViewportOffset\n" -"// Gets the offset of the viewport (as set by `setViewportShift`)\n" -"fn getViewportOffset*(): th.Vf2 {\n" -"\to := th.Vf2{}\n" -"\n" -"\tumth_window_get_viewport_shift(&o)\n" -"\treturn o\n" -"}\n" -"", -"//~~\n" -"// Particles allow for *performant* and random particle systems.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"rect.um\"\n" -"\t\"std.um\"\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~struct Particle\n" -"// Particle struct. You can tweak the start_time for godot-like explossivness.\n" -"type Particle* = struct {\n" -"//~~\n" -"\tstart_time: uint\n" -"\tseed: int32\n" -"}\n" -"\n" -"//~~struct Emitter\n" -"// Emitter. This is where everything is configured.\n" -"type Emitter* = struct {\n" -"\tpos: th.Vf2 // position\n" -"\tdm: th.Vf2 // size of the emittion area\n" -"\tgravity: th.Vf2 // gravity\n" -"\trepeat: bool // if false, particle won\'t be renewed\n" -"\tactive: bool // false, if there aren\'t any active particles anymore\n" -"\n" -"\tangle: th.Vf2 // angle in which particles are emitted\n" -"\n" -"\tlifetime: th.uu // lifetime of particles\n" -"\tlifetimeRandomness: th.fu // randomness in %/100\n" -"\n" -"\tvelocity: th.fu // velocity\n" -"\tvelocityRandomness: th.fu // randomness in %/100\n" -"\n" -"\tsize: th.fu // size\n" -"\tsizeRandomness: th.fu // randomness in %/100\n" -"\tmaxSize: th.fu // size at the end of particles lifetime\n" -"\n" -"\trotation: th.fu\n" -"\trotationRandomness: th.fu\n" -"\tmaxRotation: th.fu\n" -"\n" -"\tcolors: []uint32 // array of colors, which are interpolated between\n" -"\n" -"\tparticles: []Particle // list of particles\n" -"}\n" -"//~~\n" -"\n" -"fn umth_particles_draw(p: ^Emitter, t: int32)\n" -"//~~fn Emitter.draw\n" -"// Draws and updates the particles.\n" -"fn (e: ^Emitter) draw*(t: int32) {\n" -"//~~\n" -"\tif len(e.colors) <= 0 || len(e.particles) <= 0 {\n" -"\t\treturn\n" -"\t}\n" -"\n" -"\tumth_particles_draw(e, t)\n" -"}\n" -"\n" -"//~~fn Emitter.genParticles\n" -"// Generates particles for an emitter. The time specifies the time the first\n" -"// particles is emitted. The explosiveness argument specifies the interval at\n" -"// which particles are emitted using this formula:\n" -"/// ```umka\n" -"/// e.lifetime / count * explosiveness\n" -"/// ```\n" -"fn (e: ^Emitter) genParticles*(time, count: uint, explosiveness: th.fu = 0.0) {\n" -"//~~\n" -"\tp := make([]Particle, count)\n" -"\n" -"\tstep := real32(e.lifetime) / count * explosiveness\n" -"\tt := real32(time)\n" -"\n" -"\tfor i in p {\n" -"\t\tp[i] = { trunc(t), std.rand() }\n" -"\t\tt += step\n" -"\t}\n" -"\n" -"\te.particles = p\n" -"}\n" -"", -"//~~\n" -"// Simple linear interpolation module.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"th.um\"\t\t\t\t\t\t\t\t\n" -")\n" -"\n" -"// Lerper queue item. It interpolates between start and end for the duration\n" -"// of length in ms. Additionally you can enable swap, which instead of\n" -"// dequeueing swaps start and end and resets the progress.\n" -"type Item* = struct {\n" -"\tstart, end: th.fu\n" -"\tlength: th.uu\n" -"\tprogress: th.fu\n" -"\tswap: bool\n" -"\tctx: any\n" -"\tcallback: fn(ctx: any)\n" -"}\n" -"\n" -"// Item\'s constructor\n" -"fn mk*(start, end: th.fu, length: th.uu, swap: bool = false): Item {\n" -"\treturn Item{\n" -"\t\tstart, end, length, 0, swap, null, fn(ctx: any) {}}\n" -"}\n" -"\n" -"// Lerper is a queue of items. It will lerp the first one and if it ends\n" -"// and doesn\'t have swap enabled, it will dequeue it.\n" -"type Lerper* = []Item\n" -"\n" -"// Removes the first lerper item.\n" -"fn (l: ^Lerper) dequeue*() {\n" -"\tswitch len(l^) {\n" -"\tcase 0:\n" -"\t\treturn\n" -"\tcase 1:\n" -"\t\tl^ = Lerper{}\n" -"\tdefault:\n" -"\t\tl^ = slice(l^, 1)\n" -"\t}\n" -"}\n" -"\n" -"// Adds an item to l\'s queue\n" -"fn (l: ^Lerper) enqueue*(i: Item) {\n" -"\tl^ = append(l^, i)\n" -"}\n" -"\n" -"// Interpolates the front by delta. And returns it\'s value.\n" -"fn (l: ^Lerper) byDelta*(delta: th.uu): th.fu {\n" -"\tif len(l^) == 0 {\n" -"\t\treturn 0\n" -"\t}\n" -"\n" -"\t/*for l[0].progress >= 1.0 {\n" -"\t\tl[0].callback(l[0].ctx)\n" -"\n" -"\t\tif l[0].swap {\n" -"\t\t\ttmp := l[0].start\n" -"\t\t\tl[0].start = l[0].end\n" -"\t\t\tl[0].end = tmp\n" -"\n" -"\t\t\tl[0].progress = 0\n" -"\t\t\tbreak\n" -"\t\t}\n" -"\n" -"\t\tl.dequeue()\n" -"\t\tif len(l^) == 0 {\n" -"\t\t\treturn 0\n" -"\t\t}\n" -"\t}*/\n" -"\n" -"\tif l[0].progress >= 1 {\n" -"\t\tend := l[0].end\n" -"\t\tl.dequeue()\n" -"\t\treturn end\n" -"\t}\n" -"\n" -"\tl[0].progress += th.fu(delta)/l[0].length\n" -"\n" -"\treturn l[0].progress * (l[0].end-l[0].start) + l[0].start\n" -"}\n" -"", -"//~~\n" -"// Module for font rendering. Unicode is supported, but only left to right.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~Filtering constants\n" -"const (\n" -"\tfilterNearest* = 0\n" -"\tfilterLinear* = 1\n" -")\n" -"//~~\n" -"\n" -"//~~opaque Font\n" -"type Font* = struct { _: ^struct{} }\n" -"//~~\n" -"\n" -"fn umth_font_load(path: str, size: th.fu, filter: uint32): ^struct{}\n" -"//~~fn load\n" -"fn load*(path: str, size: th.fu, filter: uint32 = filterLinear): Font {\n" -"//~~\n" -"\treturn Font{umth_font_load(path, size, filter)}\n" -"}\n" -"\n" -"//~~fn Font.validate\n" -"fn (f: ^Font) validate*(): bool {\n" -"//~~\n" -"\treturn f._ != null\n" -"}\n" -"\n" -"fn umth_font_draw(font: Font, s: str, x: th.fu, y: th.fu, color: uint32, scale: th.fu)\n" -"//~~fn Font.draw\n" -"fn (f: ^Font) draw*(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0) {\n" -"//~~\n" -"\tif !f.validate() {\n" -"\t\tth.__error(\"Invalid font\")\n" -"\t}\n" -"\tumth_font_draw(f^, text, pos.x, pos.y, color, scale)\n" -"}\n" -"\n" -"fn umth_font_measure(font: Font, s: str, o: ^th.Vf2)\n" -"//~~fn Font.measure\n" -"fn (f: ^Font) measure*(text: str): th.Vf2 {\n" -"//~~\n" -"\tif !f.validate() {\n" -"\t\tth.__error(\"Invalid font\")\n" -"\t\treturn {}\n" -"\t}\n" -"\n" -"\tvar size: th.Vf2\n" -"\tumth_font_measure(f^, text, &size)\n" -"\treturn size\n" -"}\n" -"", -"//~~\n" -"// Module with useful variables and types.\n" -"// Variables: time, delta, platform\n" -"// Constants: black, white, red, green, blue, yellow, magenta, cyan.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"std.um\"\n" -")\n" -"\n" -"//~~Tophat type aliases\n" -"// standard type for real values\n" -"type fu* = real32\n" -"// standard type for integer values\n" -"type iu* = int32\n" -"// standard type for unsigned values\n" -"type uu* = uint32\n" -"//~~\n" -"\n" -"//~~struct Vf2\n" -"// vector 2\n" -"type Vf2* = struct {\n" -"\tx, y: fu\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mkVf2\n" -"// Vf2 constructor\n" -"fn mkVf2*(x: fu = 0, y: fu = 0): Vf2 {\n" -"\treturn Vf2{x, y}\n" -"}\n" -"//~~\n" -"\n" -"//~~fn Vf2.rotated\n" -"// rotates `p` around `origin` with `rot` in degrees\n" -"fn (p: ^Vf2) rotated*(origin: Vf2, rot: fu): Vf2 {\n" -"//~~\n" -"\tangle := (rot * std.pi) / 180\n" -"\n" -"\tpos := p^\n" -"\tpos.x -= origin.x\n" -"\tpos.y -= origin.y\n" -"\n" -"\tx := pos.x * cos(angle) - pos.y * sin(angle)\n" -"\ty := pos.x * sin(angle) + pos.y * cos(angle)\n" -"\n" -"\tpos.x = x + origin.x\n" -"\tpos.y = y + origin.y\n" -"\n" -"\treturn pos\n" -"}\n" -"\n" -"//~~fn Vf2.distanceTo\n" -"// distance between p1 and p2\n" -"fn (p1: ^Vf2) distanceTo*(p2: Vf2): fu {\n" -"//~~\n" -"\treturn sqrt((p1.x - p2.x) * (p1.x - p2.x) + (p1.y - p2.y) * (p1.y - p2.y))\n" -"}\n" -"\n" -"//~~fn Vf2.angleTo\n" -"// Angle between p1 and p2\n" -"fn (p1: ^Vf2) angleTo*(p2: Vf2): real {\n" -"//~~\n" -"\tif p1.x == p2.x && p1.y == p2.y { return 0 }\n" -"\treturn atan2(p2.y - p1.y, p2.x - p1.x) * 180 / std.pi + 180\n" -"}\n" -"\n" -"//~~fn Vf2.abs\n" -"// Absolute value of a vector.\n" -"fn (p: ^Vf2) abs*(): Vf2 {\n" -"//~~\n" -"\treturn Vf2{fabs(p.x), fabs(p.y)}\n" -"}\n" -"\n" -"//~~fn Vf2.round\n" -"// Rounds a vector.\n" -"fn (p: ^Vf2) round*(): Vf2 {\n" -"//~~\n" -"\treturn Vf2{round(p.x), round(p.y)}\n" -"}\n" -"\n" -"//~~fn Vf2.trunc\n" -"// Truncates a vector.\n" -"fn (p: ^Vf2) trunc*(): Vf2 {\n" -"//~~\n" -"\treturn Vf2{trunc(p.x), trunc(p.y)}\n" -"}\n" -"\n" -"//~~fn Vf2.floor\n" -"// Floors a vector.\n" -"fn (p: ^Vf2) floor*(): Vf2 {\n" -"//~~\n" -"\treturn Vf2{floor(p.x), floor(p.y)}\n" -"}\n" -"\n" -"//~~fn Vf2.ceil\n" -"// Ceils a vector.\n" -"fn (p: ^Vf2) ceil*(): Vf2 {\n" -"//~~\n" -"\treturn Vf2{ceil(p.x), ceil(p.y)}\n" -"}\n" -"\n" -"//~~fn vf2f\n" -"// Creates a vector with both x and y set to f\n" -"fn vf2f*(f: fu): Vf2 {\n" -"//~~\n" -"\treturn Vf2{f, f}\n" -"}\n" -"\n" -"//~~fn Vf2.sub\n" -"// Subtracts a vector from another one.\n" -"fn (p: ^Vf2) sub*(p2: Vf2): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x - p2.x, p.y - p2.y}\n" -"}\n" -"\n" -"//~~fn Vf2.subf\n" -"// Subtracts a fu from a vector.\n" -"fn (p: ^Vf2) subf*(f: fu): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x - f, p.y - f}\n" -"}\n" -"\n" -"//~~fn Vf2.add\n" -"// Adds a vector to another one.\n" -"fn (p: ^Vf2) add*(p2: Vf2): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x + p2.x, p.y + p2.y}\n" -"}\n" -"\n" -"//~~fn Vf2.addf\n" -"// Adds a fu to a vector.\n" -"fn (p: ^Vf2) addf*(f: fu): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x + f, p.y + f}\n" -"}\n" -"\n" -"//~~fn Vf2.div\n" -"// Divides a vector by another one.\n" -"fn (p: ^Vf2) div*(p2: Vf2): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x / p2.x, p.y / p2.y}\n" -"}\n" -"\n" -"//~~fn Vf2.divf\n" -"// Divides a vector by a fu.\n" -"fn (p: ^Vf2) divf*(f: fu): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x / f, p.y / f}\n" -"}\n" -"\n" -"//~~fn Vf2.mul\n" -"// Multiplies a vector by another one.\n" -"fn (p: ^Vf2) mul*(p2: Vf2): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x * p2.x, p.y * p2.y}\n" -"}\n" -"\n" -"//~~fn Vf2.mulf\n" -"// Multiplies a vector by a fu.\n" -"fn (p: ^Vf2) mulf*(f: fu): Vf2 {\n" -"//~~\n" -"\treturn Vf2{p.x * f, p.y * f}\n" -"}\n" -"\n" -"//~~fn Vf2.mag\n" -"// Returns the magnitude of a vector p.\n" -"fn (p: ^Vf2) mag*(): fu {\n" -"//~~\n" -"\treturn sqrt(p.x * p.x + p.y * p.y)\n" -"}\n" -"\n" -"//~~fn Vf2.norm\n" -"// Normalizes a vector.\n" -"fn (p: ^Vf2) norm*(): Vf2 {\n" -"//~~\n" -"\tif p.x == 0 && p.y == 0 {\n" -"\t\treturn p^\n" -"\t}\n" -"\n" -"\treturn p.divf(p.mag())\n" -"}\n" -"\n" -"//~~fn Vf2.dot\n" -"// Calculates dot product between 2 vectors.\n" -"fn (p: ^Vf2) dot*(q: Vf2): fu {\n" -"//~~\n" -"\treturn p.x*q.x + p.y*q.y\n" -"}\n" -"\n" -"//~~struct Transform\n" -"// Struct defining transformation. Used for example by entities.\n" -"type Transform* = struct {\n" -"\tp: Vf2 // position\n" -"\ts: Vf2 // scale\n" -"\to: Vf2 // origin\n" -"\tr: fu // rotation\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mkTransform\n" -"// Transform constructor\n" -"fn mkTransform*(p: Vf2, s: Vf2 = Vf2{1, 1}, o: Vf2 = Vf2{0, 0}, r: fu = 0.0): Transform {\n" -"//~~\n" -"\treturn Transform{p: p, s: s, o: o, r: r}\n" -"}\n" -"\n" -"fn umth_transform_transform(o, t: ^Transform)\n" -"//~~fn Transform.transformed\n" -"// Transforms a transform with another transform.\n" -"fn (o: ^Transform) transformed*(t: Transform): Transform {\n" -"//~~\n" -"\tret := o^\n" -"\tumth_transform_transform(&ret, &t)\n" -"\n" -"\treturn ret\n" -"}\n" -"\n" -"fn umth_transform_vf2(v: ^Vf2, t: ^Transform)\n" -"//~~fn Vf2.transformed\n" -"// Transforms a vf2 to another vf2.\n" -"// Order:\n" -"// \t1. scale\n" -"// \t2. rotation\n" -"// \t3. position\n" -"//\n" -"// This allows conversion from a relative to an absolute vf2.\n" -"fn (v: ^Vf2) transformed*(t: Transform): Vf2 {\n" -"//~~\n" -"\tret := v^\n" -"\tumth_transform_vf2(&ret, &t)\n" -"\treturn ret\n" -"}\n" -"\n" -"//~~type Quad\n" -"type Quad* = [4]Vf2\n" -"//~~\n" -"\n" -"fn umth_quad_max(o: ^Vf2, q: ^Quad)\n" -"//~~fn Quad.getMax\n" -"// Gets the maximum coordinate.\n" -"fn (q: ^Quad) getMax*(): Vf2 {\n" -"//~~\n" -"\to := Vf2{}\n" -"\tumth_quad_max(&o, q)\n" -"\treturn o\n" -"}\n" -"\n" -"fn umth_quad_min(o: ^Vf2, q: ^Quad)\n" -"//~~fn Quad.getMin\n" -"// Gets the minimum coordinate.\n" -"fn (q: ^Quad) getMin*(): Vf2 {\n" -"//~~\n" -"\to := Vf2{}\n" -"\tumth_quad_min(&o, q)\n" -"\treturn o\n" -"}\n" -"\n" -"//~~fn Quad.getDims\n" -"// Returns the dimensions of the quad\'s bounding box\n" -"fn (q: ^Quad) getDims*(): Vf2 {\n" -"//~~\n" -"\tmax := q[0]\n" -"\tmin := q[0]\n" -"\n" -"\tmaxmag := max.mag()\n" -"\tminmag := min.mag()\n" -"\n" -"\tfor i:=1; i < len(q^); i++ {\n" -"\t\tqmag := q[i].mag()\n" -"\n" -"\t\tif maxmag < qmag {\n" -"\t\t\tmax = q[i]\n" -"\t\t\tmaxmag = qmag\n" -"\t\t}\n" -"\n" -"\t\tif minmag > qmag {\n" -"\t\t\tmin = q[i]\n" -"\t\t\tminmag = qmag\n" -"\t\t}\n" -"\t}\n" -"\n" -"\treturn max.sub(min).abs()\n" -"}\n" -"\n" -"fn umth_th_getglobal(): ^struct{}\n" -"//~~fn getGlobal\n" -"// returns a pointer to the th_global. Set this as your extensions thg.\n" -"fn getGlobal*(): ^struct{} {\n" -"//~~\n" -"\treturn umth_th_getglobal()\n" -"}\n" -"\n" -"fn umth_th_getfuncs(): ^struct{}\n" -"//~~fn getFuncs\n" -"// returns pointer to tophat functions. Pass this to th_ext_set.\n" -"fn getFuncs*(): ^struct{} {\n" -"//~~\n" -"\treturn umth_th_getfuncs()\n" -"}\n" -"\n" -"//~~var enableErrrors\n" -"// If true, errors will result in a call to error(), otherwise printf is used.\n" -"var enableErrors*: bool = true\n" -"//~~\n" -"fn __error*(msg: str) {\n" -"\tif enableErrors {\n" -"\t\terror(msg)\n" -"\t} else {\n" -"\t\tprintf(\"error: %s\\n\", msg)\n" -"\t}\n" -"}\n" -"\n" -"//~~Color constants\n" -"const (\n" -"\tblack* = 0xff\n" -"\twhite* = 0xffffffff\n" -"\tred* = 0xff0000ff\n" -"\tgreen* = 0x00ff00ff\n" -"\tblue* = 0x0000ffff\n" -"\tyellow* = 0xffff00ff\n" -"\tmagenta* = 0xff00ffff\n" -"\tcyan* = 0x00ffffff\n" -")\n" -"//~~\n" -"\n" -"//~~enum Platform\n" -"type Platform* = int\n" -"const (\n" -"\tPlatformUnknown* = 0\n" -"\tPlatformLinux*\n" -"\tPlatformWindows*\n" -"\tPlatformMacOs*\n" -"\tPlatformWeb*\n" -")\n" -"//~~\n" -"\n" -"//~~Misc variables\n" -"var (\n" -"\t// time in ms from start of the game\n" -"\ttime*: uint\n" -"\t// length of the last frame in ms\n" -"\tdelta*: int\n" -"\t// platform tophat is running on\n" -"\tplatform*: Platform\n" -")\n" -"//~~\n" -"", -"//~~\n" -"// A module for importless communication between modules. A signal is a set of\n" -"// callbacks. You can use signals directly in your own structs if you want\n" -"// them to be instance specific, of you can use global signals which are\n" -"// adressed by a string name.\n" -"//~~\n" -"\n" -"//~~type Callback\n" -"// `args` is a list of arguments passed to the `emit` method.\n" -"type Callback* = fn(args: []any)\n" -"//~~\n" -"\n" -"//~~type Id\n" -"type Id* = uint\n" -"//~~\n" -"\n" -"//~~type Signal\n" -"type Signal* = map[Id]Callback\n" -"//~~\n" -"\n" -"var signals: map[str]Signal\n" -"var idCounter: Id\n" -"\n" -"//~~fn mk\n" -"// `Signal` constructor\n" -"fn mk*(): Signal {\n" -"//~~\n" -"\treturn make(Signal)\n" -"}\n" -"\n" -"//~~fn Signal.register\n" -"// Registers a callback to a signal and returns the callback id.\n" -"fn (this: ^Signal) register*(callback: Callback): Id {\n" -"//~~\n" -"\tidCounter++\n" -"\tthis[idCounter] = callback\n" -"\n" -"\treturn idCounter\n" -"}\n" -"\n" -"//~~fn Signal.remove\n" -"// Removes a callback by id.\n" -"fn (this: ^Signal) remove*(id: Id) {\n" -"//~~\n" -"\tdelete(this^, id)\n" -"}\n" -"\n" -"//~~fn Signal.emit\n" -"// Emits a signal.\n" -"fn (this: ^Signal) emit*(args: ..any) {\n" -"//~~\n" -"\tfor _,c in this {\n" -"\t\tc(args)\n" -"\t}\n" -"}\n" -"\n" -"//~~fn Signal.clear\n" -"// Removes all signal handlers.\n" -"fn (this: ^Signal) clear*() {\n" -"//~~\n" -"\tks := keys(this^)\n" -"\n" -"\tfor i, k in ks {\n" -"\t\tthis ^= delete(this^, k)\n" -"\t}\n" -"}\n" -"\n" -"//~~fn register\n" -"// Registers a callback to a global signal. There is no need to explicitly\n" -"// create global signals. Returns id of the added callback\n" -"fn register*(name: str, callback: Callback): Id {\n" -"//~~\n" -"\tif !valid(signals) {\n" -"\t\tsignals = make(map[str]Signal)\n" -"\t}\n" -"\n" -"\treturn signals[name].register(callback)\n" -"}\n" -"\n" -"//~~fn remove\n" -"// Removes a callback from a global signal by id.\n" -"fn remove*(name: str, id: Id) {\n" -"//~~\n" -"\tsignals[name].remove(id)\n" -"}\n" -"\n" -"//~~fn remove\n" -"// Removes all signal handlers from a global signal.\n" -"fn clear*(name: str) {\n" -"//~~\n" -"\tsignals[name].clear()\n" -"}\n" -"\n" -"//~~fn emit\n" -"// Calls all callbacks associated with the passed global signal name.\n" -"fn emit*(name: str, args: ..any) {\n" -"//~~\n" -"\tif !valid(signals) {\n" -"\t\tsignals = make(map[str]Signal)\n" -"\t}\n" -"\n" -"\tsignals[name].emit(args)\n" -"}\n" -"", -"\n" -"import (\n" -"\t\"th.um\"\n" -"\t\"image.um\"\n" -")\n" -"\n" -"//~~struct Atlas\n" -"// Atlas is an image containing tiles in a square grid.\n" -"type Atlas* = struct {\n" -"\ti: image.Image // source image\n" -"\tcs: th.Vf2 // size of a cell in pixels\n" -"\tdm: th.Vf2 // amount of cells in image\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mk\n" -"// i: source image\n" -"// dm: amount of cells\n" -"fn mk*(i: image.Image, dm: th.Vf2): Atlas {\n" -"//~~\n" -"\tif !i.validate() {\n" -"\t\tth.__error(\"Image is not valid\")\n" -"\t}\n" -"\n" -"\ta := Atlas{}\n" -"\n" -"\ta.i = i\n" -"\ta.dm = dm\n" -"\ta.cs = i.getDims().div(dm)\n" -"\n" -"\treturn a\n" -"}\n" -"\n" -"//~~fn Atlas.coords\n" -"// returns the coordinates of the nth tile\n" -"fn (a: ^Atlas) coords*(n: int): th.Vf2 {\n" -"//~~\n" -"\treturn th.Vf2{ n % trunc(a.dm.x), (n - n % trunc(a.dm.x)) / a.dm.x }\n" -"}\n" -"\n" -"//~~fn Atlas.cropSource\n" -"// Crops the sourse image to only show a wanted tile\n" -"fn (a: ^Atlas) cropSource*(at: th.Vf2) {\n" -"//~~\n" -"\tif (at.x > a.dm.x || at.y > a.dm.y || at.x * at.y < 0) {\n" -"\t\treturn\n" -"\t}\n" -"\n" -"\ta.i.crop(\n" -"\t\tth.Vf2{at.x / a.dm.x, at.y / a.dm.y},\n" -"\t\tth.Vf2{(at.x+1) / a.dm.x, (at.y+1) / a.dm.y})\n" -"}\n" -"\n" -"//~~enum PackStrategy\n" -"const (\n" -"\tPackSquare* = 0\n" -"\tPackRow*\n" -"\tPackColumn*\n" -")\n" -"//~~\n" -"\n" -"fn umth_atlas_pack(a: ^Atlas, images: ^[]image.Image, strategy: int)\n" -"\n" -"//~~fn pack\n" -"// Packs an array of images into an atlas\n" -"fn pack*(images: []image.Image, strategy: int): Atlas {\n" -"//~~\n" -"\tvar a: Atlas\n" -"\tumth_atlas_pack(&a, &images, strategy)\n" -"\treturn a\n" -"}\n" -"\n" -"//~~fn Atlas.draw\n" -"// Draws the tile at `at`\n" -"fn (a: ^Atlas) draw*(at: th.Vf2, t: th.Transform) {\n" -"//~~\n" -"\ta.cropSource(at)\n" -"\ta.i.draw(t, th.white)\n" -"\ta.i.crop(th.Vf2{}, th.Vf2{1, 1})\n" -"}\n" -"", -"\n" -"import (\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~opaque Shader\n" -"// Shader allows you to define your own vertex and fragment GLSL shaders. This\n" -"// is a low-level feature, so it\'s very easy to mess up.\n" -"// \n" -"// In tophat, instead of a main function, shaders provide th_vertex and\n" -"// th_fragment. The signature of th_vertex is:\n" -"// \n" -"// ```\n" -"// vec2 th_vertex(vec2 vert);\n" -"// ```\n" -"// \n" -"// where vert is the position of the vertex taken from the vertex buffer.\n" -"// The output is the vertex shader output.\n" -"// \n" -"// As for fragment shaders, there are two types of them. One for canvas\n" -"// and one for images. In canvas shaders, the fragment function is very simple:\n" -"// \n" -"// ```\n" -"// vec4 th_fragment(vec4 color);\n" -"// ```\n" -"// \n" -"// Image fragment function looks like this:\n" -"// \n" -"// ```\n" -"// vec4 th_fragment(sampler2D tex, vec2 coord);\n" -"// ```\n" -"// \n" -"// where tex is the texture and coord are the texture coordinates. Be aware to\n" -"// swap the output of the `texture2D` function. Example:\n" -"// \n" -"// ```\n" -"// texture2D(tex, coord).abgr\n" -"// ```\n" -"type Shader* = struct {\n" -"//~~\n" -"\thandle: int\n" -"}\n" -"\n" -"\n" -"//~~Default shader constants\n" -"const (\n" -"\tdefaultImageShader* = Shader{1}\n" -"\tdefaultCanvasShader* = Shader{2}\n" -")\n" -"//~~\n" -"\n" -"//~~struct Uniform\n" -"// Represents a GLSL uniform.\n" -"type Uniform* = struct {\n" -"\ts: Shader\n" -"\tl: uint\n" -"}\n" -"//~~\n" -"\n" -"fn umth_shader_compile_canvas(vertex, fragment: str): int\n" -"//~~fn mkCanvas\n" -"// Compiles a canvas shader from source. If there is a compilation error, it\n" -"// will print something to the console.\n" -"fn mkCanvas*(vertex, fragment: str): Shader {\n" -"//~~\n" -"\treturn Shader{umth_shader_compile_canvas(vertex, fragment)}\n" -"}\n" -"\n" -"fn umth_shader_compile_image(vertex, fragment: str): int\n" -"//~~fn mkImage\n" -"// Compiles an image shader from source. If there is a compilation error, it\n" -"// will print something to the console.\n" -"fn mkImage*(vertex, fragment: str): Shader {\n" -"//~~\n" -"\treturn Shader{umth_shader_compile_image(vertex, fragment)}\n" -"}\n" -"\n" -"fn umth_shader_pick_canvas(handle: int)\n" -"//~~fn Shader.pickForCanvas\n" -"// Picks the shader to be used for canvas drawing. Flushes the canvas batch.\n" -"fn (s: ^Shader) pickForCanvas*() {\n" -"//~~\n" -"\tumth_shader_pick_canvas(s.handle)\n" -"}\n" -"\n" -"fn umth_shader_pick_image(handle: int)\n" -"//~~fn Shader.pickForImage\n" -"// Picks the shader to be used for image drawing. Flushes the image batch.\n" -"fn (s: ^Shader) pickForImage*() {\n" -"//~~\n" -"\tumth_shader_pick_image(s.handle)\n" -"}\n" -"\n" -"fn umth_shader_get_uniform_location(handle: int, name: str): uint\n" -"//~~fn Shader.getUniformLocation\n" -"// Retunrs a uniform by name.\n" -"fn (s: ^Shader) getUniformLocation*(name: str): Uniform {\n" -"//~~\n" -"\treturn Uniform{s^, umth_shader_get_uniform_location(s.handle, name)}\n" -"}\n" -"\n" -"fn umth_shader_set_uniform_int(shandle, uhandle: uint, value: int)\n" -"//~~fn Uniform.setInt\n" -"// Sets a uniform to an int value. Flushes both batches.\n" -"fn (u: ^Uniform) setInt*(value: int) {\n" -"//~~\n" -"\tumth_shader_set_uniform_int(u.s.handle, u.l, value)\n" -"}\n" -"\n" -"fn umth_shader_set_uniform_vf2(shandle, uhandle: uint, value: th.Vf2)\n" -"//~~fn Uniform.setVf2\n" -"// Sets a uniform to a vf2. Flushes both batches.\n" -"fn (u: ^Uniform) setVf2*(value: th.Vf2) {\n" -"//~~\n" -"\tumth_shader_set_uniform_vf2(u.s.handle, u.l, value)\n" -"}\n" -"", -"//~~\n" -"// Color operations. Operate on RGBA uint32 values.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"th.um\"\n" -")\n" -"\n" -"fn umth_hsv2rgb_uint32(h, s, v, a: th.fu): uint32\n" -"\n" -"// Now this is hard to decide, but in my opinion executing a C function,\n" -"// for the current Umka VM would be much better than implementing it in umka itself.\n" -"// It\'s somewhat less trivial than most other operations like alpha.\n" -"fn umth_rgb_uint32(r, g, b, a: th.fu): uint32\n" -"\n" -"//~~fn hsv\n" -"// Converts HSV values into RGBA uint32 color.\n" -"// NOTE: Hue is between 0 and 1\n" -"fn hsv*(h, s, v: th.fu, a: th.fu = 1.0): uint32 {\n" -"//~~\n" -"\treturn umth_hsv2rgb_uint32(h, s, v, a);\n" -"}\n" -"\n" -"//~~fn alpha\n" -"// Sets alpha of the color c to a value in to.\n" -"fn alpha*(c: uint32, to: th.fu): uint32 {\n" -"//~~\n" -"\treturn (c & 0xFFFFFF00) | (trunc(to * 255) & 0xFF)\n" -"}\n" -"\n" -"//~~fn rgb\n" -"// Constructs RGBA uint32 from RGBA of reals.\n" -"fn rgb*(r, g, b: th.fu, a: th.fu = 1.0): uint32 {\n" -"//~~\n" -"\treturn umth_rgb_uint32(r, g, b, a)\n" -"}\n" -"\n" -"", -"//~~\n" -"// Builtin collision functions. The ic argument stores the collision position.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"th.um\"\n" -"\t\"rect.um\"\n" -")\n" -"\n" -"fn umth_coll_line_to_line(b1, e1, b2, e2, ic: ^th.Vf2): bool\n" -"//~~fn lineToLine\n" -"// Checks for a collision between 2 lines specified by their end points.\n" -"fn lineToLine*(b1, e1, b2, e2: th.Vf2, ic: ^th.Vf2): bool {\n" -"//~~\n" -"\treturn umth_coll_line_to_line(&b1, &e1, &b2, &e2, ic)\n" -"}\n" -"\n" -"fn umth_coll_point_to_quad(p: ^th.Vf2, q: ^th.Quad, ic: ^th.Vf2): bool\n" -"//~~fn vf2ToQuad\n" -"// Checks for a collision between a vf2 and a quad.\n" -"fn vf2ToQuad*(p: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n" -"//~~\n" -"\treturn umth_coll_point_to_quad(&p, &q, ic)\n" -"}\n" -"\n" -"fn umth_coll_line_to_quad(b, e: ^th.Vf2, q: ^th.Quad, ic: ^th.Vf2): bool\n" -"//~~fn lineToQuad\n" -"// Check for a collision between a line and quad edges.\n" -"fn lineToQuad*(b, e: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n" -"//~~\n" -"\treturn umth_coll_line_to_quad(&b, &e, &q, ic)\n" -"}\n" -"\n" -"fn umth_coll_quad_to_quad(q1, q2: ^th.Quad, ic: ^th.Vf2): bool\n" -"//~~fn quadToQuad\n" -"// Check for a collision between two quads.\n" -"fn quadToQuad*(q1, q2: th.Quad, ic: ^th.Vf2): bool {\n" -"//~~\n" -"\treturn umth_coll_quad_to_quad(&q1, &q2, ic)\n" -"}\n" -"\n" -"fn umth_coll_point_to_rect(p: th.Vf2, r: ^rect.Rect): bool\n" -"//~~fn vf2ToRect\n" -"// Check for a collision between a vf2 and a rectangle.\n" -"fn vf2ToRect*(p: th.Vf2, r: rect.Rect): bool {\n" -"//~~\n" -"\treturn umth_coll_point_to_rect(p, &r)\n" -"}\n" -"\n" -"fn umth_coll_rect_to_rect(r1, r2: ^rect.Rect): bool\n" -"//~~fn rectToRect\n" -"// Check for a collision between two rects\n" -"fn rectToRect*(r1, r2: rect.Rect): bool {\n" -"//~~\n" -"\treturn umth_coll_rect_to_rect(&r1, &r2)\n" -"}\n" -"\n" -"", -"import(\"image.um\"; \"th.um\")\n" -"\n" -"//~~Placeholder images\n" -"// These images are included with tophat and don\'t have to be loaded.\n" -"var (\n" -"\t// an image useful for testing\n" -"\ttest*: image.Image\n" -"\t// the image used for the app icon\n" -"\ticon*: image.Image\n" -"\t// Windows 95 style button, to be used with ninepatch (image.um) \n" -"\tbutton*: image.Image\n" -")\n" -"//~~\n" -"\n" -"fn umth_placeholder_fetch(id: uint32): ^struct{}\n" -"\n" -"// **INTERNAL**\n" -"fn __setup*() {\n" -"\ttest = image.Image{umth_placeholder_fetch(0)}\n" -"\ticon = image.Image{umth_placeholder_fetch(1)}\n" -"\tbutton = image.Image{umth_placeholder_fetch(2)}\n" -"}\n" -"\n" -"", -"\n" -"import (\n" -"\t\"canvas.um\"\n" -"\t\"color.um\"\n" -"\t\"rect.um\"\n" -"\t\"th.um\"\n" -")\n" -"\n" -"//~~struct Mesh\n" -"// Mesh is a 2d array of bool cells. If a cell is true, the cell can be used\n" -"// in a path. The mesh is located in a world using the `r` field. A cell can\n" -"// have an arbitrary size as specified by `s`.\n" -"// \n" -"// The mesh can be edited using the `addQuad` method, but it should be trivial\n" -"// to add your own, similar methods.\n" -"// \n" -"// Please use the `mk` constructor to construct a `Mesh`, unless you really\n" -"// know what you\'re doing.\n" -"type Mesh* = struct {\n" -"\t// The mesh data.\n" -"\td: []bool\n" -"\t// The dimensions and position of the mesh, r.w == w * s\n" -"\tr: rect.Rect\n" -"\t// Width of the mesh. Used to adress the mesh data.\n" -"\tw: th.uu\n" -"\t// Scale of one cell (cell is a square)\n" -"\ts: th.fu\n" -"}\n" -"//~~\n" -"\n" -"//~~fn mk\n" -"// Creates a new nav mesh.\n" -"// `r`\n" -"// : the rectangle of the mask\n" -"// \'s\'\n" -"// : the scale of the mask\n" -"fn mk*(r: rect.Rect, s: th.fu): Mesh {\n" -"//~~\n" -"\n" -"\tm := Mesh{}\n" -"\n" -"\tm.d = make([]bool, ceil(r.w/s) * ceil(r.h/s))\n" -"\tfor i in m.d {\n" -"\t\tm.d[i] = true\n" -"\t}\n" -"\n" -"\tm.w = trunc(r.w/s)\n" -"\tm.s = s\n" -"\tm.r = r\n" -"\n" -"\treturn m\n" -"}\n" -"\n" -"fn umth_nav_mesh_add_quad(m: ^Mesh, q: ^th.Quad)\n" -"//~~fn Mesh.addQuad\n" -"// Sets mask\'s fields overlapping `q` to `false`.\n" -"fn (m: ^Mesh) addQuad*(q: th.Quad) {\n" -"//~~\n" -"\tumth_nav_mesh_add_quad(m, &q)\n" -"}\n" -"\n" -"fn umth_nav_mesh_nav(cameFrom: ^[]th.Vf2, cameFromType: ^void, m: ^Mesh, p1, p2: th.Vf2)\n" -"//~~fn Mesh.nav\n" -"// Navigates between `p1` and `p2`. Returns the path as an array of `th.Vf2`s.\n" -"// If it doesn\'t find any path, or one of the points is outside of the mask,\n" -"// returns an empty array.\n" -"fn (m: ^Mesh) nav*(p1, p2: th.Vf2): []th.Vf2 {\n" -"//~~\n" -"\tvar cameFrom: []th.Vf2\n" -"\tumth_nav_mesh_nav(&cameFrom, typeptr([]th.Vf2), m, p1, p2)\n" -"\t\n" -"\tpath := []th.Vf2{p2}\n" -"\tp := p2\n" -"\tp.x = trunc((p.x - m.r.x) / m.s)\n" -"\tp.y = trunc((p.y - m.r.y) / m.s)\n" -"\n" -"\tp1.x = trunc((p1.x - m.r.x) / m.s)\n" -"\tp1.y = trunc((p1.y - m.r.y) / m.s)\n" -"\tfor (p.x != p1.x || p.y != p1.y) && p.x >= 0 && p.y >= 0 {\n" -"\t\tp = cameFrom[trunc(p.x + p.y*m.w)]\n" -"\n" -"\t\tpath = append(path, th.Vf2{\n" -"\t\t\tp.x * m.s + m.r.x + m.s/2,\n" -"\t\t\tp.y * m.s + m.r.y + m.s/2 })\n" -"\t}\n" -"\n" -"\tfor i:=0; i < len(path)/2; i++ {\n" -"\t\tt := path[i]\n" -"\t\tpath[i] = path[len(path) - i - 1]\n" -"\t\tpath[len(path) - i - 1] = t\n" -"\t}\n" -"\n" -"\t// path not found is the first element is [-1; -1]\n" -"\tif len(path) > 0 && path[0].x < m.r.x {\n" -"\t\treturn []th.Vf2{}\n" -"\t}\n" -"\n" -"\treturn path\n" -"}\n" -"\n" -"//~~fn Mesh.draw\n" -"// Draws the mesh for debugging purposes.\n" -"fn (m: ^Mesh) draw*(alpha: real32 = 1.0) {\n" -"//~~\n" -"\tfor x:=0; x < m.w; x++ {\n" -"\t\tfor y:=0; y < len(m.d)/m.w; y += 1 {\n" -"\t\t\tc := th.cyan\n" -"\t\t\tif m.d[x + y*m.w] {\n" -"\t\t\t\tc = th.black\n" -"\t\t\t}\n" -"\t\t\tc = color.alpha(c, alpha)\n" -"\t\t\tcanvas.drawRect(c, rect.mk(m.r.x + x*m.s, m.r.y + y*m.s, m.s, m.s))\n" -"\t\t}\n" -"\t}\n" -"}\n" -"", -"//~~\n" -"// `ui.um` offers an immediate GUI library suitable both for simple game menus\n" -"// and more complex applications. See the [tutorial](/tut/spritesheet.html)\n" -"// for example usage.\n" -"//~~\n" -"\n" -"import (\n" -"\t\"canvas.um\"\n" -"\t\"coll.um\"\n" -"\t\"image.um\"\n" -"\t\"input.um\"\n" -"\t\"placeholders.um\"\n" -"\t\"rect.um\"\n" -"\t\"th.um\"\n" -"\t\"utf8.um\"\n" -")\n" -"\n" -"//~~struct BoxStyle\n" -"// `BoxStyle` describes how a box within the GUI is styled. In this case box\n" -"// can be anything, ranging from a button to a container. By default the box\n" -"// is drawn using the `image.Image.drawNinepatch` method. However if the image\n" -"// is invalid, a rectangle with color `color` is drawn.\n" -"type BoxStyle* = struct {\n" -"\timg: image.Image\n" -"\touter, inner: rect.Rect\n" -"\tscale: th.fu\n" -"\tcolor: uint32\n" -"}\n" -"//~~\n" -"\n" -"//~~interface Font\n" -"// This interface is used by all elements that draw text. A `font.Font`\n" -"// implements this interface.\n" -"type Font* = interface {\n" -"\tdraw(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0)\n" -"\tmeasure(test: str): th.Vf2\n" -"}\n" -"//~~\n" -"\n" -"//~~struct PixelFont\n" -"// This struct implement the `Font` interface using the `canvas.um` pixel font.\n" -"type PixelFont* = struct { }\n" -"//~~\n" -"\n" -"fn (this: ^PixelFont) draw*(t: str, p: th.Vf2, c: uint32, s: th.fu = 1.0) {\n" -"\tcanvas.drawText(t, p, c, s)\n" -"}\n" -"\n" -"fn (this: ^PixelFont) measure*(t: str): th.Vf2 {\n" -"\treturn canvas.textSize(t, 1)\n" -"}\n" -"\n" -"//~~struct Style\n" -"// `Style` is used as a global state for styling the GUI.\n" -"type Style* = struct {\n" -"\t// current font\n" -"\tft: Font\n" -"\t// font scale\n" -"\tftScale: th.fu\n" -"\t// text color\n" -"\tftColor: uint32\n" -"\n" -"\t// Positive box - i. e. unpressed button\n" -"\tposBox: BoxStyle\n" -"\t// Negative box - i. e. pressed button, text box\n" -"\tnegBox: BoxStyle\n" -"\t// Used to draw containers\n" -"\tcontainerBox: BoxStyle\n" -"}\n" -"//~~\n" -"\n" -"//~~interface Container\n" -"// Containers are used to layout elements or other containers.\n" -"type Container* = interface {\n" -"\t// This adds a rectangle to the container, and returns the rectangle\n" -"\t// which was actually added (the container can modify the rectangle).\n" -"\t// See individual containers for further documentation.\n" -"\tpushRect(r: rect.Rect): rect.Rect\n" -"\tgetDims(): rect.Rect\n" -"}\n" -"//~~\n" -"\n" -"//~~struct Gui\n" -"// This is the main struct of any UI. Styles and containers are in a stack.\n" -"type Gui* = struct {\n" -"\t// user context passed to layout functions\n" -"\tctx: any\n" -"\n" -"\t// the index of the current selection. TODO implement properly\n" -"\tselection: int\n" -"\t// true, if the layout is being evaluated, not drawn\n" -"\tisEval: bool\n" -"\t// contains more unexported fields\n" -"//~~\n" -"\tidx: int\n" -"\n" -"\tm1Pressed: bool\n" -"\tm2Pressed: bool\n" -"\tm3Pressed: bool\n" -"\n" -"\tstyle: []Style\n" -"\tcontainer: []Container\n" -"}\n" -"\n" -"//~~fn mk\n" -"// Creates a new gui spanning `r`, with style `s`.\n" -"fn mk*(r: rect.Rect, s: Style): Gui\n" -"//~~\n" -"\n" -"//~~type LayoutFn\n" -"// The layout function calls different element or container methods to create\n" -"// the user interface itself. It is called in the `eval` and `draw`.\n" -"type LayoutFn* = fn(gui: ^Gui)\n" -"//~~\n" -"\n" -"//~~fn BoxStyle.draw\n" -"// Draws a rectangle using a BoxStyle\n" -"fn (this: ^BoxStyle) draw*(r: rect.Rect) {\n" -"//~~\n" -"\tif !this.img.validate() {\n" -"\t\tcanvas.drawRect(this.color, r)\n" -"\t\treturn\n" -"\t}\n" -"\n" -"\tthis.img.drawNinepatch(this.outer, this.inner, r, this.color,\n" -"\t\tthis.scale)\n" -"}\n" -"\n" -"//~~fn Gui.pushStyle\n" -"// Pushes a style onto the style stack.\n" -"fn (this: ^Gui) pushStyle*(s: Style) {\n" -"//~~\n" -"\tthis.style = append(this.style, s)\n" -"}\n" -"\n" -"//~~fn Gui.popStyle\n" -"// Pops a style from the style stack.\n" -"fn (this: ^Gui) popStyle*() {\n" -"//~~\n" -"\tif len(this.style) > 1 {\n" -"\t\tthis.style = slice(this.style, 0, len(this.style) - 1)\n" -"\t}\n" -"}\n" -"\n" -"//~~fn Gui.getStyle\n" -"// Returns a pointer to the style atop the style stack.\n" -"fn (this: ^Gui) getStyle*(): ^Style {\n" -"//~~\n" -"\treturn &this.style[len(this.style) - 1]\n" -"}\n" -"\n" -"//~~fn Gui.getContainer\n" -"// Returns the container atop the container stack.\n" -"fn (this: ^Gui) getContainer*(): Container {\n" -"//~~\n" -"\treturn this.container[len(this.container) - 1]\n" -"}\n" -"\n" -"//~~fn Gui.pushRect\n" -"// Shortcut to `this.getContainer().pushRect(r)`\n" -"fn (this: ^Gui) pushRect*(r: rect.Rect): rect.Rect {\n" -"//~~\n" -"\treturn this.getContainer().pushRect(r)\n" -"}\n" -"\n" -"//~~fn Gui.getDims\n" -"// Shortcut to `this.getContainer().getDims(r)`\n" -"fn (this: ^Gui) getDims*(): rect.Rect {\n" -"//~~\n" -"\treturn this.getContainer().getDims()\n" -"}\n" -"\n" -"//~~fn Gui.dupStyle\n" -"// Duplicates the current style.\n" -"fn (this: ^Gui) dupStyle*() {\n" -"//~~\n" -"\tthis.pushStyle(this.getStyle()^)\n" -"}\n" -"\n" -"//~~fn Gui.pushContainer\n" -"// Pushes a container onto the container stack.\n" -"fn (this: ^Gui) pushContainer*(c: Container) {\n" -"//~~\n" -"\tthis.container = append(this.container, c)\n" -"}\n" -"\n" -"//~~fn Gui.popContainer\n" -"// Pops a container from the container stack.\n" -"fn (this: ^Gui) popContainer*() {\n" -"//~~\n" -"\tif len(this.container) > 1 {\n" -"\t\tthis.container =\n" -"\t\t\tslice(this.container, 0, len(this.container) - 1)\n" -"\t}\n" -"}\n" -"\n" -"fn (this: ^Gui) hover(r: rect.Rect): bool {\n" -"\treturn coll.vf2ToRect(input.getMousePos(), r)\n" -"}\n" -"\n" -"//~~fn Gui.eval\n" -"// Runs the evaluation phase on `layout`.\n" -"fn (this: ^Gui) eval*(layout: LayoutFn) {\n" -"//~~\n" -"\tif input.isJustPressed(input.mouse1) { this.m1Pressed = true }\n" -"\tif input.isJustReleased(input.mouse1) { this.m1Pressed = false }\n" -"\tif input.isJustPressed(input.mouse2) { this.m2Pressed = true }\n" -"\tif input.isJustReleased(input.mouse2) { this.m2Pressed = false }\n" -"\tif input.isJustPressed(input.mouse3) { this.m3Pressed = true }\n" -"\tif input.isJustReleased(input.mouse3) { this.m3Pressed = false }\n" -"\n" -"\tthis.idx = 0\n" -"\tthis.isEval = true\n" -"\tlayout(this)\n" -"\n" -"\tif this.hover(this.container[0].getDims()) {\n" -"\t\t\tinput.clear(input.mouse1)\n" -"\t\t\tinput.clear(input.mouse2)\n" -"\t\t\tinput.clear(input.mouse3)\n" -"\t}\n" -"}\n" -"\n" -"//~~fn Gui.draw\n" -"// Runs the draw phase on `layout`.\n" -"fn (this: ^Gui) draw*(layout: LayoutFn) {\n" -"//~~\n" -"\tthis.idx = 0\n" -"\tthis.isEval = false\n" -"\tlayout(this)\n" -"}\n" -"\n" -"//~~enum BoxGrow\n" -"// The different types of \"growing\" the box can do.\n" -"type BoxGrow* = uint\n" -"const (\n" -"\t// Increments by an amount set by the user.\n" -"\tBoxGrowDimension* = BoxGrow(0)\n" -"\t// Divides the container into `n` equal parts.\n" -"\tBoxGrowSubdivision* = BoxGrow(1)\n" -"\t// Grows the box based on values in the span array.\n" -"\tBoxGrowSpan* = BoxGrow(2)\n" -"\tBoxGrowPxSpan* = BoxGrow(3)\n" -")\n" -"//~~\n" -"\n" -"//~~enum BoxDirection\n" -"// Direction in which the box will grow.\n" -"type BoxDirection* = uint\n" -"const (\n" -"\tBoxDirectionDown* = BoxDirection(0)\n" -"\tBoxDirectionRight* = BoxDirection(1)\n" -"\tBoxDirectionUp* = BoxDirection(2)\n" -"\tBoxDirectionLeft* = BoxDirection(3)\n" -")\n" -"//~~\n" -"\n" -"//~~struct BoxConfig\n" -"// Configuration of the `Box` container.\n" -"type BoxConfig* = struct {\n" -"\t// dimension to grow by if `BoxGrowDimension` is used\n" -"\tdimension: th.fu\n" -"\t// number of subdivisions if `BoxGrowSubdivisions` is used\n" -"\tsubdivisions: uint\n" -"\t// the grow type\n" -"\tgrowType: BoxGrow\n" -"\t// the grow direction\n" -"\tdir: BoxDirection\n" -"\t// Specifies the values used with BoxGrowSpan nad BoxGrowPxSpan.\n" -"\t// If BoxGrowSpan is used, 1 equals the size of the box divided by the sum\n" -"\t// of all spans.\n" -"\t// If BoxGrowPxSpan is used, 1 equals one pixel.\n" -"\tspan: []th.fu\n" -"\t// rect passed to the current container\n" -"\trect: rect.Rect\n" -"\t// padding inserted after each element\n" -"\tpadding: th.fu\n" -"}\n" -"//~~\n" -"\n" -"//~~struct Box\n" -"// `Box` is the main layout. It puts the elements next to each other,\n" -"// according to the config.\n" -"//\n" -"// If the dimensions of the rect passed to `pushRect` are non zero, they will\n" -"// be kept. Position is always forced.\n" -"type Box* = struct {\n" -"\tgrow: th.fu\n" -"\tspanCursor: int\n" -"\tdm: rect.Rect\n" -"\tcfg: BoxConfig\n" -"}\n" -"//~~\n" -"\n" -"fn (this: ^Box) getGrow(): th.fu {\n" -"\tswitch this.cfg.growType {\n" -"\t// These values are constant and can therefore be only calculated once.\n" -"\tcase BoxGrowDimension:\n" -"\t\treturn this.grow\n" -"\tcase BoxGrowSubdivision:\n" -"\t\treturn this.grow\n" -"\tcase BoxGrowSpan:\n" -"\t\t// We store the amount of pixels per a span in the grow array.\n" -"\t\tsp := this.cfg.span[this.spanCursor]\n" -"\t\tthis.spanCursor = (this.spanCursor + 1) % len(this.cfg.span)\n" -"\t\treturn sp * this.grow\n" -"\tcase BoxGrowPxSpan:\n" -"\t\tsp := this.cfg.span[this.spanCursor]\n" -"\t\tthis.spanCursor = (this.spanCursor + 1) % len(this.cfg.span)\n" -"\t\treturn sp\n" -"\t}\n" -"\n" -"\treturn 0\n" -"}\n" -"\n" -"fn (this: ^Box) pushRect(r: rect.Rect): rect.Rect {\n" -"\tswitch this.cfg.dir {\n" -"\tcase BoxDirectionDown:\n" -"\t\tr.x = this.dm.x\n" -"\t\tr.y = this.dm.y\n" -"\n" -"\t\tif r.h == 0 {\n" -"\t\t\tr.h = this.getGrow()\n" -"\t\t}\n" -"\n" -"\t\tif r.w == 0 {\n" -"\t\t\tr.w = this.dm.w\n" -"\t\t}\n" -"\n" -"\t\tthis.dm.y += r.h + this.cfg.padding\n" -"\tcase BoxDirectionRight:\n" -"\t\tr.x = this.dm.x\n" -"\t\tr.y = this.dm.y\n" -"\n" -"\t\tif r.h == 0 {\n" -"\t\t\tr.h = this.dm.h\n" -"\t\t}\n" -"\n" -"\t\tif r.w == 0 {\n" -"\t\t\tr.w = this.getGrow()\n" -"\t\t}\n" -"\n" -"\t\tthis.dm.x += r.w + this.cfg.padding\n" -"\tcase BoxDirectionUp:\n" -"\t\tif r.h == 0 {\n" -"\t\t\tr.h = this.getGrow()\n" -"\t\t}\n" -"\n" -"\t\tif r.w == 0 {\n" -"\t\t\tr.w = this.dm.w\n" -"\t\t}\n" -"\n" -"\t\tthis.dm.h -= r.h + this.cfg.padding\n" -"\t\tr.x = this.dm.x\n" -"\t\tr.y = this.dm.y + this.dm.h\n" -"\tcase BoxDirectionLeft:\n" -"\t\tif r.h == 0 {\n" -"\t\t\tr.h = this.dm.h\n" -"\t\t}\n" -"\n" -"\t\tif r.w == 0 {\n" -"\t\t\tr.w = this.getGrow()\n" -"\t\t}\n" -"\n" -"\t\tthis.dm.w -= r.w + this.cfg.padding\n" -"\t\tr.x = this.dm.x + this.dm.w\n" -"\t\tr.y = this.dm.y\n" -"\t}\n" -"\n" -"\treturn r\n" -"}\n" -"\n" -"fn (this: ^Box) getDims(): rect.Rect {\n" -"\treturn this.dm\n" -"}\n" -"\n" -"//~~fn Gui.box\n" -"// Adds the `Box` container to the gui.\n" -"fn (gui: ^Gui) box*(cfg: BoxConfig = {\n" -"\tdimension: 30,\n" -"\tgrowType: BoxGrowDimension,\n" -"\tdir: BoxDirectionDown }) {\n" -"//~~\n" -"\n" -"\tb := Box{}\n" -"\tb.dm = gui.pushRect(cfg.rect)\n" -"\tb.cfg = cfg\n" -"\n" -"\tdm := b.dm.h\n" -"\tif cfg.dir == BoxDirectionRight || cfg.dir == BoxDirectionLeft {\n" -"\t\tdm = b.dm.w\n" -"\t}\n" -"\tdm += b.cfg.padding\n" -"\n" -"\tswitch cfg.growType {\n" -"\tcase BoxGrowDimension:\n" -"\t\tb.grow = cfg.dimension\n" -"\tcase BoxGrowSubdivision:\n" -"\t\tif cfg.subdivisions == 0 {\n" -"\t\t\terror(\"Invalid subdivision count\")\n" -"\t\t}\n" -"\n" -"\t\tb.grow = dm / cfg.subdivisions\n" -"\tcase BoxGrowSpan:\n" -"\t\ts := th.fu(0)\n" -"\t\tfor _,v in b.cfg.span {\n" -"\t\t\ts += v\n" -"\t\t}\n" -"\n" -"\t\tb.grow = dm / s\n" -"\t}\n" -"\n" -"\tif !gui.isEval {\n" -"\t\tgui.getStyle().containerBox.draw(b.dm)\n" -"\t}\n" -"\n" -"\tgui.pushContainer(b)\n" -"}\n" -"\n" -"//~~struct StackConfig\n" -"// Configuration for the `Stack` container.\n" -"type StackConfig* = struct {\n" -"\trect: rect.Rect\n" -"\tpadding: th.fu\n" -"}\n" -"//~~\n" -"\n" -"//~~struct Stack\n" -"// The stack container puts elements on top of each other.\n" -"// If a property of the rect passed to `pushRect` is zero, it will be changed\n" -"// to an equivalent property of the containers\' dimensions (minus the padding),\n" -"// else it will stay the same. This means stack can be used either to put\n" -"// multiple elements/containers on top of each other, or for absolutely\n" -"// positioned elements.\n" -"type Stack* = struct {\n" -"\tdm: rect.Rect\n" -"\tcfg: StackConfig\n" -"}\n" -"//~~\n" -"\n" -"fn (this: ^Stack) pushRect(r: rect.Rect): rect.Rect {\n" -"\tr.x += this.dm.x + this.cfg.padding\n" -"\tr.y += this.dm.y + this.cfg.padding\n" -"\tif r.w == 0 { r.w = this.dm.w - 2*this.cfg.padding }\n" -"\tif r.h == 0 { r.h = this.dm.h - 2*this.cfg.padding }\n" -"\n" -"\treturn r\n" -"}\n" -"\n" -"fn (this: ^Stack) getDims(): rect.Rect {\n" -"\treturn this.dm\n" -"}\n" -"\n" -"//~~fn Gui.stack\n" -"// Adds the `Stack` container to the gui.\n" -"fn (gui: ^Gui) stack*(cfg: StackConfig = {}) {\n" -"//~~\n" -"\tgui.pushContainer(Stack{\n" -"\t\tdm: gui.pushRect(cfg.rect),\n" -"\t\tcfg: cfg })\n" -"\n" -"\tif !gui.isEval {\n" -"\t\tgui.getStyle().containerBox.draw(gui.getContainer().getDims())\n" -"\t}\n" -"}\n" -"\n" -"//~~struct ScrollAreaConfig\n" -"// Configuration for the scroll area.\n" -"type ScrollAreaConfig* = struct {\n" -"\trect: rect.Rect\n" -"\t// scroll speed. Default is 1\n" -"\tspeed: real32\n" -"\t// if true, scrolling will be horizontal\n" -"\thorizontal: bool\n" -"}\n" -"//~~\n" -"\n" -"//~~struct ScrollArea\n" -"// Scroll area is a container which allows the user to scroll. It acts as a\n" -"// stack container, but all the elements are shifted by the scroll.\n" -"type ScrollArea* = struct {\n" -"\tdm: rect.Rect\n" -"\tcfg: ScrollAreaConfig\n" -"\tscroll: ^real32\n" -"\tmaxScroll: real32\n" -"}\n" -"//~~\n" -"\n" -"fn (this: ^ScrollArea) pushRect(r: rect.Rect): rect.Rect {\n" -"\tif r.x == 0 { r.x = this.dm.x }\n" -"\tif r.y == 0 { r.y = this.dm.y }\n" -"\tif this.cfg.horizontal {\n" -"\t\tif r.w == 0 { r.w = this.maxScroll }\n" -"\t\tif r.h == 0 { r.h = this.dm.h }\n" -"\t\treturn { r.x - this.scroll^, r.y, r.w, r.h }\n" -"\t}\n" -"\n" -"\tif r.w == 0 { r.w = this.dm.w }\n" -"\tif r.h == 0 { r.h = this.maxScroll }\n" -"\treturn { r.x, r.y - this.scroll^, r.w, r.h }\n" -"}\n" -"\n" -"fn (this: ^ScrollArea) getDims(): rect.Rect {\n" -"\treturn this.dm\n" -"}\n" -"\n" -"//~~fn Gui.scrollArea\n" -"// Pushes a scroll area. `scroll` is both input and output value. Both `scroll`\n" -"// and `maxScroll` are in pixels.\n" -"fn (gui: ^Gui) scrollArea*(scroll: ^real32, maxScroll: real32, cfg: ScrollAreaConfig = {}) {\n" -"//~~\n" -"\tif cfg.speed == 0 {\n" -"\t\tcfg.speed = 1\n" -"\t}\n" -"\n" -"\tthis := ScrollArea{\n" -"\t\tdm: gui.pushRect(cfg.rect),\n" -"\t\tcfg: cfg,\n" -"\t\tscroll: scroll }\n" -"\tgui.pushContainer(this)\n" -"\n" -"\tdm := this.dm.h\n" -"\tif this.cfg.horizontal {\n" -"\t\tdm = this.dm.w\n" -"\t}\n" -"\n" -"\tif maxScroll < dm {\n" -"\t\tscroll ^= 0\n" -"\t\treturn\n" -"\t}\n" -"\n" -"\tif gui.isEval && gui.hover(this.dm) {\n" -"\t\tv := input.getMouseScroll().y\n" -"\t\tif this.cfg.horizontal {\n" -"\t\t\tv = input.getMouseScroll().x\n" -"\t\t}\n" -"\n" -"\t\tscroll ^= scroll^ - v*th.delta*this.cfg.speed\n" -"\t\tif scroll^ < 0 { scroll^ = 0 }\n" -"\t\tif maxScroll > dm && scroll^ >= maxScroll - dm { scroll^ = maxScroll - dm }\n" -"\t\tif maxScroll < dm && scroll^ >= maxScroll { scroll^ = maxScroll }\n" -"\t}\n" -"}\n" -"\n" -"//~~struct ButtonConfig\n" -"// Configuration for the button.\n" -"type ButtonConfig* = struct {\n" -"\trect: rect.Rect\n" -"}\n" -"//~~\n" -"\n" -"//~~fn Gui.button\n" -"// Adds a button to the gui. The button acts like a `Stack` container, but it\n" -"// is drawn using the pos/nexBox styles and handles clicks. If the button is\n" -"// pressed and the gui is in the eval phase, the return value will be true.\n" -"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n" -"//~~\n" -"\tgui.stack(StackConfig{ rect: cfg.rect })\n" -"\tr := gui.getContainer().getDims()\n" -"\n" -"\tif gui.isEval {\n" -"\t\tif gui.hover(r) && input.isJustReleased(input.mouse1) {\n" -"\t\t\treturn true\n" -"\t\t}\n" -"\t\treturn false\n" -"\t} else {\n" -"\t\tif gui.hover(r) && gui.m1Pressed {\n" -"\t\t\tgui.getStyle().negBox.draw(r)\n" -"\t\t} else {\n" -"\t\t\tgui.getStyle().posBox.draw(r)\n" -"\t\t}\n" -"\t}\n" -"\n" -"\treturn false\n" -"}\n" -"\n" -"//~~struct LabelConfig\n" -"type LabelConfig* = struct {\n" -"\t// centers the label along the X axis, enables `stretchX`\n" -"\tcenterX: bool\n" -"\t// centers the label along the Y axis, enables `stretchY`\n" -"\tcenterY: bool\n" -"\t// if false, the rect passed to `pushRect` will have the width of\n" -"\t// the text, else it will be 0\n" -"\tstretchX: bool\n" -"\t// if false, the rect passed to `pushRect` will have the height of\n" -"\t// the text, else it will be 0\n" -"\tstretchY: bool\n" -"\t// forces the rectangle the label will use\n" -"\trect: rect.Rect\n" -"}\n" -"//~~\n" -"\n" -"//~~fn Gui.label\n" -"// Draws a label using the current font style.\n" -"fn (gui: ^Gui) label*(text: str, cfg: LabelConfig = {\n" -"//~~\n" -"\tstretchX: true,\n" -"\tstretchY: true }) {\n" -"\n" -"\tif cfg.centerX { cfg.stretchX = true }\n" -"\tif cfg.centerY { cfg.stretchY = true }\n" -"\n" -"\tr := cfg.rect\n" -"\tstyle := gui.getStyle()\n" -"\ttxtSize := style.ft.measure(text).mulf(style.ftScale)\n" -"\tif r.w == 0 { r.w = txtSize.x }\n" -"\tif r.h == 0 { r.h = txtSize.y }\n" -"\n" -"\tif cfg.stretchX { r.w = 0 }\n" -"\tif cfg.stretchY { r.h = 0 }\n" -"\tr = gui.pushRect(r)\n" -"\n" -"\tif gui.isEval { return }\n" -"\n" -"\tx := r.x\n" -"\ty := r.y\n" -"\tif cfg.centerX {\n" -"\t\tx += (r.w-txtSize.x)/2.0\n" -"\t}\n" -"\tif cfg.centerY {\n" -"\t\ty += (r.h-txtSize.y)/2.0\n" -"\t}\n" -"\n" -"\tstyle.ft.draw(text, th.Vf2{x, y},\n" -"\t\tstyle.ftColor, style.ftScale)\n" -"}\n" -"\n" -"//~~fn Gui.qbutton\n" -"// Adds a button with a label to gui.\n" -"fn (gui: ^Gui) qbutton*(text: str, cfg: ButtonConfig = {}): bool {\n" -"//~~\n" -"\tpressed := gui.button(cfg)\n" -"\tgui.label(text, LabelConfig{centerX: true, centerY: true})\n" -"\tgui.popContainer()\n" -"\treturn pressed;\n" -"}\n" -"\n" -"//~~struct TextBoxConfig\n" -"type TextBoxConfig* = struct {\n" -"\t// force the rect of the text box\n" -"\trect: rect.Rect\n" -"}\n" -"//~~\n" -"\n" -"//~~struct TextBox\n" -"type TextBox* = struct {\n" -"\t// index of the cursor\n" -"\tcursor: int\n" -"\t// contains other unexported rules...\n" -"//~~\n" -"\tbuffer: []utf8.Rune\n" -"}\n" -"\n" -"//~~fn TextBox.clear\n" -"// Clears the textbox\n" -"fn (this: ^TextBox) clear*() {\n" -"//~~\n" -"\tthis.buffer = {}\n" -"\tthis.cursor = 0\n" -"}\n" -"\n" -"//~~fn TextBox.getBuf()\n" -"// Get the content of the textbox.\n" -"fn (this: ^TextBox) getBuf*(): str {\n" -"//~~\n" -"\treturn utf8.encode(this.buffer)\n" -"}\n" -"\n" -"//~~fn TextBox.setBuf()\n" -"// Get the content of the textbox.\n" -"fn (this: ^TextBox) setBuf*(s: str) {\n" -"//~~\n" -"\tthis.buffer = utf8.decode(s)\n" -"\tthis.cursor = len(this.buffer)\n" -"}\n" -"\n" -"//~~fn Gui.textBox\n" -"// Adds a single line textbox to the gui.\n" -"// TODO:\n" -"// * right-to-left unicode is not supported.\n" -"// * no selection\n" -"// * multiline\n" -"// * copy paste\n" -"// * stuff like home and end\n" -"fn (gui: ^Gui) textBox*(tb: ^TextBox, cfg: TextBoxConfig = {}) {\n" -"//~~\n" -"\tgui.idx++\n" -"\n" -"\tr := gui.pushRect(cfg.rect)\n" -"\n" -"\thover := gui.hover(r)\n" -"\n" -"\tif gui.isEval {\n" -"\t\tif input.isJustPressed(input.mouse1) && hover {\n" -"\t\t\tgui.selection = gui.idx\n" -"\t\t}\n" -"\n" -"\t\tif input.isJustPressed(input.mouse1) && !hover &&\n" -"\t\t\tgui.selection == gui.idx {\n" -"\t\t\t\tgui.selection = 0\n" -"\t\t}\n" -"\n" -"\t\tif input.isJustPressed(input.key_escape) && gui.selection == gui.idx {\n" -"\t\t\tgui.selection = 0\n" -"\t\t}\n" -"\n" -"\t\tif gui.selection != gui.idx {\n" -"\t\t\treturn\n" -"\t\t}\n" -"\n" -"\t\tif input.isJustPressed(input.key_left) ||\n" -"\t\t\tinput.isPressedRepeat(input.key_left) {\n" -"\t\t\tif tb.cursor > 0 { tb.cursor-- }\n" -"\t\t}\n" -"\n" -"\t\tif input.isJustPressed(input.key_right) ||\n" -"\t\t\tinput.isPressedRepeat(input.key_right) {\n" -"\t\t\tif tb.cursor < len(tb.buffer) { tb.cursor++ }\n" -"\t\t}\n" -"\n" -"\t\tif input.isJustPressed(input.key_backspace) ||\n" -"\t\t\tinput.isPressedRepeat(input.key_backspace) {\n" -"\n" -"\t\t\tif tb.cursor > 0 {\n" -"\t\t\t\ttb.buffer = append(slice(tb.buffer, 0, tb.cursor - 1), slice(tb.buffer, tb.cursor))\n" -"\t\t\t\ttb.cursor--\n" -"\t\t\t}\n" -"\t\t}\n" -"\n" -"\t\tv := true\n" -"\n" -"\t\tif input.isPressed(input.key_ctrl) && input.isJustPressedc(\'u\') {\n" -"\t\t\ttb.clear()\n" -"\t\t\tv = false\n" -"\t\t}\n" -"\n" -"\t\trunes := utf8.decode(input.getStr())\n" -"\t\tif len(runes) > 0 && v {\n" -"\t\t\ttb.buffer = append(slice(tb.buffer, 0, tb.cursor), append(slice(tb.buffer, tb.cursor), runes))\n" -"\t\t\ttb.cursor += len(runes)\n" -"\t\t}\n" -"\n" -"\t\treturn\n" -"\t}\n" -"\n" -"\tstyle := gui.getStyle()\n" -"\n" -"\tstyle.negBox.draw(r)\n" -"\tcanvas.beginScissorRect(r)\n" -"\n" -"\tbuf := utf8.encode(tb.buffer)\n" -"\tdm := style.ft.measure(buf).mulf(style.ftScale)\n" -"\n" -"\tp := th.Vf2{}\n" -"\tp.y = r.y + r.h/2 - dm.y/2\n" -"\tc := th.Vf2{r.x, p.y}\n" -"\n" -"\tcdmx := style.ft.measure(utf8.encode(slice(tb.buffer, 0, tb.cursor))).x * style.ftScale\n" -"\tif cdmx < r.w - 2 {\n" -"\t\tp.x = r.x + 1\n" -"\t\tc.x = p.x + cdmx\n" -"\t} else {\n" -"\t\tc.x = r.x + r.w - 1\n" -"\t\tp.x = c.x - cdmx\n" -"\t}\n" -"\n" -"\taW := style.ft.measure(\"A\").x * style.ftScale\n" -"\n" -"\tstyle.ft.draw(buf, p, style.ftColor, style.ftScale)\n" -"\tif gui.selection == gui.idx {\n" -"\t\tcanvas.drawRect(style.ftColor, rect.mk(c.x, c.y, aW / 4, dm.y))\n" -"\t}\n" -"\n" -"\tcanvas.endScissor()\n" -"}\n" -"\n" -"//~~struct ImageConfig\n" -"// Configuration for the images element. Behaves similarly to labels.\n" -"type ImageConfig* = struct {\n" -"\tstretchX, stretchY: bool\n" -"\tcenterX, centerY: bool\n" -"\tcolor: uint32\n" -"\tscale: th.Vf2\n" -"\trect: rect.Rect\n" -"}\n" -"//~~\n" -"\n" -"//~~fn Gui.image\n" -"// Draws an image.\n" -"fn (gui: ^Gui) image*(i: image.Image, cfg: ImageConfig = {\n" -"\tstretchX: true,\n" -"\tstretchY: true,\n" -"\tcolor: th.white,\n" -"\tscale: { 1, 1 } }) {\n" -"//~~\n" -"\n" -"\tif cfg.centerX { cfg.stretchX = true }\n" -"\tif cfg.centerY { cfg.stretchY = true }\n" -"\n" -"\tr := cfg.rect\n" -"\tdm := i.getDims().mul(cfg.scale)\n" -"\tif r.w == 0 { r.w = dm.x }\n" -"\tif r.h == 0 { r.h = dm.y }\n" -"\n" -"\tif cfg.stretchX { r.w = 0 }\n" -"\tif cfg.stretchY { r.h = 0 }\n" -"\n" -"\tr = gui.pushRect(r)\n" -"\n" -"\tif gui.isEval { return }\n" -"\n" -"\tx := r.x\n" -"\ty := r.y\n" -"\tif cfg.centerX {\n" -"\t\tx += (r.w - dm.x) / 2\n" -"\t}\n" -"\n" -"\tif cfg.centerY {\n" -"\t\ty += (r.h - dm.y) / 2\n" -"\t}\n" -"\n" -"\ti.draw(th.Transform{\n" -"\t\tp: { x, y },\n" -"\t\ts: cfg.scale }, cfg.color)\n" -"}\n" -"\n" -"//~~fn getDefaultStyle\n" -"// Returns the default tophat ui style.\n" -"fn getDefaultStyle*(): Style {\n" -"//~~\n" -"\treturn {\n" -"\t\tft: PixelFont{},\n" -"\t\tftScale: 1,\n" -"\t\tftColor: th.black,\n" -"\n" -"\t\tposBox: {\n" -"\t\t\timg: placeholders.button,\n" -"\t\t\touter: { 0, 0, 5, 5 },\n" -"\t\t\tinner: { 2, 2, 1, 1 },\n" -"\t\t\tscale: 1,\n" -"\t\t\tcolor: th.white },\n" -"\t\tnegBox: {\n" -"\t\t\timg: placeholders.button,\n" -"\t\t\touter: { 5, 0, 5, 5 },\n" -"\t\t\tinner: { 2, 2, 1, 1 },\n" -"\t\t\tscale: 1,\n" -"\t\t\tcolor: th.white },\n" -"\t\tcontainerBox: {\n" -"\t\t\tcolor: 0x888888ff } }\n" -"}\n" -"\n" -"//~~fn mk\n" -"// Creates a GUI instance.\n" -"fn mk*(r: rect.Rect, s: Style): Gui {\n" -"//~~\n" -"\tgui := Gui{}\n" -"\tgui.pushStyle(s)\n" -"\tgui.container = []Container{ Stack{ dm: r } }\n" -"\n" -"\treturn gui\n" -"}\n" -"", -}; -const char *th_em_modulenames[] = { "anim.um", "audio.um", "csv.um", "ent.um", "image.um", "input.um", "misc.um", "canvas.um", "ray.um", "rect.um", "tilemap.um", "window.um", "particles.um", "lerp.um", "font.um", "th.um", "signal.um", "atlas.um", "shader.um", "color.um", "coll.um", "placeholders.um", "nav.um", "ui.um", }; -int th_em_modulenames_count = 24; -const char *th_em_misc[] = { -"BSD 3-Clause License\n" -"\n" -"Copyright (c) 2023, Marek Maskarinec\n" -"All rights reserved.\n" -"\n" -"Redistribution and use in source and binary forms, with or without\n" -"modification, are permitted provided that the following conditions are met:\n" -"\n" -"1. Redistributions of source code must retain the above copyright notice, this\n" -" list of conditions and the following disclaimer.\n" -"\n" -"2. Redistributions in binary form must reproduce the above copyright notice,\n" -" this list of conditions and the following disclaimer in the documentation\n" -" and/or other materials provided with the distribution.\n" -"\n" -"3. Neither the name of the copyright holder nor the names of its\n" -" contributors may be used to endorse or promote products derived from\n" -" this software without specific prior written permission.\n" -"\n" -"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n" -"AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n" -"IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\n" -"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE\n" -"FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n" -"DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n" -"SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\n" -"CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n" -"OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\n" -"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" -"", -"v1.2\n" -"", -}; -const char *th_em_moduledocs[] = { -"## struct Anim\n" -"\n" -"```\n" -"type Anim* = struct {\n" -"\t// the source atlas\n" -"\tatl: atlas.Atlas\n" -"\t// the first cell of the animation\n" -"\tmin: int\n" -"\t// the last cell of the animation\n" -"\tmax: int\n" -"\tfps: real32\n" -"\t// offset in time\n" -"\toffset: int\n" -"}\n" -"```\n" -"\n" -"Anim allows you to animate between individual frames of an atlas.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(atl: atlas.Atlas, fps: int, min: int = 0, max: int = -1 /* len(atl) - 1 */, offset: int = -1 /* th.time */): Anim {\n" -"```\n" -"\n" -"`Anim` constructor\n" -"\n" -"\n" -"## fn Anim.animate\n" -"\n" -"```\n" -"fn (anm: ^Anim) animate*(time: int) {\n" -"```\n" -"\n" -"Crops the base atlas to the cell that should be visible at `time`.\n" -"\n" -"\n" -"## fn Anim.framesPlayed\n" -"\n" -"```\n" -"fn (anm: ^Anim) framesPlayed*(time: int): int {\n" -"```\n" -"\n" -"Returns how many frames were played at `time`.\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Module for audio loading and playback.\n" -"\n" -"\n" -"## opaque Sound\n" -"\n" -"```\n" -"type Sound* = struct { _: ^struct{} }\n" -"```\n" -"\n" -"Represents an instance of a playable sound. It is an opaque structure.\n" -"\n" -"\n" -"## fn load\n" -"\n" -"```\n" -"fn load*(path: str, flags: LoadFlag = 0): Sound {\n" -"```\n" -"\n" -"Loads a sounds at path, if there is an error, the underlying pointer\n" -"will be `NULL` and `validate` will return false.\n" -"\n" -"\n" -"## fn Sound.validate\n" -"\n" -"```\n" -"fn (s: ^Sound) validate*(): bool {\n" -"```\n" -"\n" -"Returns `true` if `s` loaded correctly.\n" -"\n" -"\n" -"## fn Sound.copy\n" -"\n" -"```\n" -"fn (s: ^Sound) copy*(): Sound {\n" -"```\n" -"\n" -"Copies the sound. This will create another sound which can be configured\n" -"and played independently from the original sound.\n" -"\n" -"\n" -"## fn Sound.isPlaying\n" -"\n" -"```\n" -"fn (s: ^Sound) isPlaying*(): bool {\n" -"```\n" -"\n" -"Returns true if the sound is still playing.\n" -"\n" -"\n" -"## fn Sound.play\n" -"\n" -"```\n" -"fn (s: ^Sound) play*() {\n" -"```\n" -"\n" -"Plays the sound.\n" -"\n" -"\n" -"## fn Sound.start\n" -"\n" -"```\n" -"fn (s: ^Sound) start*(): ^Sound {\n" -"```\n" -"\n" -"The start function allows you to play a single sound multiple times.\n" -"It will create a copy and return a pointer to it, so you can controll it\n" -"while it is playing. The returned pointer can be discarded.\n" -"\n" -"\n" -"## fn Sound.stop\n" -"\n" -"```\n" -"fn (s: ^Sound) stop*() {\n" -"```\n" -"\n" -"Stops the sound, but keeps the progress. If you want to start from the\n" -"begginning, use `audio.Sound.seekToFrame(0)`.\n" -"\n" -"\n" -"## fn Sound.setVol\n" -"\n" -"```\n" -"fn (s: ^Sound) setVol*(vol: real32) {\n" -"```\n" -"\n" -"Sets the volume as a multiplier of the base volume.\n" -"\n" -"\n" -"## fn Sound.setPan\n" -"\n" -"```\n" -"fn (s: ^Sound) setPan*(pan: real32) {\n" -"```\n" -"\n" -"Sets the pan of the sound.\n" -"\n" -"\n" -"## fn Sound.setPitch\n" -"\n" -"```\n" -"fn (s: ^Sound) setPitch*(pitch: real32) {\n" -"```\n" -"\n" -"Sets the pitch of the sound.\n" -"\n" -"\n" -"## fn Sound.setLooping\n" -"\n" -"```\n" -"fn (s: ^Sound) setLooping*(looping: bool) {\n" -"```\n" -"\n" -"Sets whether the sound will loop upon finishing.\n" -"\n" -"\n" -"## fn Sound.seekToFrame\n" -"\n" -"```\n" -"fn (s: ^Sound) seekToFrame*(frame: uint) {\n" -"```\n" -"\n" -"Seeks to a specified PCM frame.\n" -"\n" -"\n" -"## fn Sound.frameCount\n" -"\n" -"```\n" -"fn (s: ^Sound) frameCount*(): uint {\n" -"```\n" -"\n" -"Returns length of the sound in PCM frames.\n" -"\n" -"\n" -"## fn Sound.lengthMs\n" -"\n" -"```\n" -"fn (s: ^Sound) lengthMs*(): uint {\n" -"```\n" -"\n" -"Returns length of the sound in ms.\n" -"\n" -"\n" -"## fn Sound.setStartTimeMs\n" -"\n" -"```\n" -"fn (s: ^Sound) setStartTimeMs*(t: uint) {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Sound.setStopTimeMs\n" -"\n" -"```\n" -"fn (s: ^Sound) setStopTimeMs*(t: uint) {\n" -"```\n" -"\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"A CSV parser, which also works for similar formats. It doesn\'t support\n" -"quotes, but you can escape characters using a backslash.\n" -"\n" -"\n" -"## fn parse\n" -"\n" -"```\n" -"fn parse*(inp: str, sep: char = \',\'): [][]str {\n" -"```\n" -"\n" -"Parses input into a 2d string array.\n" -"\n" -"\n" -"## fn encode\n" -"\n" -"```\n" -"fn encode*(inp: [][]str, sep: char = \',\'): str {\n" -"```\n" -"\n" -"Converts 2d array to csv string.\n" -"\n" -"\n" -"", -"## struct Ent\n" -"\n" -"```\n" -"type Ent* = struct {\n" -"\t// used as a collider, used as backup when invalid image is supplied\n" -"\tr: rect.Rect\n" -"\t// used in drawing\n" -"\ti: image.Image\n" -"\t// used to transform and translate the image and rect\n" -"\tt: th.Transform\n" -"\t// used as a color of the rect and a color filter for the image\n" -"\tc: uint32\n" -"}\n" -"```\n" -"\n" -"Entity is the main game object. It features drawing and collisions.\n" -"Every entity has an image used for drawing and a rectangle used\n" -"for collisions. It also has a transform used for transforming it\'s image\n" -"and rectangle.\n" -"\n" -"\n" -"## struct Coll\n" -"\n" -"```\n" -"type Coll* = struct {\n" -"\tindex: th.uu\n" -"\tpos: th.Vf2\n" -"}\n" -"```\n" -"\n" -"Value returned by get coll. It contains a position where the collision\n" -"happened and the index of the entity involved in said collision.\n" -"\n" -"\n" -"## fn Ent.draw\n" -"\n" -"```\n" -"fn (e: ^Ent) draw*() {\n" -"```\n" -"\n" -"Draws the entity onto the screen.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(img: image.Image = image.Image{}, t: th.Transform = th.Transform{ s: th.Vf2{1, 1} }): Ent {\n" -"```\n" -"\n" -"ent\'s constructor\n" -"\n" -"\n" -"## fn Ent.getColl\n" -"\n" -"```\n" -"fn (e: ^Ent) getColl*(s: []^Ent, maxColls: th.uu): []Coll {\n" -"```\n" -"\n" -"Checks collisions of e with entities in s. Checks at max maxColl collisions.\n" -"If s contains e, the collision won\'t be returned.\n" -"\n" -"\n" -"## fn Ent.animate\n" -"\n" -"```\n" -"fn (e: ^Ent) animate*(fps: int, frames: ^[]image.Image, t: int) {\n" -"```\n" -"\n" -"Animates the entity\'s image with one of the `anim` array. Won\'t begin on\n" -"the first frame. If you want that, use anim.Anim.\n" -"\n" -"\n" -"", -"## opaque Image\n" -"\n" -"```\n" -"type Image* = struct{ _: ^struct{} }\n" -"```\n" -"\n" -"Represents a drawable image. It is an opaque structure.\n" -"Images support a color filter. It is applied by multiplying the color\n" -"of each pixel with the filter.\n" -"\n" -"\n" -"## opaque RenderTarget\n" -"\n" -"```\n" -"type RenderTarget* = struct { _: ^struct{} }\n" -"```\n" -"\n" -"An image you can render to.\n" -"\n" -"\n" -"## fn createRenderTarget\n" -"\n" -"```\n" -"fn createRenderTarget*(size: th.Vf2, filter: int): RenderTarget {\n" -"```\n" -"\n" -"Creates a render target you can draw to, like to a window.\n" -"Filter specifies specfifies filtering for resulting image.\n" -"Image can be retrieved via `toImage`.\n" -"\n" -"\n" -"## fn RenderTarget.end\n" -"\n" -"```\n" -"fn (rt: ^RenderTarget) begin*() {\n" -"```\n" -"\n" -"Begins the render target rendering pass.\n" -"\n" -"\n" -"## fn RenderTarget.end\n" -"\n" -"```\n" -"fn (rt: ^RenderTarget) end*(wp: th.Vf2) {\n" -"```\n" -"\n" -"Ends the render target rendering pass.\n" -"\n" -"\n" -"## fn RenderTarget.toImage\n" -"\n" -"```\n" -"fn (rt: ^RenderTarget) toImage*(): Image {\n" -"```\n" -"\n" -"Returns the image of the render target.\n" -"Do not call `setfilter` on the resulting image.\n" -"\n" -"\n" -"## fn load\n" -"\n" -"```\n" -"fn load*(path: str): Image {\n" -"```\n" -"\n" -"Loads an image at path.\n" -"\n" -"\n" -"## fn Image.validate\n" -"\n" -"```\n" -"fn (i: ^Image) validate*(): bool {\n" -"```\n" -"\n" -"Returns true, if i\'s handle points to an image.\n" -"\n" -"\n" -"## fn Image.flipv\n" -"\n" -"```\n" -"fn (i: ^Image) flipv*(flip: bool) {\n" -"```\n" -"\n" -"Flips image on it\'s vertical axis.\n" -"\n" -"\n" -"## fn Image.fliph\n" -"\n" -"```\n" -"fn (i: ^Image) fliph*(flip: bool) {\n" -"```\n" -"\n" -"Flips image on it\'s horizontal axis.\n" -"\n" -"\n" -"## fn Image.draw\n" -"\n" -"```\n" -"fn (i: ^Image) draw*(t: th.Transform, color: uint32 = th.white) {\n" -"```\n" -"\n" -"Draws the image in screen coordinates. It transforms it with t and\n" -"applies color as a color filter.\n" -"\n" -"\n" -"## fn Image.drawNinepatch\n" -"\n" -"```\n" -"fn (i: ^Image) drawNinepatch*(outer, inner, dest: rect.Rect, color: uint32 = th.white, scale: real = 1.0) {\n" -"```\n" -"\n" -"Draws \"nine-patch\" image.\n" -"`outer` specifies the texture coordinates of the outer rect of source image,\n" -"`inner` specifies coordinates of inner rect of source image, positioned relative to `outer`.\n" -"You can tint with `color`.\n" -"![](img/ninepatch.png)\n" -"\n" -"\n" -"## fn Image.drawOnQuad\n" -"\n" -"```\n" -"fn (i: ^Image) drawOnQuad*(q: th.Quad, color: uint32 = th.white) {\n" -"```\n" -"\n" -"Draws the image on top of a quad with corners of the image positioned\n" -"on the verticies of the quad.\n" -"\n" -"\n" -"## fn Image.getDims\n" -"\n" -"```\n" -"fn (i: ^Image) getDims*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns width and heigth.\n" -"\n" -"\n" -"## fn Image.crop\n" -"\n" -"```\n" -"fn (i: ^Image) crop*(tl, br: th.Vf2) {\n" -"```\n" -"\n" -"Crops an image. Coordinates are between 0, 0 (top left) and\n" -"1, 1 (bottom right)\n" -"\n" -"\n" -"## fn Image.cropPx\n" -"\n" -"```\n" -"fn (i: ^Image) cropPx*(tr, br: th.Vf2) {\n" -"```\n" -"\n" -"Same as `Image.crop`, but the positions are in pixels.\n" -"\n" -"\n" -"## fn Image.cropRect\n" -"\n" -"```\n" -"fn (i: ^Image) cropRect*(r: rect.Rect) {\n" -"```\n" -"\n" -"Same as `Image.crop`, but uses a rect instead of two positions.\n" -"\n" -"\n" -"## fn Image.cropQuad\n" -"\n" -"```\n" -"fn (i: ^Image) cropQuad*(q: th.Quad) {\n" -"```\n" -"\n" -"Crop an image using a quad.\n" -"\n" -"\n" -"## fn Image.getCropQuad\n" -"\n" -"```\n" -"fn (i: ^Image) getCropQuad*(): th.Quad {\n" -"```\n" -"\n" -"Crop an image using a quad.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(data: []uint32, dm: th.Vf2): Image {\n" -"```\n" -"\n" -"Creates an image from raw data.\n" -"\n" -"\n" -"## fn Image.copy\n" -"\n" -"```\n" -"fn (i: ^Image) copy*(): Image {\n" -"```\n" -"\n" -"Copies image into a new one.\n" -"\n" -"\n" -"## fn Image.setfilter\n" -"\n" -"```\n" -"fn (i: ^Image) setfilter*(filter: int) {\n" -"```\n" -"\n" -"Sets a mag/min filter. 0 is nearest, others are linear.\n" -"This function will regenerate the texture. This means it shouldn\'t be\n" -"used in a loop.\n" -"https://learnopengl.com/img/getting-started/texture_filtering.png\n" -"left is nearest, right is linear.\n" -"\n" -"\n" -"## fn Image.setData\n" -"\n" -"```\n" -"fn (i: ^Image) setData*(data: []uint32, dm: th.Vf2) {\n" -"```\n" -"\n" -"Updates the image data. dm are the dimensions of the new image.\n" -"The new image doesn\'t have to be the same size as the old one.\n" -"\n" -"\n" -"## fn Image.getData\n" -"\n" -"```\n" -"fn (i: ^Image) getData*(): []uint32 {\n" -"```\n" -"\n" -"Gets the image data. This downloads the data from the GPU on **each call**.\n" -"Don\'t use in performance critical sections.\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Module for getting keyboard and mouse input.\n" -"is* functions return info based on a us QWERTY layout. They are supposed to\n" -"be used for game controls. For text input use getStr.\n" -"\n" -"\n" -"## Keycode constants\n" -"\n" -"```\n" -"const (\n" -" mouse1* = 1 // NOTE: mouse 2 and 3 key codes are swapped\n" -" mouse2* = 3 // because sokol uses 3 for middle mouse\n" -" mouse3* = 2 // button.\n" -"\n" -" key_ctrl* = 16\n" -" key_shift* = 17\n" -" key_alt* = 18\n" -"\n" -" key_space* = 32\n" -" key_apostrophe* = 39 /* \' */\n" -" key_comma* = 44 /* , */\n" -" key_minus* = 45 /* - */\n" -" key_dot* = 46 /* . */\n" -" key_slash* = 47 /* / */\n" -" key_0* = 48\n" -" key_1* = 49\n" -" key_2* = 50\n" -" key_3* = 51\n" -" key_4* = 52\n" -" key_5* = 53\n" -" key_6* = 54\n" -" key_7* = 55\n" -" key_8* = 56\n" -" key_9* = 57\n" -" key_semicolon* = 59 /* ; */\n" -" key_equal* = 61 /* = */\n" -" key_a* = 65\n" -" key_b* = 66\n" -" key_c* = 67\n" -" key_d* = 68\n" -" key_e* = 69\n" -" key_f* = 70\n" -" key_g* = 71\n" -" key_h* = 72\n" -" key_i* = 73\n" -" key_j* = 74\n" -" key_k* = 75\n" -" key_l* = 76\n" -" key_m* = 77\n" -" key_n* = 78\n" -" key_o* = 79\n" -" key_p* = 80\n" -" key_q* = 81\n" -" key_r* = 82\n" -" key_s* = 83\n" -" key_t* = 84\n" -" key_u* = 85\n" -" key_v* = 86\n" -" key_w* = 87\n" -" key_x* = 88\n" -" key_y* = 89\n" -" key_z* = 90\n" -" key_left_bracket* = 91 /* [ */\n" -" key_backslash* = 92 /* \\ */\n" -" key_right_bracket* = 93 /* ] */\n" -" key_grave_accent* = 96 /* ` */\n" -" key_world_1* = 161 /* non-US #1 */\n" -" key_world_2* = 162 /* non-US #2 */\n" -" key_escape* = 256\n" -" key_enter* = 257\n" -" key_tab* = 258\n" -" key_backspace* = 259\n" -" key_insert* = 260\n" -" key_delete* = 261\n" -" key_right* = 262\n" -" key_left* = 263\n" -" key_down* = 264\n" -" key_up* = 265\n" -" key_page_up* = 266\n" -" key_page_down* = 267\n" -" key_home* = 268\n" -" key_end* = 269\n" -" key_caps_lock* = 280\n" -" key_scroll_lock* = 281\n" -" key_num_lock* = 282\n" -" key_print_screen* = 283\n" -" key_pause* = 284\n" -"\tkey_fn* = 289\n" -" key_fn1* = 290\n" -" key_fn2* = 291\n" -" key_fn3* = 292\n" -" key_fn4* = 293\n" -" key_fn5* = 294\n" -" key_fn6* = 295\n" -" key_fn7* = 296\n" -" key_fn8* = 297\n" -" key_fn9* = 298\n" -" key_fn10* = 299\n" -" key_fn11* = 300\n" -" key_fn12* = 301\n" -" key_fn13* = 302\n" -" key_fn14* = 303\n" -" key_fn15* = 304\n" -" key_fn16* = 305\n" -" key_fn17* = 306\n" -" key_fn18* = 307\n" -" key_fn19* = 308\n" -" key_fn20* = 309\n" -" key_fn21* = 310\n" -" key_fn22* = 311\n" -" key_fn23* = 312\n" -" key_fn24* = 313\n" -" key_fn25* = 314\n" -" key_kp_0* = 320\n" -" key_kp_1* = 321\n" -" key_kp_2* = 322\n" -" key_kp_3* = 323\n" -" key_kp_4* = 324\n" -" key_kp_5* = 325\n" -" key_kp_6* = 326\n" -" key_kp_7* = 327\n" -" key_kp_8* = 328\n" -" key_kp_9* = 329\n" -" key_kp_decimal* = 330\n" -" key_kp_divide* = 331\n" -" key_kp_multiply* = 332\n" -" key_kp_subtract* = 333\n" -" key_kp_add* = 334\n" -" key_kp_enter* = 335\n" -" key_kp_equal* = 336\n" -" key_left_shift* = 340\n" -" key_left_control* = 341\n" -" key_left_alt* = 342\n" -" key_left_super* = 343\n" -" key_right_shift* = 344\n" -" key_right_control* = 345\n" -" key_right_alt* = 346\n" -" key_right_super* = 347\n" -" key_menu* = 348\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## fn getMousePos\n" -"\n" -"```\n" -"fn getMousePos*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns the position of mouse cursor in relation to the screen.\n" -"\n" -"\n" -"## fn getGlobalMousePos\n" -"\n" -"```\n" -"fn getGlobalMousePos*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns the position of mouse cursor in relation to cam.\n" -"\n" -"\n" -"## fn isPressed\n" -"\n" -"```\n" -"fn isPressed*(code: int): bool {\n" -"```\n" -"\n" -"Returns true if key is pressed. Either use codes defined in the file above,\n" -"or pass lower case char/number.\n" -"\n" -"\n" -"## fn isPressedc\n" -"\n" -"```\n" -"fn isPressedc*(code: char): bool {\n" -"```\n" -"\n" -"Like `isPressed`, but you can pass char as the code.\n" -"\n" -"\n" -"## fn isJustPressed\n" -"\n" -"```\n" -"fn isJustPressed*(code: int): bool {\n" -"```\n" -"\n" -"Returns, whether code was just pressed this loop.\n" -"\n" -"\n" -"## fn isJustPressedc\n" -"\n" -"```\n" -"fn isJustPressedc*(code: char): bool {\n" -"```\n" -"\n" -"Like `isJustPressed`, but you can pass char as the code.\n" -"\n" -"\n" -"## fn isPressedRepeat\n" -"\n" -"```\n" -"fn isPressedRepeat*(code: int): bool {\n" -"```\n" -"\n" -"Returns, whether code was just pressed this loop, with key repeat.\n" -"\n" -"\n" -"## fn isPressedRepeatc\n" -"\n" -"```\n" -"fn isPressedRepeatc*(code: char): bool {\n" -"```\n" -"\n" -"Like `isPressedRepeat`, but you can pass char as the code.\n" -"\n" -"\n" -"## fn isJustReleased\n" -"\n" -"```\n" -"fn isJustReleased*(code: int): bool {\n" -"```\n" -"\n" -"Returns true if a key was just released.\n" -"\n" -"\n" -"## fn isJustReleasedc\n" -"\n" -"```\n" -"fn isJustReleasedc*(code: char): bool {\n" -"```\n" -"\n" -"Like `isJustReleased`, but you can pass char as the code.\n" -"\n" -"\n" -"## fn clear\n" -"\n" -"```\n" -"fn clear*(code: int) {\n" -"```\n" -"\n" -"Clears both the pressed and justPressed state of a code.\n" -"\n" -"\n" -"## fn clearc\n" -"\n" -"```\n" -"fn clearc*(code: char) {\n" -"```\n" -"\n" -"Like `clear`, but you can pass char as the code.\n" -"\n" -"\n" -"## fn getStr\n" -"\n" -"```\n" -"fn getStr*(): str {\n" -"```\n" -"\n" -"Returns a string entered by the user in the last cycle.\n" -"\n" -"\n" -"## fn getMouseDelta\n" -"\n" -"```\n" -"fn getMouseDelta*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns the difference between mouse positions in the last cycle. Will work\n" -"even if `window.freezeCursor` is enabled.\n" -"\n" -"\n" -"## fn getMouseScroll\n" -"\n" -"```\n" -"fn getMouseScroll*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns the scroll wheel value\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Misc functions.\n" -"\n" -"\n" -"## fn readall\n" -"\n" -"```\n" -"fn readall*(path: str): str {\n" -"```\n" -"\n" -"Reads file content into a string.\n" -"\n" -"\n" -"## fn stepify\n" -"\n" -"```\n" -"fn stepify*(val, step: th.fu): th.fu {\n" -"```\n" -"\n" -"Snaps a value to step.\n" -"\n" -"\n" -"## fn maxf\n" -"\n" -"```\n" -"fn maxf*(a, b: th.fu): th.fu {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn minf\n" -"\n" -"```\n" -"fn minf*(a, b: th.fu): th.fu {\n" -"```\n" -"\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Canvas library allowing for drawing basic shapes. Coordinates are based on\n" -"the screen.\n" -"\n" -"\n" -"## fn drawText\n" -"\n" -"```\n" -"fn drawText*(text: str, pos: th.Vf2, color: uint32, size: th.fu) {\n" -"```\n" -"\n" -"Draws a basic pixel text. Only ascii is supported.\n" -"\n" -"\n" -"## fn textSize\n" -"\n" -"```\n" -"fn textSize*(text: str, scale: th.fu): th.Vf2 {\n" -"```\n" -"\n" -"Returns the size of text taken by an equivalent drawText call.\n" -"\n" -"\n" -"## fn drawRect\n" -"\n" -"```\n" -"fn drawRect*(color: uint32, r: rect.Rect) {\n" -"```\n" -"\n" -"Draws a Rectangle.\n" -"\n" -"\n" -"## fn drawLine\n" -"\n" -"```\n" -"fn drawLine*(color: uint32, b, e: th.Vf2, thickness: th.fu) {\n" -"```\n" -"\n" -"Draws a line.\n" -"\n" -"\n" -"## fn drawRectLines\n" -"\n" -"```\n" -"fn drawRectLines*(color: uint32, r: rect.Rect, thickness: real32 = 1.0) {\n" -"```\n" -"\n" -"Draws rect border.\n" -"\n" -"\n" -"## fn drawQuad\n" -"\n" -"```\n" -"fn drawQuad*(color: uint32, q: th.Quad) {\n" -"```\n" -"\n" -"Draws a convex quad.\n" -"\n" -"\n" -"## fn beginScissorRect\n" -"\n" -"```\n" -"fn beginScissorRect*(r: rect.Rect, debug: bool = false) {\n" -"```\n" -"\n" -"Disable rendering outside of rect `r`\n" -"\n" -"\n" -"## fn endScissor\n" -"\n" -"```\n" -"fn endScissor*() {\n" -"```\n" -"\n" -"Stops cropping\n" -"\n" -"\n" -"", -"## struct Ray\n" -"\n" -"```\n" -"type Ray* = struct {\n" -"\tpos: th.Vf2\n" -"\tl: th.fu // length\n" -"\tr: th.fu // rotation\n" -"}\n" -"```\n" -"\n" -"Ray is a line specified by an origin, length and a rotation.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(pos: th.Vf2, l: th.fu, r: th.fu = 0.0): Ray {\n" -"```\n" -"\n" -"Ray constructor\n" -"\n" -"\n" -"## fn Ray.getColl\n" -"\n" -"```\n" -"fn (r: ^Ray) getColl*(s: []^ent.Ent, maxColls: th.uu): []ent.Coll {\n" -"```\n" -"\n" -"Checks the ray\'s collisions with a scene of ents. Similar to\n" -"`ent.Ent.getColl`\n" -"\n" -"\n" -"## fn Ray.getTilemapColl\n" -"\n" -"```\n" -"fn (r: ^Ray) getTilemapColl*(t: tilemap.Tilemap, ic: ^th.Vf2): bool {\n" -"```\n" -"\n" -"Gets ray\'s collision to a tilemap.\n" -"\n" -"\n" -"## fn Ray.getEnd\n" -"\n" -"```\n" -"fn (r: ^Ray) getEnd*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns the other point of the ray.\n" -"\n" -"\n" -"## fn Ray.draw\n" -"\n" -"```\n" -"fn (r: ^Ray) draw*(color: uint32, thickness: th.fu) {\n" -"```\n" -"\n" -"Draws the ray to the screen.\n" -"\n" -"\n" -"", -"## struct Rect\n" -"\n" -"```\n" -"type Rect* = struct {\n" -"\tx, y, w, h: th.fu\n" -"}\n" -"```\n" -"\n" -"A set of points representing a rectangle.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(x, y, w, h: th.fu): Rect {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn fromVf2*(p: th.Vf2, dm: th.Vf2): Rect {\n" -"```\n" -"\n" -"Creates a rect from two Vf2s - the position and the dimensions.\n" -"\n" -"\n" -"## fn Rect.getPos\n" -"\n" -"```\n" -"fn (r: ^Rect) getPos*(): th.Vf2 {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Rect.getDims\n" -"\n" -"```\n" -"fn (r: ^Rect) getDims*(): th.Vf2 {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Rect.getEnd\n" -"\n" -"```\n" -"fn (r: ^Rect) getEnd*(): th.Vf2 {\n" -"```\n" -"\n" -"returns where the second point of the rectangle lies.\n" -"\n" -"\n" -"## fn Rect.transformed\n" -"\n" -"```\n" -"fn (r: ^Rect) transformed*(t: th.Transform): th.Quad {\n" -"```\n" -"\n" -"Transforms a rect into a quad.\n" -"Order:\n" -"1. scale\n" -"2. rotation\n" -"3. position\n" -"\n" -"\n" -"## fn Rect.shrink\n" -"\n" -"```\n" -"fn (r: ^Rect) shrink*(p: th.Vf2): Rect {\n" -"```\n" -"\n" -"Shrink the rectangle by `p` pixels from all sides.\n" -"\n" -"\n" -"## fn Rect.shift\n" -"\n" -"```\n" -"fn (r: ^Rect) shift*(p: th.Vf2): Rect {\n" -"```\n" -"\n" -"Shift the rectangle by `p` pixels.\n" -"\n" -"\n" -"## fn Rect.scale\n" -"\n" -"```\n" -"fn (r: ^Rect) scale*(p: th.Vf2): Rect {\n" -"```\n" -"\n" -"Multiply the dimensions by `p`\n" -"\n" -"\n" -"## fn Rect.center\n" -"\n" -"```\n" -"fn (r: ^Rect) center*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns the position, which is the center of the rect.\n" -"\n" -"\n" -"## fn Rect.centerWithinRect\n" -"\n" -"```\n" -"fn (r: ^Rect) centerWithinRect*(child: Rect): Rect {\n" -"```\n" -"\n" -"Centers `child` with the rect `r`.\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Tilemaps allow for easy level construction and fast collisions. You can even\n" -"use them for some games instead of entities (tetris comes to mind)\n" -"\n" -"\n" -"## Direction constants used for autotile\n" -"\n" -"```\n" -"const (\n" -"\ttop* = 1\n" -"\tright* = 2\n" -"\tbot* = 4\n" -"\tleft* = 8\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## struct Tilemap\n" -"\n" -"```\n" -"type Tilemap* = struct {\n" -"\tatlas: atlas.Atlas\n" -"\tpos: th.Vf2\n" -"\tw: th.uu // width of tilemap\n" -"\tcells: []th.uu // all cells (this will draw the tile in tiles with number in cells - 1)\n" -"\tcollMask: []bool // if true, the tile collides\n" -"\tscale: th.fu\n" -"}\n" -"```\n" -"\n" -"Tilemap struct\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(cells: []th.uu, w: th.uu, at: atlas.Atlas, scale: th.fu = 1): Tilemap {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Tilemap.edit\n" -"\n" -"```\n" -"fn (t: ^Tilemap) edit*(x, y, tile: int) {\n" -"```\n" -"\n" -"Sets tile at [x, y] to tile.\n" -"\n" -"\n" -"## fn Tilemap.draw\n" -"\n" -"```\n" -"fn (t: ^Tilemap) draw*() {\n" -"```\n" -"\n" -"Draws the tilemap.\n" -"\n" -"\n" -"## fn Tilemap.getColl\n" -"\n" -"```\n" -"fn (t: ^Tilemap) getColl*(e: ent.Ent, ic: ^th.Vf2, pos: ^th.Vf2): bool {\n" -"```\n" -"\n" -"Checks whether `e` collides with any of the tiles in `t`, which are in the\n" -"collmask.\n" -"\n" -"* `ic`[out] - the position where a collision occured\n" -"* `pos`[out] - coordinates of a tile where a collision occured\n" -"\n" -"Note: While there may be multiple collisions with a tilemap, this function\n" -"will only return one.\n" -"\n" -"\n" -"## fn Tilemap.autotile\n" -"\n" -"```\n" -"fn (t: ^Tilemap) autotile*(src, tileCfg: []th.uu, tile: th.uu) {\n" -"```\n" -"\n" -"Autotile turns all `tile` tiles in `src` into tiles in `tileCfg`, so they\n" -"follow up correctly. `tileCfg` is an array of 16 tiles. They are placed in\n" -"a way where OR of all the places where the tile continues (top, right bot,\n" -"right). The constants for them are defined in this file. Example:\n" -"tileCfg[top | bot] = 21\n" -"top | bot would look something like this: |\n" -"\n" -"\n" -"", -"## Cursor types\n" -"\n" -"```\n" -"const (\n" -"\tcursorDefault* = 0\t\t// Default system cursor\n" -"\tcursorArrow*\t\t\t// Normal cursor; Arrow cursor\n" -"\tcursorIBeam*\t\t\t// \'I\' text cursor; I-Beam\n" -"\tcursorCrosshair*\t\t// \'+\' cursor; Select region cursor\n" -"\tcursorFinger*\t\t\t// Index finger pointing cursor; Click cursor\n" -"\tcursorSizeEW*\t\t\t// \'<->\' cursor; Resize width cursor; Resize horizontally cursor; East-West resize cursor\n" -"\tcursorSizeNS*\t\t\t// Resize height cursor; Resize vertically cursor; North-South resize cursor\n" -"\tcursorSizeNWSE*\t\t\t// Resize width and height from the right side cursor; Northwest-Southeast resize cursor\n" -"\tcursorSizeSWNE*\t\t\t// Resize width and height from the left side cursor; Southwest-Northeast resize cursor\n" -"\tcursorSizeAll*\t\t\t// Resize all cursor; Move cursor\n" -"\tcursorNo*\t\t\t// \'(/)\' cursor; Disabled cursor; Disallowed cursor\n" -"\tcursorCount_*\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## Window dimensions\n" -"\n" -"```\n" -"var (\n" -"\tw*, h*: int32\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## Viewport size\n" -"\n" -"```\n" -"var wp*: th.Vf2\n" -"```\n" -"\n" -"\n" -"\n" -"## signal OnFrame\n" -"\n" -"```\n" -"var onFrame*: signal.Signal\n" -"```\n" -"\n" -"\n" -"\n" -"## signal OnDestroy\n" -"\n" -"```\n" -"var onDestroy*: signal.Signal\n" -"```\n" -"\n" -"\n" -"\n" -"## fn setViewport\n" -"\n" -"```\n" -"fn setViewport*(dm: th.Vf2) {\n" -"```\n" -"\n" -"Sets the dimensions of the viewport. The dimensions are saved in the `wp`\n" -"variable.\n" -"\n" -"`dm`\n" -": dimension of the viewport\n" -"\n" -"\n" -"## fn isDpiEnabled\n" -"\n" -"```\n" -"fn isDpiEnabled*(): bool {\n" -"```\n" -"\n" -"Returns true if DPI awareness was enabled\n" -"\n" -"\n" -"## fn getDpiScaleFactor\n" -"\n" -"```\n" -"fn getDpiScaleFactor*(): th.fu {\n" -"```\n" -"\n" -"Returns the DPI scaling of the current window.\n" -"If `dpiAware` was not enabled in window setup, this function will return 1.0 (default scaling).\n" -"\n" -"\n" -"## fn setup\n" -"\n" -"```\n" -"fn setup*(title: str = \"tophat game\", width: int = 400, height: int32 = 400) {\n" -"```\n" -"\n" -"Sets up the engine and opens a window.\n" -"\n" -"\n" -"## fn cycle\n" -"\n" -"```\n" -"fn cycle(delta: real) {\n" -"```\n" -"\n" -"Cycle needs to be called every cycle for the window to work. If the window\n" -"was closed, it returns false.\n" -"\n" -"\n" -"## fn setFullscreen\n" -"\n" -"```\n" -"fn setFullscreen*(fullscreen: bool) {\n" -"```\n" -"\n" -"Makes window go full screen\n" -"\n" -"\n" -"## fn isFullscreen\n" -"\n" -"```\n" -"fn isFullscreen*(): bool {\n" -"```\n" -"\n" -"Returns true if window is fullscreen\n" -"\n" -"\n" -"## fn getDims\n" -"\n" -"```\n" -"fn getDims*(): th.Vf2 {\n" -"```\n" -"\n" -"Returns dimensions of the window in screen pixels.\n" -"\n" -"\n" -"## fn setTargetFps\n" -"\n" -"```\n" -"fn setTargetFps*(fps: int) {\n" -"```\n" -"\n" -"Sets the fps limit.\n" -"\n" -"`fps`\n" -": amount of fps the limit should be set to\n" -"\n" -"\n" -"\n" -"## fn setDims\n" -"\n" -"```\n" -"fn setDims*(dm: th.Vf2) {\n" -"```\n" -"\n" -"Sets the dimensions of the window.\n" -"\n" -"`dm`\n" -": the target dimensions in screen pixels\n" -"\n" -"\n" -"## fn setIcon\n" -"\n" -"```\n" -"fn setIcon*(img: image.Image) {\n" -"```\n" -"\n" -"Sets the window icon.\n" -"\n" -"\n" -"## fn showCursor\n" -"\n" -"```\n" -"fn showCursor*(show: bool) {\n" -"```\n" -"\n" -"Show or hide the cursor, linux only.\n" -"\n" -"\n" -"## fn freezeCursor\n" -"\n" -"```\n" -"fn freezeCursor*(freeze: bool) {\n" -"```\n" -"\n" -"Freezes the cursor in place. `input.getMouseDelta` will still report mouse\n" -"movements. The cursor will be automatically hidden.\n" -"\n" -"\n" -"## fn setCursor\n" -"\n" -"```\n" -"fn setCursor*(cursor: int) {\n" -"```\n" -"\n" -"Allows you to set the displaying cursor. Refer to the cursors section for available cursors.\n" -"\n" -"\n" -"## fn quit\n" -"\n" -"```\n" -"fn quit*() {\n" -"```\n" -"\n" -"Exits the application. Use this instead of umka\'s default `exit`.\n" -"\n" -"\n" -"## fn setClipboard\n" -"\n" -"```\n" -"fn setClipboard*(s: str) {\n" -"```\n" -"\n" -"Puts a string to the system clipboard.\n" -"\n" -"\n" -"## fn getClipboard\n" -"\n" -"```\n" -"fn getClipboard*(): str {\n" -"```\n" -"\n" -"Gets a string from the system clipboard.\n" -"\n" -"\n" -"## fn setViewportOffset\n" -"\n" -"```\n" -"fn setViewportOffset*(s: th.Vf2) {\n" -"```\n" -"\n" -"Sets the offset of the viewport.\n" -"\n" -"\n" -"## fn getViewportOffset\n" -"\n" -"```\n" -"```\n" -"\n" -"Gets the offset of the viewport (as set by `setViewportShift`)\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Particles allow for *performant* and random particle systems.\n" -"\n" -"\n" -"## struct Particle\n" -"\n" -"```\n" -"type Particle* = struct {\n" -"```\n" -"\n" -"Particle struct. You can tweak the start_time for godot-like explossivness.\n" -"\n" -"\n" -"## struct Emitter\n" -"\n" -"```\n" -"type Emitter* = struct {\n" -"\tpos: th.Vf2 // position\n" -"\tdm: th.Vf2 // size of the emittion area\n" -"\tgravity: th.Vf2 // gravity\n" -"\trepeat: bool // if false, particle won\'t be renewed\n" -"\tactive: bool // false, if there aren\'t any active particles anymore\n" -"\n" -"\tangle: th.Vf2 // angle in which particles are emitted\n" -"\n" -"\tlifetime: th.uu // lifetime of particles\n" -"\tlifetimeRandomness: th.fu // randomness in %/100\n" -"\n" -"\tvelocity: th.fu // velocity\n" -"\tvelocityRandomness: th.fu // randomness in %/100\n" -"\n" -"\tsize: th.fu // size\n" -"\tsizeRandomness: th.fu // randomness in %/100\n" -"\tmaxSize: th.fu // size at the end of particles lifetime\n" -"\n" -"\trotation: th.fu\n" -"\trotationRandomness: th.fu\n" -"\tmaxRotation: th.fu\n" -"\n" -"\tcolors: []uint32 // array of colors, which are interpolated between\n" -"\n" -"\tparticles: []Particle // list of particles\n" -"}\n" -"```\n" -"\n" -"Emitter. This is where everything is configured.\n" -"\n" -"\n" -"## fn Emitter.draw\n" -"\n" -"```\n" -"fn (e: ^Emitter) draw*(t: int32) {\n" -"```\n" -"\n" -"Draws and updates the particles.\n" -"\n" -"\n" -"## fn Emitter.genParticles\n" -"\n" -"```\n" -"fn (e: ^Emitter) genParticles*(time, count: uint, explosiveness: th.fu = 0.0) {\n" -"```\n" -"\n" -"Generates particles for an emitter. The time specifies the time the first\n" -"particles is emitted. The explosiveness argument specifies the interval at\n" -"which particles are emitted using this formula:\n" -"/ ```umka\n" -"/ e.lifetime / count * explosiveness\n" -"/ ```\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Simple linear interpolation module.\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Module for font rendering. Unicode is supported, but only left to right.\n" -"\n" -"\n" -"## Filtering constants\n" -"\n" -"```\n" -"const (\n" -"\tfilterNearest* = 0\n" -"\tfilterLinear* = 1\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## opaque Font\n" -"\n" -"```\n" -"type Font* = struct { _: ^struct{} }\n" -"```\n" -"\n" -"\n" -"\n" -"## fn load\n" -"\n" -"```\n" -"fn load*(path: str, size: th.fu, filter: uint32 = filterLinear): Font {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Font.validate\n" -"\n" -"```\n" -"fn (f: ^Font) validate*(): bool {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Font.draw\n" -"\n" -"```\n" -"fn (f: ^Font) draw*(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0) {\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Font.measure\n" -"\n" -"```\n" -"fn (f: ^Font) measure*(text: str): th.Vf2 {\n" -"```\n" -"\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Module with useful variables and types.\n" -"Variables: time, delta, platform\n" -"Constants: black, white, red, green, blue, yellow, magenta, cyan.\n" -"\n" -"\n" -"## Tophat type aliases\n" -"\n" -"```\n" -"type fu* = real32\n" -"// standard type for integer values\n" -"type iu* = int32\n" -"// standard type for unsigned values\n" -"type uu* = uint32\n" -"```\n" -"\n" -"standard type for real values\n" -"\n" -"\n" -"## struct Vf2\n" -"\n" -"```\n" -"type Vf2* = struct {\n" -"\tx, y: fu\n" -"}\n" -"```\n" -"\n" -"vector 2\n" -"\n" -"\n" -"## fn mkVf2\n" -"\n" -"```\n" -"fn mkVf2*(x: fu = 0, y: fu = 0): Vf2 {\n" -"\treturn Vf2{x, y}\n" -"}\n" -"```\n" -"\n" -"Vf2 constructor\n" -"\n" -"\n" -"## fn Vf2.rotated\n" -"\n" -"```\n" -"fn (p: ^Vf2) rotated*(origin: Vf2, rot: fu): Vf2 {\n" -"```\n" -"\n" -"rotates `p` around `origin` with `rot` in degrees\n" -"\n" -"\n" -"## fn Vf2.distanceTo\n" -"\n" -"```\n" -"fn (p1: ^Vf2) distanceTo*(p2: Vf2): fu {\n" -"```\n" -"\n" -"distance between p1 and p2\n" -"\n" -"\n" -"## fn Vf2.angleTo\n" -"\n" -"```\n" -"fn (p1: ^Vf2) angleTo*(p2: Vf2): real {\n" -"```\n" -"\n" -"Angle between p1 and p2\n" -"\n" -"\n" -"## fn Vf2.abs\n" -"\n" -"```\n" -"fn (p: ^Vf2) abs*(): Vf2 {\n" -"```\n" -"\n" -"Absolute value of a vector.\n" -"\n" -"\n" -"## fn Vf2.round\n" -"\n" -"```\n" -"fn (p: ^Vf2) round*(): Vf2 {\n" -"```\n" -"\n" -"Rounds a vector.\n" -"\n" -"\n" -"## fn Vf2.trunc\n" -"\n" -"```\n" -"fn (p: ^Vf2) trunc*(): Vf2 {\n" -"```\n" -"\n" -"Truncates a vector.\n" -"\n" -"\n" -"## fn Vf2.floor\n" -"\n" -"```\n" -"fn (p: ^Vf2) floor*(): Vf2 {\n" -"```\n" -"\n" -"Floors a vector.\n" -"\n" -"\n" -"## fn Vf2.ceil\n" -"\n" -"```\n" -"fn (p: ^Vf2) ceil*(): Vf2 {\n" -"```\n" -"\n" -"Ceils a vector.\n" -"\n" -"\n" -"## fn vf2f\n" -"\n" -"```\n" -"fn vf2f*(f: fu): Vf2 {\n" -"```\n" -"\n" -"Creates a vector with both x and y set to f\n" -"\n" -"\n" -"## fn Vf2.sub\n" -"\n" -"```\n" -"fn (p: ^Vf2) sub*(p2: Vf2): Vf2 {\n" -"```\n" -"\n" -"Subtracts a vector from another one.\n" -"\n" -"\n" -"## fn Vf2.subf\n" -"\n" -"```\n" -"fn (p: ^Vf2) subf*(f: fu): Vf2 {\n" -"```\n" -"\n" -"Subtracts a fu from a vector.\n" -"\n" -"\n" -"## fn Vf2.add\n" -"\n" -"```\n" -"fn (p: ^Vf2) add*(p2: Vf2): Vf2 {\n" -"```\n" -"\n" -"Adds a vector to another one.\n" -"\n" -"\n" -"## fn Vf2.addf\n" -"\n" -"```\n" -"fn (p: ^Vf2) addf*(f: fu): Vf2 {\n" -"```\n" -"\n" -"Adds a fu to a vector.\n" -"\n" -"\n" -"## fn Vf2.div\n" -"\n" -"```\n" -"fn (p: ^Vf2) div*(p2: Vf2): Vf2 {\n" -"```\n" -"\n" -"Divides a vector by another one.\n" -"\n" -"\n" -"## fn Vf2.divf\n" -"\n" -"```\n" -"fn (p: ^Vf2) divf*(f: fu): Vf2 {\n" -"```\n" -"\n" -"Divides a vector by a fu.\n" -"\n" -"\n" -"## fn Vf2.mul\n" -"\n" -"```\n" -"fn (p: ^Vf2) mul*(p2: Vf2): Vf2 {\n" -"```\n" -"\n" -"Multiplies a vector by another one.\n" -"\n" -"\n" -"## fn Vf2.mulf\n" -"\n" -"```\n" -"fn (p: ^Vf2) mulf*(f: fu): Vf2 {\n" -"```\n" -"\n" -"Multiplies a vector by a fu.\n" -"\n" -"\n" -"## fn Vf2.mag\n" -"\n" -"```\n" -"fn (p: ^Vf2) mag*(): fu {\n" -"```\n" -"\n" -"Returns the magnitude of a vector p.\n" -"\n" -"\n" -"## fn Vf2.norm\n" -"\n" -"```\n" -"fn (p: ^Vf2) norm*(): Vf2 {\n" -"```\n" -"\n" -"Normalizes a vector.\n" -"\n" -"\n" -"## fn Vf2.dot\n" -"\n" -"```\n" -"fn (p: ^Vf2) dot*(q: Vf2): fu {\n" -"```\n" -"\n" -"Calculates dot product between 2 vectors.\n" -"\n" -"\n" -"## struct Transform\n" -"\n" -"```\n" -"type Transform* = struct {\n" -"\tp: Vf2 // position\n" -"\ts: Vf2 // scale\n" -"\to: Vf2 // origin\n" -"\tr: fu // rotation\n" -"}\n" -"```\n" -"\n" -"Struct defining transformation. Used for example by entities.\n" -"\n" -"\n" -"## fn mkTransform\n" -"\n" -"```\n" -"fn mkTransform*(p: Vf2, s: Vf2 = Vf2{1, 1}, o: Vf2 = Vf2{0, 0}, r: fu = 0.0): Transform {\n" -"```\n" -"\n" -"Transform constructor\n" -"\n" -"\n" -"## fn Transform.transformed\n" -"\n" -"```\n" -"fn (o: ^Transform) transformed*(t: Transform): Transform {\n" -"```\n" -"\n" -"Transforms a transform with another transform.\n" -"\n" -"\n" -"## fn Vf2.transformed\n" -"\n" -"```\n" -"fn (v: ^Vf2) transformed*(t: Transform): Vf2 {\n" -"```\n" -"\n" -"Transforms a vf2 to another vf2.\n" -"Order:\n" -"1. scale\n" -"2. rotation\n" -"3. position\n" -"\n" -"This allows conversion from a relative to an absolute vf2.\n" -"\n" -"\n" -"## type Quad\n" -"\n" -"```\n" -"type Quad* = [4]Vf2\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Quad.getMax\n" -"\n" -"```\n" -"fn (q: ^Quad) getMax*(): Vf2 {\n" -"```\n" -"\n" -"Gets the maximum coordinate.\n" -"\n" -"\n" -"## fn Quad.getMin\n" -"\n" -"```\n" -"fn (q: ^Quad) getMin*(): Vf2 {\n" -"```\n" -"\n" -"Gets the minimum coordinate.\n" -"\n" -"\n" -"## fn Quad.getDims\n" -"\n" -"```\n" -"fn (q: ^Quad) getDims*(): Vf2 {\n" -"```\n" -"\n" -"Returns the dimensions of the quad\'s bounding box\n" -"\n" -"\n" -"## fn getGlobal\n" -"\n" -"```\n" -"fn getGlobal*(): ^struct{} {\n" -"```\n" -"\n" -"returns a pointer to the th_global. Set this as your extensions thg.\n" -"\n" -"\n" -"## fn getFuncs\n" -"\n" -"```\n" -"fn getFuncs*(): ^struct{} {\n" -"```\n" -"\n" -"returns pointer to tophat functions. Pass this to th_ext_set.\n" -"\n" -"\n" -"## var enableErrrors\n" -"\n" -"```\n" -"var enableErrors*: bool = true\n" -"```\n" -"\n" -"If true, errors will result in a call to error(), otherwise printf is used.\n" -"\n" -"\n" -"## Color constants\n" -"\n" -"```\n" -"const (\n" -"\tblack* = 0xff\n" -"\twhite* = 0xffffffff\n" -"\tred* = 0xff0000ff\n" -"\tgreen* = 0x00ff00ff\n" -"\tblue* = 0x0000ffff\n" -"\tyellow* = 0xffff00ff\n" -"\tmagenta* = 0xff00ffff\n" -"\tcyan* = 0x00ffffff\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## enum Platform\n" -"\n" -"```\n" -"type Platform* = int\n" -"const (\n" -"\tPlatformUnknown* = 0\n" -"\tPlatformLinux*\n" -"\tPlatformWindows*\n" -"\tPlatformMacOs*\n" -"\tPlatformWeb*\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## Misc variables\n" -"\n" -"```\n" -"var (\n" -"\t// time in ms from start of the game\n" -"\ttime*: uint\n" -"\t// length of the last frame in ms\n" -"\tdelta*: int\n" -"\t// platform tophat is running on\n" -"\tplatform*: Platform\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"A module for importless communication between modules. A signal is a set of\n" -"callbacks. You can use signals directly in your own structs if you want\n" -"them to be instance specific, of you can use global signals which are\n" -"adressed by a string name.\n" -"\n" -"\n" -"## type Callback\n" -"\n" -"```\n" -"type Callback* = fn(args: []any)\n" -"```\n" -"\n" -"`args` is a list of arguments passed to the `emit` method.\n" -"\n" -"\n" -"## type Id\n" -"\n" -"```\n" -"type Id* = uint\n" -"```\n" -"\n" -"\n" -"\n" -"## type Signal\n" -"\n" -"```\n" -"type Signal* = map[Id]Callback\n" -"```\n" -"\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(): Signal {\n" -"```\n" -"\n" -"`Signal` constructor\n" -"\n" -"\n" -"## fn Signal.register\n" -"\n" -"```\n" -"fn (this: ^Signal) register*(callback: Callback): Id {\n" -"```\n" -"\n" -"Registers a callback to a signal and returns the callback id.\n" -"\n" -"\n" -"## fn Signal.remove\n" -"\n" -"```\n" -"fn (this: ^Signal) remove*(id: Id) {\n" -"```\n" -"\n" -"Removes a callback by id.\n" -"\n" -"\n" -"## fn Signal.emit\n" -"\n" -"```\n" -"fn (this: ^Signal) emit*(args: ..any) {\n" -"```\n" -"\n" -"Emits a signal.\n" -"\n" -"\n" -"## fn Signal.clear\n" -"\n" -"```\n" -"fn (this: ^Signal) clear*() {\n" -"```\n" -"\n" -"Removes all signal handlers.\n" -"\n" -"\n" -"## fn register\n" -"\n" -"```\n" -"fn register*(name: str, callback: Callback): Id {\n" -"```\n" -"\n" -"Registers a callback to a global signal. There is no need to explicitly\n" -"create global signals. Returns id of the added callback\n" -"\n" -"\n" -"## fn remove\n" -"\n" -"```\n" -"fn remove*(name: str, id: Id) {\n" -"```\n" -"\n" -"Removes a callback from a global signal by id.\n" -"\n" -"\n" -"## fn remove\n" -"\n" -"```\n" -"fn clear*(name: str) {\n" -"```\n" -"\n" -"Removes all signal handlers from a global signal.\n" -"\n" -"\n" -"## fn emit\n" -"\n" -"```\n" -"fn emit*(name: str, args: ..any) {\n" -"```\n" -"\n" -"Calls all callbacks associated with the passed global signal name.\n" -"\n" -"\n" -"", -"## struct Atlas\n" -"\n" -"```\n" -"type Atlas* = struct {\n" -"\ti: image.Image // source image\n" -"\tcs: th.Vf2 // size of a cell in pixels\n" -"\tdm: th.Vf2 // amount of cells in image\n" -"}\n" -"```\n" -"\n" -"Atlas is an image containing tiles in a square grid.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(i: image.Image, dm: th.Vf2): Atlas {\n" -"```\n" -"\n" -"i: source image\n" -"dm: amount of cells\n" -"\n" -"\n" -"## fn Atlas.coords\n" -"\n" -"```\n" -"fn (a: ^Atlas) coords*(n: int): th.Vf2 {\n" -"```\n" -"\n" -"returns the coordinates of the nth tile\n" -"\n" -"\n" -"## fn Atlas.cropSource\n" -"\n" -"```\n" -"fn (a: ^Atlas) cropSource*(at: th.Vf2) {\n" -"```\n" -"\n" -"Crops the sourse image to only show a wanted tile\n" -"\n" -"\n" -"## enum PackStrategy\n" -"\n" -"```\n" -"const (\n" -"\tPackSquare* = 0\n" -"\tPackRow*\n" -"\tPackColumn*\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## fn pack\n" -"\n" -"```\n" -"fn pack*(images: []image.Image, strategy: int): Atlas {\n" -"```\n" -"\n" -"Packs an array of images into an atlas\n" -"\n" -"\n" -"## fn Atlas.draw\n" -"\n" -"```\n" -"fn (a: ^Atlas) draw*(at: th.Vf2, t: th.Transform) {\n" -"```\n" -"\n" -"Draws the tile at `at`\n" -"\n" -"\n" -"", -"## opaque Shader\n" -"\n" -"```\n" -"type Shader* = struct {\n" -"```\n" -"\n" -"Shader allows you to define your own vertex and fragment GLSL shaders. This\n" -"is a low-level feature, so it\'s very easy to mess up.\n" -"\n" -"In tophat, instead of a main function, shaders provide th_vertex and\n" -"th_fragment. The signature of th_vertex is:\n" -"\n" -"```\n" -"vec2 th_vertex(vec2 vert);\n" -"```\n" -"\n" -"where vert is the position of the vertex taken from the vertex buffer.\n" -"The output is the vertex shader output.\n" -"\n" -"As for fragment shaders, there are two types of them. One for canvas\n" -"and one for images. In canvas shaders, the fragment function is very simple:\n" -"\n" -"```\n" -"vec4 th_fragment(vec4 color);\n" -"```\n" -"\n" -"Image fragment function looks like this:\n" -"\n" -"```\n" -"vec4 th_fragment(sampler2D tex, vec2 coord);\n" -"```\n" -"\n" -"where tex is the texture and coord are the texture coordinates. Be aware to\n" -"swap the output of the `texture2D` function. Example:\n" -"\n" -"```\n" -"texture2D(tex, coord).abgr\n" -"```\n" -"\n" -"\n" -"## Default shader constants\n" -"\n" -"```\n" -"const (\n" -"\tdefaultImageShader* = Shader{1}\n" -"\tdefaultCanvasShader* = Shader{2}\n" -")\n" -"```\n" -"\n" -"\n" -"\n" -"## struct Uniform\n" -"\n" -"```\n" -"type Uniform* = struct {\n" -"\ts: Shader\n" -"\tl: uint\n" -"}\n" -"```\n" -"\n" -"Represents a GLSL uniform.\n" -"\n" -"\n" -"## fn mkCanvas\n" -"\n" -"```\n" -"fn mkCanvas*(vertex, fragment: str): Shader {\n" -"```\n" -"\n" -"Compiles a canvas shader from source. If there is a compilation error, it\n" -"will print something to the console.\n" -"\n" -"\n" -"## fn mkImage\n" -"\n" -"```\n" -"fn mkImage*(vertex, fragment: str): Shader {\n" -"```\n" -"\n" -"Compiles an image shader from source. If there is a compilation error, it\n" -"will print something to the console.\n" -"\n" -"\n" -"## fn Shader.pickForCanvas\n" -"\n" -"```\n" -"fn (s: ^Shader) pickForCanvas*() {\n" -"```\n" -"\n" -"Picks the shader to be used for canvas drawing. Flushes the canvas batch.\n" -"\n" -"\n" -"## fn Shader.pickForImage\n" -"\n" -"```\n" -"fn (s: ^Shader) pickForImage*() {\n" -"```\n" -"\n" -"Picks the shader to be used for image drawing. Flushes the image batch.\n" -"\n" -"\n" -"## fn Shader.getUniformLocation\n" -"\n" -"```\n" -"fn (s: ^Shader) getUniformLocation*(name: str): Uniform {\n" -"```\n" -"\n" -"Retunrs a uniform by name.\n" -"\n" -"\n" -"## fn Uniform.setInt\n" -"\n" -"```\n" -"fn (u: ^Uniform) setInt*(value: int) {\n" -"```\n" -"\n" -"Sets a uniform to an int value. Flushes both batches.\n" -"\n" -"\n" -"## fn Uniform.setVf2\n" -"\n" -"```\n" -"fn (u: ^Uniform) setVf2*(value: th.Vf2) {\n" -"```\n" -"\n" -"Sets a uniform to a vf2. Flushes both batches.\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Color operations. Operate on RGBA uint32 values.\n" -"\n" -"\n" -"## fn hsv\n" -"\n" -"```\n" -"fn hsv*(h, s, v: th.fu, a: th.fu = 1.0): uint32 {\n" -"```\n" -"\n" -"Converts HSV values into RGBA uint32 color.\n" -"NOTE: Hue is between 0 and 1\n" -"\n" -"\n" -"## fn alpha\n" -"\n" -"```\n" -"fn alpha*(c: uint32, to: th.fu): uint32 {\n" -"```\n" -"\n" -"Sets alpha of the color c to a value in to.\n" -"\n" -"\n" -"## fn rgb\n" -"\n" -"```\n" -"fn rgb*(r, g, b: th.fu, a: th.fu = 1.0): uint32 {\n" -"```\n" -"\n" -"Constructs RGBA uint32 from RGBA of reals.\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"Builtin collision functions. The ic argument stores the collision position.\n" -"\n" -"\n" -"## fn lineToLine\n" -"\n" -"```\n" -"fn lineToLine*(b1, e1, b2, e2: th.Vf2, ic: ^th.Vf2): bool {\n" -"```\n" -"\n" -"Checks for a collision between 2 lines specified by their end points.\n" -"\n" -"\n" -"## fn vf2ToQuad\n" -"\n" -"```\n" -"fn vf2ToQuad*(p: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n" -"```\n" -"\n" -"Checks for a collision between a vf2 and a quad.\n" -"\n" -"\n" -"## fn lineToQuad\n" -"\n" -"```\n" -"fn lineToQuad*(b, e: th.Vf2, q: th.Quad, ic: ^th.Vf2): bool {\n" -"```\n" -"\n" -"Check for a collision between a line and quad edges.\n" -"\n" -"\n" -"## fn quadToQuad\n" -"\n" -"```\n" -"fn quadToQuad*(q1, q2: th.Quad, ic: ^th.Vf2): bool {\n" -"```\n" -"\n" -"Check for a collision between two quads.\n" -"\n" -"\n" -"## fn vf2ToRect\n" -"\n" -"```\n" -"fn vf2ToRect*(p: th.Vf2, r: rect.Rect): bool {\n" -"```\n" -"\n" -"Check for a collision between a vf2 and a rectangle.\n" -"\n" -"\n" -"## fn rectToRect\n" -"\n" -"```\n" -"fn rectToRect*(r1, r2: rect.Rect): bool {\n" -"```\n" -"\n" -"Check for a collision between two rects\n" -"\n" -"\n" -"", -"## Placeholder images\n" -"\n" -"```\n" -"var (\n" -"\t// an image useful for testing\n" -"\ttest*: image.Image\n" -"\t// the image used for the app icon\n" -"\ticon*: image.Image\n" -"\t// Windows 95 style button, to be used with ninepatch (image.um) \n" -"\tbutton*: image.Image\n" -")\n" -"```\n" -"\n" -"These images are included with tophat and don\'t have to be loaded.\n" -"\n" -"\n" -"", -"## struct Mesh\n" -"\n" -"```\n" -"type Mesh* = struct {\n" -"\t// The mesh data.\n" -"\td: []bool\n" -"\t// The dimensions and position of the mesh, r.w == w * s\n" -"\tr: rect.Rect\n" -"\t// Width of the mesh. Used to adress the mesh data.\n" -"\tw: th.uu\n" -"\t// Scale of one cell (cell is a square)\n" -"\ts: th.fu\n" -"}\n" -"```\n" -"\n" -"Mesh is a 2d array of bool cells. If a cell is true, the cell can be used\n" -"in a path. The mesh is located in a world using the `r` field. A cell can\n" -"have an arbitrary size as specified by `s`.\n" -"\n" -"The mesh can be edited using the `addQuad` method, but it should be trivial\n" -"to add your own, similar methods.\n" -"\n" -"Please use the `mk` constructor to construct a `Mesh`, unless you really\n" -"know what you\'re doing.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(r: rect.Rect, s: th.fu): Mesh {\n" -"```\n" -"\n" -"Creates a new nav mesh.\n" -"`r`\n" -": the rectangle of the mask\n" -"\'s\'\n" -": the scale of the mask\n" -"\n" -"\n" -"## fn Mesh.addQuad\n" -"\n" -"```\n" -"fn (m: ^Mesh) addQuad*(q: th.Quad) {\n" -"```\n" -"\n" -"Sets mask\'s fields overlapping `q` to `false`.\n" -"\n" -"\n" -"## fn Mesh.nav\n" -"\n" -"```\n" -"fn (m: ^Mesh) nav*(p1, p2: th.Vf2): []th.Vf2 {\n" -"```\n" -"\n" -"Navigates between `p1` and `p2`. Returns the path as an array of `th.Vf2`s.\n" -"If it doesn\'t find any path, or one of the points is outside of the mask,\n" -"returns an empty array.\n" -"\n" -"\n" -"## fn Mesh.draw\n" -"\n" -"```\n" -"fn (m: ^Mesh) draw*(alpha: real32 = 1.0) {\n" -"```\n" -"\n" -"Draws the mesh for debugging purposes.\n" -"\n" -"\n" -"", -"## \n" -"\n" -"```\n" -"```\n" -"\n" -"`ui.um` offers an immediate GUI library suitable both for simple game menus\n" -"and more complex applications. See the [tutorial](/tut/spritesheet.html)\n" -"for example usage.\n" -"\n" -"\n" -"## struct BoxStyle\n" -"\n" -"```\n" -"type BoxStyle* = struct {\n" -"\timg: image.Image\n" -"\touter, inner: rect.Rect\n" -"\tscale: th.fu\n" -"\tcolor: uint32\n" -"}\n" -"```\n" -"\n" -"`BoxStyle` describes how a box within the GUI is styled. In this case box\n" -"can be anything, ranging from a button to a container. By default the box\n" -"is drawn using the `image.Image.drawNinepatch` method. However if the image\n" -"is invalid, a rectangle with color `color` is drawn.\n" -"\n" -"\n" -"## interface Font\n" -"\n" -"```\n" -"type Font* = interface {\n" -"\tdraw(text: str, pos: th.Vf2, color: uint32, scale: th.fu = 1.0)\n" -"\tmeasure(test: str): th.Vf2\n" -"}\n" -"```\n" -"\n" -"This interface is used by all elements that draw text. A `font.Font`\n" -"implements this interface.\n" -"\n" -"\n" -"## struct PixelFont\n" -"\n" -"```\n" -"type PixelFont* = struct { }\n" -"```\n" -"\n" -"This struct implement the `Font` interface using the `canvas.um` pixel font.\n" -"\n" -"\n" -"## struct Style\n" -"\n" -"```\n" -"type Style* = struct {\n" -"\t// current font\n" -"\tft: Font\n" -"\t// font scale\n" -"\tftScale: th.fu\n" -"\t// text color\n" -"\tftColor: uint32\n" -"\n" -"\t// Positive box - i. e. unpressed button\n" -"\tposBox: BoxStyle\n" -"\t// Negative box - i. e. pressed button, text box\n" -"\tnegBox: BoxStyle\n" -"\t// Used to draw containers\n" -"\tcontainerBox: BoxStyle\n" -"}\n" -"```\n" -"\n" -"`Style` is used as a global state for styling the GUI.\n" -"\n" -"\n" -"## interface Container\n" -"\n" -"```\n" -"type Container* = interface {\n" -"\t// This adds a rectangle to the container, and returns the rectangle\n" -"\t// which was actually added (the container can modify the rectangle).\n" -"\t// See individual containers for further documentation.\n" -"\tpushRect(r: rect.Rect): rect.Rect\n" -"\tgetDims(): rect.Rect\n" -"}\n" -"```\n" -"\n" -"Containers are used to layout elements or other containers.\n" -"\n" -"\n" -"## struct Gui\n" -"\n" -"```\n" -"type Gui* = struct {\n" -"\t// user context passed to layout functions\n" -"\tctx: any\n" -"\n" -"\t// the index of the current selection. TODO implement properly\n" -"\tselection: int\n" -"\t// true, if the layout is being evaluated, not drawn\n" -"\tisEval: bool\n" -"\t// contains more unexported fields\n" -"```\n" -"\n" -"This is the main struct of any UI. Styles and containers are in a stack.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(r: rect.Rect, s: Style): Gui\n" -"```\n" -"\n" -"Creates a new gui spanning `r`, with style `s`.\n" -"\n" -"\n" -"## type LayoutFn\n" -"\n" -"```\n" -"type LayoutFn* = fn(gui: ^Gui)\n" -"```\n" -"\n" -"The layout function calls different element or container methods to create\n" -"the user interface itself. It is called in the `eval` and `draw`.\n" -"\n" -"\n" -"## fn BoxStyle.draw\n" -"\n" -"```\n" -"fn (this: ^BoxStyle) draw*(r: rect.Rect) {\n" -"```\n" -"\n" -"Draws a rectangle using a BoxStyle\n" -"\n" -"\n" -"## fn Gui.pushStyle\n" -"\n" -"```\n" -"fn (this: ^Gui) pushStyle*(s: Style) {\n" -"```\n" -"\n" -"Pushes a style onto the style stack.\n" -"\n" -"\n" -"## fn Gui.popStyle\n" -"\n" -"```\n" -"fn (this: ^Gui) popStyle*() {\n" -"```\n" -"\n" -"Pops a style from the style stack.\n" -"\n" -"\n" -"## fn Gui.getStyle\n" -"\n" -"```\n" -"fn (this: ^Gui) getStyle*(): ^Style {\n" -"```\n" -"\n" -"Returns a pointer to the style atop the style stack.\n" -"\n" -"\n" -"## fn Gui.getContainer\n" -"\n" -"```\n" -"fn (this: ^Gui) getContainer*(): Container {\n" -"```\n" -"\n" -"Returns the container atop the container stack.\n" -"\n" -"\n" -"## fn Gui.pushRect\n" -"\n" -"```\n" -"fn (this: ^Gui) pushRect*(r: rect.Rect): rect.Rect {\n" -"```\n" -"\n" -"Shortcut to `this.getContainer().pushRect(r)`\n" -"\n" -"\n" -"## fn Gui.getDims\n" -"\n" -"```\n" -"fn (this: ^Gui) getDims*(): rect.Rect {\n" -"```\n" -"\n" -"Shortcut to `this.getContainer().getDims(r)`\n" -"\n" -"\n" -"## fn Gui.dupStyle\n" -"\n" -"```\n" -"fn (this: ^Gui) dupStyle*() {\n" -"```\n" -"\n" -"Duplicates the current style.\n" -"\n" -"\n" -"## fn Gui.pushContainer\n" -"\n" -"```\n" -"fn (this: ^Gui) pushContainer*(c: Container) {\n" -"```\n" -"\n" -"Pushes a container onto the container stack.\n" -"\n" -"\n" -"## fn Gui.popContainer\n" -"\n" -"```\n" -"fn (this: ^Gui) popContainer*() {\n" -"```\n" -"\n" -"Pops a container from the container stack.\n" -"\n" -"\n" -"## fn Gui.eval\n" -"\n" -"```\n" -"fn (this: ^Gui) eval*(layout: LayoutFn) {\n" -"```\n" -"\n" -"Runs the evaluation phase on `layout`.\n" -"\n" -"\n" -"## fn Gui.draw\n" -"\n" -"```\n" -"fn (this: ^Gui) draw*(layout: LayoutFn) {\n" -"```\n" -"\n" -"Runs the draw phase on `layout`.\n" -"\n" -"\n" -"## enum BoxGrow\n" -"\n" -"```\n" -"type BoxGrow* = uint\n" -"const (\n" -"\t// Increments by an amount set by the user.\n" -"\tBoxGrowDimension* = BoxGrow(0)\n" -"\t// Divides the container into `n` equal parts.\n" -"\tBoxGrowSubdivision* = BoxGrow(1)\n" -"\t// Grows the box based on values in the span array.\n" -"\tBoxGrowSpan* = BoxGrow(2)\n" -"\tBoxGrowPxSpan* = BoxGrow(3)\n" -")\n" -"```\n" -"\n" -"The different types of \"growing\" the box can do.\n" -"\n" -"\n" -"## enum BoxDirection\n" -"\n" -"```\n" -"type BoxDirection* = uint\n" -"const (\n" -"\tBoxDirectionDown* = BoxDirection(0)\n" -"\tBoxDirectionRight* = BoxDirection(1)\n" -"\tBoxDirectionUp* = BoxDirection(2)\n" -"\tBoxDirectionLeft* = BoxDirection(3)\n" -")\n" -"```\n" -"\n" -"Direction in which the box will grow.\n" -"\n" -"\n" -"## struct BoxConfig\n" -"\n" -"```\n" -"type BoxConfig* = struct {\n" -"\t// dimension to grow by if `BoxGrowDimension` is used\n" -"\tdimension: th.fu\n" -"\t// number of subdivisions if `BoxGrowSubdivisions` is used\n" -"\tsubdivisions: uint\n" -"\t// the grow type\n" -"\tgrowType: BoxGrow\n" -"\t// the grow direction\n" -"\tdir: BoxDirection\n" -"\t// Specifies the values used with BoxGrowSpan nad BoxGrowPxSpan.\n" -"\t// If BoxGrowSpan is used, 1 equals the size of the box divided by the sum\n" -"\t// of all spans.\n" -"\t// If BoxGrowPxSpan is used, 1 equals one pixel.\n" -"\tspan: []th.fu\n" -"\t// rect passed to the current container\n" -"\trect: rect.Rect\n" -"\t// padding inserted after each element\n" -"\tpadding: th.fu\n" -"}\n" -"```\n" -"\n" -"Configuration of the `Box` container.\n" -"\n" -"\n" -"## struct Box\n" -"\n" -"```\n" -"type Box* = struct {\n" -"\tgrow: th.fu\n" -"\tspanCursor: int\n" -"\tdm: rect.Rect\n" -"\tcfg: BoxConfig\n" -"}\n" -"```\n" -"\n" -"`Box` is the main layout. It puts the elements next to each other,\n" -"according to the config.\n" -"\n" -"If the dimensions of the rect passed to `pushRect` are non zero, they will\n" -"be kept. Position is always forced.\n" -"\n" -"\n" -"## fn Gui.box\n" -"\n" -"```\n" -"fn (gui: ^Gui) box*(cfg: BoxConfig = {\n" -"\tdimension: 30,\n" -"\tgrowType: BoxGrowDimension,\n" -"\tdir: BoxDirectionDown }) {\n" -"```\n" -"\n" -"Adds the `Box` container to the gui.\n" -"\n" -"\n" -"## struct StackConfig\n" -"\n" -"```\n" -"type StackConfig* = struct {\n" -"\trect: rect.Rect\n" -"\tpadding: th.fu\n" -"}\n" -"```\n" -"\n" -"Configuration for the `Stack` container.\n" -"\n" -"\n" -"## struct Stack\n" -"\n" -"```\n" -"type Stack* = struct {\n" -"\tdm: rect.Rect\n" -"\tcfg: StackConfig\n" -"}\n" -"```\n" -"\n" -"The stack container puts elements on top of each other.\n" -"If a property of the rect passed to `pushRect` is zero, it will be changed\n" -"to an equivalent property of the containers\' dimensions (minus the padding),\n" -"else it will stay the same. This means stack can be used either to put\n" -"multiple elements/containers on top of each other, or for absolutely\n" -"positioned elements.\n" -"\n" -"\n" -"## fn Gui.stack\n" -"\n" -"```\n" -"fn (gui: ^Gui) stack*(cfg: StackConfig = {}) {\n" -"```\n" -"\n" -"Adds the `Stack` container to the gui.\n" -"\n" -"\n" -"## struct ScrollAreaConfig\n" -"\n" -"```\n" -"type ScrollAreaConfig* = struct {\n" -"\trect: rect.Rect\n" -"\t// scroll speed. Default is 1\n" -"\tspeed: real32\n" -"\t// if true, scrolling will be horizontal\n" -"\thorizontal: bool\n" -"}\n" -"```\n" -"\n" -"Configuration for the scroll area.\n" -"\n" -"\n" -"## struct ScrollArea\n" -"\n" -"```\n" -"type ScrollArea* = struct {\n" -"\tdm: rect.Rect\n" -"\tcfg: ScrollAreaConfig\n" -"\tscroll: ^real32\n" -"\tmaxScroll: real32\n" -"}\n" -"```\n" -"\n" -"Scroll area is a container which allows the user to scroll. It acts as a\n" -"stack container, but all the elements are shifted by the scroll.\n" -"\n" -"\n" -"## fn Gui.scrollArea\n" -"\n" -"```\n" -"fn (gui: ^Gui) scrollArea*(scroll: ^real32, maxScroll: real32, cfg: ScrollAreaConfig = {}) {\n" -"```\n" -"\n" -"Pushes a scroll area. `scroll` is both input and output value. Both `scroll`\n" -"and `maxScroll` are in pixels.\n" -"\n" -"\n" -"## struct ButtonConfig\n" -"\n" -"```\n" -"type ButtonConfig* = struct {\n" -"\trect: rect.Rect\n" -"}\n" -"```\n" -"\n" -"Configuration for the button.\n" -"\n" -"\n" -"## fn Gui.button\n" -"\n" -"```\n" -"fn (gui: ^Gui) button*(cfg: ButtonConfig = {}): bool {\n" -"```\n" -"\n" -"Adds a button to the gui. The button acts like a `Stack` container, but it\n" -"is drawn using the pos/nexBox styles and handles clicks. If the button is\n" -"pressed and the gui is in the eval phase, the return value will be true.\n" -"\n" -"\n" -"## struct LabelConfig\n" -"\n" -"```\n" -"type LabelConfig* = struct {\n" -"\t// centers the label along the X axis, enables `stretchX`\n" -"\tcenterX: bool\n" -"\t// centers the label along the Y axis, enables `stretchY`\n" -"\tcenterY: bool\n" -"\t// if false, the rect passed to `pushRect` will have the width of\n" -"\t// the text, else it will be 0\n" -"\tstretchX: bool\n" -"\t// if false, the rect passed to `pushRect` will have the height of\n" -"\t// the text, else it will be 0\n" -"\tstretchY: bool\n" -"\t// forces the rectangle the label will use\n" -"\trect: rect.Rect\n" -"}\n" -"```\n" -"\n" -"\n" -"\n" -"## fn Gui.label\n" -"\n" -"```\n" -"fn (gui: ^Gui) label*(text: str, cfg: LabelConfig = {\n" -"```\n" -"\n" -"Draws a label using the current font style.\n" -"\n" -"\n" -"## fn Gui.qbutton\n" -"\n" -"```\n" -"fn (gui: ^Gui) qbutton*(text: str, cfg: ButtonConfig = {}): bool {\n" -"```\n" -"\n" -"Adds a button with a label to gui.\n" -"\n" -"\n" -"## struct TextBoxConfig\n" -"\n" -"```\n" -"type TextBoxConfig* = struct {\n" -"\t// force the rect of the text box\n" -"\trect: rect.Rect\n" -"}\n" -"```\n" -"\n" -"\n" -"\n" -"## struct TextBox\n" -"\n" -"```\n" -"type TextBox* = struct {\n" -"\t// index of the cursor\n" -"\tcursor: int\n" -"\t// contains other unexported rules...\n" -"```\n" -"\n" -"\n" -"\n" -"## fn TextBox.clear\n" -"\n" -"```\n" -"fn (this: ^TextBox) clear*() {\n" -"```\n" -"\n" -"Clears the textbox\n" -"\n" -"\n" -"## fn TextBox.getBuf()\n" -"\n" -"```\n" -"fn (this: ^TextBox) getBuf*(): str {\n" -"```\n" -"\n" -"Get the content of the textbox.\n" -"\n" -"\n" -"## fn TextBox.setBuf()\n" -"\n" -"```\n" -"fn (this: ^TextBox) setBuf*(s: str) {\n" -"```\n" -"\n" -"Get the content of the textbox.\n" -"\n" -"\n" -"## fn Gui.textBox\n" -"\n" -"```\n" -"fn (gui: ^Gui) textBox*(tb: ^TextBox, cfg: TextBoxConfig = {}) {\n" -"```\n" -"\n" -"Adds a single line textbox to the gui.\n" -"TODO:\n" -"* right-to-left unicode is not supported.\n" -"* no selection\n" -"* multiline\n" -"* copy paste\n" -"* stuff like home and end\n" -"\n" -"\n" -"## struct ImageConfig\n" -"\n" -"```\n" -"type ImageConfig* = struct {\n" -"\tstretchX, stretchY: bool\n" -"\tcenterX, centerY: bool\n" -"\tcolor: uint32\n" -"\tscale: th.Vf2\n" -"\trect: rect.Rect\n" -"}\n" -"```\n" -"\n" -"Configuration for the images element. Behaves similarly to labels.\n" -"\n" -"\n" -"## fn Gui.image\n" -"\n" -"```\n" -"fn (gui: ^Gui) image*(i: image.Image, cfg: ImageConfig = {\n" -"\tstretchX: true,\n" -"\tstretchY: true,\n" -"\tcolor: th.white,\n" -"\tscale: { 1, 1 } }) {\n" -"```\n" -"\n" -"Draws an image.\n" -"\n" -"\n" -"## fn getDefaultStyle\n" -"\n" -"```\n" -"fn getDefaultStyle*(): Style {\n" -"```\n" -"\n" -"Returns the default tophat ui style.\n" -"\n" -"\n" -"## fn mk\n" -"\n" -"```\n" -"fn mk*(r: rect.Rect, s: Style): Gui {\n" -"```\n" -"\n" -"Creates a GUI instance.\n" -"\n" -"\n" -"", -}; -static uint32_t th_em_placeholder_data_2[] = {0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff0a35d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0, 0xff3f0cf8, 0xff3f0cf8, 0xffef0cf8, 0xffef0cf8, 0xffd00a20, 0xffd00a20, 0xffd0d00a, 0xffd0d00a, 0xff3dd00a, 0xff3dd00a, 0xff0ac0d0, 0xff0ac0d0}; -static uint32_t th_em_placeholder_data_3[] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xff262626, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0xffd5aeae, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}; -static uint32_t th_em_placeholder_data_4[] = {0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffc0c0c0, 0xffc0c0c0, 0xff808080, 0xff000000, 0xff000000, 0xff808080, 0xff808080, 0xff808080, 0xffffffff, 0xffffffff, 0xffc0c0c0, 0xffc0c0c0, 0xff808080, 0xff000000, 0xff000000, 0xff808080, 0xffc0c0c0, 0xffc0c0c0, 0xffffffff, 0xffffffff, 0xff808080, 0xff808080, 0xff808080, 0xff000000, 0xff000000, 0xff808080, 0xffc0c0c0, 0xffc0c0c0, 0xffffffff, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xff000000, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff}; -th_em_placeholder th_em_placeholders[] = { -{ th_em_placeholder_data_2, { .w = 12, .h = 12 } }, -{ th_em_placeholder_data_3, { .w = 69, .h = 69 } }, -{ th_em_placeholder_data_4, { .w = 10, .h = 5 } }, -}; diff --git a/tests/uit.um b/tests/uit.um index 463cd4a6..6b02ce20 100644 --- a/tests/uit.um +++ b/tests/uit.um @@ -15,11 +15,11 @@ fn init*() { window.setup("gui test", 600, 600) window.setViewport(th.Vf2{ 200, 200 }) - ft := font.load("etc/roboto.ttf", 96, font.filterLinear) + ft := font.load("etc/roboto.ttf", 32, font.filterLinear) gui = ui.mk(rect.mk(0, 0, 200, 200), ui.getDefaultStyle()) gui.getStyle().ft = ft - gui.getStyle().ftScale = 0.1 + gui.getStyle().ftScale = 0.3 win = ui.mk(rect.mk(100, 100, 80, 50), ui.getDefaultStyle()) win.getStyle().containerBox.color = 0x88aa88ff diff --git a/umka/ui.um b/umka/ui.um index 4b2461a6..fa23ef1a 100644 --- a/umka/ui.um +++ b/umka/ui.um @@ -736,7 +736,7 @@ fn (gui: ^Gui) textBox*(tb: ^TextBox, cfg: TextBoxConfig = {}) { runes := utf8.decode(input.getStr()) if len(runes) > 0 && v { - tb.buffer = append(slice(tb.buffer, 0, tb.cursor), append(slice(tb.buffer, tb.cursor), runes)) + tb.buffer = append(append(slice(tb.buffer, 0, tb.cursor), runes), slice(tb.buffer, tb.cursor)) tb.cursor += len(runes) }