mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2025-02-20 23:47:16 -05:00
Removed render singleton. Updated refs.
This commit is contained in:
parent
7ce01ab694
commit
5bfec3ccb0
59
d2app/app.go
59
d2app/app.go
@ -29,8 +29,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2inventory"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render/ebiten"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2gamescreen"
|
||||
@ -54,6 +52,7 @@ type App struct {
|
||||
gitCommit string
|
||||
terminal d2interface.Terminal
|
||||
audio d2interface.AudioProvider
|
||||
renderer d2interface.Renderer
|
||||
tAllocSamples *ring.Ring
|
||||
}
|
||||
|
||||
@ -68,12 +67,16 @@ const bytesToMegabyte = 1024 * 1024
|
||||
const nSamplesTAlloc = 100
|
||||
|
||||
// Create creates a new instance of the application
|
||||
func Create(gitBranch, gitCommit string, terminal d2interface.Terminal, audio d2interface.AudioProvider) *App {
|
||||
func Create(gitBranch, gitCommit string,
|
||||
terminal d2interface.Terminal,
|
||||
audio d2interface.AudioProvider,
|
||||
renderer d2interface.Renderer) *App {
|
||||
result := &App{
|
||||
gitBranch: gitBranch,
|
||||
gitCommit: gitCommit,
|
||||
terminal: terminal,
|
||||
audio: audio,
|
||||
renderer: renderer,
|
||||
tAllocSamples: createZeroedRing(nSamplesTAlloc),
|
||||
}
|
||||
|
||||
@ -94,8 +97,8 @@ func (p *App) Run() {
|
||||
|
||||
windowTitle := fmt.Sprintf("OpenDiablo2 (%s)", p.gitBranch)
|
||||
// If we fail to initialize, we will show the error screen
|
||||
if err := p.initialize(p.audio, p.terminal); err != nil {
|
||||
if gameErr := d2render.Run(updateInitError, 800, 600, windowTitle); gameErr != nil {
|
||||
if err := p.initialize(); err != nil {
|
||||
if gameErr := p.renderer.Run(updateInitError, 800, 600, windowTitle); gameErr != nil {
|
||||
log.Fatal(gameErr)
|
||||
}
|
||||
|
||||
@ -104,7 +107,7 @@ func (p *App) Run() {
|
||||
return
|
||||
}
|
||||
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateMainMenu(p.audio, p.terminal))
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateMainMenu(p.renderer, p.audio, p.terminal))
|
||||
|
||||
if p.gitBranch == "" {
|
||||
p.gitBranch = "Local Build"
|
||||
@ -112,12 +115,12 @@ func (p *App) Run() {
|
||||
|
||||
d2common.SetBuildInfo(p.gitBranch, p.gitCommit)
|
||||
|
||||
if err := d2render.Run(p.update, 800, 600, windowTitle); err != nil {
|
||||
if err := p.renderer.Run(p.update, 800, 600, windowTitle); err != nil {
|
||||
log.Panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *App) initialize(audioProvider d2interface.AudioProvider, term d2interface.Terminal) error {
|
||||
func (p *App) initialize() error {
|
||||
p.timeScale = 1.0
|
||||
p.lastTime = d2common.Now()
|
||||
p.lastScreenAdvance = p.lastTime
|
||||
@ -129,17 +132,8 @@ func (p *App) initialize(audioProvider d2interface.AudioProvider, term d2interfa
|
||||
config := d2config.Get()
|
||||
d2resource.LanguageCode = config.Language
|
||||
|
||||
renderer, err := ebiten.CreateRenderer()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := d2render.Initialize(renderer); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d2render.SetWindowIcon("d2logo.png")
|
||||
term.BindLogger()
|
||||
p.renderer.SetWindowIcon("d2logo.png")
|
||||
p.terminal.BindLogger()
|
||||
|
||||
terminalActions := [...]bindTerminalEntry{
|
||||
{"dumpheap", "dumps the heap to pprof/heap.pprof", p.dumpHeap},
|
||||
@ -157,12 +151,12 @@ func (p *App) initialize(audioProvider d2interface.AudioProvider, term d2interfa
|
||||
for idx := range terminalActions {
|
||||
action := &terminalActions[idx]
|
||||
|
||||
if err := term.BindAction(action.name, action.description, action.action); err != nil {
|
||||
if err := p.terminal.BindAction(action.name, action.description, action.action); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
if err := d2asset.Initialize(term); err != nil {
|
||||
if err := d2asset.Initialize(p.renderer, p.terminal); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@ -170,7 +164,7 @@ func (p *App) initialize(audioProvider d2interface.AudioProvider, term d2interfa
|
||||
return err
|
||||
}
|
||||
|
||||
audioProvider.SetVolumes(config.BgmVolume, config.SfxVolume)
|
||||
p.audio.SetVolumes(config.BgmVolume, config.SfxVolume)
|
||||
|
||||
if err := p.loadDataDict(); err != nil {
|
||||
return err
|
||||
@ -182,7 +176,7 @@ func (p *App) initialize(audioProvider d2interface.AudioProvider, term d2interfa
|
||||
|
||||
d2inventory.LoadHeroObjects()
|
||||
|
||||
d2ui.Initialize(audioProvider)
|
||||
d2ui.Initialize(p.audio)
|
||||
|
||||
d2script.CreateScriptEngine()
|
||||
|
||||
@ -263,9 +257,9 @@ func (p *App) renderDebug(target d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
vsyncEnabled := d2render.GetVSyncEnabled()
|
||||
fps := d2render.CurrentFPS()
|
||||
cx, cy := d2render.GetCursorPos()
|
||||
vsyncEnabled := p.renderer.GetVSyncEnabled()
|
||||
fps := p.renderer.CurrentFPS()
|
||||
cx, cy := p.renderer.GetCursorPos()
|
||||
|
||||
target.PushTranslation(5, 565)
|
||||
target.DrawText("vsync:" + strconv.FormatBool(vsyncEnabled) + "\nFPS:" + strconv.Itoa(int(fps)))
|
||||
@ -481,8 +475,8 @@ func (p *App) dumpHeap() {
|
||||
}
|
||||
|
||||
func (p *App) toggleFullScreen() {
|
||||
fullscreen := !d2render.IsFullScreen()
|
||||
d2render.SetFullScreen(fullscreen)
|
||||
fullscreen := !p.renderer.IsFullScreen()
|
||||
p.renderer.SetFullScreen(fullscreen)
|
||||
p.terminal.OutputInfof("fullscreen is now: %v", fullscreen)
|
||||
}
|
||||
|
||||
@ -503,8 +497,8 @@ func (p *App) stopAnimationCapture() {
|
||||
}
|
||||
|
||||
func (p *App) toggleVsync() {
|
||||
vsync := !d2render.GetVSyncEnabled()
|
||||
d2render.SetVSyncEnabled(vsync)
|
||||
vsync := !p.renderer.GetVSyncEnabled()
|
||||
p.renderer.SetVSyncEnabled(vsync)
|
||||
p.terminal.OutputInfof("vsync is now: %v", vsync)
|
||||
}
|
||||
|
||||
@ -527,7 +521,7 @@ func (p *App) quitGame() {
|
||||
}
|
||||
|
||||
func (p *App) enterGuiPlayground() {
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateGuiTestMain())
|
||||
d2screen.SetNextScreen(d2gamescreen.CreateGuiTestMain(p.renderer))
|
||||
}
|
||||
|
||||
func createZeroedRing(n int) *ring.Ring {
|
||||
@ -584,7 +578,8 @@ func enableProfiler(profileOption string) interface{ Stop() } {
|
||||
}
|
||||
|
||||
func updateInitError(target d2interface.Surface) error {
|
||||
target.Clear(colornames.Darkred)
|
||||
_ = target.Clear(colornames.Darkred)
|
||||
|
||||
width, height := target.GetSize()
|
||||
|
||||
target.PushTranslation(width/5, height/2)
|
||||
|
@ -14,8 +14,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dc6"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dcc"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
type playMode int
|
||||
@ -62,7 +60,8 @@ type Animation struct {
|
||||
}
|
||||
|
||||
// CreateAnimationFromDCC creates an animation from d2dcc.DCC and d2dat.DATPalette
|
||||
func CreateAnimationFromDCC(dcc *d2dcc.DCC, palette *d2dat.DATPalette, transparency int) (*Animation, error) {
|
||||
func CreateAnimationFromDCC(renderer d2interface.Renderer, dcc *d2dcc.DCC, palette *d2dat.DATPalette,
|
||||
transparency int) (*Animation, error) {
|
||||
animation := &Animation{
|
||||
playLength: defaultPlayLength,
|
||||
playLoop: true,
|
||||
@ -99,7 +98,7 @@ func CreateAnimationFromDCC(dcc *d2dcc.DCC, palette *d2dat.DATPalette, transpare
|
||||
}
|
||||
}
|
||||
|
||||
sfc, err := d2render.NewSurface(frameWidth, frameHeight, d2interface.FilterNearest)
|
||||
sfc, err := renderer.NewSurface(frameWidth, frameHeight, d2interface.FilterNearest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -127,7 +126,7 @@ func CreateAnimationFromDCC(dcc *d2dcc.DCC, palette *d2dat.DATPalette, transpare
|
||||
}
|
||||
|
||||
// CreateAnimationFromDC6 creates an Animation from d2dc6.DC6 and d2dat.DATPalette
|
||||
func CreateAnimationFromDC6(dc6 *d2dc6.DC6, palette *d2dat.DATPalette) (*Animation, error) {
|
||||
func CreateAnimationFromDC6(renderer d2interface.Renderer, dc6 *d2dc6.DC6, palette *d2dat.DATPalette) (*Animation, error) {
|
||||
animation := &Animation{
|
||||
playLength: defaultPlayLength,
|
||||
playLoop: true,
|
||||
@ -135,7 +134,7 @@ func CreateAnimationFromDC6(dc6 *d2dc6.DC6, palette *d2dat.DATPalette) (*Animati
|
||||
}
|
||||
|
||||
for frameIndex, dc6Frame := range dc6.Frames {
|
||||
sfc, err := d2render.NewSurface(int(dc6Frame.Width), int(dc6Frame.Height), d2interface.FilterNearest)
|
||||
sfc, err := renderer.NewSurface(int(dc6Frame.Width), int(dc6Frame.Height), d2interface.FilterNearest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -396,7 +395,7 @@ func (a *Animation) SetCurrentFrame(frameIndex int) error {
|
||||
|
||||
// Rewind animation to beginning
|
||||
func (a *Animation) Rewind() {
|
||||
a.SetCurrentFrame(0)
|
||||
_ = a.SetCurrentFrame(0)
|
||||
}
|
||||
|
||||
// PlayForward plays animation forward
|
||||
|
@ -5,6 +5,8 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
)
|
||||
|
||||
@ -13,11 +15,15 @@ const (
|
||||
)
|
||||
|
||||
type animationManager struct {
|
||||
cache *d2common.Cache
|
||||
cache *d2common.Cache
|
||||
renderer d2interface.Renderer
|
||||
}
|
||||
|
||||
func createAnimationManager() *animationManager {
|
||||
return &animationManager{d2common.CreateCache(animationBudget)}
|
||||
func createAnimationManager(renderer d2interface.Renderer) *animationManager {
|
||||
return &animationManager{
|
||||
renderer: renderer,
|
||||
cache: d2common.CreateCache(animationBudget),
|
||||
}
|
||||
}
|
||||
|
||||
func (am *animationManager) loadAnimation(animationPath, palettePath string, transparency int) (*Animation, error) {
|
||||
@ -41,7 +47,7 @@ func (am *animationManager) loadAnimation(animationPath, palettePath string, tra
|
||||
return nil, err
|
||||
}
|
||||
|
||||
animation, err = CreateAnimationFromDC6(dc6, palette)
|
||||
animation, err = CreateAnimationFromDC6(am.renderer, dc6, palette)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -56,7 +62,7 @@ func (am *animationManager) loadAnimation(animationPath, palettePath string, tra
|
||||
return nil, err
|
||||
}
|
||||
|
||||
animation, err = CreateAnimationFromDCC(dcc, palette, transparency)
|
||||
animation, err = CreateAnimationFromDCC(am.renderer, dcc, palette, transparency)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -17,14 +17,14 @@ import (
|
||||
var singleton *assetManager
|
||||
|
||||
// Initialize creates and assigns all necessary dependencies for the assetManager top-level functions to work correctly
|
||||
func Initialize(term d2interface.Terminal) error {
|
||||
func Initialize(renderer d2interface.Renderer, term d2interface.Terminal) error {
|
||||
var (
|
||||
config = d2config.Get()
|
||||
archiveManager = createArchiveManager(&config)
|
||||
fileManager = createFileManager(&config, archiveManager)
|
||||
paletteManager = createPaletteManager()
|
||||
paletteTransformManager = createPaletteTransformManager()
|
||||
animationManager = createAnimationManager()
|
||||
animationManager = createAnimationManager(renderer)
|
||||
fontManager = createFontManager()
|
||||
)
|
||||
|
||||
|
@ -23,6 +23,7 @@ func getDefaultConfig() *Configuration {
|
||||
SfxVolume: defaultSfxVolume,
|
||||
BgmVolume: defaultBgmVolume,
|
||||
MpqPath: "C:/Program Files (x86)/Diablo II",
|
||||
Backend: "Ebiten",
|
||||
MpqLoadOrder: []string{
|
||||
"Patch_D2.mpq",
|
||||
"d2exp.mpq",
|
||||
|
@ -16,6 +16,7 @@ type Configuration struct {
|
||||
FullScreen bool
|
||||
RunInBackground bool
|
||||
VsyncEnabled bool
|
||||
Backend string
|
||||
}
|
||||
|
||||
var singleton = getDefaultConfig()
|
||||
@ -27,8 +28,10 @@ func Load() error {
|
||||
}
|
||||
|
||||
var loaded bool
|
||||
|
||||
for _, configPath := range configPaths {
|
||||
log.Printf("loading configuration file from %s...", configPath)
|
||||
|
||||
if err := load(configPath); err == nil {
|
||||
loaded = true
|
||||
break
|
||||
@ -37,6 +40,7 @@ func Load() error {
|
||||
|
||||
if !loaded {
|
||||
log.Println("failed to load configuration file, saving default configuration...")
|
||||
|
||||
if err := Save(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import (
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
type buttonState int
|
||||
@ -29,7 +28,7 @@ type Button struct {
|
||||
surfaces []d2interface.Surface
|
||||
}
|
||||
|
||||
func createButton(text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||
func createButton(renderer d2interface.Renderer, text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||
config, ok := buttonStyleConfigs[buttonStyle]
|
||||
if !ok {
|
||||
return nil, errors.New("invalid button style")
|
||||
@ -73,7 +72,7 @@ func createButton(text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||
surfaceCount := animation.GetFrameCount() / (config.segmentsX * config.segmentsY)
|
||||
surfaces := make([]d2interface.Surface, surfaceCount)
|
||||
for i := 0; i < surfaceCount; i++ {
|
||||
surface, err := d2render.NewSurface(buttonWidth, buttonHeight, d2interface.FilterNearest)
|
||||
surface, err := renderer.NewSurface(buttonWidth, buttonHeight, d2interface.FilterNearest)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -108,17 +107,17 @@ func createButton(text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||
return button, nil
|
||||
}
|
||||
|
||||
func (b *Button) onMouseButtonDown(event d2input.MouseEvent) bool {
|
||||
func (b *Button) onMouseButtonDown(_ d2input.MouseEvent) bool {
|
||||
b.state = buttonStatePressed
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Button) onMouseButtonUp(event d2input.MouseEvent) bool {
|
||||
func (b *Button) onMouseButtonUp(_ d2input.MouseEvent) bool {
|
||||
b.state = buttonStateDefault
|
||||
return false
|
||||
}
|
||||
|
||||
func (b *Button) onMouseLeave(event d2input.MouseMoveEvent) bool {
|
||||
func (b *Button) onMouseLeave(_ d2input.MouseMoveEvent) bool {
|
||||
b.state = buttonStateDefault
|
||||
return false
|
||||
}
|
||||
|
@ -34,9 +34,9 @@ func Advance(elapsed float64) error {
|
||||
return singleton.advance(elapsed)
|
||||
}
|
||||
|
||||
func CreateLayout(positionType PositionType) *Layout {
|
||||
func CreateLayout(renderer d2interface.Renderer, positionType PositionType) *Layout {
|
||||
verifyWasInit()
|
||||
return createLayout(positionType)
|
||||
return createLayout(renderer, positionType)
|
||||
}
|
||||
|
||||
func SetLayout(layout *Layout) {
|
||||
|
@ -3,25 +3,29 @@ package d2gui
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
type Label struct {
|
||||
widgetBase
|
||||
|
||||
text string
|
||||
font *d2asset.Font
|
||||
surface d2interface.Surface
|
||||
renderer d2interface.Renderer
|
||||
text string
|
||||
font *d2asset.Font
|
||||
surface d2interface.Surface
|
||||
}
|
||||
|
||||
func createLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||
func createLabel(renderer d2interface.Renderer, text string, fontStyle FontStyle) (*Label, error) {
|
||||
font, err := loadFont(fontStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
label := &Label{font: font}
|
||||
label.setText(text)
|
||||
label := &Label{
|
||||
font: font,
|
||||
renderer: renderer,
|
||||
}
|
||||
|
||||
_ = label.setText(text)
|
||||
label.SetVisible(true)
|
||||
|
||||
return label, nil
|
||||
@ -48,7 +52,7 @@ func (l *Label) SetText(text string) error {
|
||||
|
||||
func (l *Label) setText(text string) error {
|
||||
width, height := l.font.GetTextMetrics(text)
|
||||
surface, err := d2render.NewSurface(width, height, d2interface.FilterNearest)
|
||||
surface, err := l.renderer.NewSurface(width, height, d2interface.FilterNearest)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -48,6 +48,8 @@ const (
|
||||
type Layout struct {
|
||||
widgetBase
|
||||
|
||||
renderer d2interface.Renderer
|
||||
|
||||
width int
|
||||
height int
|
||||
verticalAlign VerticalAlign
|
||||
@ -56,8 +58,12 @@ type Layout struct {
|
||||
entries []*layoutEntry
|
||||
}
|
||||
|
||||
func createLayout(positionType PositionType) *Layout {
|
||||
layout := &Layout{positionType: positionType}
|
||||
func createLayout(renderer d2interface.Renderer, positionType PositionType) *Layout {
|
||||
layout := &Layout{
|
||||
renderer: renderer,
|
||||
positionType: positionType,
|
||||
}
|
||||
|
||||
layout.SetVisible(true)
|
||||
|
||||
return layout
|
||||
@ -77,7 +83,7 @@ func (l *Layout) SetHorizontalAlign(horizontalAlign HorizontalAlign) {
|
||||
}
|
||||
|
||||
func (l *Layout) AddLayout(positionType PositionType) *Layout {
|
||||
layout := createLayout(positionType)
|
||||
layout := createLayout(l.renderer, positionType)
|
||||
l.entries = append(l.entries, &layoutEntry{widget: layout})
|
||||
return layout
|
||||
}
|
||||
@ -115,7 +121,7 @@ func (l *Layout) AddAnimatedSprite(imagePath, palettePath string, direction Anim
|
||||
}
|
||||
|
||||
func (l *Layout) AddLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||
label, err := createLabel(text, fontStyle)
|
||||
label, err := createLabel(l.renderer, text, fontStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -125,7 +131,7 @@ func (l *Layout) AddLabel(text string, fontStyle FontStyle) (*Label, error) {
|
||||
}
|
||||
|
||||
func (l *Layout) AddButton(text string, buttonStyle ButtonStyle) (*Button, error) {
|
||||
button, err := createButton(text, buttonStyle)
|
||||
button, err := createButton(l.renderer, text, buttonStyle)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -1,22 +1,19 @@
|
||||
package d2mapentity
|
||||
|
||||
import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
// Object represents a composite of animations that can be projected onto the map.
|
||||
type Object struct {
|
||||
mapEntity
|
||||
composite *d2asset.Composite
|
||||
direction int
|
||||
highlight bool
|
||||
nameLabel d2ui.Label
|
||||
composite *d2asset.Composite
|
||||
direction int
|
||||
highlight bool
|
||||
// nameLabel d2ui.Label
|
||||
objectLookup *d2datadict.ObjectLookupRecord
|
||||
objectRecord *d2datadict.ObjectRecord
|
||||
objectType *d2datadict.ObjectTypeRecord
|
||||
@ -28,7 +25,7 @@ func CreateObject(x, y int, objectRec *d2datadict.ObjectRecord, palettePath stri
|
||||
mapEntity: createMapEntity(x, y),
|
||||
objectRecord: objectRec,
|
||||
objectType: &d2datadict.ObjectTypes[objectRec.Index],
|
||||
nameLabel: d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic),
|
||||
// nameLabel: d2ui.CreateLabel(renderer, d2resource.FontFormal11, d2resource.PaletteStatic),
|
||||
}
|
||||
|
||||
object := &d2datadict.ObjectLookupRecord{
|
||||
@ -118,9 +115,9 @@ func (ob *Object) Render(target d2interface.Surface) {
|
||||
)
|
||||
|
||||
if ob.highlight {
|
||||
ob.nameLabel.SetText(d2common.TranslateString(ob.objectRecord.Name))
|
||||
ob.nameLabel.SetPosition(-50, -50)
|
||||
ob.nameLabel.Render(target)
|
||||
// ob.nameLabel.SetText(d2common.TranslateString(ob.objectRecord.Name))
|
||||
// ob.nameLabel.SetPosition(-50, -50)
|
||||
// ob.nameLabel.Render(target)
|
||||
target.PushBrightness(2)
|
||||
defer target.Pop()
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
package d2mapentity
|
||||
|
||||
import (
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||
@ -11,19 +9,18 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2inventory"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
type Player struct {
|
||||
mapEntity
|
||||
composite *d2asset.Composite
|
||||
Equipment d2inventory.CharacterEquipment
|
||||
Stats d2hero.HeroStatsState
|
||||
Class d2enum.Hero
|
||||
Id string
|
||||
direction int
|
||||
name string
|
||||
nameLabel d2ui.Label
|
||||
composite *d2asset.Composite
|
||||
Equipment d2inventory.CharacterEquipment
|
||||
Stats d2hero.HeroStatsState
|
||||
Class d2enum.Hero
|
||||
Id string
|
||||
direction int
|
||||
name string
|
||||
// nameLabel d2ui.Label
|
||||
lastPathSize int
|
||||
isInTown bool
|
||||
animationMode string
|
||||
@ -62,24 +59,24 @@ func CreatePlayer(id, name string, x, y int, direction int, heroType d2enum.Hero
|
||||
stats.Stamina = stats.MaxStamina
|
||||
|
||||
result := &Player{
|
||||
Id: id,
|
||||
mapEntity: createMapEntity(x, y),
|
||||
composite: composite,
|
||||
Equipment: equipment,
|
||||
Stats: stats,
|
||||
direction: direction,
|
||||
name: name,
|
||||
Class: heroType,
|
||||
nameLabel: d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic),
|
||||
Id: id,
|
||||
mapEntity: createMapEntity(x, y),
|
||||
composite: composite,
|
||||
Equipment: equipment,
|
||||
Stats: stats,
|
||||
direction: direction,
|
||||
name: name,
|
||||
Class: heroType,
|
||||
//nameLabel: d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic),
|
||||
isRunToggled: true,
|
||||
isInTown: true,
|
||||
isRunning: true,
|
||||
}
|
||||
result.SetSpeed(baseRunSpeed)
|
||||
result.mapEntity.directioner = result.rotate
|
||||
result.nameLabel.Alignment = d2ui.LabelAlignCenter
|
||||
result.nameLabel.SetText(name)
|
||||
result.nameLabel.Color = color.White
|
||||
//result.nameLabel.Alignment = d2ui.LabelAlignCenter
|
||||
//result.nameLabel.SetText(name)
|
||||
//result.nameLabel.Color = color.White
|
||||
err = result.SetMode(d2enum.AnimationModePlayerTownNeutral.String(), equipment.RightHand.GetWeaponClass(), direction)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -6,19 +6,18 @@ import (
|
||||
"log"
|
||||
"math"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dat"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map/d2mapengine"
|
||||
)
|
||||
|
||||
// The map renderer, used to render the map
|
||||
type MapRenderer struct {
|
||||
renderer d2interface.Renderer // The renderer to use for drawing operations
|
||||
mapEngine *d2mapengine.MapEngine // The map engine that is being rendered
|
||||
palette *d2dat.DATPalette // The palette used for this map
|
||||
viewport *Viewport // The viewport for the map renderer (used for rendering offsets)
|
||||
@ -29,8 +28,9 @@ type MapRenderer struct {
|
||||
}
|
||||
|
||||
// Creates an instance of the map renderer
|
||||
func CreateMapRenderer(mapEngine *d2mapengine.MapEngine, term d2interface.Terminal) *MapRenderer {
|
||||
func CreateMapRenderer(renderer d2interface.Renderer, mapEngine *d2mapengine.MapEngine, term d2interface.Terminal) *MapRenderer {
|
||||
result := &MapRenderer{
|
||||
renderer: renderer,
|
||||
mapEngine: mapEngine,
|
||||
viewport: NewViewport(0, 0, 800, 600),
|
||||
}
|
||||
|
@ -3,14 +3,11 @@ package d2maprenderer
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2ds1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
func (mr *MapRenderer) generateTileCache() {
|
||||
@ -76,10 +73,10 @@ func (mr *MapRenderer) generateFloorCache(tile *d2ds1.FloorShadowRecord, tileX,
|
||||
}
|
||||
tileYOffset := d2common.AbsInt32(tileYMinimum)
|
||||
tileHeight := d2common.AbsInt32(tileData[i].Height)
|
||||
image, _ := d2render.NewSurface(int(tileData[i].Width), int(tileHeight), d2interface.FilterNearest)
|
||||
image, _ := mr.renderer.NewSurface(int(tileData[i].Width), int(tileHeight), d2interface.FilterNearest)
|
||||
pixels := make([]byte, 4*tileData[i].Width*tileHeight)
|
||||
mr.decodeTileGfxData(tileData[i].Blocks, &pixels, tileYOffset, tileData[i].Width)
|
||||
image.ReplacePixels(pixels)
|
||||
_ = image.ReplacePixels(pixels)
|
||||
mr.setImageCacheRecord(tile.Style, tile.Sequence, 0, tileIndex, image)
|
||||
}
|
||||
}
|
||||
@ -115,10 +112,10 @@ func (mr *MapRenderer) generateShadowCache(tile *d2ds1.FloorShadowRecord, tileX,
|
||||
return
|
||||
}
|
||||
|
||||
image, _ := d2render.NewSurface(int(tileData.Width), tileHeight, d2interface.FilterNearest)
|
||||
image, _ := mr.renderer.NewSurface(int(tileData.Width), tileHeight, d2interface.FilterNearest)
|
||||
pixels := make([]byte, 4*tileData.Width*int32(tileHeight))
|
||||
mr.decodeTileGfxData(tileData.Blocks, &pixels, tileYOffset, tileData.Width)
|
||||
image.ReplacePixels(pixels)
|
||||
_ = image.ReplacePixels(pixels)
|
||||
mr.setImageCacheRecord(tile.Style, tile.Sequence, 13, tileIndex, image)
|
||||
}
|
||||
|
||||
@ -176,8 +173,9 @@ func (mr *MapRenderer) generateWallCache(tile *d2ds1.WallRecord, tileX, tileY in
|
||||
return
|
||||
}
|
||||
|
||||
image, _ := d2render.NewSurface(160, int(realHeight), d2interface.FilterNearest)
|
||||
image, _ := mr.renderer.NewSurface(160, int(realHeight), d2interface.FilterNearest)
|
||||
pixels := make([]byte, 4*160*realHeight)
|
||||
|
||||
mr.decodeTileGfxData(tileData.Blocks, &pixels, tileYOffset, 160)
|
||||
|
||||
if newTileData != nil {
|
||||
|
@ -139,7 +139,8 @@ func (mr *Stamp) Entities(tileOffsetX, tileOffsetY int) []d2mapentity.MapEntity
|
||||
objectRecord := d2datadict.Objects[lookup.ObjectsTxtId]
|
||||
|
||||
if objectRecord != nil {
|
||||
entity, err := d2mapentity.CreateObject((tileOffsetX*5)+object.X, (tileOffsetY*5)+object.Y, objectRecord, d2resource.PaletteUnits)
|
||||
entity, err := d2mapentity.CreateObject((tileOffsetX*5)+object.X,
|
||||
(tileOffsetY*5)+object.Y, objectRecord, d2resource.PaletteUnits)
|
||||
|
||||
if err != nil {
|
||||
panic(err)
|
||||
|
@ -1,106 +0,0 @@
|
||||
package d2render
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
)
|
||||
|
||||
var (
|
||||
// ErrWasInit holding an error instance for initialized rendering system
|
||||
ErrWasInit = errors.New("rendering system is already initialized")
|
||||
// ErrNotInit holding an error instance for non-initialized rendering system
|
||||
ErrNotInit = errors.New("rendering system has not been initialized")
|
||||
// ErrInvalidRenderer holding an error instance for invalid rendering system specification
|
||||
ErrInvalidRenderer = errors.New("invalid rendering system specified")
|
||||
)
|
||||
|
||||
var singleton d2interface.Renderer
|
||||
|
||||
// Initialize the renderer
|
||||
func Initialize(rend d2interface.Renderer) error {
|
||||
verifyNotInit()
|
||||
singleton = rend
|
||||
log.Printf("Initialized the %s renderer...", singleton.GetRendererName())
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetWindowIcon sets the window icon by a given file name as string
|
||||
func SetWindowIcon(fileName string) {
|
||||
verifyWasInit()
|
||||
singleton.SetWindowIcon(fileName)
|
||||
}
|
||||
|
||||
// Run will run the renderer
|
||||
func Run(f func(d2interface.Surface) error, width, height int, title string) error {
|
||||
verifyWasInit()
|
||||
singleton.Run(f, width, height, title)
|
||||
return nil
|
||||
}
|
||||
|
||||
// IsDrawingSkipped checks whether the drawing is skipped
|
||||
func IsDrawingSkipped() bool {
|
||||
verifyWasInit()
|
||||
return singleton.IsDrawingSkipped()
|
||||
}
|
||||
|
||||
// CreateSurface creates a new surface, which returns the newly created surface or error
|
||||
func CreateSurface(surface d2interface.Surface) (d2interface.Surface, error) {
|
||||
verifyWasInit()
|
||||
return singleton.CreateSurface(surface)
|
||||
}
|
||||
|
||||
// NewSurface adds a new surface, and returns the new surface or error
|
||||
func NewSurface(width, height int, filter d2interface.Filter) (d2interface.Surface, error) {
|
||||
verifyWasInit()
|
||||
return singleton.NewSurface(width, height, filter)
|
||||
}
|
||||
|
||||
// IsFullScreen checks whether the window is on full screen
|
||||
func IsFullScreen() bool {
|
||||
verifyWasInit()
|
||||
return singleton.IsFullScreen()
|
||||
}
|
||||
|
||||
// SetFullScreen sets the window in fullscreen or windowed mode depending on the fullScreen flag
|
||||
func SetFullScreen(fullScreen bool) {
|
||||
verifyWasInit()
|
||||
singleton.SetFullScreen(fullScreen)
|
||||
}
|
||||
|
||||
// SetVSyncEnabled sets or unsets the VSync depending on the given vsync parameter flag
|
||||
func SetVSyncEnabled(vsync bool) {
|
||||
verifyWasInit()
|
||||
singleton.SetVSyncEnabled(vsync)
|
||||
}
|
||||
|
||||
// GetVSyncEnabled checks whether the VSync is enabled or not
|
||||
func GetVSyncEnabled() bool {
|
||||
verifyWasInit()
|
||||
return singleton.GetVSyncEnabled()
|
||||
}
|
||||
|
||||
// GetCursorPos returns the exact current position of the cursor
|
||||
func GetCursorPos() (int, int) {
|
||||
verifyWasInit()
|
||||
return singleton.GetCursorPos()
|
||||
}
|
||||
|
||||
// CurrentFPS returns the current frames per second
|
||||
func CurrentFPS() float64 {
|
||||
verifyWasInit()
|
||||
return singleton.CurrentFPS()
|
||||
}
|
||||
|
||||
func verifyWasInit() {
|
||||
if singleton == nil {
|
||||
panic(ErrNotInit)
|
||||
}
|
||||
}
|
||||
|
||||
func verifyNotInit() {
|
||||
if singleton != nil {
|
||||
panic(ErrWasInit)
|
||||
}
|
||||
}
|
@ -5,14 +5,9 @@ import (
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
)
|
||||
|
||||
// ButtonType defines the type of button
|
||||
@ -107,7 +102,7 @@ type Button struct {
|
||||
}
|
||||
|
||||
// CreateButton creates an instance of Button
|
||||
func CreateButton(buttonType ButtonType, text string) Button {
|
||||
func CreateButton(renderer d2interface.Renderer, buttonType ButtonType, text string) Button {
|
||||
result := Button{
|
||||
width: 0,
|
||||
height: 0,
|
||||
@ -131,7 +126,7 @@ func CreateButton(buttonType ButtonType, text string) Button {
|
||||
result.height += h
|
||||
}
|
||||
|
||||
result.normalSurface, _ = d2render.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
result.normalSurface, _ = renderer.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
_, fontHeight := font.GetTextMetrics(text)
|
||||
textY := (result.height / 2) - (fontHeight / 2) + buttonLayout.TextOffset
|
||||
|
||||
@ -141,22 +136,22 @@ func CreateButton(buttonType ButtonType, text string) Button {
|
||||
font.Render(0, textY, text, color.RGBA{R: 100, G: 100, B: 100, A: 255}, result.normalSurface)
|
||||
if buttonLayout.AllowFrameChange {
|
||||
if totalButtonTypes > 1 {
|
||||
result.pressedSurface, _ = d2render.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
result.pressedSurface, _ = renderer.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
buttonSprite.RenderSegmented(result.pressedSurface, buttonLayout.XSegments, buttonLayout.YSegments, buttonLayout.BaseFrame+1)
|
||||
font.Render(-2, textY+2, text, color.RGBA{R: 100, G: 100, B: 100, A: 255}, result.pressedSurface)
|
||||
}
|
||||
if totalButtonTypes > 2 {
|
||||
result.toggledSurface, _ = d2render.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
result.toggledSurface, _ = renderer.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
buttonSprite.RenderSegmented(result.toggledSurface, buttonLayout.XSegments, buttonLayout.YSegments, buttonLayout.BaseFrame+2)
|
||||
font.Render(0, textY, text, color.RGBA{R: 100, G: 100, B: 100, A: 255}, result.toggledSurface)
|
||||
}
|
||||
if totalButtonTypes > 3 {
|
||||
result.pressedToggledSurface, _ = d2render.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
result.pressedToggledSurface, _ = renderer.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
buttonSprite.RenderSegmented(result.pressedToggledSurface, buttonLayout.XSegments, buttonLayout.YSegments, buttonLayout.BaseFrame+3)
|
||||
font.Render(0, textY, text, color.RGBA{R: 100, G: 100, B: 100, A: 255}, result.pressedToggledSurface)
|
||||
}
|
||||
if buttonLayout.DisabledFrame != -1 {
|
||||
result.disabledSurface, _ = d2render.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
result.disabledSurface, _ = renderer.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
buttonSprite.RenderSegmented(result.disabledSurface, buttonLayout.XSegments, buttonLayout.YSegments, buttonLayout.DisabledFrame)
|
||||
font.Render(0, textY, text, color.RGBA{R: 100, G: 100, B: 100, A: 255}, result.disabledSurface)
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
type Checkbox struct {
|
||||
@ -19,7 +18,7 @@ type Checkbox struct {
|
||||
enabled bool
|
||||
}
|
||||
|
||||
func CreateCheckbox(checkState bool) Checkbox {
|
||||
func CreateCheckbox(renderer d2interface.Renderer, checkState bool) Checkbox {
|
||||
result := Checkbox{
|
||||
checkState: checkState,
|
||||
visible: true,
|
||||
@ -33,11 +32,13 @@ func CreateCheckbox(checkState bool) Checkbox {
|
||||
result.width, result.height, _ = checkboxSprite.GetFrameSize(0)
|
||||
checkboxSprite.SetPosition(0, 0)
|
||||
|
||||
result.Image, _ = d2render.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
checkboxSprite.RenderSegmented(result.Image, 1, 1, 0)
|
||||
result.Image, _ = renderer.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
|
||||
result.checkedImage, _ = d2render.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
checkboxSprite.RenderSegmented(result.checkedImage, 1, 1, 1)
|
||||
_ = checkboxSprite.RenderSegmented(result.Image, 1, 1, 0)
|
||||
|
||||
result.checkedImage, _ = renderer.NewSurface(result.width, result.height, d2interface.FilterNearest)
|
||||
|
||||
_ = checkboxSprite.RenderSegmented(result.checkedImage, 1, 1, 1)
|
||||
return result
|
||||
}
|
||||
|
||||
@ -48,9 +49,9 @@ func (v *Checkbox) Render(target d2interface.Surface) {
|
||||
defer target.PopN(3)
|
||||
|
||||
if v.checkState {
|
||||
target.Render(v.checkedImage)
|
||||
_ = target.Render(v.checkedImage)
|
||||
} else {
|
||||
target.Render(v.Image)
|
||||
_ = target.Render(v.Image)
|
||||
}
|
||||
}
|
||||
|
||||
@ -66,7 +67,7 @@ func (v *Checkbox) SetEnabled(enabled bool) {
|
||||
v.enabled = enabled
|
||||
}
|
||||
|
||||
func (v *Checkbox) SetPressed(pressed bool) {
|
||||
func (v *Checkbox) SetPressed(_ bool) {
|
||||
}
|
||||
|
||||
func (v *Checkbox) SetCheckState(checkState bool) {
|
||||
|
@ -4,10 +4,7 @@ import (
|
||||
"image/color"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2interface"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
)
|
||||
|
||||
// LabelAlignment represents a label's alignment
|
||||
@ -25,6 +22,7 @@ const (
|
||||
// Label represents a user interface label
|
||||
type Label struct {
|
||||
text string
|
||||
renderer d2interface.Renderer
|
||||
X int
|
||||
Y int
|
||||
Width int
|
||||
@ -36,8 +34,9 @@ type Label struct {
|
||||
}
|
||||
|
||||
// CreateLabel creates a new instance of a UI label
|
||||
func CreateLabel(fontPath, palettePath string) Label {
|
||||
func CreateLabel(renderer d2interface.Renderer, fontPath, palettePath string) Label {
|
||||
result := Label{
|
||||
renderer: renderer,
|
||||
Alignment: LabelAlignLeft,
|
||||
Color: color.White,
|
||||
font: GetFont(fontPath, palettePath),
|
||||
@ -66,7 +65,7 @@ func (v *Label) Render(target d2interface.Surface) {
|
||||
target.PushTranslation(x, y)
|
||||
defer target.PopN(3)
|
||||
|
||||
target.Render(v.imageData[v.text])
|
||||
_ = target.Render(v.imageData[v.text])
|
||||
}
|
||||
|
||||
// SetPosition moves the label to the specified location
|
||||
@ -86,8 +85,8 @@ func (v *Label) cacheImage() {
|
||||
width, height := v.font.GetTextMetrics(v.text)
|
||||
v.Width = width
|
||||
v.Height = height
|
||||
v.imageData[v.text], _ = d2render.NewSurface(width, height, d2interface.FilterNearest)
|
||||
surface, _ := d2render.CreateSurface(v.imageData[v.text])
|
||||
v.imageData[v.text], _ = v.renderer.NewSurface(width, height, d2interface.FilterNearest)
|
||||
surface, _ := v.renderer.CreateSurface(v.imageData[v.text])
|
||||
v.font.Render(0, 0, v.text, v.Color, surface)
|
||||
}
|
||||
|
||||
|
@ -27,14 +27,14 @@ type TextBox struct {
|
||||
filter string
|
||||
}
|
||||
|
||||
func CreateTextbox() TextBox {
|
||||
func CreateTextbox(renderer d2interface.Renderer) TextBox {
|
||||
animation, _ := d2asset.LoadAnimation(d2resource.TextBox2, d2resource.PaletteUnits)
|
||||
bgSprite, _ := LoadSprite(animation)
|
||||
tb := TextBox{
|
||||
filter: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
|
||||
bgSprite: bgSprite,
|
||||
textLabel: CreateLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
|
||||
lineBar: CreateLabel(d2resource.FontFormal11, d2resource.PaletteUnits),
|
||||
textLabel: CreateLabel(renderer, d2resource.FontFormal11, d2resource.PaletteUnits),
|
||||
lineBar: CreateLabel(renderer, d2resource.FontFormal11, d2resource.PaletteUnits),
|
||||
enabled: true,
|
||||
visible: true,
|
||||
}
|
||||
|
@ -49,16 +49,19 @@ type CharacterSelect struct {
|
||||
connectionHost string
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
renderer d2interface.Renderer
|
||||
}
|
||||
|
||||
// CreateCharacterSelect creates the character select screen and returns a pointer to it
|
||||
func CreateCharacterSelect(
|
||||
renderer d2interface.Renderer,
|
||||
audioProvider d2interface.AudioProvider,
|
||||
connectionType d2clientconnectiontype.ClientConnectionType,
|
||||
connectionHost string, term d2interface.Terminal,
|
||||
) *CharacterSelect {
|
||||
return &CharacterSelect{
|
||||
selectedCharacter: -1,
|
||||
renderer: renderer,
|
||||
connectionType: connectionType,
|
||||
connectionHost: connectionHost,
|
||||
audioProvider: audioProvider,
|
||||
@ -82,13 +85,13 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
|
||||
|
||||
v.createButtons(loading)
|
||||
|
||||
v.d2HeroTitle = d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteUnits)
|
||||
v.d2HeroTitle = d2ui.CreateLabel(v.renderer, d2resource.Font42, d2resource.PaletteUnits)
|
||||
v.d2HeroTitle.SetPosition(320, 23)
|
||||
v.d2HeroTitle.Alignment = d2ui.LabelAlignCenter
|
||||
|
||||
loading.Progress(0.3)
|
||||
|
||||
v.deleteCharConfirmLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.deleteCharConfirmLabel = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
lines := d2common.SplitIntoLinesWithMaxWidth(
|
||||
"Are you sure that you want to delete this character? Take note: this will delete all versions of this Character.",
|
||||
29,
|
||||
@ -116,12 +119,12 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
|
||||
xOffset = 385
|
||||
}
|
||||
|
||||
v.characterNameLabel[i] = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.characterNameLabel[i] = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.characterNameLabel[i].Color = color.RGBA{R: 188, G: 168, B: 140, A: 255}
|
||||
v.characterNameLabel[i].SetPosition(xOffset, 100+((i/2)*95))
|
||||
v.characterStatsLabel[i] = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.characterStatsLabel[i] = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.characterStatsLabel[i].SetPosition(xOffset, 115+((i/2)*95))
|
||||
v.characterExpLabel[i] = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteStatic)
|
||||
v.characterExpLabel[i] = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteStatic)
|
||||
v.characterExpLabel[i].Color = color.RGBA{R: 24, G: 255, A: 255}
|
||||
v.characterExpLabel[i].SetPosition(xOffset, 130+((i/2)*95))
|
||||
}
|
||||
@ -130,6 +133,7 @@ func (v *CharacterSelect) OnLoad(loading d2screen.LoadingState) {
|
||||
|
||||
func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) {
|
||||
v.newCharButton = d2ui.CreateButton(
|
||||
v.renderer,
|
||||
d2ui.ButtonTypeTall,
|
||||
d2common.CombineStrings(d2common.SplitIntoLinesWithMaxWidth("CREATE NEW CHARACTER", 15)),
|
||||
)
|
||||
@ -138,6 +142,7 @@ func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) {
|
||||
d2ui.AddWidget(&v.newCharButton)
|
||||
|
||||
v.convertCharButton = d2ui.CreateButton(
|
||||
v.renderer,
|
||||
d2ui.ButtonTypeTall,
|
||||
d2common.CombineStrings(d2common.SplitIntoLinesWithMaxWidth("CONVERT TO EXPANSION", 15)),
|
||||
)
|
||||
@ -146,6 +151,7 @@ func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) {
|
||||
d2ui.AddWidget(&v.convertCharButton)
|
||||
|
||||
v.deleteCharButton = d2ui.CreateButton(
|
||||
v.renderer,
|
||||
d2ui.ButtonTypeTall,
|
||||
d2common.CombineStrings(d2common.SplitIntoLinesWithMaxWidth("DELETE CHARACTER", 15)),
|
||||
)
|
||||
@ -153,25 +159,25 @@ func (v *CharacterSelect) createButtons(loading d2screen.LoadingState) {
|
||||
v.deleteCharButton.SetPosition(433, 468)
|
||||
d2ui.AddWidget(&v.deleteCharButton)
|
||||
|
||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, "EXIT")
|
||||
v.exitButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeMedium, "EXIT")
|
||||
v.exitButton.SetPosition(33, 537)
|
||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
d2ui.AddWidget(&v.exitButton)
|
||||
loading.Progress(0.2)
|
||||
|
||||
v.deleteCharCancelButton = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, "NO")
|
||||
v.deleteCharCancelButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeOkCancel, "NO")
|
||||
v.deleteCharCancelButton.SetPosition(282, 308)
|
||||
v.deleteCharCancelButton.SetVisible(false)
|
||||
v.deleteCharCancelButton.OnActivated(func() { v.onDeleteCharacterCancelClicked() })
|
||||
d2ui.AddWidget(&v.deleteCharCancelButton)
|
||||
|
||||
v.deleteCharOkButton = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, "YES")
|
||||
v.deleteCharOkButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeOkCancel, "YES")
|
||||
v.deleteCharOkButton.SetPosition(422, 308)
|
||||
v.deleteCharOkButton.SetVisible(false)
|
||||
v.deleteCharOkButton.OnActivated(func() { v.onDeleteCharacterConfirmClicked() })
|
||||
d2ui.AddWidget(&v.deleteCharOkButton)
|
||||
|
||||
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, "OK")
|
||||
v.okButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeMedium, "OK")
|
||||
v.okButton.SetPosition(625, 537)
|
||||
v.okButton.OnActivated(func() { v.onOkButtonClicked() })
|
||||
d2ui.AddWidget(&v.okButton)
|
||||
@ -209,11 +215,11 @@ func (v *CharacterSelect) updateCharacterBoxes() {
|
||||
}
|
||||
|
||||
func (v *CharacterSelect) onNewCharButtonClicked() {
|
||||
d2screen.SetNextScreen(CreateSelectHeroClass(v.audioProvider, v.connectionType, v.connectionHost, v.terminal))
|
||||
d2screen.SetNextScreen(CreateSelectHeroClass(v.renderer, v.audioProvider, v.connectionType, v.connectionHost, v.terminal))
|
||||
}
|
||||
|
||||
func (v *CharacterSelect) onExitButtonClicked() {
|
||||
mainMenu := CreateMainMenu(v.audioProvider, v.terminal)
|
||||
mainMenu := CreateMainMenu(v.renderer, v.audioProvider, v.terminal)
|
||||
mainMenu.setScreenMode(screenModeMainMenu)
|
||||
d2screen.SetNextScreen(mainMenu)
|
||||
}
|
||||
@ -371,5 +377,5 @@ func (v *CharacterSelect) onOkButtonClicked() {
|
||||
fmt.Printf("can not connect to the host: %s", host)
|
||||
}
|
||||
|
||||
d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient, v.terminal))
|
||||
d2screen.SetNextScreen(CreateGame(v.renderer, v.audioProvider, gameClient, v.terminal))
|
||||
}
|
||||
|
@ -34,17 +34,19 @@ type Credits struct {
|
||||
cycleTime float64
|
||||
cyclesTillNextLine int
|
||||
doneWithCredits bool
|
||||
renderer d2interface.Renderer
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
// CreateCredits creates an instance of the credits screen
|
||||
func CreateCredits(audioProvider d2interface.AudioProvider) *Credits {
|
||||
func CreateCredits(renderer d2interface.Renderer, audioProvider d2interface.AudioProvider) *Credits {
|
||||
result := &Credits{
|
||||
labels: make([]*labelItem, 0),
|
||||
cycleTime: 0,
|
||||
doneWithCredits: false,
|
||||
cyclesTillNextLine: 0,
|
||||
renderer: renderer,
|
||||
audioProvider: audioProvider,
|
||||
}
|
||||
|
||||
@ -83,7 +85,7 @@ func (v *Credits) OnLoad(loading d2screen.LoadingState) {
|
||||
v.creditsBackground.SetPosition(0, 0)
|
||||
loading.Progress(0.2)
|
||||
|
||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, "EXIT")
|
||||
v.exitButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeMedium, "EXIT")
|
||||
v.exitButton.SetPosition(33, 543)
|
||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
d2ui.AddWidget(&v.exitButton)
|
||||
@ -157,7 +159,7 @@ func (v *Credits) Advance(tickTime float64) error {
|
||||
}
|
||||
|
||||
func (v *Credits) onExitButtonClicked() {
|
||||
mainMenu := CreateMainMenu(v.audioProvider, v.terminal)
|
||||
mainMenu := CreateMainMenu(v.renderer, v.audioProvider, v.terminal)
|
||||
mainMenu.setScreenMode(screenModeMainMenu)
|
||||
d2screen.SetNextScreen(mainMenu)
|
||||
}
|
||||
@ -254,7 +256,7 @@ func (v *Credits) getNewFontLabel(isHeading bool) *d2ui.Label {
|
||||
newLabelItem := &labelItem{
|
||||
Available: false,
|
||||
IsHeading: isHeading,
|
||||
Label: d2ui.CreateLabel(d2resource.FontFormal10, d2resource.PaletteSky),
|
||||
Label: d2ui.CreateLabel(v.renderer, d2resource.FontFormal10, d2resource.PaletteSky),
|
||||
}
|
||||
|
||||
if isHeading {
|
||||
|
@ -64,9 +64,11 @@ type EscapeMenu struct {
|
||||
currentLayout layoutID
|
||||
|
||||
// leftPent and rightPent are generated once and shared between the layouts
|
||||
leftPent *d2gui.AnimatedSprite
|
||||
rightPent *d2gui.AnimatedSprite
|
||||
layouts []*layout
|
||||
leftPent *d2gui.AnimatedSprite
|
||||
rightPent *d2gui.AnimatedSprite
|
||||
layouts []*layout
|
||||
|
||||
renderer d2interface.Renderer
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
@ -122,10 +124,11 @@ type actionableElement interface {
|
||||
}
|
||||
|
||||
// NewEscapeMenu creates a new escape menu
|
||||
func NewEscapeMenu(audioProvider d2interface.AudioProvider, term d2interface.Terminal) *EscapeMenu {
|
||||
func NewEscapeMenu(renderer d2interface.Renderer, audioProvider d2interface.AudioProvider, term d2interface.Terminal) *EscapeMenu {
|
||||
m := &EscapeMenu{
|
||||
audioProvider: audioProvider,
|
||||
terminal: term,
|
||||
renderer: renderer,
|
||||
}
|
||||
|
||||
m.layouts = []*layout{
|
||||
@ -204,7 +207,7 @@ func (m *EscapeMenu) newConfigureControlsLayout() *layout {
|
||||
}
|
||||
|
||||
func (m *EscapeMenu) wrapLayout(fn func(*layout)) *layout {
|
||||
wrapper := d2gui.CreateLayout(d2gui.PositionTypeHorizontal)
|
||||
wrapper := d2gui.CreateLayout(m.renderer, d2gui.PositionTypeHorizontal)
|
||||
wrapper.SetVerticalAlign(d2gui.VerticalAlignMiddle)
|
||||
wrapper.AddSpacerDynamic()
|
||||
|
||||
@ -365,7 +368,7 @@ func (m *EscapeMenu) showLayout(id layoutID) {
|
||||
}
|
||||
|
||||
if id == saveLayoutID {
|
||||
mainMenu := CreateMainMenu(m.audioProvider, m.terminal)
|
||||
mainMenu := CreateMainMenu(m.renderer, m.audioProvider, m.terminal)
|
||||
mainMenu.setScreenMode(screenModeMainMenu)
|
||||
d2screen.SetNextScreen(mainMenu)
|
||||
|
||||
|
@ -25,38 +25,42 @@ type Game struct {
|
||||
gameControls *d2player.GameControls // TODO: Hack
|
||||
localPlayer *d2mapentity.Player
|
||||
lastRegionType d2enum.RegionIdType
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
ticksSinceLevelCheck float64
|
||||
escapeMenu *EscapeMenu
|
||||
|
||||
renderer d2interface.Renderer
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
func CreateGame(audioProvider d2interface.AudioProvider, gameClient *d2client.GameClient, term d2interface.Terminal) *Game {
|
||||
func CreateGame(renderer d2interface.Renderer, audioProvider d2interface.AudioProvider, gameClient *d2client.GameClient,
|
||||
term d2interface.Terminal) *Game {
|
||||
result := &Game{
|
||||
gameClient: gameClient,
|
||||
gameControls: nil,
|
||||
localPlayer: nil,
|
||||
lastRegionType: d2enum.RegionNone,
|
||||
ticksSinceLevelCheck: 0,
|
||||
mapRenderer: d2maprenderer.CreateMapRenderer(gameClient.MapEngine, term),
|
||||
escapeMenu: NewEscapeMenu(audioProvider, term),
|
||||
mapRenderer: d2maprenderer.CreateMapRenderer(renderer, gameClient.MapEngine, term),
|
||||
escapeMenu: NewEscapeMenu(renderer, audioProvider, term),
|
||||
audioProvider: audioProvider,
|
||||
renderer: renderer,
|
||||
terminal: term,
|
||||
}
|
||||
result.escapeMenu.onLoad()
|
||||
d2input.BindHandler(result.escapeMenu)
|
||||
_ = d2input.BindHandler(result.escapeMenu)
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (v *Game) OnLoad(loading d2screen.LoadingState) {
|
||||
func (v *Game) OnLoad(_ d2screen.LoadingState) {
|
||||
v.audioProvider.PlayBGM("")
|
||||
}
|
||||
|
||||
func (v *Game) OnUnload() error {
|
||||
d2input.UnbindHandler(v.gameControls) // TODO: hack
|
||||
d2input.UnbindHandler(v.escapeMenu) // TODO: hack
|
||||
v.gameClient.Close()
|
||||
_ = d2input.UnbindHandler(v.gameControls) // TODO: hack
|
||||
_ = d2input.UnbindHandler(v.escapeMenu) // TODO: hack
|
||||
_ = v.gameClient.Close()
|
||||
|
||||
return nil
|
||||
}
|
||||
@ -67,7 +71,7 @@ func (v *Game) Render(screen d2interface.Surface) error {
|
||||
v.mapRenderer.RegenerateTileCache()
|
||||
}
|
||||
|
||||
screen.Clear(color.Black)
|
||||
_ = screen.Clear(color.Black)
|
||||
v.mapRenderer.Render(screen)
|
||||
|
||||
if v.gameControls != nil {
|
||||
@ -85,7 +89,7 @@ func (v *Game) Advance(tickTime float64) error {
|
||||
}
|
||||
|
||||
if v.gameControls != nil {
|
||||
v.gameControls.Advance(tickTime)
|
||||
_ = v.gameControls.Advance(tickTime)
|
||||
}
|
||||
|
||||
v.ticksSinceLevelCheck += tickTime
|
||||
@ -118,9 +122,9 @@ func (v *Game) Advance(tickTime float64) error {
|
||||
}
|
||||
|
||||
v.localPlayer = player
|
||||
v.gameControls = d2player.NewGameControls(player, v.gameClient.MapEngine, v.mapRenderer, v, v.terminal)
|
||||
v.gameControls = d2player.NewGameControls(v.renderer, player, v.gameClient.MapEngine, v.mapRenderer, v, v.terminal)
|
||||
v.gameControls.Load()
|
||||
d2input.BindHandler(v.gameControls)
|
||||
_ = d2input.BindHandler(v.gameControls)
|
||||
|
||||
break
|
||||
}
|
||||
@ -138,9 +142,9 @@ func (v *Game) Advance(tickTime float64) error {
|
||||
func (v *Game) OnPlayerMove(x, y float64) {
|
||||
heroPosX := v.localPlayer.LocationX / 5.0
|
||||
heroPosY := v.localPlayer.LocationY / 5.0
|
||||
v.gameClient.SendPacketToServer(d2netpacket.CreateMovePlayerPacket(v.gameClient.PlayerId, heroPosX, heroPosY, x, y))
|
||||
_ = v.gameClient.SendPacketToServer(d2netpacket.CreateMovePlayerPacket(v.gameClient.PlayerId, heroPosX, heroPosY, x, y))
|
||||
}
|
||||
|
||||
func (v *Game) OnPlayerCast(missleID int, targetX, targetY float64) {
|
||||
v.gameClient.SendPacketToServer(d2netpacket.CreateCastPacket(v.gameClient.PlayerId, missleID, targetX, targetY))
|
||||
_ = v.gameClient.SendPacketToServer(d2netpacket.CreateCastPacket(v.gameClient.PlayerId, missleID, targetX, targetY))
|
||||
}
|
||||
|
@ -6,47 +6,51 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2screen"
|
||||
)
|
||||
|
||||
type GuiTestMain struct{}
|
||||
type GuiTestMain struct {
|
||||
renderer d2interface.Renderer
|
||||
}
|
||||
|
||||
func CreateGuiTestMain() *GuiTestMain {
|
||||
return &GuiTestMain{}
|
||||
func CreateGuiTestMain(renderer d2interface.Renderer) *GuiTestMain {
|
||||
return &GuiTestMain{
|
||||
renderer: renderer,
|
||||
}
|
||||
}
|
||||
|
||||
func (g *GuiTestMain) OnLoad(loading d2screen.LoadingState) {
|
||||
layout := d2gui.CreateLayout(d2gui.PositionTypeHorizontal)
|
||||
layout := d2gui.CreateLayout(g.renderer, d2gui.PositionTypeHorizontal)
|
||||
|
||||
loading.Progress(0.3)
|
||||
//
|
||||
layoutLeft := layout.AddLayout(d2gui.PositionTypeVertical)
|
||||
layoutLeft.SetHorizontalAlign(d2gui.HorizontalAlignCenter)
|
||||
layoutLeft.AddLabel("FontStyle16Units", d2gui.FontStyle16Units)
|
||||
_, _ = layoutLeft.AddLabel("FontStyle16Units", d2gui.FontStyle16Units)
|
||||
layoutLeft.AddSpacerStatic(0, 100)
|
||||
layoutLeft.AddLabel("FontStyle30Units", d2gui.FontStyle30Units)
|
||||
layoutLeft.AddLabel("FontStyle42Units", d2gui.FontStyle42Units)
|
||||
layoutLeft.AddLabel("FontStyleFormal10Static", d2gui.FontStyleFormal10Static)
|
||||
layoutLeft.AddLabel("FontStyleFormal11Units", d2gui.FontStyleFormal11Units)
|
||||
layoutLeft.AddLabel("FontStyleFormal12Static", d2gui.FontStyleFormal12Static)
|
||||
_, _ = layoutLeft.AddLabel("FontStyle30Units", d2gui.FontStyle30Units)
|
||||
_, _ = layoutLeft.AddLabel("FontStyle42Units", d2gui.FontStyle42Units)
|
||||
_, _ = layoutLeft.AddLabel("FontStyleFormal10Static", d2gui.FontStyleFormal10Static)
|
||||
_, _ = layoutLeft.AddLabel("FontStyleFormal11Units", d2gui.FontStyleFormal11Units)
|
||||
_, _ = layoutLeft.AddLabel("FontStyleFormal12Static", d2gui.FontStyleFormal12Static)
|
||||
loading.Progress(0.6)
|
||||
|
||||
layout.AddSpacerDynamic()
|
||||
|
||||
layoutRight := layout.AddLayout(d2gui.PositionTypeVertical)
|
||||
layoutRight.SetHorizontalAlign(d2gui.HorizontalAlignRight)
|
||||
layoutRight.AddButton("Medium", d2gui.ButtonStyleMedium)
|
||||
layoutRight.AddButton("Narrow", d2gui.ButtonStyleNarrow)
|
||||
layoutRight.AddButton("OkCancel", d2gui.ButtonStyleOkCancel)
|
||||
layoutRight.AddButton("Short", d2gui.ButtonStyleShort)
|
||||
layoutRight.AddButton("Wide", d2gui.ButtonStyleWide)
|
||||
_, _ = layoutRight.AddButton("Medium", d2gui.ButtonStyleMedium)
|
||||
_, _ = layoutRight.AddButton("Narrow", d2gui.ButtonStyleNarrow)
|
||||
_, _ = layoutRight.AddButton("OkCancel", d2gui.ButtonStyleOkCancel)
|
||||
_, _ = layoutRight.AddButton("Short", d2gui.ButtonStyleShort)
|
||||
_, _ = layoutRight.AddButton("Wide", d2gui.ButtonStyleWide)
|
||||
loading.Progress(0.9)
|
||||
|
||||
layout.SetVerticalAlign(d2gui.VerticalAlignMiddle)
|
||||
d2gui.SetLayout(layout)
|
||||
}
|
||||
|
||||
func (g *GuiTestMain) Render(screen d2interface.Surface) error {
|
||||
func (g *GuiTestMain) Render(_ d2interface.Surface) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (g *GuiTestMain) Advance(tickTime float64) error {
|
||||
func (g *GuiTestMain) Advance(_ float64) error {
|
||||
return nil
|
||||
}
|
||||
|
@ -69,15 +69,17 @@ type MainMenu struct {
|
||||
tcpJoinGameEntry d2ui.TextBox
|
||||
screenMode mainMenuScreenMode
|
||||
leftButtonHeld bool
|
||||
renderer d2interface.Renderer
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
}
|
||||
|
||||
// CreateMainMenu creates an instance of MainMenu
|
||||
func CreateMainMenu(audioProvider d2interface.AudioProvider, term d2interface.Terminal) *MainMenu {
|
||||
func CreateMainMenu(renderer d2interface.Renderer, audioProvider d2interface.AudioProvider, term d2interface.Terminal) *MainMenu {
|
||||
return &MainMenu{
|
||||
screenMode: screenModeUnknown,
|
||||
leftButtonHeld: true,
|
||||
renderer: renderer,
|
||||
audioProvider: audioProvider,
|
||||
terminal: term,
|
||||
}
|
||||
@ -93,7 +95,7 @@ func (v *MainMenu) OnLoad(loading d2screen.LoadingState) {
|
||||
v.createLogos(loading)
|
||||
v.createButtons(loading)
|
||||
|
||||
v.tcpJoinGameEntry = d2ui.CreateTextbox()
|
||||
v.tcpJoinGameEntry = d2ui.CreateTextbox(v.renderer)
|
||||
v.tcpJoinGameEntry.SetPosition(318, 245)
|
||||
v.tcpJoinGameEntry.SetFilter("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._:")
|
||||
d2ui.AddWidget(&v.tcpJoinGameEntry)
|
||||
@ -129,44 +131,44 @@ func (v *MainMenu) loadBackgroundSprites() {
|
||||
}
|
||||
|
||||
func (v *MainMenu) createLabels(loading d2screen.LoadingState) {
|
||||
v.versionLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||
v.versionLabel = d2ui.CreateLabel(v.renderer, d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||
v.versionLabel.Alignment = d2ui.LabelAlignRight
|
||||
v.versionLabel.SetText("OpenDiablo2 - " + d2common.BuildInfo.Branch)
|
||||
v.versionLabel.Color = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
||||
v.versionLabel.SetPosition(795, -10)
|
||||
|
||||
v.commitLabel = d2ui.CreateLabel(d2resource.FontFormal10, d2resource.PaletteStatic)
|
||||
v.commitLabel = d2ui.CreateLabel(v.renderer, d2resource.FontFormal10, d2resource.PaletteStatic)
|
||||
v.commitLabel.Alignment = d2ui.LabelAlignLeft
|
||||
v.commitLabel.SetText(d2common.BuildInfo.Commit)
|
||||
v.commitLabel.Color = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
||||
v.commitLabel.SetPosition(2, 2)
|
||||
|
||||
v.copyrightLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||
v.copyrightLabel = d2ui.CreateLabel(v.renderer, d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||
v.copyrightLabel.Alignment = d2ui.LabelAlignCenter
|
||||
v.copyrightLabel.SetText("Diablo 2 is © Copyright 2000-2016 Blizzard Entertainment")
|
||||
v.copyrightLabel.Color = color.RGBA{R: 188, G: 168, B: 140, A: 255}
|
||||
v.copyrightLabel.SetPosition(400, 500)
|
||||
loading.Progress(0.3)
|
||||
|
||||
v.copyrightLabel2 = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||
v.copyrightLabel2 = d2ui.CreateLabel(v.renderer, d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||
v.copyrightLabel2.Alignment = d2ui.LabelAlignCenter
|
||||
v.copyrightLabel2.SetText("All Rights Reserved.")
|
||||
v.copyrightLabel2.Color = color.RGBA{R: 188, G: 168, B: 140, A: 255}
|
||||
v.copyrightLabel2.SetPosition(400, 525)
|
||||
|
||||
v.openDiabloLabel = d2ui.CreateLabel(d2resource.FontFormal10, d2resource.PaletteStatic)
|
||||
v.openDiabloLabel = d2ui.CreateLabel(v.renderer, d2resource.FontFormal10, d2resource.PaletteStatic)
|
||||
v.openDiabloLabel.Alignment = d2ui.LabelAlignCenter
|
||||
v.openDiabloLabel.SetText("OpenDiablo2 is neither developed by, nor endorsed by Blizzard or its parent company Activision")
|
||||
v.openDiabloLabel.Color = color.RGBA{R: 255, G: 255, B: 140, A: 255}
|
||||
v.openDiabloLabel.SetPosition(400, 580)
|
||||
loading.Progress(0.5)
|
||||
|
||||
v.tcpIPOptionsLabel = d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteUnits)
|
||||
v.tcpIPOptionsLabel = d2ui.CreateLabel(v.renderer, d2resource.Font42, d2resource.PaletteUnits)
|
||||
v.tcpIPOptionsLabel.SetPosition(400, 23)
|
||||
v.tcpIPOptionsLabel.Alignment = d2ui.LabelAlignCenter
|
||||
v.tcpIPOptionsLabel.SetText("TCP/IP Options")
|
||||
|
||||
v.tcpJoinGameLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.tcpJoinGameLabel = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.tcpJoinGameLabel.Alignment = d2ui.LabelAlignCenter
|
||||
v.tcpJoinGameLabel.SetText(d2common.CombineStrings(
|
||||
d2common.SplitIntoLinesWithMaxWidth("Enter Host IP Address to Join Game", 23)))
|
||||
@ -199,47 +201,47 @@ func (v *MainMenu) createLogos(loading d2screen.LoadingState) {
|
||||
}
|
||||
|
||||
func (v *MainMenu) createButtons(loading d2screen.LoadingState) {
|
||||
v.exitDiabloButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "EXIT DIABLO II")
|
||||
v.exitDiabloButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "EXIT DIABLO II")
|
||||
v.exitDiabloButton.SetPosition(264, 535)
|
||||
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
d2ui.AddWidget(&v.exitDiabloButton)
|
||||
|
||||
v.creditsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, "CREDITS")
|
||||
v.creditsButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeShort, "CREDITS")
|
||||
v.creditsButton.SetPosition(264, 505)
|
||||
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
||||
d2ui.AddWidget(&v.creditsButton)
|
||||
|
||||
v.cinematicsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, "CINEMATICS")
|
||||
v.cinematicsButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeShort, "CINEMATICS")
|
||||
v.cinematicsButton.SetPosition(401, 505)
|
||||
d2ui.AddWidget(&v.cinematicsButton)
|
||||
loading.Progress(0.7)
|
||||
|
||||
v.singlePlayerButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "SINGLE PLAYER")
|
||||
v.singlePlayerButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "SINGLE PLAYER")
|
||||
v.singlePlayerButton.SetPosition(264, 290)
|
||||
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
||||
d2ui.AddWidget(&v.singlePlayerButton)
|
||||
|
||||
v.githubButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "PROJECT WEBSITE")
|
||||
v.githubButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "PROJECT WEBSITE")
|
||||
v.githubButton.SetPosition(264, 400)
|
||||
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
||||
d2ui.AddWidget(&v.githubButton)
|
||||
|
||||
v.mapTestButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "MAP ENGINE TEST")
|
||||
v.mapTestButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "MAP ENGINE TEST")
|
||||
v.mapTestButton.SetPosition(264, 440)
|
||||
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
||||
d2ui.AddWidget(&v.mapTestButton)
|
||||
|
||||
v.btnTCPIPCancel = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("cancel"))
|
||||
v.btnTCPIPCancel = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeMedium, d2common.TranslateString("cancel"))
|
||||
v.btnTCPIPCancel.SetPosition(33, 543)
|
||||
v.btnTCPIPCancel.OnActivated(func() { v.onTCPIPCancelClicked() })
|
||||
d2ui.AddWidget(&v.btnTCPIPCancel)
|
||||
|
||||
v.btnServerIPCancel = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, "CANCEL")
|
||||
v.btnServerIPCancel = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeOkCancel, "CANCEL")
|
||||
v.btnServerIPCancel.SetPosition(285, 305)
|
||||
v.btnServerIPCancel.OnActivated(func() { v.onBtnTCPIPCancelClicked() })
|
||||
d2ui.AddWidget(&v.btnServerIPCancel)
|
||||
|
||||
v.btnServerIPOk = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, "OK")
|
||||
v.btnServerIPOk = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeOkCancel, "OK")
|
||||
v.btnServerIPOk.SetPosition(420, 305)
|
||||
v.btnServerIPOk.OnActivated(func() { v.onBtnTCPIPOkClicked() })
|
||||
d2ui.AddWidget(&v.btnServerIPOk)
|
||||
@ -249,44 +251,46 @@ func (v *MainMenu) createButtons(loading d2screen.LoadingState) {
|
||||
}
|
||||
|
||||
func (v *MainMenu) createMultiplayerMenuButtons() {
|
||||
v.multiplayerButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "MULTIPLAYER")
|
||||
v.multiplayerButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "MULTIPLAYER")
|
||||
v.multiplayerButton.SetPosition(264, 330)
|
||||
v.multiplayerButton.OnActivated(func() { v.onMultiplayerClicked() })
|
||||
d2ui.AddWidget(&v.multiplayerButton)
|
||||
|
||||
v.networkTCPIPButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "TCP/IP GAME")
|
||||
v.networkTCPIPButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "TCP/IP GAME")
|
||||
v.networkTCPIPButton.SetPosition(264, 280)
|
||||
v.networkTCPIPButton.OnActivated(func() { v.onNetworkTCPIPClicked() })
|
||||
d2ui.AddWidget(&v.networkTCPIPButton)
|
||||
|
||||
v.networkCancelButton = d2ui.CreateButton(d2ui.ButtonTypeWide, d2common.TranslateString("cancel"))
|
||||
v.networkCancelButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, d2common.TranslateString("cancel"))
|
||||
v.networkCancelButton.SetPosition(264, 540)
|
||||
v.networkCancelButton.OnActivated(func() { v.onNetworkCancelClicked() })
|
||||
d2ui.AddWidget(&v.networkCancelButton)
|
||||
|
||||
v.btnTCPIPHostGame = d2ui.CreateButton(d2ui.ButtonTypeWide, "HOST GAME")
|
||||
v.btnTCPIPHostGame = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "HOST GAME")
|
||||
v.btnTCPIPHostGame.SetPosition(264, 280)
|
||||
v.btnTCPIPHostGame.OnActivated(func() { v.onTCPIPHostGameClicked() })
|
||||
d2ui.AddWidget(&v.btnTCPIPHostGame)
|
||||
|
||||
v.btnTCPIPJoinGame = d2ui.CreateButton(d2ui.ButtonTypeWide, "JOIN GAME")
|
||||
v.btnTCPIPJoinGame = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeWide, "JOIN GAME")
|
||||
v.btnTCPIPJoinGame.SetPosition(264, 320)
|
||||
v.btnTCPIPJoinGame.OnActivated(func() { v.onTCPIPJoinGameClicked() })
|
||||
d2ui.AddWidget(&v.btnTCPIPJoinGame)
|
||||
}
|
||||
|
||||
func (v *MainMenu) onMapTestClicked() {
|
||||
d2screen.SetNextScreen(CreateMapEngineTest(0, 1, v.terminal))
|
||||
d2screen.SetNextScreen(CreateMapEngineTest(0, 1, v.terminal, v.renderer))
|
||||
}
|
||||
|
||||
func (v *MainMenu) onSinglePlayerClicked() {
|
||||
// Go here only if existing characters are available to select
|
||||
if d2player.HasGameStates() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.renderer, v.audioProvider, d2clientconnectiontype.Local,
|
||||
v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
return
|
||||
}
|
||||
|
||||
d2screen.SetNextScreen(CreateSelectHeroClass(v.audioProvider, d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
d2screen.SetNextScreen(CreateSelectHeroClass(v.renderer, v.audioProvider,
|
||||
d2clientconnectiontype.Local, v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
}
|
||||
|
||||
func (v *MainMenu) onGithubButtonClicked() {
|
||||
@ -315,7 +319,7 @@ func (v *MainMenu) onExitButtonClicked() {
|
||||
}
|
||||
|
||||
func (v *MainMenu) onCreditsButtonClicked() {
|
||||
d2screen.SetNextScreen(CreateCredits(v.audioProvider))
|
||||
d2screen.SetNextScreen(CreateCredits(v.renderer, v.audioProvider))
|
||||
}
|
||||
|
||||
// Render renders the main menu
|
||||
@ -480,7 +484,8 @@ func (v *MainMenu) onTCPIPCancelClicked() {
|
||||
}
|
||||
|
||||
func (v *MainMenu) onTCPIPHostGameClicked() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANServer, "", v.terminal))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.renderer, v.audioProvider,
|
||||
d2clientconnectiontype.LANServer, "", v.terminal))
|
||||
}
|
||||
|
||||
func (v *MainMenu) onTCPIPJoinGameClicked() {
|
||||
@ -492,5 +497,6 @@ func (v *MainMenu) onBtnTCPIPCancelClicked() {
|
||||
}
|
||||
|
||||
func (v *MainMenu) onBtnTCPIPOkClicked() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, d2clientconnectiontype.LANClient, v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.renderer, v.audioProvider,
|
||||
d2clientconnectiontype.LANClient, v.tcpJoinGameEntry.GetText(), v.terminal))
|
||||
}
|
||||
|
@ -84,6 +84,7 @@ type MapEngineTest struct {
|
||||
mapEngine *d2mapengine.MapEngine
|
||||
mapRenderer *d2maprenderer.MapRenderer
|
||||
terminal d2interface.Terminal
|
||||
renderer d2interface.Renderer
|
||||
|
||||
//TODO: this is region specific properties, should be refactored for multi-region rendering
|
||||
currentRegion int
|
||||
@ -95,7 +96,7 @@ type MapEngineTest struct {
|
||||
}
|
||||
|
||||
// CreateMapEngineTest creates the Map Engine Test screen and returns a pointer to it
|
||||
func CreateMapEngineTest(currentRegion, levelPreset int, term d2interface.Terminal) *MapEngineTest {
|
||||
func CreateMapEngineTest(currentRegion, levelPreset int, term d2interface.Terminal, renderer d2interface.Renderer) *MapEngineTest {
|
||||
result := &MapEngineTest{
|
||||
currentRegion: currentRegion,
|
||||
levelPreset: levelPreset,
|
||||
@ -103,6 +104,7 @@ func CreateMapEngineTest(currentRegion, levelPreset int, term d2interface.Termin
|
||||
regionSpec: regionSpec{},
|
||||
filesCount: 0,
|
||||
terminal: term,
|
||||
renderer: renderer,
|
||||
}
|
||||
result.gameState = d2player.CreateTestGameState()
|
||||
|
||||
@ -165,7 +167,7 @@ func (met *MapEngineTest) OnLoad(loading d2screen.LoadingState) {
|
||||
|
||||
loading.Progress(0.5)
|
||||
|
||||
met.mapRenderer = d2maprenderer.CreateMapRenderer(met.mapEngine, met.terminal)
|
||||
met.mapRenderer = d2maprenderer.CreateMapRenderer(met.renderer, met.mapEngine, met.terminal)
|
||||
|
||||
loading.Progress(0.7)
|
||||
met.loadRegionByIndex(met.currentRegion, met.levelPreset, met.fileIndex)
|
||||
|
@ -69,9 +69,11 @@ type SelectHeroClass struct {
|
||||
connectionHost string
|
||||
audioProvider d2interface.AudioProvider
|
||||
terminal d2interface.Terminal
|
||||
renderer d2interface.Renderer
|
||||
}
|
||||
|
||||
func CreateSelectHeroClass(
|
||||
renderer d2interface.Renderer,
|
||||
audioProvider d2interface.AudioProvider,
|
||||
connectionType d2clientconnectiontype.ClientConnectionType,
|
||||
connectionHost string,
|
||||
@ -84,6 +86,7 @@ func CreateSelectHeroClass(
|
||||
connectionHost: connectionHost,
|
||||
audioProvider: audioProvider,
|
||||
terminal: terminal,
|
||||
renderer: renderer,
|
||||
}
|
||||
|
||||
return result
|
||||
@ -96,26 +99,26 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
|
||||
v.bgImage = loadSprite(d2resource.CharacterSelectBackground, d2resource.PaletteFechar)
|
||||
v.bgImage.SetPosition(0, 0)
|
||||
|
||||
v.headingLabel = d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||
v.headingLabel = d2ui.CreateLabel(v.renderer, d2resource.Font30, d2resource.PaletteUnits)
|
||||
fontWidth, _ := v.headingLabel.GetSize()
|
||||
v.headingLabel.SetPosition(400-fontWidth/2, 17)
|
||||
v.headingLabel.SetText("Select Hero Class")
|
||||
v.headingLabel.Alignment = d2ui.LabelAlignCenter
|
||||
|
||||
v.heroClassLabel = d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||
v.heroClassLabel = d2ui.CreateLabel(v.renderer, d2resource.Font30, d2resource.PaletteUnits)
|
||||
v.heroClassLabel.Alignment = d2ui.LabelAlignCenter
|
||||
v.heroClassLabel.SetPosition(400, 65)
|
||||
|
||||
v.heroDesc1Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroDesc1Label = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroDesc1Label.Alignment = d2ui.LabelAlignCenter
|
||||
v.heroDesc1Label.SetPosition(400, 100)
|
||||
loading.Progress(0.3)
|
||||
|
||||
v.heroDesc2Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroDesc2Label = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroDesc2Label.Alignment = d2ui.LabelAlignCenter
|
||||
v.heroDesc2Label.SetPosition(400, 115)
|
||||
|
||||
v.heroDesc3Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroDesc3Label = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroDesc3Label.Alignment = d2ui.LabelAlignCenter
|
||||
v.heroDesc3Label.SetPosition(400, 130)
|
||||
|
||||
@ -124,47 +127,47 @@ func (v *SelectHeroClass) OnLoad(loading d2screen.LoadingState) {
|
||||
v.campfire.PlayForward()
|
||||
v.campfire.SetBlend(true)
|
||||
|
||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, "EXIT")
|
||||
v.exitButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeMedium, "EXIT")
|
||||
v.exitButton.SetPosition(33, 537)
|
||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||
d2ui.AddWidget(&v.exitButton)
|
||||
|
||||
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, "OK")
|
||||
v.okButton = d2ui.CreateButton(v.renderer, d2ui.ButtonTypeMedium, "OK")
|
||||
v.okButton.SetPosition(630, 537)
|
||||
v.okButton.OnActivated(func() { v.onOkButtonClicked() })
|
||||
v.okButton.SetVisible(false)
|
||||
v.okButton.SetEnabled(false)
|
||||
d2ui.AddWidget(&v.okButton)
|
||||
|
||||
v.heroNameLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroNameLabel = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.heroNameLabel.Alignment = d2ui.LabelAlignLeft
|
||||
v.heroNameLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
||||
v.heroNameLabel.SetText("Character Name")
|
||||
v.heroNameLabel.SetPosition(321, 475)
|
||||
loading.Progress(0.4)
|
||||
|
||||
v.heroNameTextbox = d2ui.CreateTextbox()
|
||||
v.heroNameTextbox = d2ui.CreateTextbox(v.renderer)
|
||||
v.heroNameTextbox.SetPosition(318, 493)
|
||||
v.heroNameTextbox.SetVisible(false)
|
||||
d2ui.AddWidget(&v.heroNameTextbox)
|
||||
|
||||
v.expansionCheckbox = d2ui.CreateCheckbox(true)
|
||||
v.expansionCheckbox = d2ui.CreateCheckbox(v.renderer, true)
|
||||
v.expansionCheckbox.SetPosition(318, 526)
|
||||
v.expansionCheckbox.SetVisible(false)
|
||||
d2ui.AddWidget(&v.expansionCheckbox)
|
||||
|
||||
v.expansionCharLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.expansionCharLabel = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.expansionCharLabel.Alignment = d2ui.LabelAlignLeft
|
||||
v.expansionCharLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
||||
v.expansionCharLabel.SetText("EXPANSION CHARACTER")
|
||||
v.expansionCharLabel.SetPosition(339, 526)
|
||||
|
||||
v.hardcoreCheckbox = d2ui.CreateCheckbox(false)
|
||||
v.hardcoreCheckbox = d2ui.CreateCheckbox(v.renderer, false)
|
||||
v.hardcoreCheckbox.SetPosition(318, 548)
|
||||
v.hardcoreCheckbox.SetVisible(false)
|
||||
d2ui.AddWidget(&v.hardcoreCheckbox)
|
||||
|
||||
v.hardcoreCharLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.hardcoreCharLabel = d2ui.CreateLabel(v.renderer, d2resource.Font16, d2resource.PaletteUnits)
|
||||
v.hardcoreCharLabel.Alignment = d2ui.LabelAlignLeft
|
||||
v.hardcoreCharLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
||||
v.hardcoreCharLabel.SetText("Hardcore")
|
||||
@ -440,36 +443,46 @@ func (v *SelectHeroClass) OnUnload() error {
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) onExitButtonClicked() {
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.audioProvider, v.connectionType, v.connectionHost, v.terminal))
|
||||
d2screen.SetNextScreen(CreateCharacterSelect(v.renderer, v.audioProvider, v.connectionType,
|
||||
v.connectionHost, v.terminal))
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) onOkButtonClicked() {
|
||||
gameState := d2player.CreatePlayerState(v.heroNameTextbox.GetText(), v.selectedHero, d2datadict.CharStats[v.selectedHero], v.hardcoreCheckbox.GetCheckState())
|
||||
gameState := d2player.CreatePlayerState(v.heroNameTextbox.GetText(), v.selectedHero,
|
||||
d2datadict.CharStats[v.selectedHero], v.hardcoreCheckbox.GetCheckState())
|
||||
gameClient, _ := d2client.Create(d2clientconnectiontype.Local)
|
||||
gameClient.Open(v.connectionHost, gameState.FilePath)
|
||||
d2screen.SetNextScreen(CreateGame(v.audioProvider, gameClient, v.terminal))
|
||||
|
||||
_ = gameClient.Open(v.connectionHost, gameState.FilePath)
|
||||
d2screen.SetNextScreen(CreateGame(v.renderer, v.audioProvider, gameClient, v.terminal))
|
||||
}
|
||||
|
||||
func (v *SelectHeroClass) Render(screen d2interface.Surface) error {
|
||||
v.bgImage.RenderSegmented(screen, 4, 3, 0)
|
||||
_ = v.bgImage.RenderSegmented(screen, 4, 3, 0)
|
||||
v.headingLabel.Render(screen)
|
||||
|
||||
if v.selectedHero != d2enum.HeroNone {
|
||||
v.heroClassLabel.Render(screen)
|
||||
v.heroDesc1Label.Render(screen)
|
||||
v.heroDesc2Label.Render(screen)
|
||||
v.heroDesc3Label.Render(screen)
|
||||
}
|
||||
|
||||
for heroClass, heroInfo := range v.heroRenderInfo {
|
||||
if heroInfo.Stance == d2enum.HeroStanceIdle || heroInfo.Stance == d2enum.HeroStanceIdleSelected {
|
||||
v.renderHero(screen, heroClass)
|
||||
}
|
||||
}
|
||||
|
||||
for heroClass, heroInfo := range v.heroRenderInfo {
|
||||
if heroInfo.Stance != d2enum.HeroStanceIdle && heroInfo.Stance != d2enum.HeroStanceIdleSelected {
|
||||
v.renderHero(screen, heroClass)
|
||||
}
|
||||
}
|
||||
v.campfire.Render(screen)
|
||||
|
||||
if err := v.campfire.Render(screen); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if v.heroNameTextbox.GetVisible() {
|
||||
v.heroNameLabel.Render(screen)
|
||||
v.expansionCharLabel.Render(screen)
|
||||
@ -481,17 +494,26 @@ func (v *SelectHeroClass) Render(screen d2interface.Surface) error {
|
||||
|
||||
func (v *SelectHeroClass) Advance(tickTime float64) error {
|
||||
canSelect := true
|
||||
v.campfire.Advance(tickTime)
|
||||
for _, info := range v.heroRenderInfo {
|
||||
info.Advance(tickTime)
|
||||
if info.Stance != d2enum.HeroStanceIdle && info.Stance != d2enum.HeroStanceIdleSelected && info.Stance != d2enum.HeroStanceSelected {
|
||||
|
||||
if err := v.campfire.Advance(tickTime); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for infoIdx := range v.heroRenderInfo {
|
||||
v.heroRenderInfo[infoIdx].Advance(tickTime)
|
||||
if v.heroRenderInfo[infoIdx].Stance != d2enum.HeroStanceIdle &&
|
||||
v.heroRenderInfo[infoIdx].Stance != d2enum.HeroStanceIdleSelected &&
|
||||
v.heroRenderInfo[infoIdx].Stance != d2enum.HeroStanceSelected {
|
||||
canSelect = false
|
||||
}
|
||||
}
|
||||
for heroType, _ := range v.heroRenderInfo {
|
||||
v.updateHeroSelectionHover(heroType, canSelect)
|
||||
|
||||
for heroTypeIdx := range v.heroRenderInfo {
|
||||
v.updateHeroSelectionHover(heroTypeIdx, canSelect)
|
||||
}
|
||||
|
||||
v.okButton.SetEnabled(len(v.heroNameTextbox.GetText()) >= 2 && v.selectedHero != d2enum.HeroNone)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -548,10 +570,12 @@ func (v *SelectHeroClass) updateHeroSelectionHover(hero d2enum.Hero, canSelect b
|
||||
}
|
||||
|
||||
if mouseHover && renderInfo.Stance != d2enum.HeroStanceIdleSelected {
|
||||
renderInfo.IdleSelectedSprite.SetCurrentFrame(renderInfo.IdleSprite.GetCurrentFrame())
|
||||
_ = renderInfo.IdleSelectedSprite.SetCurrentFrame(renderInfo.IdleSprite.GetCurrentFrame())
|
||||
|
||||
renderInfo.Stance = d2enum.HeroStanceIdleSelected
|
||||
} else if !mouseHover && renderInfo.Stance != d2enum.HeroStanceIdle {
|
||||
renderInfo.IdleSprite.SetCurrentFrame(renderInfo.IdleSelectedSprite.GetCurrentFrame())
|
||||
_ = renderInfo.IdleSprite.SetCurrentFrame(renderInfo.IdleSelectedSprite.GetCurrentFrame())
|
||||
|
||||
renderInfo.Stance = d2enum.HeroStanceIdle
|
||||
}
|
||||
|
||||
@ -652,13 +676,13 @@ func setSpriteToFirstFrame(sprite *d2ui.Sprite) {
|
||||
|
||||
func drawSprite(sprite *d2ui.Sprite, target d2interface.Surface) {
|
||||
if sprite != nil {
|
||||
sprite.Render(target)
|
||||
_ = sprite.Render(target)
|
||||
}
|
||||
}
|
||||
|
||||
func advanceSprite(sprite *d2ui.Sprite, elapsed float64) {
|
||||
if sprite != nil {
|
||||
sprite.Advance(elapsed)
|
||||
_ = sprite.Advance(elapsed)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -39,15 +39,16 @@ var rightMenuRect = d2common.Rectangle{Left: 400, Top: 0, Width: 400, Height: 60
|
||||
var bottomMenuRect = d2common.Rectangle{Left: 0, Top: 550, Width: 800, Height: 50}
|
||||
|
||||
type GameControls struct {
|
||||
hero *d2mapentity.Player
|
||||
mapEngine *d2mapengine.MapEngine
|
||||
mapRenderer *d2maprenderer.MapRenderer
|
||||
inventory *Inventory
|
||||
heroStatsPanel *HeroStatsPanel
|
||||
inputListener InputCallbackListener
|
||||
FreeCam bool
|
||||
lastMouseX int
|
||||
lastMouseY int
|
||||
renderer d2interface.Renderer // TODO: This shouldn't be a dependency
|
||||
hero *d2mapentity.Player
|
||||
mapEngine *d2mapengine.MapEngine
|
||||
mapRenderer *d2maprenderer.MapRenderer
|
||||
inventory *Inventory
|
||||
heroStatsPanel *HeroStatsPanel
|
||||
inputListener InputCallbackListener
|
||||
FreeCam bool
|
||||
lastMouseX int
|
||||
lastMouseY int
|
||||
|
||||
// UI
|
||||
globeSprite *d2ui.Sprite
|
||||
@ -80,27 +81,29 @@ const (
|
||||
rightSkill = ActionableType(iota)
|
||||
)
|
||||
|
||||
func NewGameControls(hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine, mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener, term d2interface.Terminal) *GameControls {
|
||||
func NewGameControls(renderer d2interface.Renderer, hero *d2mapentity.Player, mapEngine *d2mapengine.MapEngine,
|
||||
mapRenderer *d2maprenderer.MapRenderer, inputListener InputCallbackListener, term d2interface.Terminal) *GameControls {
|
||||
term.BindAction("setmissile", "set missile id to summon on right click", func(id int) {
|
||||
missileID = id
|
||||
})
|
||||
|
||||
zoneLabel := d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||
zoneLabel := d2ui.CreateLabel(renderer, d2resource.Font30, d2resource.PaletteUnits)
|
||||
zoneLabel.Color = color.RGBA{R: 255, G: 88, B: 82, A: 255}
|
||||
zoneLabel.Alignment = d2ui.LabelAlignCenter
|
||||
|
||||
nameLabel := d2ui.CreateLabel(d2resource.FontFormal11, d2resource.PaletteStatic)
|
||||
nameLabel := d2ui.CreateLabel(renderer, d2resource.FontFormal11, d2resource.PaletteStatic)
|
||||
nameLabel.Alignment = d2ui.LabelAlignCenter
|
||||
nameLabel.SetText("")
|
||||
nameLabel.Color = color.White
|
||||
|
||||
gc := &GameControls{
|
||||
renderer: renderer,
|
||||
hero: hero,
|
||||
mapEngine: mapEngine,
|
||||
inputListener: inputListener,
|
||||
mapRenderer: mapRenderer,
|
||||
inventory: NewInventory(),
|
||||
heroStatsPanel: NewHeroStatsPanel(hero.Name(), hero.Class, hero.Stats),
|
||||
heroStatsPanel: NewHeroStatsPanel(renderer, hero.Name(), hero.Class, hero.Stats),
|
||||
nameLabel: &nameLabel,
|
||||
zoneChangeText: &zoneLabel,
|
||||
actionableRegions: []ActionableRegion{
|
||||
@ -269,7 +272,7 @@ func (g *GameControls) Load() {
|
||||
|
||||
func (g *GameControls) loadUIButtons() {
|
||||
// Run button
|
||||
g.runButton = d2ui.CreateButton(d2ui.ButtonTypeRun, "")
|
||||
g.runButton = d2ui.CreateButton(g.renderer, d2ui.ButtonTypeRun, "")
|
||||
g.runButton.SetPosition(255, 570)
|
||||
g.runButton.OnActivated(func() { g.onToggleRunButton() })
|
||||
if g.hero.IsRunToggled() {
|
||||
|
@ -9,7 +9,6 @@ import (
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2hero"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||
)
|
||||
|
||||
@ -74,6 +73,7 @@ type HeroStatsPanel struct {
|
||||
heroState *d2hero.HeroStatsState
|
||||
heroName string
|
||||
heroClass d2enum.Hero
|
||||
renderer d2interface.Renderer
|
||||
staticMenuImageCache *d2interface.Surface
|
||||
labels *StatsPanelLabels
|
||||
|
||||
@ -82,11 +82,13 @@ type HeroStatsPanel struct {
|
||||
isOpen bool
|
||||
}
|
||||
|
||||
func NewHeroStatsPanel(heroName string, heroClass d2enum.Hero, heroState d2hero.HeroStatsState) *HeroStatsPanel {
|
||||
func NewHeroStatsPanel(renderer d2interface.Renderer, heroName string, heroClass d2enum.Hero,
|
||||
heroState d2hero.HeroStatsState) *HeroStatsPanel {
|
||||
originX := 0
|
||||
originY := 0
|
||||
|
||||
return &HeroStatsPanel{
|
||||
renderer: renderer,
|
||||
originX: originX,
|
||||
originY: originY,
|
||||
heroState: &heroState,
|
||||
@ -128,7 +130,7 @@ func (s *HeroStatsPanel) Render(target d2interface.Surface) {
|
||||
if s.staticMenuImageCache == nil {
|
||||
frameWidth, frameHeight := s.frame.GetFrameBounds()
|
||||
framesCount := s.frame.GetFrameCount()
|
||||
surface, err := d2render.NewSurface(frameWidth*framesCount, frameHeight*framesCount, d2interface.FilterNearest)
|
||||
surface, err := s.renderer.NewSurface(frameWidth*framesCount, frameHeight*framesCount, d2interface.FilterNearest)
|
||||
|
||||
if err != nil {
|
||||
return
|
||||
@ -274,7 +276,7 @@ func (s *HeroStatsPanel) createStatValueLabel(stat int, x int, y int) d2ui.Label
|
||||
}
|
||||
|
||||
func (s *HeroStatsPanel) createTextLabel(element PanelText) d2ui.Label {
|
||||
label := d2ui.CreateLabel(element.Font, d2resource.PaletteStatic)
|
||||
label := d2ui.CreateLabel(s.renderer, element.Font, d2resource.PaletteStatic)
|
||||
if element.AlignCenter {
|
||||
label.Alignment = d2ui.LabelAlignCenter
|
||||
}
|
||||
|
3
go.mod
3
go.mod
@ -7,11 +7,12 @@ require (
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
|
||||
github.com/go-restruct/restruct v0.0.0-20191227155143-5734170a48a1
|
||||
github.com/hajimehoshi/ebiten v1.12.0-alpha.6.0.20200629133528-780465b702ce
|
||||
github.com/hajimehoshi/ebiten v1.12.0-alpha.7.0.20200703165837-6c33ed107f28
|
||||
github.com/pkg/profile v1.5.0
|
||||
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff
|
||||
github.com/satori/go.uuid v1.2.0
|
||||
github.com/stretchr/testify v1.4.0
|
||||
github.com/veandco/go-sdl2 v0.4.4 // indirect
|
||||
golang.org/x/image v0.0.0-20200119044424-58c23975cae1
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6
|
||||
gopkg.in/sourcemap.v1 v1.0.5 // indirect
|
||||
|
6
go.sum
6
go.sum
@ -23,6 +23,8 @@ github.com/hajimehoshi/ebiten v1.12.0-alpha.5.0.20200627174955-aea4630b5f84 h1:B
|
||||
github.com/hajimehoshi/ebiten v1.12.0-alpha.5.0.20200627174955-aea4630b5f84/go.mod h1:8vzUI4e0fBkbONYOY4WJN/qikY2zv/VG6kFTzJ0B//o=
|
||||
github.com/hajimehoshi/ebiten v1.12.0-alpha.6.0.20200629133528-780465b702ce h1:cEKWqbtxFremkIRhJxz0Z80wXqNNe8ZNk6ra8XASC1I=
|
||||
github.com/hajimehoshi/ebiten v1.12.0-alpha.6.0.20200629133528-780465b702ce/go.mod h1:8vzUI4e0fBkbONYOY4WJN/qikY2zv/VG6kFTzJ0B//o=
|
||||
github.com/hajimehoshi/ebiten v1.12.0-alpha.7.0.20200703165837-6c33ed107f28 h1:su0k5pB/7j3FCoLsXGoPNWMJW7phujO0GC8sViJ07ow=
|
||||
github.com/hajimehoshi/ebiten v1.12.0-alpha.7.0.20200703165837-6c33ed107f28/go.mod h1:vDl2Rhoz8i09Red8XR3B+/Jw+IubfG+V9SDBgQOEI8I=
|
||||
github.com/hajimehoshi/go-mp3 v0.2.1/go.mod h1:Rr+2P46iH6PwTPVgSsEwBkon0CK5DxCAeX/Rp65DCTE=
|
||||
github.com/hajimehoshi/go-mp3 v0.3.0/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM=
|
||||
github.com/hajimehoshi/oto v0.3.4/go.mod h1:PgjqsBJff0efqL2nlMJidJgVJywLn6M4y8PI4TfeWfA=
|
||||
@ -54,6 +56,8 @@ github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdh
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/veandco/go-sdl2 v0.4.4 h1:coOJGftOdvNvGoUIZmm4XD+ZRQF4mg9ZVHmH3/42zFQ=
|
||||
github.com/veandco/go-sdl2 v0.4.4/go.mod h1:FB+kTpX9YTE+urhYiClnRzpOXbiWgaU3+5F2AB78DPg=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
@ -74,6 +78,8 @@ golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0 h1:nZASbxDuz7CO3227BWCCf0
|
||||
golang.org/x/mobile v0.0.0-20200222142934-3c8601c510d0/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mobile v0.0.0-20200329125638-4c31acba0007 h1:JxsyO7zPDWn1rBZW8FV5RFwCKqYeXnyaS/VQPLpXu6I=
|
||||
golang.org/x/mobile v0.0.0-20200329125638-4c31acba0007/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mobile v0.0.0-20200629153529-33b80540585f h1:9MxnlCHwn6IfUTinHBBzcBhmrX4OXfRmi954tWGKq+M=
|
||||
golang.org/x/mobile v0.0.0-20200629153529-33b80540585f/go.mod h1:skQtrUTUwhdJvXM/2KKJzY8pDgNr9I/FOMqDVRPBUS4=
|
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY=
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/mod v0.1.1-0.20191209134235-331c550502dd/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
|
10
main.go
10
main.go
@ -3,6 +3,8 @@ package main
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render/ebiten"
|
||||
|
||||
"github.com/OpenDiablo2/OpenDiablo2/d2app"
|
||||
|
||||
ebiten_input "github.com/OpenDiablo2/OpenDiablo2/d2core/d2input/ebiten"
|
||||
@ -26,18 +28,24 @@ func main() {
|
||||
log.Println("OpenDiablo2 - Open source Diablo 2 engine")
|
||||
|
||||
// Initialize our providers
|
||||
renderer, err := ebiten.CreateRenderer()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
audio, err := ebiten2.CreateAudio()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
d2input.Initialize(ebiten_input.InputService{}) // TODO d2input singleton must be init before d2term
|
||||
|
||||
term, err := d2term.Initialize()
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
app := d2app.Create(GitBranch, GitCommit, term, audio)
|
||||
app := d2app.Create(GitBranch, GitCommit, term, audio, renderer)
|
||||
app.Run()
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user