ui: Scale is now float64 (#236)

This commit is contained in:
Hajime Hoshi 2016-06-19 02:59:17 +09:00
parent 42332c7b49
commit bb511b2c13
11 changed files with 59 additions and 60 deletions

View File

@ -107,7 +107,7 @@ func main() {
}
canvasImage.Fill(color.White)
if err := ebiten.Run(update, screenWidth, screenHeight, 2, "Paint (Ebiten Demo)"); err != nil {
if err := ebiten.Run(update, screenWidth, screenHeight, 1.5, "Paint (Ebiten Demo)"); err != nil {
log.Fatal(err)
}
}

View File

@ -30,11 +30,11 @@ type graphicsContext struct {
f func(*Image) error
offscreen *Image
screen *Image
screenScale int
screenScale float64
initialized bool
}
func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) error {
func (c *graphicsContext) SetSize(screenWidth, screenHeight int, screenScale float64) error {
if c.screen != nil {
c.screen.Dispose()
}
@ -45,7 +45,9 @@ func (c *graphicsContext) SetSize(screenWidth, screenHeight, screenScale int) er
if err != nil {
return err
}
c.screen, err = newImageWithScreenFramebuffer(screenWidth*screenScale, screenHeight*screenScale)
w := int(float64(screenWidth) * screenScale)
h := int(float64(screenHeight) * screenScale)
c.screen, err = newImageWithScreenFramebuffer(w, h)
if err != nil {
return err
}

View File

@ -98,12 +98,12 @@ func (c *runContext) setRunningSlowly(isRunningSlowly bool) {
}
type GraphicsContext interface {
SetSize(width, height, scale int) error
SetSize(width, height int, scale float64) error
UpdateAndDraw() error
Draw() error
}
func Run(g GraphicsContext, width, height, scale int, title string, fps int) error {
func Run(g GraphicsContext, width, height int, scale float64, title string, fps int) error {
if currentRunContext != nil {
return errors.New("loop: The game is already running")
}

View File

@ -20,7 +20,7 @@ type CloseEvent struct {
type ScreenSizeEvent struct {
Width int
Height int
ActualScale int
ActualScale float64
}
type RenderEvent struct {

View File

@ -20,8 +20,6 @@
package ui
import (
"math"
glfw "github.com/go-gl/glfw/v3.1/glfw"
)
@ -31,7 +29,7 @@ var glfwMouseButtonToMouseButton = map[glfw.MouseButton]MouseButton{
glfw.MouseButtonMiddle: MouseButtonMiddle,
}
func (i *input) update(window *glfw.Window, scale int) error {
func (i *input) update(window *glfw.Window, scale float64) error {
i.m.Lock()
defer i.m.Unlock()
@ -42,8 +40,8 @@ func (i *input) update(window *glfw.Window, scale int) error {
i.mouseButtonPressed[e] = window.GetMouseButton(g) == glfw.Press
}
x, y := window.GetCursorPos()
i.cursorX = int(math.Floor(x)) / scale
i.cursorY = int(math.Floor(y)) / scale
i.cursorX = int(x / scale)
i.cursorY = int(y / scale)
for id := glfw.Joystick(0); id < glfw.Joystick(len(i.gamepads)); id++ {
if !glfw.JoystickPresent(id) {
continue

View File

@ -15,11 +15,11 @@
package ui
type UserInterface interface {
Start(width, height, scale int, title string) error
Start(width, height int, scale float64, title string) error
Update() (interface{}, error)
SwapBuffers() error
Terminate() error
ScreenScale() int
ScreenScale() float64
SetScreenSize(width, height int) bool
SetScreenScale(scale int) bool
SetScreenScale(scale float64) bool
}

View File

@ -32,9 +32,9 @@ type userInterface struct {
window *glfw.Window
width int
height int
scale int
scale float64
deviceScale float64
framebufferScale int
framebufferScale float64
context *opengl.Context
funcs chan func()
sizeChanged bool
@ -125,7 +125,7 @@ func (u *userInterface) SetScreenSize(width, height int) bool {
return r
}
func (u *userInterface) SetScreenScale(scale int) bool {
func (u *userInterface) SetScreenScale(scale float64) bool {
r := false
u.runOnMainThread(func() {
r = u.setScreenSize(u.width, u.height, scale)
@ -133,22 +133,21 @@ func (u *userInterface) SetScreenScale(scale int) bool {
return r
}
func (u *userInterface) ScreenScale() int {
s := 0
func (u *userInterface) ScreenScale() float64 {
s := 0.0
u.runOnMainThread(func() {
s = u.scale
})
return s
}
func (u *userInterface) Start(width, height, scale int, title string) error {
func (u *userInterface) Start(width, height int, scale float64, title string) error {
var err error
u.runOnMainThread(func() {
m := glfw.GetPrimaryMonitor()
v := m.GetVideoMode()
u.deviceScale = deviceScale()
u.framebufferScale = 1
if !u.setScreenSize(width, height, scale) {
err = errors.New("ui: Fail to set the screen size")
return
@ -156,18 +155,18 @@ func (u *userInterface) Start(width, height, scale int, title string) error {
u.window.SetTitle(title)
u.window.Show()
x := (v.Width - width*u.windowScale()) / 2
y := (v.Height - height*u.windowScale()) / 3
x := (v.Width - int(float64(width)*u.windowScale())) / 2
y := (v.Height - int(float64(height)*u.windowScale())) / 3
u.window.SetPos(x, y)
})
return err
}
func (u *userInterface) windowScale() int {
return u.scale * int(u.deviceScale)
func (u *userInterface) windowScale() float64 {
return u.scale * u.deviceScale
}
func (u *userInterface) actualScreenScale() int {
func (u *userInterface) actualScreenScale() float64 {
return u.windowScale() * u.framebufferScale
}
@ -260,7 +259,7 @@ func (u *userInterface) FinishRendering() error {
return nil
}
func (u *userInterface) setScreenSize(width, height, scale int) bool {
func (u *userInterface) setScreenSize(width, height int, scale float64) bool {
if u.width == width && u.height == height && u.scale == scale {
return false
}
@ -273,7 +272,7 @@ func (u *userInterface) setScreenSize(width, height, scale int) bool {
// To prevent hanging up, return asap if the width is too small.
// 252 is an arbitrary number and I guess this is small enough.
const minWindowWidth = 252
if width*u.actualScreenScale() < minWindowWidth {
if int(float64(width)*u.actualScreenScale()) < minWindowWidth {
u.scale = origScale
return false
}
@ -290,7 +289,7 @@ func (u *userInterface) setScreenSize(width, height, scale int) bool {
window.SetFramebufferSizeCallback(nil)
close(ch)
})
window.SetSize(width*u.windowScale(), height*u.windowScale())
window.SetSize(int(float64(width)*u.windowScale()), int(float64(height)*u.windowScale()))
event:
for {
@ -303,7 +302,7 @@ event:
}
// This is usually 1, but sometimes more than 1 (e.g. Retina Mac)
fw, _ := window.GetFramebufferSize()
u.framebufferScale = fw / width / u.windowScale()
u.framebufferScale = float64(fw) / float64(width) / u.windowScale()
u.sizeChanged = true
return true
}

View File

@ -26,7 +26,7 @@ import (
var canvas *js.Object
type userInterface struct {
scale int
scale float64
deviceScale float64
sizeChanged bool
}
@ -66,17 +66,17 @@ func (u *userInterface) SetScreenSize(width, height int) bool {
return u.setScreenSize(width, height, u.scale)
}
func (u *userInterface) SetScreenScale(scale int) bool {
func (u *userInterface) SetScreenScale(scale float64) bool {
width, height := u.size()
return u.setScreenSize(width, height, scale)
}
func (u *userInterface) ScreenScale() int {
func (u *userInterface) ScreenScale() float64 {
return u.scale
}
func (u *userInterface) ActualScreenScale() int {
return u.scale * int(u.deviceScale)
func (u *userInterface) ActualScreenScale() float64 {
return u.scale * u.deviceScale
}
func (u *userInterface) Update() (interface{}, error) {
@ -122,8 +122,8 @@ func touchEventToTouches(e *js.Object) []touch {
for i := 0; i < len(t); i++ {
jj := j.Call("item", i)
t[i].id = jj.Get("identifier").Int()
t[i].x = (jj.Get("clientX").Int() - left) / scale
t[i].y = (jj.Get("clientY").Int() - top) / scale
t[i].x = int(float64(jj.Get("clientX").Int()-left) / scale)
t[i].y = int(float64(jj.Get("clientY").Int()-top) / scale)
}
return t
}
@ -242,7 +242,7 @@ func setMouseCursorFromEvent(e *js.Object) {
x, y := e.Get("clientX").Int(), e.Get("clientY").Int()
x -= rect.Get("left").Int()
y -= rect.Get("top").Int()
currentInput.setMouseCursor(x/scale, y/scale)
currentInput.setMouseCursor(int(float64(x)/scale), int(float64(y)/scale))
}
func devicePixelRatio() float64 {
@ -258,7 +258,7 @@ func Main() error {
return nil
}
func (u *userInterface) Start(width, height, scale int, title string) error {
func (u *userInterface) Start(width, height int, scale float64, title string) error {
doc := js.Global.Get("document")
doc.Set("title", title)
u.setScreenSize(width, height, scale)
@ -277,7 +277,7 @@ func (u *userInterface) size() (width, height int) {
return
}
func (u *userInterface) setScreenSize(width, height, scale int) bool {
func (u *userInterface) setScreenSize(width, height int, scale float64) bool {
w, h := u.size()
s := u.scale
if w == width && h == height && s == scale {
@ -285,12 +285,12 @@ func (u *userInterface) setScreenSize(width, height, scale int) bool {
}
u.scale = scale
u.deviceScale = devicePixelRatio()
canvas.Set("width", width*u.ActualScreenScale())
canvas.Set("height", height*u.ActualScreenScale())
canvas.Set("width", int(float64(width)*u.ActualScreenScale()))
canvas.Set("height", int(float64(height)*u.ActualScreenScale()))
canvasStyle := canvas.Get("style")
cssWidth := width * scale
cssHeight := height * scale
cssWidth := int(float64(width) * scale)
cssHeight := int(float64(height) * scale)
canvasStyle.Set("width", strconv.Itoa(cssWidth)+"px")
canvasStyle.Set("height", strconv.Itoa(cssHeight)+"px")
// CSS calc requires space chars.

View File

@ -76,7 +76,7 @@ loop:
type userInterface struct {
width int
height int
scale int
scale float64
sizeChanged bool
}
@ -94,7 +94,7 @@ func CurrentUI() UserInterface {
return currentUI
}
func (u *userInterface) Start(width, height, scale int, title string) error {
func (u *userInterface) Start(width, height int, scale float64, title string) error {
u.width = width
u.height = height
u.scale = scale
@ -135,17 +135,17 @@ func (u *userInterface) SetScreenSize(width, height int) bool {
return false
}
func (u *userInterface) SetScreenScale(scale int) bool {
func (u *userInterface) SetScreenScale(scale float64) bool {
// TODO: Implement
return false
}
func (u *userInterface) ScreenScale() int {
func (u *userInterface) ScreenScale() float64 {
return u.scale
}
func (u *userInterface) actualScreenScale() int {
return u.scale * int(deviceScale())
func (u *userInterface) actualScreenScale() float64 {
return u.scale * deviceScale()
}
func UpdateTouches(touches []Touch) {

View File

@ -29,7 +29,7 @@ var chError <-chan error
type EventDispatcher interface {
SetScreenSize(width, height int)
SetScreenScale(scale int)
SetScreenScale(scale float64)
Render() error
UpdateTouchesOnAndroid(action int, id int, x, y int)
UpdateTouchesOnIOS(phase int, ptr int, x, y int)
@ -38,7 +38,7 @@ type EventDispatcher interface {
// Start starts the game and returns immediately.
//
// Different from ebiten.Run, this invokes only the game loop and not the main (UI) loop.
func Start(f func(*ebiten.Image) error, width, height, scale int, title string) (EventDispatcher, error) {
func Start(f func(*ebiten.Image) error, width, height int, scale float64, title string) (EventDispatcher, error) {
chError = ebiten.RunWithoutMainLoop(f, width, height, scale, title)
return &eventDispatcher{
touches: map[int]position{},
@ -58,7 +58,7 @@ func (e *eventDispatcher) SetScreenSize(width, height int) {
ui.CurrentUI().SetScreenSize(width, height)
}
func (e *eventDispatcher) SetScreenScale(scale int) {
func (e *eventDispatcher) SetScreenScale(scale float64) {
ui.CurrentUI().SetScreenScale(scale)
}
@ -81,8 +81,8 @@ func (t touch) ID() int {
func (t touch) Position() (int, int) {
// TODO: Is this OK to adjust the position here?
return t.position.x / ui.CurrentUI().ScreenScale(),
t.position.y / ui.CurrentUI().ScreenScale()
return int(float64(t.position.x) / ui.CurrentUI().ScreenScale()),
int(float64(t.position.y) / ui.CurrentUI().ScreenScale())
}
// UpdateTouchesOnAndroid updates the touch state on Android.

8
run.go
View File

@ -53,7 +53,7 @@ func IsRunningSlowly() bool {
// The given function f is guaranteed to be called 60 times a second
// even if a rendering frame is skipped.
// f is not called when the screen is not shown.
func Run(f func(*Image) error, width, height, scale int, title string) error {
func Run(f func(*Image) error, width, height int, scale float64, title string) error {
ch := make(chan error)
go func() {
g := newGraphicsContext(f)
@ -68,7 +68,7 @@ func Run(f func(*Image) error, width, height, scale int, title string) error {
//
// Typically, Ebiten users don't have to call this directly.
// Instead, functions in github.com/hajimehoshi/ebiten/mobile module call this.
func RunWithoutMainLoop(f func(*Image) error, width, height, scale int, title string) <-chan error {
func RunWithoutMainLoop(f func(*Image) error, width, height int, scale float64, title string) <-chan error {
ch := make(chan error)
go func() {
g := newGraphicsContext(f)
@ -94,7 +94,7 @@ func SetScreenSize(width, height int) {
// SetScreenScale changes the scale of the screen.
//
// This function is concurrent-safe.
func SetScreenScale(scale int) {
func SetScreenScale(scale float64) {
if scale <= 0 {
panic("ebiten: scale must be positive")
}
@ -104,6 +104,6 @@ func SetScreenScale(scale int) {
// ScreenScale returns the current screen scale.
//
// This function is concurrent-safe.
func ScreenScale() int {
func ScreenScale() float64 {
return ui.CurrentUI().ScreenScale()
}