mirror of
https://github.com/OpenDiablo2/OpenDiablo2
synced 2024-09-27 21:56:19 -04:00
Scene and GUI rework (#300)
This commit is contained in:
parent
b957661915
commit
5e958b9174
@ -1,10 +1,18 @@
|
|||||||
package d2mpq
|
package d2mpq
|
||||||
|
|
||||||
// CryptoBuffer contains the crypto bytes for filename hashing
|
var cryptoBuffer [0x500]uint32
|
||||||
var CryptoBuffer [0x500]uint32
|
var cryptoBufferReady bool
|
||||||
|
|
||||||
// InitializeCryptoBuffer initializes the crypto buffer
|
func cryptoLookup(index uint32) uint32 {
|
||||||
func InitializeCryptoBuffer() {
|
if !cryptoBufferReady {
|
||||||
|
cryptoInitialize()
|
||||||
|
cryptoBufferReady = true
|
||||||
|
}
|
||||||
|
|
||||||
|
return cryptoBuffer[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
func cryptoInitialize() {
|
||||||
seed := uint32(0x00100001)
|
seed := uint32(0x00100001)
|
||||||
for index1 := 0; index1 < 0x100; index1++ {
|
for index1 := 0; index1 < 0x100; index1++ {
|
||||||
index2 := index1
|
index2 := index1
|
||||||
@ -13,7 +21,7 @@ func InitializeCryptoBuffer() {
|
|||||||
temp1 := (seed & 0xFFFF) << 0x10
|
temp1 := (seed & 0xFFFF) << 0x10
|
||||||
seed = (seed*125 + 3) % 0x2AAAAB
|
seed = (seed*125 + 3) % 0x2AAAAB
|
||||||
temp2 := seed & 0xFFFF
|
temp2 := seed & 0xFFFF
|
||||||
CryptoBuffer[index2] = temp1 | temp2
|
cryptoBuffer[index2] = temp1 | temp2
|
||||||
index2 += 0x100
|
index2 += 0x100
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ func decrypt(data []uint32, seed uint32) {
|
|||||||
seed2 := uint32(0xeeeeeeee)
|
seed2 := uint32(0xeeeeeeee)
|
||||||
|
|
||||||
for i := 0; i < len(data); i++ {
|
for i := 0; i < len(data); i++ {
|
||||||
seed2 += CryptoBuffer[0x400+(seed&0xff)]
|
seed2 += cryptoLookup(0x400 + (seed & 0xff))
|
||||||
result := data[i]
|
result := data[i]
|
||||||
result ^= seed + seed2
|
result ^= seed + seed2
|
||||||
|
|
||||||
@ -215,7 +215,7 @@ func decrypt(data []uint32, seed uint32) {
|
|||||||
func decryptBytes(data []byte, seed uint32) {
|
func decryptBytes(data []byte, seed uint32) {
|
||||||
seed2 := uint32(0xEEEEEEEE)
|
seed2 := uint32(0xEEEEEEEE)
|
||||||
for i := 0; i < len(data)-3; i += 4 {
|
for i := 0; i < len(data)-3; i += 4 {
|
||||||
seed2 += CryptoBuffer[0x400+(seed&0xFF)]
|
seed2 += cryptoLookup(0x400 + (seed & 0xFF))
|
||||||
result := binary.LittleEndian.Uint32(data[i : i+4])
|
result := binary.LittleEndian.Uint32(data[i : i+4])
|
||||||
result ^= seed + seed2
|
result ^= seed + seed2
|
||||||
seed = ((^seed << 21) + 0x11111111) | (seed >> 11)
|
seed = ((^seed << 21) + 0x11111111) | (seed >> 11)
|
||||||
@ -235,7 +235,7 @@ func hashString(key string, hashType uint32) uint32 {
|
|||||||
|
|
||||||
/* prepare seeds. */
|
/* prepare seeds. */
|
||||||
for _, char := range strings.ToUpper(key) {
|
for _, char := range strings.ToUpper(key) {
|
||||||
seed1 = CryptoBuffer[(hashType*0x100)+uint32(char)] ^ (seed1 + seed2)
|
seed1 = cryptoLookup((hashType*0x100)+uint32(char)) ^ (seed1 + seed2)
|
||||||
seed2 = uint32(char) + seed1 + seed2 + (seed2 << 5) + 3
|
seed2 = uint32(char) + seed1 + seed2 + (seed2 << 5) + 3
|
||||||
}
|
}
|
||||||
return seed1
|
return seed1
|
||||||
|
@ -38,7 +38,7 @@ func (eap *AudioProvider) PlayBGM(song string) {
|
|||||||
_ = eap.bgmAudio.Pause()
|
_ = eap.bgmAudio.Pause()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
go func() {
|
|
||||||
if eap.bgmAudio != nil {
|
if eap.bgmAudio != nil {
|
||||||
err := eap.bgmAudio.Close()
|
err := eap.bgmAudio.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -68,7 +68,6 @@ func (eap *AudioProvider) PlayBGM(song string) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
}()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (eap *AudioProvider) LoadSoundEffect(sfx string) (d2audio.SoundEffect, error) {
|
func (eap *AudioProvider) LoadSoundEffect(sfx string) (d2audio.SoundEffect, error) {
|
||||||
|
76
d2core/d2gui/d2gui.go
Normal file
76
d2core/d2gui/d2gui.go
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package d2gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrWasInit = errors.New("gui system is already initialized")
|
||||||
|
ErrNotInit = errors.New("gui system is not initialized")
|
||||||
|
)
|
||||||
|
|
||||||
|
var singleton *guiManager
|
||||||
|
|
||||||
|
func Initialize() error {
|
||||||
|
assertNotInit()
|
||||||
|
|
||||||
|
var err error
|
||||||
|
if singleton, err = createGuiManager(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Shutdown() {
|
||||||
|
singleton = nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func Render(target d2render.Surface) error {
|
||||||
|
assertWasInit()
|
||||||
|
return singleton.render(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Advance(elapsed float64) error {
|
||||||
|
assertWasInit()
|
||||||
|
return singleton.advance(elapsed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Clear() {
|
||||||
|
assertWasInit()
|
||||||
|
singleton.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ShowLoadScreen(progress float64) {
|
||||||
|
assertWasInit()
|
||||||
|
singleton.showLoadScreen(progress)
|
||||||
|
}
|
||||||
|
|
||||||
|
func HideLoadScreen() {
|
||||||
|
assertWasInit()
|
||||||
|
singleton.hideLoadScreen()
|
||||||
|
}
|
||||||
|
|
||||||
|
func ShowCursor() {
|
||||||
|
assertWasInit()
|
||||||
|
singleton.showCursor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func HideCursor() {
|
||||||
|
assertWasInit()
|
||||||
|
singleton.hideCursor()
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertWasInit() {
|
||||||
|
if singleton == nil {
|
||||||
|
panic(ErrNotInit)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func assertNotInit() {
|
||||||
|
if singleton != nil {
|
||||||
|
panic(ErrWasInit)
|
||||||
|
}
|
||||||
|
}
|
125
d2core/d2gui/gui_manager.go
Normal file
125
d2core/d2gui/gui_manager.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package d2gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image/color"
|
||||||
|
"math"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
)
|
||||||
|
|
||||||
|
type guiWidget interface {
|
||||||
|
getLayer() int
|
||||||
|
render(target d2render.Surface) error
|
||||||
|
advance(elapsed float64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type guiManager struct {
|
||||||
|
cursorSprite *Sprite
|
||||||
|
loadSprite *Sprite
|
||||||
|
widgets []guiWidget
|
||||||
|
loading bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func createGuiManager() (*guiManager, error) {
|
||||||
|
cursorSprite, err := CreateSprite(d2resource.CursorDefault, d2resource.PaletteUnits)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
loadSprite, err := CreateSprite(d2resource.LoadingScreen, d2resource.PaletteLoading)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
width, height := loadSprite.getSize()
|
||||||
|
loadSprite.SetPosition(400-width/2, 300+height/2)
|
||||||
|
|
||||||
|
manager := &guiManager{
|
||||||
|
cursorSprite: cursorSprite,
|
||||||
|
loadSprite: loadSprite,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2input.BindHandler(manager); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return manager, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) OnMouseMove(event d2input.MouseMoveEvent) bool {
|
||||||
|
gui.cursorSprite.SetPosition(event.X, event.Y)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) render(target d2render.Surface) error {
|
||||||
|
if gui.loading {
|
||||||
|
target.Clear(color.Black)
|
||||||
|
if err := gui.loadSprite.render(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for _, widget := range gui.widgets {
|
||||||
|
if err := widget.render(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gui.cursorSprite.render(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) advance(elapsed float64) error {
|
||||||
|
if gui.loading {
|
||||||
|
gui.loadSprite.Show()
|
||||||
|
if err := gui.loadSprite.advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
gui.loadSprite.Hide()
|
||||||
|
for _, widget := range gui.widgets {
|
||||||
|
if err := widget.advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := gui.loadSprite.advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) showLoadScreen(progress float64) {
|
||||||
|
progress = math.Min(progress, 1.0)
|
||||||
|
progress = math.Max(progress, 0.0)
|
||||||
|
|
||||||
|
animation := gui.loadSprite.animation
|
||||||
|
frameCount := animation.GetFrameCount()
|
||||||
|
animation.SetCurrentFrame(int(float64(frameCount-1.0) * progress))
|
||||||
|
|
||||||
|
gui.loading = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) hideLoadScreen() {
|
||||||
|
gui.loading = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) showCursor() {
|
||||||
|
gui.cursorSprite.Show()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) hideCursor() {
|
||||||
|
gui.cursorSprite.Hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (gui *guiManager) clear() {
|
||||||
|
gui.widgets = nil
|
||||||
|
gui.hideLoadScreen()
|
||||||
|
}
|
104
d2core/d2gui/sprite.go
Normal file
104
d2core/d2gui/sprite.go
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
package d2gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Sprite struct {
|
||||||
|
x int
|
||||||
|
y int
|
||||||
|
|
||||||
|
segmentsX int
|
||||||
|
segmentsY int
|
||||||
|
frameOffset int
|
||||||
|
|
||||||
|
visible bool
|
||||||
|
animation *d2asset.Animation
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateSprite(imagePath, palettePath string) (*Sprite, error) {
|
||||||
|
animation, err := d2asset.LoadAnimation(imagePath, palettePath)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
sprite := &Sprite{
|
||||||
|
animation: animation,
|
||||||
|
visible: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
return sprite, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) SetSegmented(segmentsX, segmentsY, frameOffset int) {
|
||||||
|
s.segmentsX = segmentsX
|
||||||
|
s.segmentsY = segmentsY
|
||||||
|
s.frameOffset = frameOffset
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) SetPosition(x, y int) {
|
||||||
|
s.x = x
|
||||||
|
s.y = y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) Show() {
|
||||||
|
s.visible = true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) Hide() {
|
||||||
|
s.visible = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) getPosition() (int, int) {
|
||||||
|
return s.x, s.y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) getSize() (int, int) {
|
||||||
|
return s.animation.GetCurrentFrameSize()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) render(target d2render.Surface) error {
|
||||||
|
if !s.visible {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
_, height := s.animation.GetCurrentFrameSize()
|
||||||
|
target.PushTranslation(s.x, s.y-height)
|
||||||
|
defer target.Pop()
|
||||||
|
|
||||||
|
if s.segmentsX == 0 && s.segmentsY == 0 {
|
||||||
|
return s.animation.Render(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
var currentY int
|
||||||
|
for y := 0; y < s.segmentsY; y++ {
|
||||||
|
var currentX int
|
||||||
|
var maxHeight int
|
||||||
|
for x := 0; x < s.segmentsX; x++ {
|
||||||
|
if err := s.animation.SetCurrentFrame(x + y*s.segmentsX + s.frameOffset*s.segmentsX*s.segmentsY); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
target.PushTranslation(s.x+currentX, s.y+currentY)
|
||||||
|
err := s.animation.Render(target)
|
||||||
|
target.Pop()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
width, height := s.animation.GetCurrentFrameSize()
|
||||||
|
maxHeight = d2common.MaxInt(maxHeight, height)
|
||||||
|
currentX += width
|
||||||
|
}
|
||||||
|
|
||||||
|
currentY += maxHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Sprite) advance(elapsed float64) error {
|
||||||
|
return s.animation.Advance(elapsed)
|
||||||
|
}
|
13
d2core/d2gui/widget_manager.go
Normal file
13
d2core/d2gui/widget_manager.go
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
package d2gui
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
)
|
||||||
|
|
||||||
|
type widget interface {
|
||||||
|
Render(target d2render.Surface) error
|
||||||
|
Advance(elapsed float64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type widgetManager struct {
|
||||||
|
}
|
@ -1,107 +1,88 @@
|
|||||||
package d2scene
|
package d2scene
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Scene defines the function necessary for scene management
|
type Scene interface{}
|
||||||
type Scene interface {
|
|
||||||
Load() []func()
|
type SceneLoadHandler interface {
|
||||||
Unload()
|
OnLoad() error
|
||||||
Render(target d2render.Surface)
|
|
||||||
Advance(tickTime float64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var nextScene Scene // The next scene to be loaded at the end of the game loop
|
type SceneUnloadHandler interface {
|
||||||
var currentScene Scene // The current scene being rendered
|
OnUnload() error
|
||||||
var loadingIndex int // Determines which load function is currently being called
|
}
|
||||||
var thingsToLoad []func() // The load functions for the next scene
|
|
||||||
var loadingProgress float64 // LoadingProcess is a range between 0.0 and 1.0. If set, loading screen displays.
|
type SceneRenderHandler interface {
|
||||||
var stepLoadingSize float64 // The size for each loading step
|
Render(target d2render.Surface) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type SceneAdvanceHandler interface {
|
||||||
|
Advance(elapsed float64) error
|
||||||
|
}
|
||||||
|
|
||||||
|
var singleton struct {
|
||||||
|
nextScene Scene
|
||||||
|
loadingScene Scene
|
||||||
|
currentScene Scene
|
||||||
|
}
|
||||||
|
|
||||||
// SetNextScene tells the engine what scene to load on the next update cycle
|
|
||||||
func SetNextScene(scene Scene) {
|
func SetNextScene(scene Scene) {
|
||||||
nextScene = scene
|
singleton.nextScene = scene
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCurrentScene() Scene {
|
func Advance(elapsed float64) error {
|
||||||
return currentScene
|
if singleton.nextScene != nil {
|
||||||
|
if handler, ok := singleton.currentScene.(SceneUnloadHandler); ok {
|
||||||
|
if err := handler.OnUnload(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateScene handles the scene maintenance for the engine
|
|
||||||
func UpdateScene() {
|
|
||||||
if nextScene == nil {
|
|
||||||
if thingsToLoad != nil {
|
|
||||||
if loadingIndex < len(thingsToLoad) {
|
|
||||||
thingsToLoad[loadingIndex]()
|
|
||||||
loadingIndex++
|
|
||||||
if loadingIndex < len(thingsToLoad) {
|
|
||||||
StepLoading()
|
|
||||||
} else {
|
|
||||||
FinishLoading()
|
|
||||||
thingsToLoad = nil
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if currentScene != nil {
|
|
||||||
currentScene.Unload()
|
|
||||||
runtime.GC()
|
|
||||||
}
|
|
||||||
currentScene = nextScene
|
|
||||||
nextScene = nil
|
|
||||||
d2ui.Reset()
|
d2ui.Reset()
|
||||||
thingsToLoad = currentScene.Load()
|
d2gui.Clear()
|
||||||
loadingIndex = 0
|
|
||||||
SetLoadingStepSize(1.0 / float64(len(thingsToLoad)))
|
if _, ok := singleton.nextScene.(SceneLoadHandler); ok {
|
||||||
ResetLoading()
|
d2gui.ShowLoadScreen(0)
|
||||||
|
d2gui.HideCursor()
|
||||||
|
singleton.currentScene = nil
|
||||||
|
singleton.loadingScene = singleton.nextScene
|
||||||
|
} else {
|
||||||
|
singleton.currentScene = singleton.nextScene
|
||||||
|
singleton.loadingScene = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Advance(time float64) {
|
singleton.nextScene = nil
|
||||||
if currentScene == nil {
|
} else if singleton.loadingScene != nil {
|
||||||
return
|
handler := singleton.loadingScene.(SceneLoadHandler)
|
||||||
}
|
if err := handler.OnLoad(); err != nil {
|
||||||
currentScene.Advance(time)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func Render(surface d2render.Surface) {
|
singleton.currentScene = singleton.loadingScene
|
||||||
if currentScene == nil {
|
singleton.loadingScene = nil
|
||||||
return
|
d2gui.ShowCursor()
|
||||||
|
d2gui.HideLoadScreen()
|
||||||
|
} else if singleton.currentScene != nil {
|
||||||
|
if handler, ok := singleton.currentScene.(SceneAdvanceHandler); ok {
|
||||||
|
if err := handler.Advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
currentScene.Render(surface)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetLoadingStepSize sets the size of the loading step
|
return nil
|
||||||
func SetLoadingStepSize(size float64) {
|
|
||||||
stepLoadingSize = size
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ResetLoading resets the loading progress
|
func Render(surface d2render.Surface) error {
|
||||||
func ResetLoading() {
|
if handler, ok := singleton.currentScene.(SceneRenderHandler); ok {
|
||||||
loadingProgress = 0.0
|
if err := handler.Render(surface); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// StepLoading increments the loading progress
|
return nil
|
||||||
func StepLoading() {
|
|
||||||
loadingProgress = math.Min(1.0, loadingProgress+stepLoadingSize)
|
|
||||||
}
|
|
||||||
|
|
||||||
// FinishLoading terminates the loading phase
|
|
||||||
func FinishLoading() {
|
|
||||||
loadingProgress = 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsLoading returns true if the engine is currently in a loading state
|
|
||||||
func IsLoading() bool {
|
|
||||||
return loadingProgress < 1.0
|
|
||||||
}
|
|
||||||
|
|
||||||
func GetLoadingProgress() float64 {
|
|
||||||
return loadingProgress
|
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var widgets []Widget
|
var widgets []Widget
|
||||||
var cursorSprite *Sprite
|
|
||||||
var cursorButtons CursorButton
|
var cursorButtons CursorButton
|
||||||
var pressedIndex int
|
var pressedIndex int
|
||||||
var CursorX int
|
var CursorX int
|
||||||
@ -26,8 +25,7 @@ var CursorY int
|
|||||||
var clickSfx d2audio.SoundEffect
|
var clickSfx d2audio.SoundEffect
|
||||||
var waitForLeftMouseUp bool
|
var waitForLeftMouseUp bool
|
||||||
|
|
||||||
func Initialize(curSprite *Sprite) {
|
func Initialize() {
|
||||||
cursorSprite = curSprite
|
|
||||||
pressedIndex = -1
|
pressedIndex = -1
|
||||||
clickSfx, _ = d2audio.LoadSoundEffect(d2resource.SFXButtonClick)
|
clickSfx, _ = d2audio.LoadSoundEffect(d2resource.SFXButtonClick)
|
||||||
waitForLeftMouseUp = false
|
waitForLeftMouseUp = false
|
||||||
@ -56,10 +54,6 @@ func Render(target d2render.Surface) {
|
|||||||
widget.Render(target)
|
widget.Render(target)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cx, cy := ebiten.CursorPosition()
|
|
||||||
cursorSprite.SetPosition(cx, cy)
|
|
||||||
cursorSprite.Render(target)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update updates all of the UI elements
|
// Update updates all of the UI elements
|
||||||
@ -142,7 +136,3 @@ func CursorButtonPressed(button CursorButton) bool {
|
|||||||
func KeyPressed(key ebiten.Key) bool {
|
func KeyPressed(key ebiten.Key) bool {
|
||||||
return ebiten.IsKeyPressed(key)
|
return ebiten.IsKeyPressed(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetCursorSprite() *Sprite {
|
|
||||||
return cursorSprite
|
|
||||||
}
|
|
||||||
|
153
d2game/d2game.go
153
d2game/d2game.go
@ -1,153 +0,0 @@
|
|||||||
package d2game
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"runtime"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
|
||||||
)
|
|
||||||
|
|
||||||
var singleton struct {
|
|
||||||
loadingSprite *d2ui.Sprite // The sprite shown when loading stuff
|
|
||||||
lastTime float64 // Last time we updated the scene
|
|
||||||
showFPS bool
|
|
||||||
timeScale float64
|
|
||||||
}
|
|
||||||
|
|
||||||
func Initialize(loadingSpr *d2ui.Sprite) error {
|
|
||||||
singleton.loadingSprite = loadingSpr
|
|
||||||
singleton.timeScale = 1.0
|
|
||||||
singleton.lastTime = d2common.Now()
|
|
||||||
|
|
||||||
d2term.BindAction("fullscreen", "toggles fullscreen", func() {
|
|
||||||
fullscreen, err := d2render.IsFullScreen()
|
|
||||||
if err == nil {
|
|
||||||
fullscreen = !fullscreen
|
|
||||||
d2render.SetFullScreen(fullscreen)
|
|
||||||
d2term.OutputInfo("fullscreen is now: %v", fullscreen)
|
|
||||||
} else {
|
|
||||||
d2term.OutputError(err.Error())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
d2term.BindAction("vsync", "toggles vsync", func() {
|
|
||||||
vsync, err := d2render.GetVSyncEnabled()
|
|
||||||
if err == nil {
|
|
||||||
vsync = !vsync
|
|
||||||
d2render.SetVSyncEnabled(vsync)
|
|
||||||
d2term.OutputInfo("vsync is now: %v", vsync)
|
|
||||||
} else {
|
|
||||||
d2term.OutputError(err.Error())
|
|
||||||
}
|
|
||||||
})
|
|
||||||
d2term.BindAction("fps", "toggle fps counter", func() {
|
|
||||||
singleton.showFPS = !singleton.showFPS
|
|
||||||
d2term.OutputInfo("fps counter is now: %v", singleton.showFPS)
|
|
||||||
})
|
|
||||||
d2term.BindAction("timescale", "set scalar for elapsed time", func(timeScale float64) {
|
|
||||||
if timeScale <= 0 {
|
|
||||||
d2term.OutputError("invalid time scale value")
|
|
||||||
} else {
|
|
||||||
singleton.timeScale = timeScale
|
|
||||||
d2term.OutputInfo("timescale changed from %f to %f", singleton.timeScale, timeScale)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func Run(gitBranch string) error {
|
|
||||||
if err := d2render.Run(update, 800, 600, "OpenDiablo 2 ("+gitBranch+")"); err != nil {
|
|
||||||
log.Fatal(err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Advance updates the internal state of the engine
|
|
||||||
func Advance() {
|
|
||||||
d2scene.UpdateScene()
|
|
||||||
if d2scene.GetCurrentScene() == nil {
|
|
||||||
log.Fatal("no scene loaded")
|
|
||||||
}
|
|
||||||
|
|
||||||
if d2scene.IsLoading() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
currentTime := d2common.Now()
|
|
||||||
deltaTime := (currentTime - singleton.lastTime) * singleton.timeScale
|
|
||||||
singleton.lastTime = currentTime
|
|
||||||
|
|
||||||
d2scene.Advance(deltaTime)
|
|
||||||
d2ui.Advance(deltaTime)
|
|
||||||
d2term.Advance(deltaTime)
|
|
||||||
d2input.Advance(deltaTime)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Draw draws the game
|
|
||||||
func render(target d2render.Surface) {
|
|
||||||
if d2scene.GetLoadingProgress() < 1.0 {
|
|
||||||
singleton.loadingSprite.SetCurrentFrame(
|
|
||||||
int(d2common.Max(0, d2common.Min(
|
|
||||||
uint32(singleton.loadingSprite.GetFrameCount()-1),
|
|
||||||
uint32(float64(singleton.loadingSprite.GetFrameCount()-1)*d2scene.GetLoadingProgress()),
|
|
||||||
))),
|
|
||||||
)
|
|
||||||
singleton.loadingSprite.Render(target)
|
|
||||||
} else {
|
|
||||||
if d2scene.GetCurrentScene() == nil {
|
|
||||||
log.Fatal("no scene loaded")
|
|
||||||
}
|
|
||||||
d2scene.Render(target)
|
|
||||||
d2ui.Render(target)
|
|
||||||
}
|
|
||||||
if singleton.showFPS {
|
|
||||||
target.PushTranslation(5, 565)
|
|
||||||
vsyncEnabled, _ := d2render.GetVSyncEnabled()
|
|
||||||
fps, _ := d2render.CurrentFPS()
|
|
||||||
target.DrawText("vsync:" + strconv.FormatBool(vsyncEnabled) + "\nFPS:" + strconv.Itoa(int(fps)))
|
|
||||||
target.Pop()
|
|
||||||
|
|
||||||
cx, cy, _ := d2render.GetCursorPos()
|
|
||||||
|
|
||||||
var m runtime.MemStats
|
|
||||||
runtime.ReadMemStats(&m)
|
|
||||||
|
|
||||||
target.PushTranslation(680, 0)
|
|
||||||
target.DrawText("Alloc " + strconv.FormatInt(int64(m.Alloc)/1024/1024, 10))
|
|
||||||
target.PushTranslation(0, 16)
|
|
||||||
target.DrawText("Pause " + strconv.FormatInt(int64(m.PauseTotalNs/1024/1024), 10))
|
|
||||||
target.PushTranslation(0, 16)
|
|
||||||
target.DrawText("HeapSys " + strconv.FormatInt(int64(m.HeapSys/1024/1024), 10))
|
|
||||||
target.PushTranslation(0, 16)
|
|
||||||
target.DrawText("NumGC " + strconv.FormatInt(int64(m.NumGC), 10))
|
|
||||||
target.PushTranslation(0, 16)
|
|
||||||
target.DrawText("Coords " + strconv.FormatInt(int64(cx), 10) + "," + strconv.FormatInt(int64(cy), 10))
|
|
||||||
target.PopN(5)
|
|
||||||
}
|
|
||||||
|
|
||||||
d2term.Render(target)
|
|
||||||
}
|
|
||||||
|
|
||||||
func update(screen d2render.Surface) error {
|
|
||||||
Advance()
|
|
||||||
err, drawingSkipped := d2render.IsDrawingSkipped()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if !drawingSkipped {
|
|
||||||
_, surface := d2render.CreateSurface(screen)
|
|
||||||
render(surface)
|
|
||||||
if surface.GetDepth() > 0 {
|
|
||||||
panic("detected surface stack leak")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
@ -3,7 +3,6 @@ package d2gamescene
|
|||||||
import (
|
import (
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2video"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2video"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
"github.com/hajimehoshi/ebiten"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type BlizzardIntro struct {
|
type BlizzardIntro struct {
|
||||||
@ -11,31 +10,15 @@ type BlizzardIntro struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateBlizzardIntro() *BlizzardIntro {
|
func CreateBlizzardIntro() *BlizzardIntro {
|
||||||
result := &BlizzardIntro{}
|
return &BlizzardIntro{}
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *BlizzardIntro) Load() []func() {
|
func (v *BlizzardIntro) OnLoad() error {
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
videoBytes, err := d2asset.LoadFile("/data/local/video/BlizNorth640x480.bik")
|
videoBytes, err := d2asset.LoadFile("/data/local/video/BlizNorth640x480.bik")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
v.videoDecoder = d2video.CreateBinkDecoder(videoBytes)
|
v.videoDecoder = d2video.CreateBinkDecoder(videoBytes)
|
||||||
},
|
return nil
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *BlizzardIntro) Unload() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *BlizzardIntro) Render(screen *ebiten.Image) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func (v *BlizzardIntro) Update(tickTime float64) {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -47,92 +47,75 @@ type CharacterSelect struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func CreateCharacterSelect() *CharacterSelect {
|
func CreateCharacterSelect() *CharacterSelect {
|
||||||
result := &CharacterSelect{
|
return &CharacterSelect{selectedCharacter: -1}
|
||||||
selectedCharacter: -1,
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) Load() []func() {
|
func (v *CharacterSelect) OnLoad() error {
|
||||||
d2audio.PlayBGM(d2resource.BGMTitle)
|
d2audio.PlayBGM(d2resource.BGMTitle)
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.CharacterSelectionBackground, d2resource.PaletteSky)
|
animation, _ := d2asset.LoadAnimation(d2resource.CharacterSelectionBackground, d2resource.PaletteSky)
|
||||||
v.background, _ = d2ui.LoadSprite(animation)
|
v.background, _ = d2ui.LoadSprite(animation)
|
||||||
v.background.SetPosition(0, 0)
|
v.background.SetPosition(0, 0)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.newCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, d2common.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#831"), 15)))
|
v.newCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, d2common.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#831"), 15)))
|
||||||
v.newCharButton.SetPosition(33, 468)
|
v.newCharButton.SetPosition(33, 468)
|
||||||
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
|
v.newCharButton.OnActivated(func() { v.onNewCharButtonClicked() })
|
||||||
d2ui.AddWidget(&v.newCharButton)
|
d2ui.AddWidget(&v.newCharButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.convertCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, d2common.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#825"), 15)))
|
v.convertCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, d2common.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#825"), 15)))
|
||||||
v.convertCharButton.SetPosition(233, 468)
|
v.convertCharButton.SetPosition(233, 468)
|
||||||
v.convertCharButton.SetEnabled(false)
|
v.convertCharButton.SetEnabled(false)
|
||||||
d2ui.AddWidget(&v.convertCharButton)
|
d2ui.AddWidget(&v.convertCharButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.deleteCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, d2common.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#832"), 15)))
|
v.deleteCharButton = d2ui.CreateButton(d2ui.ButtonTypeTall, d2common.CombineStrings(dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#832"), 15)))
|
||||||
v.deleteCharButton.OnActivated(func() { v.onDeleteCharButtonClicked() })
|
v.deleteCharButton.OnActivated(func() { v.onDeleteCharButtonClicked() })
|
||||||
v.deleteCharButton.SetPosition(433, 468)
|
v.deleteCharButton.SetPosition(433, 468)
|
||||||
d2ui.AddWidget(&v.deleteCharButton)
|
d2ui.AddWidget(&v.deleteCharButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#970"))
|
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#970"))
|
||||||
v.exitButton.SetPosition(33, 537)
|
v.exitButton.SetPosition(33, 537)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
d2ui.AddWidget(&v.exitButton)
|
d2ui.AddWidget(&v.exitButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.deleteCharCancelButton = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, d2common.TranslateString("#4231"))
|
v.deleteCharCancelButton = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, d2common.TranslateString("#4231"))
|
||||||
v.deleteCharCancelButton.SetPosition(282, 308)
|
v.deleteCharCancelButton.SetPosition(282, 308)
|
||||||
v.deleteCharCancelButton.SetVisible(false)
|
v.deleteCharCancelButton.SetVisible(false)
|
||||||
v.deleteCharCancelButton.OnActivated(func() { v.onDeleteCharacterCancelClicked() })
|
v.deleteCharCancelButton.OnActivated(func() { v.onDeleteCharacterCancelClicked() })
|
||||||
d2ui.AddWidget(&v.deleteCharCancelButton)
|
d2ui.AddWidget(&v.deleteCharCancelButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.deleteCharOkButton = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, d2common.TranslateString("#4227"))
|
v.deleteCharOkButton = d2ui.CreateButton(d2ui.ButtonTypeOkCancel, d2common.TranslateString("#4227"))
|
||||||
v.deleteCharOkButton.SetPosition(422, 308)
|
v.deleteCharOkButton.SetPosition(422, 308)
|
||||||
v.deleteCharOkButton.SetVisible(false)
|
v.deleteCharOkButton.SetVisible(false)
|
||||||
v.deleteCharOkButton.OnActivated(func() { v.onDeleteCharacterConfirmClicked() })
|
v.deleteCharOkButton.OnActivated(func() { v.onDeleteCharacterConfirmClicked() })
|
||||||
d2ui.AddWidget(&v.deleteCharOkButton)
|
d2ui.AddWidget(&v.deleteCharOkButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#971"))
|
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#971"))
|
||||||
v.okButton.SetPosition(625, 537)
|
v.okButton.SetPosition(625, 537)
|
||||||
v.okButton.OnActivated(func() { v.onOkButtonClicked() })
|
v.okButton.OnActivated(func() { v.onOkButtonClicked() })
|
||||||
d2ui.AddWidget(&v.okButton)
|
d2ui.AddWidget(&v.okButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.d2HeroTitle = d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteUnits)
|
v.d2HeroTitle = d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteUnits)
|
||||||
v.d2HeroTitle.SetPosition(320, 23)
|
v.d2HeroTitle.SetPosition(320, 23)
|
||||||
v.d2HeroTitle.Alignment = d2ui.LabelAlignCenter
|
v.d2HeroTitle.Alignment = d2ui.LabelAlignCenter
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.deleteCharConfirmLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
v.deleteCharConfirmLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||||
lines := dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#1878"), 29)
|
lines := dh.SplitIntoLinesWithMaxWidth(d2common.TranslateString("#1878"), 29)
|
||||||
v.deleteCharConfirmLabel.SetText(strings.Join(lines, "\n"))
|
v.deleteCharConfirmLabel.SetText(strings.Join(lines, "\n"))
|
||||||
v.deleteCharConfirmLabel.Alignment = d2ui.LabelAlignCenter
|
v.deleteCharConfirmLabel.Alignment = d2ui.LabelAlignCenter
|
||||||
v.deleteCharConfirmLabel.SetPosition(400, 185)
|
v.deleteCharConfirmLabel.SetPosition(400, 185)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.CharacterSelectionSelectBox, d2resource.PaletteSky)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.CharacterSelectionSelectBox, d2resource.PaletteSky)
|
|
||||||
v.selectionBox, _ = d2ui.LoadSprite(animation)
|
v.selectionBox, _ = d2ui.LoadSprite(animation)
|
||||||
v.selectionBox.SetPosition(37, 86)
|
v.selectionBox.SetPosition(37, 86)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.PopUpOkCancel, d2resource.PaletteFechar)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.PopUpOkCancel, d2resource.PaletteFechar)
|
|
||||||
v.okCancelBox, _ = d2ui.LoadSprite(animation)
|
v.okCancelBox, _ = d2ui.LoadSprite(animation)
|
||||||
v.okCancelBox.SetPosition(270, 175)
|
v.okCancelBox.SetPosition(270, 175)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.charScrollbar = d2ui.CreateScrollbar(586, 87, 369)
|
v.charScrollbar = d2ui.CreateScrollbar(586, 87, 369)
|
||||||
v.charScrollbar.OnActivated(func() { v.onScrollUpdate() })
|
v.charScrollbar.OnActivated(func() { v.onScrollUpdate() })
|
||||||
d2ui.AddWidget(&v.charScrollbar)
|
d2ui.AddWidget(&v.charScrollbar)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
for i := 0; i < 8; i++ {
|
for i := 0; i < 8; i++ {
|
||||||
xOffset := 115
|
xOffset := 115
|
||||||
if i&1 > 0 {
|
if i&1 > 0 {
|
||||||
@ -148,8 +131,8 @@ func (v *CharacterSelect) Load() []func() {
|
|||||||
v.characterExpLabel[i].SetPosition(xOffset, 130+((i/2)*95))
|
v.characterExpLabel[i].SetPosition(xOffset, 130+((i/2)*95))
|
||||||
}
|
}
|
||||||
v.refreshGameStates()
|
v.refreshGameStates()
|
||||||
},
|
|
||||||
}
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) onScrollUpdate() {
|
func (v *CharacterSelect) onScrollUpdate() {
|
||||||
@ -192,10 +175,7 @@ func (v *CharacterSelect) onExitButtonClicked() {
|
|||||||
d2scene.SetNextScene(mainMenu)
|
d2scene.SetNextScene(mainMenu)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) Unload() {
|
func (v *CharacterSelect) Render(screen d2render.Surface) error {
|
||||||
}
|
|
||||||
|
|
||||||
func (v *CharacterSelect) Render(screen d2render.Surface) {
|
|
||||||
v.background.RenderSegmented(screen, 4, 3, 0)
|
v.background.RenderSegmented(screen, 4, 3, 0)
|
||||||
v.d2HeroTitle.Render(screen)
|
v.d2HeroTitle.Render(screen)
|
||||||
actualSelectionIndex := v.selectedCharacter - (v.charScrollbar.GetCurrentOffset() * 2)
|
actualSelectionIndex := v.selectedCharacter - (v.charScrollbar.GetCurrentOffset() * 2)
|
||||||
@ -219,6 +199,8 @@ func (v *CharacterSelect) Render(screen d2render.Surface) {
|
|||||||
v.okCancelBox.RenderSegmented(screen, 2, 1, 0)
|
v.okCancelBox.RenderSegmented(screen, 2, 1, 0)
|
||||||
v.deleteCharConfirmLabel.Render(screen)
|
v.deleteCharConfirmLabel.Render(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) moveSelectionBox() {
|
func (v *CharacterSelect) moveSelectionBox() {
|
||||||
@ -233,7 +215,7 @@ func (v *CharacterSelect) moveSelectionBox() {
|
|||||||
v.d2HeroTitle.SetText(v.gameStates[v.selectedCharacter].HeroName)
|
v.d2HeroTitle.SetText(v.gameStates[v.selectedCharacter].HeroName)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) Advance(tickTime float64) {
|
func (v *CharacterSelect) Advance(tickTime float64) error {
|
||||||
if !v.showDeleteConfirmation {
|
if !v.showDeleteConfirmation {
|
||||||
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
if ebiten.IsMouseButtonPressed(ebiten.MouseButtonLeft) {
|
||||||
if !v.mouseButtonPressed {
|
if !v.mouseButtonPressed {
|
||||||
@ -264,6 +246,8 @@ func (v *CharacterSelect) Advance(tickTime float64) {
|
|||||||
hero.AnimatedEntity.Advance(tickTime)
|
hero.AnimatedEntity.Advance(tickTime)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *CharacterSelect) onDeleteCharButtonClicked() {
|
func (v *CharacterSelect) onDeleteCharButtonClicked() {
|
||||||
|
@ -8,16 +8,13 @@ import (
|
|||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
dh "github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
dh "github.com/OpenDiablo2/OpenDiablo2/d2common"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -68,23 +65,19 @@ func (v *Credits) LoadContributors() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load is called to load the resources for the credits scene
|
// Load is called to load the resources for the credits scene
|
||||||
func (v *Credits) Load() []func() {
|
func (v *Credits) OnLoad() error {
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.CreditsBackground, d2resource.PaletteSky)
|
animation, _ := d2asset.LoadAnimation(d2resource.CreditsBackground, d2resource.PaletteSky)
|
||||||
v.creditsBackground, _ = d2ui.LoadSprite(animation)
|
v.creditsBackground, _ = d2ui.LoadSprite(animation)
|
||||||
v.creditsBackground.SetPosition(0, 0)
|
v.creditsBackground.SetPosition(0, 0)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#970"))
|
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#970"))
|
||||||
v.exitButton.SetPosition(33, 543)
|
v.exitButton.SetPosition(33, 543)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
d2ui.AddWidget(&v.exitButton)
|
d2ui.AddWidget(&v.exitButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
fileData, err := d2asset.LoadFile(d2resource.CreditsText)
|
fileData, err := d2asset.LoadFile(d2resource.CreditsText)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
creditData, _ := dh.Utf16BytesToString(fileData[2:])
|
creditData, _ := dh.Utf16BytesToString(fileData[2:])
|
||||||
v.creditsText = strings.Split(creditData, "\r\n")
|
v.creditsText = strings.Split(creditData, "\r\n")
|
||||||
@ -92,17 +85,11 @@ func (v *Credits) Load() []func() {
|
|||||||
v.creditsText[i] = strings.Trim(v.creditsText[i], " ")
|
v.creditsText[i] = strings.Trim(v.creditsText[i], " ")
|
||||||
}
|
}
|
||||||
v.creditsText = append(v.LoadContributors(), v.creditsText...)
|
v.creditsText = append(v.LoadContributors(), v.creditsText...)
|
||||||
},
|
return nil
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unload unloads the data for the credits scene
|
|
||||||
func (v *Credits) Unload() {
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render renders the credits scene
|
// Render renders the credits scene
|
||||||
func (v *Credits) Render(screen d2render.Surface) {
|
func (v *Credits) Render(screen d2render.Surface) error {
|
||||||
v.creditsBackground.RenderSegmented(screen, 4, 3, 0)
|
v.creditsBackground.RenderSegmented(screen, 4, 3, 0)
|
||||||
for _, label := range v.labels {
|
for _, label := range v.labels {
|
||||||
if label.Available {
|
if label.Available {
|
||||||
@ -110,12 +97,14 @@ func (v *Credits) Render(screen d2render.Surface) {
|
|||||||
}
|
}
|
||||||
label.Label.Render(screen)
|
label.Label.Render(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
const secondsPerCycle = float64(0.02)
|
const secondsPerCycle = float64(0.02)
|
||||||
|
|
||||||
// Update runs the update logic on the credits scene
|
// Update runs the update logic on the credits scene
|
||||||
func (v *Credits) Advance(tickTime float64) {
|
func (v *Credits) Advance(tickTime float64) error {
|
||||||
v.cycleTime += tickTime
|
v.cycleTime += tickTime
|
||||||
for v.cycleTime >= secondsPerCycle {
|
for v.cycleTime >= secondsPerCycle {
|
||||||
v.cycleTime -= secondsPerCycle
|
v.cycleTime -= secondsPerCycle
|
||||||
@ -135,6 +124,8 @@ func (v *Credits) Advance(tickTime float64) {
|
|||||||
label.Label.Y--
|
label.Label.Y--
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Credits) onExitButtonClicked() {
|
func (v *Credits) onExitButtonClicked() {
|
||||||
|
@ -12,7 +12,6 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
|
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2player"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -26,38 +25,28 @@ type Game struct {
|
|||||||
gameControls *d2player.GameControls
|
gameControls *d2player.GameControls
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateGame(
|
func CreateGame(gameState *d2gamestate.GameState) *Game {
|
||||||
gameState *d2gamestate.GameState,
|
return &Game{gameState: gameState}
|
||||||
) *Game {
|
|
||||||
result := &Game{
|
|
||||||
gameState: gameState,
|
|
||||||
}
|
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Game) Load() []func() {
|
func (v *Game) OnLoad() error {
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.PentSpin, d2resource.PaletteSky)
|
animation, _ := d2asset.LoadAnimation(d2resource.PentSpin, d2resource.PaletteSky)
|
||||||
v.pentSpinLeft, _ = d2ui.LoadSprite(animation)
|
v.pentSpinLeft, _ = d2ui.LoadSprite(animation)
|
||||||
v.pentSpinLeft.PlayBackward()
|
v.pentSpinLeft.PlayBackward()
|
||||||
v.pentSpinLeft.SetPlayLengthMs(475)
|
v.pentSpinLeft.SetPlayLengthMs(475)
|
||||||
v.pentSpinLeft.SetPosition(100, 300)
|
v.pentSpinLeft.SetPosition(100, 300)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.PentSpin, d2resource.PaletteSky)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.PentSpin, d2resource.PaletteSky)
|
|
||||||
v.pentSpinRight, _ = d2ui.LoadSprite(animation)
|
v.pentSpinRight, _ = d2ui.LoadSprite(animation)
|
||||||
v.pentSpinRight.PlayForward()
|
v.pentSpinRight.PlayForward()
|
||||||
v.pentSpinRight.SetPlayLengthMs(475)
|
v.pentSpinRight.SetPlayLengthMs(475)
|
||||||
v.pentSpinRight.SetPosition(650, 300)
|
v.pentSpinRight.SetPosition(650, 300)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.testLabel = d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteUnits)
|
v.testLabel = d2ui.CreateLabel(d2resource.Font42, d2resource.PaletteUnits)
|
||||||
v.testLabel.Alignment = d2ui.LabelAlignCenter
|
v.testLabel.Alignment = d2ui.LabelAlignCenter
|
||||||
v.testLabel.SetText("Soon :tm:")
|
v.testLabel.SetText("Soon :tm:")
|
||||||
v.testLabel.SetPosition(400, 250)
|
v.testLabel.SetPosition(400, 250)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.mapEngine = d2map.CreateMapEngine(v.gameState)
|
v.mapEngine = d2map.CreateMapEngine(v.gameState)
|
||||||
v.mapEngine.GenerateMap(d2enum.RegionAct1Town, 1, 0)
|
v.mapEngine.GenerateMap(d2enum.RegionAct1Town, 1, 0)
|
||||||
|
|
||||||
@ -70,28 +59,30 @@ func (v *Game) Load() []func() {
|
|||||||
v.gameState.Equipment,
|
v.gameState.Equipment,
|
||||||
)
|
)
|
||||||
v.mapEngine.AddEntity(v.hero)
|
v.mapEngine.AddEntity(v.hero)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.gameControls = d2player.NewGameControls(v.hero, v.mapEngine)
|
v.gameControls = d2player.NewGameControls(v.hero, v.mapEngine)
|
||||||
v.gameControls.Load()
|
v.gameControls.Load()
|
||||||
d2input.BindHandler(v.gameControls)
|
d2input.BindHandler(v.gameControls)
|
||||||
},
|
|
||||||
}
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Game) Unload() {
|
func (v *Game) OnUnload() error {
|
||||||
d2input.UnbindHandler(v.gameControls)
|
d2input.UnbindHandler(v.gameControls)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v Game) Render(screen d2render.Surface) {
|
func (v *Game) Render(screen d2render.Surface) error {
|
||||||
screen.Clear(color.Black)
|
screen.Clear(color.Black)
|
||||||
v.mapEngine.Render(screen)
|
v.mapEngine.Render(screen)
|
||||||
v.gameControls.Render(screen)
|
v.gameControls.Render(screen)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *Game) Advance(tickTime float64) {
|
func (v *Game) Advance(tickTime float64) error {
|
||||||
v.mapEngine.Advance(tickTime)
|
v.mapEngine.Advance(tickTime)
|
||||||
|
|
||||||
rx, ry := v.mapEngine.WorldToOrtho(v.hero.AnimatedEntity.LocationX/5, v.hero.AnimatedEntity.LocationY/5)
|
rx, ry := v.mapEngine.WorldToOrtho(v.hero.AnimatedEntity.LocationX/5, v.hero.AnimatedEntity.LocationY/5)
|
||||||
v.mapEngine.MoveCameraTo(rx, ry)
|
v.mapEngine.MoveCameraTo(rx, ry)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -8,18 +8,14 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gamestate"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gamestate"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -49,128 +45,110 @@ type MainMenu struct {
|
|||||||
|
|
||||||
// CreateMainMenu creates an instance of MainMenu
|
// CreateMainMenu creates an instance of MainMenu
|
||||||
func CreateMainMenu() *MainMenu {
|
func CreateMainMenu() *MainMenu {
|
||||||
result := &MainMenu{
|
return &MainMenu{
|
||||||
ShowTrademarkScreen: true,
|
ShowTrademarkScreen: true,
|
||||||
leftButtonHeld: true,
|
leftButtonHeld: true,
|
||||||
}
|
}
|
||||||
return result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load is called to load the resources for the main menu
|
// Load is called to load the resources for the main menu
|
||||||
func (v *MainMenu) Load() []func() {
|
func (v *MainMenu) OnLoad() error {
|
||||||
d2audio.PlayBGM(d2resource.BGMTitle)
|
d2audio.PlayBGM(d2resource.BGMTitle)
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
v.versionLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
v.versionLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||||
v.versionLabel.Alignment = d2ui.LabelAlignRight
|
v.versionLabel.Alignment = d2ui.LabelAlignRight
|
||||||
v.versionLabel.SetText("OpenDiablo2 - " + d2common.BuildInfo.Branch)
|
v.versionLabel.SetText("OpenDiablo2 - " + d2common.BuildInfo.Branch)
|
||||||
v.versionLabel.Color = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
v.versionLabel.Color = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
||||||
v.versionLabel.SetPosition(795, -10)
|
v.versionLabel.SetPosition(795, -10)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.commitLabel = d2ui.CreateLabel(d2resource.FontFormal10, d2resource.PaletteStatic)
|
v.commitLabel = d2ui.CreateLabel(d2resource.FontFormal10, d2resource.PaletteStatic)
|
||||||
v.commitLabel.Alignment = d2ui.LabelAlignLeft
|
v.commitLabel.Alignment = d2ui.LabelAlignLeft
|
||||||
v.commitLabel.SetText(d2common.BuildInfo.Commit)
|
v.commitLabel.SetText(d2common.BuildInfo.Commit)
|
||||||
v.commitLabel.Color = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
v.commitLabel.Color = color.RGBA{R: 255, G: 255, B: 255, A: 255}
|
||||||
v.commitLabel.SetPosition(2, 2)
|
v.commitLabel.SetPosition(2, 2)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.copyrightLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
v.copyrightLabel = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||||
v.copyrightLabel.Alignment = d2ui.LabelAlignCenter
|
v.copyrightLabel.Alignment = d2ui.LabelAlignCenter
|
||||||
v.copyrightLabel.SetText("Diablo 2 is © Copyright 2000-2016 Blizzard Entertainment")
|
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.Color = color.RGBA{R: 188, G: 168, B: 140, A: 255}
|
||||||
v.copyrightLabel.SetPosition(400, 500)
|
v.copyrightLabel.SetPosition(400, 500)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.copyrightLabel2 = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
v.copyrightLabel2 = d2ui.CreateLabel(d2resource.FontFormal12, d2resource.PaletteStatic)
|
||||||
v.copyrightLabel2.Alignment = d2ui.LabelAlignCenter
|
v.copyrightLabel2.Alignment = d2ui.LabelAlignCenter
|
||||||
v.copyrightLabel2.SetText(d2common.TranslateString("#1614"))
|
v.copyrightLabel2.SetText(d2common.TranslateString("#1614"))
|
||||||
v.copyrightLabel2.Color = color.RGBA{R: 188, G: 168, B: 140, A: 255}
|
v.copyrightLabel2.Color = color.RGBA{R: 188, G: 168, B: 140, A: 255}
|
||||||
v.copyrightLabel2.SetPosition(400, 525)
|
v.copyrightLabel2.SetPosition(400, 525)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.openDiabloLabel = d2ui.CreateLabel(d2resource.FontFormal10, d2resource.PaletteStatic)
|
v.openDiabloLabel = d2ui.CreateLabel(d2resource.FontFormal10, d2resource.PaletteStatic)
|
||||||
v.openDiabloLabel.Alignment = d2ui.LabelAlignCenter
|
v.openDiabloLabel.Alignment = d2ui.LabelAlignCenter
|
||||||
v.openDiabloLabel.SetText("OpenDiablo2 is neither developed by, nor endorsed by Blizzard or its parent company Activision")
|
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.Color = color.RGBA{R: 255, G: 255, B: 140, A: 255}
|
||||||
v.openDiabloLabel.SetPosition(400, 580)
|
v.openDiabloLabel.SetPosition(400, 580)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.GameSelectScreen, d2resource.PaletteSky)
|
animation, _ := d2asset.LoadAnimation(d2resource.GameSelectScreen, d2resource.PaletteSky)
|
||||||
v.background, _ = d2ui.LoadSprite(animation)
|
v.background, _ = d2ui.LoadSprite(animation)
|
||||||
v.background.SetPosition(0, 0)
|
v.background.SetPosition(0, 0)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.TrademarkScreen, d2resource.PaletteSky)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.TrademarkScreen, d2resource.PaletteSky)
|
|
||||||
v.trademarkBackground, _ = d2ui.LoadSprite(animation)
|
v.trademarkBackground, _ = d2ui.LoadSprite(animation)
|
||||||
v.trademarkBackground.SetPosition(0, 0)
|
v.trademarkBackground.SetPosition(0, 0)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.Diablo2LogoFireLeft, d2resource.PaletteUnits)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.Diablo2LogoFireLeft, d2resource.PaletteUnits)
|
|
||||||
v.diabloLogoLeft, _ = d2ui.LoadSprite(animation)
|
v.diabloLogoLeft, _ = d2ui.LoadSprite(animation)
|
||||||
v.diabloLogoLeft.SetBlend(true)
|
v.diabloLogoLeft.SetBlend(true)
|
||||||
v.diabloLogoLeft.PlayForward()
|
v.diabloLogoLeft.PlayForward()
|
||||||
v.diabloLogoLeft.SetPosition(400, 120)
|
v.diabloLogoLeft.SetPosition(400, 120)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.Diablo2LogoFireRight, d2resource.PaletteUnits)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.Diablo2LogoFireRight, d2resource.PaletteUnits)
|
|
||||||
v.diabloLogoRight, _ = d2ui.LoadSprite(animation)
|
v.diabloLogoRight, _ = d2ui.LoadSprite(animation)
|
||||||
v.diabloLogoRight.SetBlend(true)
|
v.diabloLogoRight.SetBlend(true)
|
||||||
v.diabloLogoRight.PlayForward()
|
v.diabloLogoRight.PlayForward()
|
||||||
v.diabloLogoRight.SetPosition(400, 120)
|
v.diabloLogoRight.SetPosition(400, 120)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.Diablo2LogoBlackLeft, d2resource.PaletteUnits)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.Diablo2LogoBlackLeft, d2resource.PaletteUnits)
|
|
||||||
v.diabloLogoLeftBack, _ = d2ui.LoadSprite(animation)
|
v.diabloLogoLeftBack, _ = d2ui.LoadSprite(animation)
|
||||||
v.diabloLogoLeftBack.SetPosition(400, 120)
|
v.diabloLogoLeftBack.SetPosition(400, 120)
|
||||||
},
|
|
||||||
func() {
|
animation, _ = d2asset.LoadAnimation(d2resource.Diablo2LogoBlackRight, d2resource.PaletteUnits)
|
||||||
animation, _ := d2asset.LoadAnimation(d2resource.Diablo2LogoBlackRight, d2resource.PaletteUnits)
|
|
||||||
v.diabloLogoRightBack, _ = d2ui.LoadSprite(animation)
|
v.diabloLogoRightBack, _ = d2ui.LoadSprite(animation)
|
||||||
v.diabloLogoRightBack.SetPosition(400, 120)
|
v.diabloLogoRightBack.SetPosition(400, 120)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.exitDiabloButton = d2ui.CreateButton(d2ui.ButtonTypeWide, d2common.TranslateString("#1625"))
|
v.exitDiabloButton = d2ui.CreateButton(d2ui.ButtonTypeWide, d2common.TranslateString("#1625"))
|
||||||
v.exitDiabloButton.SetPosition(264, 535)
|
v.exitDiabloButton.SetPosition(264, 535)
|
||||||
v.exitDiabloButton.SetVisible(!v.ShowTrademarkScreen)
|
v.exitDiabloButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitDiabloButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
d2ui.AddWidget(&v.exitDiabloButton)
|
d2ui.AddWidget(&v.exitDiabloButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.creditsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, d2common.TranslateString("#1627"))
|
v.creditsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, d2common.TranslateString("#1627"))
|
||||||
v.creditsButton.SetPosition(264, 505)
|
v.creditsButton.SetPosition(264, 505)
|
||||||
v.creditsButton.SetVisible(!v.ShowTrademarkScreen)
|
v.creditsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
v.creditsButton.OnActivated(func() { v.onCreditsButtonClicked() })
|
||||||
d2ui.AddWidget(&v.creditsButton)
|
d2ui.AddWidget(&v.creditsButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.cinematicsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, d2common.TranslateString("#1639"))
|
v.cinematicsButton = d2ui.CreateButton(d2ui.ButtonTypeShort, d2common.TranslateString("#1639"))
|
||||||
v.cinematicsButton.SetPosition(401, 505)
|
v.cinematicsButton.SetPosition(401, 505)
|
||||||
v.cinematicsButton.SetVisible(!v.ShowTrademarkScreen)
|
v.cinematicsButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
d2ui.AddWidget(&v.cinematicsButton)
|
d2ui.AddWidget(&v.cinematicsButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.singlePlayerButton = d2ui.CreateButton(d2ui.ButtonTypeWide, d2common.TranslateString("#1620"))
|
v.singlePlayerButton = d2ui.CreateButton(d2ui.ButtonTypeWide, d2common.TranslateString("#1620"))
|
||||||
v.singlePlayerButton.SetPosition(264, 290)
|
v.singlePlayerButton.SetPosition(264, 290)
|
||||||
v.singlePlayerButton.SetVisible(!v.ShowTrademarkScreen)
|
v.singlePlayerButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
v.singlePlayerButton.OnActivated(func() { v.onSinglePlayerClicked() })
|
||||||
d2ui.AddWidget(&v.singlePlayerButton)
|
d2ui.AddWidget(&v.singlePlayerButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.githubButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "PROJECT WEBSITE")
|
v.githubButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "PROJECT WEBSITE")
|
||||||
v.githubButton.SetPosition(264, 330)
|
v.githubButton.SetPosition(264, 330)
|
||||||
v.githubButton.SetVisible(!v.ShowTrademarkScreen)
|
v.githubButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
v.githubButton.OnActivated(func() { v.onGithubButtonClicked() })
|
||||||
d2ui.AddWidget(&v.githubButton)
|
d2ui.AddWidget(&v.githubButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.mapTestButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "MAP ENGINE TEST")
|
v.mapTestButton = d2ui.CreateButton(d2ui.ButtonTypeWide, "MAP ENGINE TEST")
|
||||||
v.mapTestButton.SetPosition(264, 450)
|
v.mapTestButton.SetPosition(264, 450)
|
||||||
v.mapTestButton.SetVisible(!v.ShowTrademarkScreen)
|
v.mapTestButton.SetVisible(!v.ShowTrademarkScreen)
|
||||||
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
v.mapTestButton.OnActivated(func() { v.onMapTestClicked() })
|
||||||
|
|
||||||
d2ui.AddWidget(&v.mapTestButton)
|
d2ui.AddWidget(&v.mapTestButton)
|
||||||
},
|
return nil
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *MainMenu) onMapTestClicked() {
|
func (v *MainMenu) onMapTestClicked() {
|
||||||
@ -217,13 +195,8 @@ func (v *MainMenu) onCreditsButtonClicked() {
|
|||||||
d2scene.SetNextScene(CreateCredits())
|
d2scene.SetNextScene(CreateCredits())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unload unloads the data for the main menu
|
|
||||||
func (v *MainMenu) Unload() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Render renders the main menu
|
// Render renders the main menu
|
||||||
func (v *MainMenu) Render(screen d2render.Surface) {
|
func (v *MainMenu) Render(screen d2render.Surface) error {
|
||||||
if v.ShowTrademarkScreen {
|
if v.ShowTrademarkScreen {
|
||||||
v.trademarkBackground.RenderSegmented(screen, 4, 3, 0)
|
v.trademarkBackground.RenderSegmented(screen, 4, 3, 0)
|
||||||
} else {
|
} else {
|
||||||
@ -242,10 +215,12 @@ func (v *MainMenu) Render(screen d2render.Surface) {
|
|||||||
v.versionLabel.Render(screen)
|
v.versionLabel.Render(screen)
|
||||||
v.commitLabel.Render(screen)
|
v.commitLabel.Render(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update runs the update logic on the main menu
|
// Update runs the update logic on the main menu
|
||||||
func (v *MainMenu) Advance(tickTime float64) {
|
func (v *MainMenu) Advance(tickTime float64) error {
|
||||||
v.diabloLogoLeftBack.Advance(tickTime)
|
v.diabloLogoLeftBack.Advance(tickTime)
|
||||||
v.diabloLogoRightBack.Advance(tickTime)
|
v.diabloLogoRightBack.Advance(tickTime)
|
||||||
v.diabloLogoLeft.Advance(tickTime)
|
v.diabloLogoLeft.Advance(tickTime)
|
||||||
@ -254,7 +229,7 @@ func (v *MainMenu) Advance(tickTime float64) {
|
|||||||
if v.ShowTrademarkScreen {
|
if v.ShowTrademarkScreen {
|
||||||
if d2ui.CursorButtonPressed(d2ui.CursorButtonLeft) {
|
if d2ui.CursorButtonPressed(d2ui.CursorButtonLeft) {
|
||||||
if v.leftButtonHeld {
|
if v.leftButtonHeld {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
d2ui.WaitForMouseRelease()
|
d2ui.WaitForMouseRelease()
|
||||||
v.leftButtonHeld = true
|
v.leftButtonHeld = true
|
||||||
@ -268,6 +243,7 @@ func (v *MainMenu) Advance(tickTime float64) {
|
|||||||
} else {
|
} else {
|
||||||
v.leftButtonHeld = false
|
v.leftButtonHeld = false
|
||||||
}
|
}
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -4,20 +4,14 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2dt1"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gamestate"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gamestate"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2map"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
||||||
)
|
)
|
||||||
|
|
||||||
type RegionSpec struct {
|
type RegionSpec struct {
|
||||||
@ -140,23 +134,22 @@ func (met *MapEngineTest) LoadRegionByIndex(n int, levelPreset, fileIndex int) {
|
|||||||
met.mapEngine.MoveCameraTo(met.mapEngine.WorldToOrtho(met.mapEngine.GetCenterPosition()))
|
met.mapEngine.MoveCameraTo(met.mapEngine.WorldToOrtho(met.mapEngine.GetCenterPosition()))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (met *MapEngineTest) Load() []func() {
|
func (met *MapEngineTest) OnLoad() error {
|
||||||
// TODO: Game seed comes from the game state object
|
// TODO: Game seed comes from the game state object
|
||||||
d2input.BindHandler(met)
|
d2input.BindHandler(met)
|
||||||
d2audio.PlayBGM("")
|
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
met.mapEngine = d2map.CreateMapEngine(met.gameState)
|
met.mapEngine = d2map.CreateMapEngine(met.gameState)
|
||||||
met.LoadRegionByIndex(met.currentRegion, met.levelPreset, met.fileIndex)
|
met.LoadRegionByIndex(met.currentRegion, met.levelPreset, met.fileIndex)
|
||||||
},
|
|
||||||
}
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (met *MapEngineTest) Unload() {
|
func (met *MapEngineTest) OnUnload() error {
|
||||||
d2input.UnbindHandler(met)
|
d2input.UnbindHandler(met)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (met *MapEngineTest) Render(screen d2render.Surface) {
|
func (met *MapEngineTest) Render(screen d2render.Surface) error {
|
||||||
met.mapEngine.Render(screen)
|
met.mapEngine.Render(screen)
|
||||||
|
|
||||||
screenX, screenY, _ := d2render.GetCursorPos()
|
screenX, screenY, _ := d2render.GetCursorPos()
|
||||||
@ -166,7 +159,7 @@ func (met *MapEngineTest) Render(screen d2render.Surface) {
|
|||||||
|
|
||||||
curRegion := met.mapEngine.GetRegionAtTile(int(worldX), int(worldY))
|
curRegion := met.mapEngine.GetRegionAtTile(int(worldX), int(worldY))
|
||||||
if curRegion == nil {
|
if curRegion == nil {
|
||||||
return
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
tileRect := curRegion.GetTileRect()
|
tileRect := curRegion.GetTileRect()
|
||||||
@ -268,10 +261,13 @@ func (met *MapEngineTest) Render(screen d2render.Surface) {
|
|||||||
}
|
}
|
||||||
screen.PopN(popN)
|
screen.PopN(popN)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (met *MapEngineTest) Advance(tickTime float64) {
|
func (met *MapEngineTest) Advance(tickTime float64) error {
|
||||||
met.mapEngine.Advance(tickTime)
|
met.mapEngine.Advance(tickTime)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (met *MapEngineTest) OnKeyRepeat(event d2input.KeyEvent) bool {
|
func (met *MapEngineTest) OnKeyRepeat(event d2input.KeyEvent) bool {
|
||||||
|
@ -4,21 +4,16 @@ import (
|
|||||||
"image"
|
"image"
|
||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
dh "github.com/OpenDiablo2/OpenDiablo2/d2common"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gamestate"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2asset"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common"
|
|
||||||
|
|
||||||
dh "github.com/OpenDiablo2/OpenDiablo2/d2common"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gamestate"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -76,100 +71,84 @@ func CreateSelectHeroClass() *SelectHeroClass {
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) Load() []func() {
|
func (v *SelectHeroClass) OnLoad() error {
|
||||||
d2audio.PlayBGM(d2resource.BGMTitle)
|
d2audio.PlayBGM(d2resource.BGMTitle)
|
||||||
return []func(){
|
|
||||||
func() {
|
|
||||||
v.bgImage = loadSprite(d2resource.CharacterSelectBackground, d2resource.PaletteFechar)
|
v.bgImage = loadSprite(d2resource.CharacterSelectBackground, d2resource.PaletteFechar)
|
||||||
v.bgImage.SetPosition(0, 0)
|
v.bgImage.SetPosition(0, 0)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.headingLabel = d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
v.headingLabel = d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||||
fontWidth, _ := v.headingLabel.GetSize()
|
fontWidth, _ := v.headingLabel.GetSize()
|
||||||
v.headingLabel.SetPosition(400-fontWidth/2, 17)
|
v.headingLabel.SetPosition(400-fontWidth/2, 17)
|
||||||
v.headingLabel.SetText("Select Hero Class")
|
v.headingLabel.SetText("Select Hero Class")
|
||||||
v.headingLabel.Alignment = d2ui.LabelAlignCenter
|
v.headingLabel.Alignment = d2ui.LabelAlignCenter
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroClassLabel = d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
v.heroClassLabel = d2ui.CreateLabel(d2resource.Font30, d2resource.PaletteUnits)
|
||||||
v.heroClassLabel.Alignment = d2ui.LabelAlignCenter
|
v.heroClassLabel.Alignment = d2ui.LabelAlignCenter
|
||||||
v.heroClassLabel.SetPosition(400, 65)
|
v.heroClassLabel.SetPosition(400, 65)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroDesc1Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
v.heroDesc1Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||||
v.heroDesc1Label.Alignment = d2ui.LabelAlignCenter
|
v.heroDesc1Label.Alignment = d2ui.LabelAlignCenter
|
||||||
v.heroDesc1Label.SetPosition(400, 100)
|
v.heroDesc1Label.SetPosition(400, 100)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroDesc2Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
v.heroDesc2Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||||
v.heroDesc2Label.Alignment = d2ui.LabelAlignCenter
|
v.heroDesc2Label.Alignment = d2ui.LabelAlignCenter
|
||||||
v.heroDesc2Label.SetPosition(400, 115)
|
v.heroDesc2Label.SetPosition(400, 115)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroDesc3Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
v.heroDesc3Label = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||||
v.heroDesc3Label.Alignment = d2ui.LabelAlignCenter
|
v.heroDesc3Label.Alignment = d2ui.LabelAlignCenter
|
||||||
v.heroDesc3Label.SetPosition(400, 130)
|
v.heroDesc3Label.SetPosition(400, 130)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.campfire = loadSprite(d2resource.CharacterSelectCampfire, d2resource.PaletteFechar)
|
v.campfire = loadSprite(d2resource.CharacterSelectCampfire, d2resource.PaletteFechar)
|
||||||
v.campfire.SetPosition(380, 335)
|
v.campfire.SetPosition(380, 335)
|
||||||
v.campfire.PlayForward()
|
v.campfire.PlayForward()
|
||||||
v.campfire.SetBlend(true)
|
v.campfire.SetBlend(true)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#970"))
|
v.exitButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#970"))
|
||||||
v.exitButton.SetPosition(33, 537)
|
v.exitButton.SetPosition(33, 537)
|
||||||
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
v.exitButton.OnActivated(func() { v.onExitButtonClicked() })
|
||||||
d2ui.AddWidget(&v.exitButton)
|
d2ui.AddWidget(&v.exitButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#971"))
|
v.okButton = d2ui.CreateButton(d2ui.ButtonTypeMedium, d2common.TranslateString("#971"))
|
||||||
v.okButton.SetPosition(630, 537)
|
v.okButton.SetPosition(630, 537)
|
||||||
v.okButton.OnActivated(func() { v.onOkButtonClicked() })
|
v.okButton.OnActivated(func() { v.onOkButtonClicked() })
|
||||||
v.okButton.SetVisible(false)
|
v.okButton.SetVisible(false)
|
||||||
v.okButton.SetEnabled(false)
|
v.okButton.SetEnabled(false)
|
||||||
d2ui.AddWidget(&v.okButton)
|
d2ui.AddWidget(&v.okButton)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroNameLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
v.heroNameLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||||
v.heroNameLabel.Alignment = d2ui.LabelAlignLeft
|
v.heroNameLabel.Alignment = d2ui.LabelAlignLeft
|
||||||
v.heroNameLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
v.heroNameLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
||||||
v.heroNameLabel.SetText(d2common.TranslateString("#1694"))
|
v.heroNameLabel.SetText(d2common.TranslateString("#1694"))
|
||||||
v.heroNameLabel.SetPosition(321, 475)
|
v.heroNameLabel.SetPosition(321, 475)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroNameTextbox = d2ui.CreateTextbox()
|
v.heroNameTextbox = d2ui.CreateTextbox()
|
||||||
v.heroNameTextbox.SetPosition(318, 493)
|
v.heroNameTextbox.SetPosition(318, 493)
|
||||||
v.heroNameTextbox.SetVisible(false)
|
v.heroNameTextbox.SetVisible(false)
|
||||||
d2ui.AddWidget(&v.heroNameTextbox)
|
d2ui.AddWidget(&v.heroNameTextbox)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.expansionCheckbox = d2ui.CreateCheckbox(true)
|
v.expansionCheckbox = d2ui.CreateCheckbox(true)
|
||||||
v.expansionCheckbox.SetPosition(318, 526)
|
v.expansionCheckbox.SetPosition(318, 526)
|
||||||
v.expansionCheckbox.SetVisible(false)
|
v.expansionCheckbox.SetVisible(false)
|
||||||
d2ui.AddWidget(&v.expansionCheckbox)
|
d2ui.AddWidget(&v.expansionCheckbox)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.expansionCharLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
v.expansionCharLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||||
v.expansionCharLabel.Alignment = d2ui.LabelAlignLeft
|
v.expansionCharLabel.Alignment = d2ui.LabelAlignLeft
|
||||||
v.expansionCharLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
v.expansionCharLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
||||||
v.expansionCharLabel.SetText(d2common.TranslateString("#803"))
|
v.expansionCharLabel.SetText(d2common.TranslateString("#803"))
|
||||||
v.expansionCharLabel.SetPosition(339, 526)
|
v.expansionCharLabel.SetPosition(339, 526)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.hardcoreCheckbox = d2ui.CreateCheckbox(false)
|
v.hardcoreCheckbox = d2ui.CreateCheckbox(false)
|
||||||
v.hardcoreCheckbox.SetPosition(318, 548)
|
v.hardcoreCheckbox.SetPosition(318, 548)
|
||||||
v.hardcoreCheckbox.SetVisible(false)
|
v.hardcoreCheckbox.SetVisible(false)
|
||||||
d2ui.AddWidget(&v.hardcoreCheckbox)
|
d2ui.AddWidget(&v.hardcoreCheckbox)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.hardcoreCharLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
v.hardcoreCharLabel = d2ui.CreateLabel(d2resource.Font16, d2resource.PaletteUnits)
|
||||||
v.hardcoreCharLabel.Alignment = d2ui.LabelAlignLeft
|
v.hardcoreCharLabel.Alignment = d2ui.LabelAlignLeft
|
||||||
v.hardcoreCharLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
v.hardcoreCharLabel.Color = color.RGBA{R: 216, G: 196, B: 128, A: 255}
|
||||||
v.hardcoreCharLabel.SetText(d2common.TranslateString("#1696"))
|
v.hardcoreCharLabel.SetText(d2common.TranslateString("#1696"))
|
||||||
v.hardcoreCharLabel.SetPosition(339, 548)
|
v.hardcoreCharLabel.SetPosition(339, 548)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[d2enum.HeroBarbarian] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroBarbarian] = &HeroRenderInfo{
|
||||||
d2enum.HeroStanceIdle,
|
d2enum.HeroStanceIdle,
|
||||||
loadSprite(d2resource.CharacterSelectBarbarianUnselected, d2resource.PaletteFechar),
|
loadSprite(d2resource.CharacterSelectBarbarianUnselected, d2resource.PaletteFechar),
|
||||||
@ -202,8 +181,7 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.heroRenderInfo[d2enum.HeroBarbarian].BackWalkSprite.PlayForward()
|
v.heroRenderInfo[d2enum.HeroBarbarian].BackWalkSprite.PlayForward()
|
||||||
v.heroRenderInfo[d2enum.HeroBarbarian].BackWalkSprite.SetPlayLengthMs(1000)
|
v.heroRenderInfo[d2enum.HeroBarbarian].BackWalkSprite.SetPlayLengthMs(1000)
|
||||||
v.heroRenderInfo[d2enum.HeroBarbarian].BackWalkSprite.SetPlayLoop(false)
|
v.heroRenderInfo[d2enum.HeroBarbarian].BackWalkSprite.SetPlayLoop(false)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[d2enum.HeroSorceress] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroSorceress] = &HeroRenderInfo{
|
||||||
d2enum.HeroStanceIdle,
|
d2enum.HeroStanceIdle,
|
||||||
loadSprite(d2resource.CharacterSelecSorceressUnselected, d2resource.PaletteFechar),
|
loadSprite(d2resource.CharacterSelecSorceressUnselected, d2resource.PaletteFechar),
|
||||||
@ -249,8 +227,7 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.heroRenderInfo[d2enum.HeroSorceress].BackWalkSpriteOverlay.PlayForward()
|
v.heroRenderInfo[d2enum.HeroSorceress].BackWalkSpriteOverlay.PlayForward()
|
||||||
v.heroRenderInfo[d2enum.HeroSorceress].BackWalkSpriteOverlay.SetPlayLengthMs(1200)
|
v.heroRenderInfo[d2enum.HeroSorceress].BackWalkSpriteOverlay.SetPlayLengthMs(1200)
|
||||||
v.heroRenderInfo[d2enum.HeroSorceress].BackWalkSpriteOverlay.SetPlayLoop(false)
|
v.heroRenderInfo[d2enum.HeroSorceress].BackWalkSpriteOverlay.SetPlayLoop(false)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[d2enum.HeroNecromancer] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroNecromancer] = &HeroRenderInfo{
|
||||||
d2enum.HeroStanceIdle,
|
d2enum.HeroStanceIdle,
|
||||||
loadSprite(d2resource.CharacterSelectNecromancerUnselected, d2resource.PaletteFechar),
|
loadSprite(d2resource.CharacterSelectNecromancerUnselected, d2resource.PaletteFechar),
|
||||||
@ -294,8 +271,7 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.heroRenderInfo[d2enum.HeroNecromancer].BackWalkSpriteOverlay.PlayForward()
|
v.heroRenderInfo[d2enum.HeroNecromancer].BackWalkSpriteOverlay.PlayForward()
|
||||||
v.heroRenderInfo[d2enum.HeroNecromancer].BackWalkSpriteOverlay.SetPlayLengthMs(1500)
|
v.heroRenderInfo[d2enum.HeroNecromancer].BackWalkSpriteOverlay.SetPlayLengthMs(1500)
|
||||||
v.heroRenderInfo[d2enum.HeroNecromancer].BackWalkSpriteOverlay.SetPlayLoop(false)
|
v.heroRenderInfo[d2enum.HeroNecromancer].BackWalkSpriteOverlay.SetPlayLoop(false)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[d2enum.HeroPaladin] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroPaladin] = &HeroRenderInfo{
|
||||||
d2enum.HeroStanceIdle,
|
d2enum.HeroStanceIdle,
|
||||||
loadSprite(d2resource.CharacterSelectPaladinUnselected, d2resource.PaletteFechar),
|
loadSprite(d2resource.CharacterSelectPaladinUnselected, d2resource.PaletteFechar),
|
||||||
@ -331,8 +307,7 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.heroRenderInfo[d2enum.HeroPaladin].BackWalkSprite.PlayForward()
|
v.heroRenderInfo[d2enum.HeroPaladin].BackWalkSprite.PlayForward()
|
||||||
v.heroRenderInfo[d2enum.HeroPaladin].BackWalkSprite.SetPlayLengthMs(1300)
|
v.heroRenderInfo[d2enum.HeroPaladin].BackWalkSprite.SetPlayLengthMs(1300)
|
||||||
v.heroRenderInfo[d2enum.HeroPaladin].BackWalkSprite.SetPlayLoop(false)
|
v.heroRenderInfo[d2enum.HeroPaladin].BackWalkSprite.SetPlayLoop(false)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[d2enum.HeroAmazon] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroAmazon] = &HeroRenderInfo{
|
||||||
d2enum.HeroStanceIdle,
|
d2enum.HeroStanceIdle,
|
||||||
loadSprite(d2resource.CharacterSelectAmazonUnselected, d2resource.PaletteFechar),
|
loadSprite(d2resource.CharacterSelectAmazonUnselected, d2resource.PaletteFechar),
|
||||||
@ -364,8 +339,7 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.heroRenderInfo[d2enum.HeroAmazon].BackWalkSprite.PlayForward()
|
v.heroRenderInfo[d2enum.HeroAmazon].BackWalkSprite.PlayForward()
|
||||||
v.heroRenderInfo[d2enum.HeroAmazon].BackWalkSprite.SetPlayLengthMs(1500)
|
v.heroRenderInfo[d2enum.HeroAmazon].BackWalkSprite.SetPlayLengthMs(1500)
|
||||||
v.heroRenderInfo[d2enum.HeroAmazon].BackWalkSprite.SetPlayLoop(false)
|
v.heroRenderInfo[d2enum.HeroAmazon].BackWalkSprite.SetPlayLoop(false)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[d2enum.HeroAssassin] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroAssassin] = &HeroRenderInfo{
|
||||||
d2enum.HeroStanceIdle,
|
d2enum.HeroStanceIdle,
|
||||||
loadSprite(d2resource.CharacterSelectAssassinUnselected, d2resource.PaletteFechar),
|
loadSprite(d2resource.CharacterSelectAssassinUnselected, d2resource.PaletteFechar),
|
||||||
@ -397,8 +371,7 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.heroRenderInfo[d2enum.HeroAssassin].BackWalkSprite.PlayForward()
|
v.heroRenderInfo[d2enum.HeroAssassin].BackWalkSprite.PlayForward()
|
||||||
v.heroRenderInfo[d2enum.HeroAssassin].BackWalkSprite.SetPlayLengthMs(1500)
|
v.heroRenderInfo[d2enum.HeroAssassin].BackWalkSprite.SetPlayLengthMs(1500)
|
||||||
v.heroRenderInfo[d2enum.HeroAssassin].BackWalkSprite.SetPlayLoop(false)
|
v.heroRenderInfo[d2enum.HeroAssassin].BackWalkSprite.SetPlayLoop(false)
|
||||||
},
|
|
||||||
func() {
|
|
||||||
v.heroRenderInfo[d2enum.HeroDruid] = &HeroRenderInfo{
|
v.heroRenderInfo[d2enum.HeroDruid] = &HeroRenderInfo{
|
||||||
d2enum.HeroStanceIdle,
|
d2enum.HeroStanceIdle,
|
||||||
loadSprite(d2resource.CharacterSelectDruidUnselected, d2resource.PaletteFechar),
|
loadSprite(d2resource.CharacterSelectDruidUnselected, d2resource.PaletteFechar),
|
||||||
@ -430,16 +403,17 @@ func (v *SelectHeroClass) Load() []func() {
|
|||||||
v.heroRenderInfo[d2enum.HeroDruid].BackWalkSprite.PlayForward()
|
v.heroRenderInfo[d2enum.HeroDruid].BackWalkSprite.PlayForward()
|
||||||
v.heroRenderInfo[d2enum.HeroDruid].BackWalkSprite.SetPlayLengthMs(1500)
|
v.heroRenderInfo[d2enum.HeroDruid].BackWalkSprite.SetPlayLengthMs(1500)
|
||||||
v.heroRenderInfo[d2enum.HeroDruid].BackWalkSprite.SetPlayLoop(false)
|
v.heroRenderInfo[d2enum.HeroDruid].BackWalkSprite.SetPlayLoop(false)
|
||||||
},
|
|
||||||
}
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) Unload() {
|
func (v *SelectHeroClass) OnUnload() error {
|
||||||
for i := range v.heroRenderInfo {
|
for i := range v.heroRenderInfo {
|
||||||
v.heroRenderInfo[i].SelectSfx.Stop()
|
v.heroRenderInfo[i].SelectSfx.Stop()
|
||||||
v.heroRenderInfo[i].DeselectSfx.Stop()
|
v.heroRenderInfo[i].DeselectSfx.Stop()
|
||||||
}
|
}
|
||||||
v.heroRenderInfo = nil
|
v.heroRenderInfo = nil
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v SelectHeroClass) onExitButtonClicked() {
|
func (v SelectHeroClass) onExitButtonClicked() {
|
||||||
@ -451,7 +425,7 @@ func (v SelectHeroClass) onOkButtonClicked() {
|
|||||||
d2scene.SetNextScene(CreateGame(gameState))
|
d2scene.SetNextScene(CreateGame(gameState))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) Render(screen d2render.Surface) {
|
func (v *SelectHeroClass) Render(screen d2render.Surface) error {
|
||||||
v.bgImage.RenderSegmented(screen, 4, 3, 0)
|
v.bgImage.RenderSegmented(screen, 4, 3, 0)
|
||||||
v.headingLabel.Render(screen)
|
v.headingLabel.Render(screen)
|
||||||
if v.selectedHero != d2enum.HeroNone {
|
if v.selectedHero != d2enum.HeroNone {
|
||||||
@ -476,9 +450,11 @@ func (v *SelectHeroClass) Render(screen d2render.Surface) {
|
|||||||
v.expansionCharLabel.Render(screen)
|
v.expansionCharLabel.Render(screen)
|
||||||
v.hardcoreCharLabel.Render(screen)
|
v.hardcoreCharLabel.Render(screen)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) Advance(tickTime float64) {
|
func (v *SelectHeroClass) Advance(tickTime float64) error {
|
||||||
canSelect := true
|
canSelect := true
|
||||||
v.campfire.Advance(tickTime)
|
v.campfire.Advance(tickTime)
|
||||||
for _, info := range v.heroRenderInfo {
|
for _, info := range v.heroRenderInfo {
|
||||||
@ -499,6 +475,7 @@ func (v *SelectHeroClass) Advance(tickTime float64) {
|
|||||||
}
|
}
|
||||||
v.heroNameTextbox.Update()
|
v.heroNameTextbox.Update()
|
||||||
v.okButton.SetEnabled(len(v.heroNameTextbox.GetText()) >= 2)
|
v.okButton.SetEnabled(len(v.heroNameTextbox.GetText()) >= 2)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *SelectHeroClass) updateHeroSelectionHover(hero d2enum.Hero, canSelect bool) {
|
func (v *SelectHeroClass) updateHeroSelectionHover(hero d2enum.Hero, canSelect bool) {
|
||||||
|
342
main.go
342
main.go
@ -1,7 +1,12 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
"gopkg.in/alecthomas/kingpin.v2"
|
"gopkg.in/alecthomas/kingpin.v2"
|
||||||
|
|
||||||
@ -9,7 +14,6 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2data/d2datadict"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2enum"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2fileformats/d2mpq"
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
"github.com/OpenDiablo2/OpenDiablo2/d2common/d2resource"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2gamescene"
|
"github.com/OpenDiablo2/OpenDiablo2/d2game/d2gamescene"
|
||||||
|
|
||||||
@ -17,14 +21,13 @@ import (
|
|||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio"
|
||||||
ebiten2 "github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio/ebiten"
|
ebiten2 "github.com/OpenDiablo2/OpenDiablo2/d2core/d2audio/ebiten"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2config"
|
||||||
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2gui"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2input"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render/ebiten"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2render/ebiten"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2scene"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2term"
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
"github.com/OpenDiablo2/OpenDiablo2/d2core/d2ui"
|
||||||
|
|
||||||
"github.com/OpenDiablo2/OpenDiablo2/d2game"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// GitBranch is set by the CI build process to the name of the branch
|
// GitBranch is set by the CI build process to the name of the branch
|
||||||
@ -33,13 +36,19 @@ var GitBranch string
|
|||||||
// GitCommit is set by the CI build process to the commit hash
|
// GitCommit is set by the CI build process to the commit hash
|
||||||
var GitCommit string
|
var GitCommit string
|
||||||
|
|
||||||
|
var singleton struct {
|
||||||
|
lastTime float64
|
||||||
|
showFPS bool
|
||||||
|
timeScale float64
|
||||||
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
if len(GitBranch) == 0 {
|
if len(GitBranch) == 0 {
|
||||||
d2common.SetBuildInfo("Local Build", "")
|
GitBranch = "Local Build"
|
||||||
} else {
|
|
||||||
d2common.SetBuildInfo(GitBranch, GitCommit)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
d2common.SetBuildInfo(GitBranch, GitCommit)
|
||||||
|
|
||||||
region := kingpin.Arg("region", "Region type id").Int()
|
region := kingpin.Arg("region", "Region type id").Int()
|
||||||
preset := kingpin.Arg("preset", "Level preset").Int()
|
preset := kingpin.Arg("preset", "Level preset").Int()
|
||||||
kingpin.Parse()
|
kingpin.Parse()
|
||||||
@ -47,7 +56,7 @@ func main() {
|
|||||||
log.SetFlags(log.Lshortfile)
|
log.SetFlags(log.Lshortfile)
|
||||||
log.Println("OpenDiablo2 - Open source Diablo 2 engine")
|
log.Println("OpenDiablo2 - Open source Diablo 2 engine")
|
||||||
|
|
||||||
if err := initializeEverything(); err != nil {
|
if err := initialize(); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,28 +66,222 @@ func main() {
|
|||||||
d2scene.SetNextScene(d2gamescene.CreateMapEngineTest(*region, *preset))
|
d2scene.SetNextScene(d2gamescene.CreateMapEngineTest(*region, *preset))
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d2game.Run(GitBranch); err != nil {
|
windowTitle := fmt.Sprintf("OpenDiablo2 (%s)", GitBranch)
|
||||||
|
if err := d2render.Run(update, 800, 600, windowTitle); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadStrings() error {
|
func initialize() error {
|
||||||
tablePaths := []string{
|
singleton.timeScale = 1.0
|
||||||
d2resource.PatchStringTable,
|
singleton.lastTime = d2common.Now()
|
||||||
d2resource.ExpansionStringTable,
|
|
||||||
d2resource.StringTable,
|
if err := d2config.Initialize(); err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tablePath := range tablePaths {
|
config, err := d2config.Get()
|
||||||
data, err := d2asset.LoadFile(tablePath)
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
d2resource.LanguageCode = config.Language
|
||||||
|
|
||||||
|
renderer, err := ebiten.CreateRenderer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
d2common.LoadDictionary(data)
|
if err := d2render.Initialize(renderer); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2render.SetWindowIcon("d2logo.png"); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2asset.Initialize(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2input.Initialize(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2gui.Initialize(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2term.Initialize(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d2term.BindLogger()
|
||||||
|
d2term.BindAction("fullscreen", "toggles fullscreen", func() {
|
||||||
|
fullscreen, err := d2render.IsFullScreen()
|
||||||
|
if err == nil {
|
||||||
|
fullscreen = !fullscreen
|
||||||
|
d2render.SetFullScreen(fullscreen)
|
||||||
|
d2term.OutputInfo("fullscreen is now: %v", fullscreen)
|
||||||
|
} else {
|
||||||
|
d2term.OutputError(err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
d2term.BindAction("vsync", "toggles vsync", func() {
|
||||||
|
vsync, err := d2render.GetVSyncEnabled()
|
||||||
|
if err == nil {
|
||||||
|
vsync = !vsync
|
||||||
|
d2render.SetVSyncEnabled(vsync)
|
||||||
|
d2term.OutputInfo("vsync is now: %v", vsync)
|
||||||
|
} else {
|
||||||
|
d2term.OutputError(err.Error())
|
||||||
|
}
|
||||||
|
})
|
||||||
|
d2term.BindAction("fps", "toggle fps counter", func() {
|
||||||
|
singleton.showFPS = !singleton.showFPS
|
||||||
|
d2term.OutputInfo("fps counter is now: %v", singleton.showFPS)
|
||||||
|
})
|
||||||
|
d2term.BindAction("timescale", "set scalar for elapsed time", func(timeScale float64) {
|
||||||
|
if timeScale <= 0 {
|
||||||
|
d2term.OutputError("invalid time scale value")
|
||||||
|
} else {
|
||||||
|
d2term.OutputInfo("timescale changed from %f to %f", singleton.timeScale, timeScale)
|
||||||
|
singleton.timeScale = timeScale
|
||||||
|
}
|
||||||
|
})
|
||||||
|
d2term.BindAction("quit", "exits the game", func() {
|
||||||
|
os.Exit(0)
|
||||||
|
})
|
||||||
|
|
||||||
|
audioProvider, err := ebiten2.CreateAudio()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2audio.Initialize(audioProvider); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2audio.SetVolumes(config.BgmVolume, config.SfxVolume); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := loadDataDict(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := loadPalettes(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := loadStrings(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d2ui.Initialize()
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func update(target d2render.Surface) error {
|
||||||
|
currentTime := d2common.Now()
|
||||||
|
elapsedTime := (currentTime - singleton.lastTime) * singleton.timeScale
|
||||||
|
singleton.lastTime = currentTime
|
||||||
|
|
||||||
|
if err := advance(elapsedTime); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := render(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if target.GetDepth() > 0 {
|
||||||
|
return errors.New("detected surface stack leak")
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func advance(elapsed float64) error {
|
||||||
|
if err := d2scene.Advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d2ui.Advance(elapsed)
|
||||||
|
|
||||||
|
if err := d2input.Advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2gui.Advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2term.Advance(elapsed); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func render(target d2render.Surface) error {
|
||||||
|
if err := d2scene.Render(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
d2ui.Render(target)
|
||||||
|
|
||||||
|
if err := d2gui.Render(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := d2term.Render(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := renderDebug(target); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func renderDebug(target d2render.Surface) error {
|
||||||
|
if singleton.showFPS {
|
||||||
|
vsyncEnabled, err := d2render.GetVSyncEnabled()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fps, err := d2render.CurrentFPS()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
target.PushTranslation(5, 565)
|
||||||
|
target.DrawText("vsync:" + strconv.FormatBool(vsyncEnabled) + "\nFPS:" + strconv.Itoa(int(fps)))
|
||||||
|
target.Pop()
|
||||||
|
|
||||||
|
cx, cy, err := d2render.GetCursorPos()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
var m runtime.MemStats
|
||||||
|
runtime.ReadMemStats(&m)
|
||||||
|
target.PushTranslation(680, 0)
|
||||||
|
target.DrawText("Alloc " + strconv.FormatInt(int64(m.Alloc)/1024/1024, 10))
|
||||||
|
target.PushTranslation(0, 16)
|
||||||
|
target.DrawText("Pause " + strconv.FormatInt(int64(m.PauseTotalNs/1024/1024), 10))
|
||||||
|
target.PushTranslation(0, 16)
|
||||||
|
target.DrawText("HeapSys " + strconv.FormatInt(int64(m.HeapSys/1024/1024), 10))
|
||||||
|
target.PushTranslation(0, 16)
|
||||||
|
target.DrawText("NumGC " + strconv.FormatInt(int64(m.NumGC), 10))
|
||||||
|
target.PushTranslation(0, 16)
|
||||||
|
target.DrawText("Coords " + strconv.FormatInt(int64(cx), 10) + "," + strconv.FormatInt(int64(cy), 10))
|
||||||
|
target.PopN(5)
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("Loaded %d entries from the string table", d2common.GetDictionaryEntryCount())
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,110 +352,21 @@ func loadDataDict() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadLoadingSprite() (*d2ui.Sprite, error) {
|
func loadStrings() error {
|
||||||
animation, err := d2asset.LoadAnimation(d2resource.LoadingScreen, d2resource.PaletteLoading)
|
tablePaths := []string{
|
||||||
if err != nil {
|
d2resource.PatchStringTable,
|
||||||
return nil, err
|
d2resource.ExpansionStringTable,
|
||||||
|
d2resource.StringTable,
|
||||||
}
|
}
|
||||||
|
|
||||||
loadingSprite, err := d2ui.LoadSprite(animation)
|
for _, tablePath := range tablePaths {
|
||||||
if err != nil {
|
data, err := d2asset.LoadFile(tablePath)
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
loadingSpriteSizeX, loadingSpriteSizeY := loadingSprite.GetCurrentFrameSize()
|
|
||||||
loadingSprite.SetPosition(400-(loadingSpriteSizeX/2), 300+(loadingSpriteSizeY/2))
|
|
||||||
return loadingSprite, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadCursorSprite() (*d2ui.Sprite, error) {
|
|
||||||
animation, err := d2asset.LoadAnimation(d2resource.CursorDefault, d2resource.PaletteUnits)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorSprite, err := d2ui.LoadSprite(animation)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return cursorSprite, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func initializeEverything() error {
|
|
||||||
if err := d2config.Initialize(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
config, err := d2config.Get()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d2resource.LanguageCode = config.Language
|
|
||||||
|
|
||||||
renderer, err := ebiten.CreateRenderer()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d2render.Initialize(renderer); err != nil {
|
d2common.LoadDictionary(data)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := d2render.SetWindowIcon("d2logo.png"); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := d2input.Initialize(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := d2term.Initialize(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d2term.BindLogger()
|
|
||||||
|
|
||||||
d2mpq.InitializeCryptoBuffer()
|
|
||||||
if err := d2asset.Initialize(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
audioProvider, err := ebiten2.CreateAudio()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := d2audio.Initialize(audioProvider); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := d2audio.SetVolumes(config.BgmVolume, config.SfxVolume); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := loadDataDict(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := loadPalettes(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := loadStrings(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cursorSprite, err := loadCursorSprite()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d2ui.Initialize(cursorSprite)
|
|
||||||
|
|
||||||
loadingSprite, err := loadLoadingSprite()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d2game.Initialize(loadingSprite)
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user