package main import ( "flag" "log" "math" "os" "path/filepath" "github.com/faiface/pixel" "github.com/faiface/pixel/pixelgl" "golang.org/x/image/colornames" "ur.gs/ordoor/internal/conv" "ur.gs/ordoor/internal/data" "ur.gs/ordoor/internal/ui" ) var ( gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation") objFile = flag.String("obj", "", "Path to a .obj file, e.g. ./orig/Obj/TZEENTCH.OBJ") ) type env struct { obj *conv.Object } type state struct { env *env step int spriteIdx int zoom float64 cam pixel.Matrix camPos pixel.Vec } func main() { flag.Parse() if *gamePath == "" || *objFile == "" { flag.Usage() os.Exit(1) } rawObj, err := data.LoadObject(*objFile) if err != nil { log.Fatalf("Failed to load %s: %v", *objFile, err) } obj := conv.ConvertObject(rawObj, filepath.Base(*objFile)) env := &env{obj: obj} // The main thread now belongs to pixelgl pixelgl.Run(env.run) } func (e *env) run() { win, err := ui.NewWindow("View Object: " + *objFile) if err != nil { log.Fatal("Couldn't create window: %v", err) } pWin := win.PixelWindow state := &state{ env: e, camPos: pixel.V(0, float64(-pWin.Bounds().Size().Y)), zoom: 8.0, } // For now, just try to display the various objects // left + right to change object, up + down to change frame win.Run(func() { oldState := *state state = state.runStep(pWin) if oldState != *state || oldState.step == 0 { log.Printf( "new state: numSprites=%d sprite=%d zoom=%.2f", len(state.env.obj.Sprites), state.spriteIdx, state.zoom, ) state.present(pWin) } state.step += 1 }) } func (s *state) runStep(pWin *pixelgl.Window) *state { newState := *s newState.handleKeys(pWin) return &newState } func (s *state) present(pWin *pixelgl.Window) { obj := s.env.obj sprite := obj.Sprites[s.spriteIdx] center := pWin.Bounds().Center() cam := pixel.IM cam = cam.ScaledXY(center, pixel.Vec{1.0, -1.0}) // invert the Y axis cam = cam.Scaled(center, s.zoom) // apply current zoom factor //cam = cam.Moved(center.Sub(s.camPos)) // Make it central //cam = cam.Rotated(center, -0.785) // Apply isometric angle s.cam = cam pWin.SetMatrix(s.cam) pWin.Clear(colornames.Black) pixel.NewSprite(sprite.Pic, sprite.Pic.Bounds()).Draw(pWin, pixel.IM.Moved(center)) } func (s *state) handleKeys(pWin *pixelgl.Window) { if pWin.JustPressed(pixelgl.KeyMinus) { if s.spriteIdx > 0 { s.spriteIdx -= 1 } } if pWin.JustPressed(pixelgl.KeyEqual) { if s.spriteIdx < len(s.env.obj.Sprites)-1 { s.spriteIdx += 1 } } // Zoom in and out with the mouse wheel s.zoom *= math.Pow(1.2, pWin.MouseScroll().Y) }