156 lines
4.0 KiB
Go
156 lines
4.0 KiB
Go
package edit
|
|
|
|
import (
|
|
"fmt"
|
|
"image"
|
|
"image/png"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"aego/editor/core/command"
|
|
"aego/editor/core/context"
|
|
"aego/editor/core/workspace"
|
|
"aego/editor/panels/gameview"
|
|
"aego/editor/shell"
|
|
)
|
|
|
|
// EnvShots makes the editor write the documentation screenshots to this directory and exit.
|
|
const EnvShots = "AEGO_SHOTS"
|
|
|
|
type shot struct {
|
|
name string
|
|
frames int
|
|
inset int
|
|
bottom int
|
|
setup func(s *Session) error
|
|
}
|
|
|
|
func (s *Session) shots(dir string) error {
|
|
defer s.Close()
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
return err
|
|
}
|
|
if !s.Step() {
|
|
return fmt.Errorf("the editor quit")
|
|
}
|
|
ctx := s.App.Context()
|
|
scene := func() { ctx.Open(context.At("scenes/main.aescene", 1, 1)) }
|
|
frameAll := func() error {
|
|
if err := ctx.Commands.Run(command.EditSelectAll); err != nil {
|
|
return err
|
|
}
|
|
if err := ctx.Commands.Run(command.SceneFrame); err != nil {
|
|
return err
|
|
}
|
|
for i := 0; i < 30; i++ {
|
|
s.Step()
|
|
}
|
|
return nil
|
|
}
|
|
list := []shot{
|
|
{name: "editor", frames: 240, setup: func(s *Session) error {
|
|
scene()
|
|
s.App.Workspace().Show(workspace.Inspector)
|
|
if err := frameAll(); err != nil {
|
|
return err
|
|
}
|
|
return selectNamed(ctx, "Player")
|
|
}},
|
|
{name: "tags", frames: 60, setup: func(s *Session) error {
|
|
return selectNamed(ctx, "Player")
|
|
}},
|
|
{name: "prefab", frames: 60, setup: func(s *Session) error {
|
|
return selectNamed(ctx, "EnemyLeft")
|
|
}},
|
|
{name: "settings-input", frames: 60, setup: func(s *Session) error {
|
|
ctx.Open(context.SettingsAt("input"))
|
|
return nil
|
|
}},
|
|
{name: "settings-physics", frames: 60, setup: func(s *Session) error {
|
|
ctx.Open(context.SettingsAt("physics"))
|
|
return nil
|
|
}},
|
|
{name: "script", frames: 90, setup: func(s *Session) error {
|
|
ctx.Open(context.At("scripts/player/player.aes", 1, 1))
|
|
return nil
|
|
}},
|
|
{name: "workspace-programming", frames: 60, setup: func(s *Session) error {
|
|
s.App.Workspace().Switch(workspace.Programming)
|
|
return nil
|
|
}},
|
|
{name: "play", frames: 150, setup: func(s *Session) error {
|
|
s.App.Workspace().Switch(workspace.Design)
|
|
scene()
|
|
return ctx.Commands.Run(command.PlayStart)
|
|
}},
|
|
{name: "physics-debug", frames: 30, setup: func(s *Session) error {
|
|
ctx.Overlay.Set("physics.debug.contacts", true)
|
|
return ctx.Commands.Run(gameview.CommandOverlays)
|
|
}},
|
|
{name: "demo", frames: 60, inset: 2, bottom: 28, setup: func(s *Session) error {
|
|
for _, f := range []string{"physics.debug", "physics.debug.shapes", "physics.debug.contacts", "physics.debug.joints"} {
|
|
ctx.Overlay.Set(f, false)
|
|
}
|
|
return ctx.Commands.Run(shell.CommandFullscreenPlay)
|
|
}},
|
|
{name: "prefab-mode", frames: 120, setup: func(s *Session) error {
|
|
if err := ctx.Commands.Run(command.PlayStop); err != nil {
|
|
return err
|
|
}
|
|
id, ok := s.Pipeline.Lookup("prefabs/enemy.aeprefab")
|
|
if !ok {
|
|
return fmt.Errorf("no prefabs/enemy.aeprefab")
|
|
}
|
|
return s.App.Prefabs().Open(id)
|
|
}},
|
|
}
|
|
for _, sh := range list {
|
|
if err := sh.setup(s); err != nil {
|
|
return fmt.Errorf("%s: %w", sh.name, err)
|
|
}
|
|
if err := s.capture(sh, filepath.Join(dir, sh.name+".png")); err != nil {
|
|
return fmt.Errorf("%s: %w", sh.name, err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func selectNamed(ctx *context.Editor, name string) error {
|
|
sc := ctx.Scene()
|
|
if sc == nil {
|
|
return fmt.Errorf("no scene is open")
|
|
}
|
|
h := sc.Find(sc.Root(), name)
|
|
if !sc.IsAlive(h) {
|
|
return fmt.Errorf("the scene has no node %q", name)
|
|
}
|
|
ctx.Select(sc.ID(h))
|
|
return nil
|
|
}
|
|
|
|
func (s *Session) capture(sh shot, path string) error {
|
|
for i := 0; i < sh.frames; i++ {
|
|
if !s.Step() {
|
|
return fmt.Errorf("the editor quit")
|
|
}
|
|
}
|
|
var img *image.RGBA
|
|
var err error
|
|
s.Engine.CaptureFrame(func(got *image.RGBA, e error) { img, err = got, e })
|
|
s.Step()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if img == nil {
|
|
return fmt.Errorf("no frame was presented")
|
|
}
|
|
b := img.Bounds()
|
|
crop := img.SubImage(image.Rect(b.Min.X+sh.inset, b.Min.Y+sh.inset, b.Max.X-sh.inset, b.Max.Y-sh.inset-sh.bottom))
|
|
f, err := os.Create(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer f.Close()
|
|
return png.Encode(f, crop)
|
|
}
|