diff --git a/demos/flappy/main.um b/demos/flappy/main.um index 9ec9add..5634ae0 100644 --- a/demos/flappy/main.um +++ b/demos/flappy/main.um @@ -25,10 +25,8 @@ const ( ) // The different frames for the bird -const ( - BirdAnimJump = th::Vf2{ 0, 0 } - BirdAnimFall = th::Vf2{ 1, 0 } -) +BirdAnimJump := th::Vf2{ 0, 0 } +BirdAnimFall := th::Vf2{ 1, 0 } var ( // atlas containing the bird textures diff --git a/demos/pomodoro/main.um b/demos/pomodoro/main.um index 859e69d..b30f014 100644 --- a/demos/pomodoro/main.um +++ b/demos/pomodoro/main.um @@ -259,10 +259,8 @@ type ( } ) -const ( - c_colorschemeDark = Colorscheme{item: 0x565758FF, itemHovered: 0x727475FF, text: 0xFFFFFFFF, background: 0x202122FF, current: 0x4ffa7aFF} - c_colorschemeLight = Colorscheme{item: 0xd7d7d7FF, itemHovered: 0xC4C4C4FF, text: 0x000000FF, background: 0xEEEEEFFF, current: 0x178c35FF} -) +c_colorschemeDark := Colorscheme{item: 0x565758FF, itemHovered: 0x727475FF, text: 0xFFFFFFFF, background: 0x202122FF, current: 0x4ffa7aFF} +c_colorschemeLight := Colorscheme{item: 0xd7d7d7FF, itemHovered: 0xC4C4C4FF, text: 0x000000FF, background: 0xEEEEEFFF, current: 0x178c35FF} var ( v_mainFont: th_font::Font @@ -270,7 +268,7 @@ var ( v_rectBase: th_image::Image isDark: bool = true - v_colorscheme: Colorscheme = c_colorschemeDark + v_colorscheme: Colorscheme v_lastTime: int v_countdown: Countdown v_countdownNumber: int @@ -490,6 +488,7 @@ const onFrame = fn(args: []any) { fn init*() { var err: std::Err + v_colorscheme = c_colorschemeDark v_lastTime = th::time th_window::setup("Pomodoro", trunc(screen.w), trunc(screen.h)) th_window::setViewport(th::Vf2{screen.w, screen.h}) diff --git a/demos/space-shooter/enemy.um b/demos/space-shooter/enemy.um index 40c91a0..95f5121 100644 --- a/demos/space-shooter/enemy.um +++ b/demos/space-shooter/enemy.um @@ -15,8 +15,8 @@ type Enemy* = struct { ent: ent::Ent } +speed := th::Vf2{0.015, 0.04} const ( - speed = th::Vf2{0.015, 0.04} maxEnemies = 4 ) diff --git a/demos/space-shooter/hud.um b/demos/space-shooter/hud.um index 146ef3c..bd1930d 100644 --- a/demos/space-shooter/hud.um +++ b/demos/space-shooter/hud.um @@ -19,7 +19,7 @@ fn init*() { hearth, err = image::load("gfx/hearth.png") std::exitif(err) - mainFont, err = font::load("gfx/marediv-regular.ttf", 64, font::Filter.nearest) + mainFont, err = font::load("gfx/marediv-regular.ttf", 64, .nearest) std::exitif(err) } diff --git a/demos/tetris/field.um b/demos/tetris/field.um index 5b0d3aa..c05b692 100644 --- a/demos/tetris/field.um +++ b/demos/tetris/field.um @@ -10,17 +10,19 @@ const ( FieldWidth* = 10 FieldHeight* = 22 - Colors* = [8]int{ - /*None*/ 0x000000FF, - /*Red*/ 0xFF0000FF, - /*Green*/ 0x00FF00FF, - /*Blue*/ 0x0000FFFF, - /*Yellow*/0xFFFF00FF, - /*Purple*/0xFF00FFFF, - /*Orange*/0xFF9900FF, - /*Cyan*/ 0x00CCFFFF} ) +colors* := [8]int{ + /*None*/ 0x000000FF, + /*Red*/ 0xFF0000FF, + /*Green*/ 0x00FF00FF, + /*Blue*/ 0x0000FFFF, + /*Yellow*/0xFFFF00FF, + /*Purple*/0xFF00FFFF, + /*Orange*/0xFF9900FF, + /*Cyan*/ 0x00CCFFFF} + + var ( lost*: bool playfield*: [FieldWidth][FieldHeight]int diff --git a/demos/tetris/fx.um b/demos/tetris/fx.um index a8d87cc..a05c288 100644 --- a/demos/tetris/fx.um +++ b/demos/tetris/fx.um @@ -11,19 +11,12 @@ import ( "crazytext.um" ) -const ( - reference_frame = rect::Rect{ - 0, 0, - field::FieldWidth*16+6*16, - field::FieldHeight*16 } - - EffectClearRow = 0 -) +reference_frame := rect::Rect{ 0, 0, field::FieldWidth*16+6*16, field::FieldHeight*16 } +const EffectClearRow = 0 type Effect = struct { kind: int life: real - int_data: int } @@ -95,14 +88,14 @@ fn drawCell(c: uint32, r: rect::Rect) { } fn cellRec(x, y: int) { - drawCell(field::Colors[field::playfield[x][y]], rect::Rect { offset_x + x * 16, offset_y + y * 16, 15, 15 }) + drawCell(field::colors[field::playfield[x][y]], rect::Rect { offset_x + x * 16, offset_y + y * 16, 15, 15 }) } fn drawPiece(it: piece::Piece, x, y: int, mask: int) { x_origin := x for _, chr in it.data { if chr == '#' { - drawCell(field::Colors[it.color] & mask, rect::Rect { x, y, 15, 15 }) + drawCell(field::colors[it.color] & mask, rect::Rect { x, y, 15, 15 }) } x += 16 if chr == '\n' { @@ -116,7 +109,7 @@ fn drawStash() { canvas::drawRect(0xFFFFFF11, rect::Rect {16*11-1+offset_x, 1*16-1+offset_y, 16*4+1, 16*4+1}) for i := 0; i < 4; i += 1 { for j := 0; j < 4; j += 1 { - drawCell(field::Colors[field::None], rect::Rect{ (11+i)*16+offset_x, (1+j)*16+offset_y, 15, 15 }) + drawCell(field::colors[field::None], rect::Rect{ (11+i)*16+offset_x, (1+j)*16+offset_y, 15, 15 }) } } if gameplay::stash < 0 { diff --git a/demos/tetris/presets.um b/demos/tetris/presets.um index 624396a..c4d217b 100644 --- a/demos/tetris/presets.um +++ b/demos/tetris/presets.um @@ -11,203 +11,203 @@ type Kick* = struct { const ( pieceTypeT* = 5 +) - // I will not implement matrix rotation stuff - I* = [4]piece::Piece{ - piece::Piece { - "....\n"+ - "....\n"+ - "####\n"+ - "....\n", - field::Cyan}, - piece::Piece { - ".#..\n"+ - ".#..\n"+ - ".#..\n"+ - ".#..\n", - field::Cyan}, - piece::Piece { - "....\n"+ - "####\n"+ - "....\n"+ - "....\n", - field::Cyan}, - piece::Piece { - "..#.\n"+ - "..#.\n"+ - "..#.\n"+ - "..#.\n", - field::Cyan}} - J* = [4]piece::Piece{ - piece::Piece { - "#..\n"+ - "###\n"+ - "...\n", - field::Blue}, - piece::Piece { - ".##\n"+ - ".#.\n"+ - ".#.\n", - field::Blue}, - piece::Piece { - "...\n"+ - "###\n"+ - "..#\n", - field::Blue}, - piece::Piece { - ".#.\n"+ - ".#.\n"+ - "##.\n", - field::Blue}} - L* = [4]piece::Piece{ - piece::Piece { - "..#\n"+ - "###\n"+ - "...\n", - field::Orange}, - piece::Piece { - ".#.\n"+ - ".#.\n"+ - ".##\n", - field::Orange}, - piece::Piece { - "...\n"+ - "###\n"+ - "#..\n", - field::Orange}, - piece::Piece { - "##.\n"+ - ".#.\n"+ - ".#.\n", - field::Orange}} - O* = [4]piece::Piece{ - piece::Piece { - "...\n"+ - ".##\n"+ - ".##\n", - field::Yellow}, - piece::Piece { - "...\n"+ - ".##\n"+ - ".##\n", - field::Yellow}, - piece::Piece { - "...\n"+ - ".##\n"+ - ".##\n", - field::Yellow}, - piece::Piece { - "...\n"+ - ".##\n"+ - ".##\n", - field::Yellow}} - S* = [4]piece::Piece{ - piece::Piece { - ".##\n"+ - "##.\n"+ - "...\n", - field::Green}, - piece::Piece { - ".#.\n"+ - ".##\n"+ - "..#\n", - field::Green}, - piece::Piece { - "...\n"+ - ".##\n"+ - "##.\n", - field::Green}, - piece::Piece { - "#..\n"+ - "##.\n"+ - ".#.\n", - field::Green}} - T* = [4]piece::Piece{ - piece::Piece { - ".#.\n"+ - "###\n"+ - "...\n", - field::Purple}, - piece::Piece { - ".#.\n"+ - ".##\n"+ - ".#.\n", - field::Purple}, - piece::Piece { - "...\n"+ - "###\n"+ - ".#.\n", - field::Purple}, - piece::Piece { - ".#.\n"+ - "##.\n"+ - ".#.\n", - field::Purple}} - Z* = [4]piece::Piece{ - piece::Piece { - "...\n"+ - "##.\n"+ - ".##\n", - field::Red}, - piece::Piece { - ".#.\n"+ - "##.\n"+ - "#..\n", - field::Red}, - piece::Piece { - "##.\n"+ - ".##\n"+ - "...\n", - field::Red}, - piece::Piece { - "..#\n"+ - ".##\n"+ - ".#.\n", - field::Red}} +// I will not implement matrix rotation stuff +I* := [4]piece::Piece{ + piece::Piece { + "....\n"+ + "....\n"+ + "####\n"+ + "....\n", + field::Cyan}, + piece::Piece { + ".#..\n"+ + ".#..\n"+ + ".#..\n"+ + ".#..\n", + field::Cyan}, + piece::Piece { + "....\n"+ + "####\n"+ + "....\n"+ + "....\n", + field::Cyan}, + piece::Piece { + "..#.\n"+ + "..#.\n"+ + "..#.\n"+ + "..#.\n", + field::Cyan}} +J* := [4]piece::Piece{ + piece::Piece { + "#..\n"+ + "###\n"+ + "...\n", + field::Blue}, + piece::Piece { + ".##\n"+ + ".#.\n"+ + ".#.\n", + field::Blue}, + piece::Piece { + "...\n"+ + "###\n"+ + "..#\n", + field::Blue}, + piece::Piece { + ".#.\n"+ + ".#.\n"+ + "##.\n", + field::Blue}} +L* := [4]piece::Piece{ + piece::Piece { + "..#\n"+ + "###\n"+ + "...\n", + field::Orange}, + piece::Piece { + ".#.\n"+ + ".#.\n"+ + ".##\n", + field::Orange}, + piece::Piece { + "...\n"+ + "###\n"+ + "#..\n", + field::Orange}, + piece::Piece { + "##.\n"+ + ".#.\n"+ + ".#.\n", + field::Orange}} +O* := [4]piece::Piece{ + piece::Piece { + "...\n"+ + ".##\n"+ + ".##\n", + field::Yellow}, + piece::Piece { + "...\n"+ + ".##\n"+ + ".##\n", + field::Yellow}, + piece::Piece { + "...\n"+ + ".##\n"+ + ".##\n", + field::Yellow}, + piece::Piece { + "...\n"+ + ".##\n"+ + ".##\n", + field::Yellow}} +S* := [4]piece::Piece{ + piece::Piece { + ".##\n"+ + "##.\n"+ + "...\n", + field::Green}, + piece::Piece { + ".#.\n"+ + ".##\n"+ + "..#\n", + field::Green}, + piece::Piece { + "...\n"+ + ".##\n"+ + "##.\n", + field::Green}, + piece::Piece { + "#..\n"+ + "##.\n"+ + ".#.\n", + field::Green}} +T* := [4]piece::Piece{ + piece::Piece { + ".#.\n"+ + "###\n"+ + "...\n", + field::Purple}, + piece::Piece { + ".#.\n"+ + ".##\n"+ + ".#.\n", + field::Purple}, + piece::Piece { + "...\n"+ + "###\n"+ + ".#.\n", + field::Purple}, + piece::Piece { + ".#.\n"+ + "##.\n"+ + ".#.\n", + field::Purple}} +Z* := [4]piece::Piece{ + piece::Piece { + "...\n"+ + "##.\n"+ + ".##\n", + field::Red}, + piece::Piece { + ".#.\n"+ + "##.\n"+ + "#..\n", + field::Red}, + piece::Piece { + "##.\n"+ + ".##\n"+ + "...\n", + field::Red}, + piece::Piece { + "..#\n"+ + ".##\n"+ + ".#.\n", + field::Red}} - // SRS kick tables - ClockwiseNI* = [4][4]Kick{ - // 0>>1 - [4]Kick {Kick {-1, 0},Kick{-1,1},Kick{0,-2},Kick{-1,-2}}, - // 1>>2 - [4]Kick {Kick { 1, 0},Kick{1,-1},Kick{0, 2},Kick{ 1, 2}}, - // 2>>3 - [4]Kick {Kick { 1, 0},Kick{ 1, 1},Kick{0,-2},Kick{ 1,-2}}, - // 3>>0 - [4]Kick {Kick {-1, 0},Kick{-1,-1},Kick{0, 2},Kick{0,-2}}} +// SRS kick tables +ClockwiseNI* := [4][4]Kick{ + // 0>>1 + [4]Kick {Kick {-1, 0},Kick{-1,1},Kick{0,-2},Kick{-1,-2}}, + // 1>>2 + [4]Kick {Kick { 1, 0},Kick{1,-1},Kick{0, 2},Kick{ 1, 2}}, + // 2>>3 + [4]Kick {Kick { 1, 0},Kick{ 1, 1},Kick{0,-2},Kick{ 1,-2}}, + // 3>>0 + [4]Kick {Kick {-1, 0},Kick{-1,-1},Kick{0, 2},Kick{0,-2}}} - CounterclockwiseNI* = [4][4]Kick{ - // 0>>3 - [4]Kick {Kick { 1, 0},Kick{ 1,1},Kick{0,-2},Kick{ 1,-2}}, - // 1>>0 - [4]Kick {Kick { 1, 0},Kick{1,-1},Kick{0, 2},Kick{ 1, 2}}, - // 2>>1 - [4]Kick {Kick {-1, 0},Kick{-1, 1},Kick{0,-2},Kick{-1,-2}}, - // 3>>2 - [4]Kick {Kick {-1, 0},Kick{-1,-1},Kick{0, 2},Kick{-1, 2}}} +CounterclockwiseNI* := [4][4]Kick{ + // 0>>3 + [4]Kick {Kick { 1, 0},Kick{ 1,1},Kick{0,-2},Kick{ 1,-2}}, + // 1>>0 + [4]Kick {Kick { 1, 0},Kick{1,-1},Kick{0, 2},Kick{ 1, 2}}, + // 2>>1 + [4]Kick {Kick {-1, 0},Kick{-1, 1},Kick{0,-2},Kick{-1,-2}}, + // 3>>2 + [4]Kick {Kick {-1, 0},Kick{-1,-1},Kick{0, 2},Kick{-1, 2}}} - ClockwiseI* = [4][4]Kick{ - // 0>>1 - [4]Kick {Kick {-2, 0},Kick{ 1,0},Kick{-2,-1},Kick{ 1,2}}, - // 1>>2 - [4]Kick {Kick {-1, 0},Kick{2, 0},Kick{-1, 2},Kick{ 2,-1}}, - // 2>>3 - [4]Kick {Kick {2, 0},Kick{-1, 0},Kick{2,1},Kick{-1,-2}}, - // 3>>0 - [4]Kick {Kick {1, 0},Kick{-2,0},Kick{1, -2},Kick{-2, 1}}} +ClockwiseI* := [4][4]Kick{ + // 0>>1 + [4]Kick {Kick {-2, 0},Kick{ 1,0},Kick{-2,-1},Kick{ 1,2}}, + // 1>>2 + [4]Kick {Kick {-1, 0},Kick{2, 0},Kick{-1, 2},Kick{ 2,-1}}, + // 2>>3 + [4]Kick {Kick {2, 0},Kick{-1, 0},Kick{2,1},Kick{-1,-2}}, + // 3>>0 + [4]Kick {Kick {1, 0},Kick{-2,0},Kick{1, -2},Kick{-2, 1}}} - CounterclockwiseI* = [4][4]Kick{ - // 0>>3 - [4]Kick {Kick {-1, 0},Kick{ 2,0},Kick{-1,2},Kick{ 2,-1}}, - // 1>>0 - [4]Kick {Kick {2, 0},Kick{-1, 0},Kick{2, 1},Kick{-1,-2}}, - // 2>>1 - [4]Kick {Kick {1, 0},Kick{-2, 0},Kick{1,-2},Kick{-2,1}}, - // 3>>2 - [4]Kick {Kick {-2, 0},Kick{1,0},Kick{-2, -1},Kick{1, 2}}} -) +CounterclockwiseI* := [4][4]Kick{ + // 0>>3 + [4]Kick {Kick {-1, 0},Kick{2, 0},Kick{-1,2},Kick{ 2,-1}}, + // 1>>0 + [4]Kick {Kick {2, 0},Kick{-1, 0},Kick{2, 1},Kick{-1,-2}}, + // 2>>1 + [4]Kick {Kick {1, 0},Kick{-2, 0},Kick{1,-2},Kick{-2,1}}, + // 3>>2 + [4]Kick {Kick {-2, 0},Kick{1,0},Kick{-2, -1},Kick{1, 2}}} fn pieceValue*(kind, rotation: int): piece::Piece { rotation %= 4 @@ -254,4 +254,4 @@ fn getScore*(streak: int, tSpin: bool): int { } return score -} \ No newline at end of file +} diff --git a/etc/shell.html b/etc/shell.html index 5960d19..0e0c54b 100644 --- a/etc/shell.html +++ b/etc/shell.html @@ -31,6 +31,7 @@ var statusElement = document.getElementById('status'); var progressElement = document.getElementById('progress'); var spinnerElement = document.getElementById('spinner'); + var canvas = document.getElementById('canvas'); var Module = { postRun: [], @@ -59,14 +60,33 @@ } }; window.addEventListener("resize", (e) => { - var canvas = document.getElementById('canvas') window.focus(); canvas.focus(); canvas.width = window.innerWidth; canvas.height = window.innerHeight; }) + window.addEventListener("mousedown", (e) => { + e.preventDefault() + window.focus(); + canvas.focus(); + }) + canvas.addEventListener("wheel", (e) => { + e.preventDefault(); + }) + canvas.addEventListener("mousewheel", (e) => { + e.preventDefault(); + }) + window.addEventListener("mouseup", (e) => { + e.preventDefault() + window.focus(); + canvas.focus(); + }) + window.addEventListener("scroll", (e) => { + e.preventDefault() + window.focus(); + canvas.focus(); + }) window.addEventListener("click", (e) => { - var canvas = document.getElementById('canvas') window.focus(); canvas.focus(); }) diff --git a/lib/sokol b/lib/sokol index a693ad0..3c9719d 160000 --- a/lib/sokol +++ b/lib/sokol @@ -1 +1 @@ -Subproject commit a693ad02c8629254e0ebfb75b1ed3a4acbda6777 +Subproject commit 3c9719dfe3bd4f4cf7faeaf6947ddbcd9eb6f5ff diff --git a/lib/umka b/lib/umka index 34e70df..ebe1093 160000 --- a/lib/umka +++ b/lib/umka @@ -1 +1 @@ -Subproject commit 34e70df085b7dec3d483493d12804f7362c70ec5 +Subproject commit ebe1093bf452aa6165e479634fea192bb577a05f diff --git a/src/bindings.c b/src/bindings.c index 4c7a6b1..7e8dcd0 100644 --- a/src/bindings.c +++ b/src/bindings.c @@ -208,7 +208,9 @@ umth_tilemap_draw(UmkaStackSlot *p, UmkaStackSlot *r) { th_tmap *t = umkaGetParam(p, 0)->ptrVal; th_transform tr = *(th_transform *)umkaGetParam(p, 1); - th_tmap_draw(t, tr); + uint32_t tint = umkaGetParam(p, 2)->uintVal; + + th_tmap_draw(t, tr, tint); } // checks, if tilemap collides with entity. diff --git a/src/main.c b/src/main.c index 9ba2b25..9a5d9c4 100644 --- a/src/main.c +++ b/src/main.c @@ -193,8 +193,13 @@ th_deinit() } } - if (umkaAlive(thg->umka)) - umkaCall(thg->umka, &thg->umka_destroy); + if (umkaAlive(thg->umka)) { + int code = umkaCall(thg->umka, &thg->umka_destroy); + if (!umkaAlive(thg->umka) || code != 0) { + th_print_umka_error_and_quit(code); + } + } + if (umkaAlive(thg->umka)) umkaRun(thg->umka); @@ -217,8 +222,12 @@ int run_playground(const char *src) { if (thg->umka) { - if (umkaAlive(thg->umka)) - umkaCall(thg->umka, &thg->umka_destroy); + if (umkaAlive(thg->umka)) { + int code = umkaCall(thg->umka, &thg->umka_destroy); + if (!umkaAlive(thg->umka) || code != 0) { + th_print_umka_error_and_quit(code); + } + } if (umkaAlive(thg->umka)) umkaRun(thg->umka); umkaFree(thg->umka); diff --git a/src/misc.c b/src/misc.c index 4ccef87..eac6de0 100644 --- a/src/misc.c +++ b/src/misc.c @@ -1,9 +1,10 @@ +#include "tophat.h" #include #include #include #include -#include "tophat.h" +#define MSG_LEN 1024 extern th_global *thg; @@ -164,3 +165,38 @@ th_regularize_path(const char *path, const char *cur_folder, char *regularized_p th_error("Path too long: %s%s", cur_folder, path); exit(-1); } + +void +th_print_umka_error_and_quit(int code) +{ + UmkaError *error = umkaGetError(thg->umka); + + if (error->code != 0 && error->msg[0]) { + th_error("%s (%d): %s\n", error->fileName, error->line, error->msg); + + fprintf(stderr, "\tStack trace:\n"); + + for (int depth = 0; depth < 10; depth++) { + char fnName[MSG_LEN + 1]; + char file[MSG_LEN + 1]; + int line, offset; + + if (!umkaGetCallStack( + thg->umka, depth, MSG_LEN + 1, &offset, file, fnName, &line)) { + fprintf(stderr, "\t\t...\n"); + break; + } +#ifndef _WIN32 + fprintf(stderr, "\033[34m"); +#endif + fprintf(stderr, "\t\t%s:%06d: ", file, line); +#ifndef _WIN32 + fprintf(stderr, "\033[0m"); +#endif + fprintf(stderr, "%s\n", fnName); + } + } + + th_deinit(); + exit(code); +} diff --git a/src/staembed.c b/src/staembed.c index e4c4115..bb46422 100644 --- a/src/staembed.c +++ b/src/staembed.c @@ -1,4 +1,4 @@ -#include "tophat.h" +#include "tophat.h" const char *th_em_modulesrc[] = { "\n" "import (\n" @@ -490,6 +490,14 @@ const char *th_em_modulesrc[] = { "\t\"th.um\"\n" ")\n" "\n" +"//~~enum Filter\n" +"// Filtering mode for images, render targets, and fonts.\n" +"type Filter* = enum {\n" +"\tnearest = 0\n" +"\tlinear = 1\n" +"}\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" @@ -502,12 +510,12 @@ const char *th_em_modulesrc[] = { "type RenderTarget* = struct { _: ^struct{} }\n" "//~~\n" "\n" -"fn umth_image_create_render_target(ret: ^RenderTarget, width: int, height: int, filter: int): th::ErrCode\n" +"fn umth_image_create_render_target(ret: ^RenderTarget, width: int, height: int, filter: Filter): th::ErrCode\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, std::Err) {\n" +"fn createRenderTarget*(size: th::Vf2, filter: Filter): (RenderTarget, std::Err) {\n" "//~~\n" "\trt := RenderTarget{}\n" "\tec := umth_image_create_render_target(&rt, trunc(size.x), trunc(size.y), filter)\n" @@ -735,14 +743,14 @@ const char *th_em_modulesrc[] = { "\treturn img, th::__errFromCode(ec)\n" "}\n" "\n" -"fn umth_image_set_filter(data: Image, filter: int): th::ErrCode\n" +"fn umth_image_set_filter(data: Image, filter: Filter): th::ErrCode\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): std::Err {\n" +"fn (i: ^Image) setfilter*(filter: Filter): std::Err {\n" "//~~\n" "\tif !i.validate() {\n" "\t\tth::__error(\"image is invalid\")\n" @@ -1482,10 +1490,10 @@ const char *th_em_modulesrc[] = { "\n" "//~~Direction constants used for autotile\n" "const (\n" -"\ttop* = 1\n" +"\ttop* = 1\n" "\tright* = 2\n" -"\tbot* = 4\n" -"\tleft* = 8\n" +"\tbot* = 4\n" +"\tleft* = 8\n" ")\n" "//~~\n" "\n" @@ -1559,14 +1567,14 @@ const char *th_em_modulesrc[] = { "}\n" "\n" "\n" -"fn umth_tilemap_draw(ct: ^Tilemap, tr: th::Transform)\n" +"fn umth_tilemap_draw(ct: ^Tilemap, tr: th::Transform, tint: uint32)\n" "//~~fn Tilemap.draw\n" "// Draws the tilemap.\n" -"fn (t: ^Tilemap) draw*(tr: th::Transform) {\n" +"fn (t: ^Tilemap) draw*(tr: th::Transform, tint: uint32 = 0xFFFFFFFF) {\n" "//~~\n" "\tif len(t.cells) == 0 { return }\n" "\n" -"\tumth_tilemap_draw(t, tr)\n" +"\tumth_tilemap_draw(t, tr, tint)\n" "}\n" "\n" "fn umth_tilemap_getcoll(pos: ^th::Vf2, vert: ^th::Vf2, t: ^Tilemap, e: ^ent::Ent): bool\n" @@ -2079,19 +2087,13 @@ const char *th_em_modulesrc[] = { "import (\n" "\t\"th.um\"\n" "\t\"std.um\"\n" +"\t\"image.um\"\n" ")\n" "\n" -"//~~Filtering constants\n" -"type Filter* = enum {\n" -"\tnearest = 0\n" -"\tlinear = 1\n" -"}\n" -"//~~\n" -"\n" "// TODO: should this be exported and documented?\n" "type TrueType* = struct { _: ^struct{} }\n" "\n" -"fn umth_ttf_font_load(f: ^TrueType, path: str, size: th::fu, filter: Filter): th::ErrCode\n" +"fn umth_ttf_font_load(f: ^TrueType, path: str, size: th::fu, filter: image::Filter): th::ErrCode\n" "fn umth_ttf_font_draw(font: TrueType, s: str, x: th::fu, y: th::fu, color: uint32, scale: th::fu)\n" "fn umth_ttf_font_measure(font: TrueType, s: str): th::Vf2\n" "\n" @@ -2130,7 +2132,7 @@ const char *th_em_modulesrc[] = { "\n" "//~~fn load\n" "// Loads a font from a path and returns it.\n" -"fn load*(path: str, size: th::fu, filter: Filter = Filter.linear): (Font, std::Err) {\n" +"fn load*(path: str, size: th::fu, filter: image::Filter = .linear): (Font, std::Err) {\n" "//~~\n" "\tvar f: TrueType\n" "\tec := umth_ttf_font_load(&f, path, size, filter)\n" @@ -2497,14 +2499,14 @@ const char *th_em_modulesrc[] = { "\n" "//~~Color constants\n" "const (\n" -"\tblack* = 0xff\n" -"\twhite* = 0xffffffff\n" -"\tred* = 0xff0000ff\n" -"\tgreen* = 0x00ff00ff\n" -"\tblue* = 0x0000ffff\n" -"\tyellow* = 0xffff00ff\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" +"\tcyan* = 0x00ffffff\n" ")\n" "//~~\n" "\n" @@ -2773,10 +2775,10 @@ const char *th_em_modulesrc[] = { "\n" "//~~fn Atlas.draw\n" "// Draws the tile at `at`\n" -"fn (a: ^Atlas) draw*(at: th::Vf2, t: th::Transform) {\n" +"fn (a: ^Atlas) draw*(at: th::Vf2, t: th::Transform, tint: uint32 = 0xFFFFFFFF) {\n" "//~~\n" "\ta.cropSource(at)\n" -"\ta.i.draw(t, th::white)\n" +"\ta.i.draw(t, tint)\n" "\ta.i.crop({}, {1, 1})\n" "}\n" "", @@ -2825,10 +2827,8 @@ const char *th_em_modulesrc[] = { "\n" "\n" "//~~Default shader constants\n" -"const (\n" -"\tdefaultImageShader* = Shader{1}\n" -"\tdefaultCanvasShader* = Shader{2}\n" -")\n" +"defaultImageShader* := Shader{1}\n" +"defaultCanvasShader* := Shader{2}\n" "//~~\n" "\n" "//~~struct Uniform\n" @@ -4389,6 +4389,238 @@ const char *th_em_moduledocs[] = { "---------\n" "\n" "", +"enum Filter\n" +"\n" +"type Filter* = enum {\n" +"\tnearest = 0\n" +"\tlinear = 1\n" +"}\n" +"\n" +"Filtering mode for images, render targets, and fonts.\n" +"\n" +"---------\n" +"\n" +"opaque Image\n" +"\n" +"type Image* = struct{ _: ^struct{} }\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" +"\n" +"opaque RenderTarget\n" +"\n" +"type RenderTarget* = struct { _: ^struct{} }\n" +"\n" +"An image you can render to.\n" +"\n" +"---------\n" +"\n" +"fn createRenderTarget\n" +"\n" +"fn createRenderTarget*(size: th::Vf2, filter: Filter): (RenderTarget, std::Err) {\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" +"\n" +"fn RenderTarget.begin\n" +"\n" +"fn (rt: ^RenderTarget) begin*(): std::Err {\n" +"\n" +"Begins the render target rendering pass.\n" +"\n" +"---------\n" +"\n" +"fn RenderTarget.end\n" +"\n" +"fn (rt: ^RenderTarget) end*(wp: th::Vf2): std::Err {\n" +"\n" +"Ends the render target rendering pass.\n" +"\n" +"---------\n" +"\n" +"fn RenderTarget.toImage\n" +"\n" +"fn (rt: ^RenderTarget) toImage*(): Image {\n" +"\n" +"Returns the image of the render target. The resulting image has the same\n" +"lifetime as the base RenderTarget. If you need to use it past the lifetime\n" +"of the RenderTarget, use the copy method.\n" +"Do not call `setfilter` on the resulting image.\n" +"\n" +"---------\n" +"\n" +"fn load\n" +"\n" +"fn load*(path: str): (Image, std::Err) {\n" +"\n" +"Loads an image at path.\n" +"\n" +"---------\n" +"\n" +"fn Image.validate\n" +"\n" +"fn (i: ^Image) validate*(): bool {\n" +"\n" +"Returns true, if i\'s handle points to an image.\n" +"\n" +"---------\n" +"\n" +"fn Image.flipv\n" +"\n" +"fn (i: ^Image) flipv*(flip: bool) {\n" +"\n" +"Flips image on it\'s vertical axis.\n" +"\n" +"---------\n" +"\n" +"fn Image.fliph\n" +"\n" +"fn (i: ^Image) fliph*(flip: bool) {\n" +"\n" +"Flips image on it\'s horizontal axis.\n" +"\n" +"---------\n" +"\n" +"fn Image.draw\n" +"\n" +"fn (i: ^Image) draw*(t: th::Transform, color: uint32 = th::white) {\n" +"\n" +"Draws the image in screen coordinates. It transforms it with t and\n" +"applies color as a color filter.\n" +"\n" +"---------\n" +"\n" +"fn Image.blit\n" +"\n" +"fn (i: ^Image) blit*(src, dest: rect::Rect, color: uint32 = 0xFFFFFFFF, rot: th::fu = 0, origin: th::Vf2 = {0, 0}) {\n" +"\n" +"Copies source rectangle (texture coordinates) to destination rectangle (screen coordinates).\n" +"\n" +"---------\n" +"\n" +"fn Image.drawNinepatch\n" +"\n" +"fn (i: ^Image) drawNinepatch*(outer, inner, dest: rect::Rect, color: uint32 = th::white, scale: real = 1.0) {\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" +"\n" +"![](img/ninepatch.png)\n" +"\n" +"---------\n" +"\n" +"fn Image.drawOnQuad\n" +"\n" +"fn (i: ^Image) drawOnQuad*(q: th::Quad, color: uint32 = th::white) {\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" +"\n" +"fn Image.getDims\n" +"\n" +"fn (i: ^Image) getDims*(): th::Vf2 {\n" +"\n" +"Returns width and heigth.\n" +"\n" +"---------\n" +"\n" +"fn Image.crop\n" +"\n" +"fn (i: ^Image) crop*(tl, br: th::Vf2) {\n" +"\n" +"Crops an image. Coordinates are between 0, 0 (top left) and\n" +"1, 1 (bottom right)\n" +"\n" +"---------\n" +"\n" +"fn Image.cropPx\n" +"\n" +"fn (i: ^Image) cropPx*(tr, br: th::Vf2) {\n" +"\n" +"Same as `Image.crop`, but the positions are in pixels.\n" +"\n" +"---------\n" +"\n" +"fn Image.cropRect\n" +"\n" +"fn (i: ^Image) cropRect*(r: rect::Rect) {\n" +"\n" +"Same as `Image.crop`, but uses a rect instead of two positions.\n" +"\n" +"---------\n" +"\n" +"fn Image.cropQuad\n" +"\n" +"fn (i: ^Image) cropQuad*(q: th::Quad) {\n" +"\n" +"Crop an image using a quad.\n" +"\n" +"---------\n" +"\n" +"fn Image.getCropQuad\n" +"\n" +"fn (i: ^Image) getCropQuad*(): th::Quad {\n" +"\n" +"Crop an image using a quad.\n" +"\n" +"---------\n" +"\n" +"fn mk\n" +"\n" +"fn mk*(data: []uint32, dm: th::Vf2): (Image, std::Err) {\n" +"\n" +"Creates an image from raw data.\n" +"\n" +"---------\n" +"\n" +"fn Image.copy\n" +"\n" +"fn (i: ^Image) copy*(): (Image, std::Err) {\n" +"\n" +"Copies image into a new one.\n" +"\n" +"---------\n" +"\n" +"fn Image.setfilter\n" +"\n" +"fn (i: ^Image) setfilter*(filter: Filter): std::Err {\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" +"\n" +"fn Image.setData\n" +"\n" +"fn (i: ^Image) setData*(data: []uint32, dm: th::Vf2): std::Err {\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" +"\n" +"fn Image.getData\n" +"\n" +"fn (i: ^Image) getData*(): []uint32 {\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" @@ -4796,6 +5028,94 @@ const char *th_em_moduledocs[] = { "---------\n" "\n" "", +"\n" +"\n" +"\n" +"Canvas library allowing for drawing basic shapes. Coordinates are based on\n" +"the screen.\n" +"\n" +"---------\n" +"\n" +"fn drawText\n" +"\n" +"fn drawText*(text: str, pos: th::Vf2, color: uint32, size: th::fu) {\n" +"\n" +"Draws a basic pixel text. Only ascii is supported.\n" +"\n" +"---------\n" +"\n" +"fn textSize\n" +"\n" +"fn textSize*(text: str, scale: th::fu): th::Vf2 {\n" +"\n" +"Returns the size of text taken by an equivalent drawText call.\n" +"\n" +"---------\n" +"\n" +"Pixel Font\n" +"\n" +"var pixelFont*: PixelFont\n" +"\n" +"The `pixelFont` variable exposes the canvas pixel font as a generic font.\n" +"\n" +"---------\n" +"\n" +"fn drawRect\n" +"\n" +"fn drawRect*(color: uint32, r: rect::Rect) {\n" +"\n" +"Draws a Rectangle.\n" +"\n" +"---------\n" +"\n" +"fn drawLine\n" +"\n" +"fn drawLine*(color: uint32, b, e: th::Vf2, thickness: th::fu) {\n" +"\n" +"Draws a line.\n" +"\n" +"---------\n" +"\n" +"fn drawRectLines\n" +"\n" +"fn drawRectLines*(color: uint32, r: rect::Rect, thickness: real32 = 1.0) {\n" +"\n" +"Draws rect border.\n" +"\n" +"---------\n" +"\n" +"fn drawQuad\n" +"\n" +"fn drawQuad*(color: uint32, q: th::Quad) {\n" +"\n" +"Draws a convex quad.\n" +"\n" +"---------\n" +"\n" +"fn drawTrig\n" +"\n" +"fn drawTrig*(color: uint32, a, b, c: th::Vf2) {\n" +"\n" +"Draws a triangle.\n" +"\n" +"---------\n" +"\n" +"fn beginScissorRect\n" +"\n" +"fn beginScissorRect*(r: rect::Rect, debug: bool = false) {\n" +"\n" +"Disable rendering outside of rect `r`\n" +"\n" +"---------\n" +"\n" +"fn endScissor\n" +"\n" +"fn endScissor*() {\n" +"\n" +"Stops cropping\n" +"\n" +"---------\n" +"\n" "", "struct Rect\n" "\n" @@ -4908,10 +5228,10 @@ const char *th_em_moduledocs[] = { "Direction constants used for autotile\n" "\n" "const (\n" -"\ttop* = 1\n" +"\ttop* = 1\n" "\tright* = 2\n" -"\tbot* = 4\n" -"\tleft* = 8\n" +"\tbot* = 4\n" +"\tleft* = 8\n" ")\n" "\n" "\n" @@ -4974,7 +5294,7 @@ const char *th_em_moduledocs[] = { "\n" "fn Tilemap.draw\n" "\n" -"fn (t: ^Tilemap) draw*(tr: th::Transform) {\n" +"fn (t: ^Tilemap) draw*(tr: th::Transform, tint: uint32 = 0xFFFFFFFF) {\n" "\n" "Draws the tilemap.\n" "\n" @@ -5320,16 +5640,6 @@ const char *th_em_moduledocs[] = { "\n" "---------\n" "\n" -"Filtering constants\n" -"\n" -"type Filter* = enum {\n" -"\tnearest = 0\n" -"\tlinear = 1\n" -"}\n" -"\n" -"\n" -"---------\n" -"\n" "interface Font\n" "\n" "type Font* = interface {\n" @@ -5348,7 +5658,7 @@ const char *th_em_moduledocs[] = { "\n" "fn load\n" "\n" -"fn load*(path: str, size: th::fu, filter: Filter = Filter.linear): (Font, std::Err) {\n" +"fn load*(path: str, size: th::fu, filter: image::Filter = .linear): (Font, std::Err) {\n" "\n" "Loads a font from a path and returns it.\n" "\n" @@ -5682,14 +5992,14 @@ const char *th_em_moduledocs[] = { "Color constants\n" "\n" "const (\n" -"\tblack* = 0xff\n" -"\twhite* = 0xffffffff\n" -"\tred* = 0xff0000ff\n" -"\tgreen* = 0x00ff00ff\n" -"\tblue* = 0x0000ffff\n" -"\tyellow* = 0xffff00ff\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" +"\tcyan* = 0x00ffffff\n" ")\n" "\n" "\n" @@ -5936,7 +6246,7 @@ const char *th_em_moduledocs[] = { "\n" "fn Atlas.draw\n" "\n" -"fn (a: ^Atlas) draw*(at: th::Vf2, t: th::Transform) {\n" +"fn (a: ^Atlas) draw*(at: th::Vf2, t: th::Transform, tint: uint32 = 0xFFFFFFFF) {\n" "\n" "Draws the tile at `at`\n" "\n" @@ -5984,10 +6294,8 @@ const char *th_em_moduledocs[] = { "\n" "Default shader constants\n" "\n" -"const (\n" -"\tdefaultImageShader* = Shader{1}\n" -"\tdefaultCanvasShader* = Shader{2}\n" -")\n" +"defaultImageShader* := Shader{1}\n" +"defaultCanvasShader* := Shader{2}\n" "\n" "\n" "---------\n" diff --git a/src/thextdata.h b/src/thextdata.h index 75e8eb9..6504215 100644 --- a/src/thextdata.h +++ b/src/thextdata.h @@ -88,7 +88,7 @@ THEXT(void, th_transform_transform, th_transform *o, th_transform t); THEXT(void, th_rotate_point, th_vf2 *p, th_vf2 o, fu rot); THEXT(void, th_vector_normalize, float *x, float *y); THEXT(uint32_t, th_sg_get_gl_image, sg_image img); -THEXT(void, th_tmap_draw, th_tmap *t, th_transform tr); +THEXT(void, th_tmap_draw, th_tmap *t, th_transform tr, uint32_t tint); THEXT(void, th_tmap_autotile, uu *tgt, uu *src, uu w, uu h, uu *tiles, uu limiter); THEXT(th_shader *, th_get_shader, uu index); THEXT(th_shader *, th_get_shader_err, uu index); diff --git a/src/tilemap.c b/src/tilemap.c index e2481f5..71bb643 100644 --- a/src/tilemap.c +++ b/src/tilemap.c @@ -8,7 +8,7 @@ extern th_global *thg; void -th_tmap_draw(th_tmap *t, th_transform tr) +th_tmap_draw(th_tmap *t, th_transform tr, uint32_t tint) { th_image *a = t->a.i; if (!a) @@ -36,7 +36,7 @@ th_tmap_draw(th_tmap *t, th_transform tr) th_quad q = {0}; th_transform_rect(&q, tt, (th_rect){.w = t->a.cs.x, .h = t->a.cs.y}); th_transform_quad(&q, tr); - th_image_draw_quad(a, q, 0xffffffff); + th_image_draw_quad(a, q, tint); } } diff --git a/src/tophat.h b/src/tophat.h index d823e13..93fdfdb 100644 --- a/src/tophat.h +++ b/src/tophat.h @@ -593,7 +593,7 @@ th_sg_get_gl_image(sg_image img); // tilemap void -th_tmap_draw(th_tmap *t, th_transform tr); +th_tmap_draw(th_tmap *t, th_transform tr, uint32_t tint); void th_tmap_autotile(uu *tgt, uu *src, uu w, uu h, uu *tiles, uu limiter); diff --git a/src/window.c b/src/window.c index e7da1f4..9e8886e 100644 --- a/src/window.c +++ b/src/window.c @@ -10,45 +10,9 @@ #include #include -#define MSG_LEN 1024 extern th_global *thg; -void -th_print_umka_error_and_quit(int code) -{ - UmkaError *error = umkaGetError(thg->umka); - - if (error->code != 0 && error->msg[0]) { - th_error("%s (%d): %s\n", error->fileName, error->line, error->msg); - - fprintf(stderr, "\tStack trace:\n"); - - for (int depth = 0; depth < 10; depth++) { - char fnName[MSG_LEN + 1]; - char file[MSG_LEN + 1]; - int line, offset; - - if (!umkaGetCallStack( - thg->umka, depth, MSG_LEN + 1, &offset, file, fnName, &line)) { - fprintf(stderr, "\t\t...\n"); - break; - } -#ifndef _WIN32 - fprintf(stderr, "\033[34m"); -#endif - fprintf(stderr, "\t\t%s:%06d: ", file, line); -#ifndef _WIN32 - fprintf(stderr, "\033[0m"); -#endif - fprintf(stderr, "%s\n", fnName); - } - } - - th_deinit(); - exit(code); -} - static void init(void) { @@ -174,6 +138,8 @@ th_window_sapp_desc() .icon.sokol_default = true, .logger.func = slog_func, .high_dpi = thg->dpi_aware, + .gl_major_version = 4, + .gl_minor_version = 1, #ifdef __EMSCRIPTEN__ .html5_bubble_mouse_events = true, .html5_bubble_touch_events = true, diff --git a/umka/atlas.um b/umka/atlas.um index f46b903..edea7b2 100644 --- a/umka/atlas.um +++ b/umka/atlas.um @@ -119,9 +119,9 @@ fn pack*(images: []image::Image, strategy: PackStrategy): (Atlas, std::Err) { //~~fn Atlas.draw // Draws the tile at `at` -fn (a: ^Atlas) draw*(at: th::Vf2, t: th::Transform) { +fn (a: ^Atlas) draw*(at: th::Vf2, t: th::Transform, tint: uint32 = 0xFFFFFFFF) { //~~ a.cropSource(at) - a.i.draw(t, th::white) + a.i.draw(t, tint) a.i.crop({}, {1, 1}) } diff --git a/umka/font.um b/umka/font.um index d6202e9..73eccb1 100644 --- a/umka/font.um +++ b/umka/font.um @@ -5,19 +5,13 @@ import ( "th.um" "std.um" + "image.um" ) -//~~Filtering constants -type Filter* = enum { - nearest = 0 - linear = 1 -} -//~~ - // TODO: should this be exported and documented? type TrueType* = struct { _: ^struct{} } -fn umth_ttf_font_load(f: ^TrueType, path: str, size: th::fu, filter: Filter): th::ErrCode +fn umth_ttf_font_load(f: ^TrueType, path: str, size: th::fu, filter: image::Filter): th::ErrCode fn umth_ttf_font_draw(font: TrueType, s: str, x: th::fu, y: th::fu, color: uint32, scale: th::fu) fn umth_ttf_font_measure(font: TrueType, s: str): th::Vf2 @@ -56,7 +50,7 @@ type Font* = interface { //~~fn load // Loads a font from a path and returns it. -fn load*(path: str, size: th::fu, filter: Filter = Filter.linear): (Font, std::Err) { +fn load*(path: str, size: th::fu, filter: image::Filter = .linear): (Font, std::Err) { //~~ var f: TrueType ec := umth_ttf_font_load(&f, path, size, filter) diff --git a/umka/image.um b/umka/image.um index a34a993..6c30aa7 100644 --- a/umka/image.um +++ b/umka/image.um @@ -4,6 +4,14 @@ import ( "th.um" ) +//~~enum Filter +// Filtering mode for images, render targets, and fonts. +type Filter* = enum { + nearest = 0 + linear = 1 +} +//~~ + //~~opaque Image // Represents a drawable image. It is an opaque structure. // Images support a color filter. It is applied by multiplying the color @@ -16,12 +24,12 @@ type Image* = struct{ _: ^struct{} } type RenderTarget* = struct { _: ^struct{} } //~~ -fn umth_image_create_render_target(ret: ^RenderTarget, width: int, height: int, filter: int): th::ErrCode +fn umth_image_create_render_target(ret: ^RenderTarget, width: int, height: int, filter: Filter): th::ErrCode //~~fn createRenderTarget // Creates a render target you can draw to, like to a window. // Filter specifies specfifies filtering for resulting image. // Image can be retrieved via `toImage`. -fn createRenderTarget*(size: th::Vf2, filter: int): (RenderTarget, std::Err) { +fn createRenderTarget*(size: th::Vf2, filter: Filter): (RenderTarget, std::Err) { //~~ rt := RenderTarget{} ec := umth_image_create_render_target(&rt, trunc(size.x), trunc(size.y), filter) @@ -249,14 +257,14 @@ fn (i: ^Image) copy*(): (Image, std::Err) { return img, th::__errFromCode(ec) } -fn umth_image_set_filter(data: Image, filter: int): th::ErrCode +fn umth_image_set_filter(data: Image, filter: Filter): th::ErrCode //~~fn Image.setfilter // Sets a mag/min filter. 0 is nearest, others are linear. // This function will regenerate the texture. This means it shouldn't be // used in a loop. // https://learnopengl.com/img/getting-started/texture_filtering.png // left is nearest, right is linear. -fn (i: ^Image) setfilter*(filter: int): std::Err { +fn (i: ^Image) setfilter*(filter: Filter): std::Err { //~~ if !i.validate() { th::__error("image is invalid") diff --git a/umka/shader.um b/umka/shader.um index b0648b4..4cc48d7 100644 --- a/umka/shader.um +++ b/umka/shader.um @@ -43,10 +43,8 @@ type Shader* = struct { //~~Default shader constants -const ( - defaultImageShader* = Shader{1} - defaultCanvasShader* = Shader{2} -) +defaultImageShader* := Shader{1} +defaultCanvasShader* := Shader{2} //~~ //~~struct Uniform diff --git a/umka/th.um b/umka/th.um index 6650ffd..48499ad 100644 --- a/umka/th.um +++ b/umka/th.um @@ -358,14 +358,14 @@ fn __error*(msg: str) { //~~Color constants const ( - black* = 0xff - white* = 0xffffffff - red* = 0xff0000ff - green* = 0x00ff00ff - blue* = 0x0000ffff - yellow* = 0xffff00ff + black* = 0xff + white* = 0xffffffff + red* = 0xff0000ff + green* = 0x00ff00ff + blue* = 0x0000ffff + yellow* = 0xffff00ff magenta* = 0xff00ffff - cyan* = 0x00ffffff + cyan* = 0x00ffffff ) //~~ diff --git a/umka/tilemap.um b/umka/tilemap.um index f23a395..6608baa 100644 --- a/umka/tilemap.um +++ b/umka/tilemap.um @@ -11,10 +11,10 @@ import ( //~~Direction constants used for autotile const ( - top* = 1 + top* = 1 right* = 2 - bot* = 4 - left* = 8 + bot* = 4 + left* = 8 ) //~~ @@ -88,14 +88,14 @@ fn (t: ^Tilemap) get*(x, y: int): int { } -fn umth_tilemap_draw(ct: ^Tilemap, tr: th::Transform) +fn umth_tilemap_draw(ct: ^Tilemap, tr: th::Transform, tint: uint32) //~~fn Tilemap.draw // Draws the tilemap. -fn (t: ^Tilemap) draw*(tr: th::Transform) { +fn (t: ^Tilemap) draw*(tr: th::Transform, tint: uint32 = 0xFFFFFFFF) { //~~ if len(t.cells) == 0 { return } - umth_tilemap_draw(t, tr) + umth_tilemap_draw(t, tr, tint) } fn umth_tilemap_getcoll(pos: ^th::Vf2, vert: ^th::Vf2, t: ^Tilemap, e: ^ent::Ent): bool