From 0320743b30a5fd8a5dbf9a05e5f09be5594aa863 Mon Sep 17 00:00:00 2001 From: Nick Thomas Date: Wed, 9 Oct 2019 00:41:41 +0100 Subject: [PATCH] Play around with menus some more We now display the buttons in Main.mnu, but a lot remains unknown. --- cmd/view-menu/main.go | 80 +++++++++++++++++++++++++++++++---------- internal/conv/font.go | 37 +++++++++++++++++++ internal/menus/menus.go | 14 ++++++-- 3 files changed, 111 insertions(+), 20 deletions(-) create mode 100644 internal/conv/font.go diff --git a/cmd/view-menu/main.go b/cmd/view-menu/main.go index 815581e..8ebb192 100644 --- a/cmd/view-menu/main.go +++ b/cmd/view-menu/main.go @@ -2,6 +2,7 @@ package main import ( "flag" + "fmt" "log" "os" "path/filepath" @@ -27,13 +28,14 @@ type env struct { objects []*conv.Object batch *pixel.Batch - fonts []*fonts.Font + fonts []*conv.Font fontObjs []*conv.Object fontBatch *pixel.Batch } type state struct { env *env + cam pixel.Matrix step int // Redraw the window if these change @@ -80,26 +82,36 @@ func main() { menu.Internationalize(i18n) } - var loadedFonts []*fonts.Font - for _, name := range menu.FontNames { - font, err := fonts.LoadFont(filepath.Join(*gamePath, "Fonts", name+".fnt")) - if err != nil { - log.Fatalf("Failed to load font %v: %v", name, err) - } - loadedFonts = append(loadedFonts, font) + loadedFonts, err := loadFonts(menu.FontNames...) + if err != nil { + log.Fatalf("Failed to load font: %v", err) } menuObjs, menuBatch := loadObjects(menu.ObjectFiles...) env := &env{ menu: menu, objects: menuObjs, batch: menuBatch, - fonts: loadedFonts, // TODO: load the objects and start displaying text + fonts: loadedFonts, } // The main thread now belongs to pixelgl pixelgl.Run(env.run) } +func loadFonts(names ...string) ([]*conv.Font, error) { + var out []*conv.Font + for _, name := range names { + fnt, err := fonts.LoadFont(filepath.Join(*gamePath, "Fonts", name+".fnt")) + if err != nil { + return nil, fmt.Errorf("%v: %v", name, err) + } + + out = append(out, conv.ConvertFont(fnt)) + } + + return out, nil +} + func (e *env) run() { win, err := ui.NewWindow("View Menu: " + *menuFile) if err != nil { @@ -151,22 +163,40 @@ func (s *state) present(pWin *pixelgl.Window) { cam = cam.ScaledXY(pixel.ZV, pixel.Vec{1.0, -1.0}) // invert the Y axis cam = cam.Moved(pixel.Vec{origX / 2, origY / 2}) cam = cam.ScaledXY(pixel.ZV, scaleFactor) + s.cam = cam s.env.batch.SetMatrix(cam) + textCanvas := pixelgl.NewCanvas(pWin.Bounds()) + textCanvas.SetMatrix(pixel.IM.ScaledXY(pixel.ZV, scaleFactor)) + for _, record := range s.env.menu.Records { - s.drawRecord(record, s.env.batch) + s.drawRecord(record, s.env.batch, textCanvas) } s.env.batch.Draw(pWin) + textCanvas.Draw(pWin, pixel.IM) } -func (s *state) drawRecord(record *menus.Record, target pixel.Target) { +func (s *state) drawRecord(record *menus.Record, target, textTarget pixel.Target) { // Draw this record if it's valid to do so. FIXME: lots to learn - if record.SpriteId >= 0 { + if len(record.SpriteId) >= 0 { + spriteId := record.SpriteId[0] x := float64(record.X) y := float64(record.Y) - // FIXME: some are set at -1, -1. No idea why + // Theory: we either give spriteid, or y,x,spriteId + if len(record.SpriteId) == 3 { + x = x + float64(record.SpriteId[1]) + y = y + float64(record.SpriteId[0]*2) // FIXME: *2 works, no idea + spriteId = record.SpriteId[2] + } + + // FIXME: some here are set at -1. Presume that means don't draw. + if spriteId < 0 { + goto out + } + + // FIXME: some are set at -1, -1. No idea why. Origin? if x < 0.0 { x = 0.0 } @@ -176,22 +206,36 @@ func (s *state) drawRecord(record *menus.Record, target pixel.Target) { log.Printf( "Drawing id=%v type=%v spriteid=%v x=%v y=%v desc=%q parent=%p", - record.Id, record.Type, record.SpriteId, record.X, record.Y, record.Desc, record.Parent, + record.Id, record.Type, spriteId, record.X, record.Y, record.Desc, record.Parent, ) // FIXME: Need to handle multiple objects + offset := pixel.V(x, y) obj := s.env.objects[0] - sprite := obj.Sprites[record.SpriteId] - sprite.Spr.Draw(target, pixel.IM.Moved(pixel.V(x, y))) - } + sprite := obj.Sprites[spriteId] + sprite.Spr.Draw(target, pixel.IM.Moved(offset)) + // FIXME: we probably shouldn't draw everything? + // FIXME: handle multiple fonts + if len(s.env.fonts) > 0 && record.Desc != "" { + s.env.fonts[0].Output(textTarget, pixel.IM.Moved(offset), record.Desc) + } + } +out: // Draw all children of this record for _, child := range record.Children { - s.drawRecord(child, target) + s.drawRecord(child, target, textTarget) } } func (s *state) handleKeys(pWin *pixelgl.Window) { + if pWin.JustPressed(pixelgl.MouseButton1) { + log.Printf("cam: %#v", s.cam) + + pos := s.cam.Unproject(pWin.MousePosition()) + log.Printf("X=%v Y=%v", pos.X, pos.Y) + } + /* if pWin.JustPressed(pixelgl.KeyLeft) { if s.objIdx > 0 { diff --git a/internal/conv/font.go b/internal/conv/font.go new file mode 100644 index 0000000..2137f01 --- /dev/null +++ b/internal/conv/font.go @@ -0,0 +1,37 @@ +package conv + +import ( + "fmt" + + "github.com/faiface/pixel" + "github.com/faiface/pixel/text" + "golang.org/x/image/colornames" + "golang.org/x/image/font/basicfont" + + "ur.gs/ordoor/internal/fonts" +) + +type Font struct { + Name string + Atlas *text.Atlas + Text *text.Text +} + +func (f *Font) Output(to pixel.Target, m pixel.Matrix, format string, args ...interface{}) { + text := text.New(pixel.V(0.0, 0.0), f.Atlas) + text.Color = colornames.White + + fmt.Fprintf(text, format, args...) + + text.Draw(to, m) +} + +func ConvertFont(font *fonts.Font) *Font { + // FIXME: actually use the pixel data in font + atlas := text.NewAtlas(basicfont.Face7x13, text.ASCII) + + return &Font{ + Name: font.Name, + Atlas: atlas, + } +} diff --git a/internal/menus/menus.go b/internal/menus/menus.go index 4145d88..7f4853b 100644 --- a/internal/menus/menus.go +++ b/internal/menus/menus.go @@ -16,8 +16,9 @@ type Record struct { Id int Type int + FontType int Active bool - SpriteId int + SpriteId []int X int Y int Desc string @@ -161,7 +162,14 @@ func (r *Record) Toplevel() *Record { } func setProperty(r *Record, k, v string) { + vSplit := strings.Split(v, ",") vInt, _ := strconv.Atoi(v) + vSplitInt := make([]int, len(vSplit)) + + for i, subV := range vSplit { + vSplitInt[i], _ = strconv.Atoi(subV) + } + switch k { case "MENUID", "SUBMENUID": r.Id = vInt @@ -170,13 +178,15 @@ func setProperty(r *Record, k, v string) { case "ACTIVE": r.Active = (vInt != 0) case "SPRITEID": - r.SpriteId = vInt + r.SpriteId = vSplitInt case "X-CORD": r.X = vInt case "Y-CORD": r.Y = vInt case "DESC": r.Desc = v + case "FONTTYPE": + r.FontType = vInt default: r.properties[k] = v }