diff --git a/examples/tetris/tetris.v b/examples/tetris/tetris.v index ecf04a552b..480d6b5881 100644 --- a/examples/tetris/tetris.v +++ b/examples/tetris/tetris.v @@ -4,10 +4,12 @@ module main +import os import rand import time import gx import gg2 as gg +import gg2.ft import sokol.sapp const ( @@ -124,10 +126,9 @@ struct Game { // Index of the rotation (0-3) rotation_idx int // gg context for drawing - gg &gg.GG + gg &gg.GG = voidptr(0) // ft context for font drawing - //ft &freetype.FreeType - //ft &ft.FT + ft &ft.FT = voidptr(0) font_loaded bool // frame/time counters: frame int @@ -136,6 +137,13 @@ struct Game { second_sw time.StopWatch = time.new_stopwatch({}) } +const ( fpath = os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf') ) +fn init_gui(mut game Game){ + x := ft.new({ font_path: fpath }) or {panic(err)} + game.ft = x + game.font_loaded = true +} + [if showfps] fn (game &Game) showfps() { game.frame++ @@ -151,27 +159,18 @@ fn (game &Game) showfps() { fn frame(game &Game) { game.frame_sw.restart() - //C.sfons_flush(game.ft.fons) + game.ft.flush() game.gg.begin() game.draw_scene() game.showfps() game.gg.end() } + fn main() { - // TODO - /* - f := ft.new( - //font_path: os.resource_abs_path('../assets/fonts/RobotoMono-Regular.ttf') - font_path: ('../assets/fonts/RobotoMono-Regular.ttf') - ) or { - println('failed to loat the font') - return - } - */ mut game := &Game{ gg: 0 - //ft: f + ft: 0 } game.gg = gg.new_context( bg_color: gx.white @@ -180,9 +179,10 @@ fn main() { use_ortho: true // This is needed for 2D drawing create_window: true window_title: 'V Tetris' - frame_fn: frame + // user_data: game - //on_key_down: key_down + init_fn: init_gui + frame_fn: frame event_cb: on_event ) game.init_game() @@ -352,17 +352,17 @@ fn (g &Game) draw_field() { fn (mut g Game) draw_ui() { if g.font_loaded { - //g.ft.draw_text(1, 3, g.score.str(), text_cfg) + g.ft.draw_text(1, 3, g.score.str(), text_cfg) if g.state == .gameover { g.gg.draw_rect(0, win_height / 2 - text_size, win_width, 5 * text_size, ui_color) - //g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Over', over_cfg) - //g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'Space to restart', over_cfg) + g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Over', over_cfg) + g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'Space to restart', over_cfg) } else if g.state == .paused { g.gg.draw_rect(0, win_height / 2 - text_size, win_width, 5 * text_size, ui_color) - //g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Paused', text_cfg) - //g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'SPACE to resume', text_cfg) + g.ft.draw_text(1, win_height / 2 + 0 * text_size, 'Game Paused', text_cfg) + g.ft.draw_text(1, win_height / 2 + 2 * text_size, 'SPACE to resume', text_cfg) } } //g.gg.draw_rect(0, block_size, win_width, limit_thickness, ui_color) diff --git a/vlib/gg2/ft/ft.v b/vlib/gg2/ft/ft.v index dd40d40e16..e39e852f35 100644 --- a/vlib/gg2/ft/ft.v +++ b/vlib/gg2/ft/ft.v @@ -34,9 +34,7 @@ pub fn new(c Config) ?&FT{ println('failed to load font "$c.font_path"') return none } - s := &C.sgl_desc_t{} - C.sgl_setup(s) - fons :=sfons.create(512, 512, 1) + fons := sfons.create(512, 512, 1) return &FT{ fons : fons font_normal: C.fonsAddFontMem(fons, 'sans', bytes.data, bytes.len, false) @@ -44,27 +42,26 @@ pub fn new(c Config) ?&FT{ } -pub fn (gg &FT) draw_text(x, y int, text string, cfg gx.TextCfg) { - /* - gg.fons.set_font(gg.font_normal) - gg.fons.set_size(f32(cfg.size)) +pub fn (ft &FT) draw_text(x, y int, text string, cfg gx.TextCfg) { + ft.fons.set_font(ft.font_normal) + ft.fons.set_size(2*f32(cfg.size)) // TODO: is this 2* needed? + C.fonsSetAlign(ft.fons, C.FONS_ALIGN_LEFT | C.FONS_ALIGN_TOP) + color := C.sfons_rgba(cfg.color.r, cfg.color.g, cfg.color.b, 255) + C.fonsSetColor(ft.fons, color) ascender := f32(0.0) descender := f32(0.0) lh := f32(0.0) - gg.fons.vert_metrics(&ascender, &descender, &lh) - color:= C.sfons_rgba(cfg.color.r, cfg.color.g, cfg.color.b, 255) - C.fonsSetColor(gg.fons, color) - C.fonsDrawText(gg.fons, x, y, text.str, 0) - */ + ft.fons.vert_metrics(&ascender, &descender, &lh) + C.fonsDrawText(ft.fons, x, y, text.str, 0) // TODO: check offsets/alignment } -pub fn (ctx &FT) draw_text_def(x, y int, text string) { +pub fn (ft &FT) draw_text_def(x, y int, text string) { cfg := gx.TextCfg { color: gx.black size: default_font_size align: gx.align_left } - ctx.draw_text(x, y, text, cfg) + ft.draw_text(x, y, text, cfg) } pub fn (mut gg FT) init_font() { @@ -73,4 +70,6 @@ pub fn (mut gg FT) init_font() { //gg.font_normal=g_font_normal } - +pub fn (ft &FT) flush(){ + sfons.flush(ft.fons) +} diff --git a/vlib/gg2/gg.v b/vlib/gg2/gg.v index 7c03dd034f..f137902622 100644 --- a/vlib/gg2/gg.v +++ b/vlib/gg2/gg.v @@ -10,6 +10,9 @@ import sokol.sapp import sokol.sgl import sokol.gfx +type FNvoidptr1 fn(voidptr) +type FNvoidptr2 fn(voidptr,voidptr) + pub struct Config { pub: width int @@ -24,10 +27,12 @@ pub: window_title string always_on_top bool scale int - frame_fn fn(voidptr) bg_color gx.Color - on_key_down fn(voidptr) - event_cb fn(voidptr, voidptr) + init_fn FNvoidptr1 = voidptr(0) + frame_fn FNvoidptr1 = voidptr(0) + on_key_down FNvoidptr1 = voidptr(0) + event_cb FNvoidptr2 = voidptr(0) + wait_events bool = false // set this to true for UIs, to save power } pub struct GG { @@ -37,10 +42,11 @@ pub mut: height int clear_pass C.sg_pass_action window C.sapp_desc - render_fn fn() + config Config } -fn init_sokol_window(user_data voidptr) { +fn gg_init_sokol_window(user_data voidptr) { + mut g := &GG(user_data) desc := C.sg_desc{ mtl_device: sapp.metal_get_device() mtl_renderpass_descriptor_cb: sapp.metal_get_renderpass_descriptor @@ -53,19 +59,47 @@ fn init_sokol_window(user_data voidptr) { gfx.setup(&desc) sgl_desc := C.sgl_desc_t{} sgl.setup(&sgl_desc) + if g.config.init_fn != voidptr(0) { + g.config.init_fn( g.config.user_data ) + } } +fn gg_frame_fn(user_data voidptr) { + mut g := &GG(user_data) + if g.config.frame_fn != voidptr(0) { + g.config.frame_fn( g.config.user_data ) + } +} + +fn gg_event_cb(e &C.sapp_event, b voidptr){ + mut g := &GG(b) + if g.config.event_cb != voidptr(0) { + g.config.event_cb(e, g.config.user_data) + } +} + +// + fn eventcb(e &C.sapp_event, b voidptr){ println("EVENT") } pub fn new_context(cfg Config) &GG { + mut g := &GG{ + width: cfg.width + height: cfg.height + clear_pass: gfx.create_clear_pass( f32(cfg.bg_color.r) / 255.0, f32(cfg.bg_color.g) / 255.0, +f32(cfg.bg_color.b) / 255.0, 1.0) + scale: 1 // scale + config: cfg + } + //C.printf('new_context() %p\n', cfg.user_data) window := C.sapp_desc{ - user_data: cfg.user_data - init_userdata_cb: init_sokol_window - frame_userdata_cb: cfg.frame_fn - event_userdata_cb: cfg.event_cb //eventcb + user_data: g + init_userdata_cb: gg_init_sokol_window + frame_userdata_cb: gg_frame_fn + event_userdata_cb: gg_event_cb //eventcb window_title: cfg.window_title.str html5_canvas_name: cfg.window_title.str width: cfg.width @@ -74,14 +108,8 @@ pub fn new_context(cfg Config) &GG { } if cfg.use_ortho {} else {} - return &GG{ - width: cfg.width - height: cfg.height - window: window - clear_pass: gfx.create_clear_pass( f32(cfg.bg_color.r) / 255.0, f32(cfg.bg_color.g) / 255.0, -f32(cfg.bg_color.b) / 255.0, 1.0) - scale: 1 // scale - } + g.window = window + return g } pub fn (gg &GG) run() { @@ -148,7 +176,9 @@ pub fn (gg &GG) end() { sgl.draw() gfx.end_pass() gfx.commit() - wait_events() + if gg.config.wait_events { + wait_events() + } } pub fn (ctx &GG) draw_line(x, y, x2, y2 f32, color gx.Color) {}