Get view-menu to play the interface sound
This commit is contained in:
49
README.md
49
README.md
@@ -19,7 +19,7 @@ installed on your system:
|
||||
|
||||
```
|
||||
$ go version
|
||||
go version go1.13 linux/amd64
|
||||
go version go1.14 linux/amd64
|
||||
```
|
||||
|
||||
In addition, you'll also need the following packages installed, at least in
|
||||
@@ -27,13 +27,11 @@ Debian:
|
||||
|
||||
```
|
||||
# apt install libx11-dev libxcursor-dev mesa-common-dev libxrandr-dev \
|
||||
libxinerama-dev libgl1-mesa-dev libxi-dev mpv
|
||||
libxinerama-dev libgl1-mesa-dev libxi-dev libasound2-dev mpv ffmpeg
|
||||
```
|
||||
|
||||
You can then run `make all` in the source tree to get the binaries that are
|
||||
present at hte moment.
|
||||
|
||||
They're not very interesting :D.
|
||||
present at the moment.
|
||||
|
||||
Place your WH40K: Chaos Gate installation in `./orig` to benefit from automatic
|
||||
path defaults. Otherwise, point to it with `-game-path`
|
||||
@@ -42,14 +40,13 @@ The `view-map` binary attempts to render a map, and is the current focus of
|
||||
effort. Once I can render a whole map, including pre-placed characters (cultist
|
||||
scum), things can start to get more interesting.
|
||||
|
||||
Current status: map tiles are rendered at correct offsets. Static objects (four
|
||||
per map coordinate: floor, centre, left, and right) are rendered mostly fine,
|
||||
although objects at each Z level don't *quite* stack correctly on top of each
|
||||
other yet.
|
||||
Current status: almost pixel-perfect map rendering. Static objects (four per map
|
||||
coordinate: floor, centre, left, and right) are rendered fine, and each Z level
|
||||
looks good. There are a few minor artifacts here and there.
|
||||
|
||||
Characters and animations aren't touched at all yet. Rendering performance is
|
||||
atrocious. No gameplay, no sound, no campaign logic. Interaction with the play
|
||||
area is minimal and limited to pan, zoom, and click for basic console output.
|
||||
poor. No gameplay, no campaign logic. Interaction with the play area is minimal
|
||||
and limited to pan, zoom, and click for basic console output.
|
||||
|
||||
Still, I'm proud of myself.
|
||||
|
||||
@@ -57,7 +54,7 @@ To run:
|
||||
|
||||
```
|
||||
$ make view-map
|
||||
$ ./view-map -map orig/Maps/Chapter01.MAP -txt orig/Maps/Chapter01.TXT
|
||||
$ ./view-map -map Chapter01
|
||||
```
|
||||
|
||||
Looks like this:
|
||||
@@ -72,12 +69,36 @@ Dependency management uses `go mod`, so ensure you have at least Go 1.11.
|
||||
There is the **start** of the menu / campaign flow in a `wh40k` binary:
|
||||
|
||||
```
|
||||
$ cp config.toml.example config.toml
|
||||
$ make wh40k
|
||||
$ ./wh40k
|
||||
```
|
||||
|
||||
This plays the introductory video so far, and nothing else. I'm hopeful I can
|
||||
render the main menu next.
|
||||
This plays the introductory videos so far, and nothing else.
|
||||
|
||||
Menus are in the process of being rendered; you can use the `view-menu` binary
|
||||
to inspect them:
|
||||
|
||||
```
|
||||
make view-menu
|
||||
./view-menu -menu ./orig/Menu/Main.mnu
|
||||
```
|
||||
|
||||
This menu *displays* OK, including
|
||||
|
||||
## Sound
|
||||
|
||||
Sound is in the very early stages. Chaos Gate uses ADPCM WAV files, which are a
|
||||
pain to play in Go, so for now, a preprocessing step that converts them to .ogg
|
||||
is used instead. To create ./orig/Wav/*.wav.ogg, run:
|
||||
|
||||
```
|
||||
# apt install ffmpeg
|
||||
$ ./scripts/convert-wav ./orig/Wav
|
||||
```
|
||||
|
||||
As with video playback, the ambition is to *eventually* remove this dependency
|
||||
and operate on the unmodified files instead.
|
||||
|
||||
## Miscellany
|
||||
|
||||
|
@@ -7,12 +7,12 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
|
||||
"code.ur.gs/lupine/ordoor/internal/assetstore"
|
||||
"code.ur.gs/lupine/ordoor/internal/data"
|
||||
"code.ur.gs/lupine/ordoor/internal/menus"
|
||||
"code.ur.gs/lupine/ordoor/internal/ui"
|
||||
"github.com/hajimehoshi/ebiten"
|
||||
"github.com/hajimehoshi/ebiten/audio"
|
||||
)
|
||||
|
||||
var (
|
||||
@@ -76,6 +76,20 @@ func main() {
|
||||
menuObjs = append(menuObjs, obj)
|
||||
}
|
||||
|
||||
// Yay sound
|
||||
if _, err := audio.NewContext(48000); err != nil {
|
||||
log.Fatalf("Failed to audio: %v", err)
|
||||
}
|
||||
music, err := assets.Sound("music_interface") // FIXME: should be a reference to Sounds.dat
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to find interface music: %v", err)
|
||||
}
|
||||
player, err := music.InfinitePlayer()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to generate music player for interface: %v", err)
|
||||
}
|
||||
player.Play()
|
||||
|
||||
state := state{}
|
||||
env := &env{
|
||||
menu: menu,
|
||||
|
4
go.mod
4
go.mod
@@ -5,8 +5,8 @@ go 1.12
|
||||
require (
|
||||
github.com/BurntSushi/toml v0.3.1
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5
|
||||
golang.org/x/exp v0.0.0-20200319221330-857350248e3d // indirect
|
||||
golang.org/x/exp v0.0.0-20200320212757-167ffe94c325 // indirect
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1 // indirect
|
||||
golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0 // indirect
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d // indirect
|
||||
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae // indirect
|
||||
)
|
||||
|
9
go.sum
9
go.sum
@@ -14,13 +14,18 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw
|
||||
github.com/hajimehoshi/bitmapfont v1.2.0/go.mod h1:h9QrPk6Ktb2neObTlAbma6Ini1xgMjbJ3w7ysmD7IOU=
|
||||
github.com/hajimehoshi/ebiten v1.10.2 h1:PiJBY4Q4udip675T+Zqvb3NKMp1eyLWBelp660ZMrkQ=
|
||||
github.com/hajimehoshi/ebiten v1.10.2/go.mod h1:i9dIEUf5/MuPtbK1/wHR0PB7ZtqhjOxxg+U1xfxapcY=
|
||||
github.com/hajimehoshi/ebiten v1.10.5 h1:hVb3GJP4IDqOETifRmPg4xmURRgbIJoB9gQk+Jqe8Uk=
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5 h1:hke9UdXY1YPfqjXG1bCSZnoVnfVBw9SzvmlrRn3dL3w=
|
||||
github.com/hajimehoshi/ebiten v1.11.0-alpha.2.0.20200101150127-38815ba801a5/go.mod h1:0SLvfr8iI2NxzpNB/olBM+dLN9Ur5a9szG13wOgQ0nQ=
|
||||
github.com/hajimehoshi/go-mp3 v0.2.1 h1:DH4ns3cPv39n3cs8MPcAlWqPeAwLCK8iNgqvg0QBWI8=
|
||||
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
|
||||
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA=
|
||||
github.com/hajimehoshi/oto v0.5.4 h1:Dn+WcYeF310xqStKm0tnvoruYUV5Sce8+sfUaIvWGkE=
|
||||
github.com/hajimehoshi/oto v0.5.4/go.mod h1:0QXGEkbuJRohbJaxr7ZQSxnju7hEhseiPx2hrh6raOI=
|
||||
github.com/jakecoffman/cp v0.1.0/go.mod h1:a3xPx9N8RyFAACD644t2dj/nK4SuLg1v+jL61m2yVo4=
|
||||
github.com/jfreymuth/oggvorbis v1.0.0 h1:aOpiihGrFLXpsh2osOlEvTcg5/aluzGQeC7m3uYWOZ0=
|
||||
github.com/jfreymuth/oggvorbis v1.0.0/go.mod h1:abe6F9QRjuU9l+2jek3gj46lu40N4qlYxh2grqkLEDM=
|
||||
github.com/jfreymuth/vorbis v1.0.0 h1:SmDf783s82lIjGZi8EGUUaS7YxPHgRj4ZXW/h7rUi7U=
|
||||
github.com/jfreymuth/vorbis v1.0.0/go.mod h1:8zy3lUAm9K/rJJk223RKy6vjCZTWC61NA2QD06bfOE0=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
@@ -38,6 +43,8 @@ golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85 h1:jqhIzSw5SQNkbu5hOGpgMHhkf
|
||||
golang.org/x/exp v0.0.0-20200228211341-fcea875c7e85/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20200319221330-857350248e3d h1:1kJNg12kVM6Xid7xoFkhq/YJVU4NMTv5b3hJCfQnwjc=
|
||||
golang.org/x/exp v0.0.0-20200319221330-857350248e3d/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/exp v0.0.0-20200320212757-167ffe94c325 h1:iPGJw87eUJvke9YLYKX0jIwLHiIrY/kXcFSgOpjav28=
|
||||
golang.org/x/exp v0.0.0-20200320212757-167ffe94c325/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw=
|
||||
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
|
||||
golang.org/x/image v0.0.0-20190703141733-d6a02ce849c9/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
|
||||
@@ -69,6 +76,8 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d h1:62ap6LNOjDU6uGmKXHJbSfciMoV+FeI1sRXx/pLDL44=
|
||||
golang.org/x/sys v0.0.0-20200317113312-5766fd39f98d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae h1:3tcmuaB7wwSZtelmiv479UjUB+vviwABz7a133ZwOKQ=
|
||||
golang.org/x/sys v0.0.0-20200321134203-328b4cd54aae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190909214602-067311248421/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
|
@@ -32,9 +32,10 @@ type AssetStore struct {
|
||||
entries entryMap
|
||||
|
||||
// These members are used to store things we've already loaded
|
||||
maps map[string]*Map
|
||||
objs map[string]*Object
|
||||
sets map[string]*Set
|
||||
maps map[string]*Map
|
||||
objs map[string]*Object
|
||||
sets map[string]*Set
|
||||
sounds map[string]*Sound
|
||||
}
|
||||
|
||||
// New returns a new AssetStore
|
||||
@@ -82,6 +83,7 @@ func (a *AssetStore) Refresh() error {
|
||||
a.maps = make(map[string]*Map)
|
||||
a.objs = make(map[string]*Object)
|
||||
a.sets = make(map[string]*Set)
|
||||
a.sounds = make(map[string]*Sound)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
78
internal/assetstore/sound.go
Normal file
78
internal/assetstore/sound.go
Normal file
@@ -0,0 +1,78 @@
|
||||
package assetstore
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/audio"
|
||||
"github.com/hajimehoshi/ebiten/audio/vorbis"
|
||||
)
|
||||
|
||||
type Sound struct {
|
||||
Name string
|
||||
|
||||
filename string
|
||||
}
|
||||
|
||||
func (a *AssetStore) Sound(name string) (*Sound, error) {
|
||||
name = canonical(name)
|
||||
|
||||
if sound, ok := a.sounds[name]; ok {
|
||||
return sound, nil
|
||||
}
|
||||
|
||||
// TODO: Data/Sounds.dat + Sounds/wh40k.ds seem to operate together to allow
|
||||
// attributes and a .wav file to be attached to event names, which could be
|
||||
// what we use here instead. For now, we're just using the .wav files!
|
||||
log.Printf("Loading sound %v", name)
|
||||
|
||||
// FIXME: a preprocessing script is used to create these files from the
|
||||
// original ADPCM .wav files. Instead, use the original .wav files.
|
||||
filename, err := a.lookup(name, "wav.ogg", "Wav")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
sound := &Sound{
|
||||
Name: name,
|
||||
filename: filename,
|
||||
}
|
||||
|
||||
a.sounds[name] = sound
|
||||
return sound, nil
|
||||
}
|
||||
|
||||
func (s *Sound) Player() (*audio.Player, error) {
|
||||
decoder, err := s.decoder()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return audio.NewPlayer(audio.CurrentContext(), decoder)
|
||||
}
|
||||
|
||||
func (s *Sound) InfinitePlayer() (*audio.Player, error) {
|
||||
decoder, err := s.decoder()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
infinite := audio.NewInfiniteLoop(decoder, decoder.Size())
|
||||
|
||||
return audio.NewPlayer(audio.CurrentContext(), infinite)
|
||||
}
|
||||
|
||||
func (s *Sound) decoder() (*vorbis.Stream, error) {
|
||||
f, err := os.Open(s.filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
decoder, err := vorbis.Decode(audio.CurrentContext(), f)
|
||||
if err != nil {
|
||||
_ = f.Close()
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return decoder, nil
|
||||
}
|
6
scripts/convert-wav
Executable file
6
scripts/convert-wav
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
for file in $(ls $1/*.wav); do
|
||||
ffmpeg -i $file -codec:a libvorbis $file.ogg
|
||||
done
|
||||
|
Reference in New Issue
Block a user