diff --git a/cmd/view-map/main.go b/cmd/view-map/main.go index 0ed89f1..f29ab09 100644 --- a/cmd/view-map/main.go +++ b/cmd/view-map/main.go @@ -112,10 +112,10 @@ func (e *env) run() { }) } -func (e *env) getSprite(palette []string, ref maps.ObjRef) (*conv.Sprite, *conv.Object) { +func (e *env) getSprite(palette []string, ref maps.ObjRef) *conv.Sprite { if ref.Index() >= len(palette) { log.Printf("Palette too small: %v requested", ref.Index()) - return nil, nil + return nil } name := palette[ref.Index()] @@ -123,15 +123,15 @@ func (e *env) getSprite(palette []string, ref maps.ObjRef) (*conv.Sprite, *conv. obj := e.objects[name] if obj == nil { log.Printf("Failed to find surface sprite %#v -> %q", ref, name) - return nil, nil + return nil } if ref.Frame() >= len(obj.Sprites) { log.Printf("Out-of-index sprite %v requested for %v", ref.Frame(), name) - return nil, obj + return nil } - return &obj.Sprites[ref.Frame()], obj + return &obj.Sprites[ref.Frame()] } var ( @@ -142,8 +142,6 @@ var ( // TODO: build all the sprites in the set into a single spritesheet so we can // use pixel.Batch func (s *state) present(pWin *pixelgl.Window) { - gameMap := s.env.gameMap - pWin.Clear(colornames.Black) center := pWin.Bounds().Center() @@ -156,45 +154,56 @@ func (s *state) present(pWin *pixelgl.Window) { s.cam = cam pWin.SetMatrix(cam) - // TODO: bounds clipping - z := int(s.zIdx) - for y := int(gameMap.MinLength); y < int(gameMap.MaxLength); y++ { - for x := int(gameMap.MinWidth); x < int(gameMap.MaxWidth); x++ { + // TODO: we should be able to perform bounds clipping on these + minX := int(s.env.gameMap.MinWidth) + maxX := int(s.env.gameMap.MaxWidth) + minY := int(s.env.gameMap.MinLength) + maxY := int(s.env.gameMap.MaxLength) + minZ := 0 + maxZ := int(s.zIdx) + 1 - cell := gameMap.Cells.At(x, y, z) - - surfaceSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Surface) - centerSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Center) - leftSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Left) - rightSprite, _ := s.env.getSprite(s.env.set.Palette, cell.Right) - - fX := float64(x) - fY := float64(y) - - xPos := fX * cellWidth - yPos := fY * cellLength - - // The rotation translates the rectangular coordinates to diamond - // ones \o/ - // FIXME: these are off by a bit - orig := pixel.V(xPos, yPos) - iso := pixel.V(orig.X-orig.Y, (orig.X+orig.Y)/2.0) - - if surfaceSprite != nil { - surfaceSprite.Spr.Draw(pWin, pixel.IM.Moved(iso)) + for z := minZ; z < maxZ; z++ { + for y := minY; y < maxY; y++ { + for x := minX; x < maxX; x++ { + s.renderCell(x, y, z, pWin) } + } + } +} - if centerSprite != nil { - centerSprite.Spr.Draw(pWin, pixel.IM.Moved(iso)) - } +func (s *state) renderCell(x, y, z int, pWin *pixelgl.Window) { + var sprites []*conv.Sprite - if leftSprite != nil { - leftSprite.Spr.Draw(pWin, pixel.IM.Moved(iso)) - } + cell := s.env.gameMap.Cells.At(x, y, z) - if rightSprite != nil { - rightSprite.Spr.Draw(pWin, pixel.IM.Moved(iso)) - } + // Try optimizing zero surfaces out, they tend to be? all-transparent + if cell.Surface.Index() != 0 { + sprites = append(sprites, s.env.getSprite(s.env.set.Palette, cell.Surface)) + } + + sprites = append( + sprites, + s.env.getSprite(s.env.set.Palette, cell.Center), + s.env.getSprite(s.env.set.Palette, cell.Left), + s.env.getSprite(s.env.set.Palette, cell.Right), + ) + + // Taking the Z index away *seems* to draw the object in the correct place. + // FIXME: There are some artifacts, investigate more + fX := float64(x - z) + fY := float64(y - z) + + xPos := fX * cellWidth + yPos := fY * cellLength + + // The rotation translates the rectangular coordinates to diamond + // ones \o/ + orig := pixel.V(xPos, yPos) + iso := pixel.V(orig.X-orig.Y, (orig.X+orig.Y)/2.0) + + for _, sprite := range sprites { + if sprite != nil { + sprite.Spr.Draw(pWin, pixel.IM.Moved(iso)) } } }