package main import ( "flag" "image/color" "log" "os" "path/filepath" "github.com/faiface/pixel" // "github.com/faiface/pixel/imdraw" "github.com/faiface/pixel/pixelgl" "golang.org/x/image/colornames" "ur.gs/chaos-gate/internal/data" "ur.gs/chaos-gate/internal/sets" "ur.gs/chaos-gate/internal/ui" ) var ( gamePath = flag.String("game-path", "./orig", "Path to a WH40K: Chaos Gate installation") setFile = flag.String("set", "", "Path to a .set file, e.g. ./orig/Sets/map01.set") ) type env struct { set *sets.MapSet objects map[string]*data.Object } type state struct { env *env objIdx int spriteIdx int zoom float64 cam pixel.Matrix camPos pixel.Vec } func main() { flag.Parse() if *gamePath == "" || *setFile == "" { flag.Usage() os.Exit(1) } mapSet, err := sets.LoadSet(*setFile) if err != nil { log.Fatalf("Couldn't load set file %s: %v", setFile, err) } objects := make(map[string]*data.Object) for _, name := range mapSet.Palette { objFile := filepath.Join(*gamePath, "Obj", name+".obj") obj, err := data.LoadObject(objFile) if err != nil { log.Fatalf("Failed to load %s: %v", name, err) } objects[filepath.Base(objFile)] = obj } env := &env{objects: objects, set: mapSet} // The main thread now belongs to pixelgl pixelgl.Run(env.run) } func (e *env) run() { win, err := ui.NewWindow("View Set: " + *setFile) 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 { log.Printf( "new state: numObj=%d object=%d (%s) numFrames=%d frame=%d", // FIXME: rename to sprite throughout state.env.set.Count(), state.objIdx, state.env.set.Palette[state.objIdx], state.curObject().NumFrames, state.spriteIdx) state.present(pWin) } }) } func (s *state) runStep(pWin *pixelgl.Window) *state { newState := *s newState.handleKeys(pWin) return &newState } func (s *state) present(pWin *pixelgl.Window) { obj := s.curObject() frame := obj.Frames[s.spriteIdx] // FIXME: Rename Frame to Sprite throughout log.Printf("%#v", frame) pic := pixel.MakePictureData(pixel.R(0, 0, float64(frame.Width), float64(frame.Height))) // FIXME: how do I convert? Do I even have the right data here? for i, b := range frame.PixelData { pic.Pix[i] = color.RGBA{b, b, b, 255} } sprite := pixel.NewSprite(pic, pic.Bounds()) pWin.Clear(colornames.White) sprite.Draw(pWin, pixel.IM.Moved(pWin.Bounds().Center())) } func (s *state) handleKeys(pWin *pixelgl.Window) { if pWin.JustPressed(pixelgl.KeyLeft) { if s.objIdx > 0 { s.objIdx -= 1 s.spriteIdx = 0 } } if pWin.JustPressed(pixelgl.KeyRight) { if s.objIdx < s.env.set.Count()-1 { s.objIdx += 1 s.spriteIdx = 0 } } if pWin.JustPressed(pixelgl.KeyDown) { if s.spriteIdx > 0 { s.spriteIdx -= 1 } } if pWin.JustPressed(pixelgl.KeyUp) { if s.spriteIdx < int(s.curObject().NumFrames)-1 { s.spriteIdx += 1 } } } func (s *state) curObject() *data.Object { name := s.env.set.Palette[s.objIdx] + ".obj" return s.env.objects[name] // FIXME: we should use consistent naming! }