Skip to content

Commit 00d8f84

Browse files
committed
Make low-level API safer to use
mem package is unsafe to use. User might set screen size without updating data slice. Same for sprite-sheet. Also, mem package duplicates a lot information which might be confusing for user (for example which package mem or pi the source of truth?) Also, functions like pi.Boot() or pi.Run() are hard to understand. User has to remember than after specifying the new screen size he has to boot the game again. This change is a huge one. It removes mem package completely and instead it introduces new functions: * SetScreenSize * UseEmptySpriteSheet * SetCustomFontWidth * SetCustomFontSpecialWidth * SetCustomFontHeight
1 parent f4295a2 commit 00d8f84

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

59 files changed

+1114
-1330
lines changed

controller.go

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package pi
55

66
import (
77
"github.com/elgopher/pi/internal/input"
8-
"github.com/elgopher/pi/mem"
98
)
109

1110
// Button is a virtual button on any game controller. The game controller can be a gamepad or a keyboard.
@@ -21,14 +20,22 @@ type Button int
2120
// First connected gamepad controller is player 0, second player 1 and so on.
2221
// On XBox controller [O] is A and Y, [X] is B and X.
2322
const (
24-
Left = mem.ControllerLeft
25-
Right = mem.ControllerRight
26-
Up = mem.ControllerUp
27-
Down = mem.ControllerDown
28-
O = mem.ControllerO // O is a first fire button
29-
X = mem.ControllerX // X is a second fire button
23+
Left = 0
24+
Right = 1
25+
Up = 2
26+
Down = 3
27+
O = 4 // O is a first fire button
28+
X = 5 // X is a second fire button
3029
)
3130

31+
var Controllers [8]Controller // 0th element is for Player 0, 1st for Player 1 etc.
32+
33+
type Controller struct {
34+
// BtnDuration is how many frames button was pressed:
35+
// Index of array is equal to controller button constant.
36+
BtnDuration [6]uint
37+
}
38+
3239
// Btn returns true if a controller button is being pressed at this moment by player 0.
3340
func Btn(button Button) bool {
3441
return BtnPlayer(button, 0)
@@ -87,15 +94,15 @@ func buttonDuration(player int, button Button) uint {
8794
return 0
8895
}
8996

90-
return mem.Controllers[player].BtnDuration[button]
97+
return Controllers[player].BtnDuration[button]
9198
}
9299

93100
func isPressed(duration uint) bool {
94101
return duration > 0
95102
}
96103

97104
func buttonBits(player int, isSet func(uint) bool) int {
98-
c := mem.Controllers[player]
105+
c := Controllers[player]
99106
var b int
100107
for i := 0; i <= X; i++ {
101108
if isSet(c.BtnDuration[i]) {

defaults.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33

44
package pi
55

6-
import "github.com/elgopher/pi/mem"
6+
import (
7+
"github.com/elgopher/pi/image"
8+
)
79

810
const (
911
defaultSpriteSheetWidth = 128
@@ -14,7 +16,7 @@ const (
1416

1517
var (
1618
//nolint:govet
17-
defaultPalette = [256]mem.RGB{
19+
defaultPalette = [256]image.RGB{
1820
{0, 0, 0}, // 0 - black
1921
{0x1D, 0x2B, 0x53}, // 1 - dark blue
2022
{0x7E, 0x25, 0x53}, // 2 - dark purple

devtools/control.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
package devtools
55

66
import (
7+
"github.com/elgopher/pi"
78
"github.com/elgopher/pi/devtools/internal/snapshot"
8-
"github.com/elgopher/pi/mem"
99
)
1010

1111
var (
@@ -15,12 +15,12 @@ var (
1515

1616
func pauseGame() {
1717
gamePaused = true
18-
timeWhenPaused = mem.TimeSeconds
18+
timeWhenPaused = pi.TimeSeconds
1919
snapshot.Take()
2020
}
2121

2222
func resumeGame() {
2323
gamePaused = false
24-
mem.TimeSeconds = timeWhenPaused
24+
pi.TimeSeconds = timeWhenPaused
2525
snapshot.Draw()
2626
}

devtools/devtools.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import (
88

99
"github.com/elgopher/pi"
1010
"github.com/elgopher/pi/devtools/internal/inspector"
11-
"github.com/elgopher/pi/mem"
1211
)
1312

1413
var (
@@ -18,7 +17,7 @@ var (
1817
FgColor byte = 7
1918
)
2019

21-
// MustRun runs the game using backend, similarly to pi.MustRun.
20+
// MustRun runs the game with devtools.
2221
//
2322
// Any time you can pause them game by pressing F12. This will
2423
// show screen inspector. F12 again resumes the game.
@@ -47,12 +46,14 @@ func MustRun(runBackend func() error) {
4746
}
4847
}
4948

50-
pi.MustRun(runBackend)
49+
if err := runBackend(); err != nil {
50+
panic(fmt.Sprintf("Something terrible happened! Pi cannot be run: %v\n", err))
51+
}
5152
}
5253

5354
func handleStoppedGame() {
54-
if mem.GameLoopStopped {
55+
if pi.GameLoopStopped {
5556
pauseGame()
56-
mem.GameLoopStopped = false
57+
pi.GameLoopStopped = false
5758
}
5859
}

devtools/internal/icons/icons.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@ var iconsPng []byte
2020

2121
var icons = pi.Font{
2222
Width: 4,
23-
WidthSpecial: 8,
23+
SpecialWidth: 8,
2424
Height: 8,
2525
}
2626

2727
func init() {
28-
if err := font.Load(iconsPng, icons.Data[:]); err != nil {
28+
var err error
29+
icons.Data, err = font.Load(iconsPng)
30+
if err != nil {
2931
panic(fmt.Sprintf("problem loading devtools icons %s", err))
3032
}
3133
}

devtools/internal/inspector/draw.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"github.com/elgopher/pi/devtools/internal/rgb"
1212
"github.com/elgopher/pi/devtools/internal/snapshot"
1313
"github.com/elgopher/pi/key"
14-
"github.com/elgopher/pi/mem"
1514
"github.com/elgopher/pi/snap"
1615
)
1716

@@ -37,17 +36,19 @@ func Draw() {
3736

3837
func cursorOutOfWindow() bool {
3938
x, y := pi.MousePos()
40-
return x < 0 || x >= mem.ScreenWidth || y < 0 || y >= mem.ScreenHeight
39+
screen := pi.Scr()
40+
return x < 0 || x >= screen.W || y < 0 || y >= screen.H
4141
}
4242

4343
func drawBar() {
44+
screen := pi.Scr()
4445
mouseX, mouseY := pi.MousePos()
4546
var barY int
4647
if !isBarOnTop {
47-
barY = mem.ScreenHeight - 7
48+
barY = screen.H - 7
4849
}
4950

50-
pi.RectFill(0, barY, mem.ScreenWidth, barY+6, BgColor)
51+
pi.RectFill(0, barY, screen.W, barY+6, BgColor)
5152

5253
textX := 1
5354
textY := barY + 1
@@ -77,7 +78,7 @@ func drawPointer() {
7778

7879
func choosePointerColor(x, y int) byte {
7980
c := pixelColorAtMouseCoords
80-
if rgb.BrightnessDelta(mem.Palette[FgColor], mem.Palette[c]) >= rgb.BrightnessDelta(mem.Palette[BgColor], mem.Palette[c]) {
81+
if rgb.BrightnessDelta(pi.Palette[FgColor], pi.Palette[c]) >= rgb.BrightnessDelta(pi.Palette[BgColor], pi.Palette[c]) {
8182
return FgColor
8283
}
8384

devtools/internal/inspector/inspector.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ package inspector
55

66
import (
77
"github.com/elgopher/pi"
8-
"github.com/elgopher/pi/mem"
98
)
109

1110
var isBarOnTop bool
@@ -15,7 +14,7 @@ func moveBarIfNeeded() {
1514
switch {
1615
case isBarOnTop && mouseY <= 12:
1716
isBarOnTop = false
18-
case !isBarOnTop && mouseY >= mem.ScreenHeight-12:
17+
case !isBarOnTop && mouseY >= pi.Scr().H-12:
1918
isBarOnTop = true
2019
}
2120
}

devtools/internal/rgb/rgb.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
package rgb
22

3-
import "github.com/elgopher/pi/mem"
3+
import (
4+
"github.com/elgopher/pi/image"
5+
)
46

5-
func BrightnessIndex(rgb mem.RGB) byte {
7+
func BrightnessIndex(rgb image.RGB) byte {
68
return byte((299*int(rgb.R) + 587*int(rgb.G) + 114*int(rgb.B)) / 1000)
79
}
810

9-
func BrightnessDelta(rgb1, rgb2 mem.RGB) byte {
11+
func BrightnessDelta(rgb1, rgb2 image.RGB) byte {
1012
i1 := BrightnessIndex(rgb1)
1113
i2 := BrightnessIndex(rgb2)
1214
if i1 > i2 {

devtools/internal/snapshot/snapshot.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,19 @@
44
package snapshot
55

66
import (
7-
"github.com/elgopher/pi/mem"
7+
"github.com/elgopher/pi"
88
)
99

1010
var snapshot []byte
1111

1212
func Take() {
13+
screen := pi.Scr()
1314
if snapshot == nil {
14-
snapshot = make([]byte, len(mem.ScreenData))
15+
snapshot = make([]byte, len(screen.Pix))
1516
}
16-
copy(snapshot, mem.ScreenData)
17+
copy(snapshot, screen.Pix)
1718
}
1819

1920
func Draw() {
20-
copy(mem.ScreenData, snapshot)
21+
copy(pi.Scr().Pix, snapshot)
2122
}

ebitengine/controller.go

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package ebitengine
66
import (
77
"github.com/hajimehoshi/ebiten/v2"
88

9-
"github.com/elgopher/pi/mem"
9+
"github.com/elgopher/pi"
1010
)
1111

1212
func updateController() {
@@ -16,12 +16,12 @@ func updateController() {
1616
}
1717

1818
func getController(player int) *controller {
19-
c := controller{&mem.Controllers[player]}
19+
c := controller{&pi.Controllers[player]}
2020
return &c
2121
}
2222

2323
type controller struct {
24-
*mem.Controller
24+
*pi.Controller
2525
}
2626

2727
func (c *controller) update(player int) {
@@ -37,32 +37,32 @@ func (c *controller) updateDirections(player int) {
3737

3838
if axisX < -0.5 ||
3939
ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonLeftLeft) ||
40-
isKeyboardPressed(player, mem.ControllerLeft) {
41-
c.BtnDuration[mem.ControllerLeft] += 1
42-
c.BtnDuration[mem.ControllerRight] = 0
40+
isKeyboardPressed(player, pi.Left) {
41+
c.BtnDuration[pi.Left] += 1
42+
c.BtnDuration[pi.Right] = 0
4343
} else if axisX > 0.5 ||
4444
ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonLeftRight) ||
45-
isKeyboardPressed(player, mem.ControllerRight) {
46-
c.BtnDuration[mem.ControllerRight] += 1
47-
c.BtnDuration[mem.ControllerLeft] = 0
45+
isKeyboardPressed(player, pi.Right) {
46+
c.BtnDuration[pi.Right] += 1
47+
c.BtnDuration[pi.Left] = 0
4848
} else {
49-
c.BtnDuration[mem.ControllerRight] = 0
50-
c.BtnDuration[mem.ControllerLeft] = 0
49+
c.BtnDuration[pi.Right] = 0
50+
c.BtnDuration[pi.Left] = 0
5151
}
5252

5353
if axisY < -0.5 ||
5454
ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonLeftTop) ||
55-
isKeyboardPressed(player, mem.ControllerUp) {
56-
c.BtnDuration[mem.ControllerUp] += 1
57-
c.BtnDuration[mem.ControllerDown] = 0
55+
isKeyboardPressed(player, pi.Up) {
56+
c.BtnDuration[pi.Up] += 1
57+
c.BtnDuration[pi.Down] = 0
5858
} else if axisY > 0.5 ||
5959
ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonLeftBottom) ||
60-
isKeyboardPressed(player, mem.ControllerDown) {
61-
c.BtnDuration[mem.ControllerDown] += 1
62-
c.BtnDuration[mem.ControllerUp] = 0
60+
isKeyboardPressed(player, pi.Down) {
61+
c.BtnDuration[pi.Down] += 1
62+
c.BtnDuration[pi.Up] = 0
6363
} else {
64-
c.BtnDuration[mem.ControllerUp] = 0
65-
c.BtnDuration[mem.ControllerDown] = 0
64+
c.BtnDuration[pi.Up] = 0
65+
c.BtnDuration[pi.Down] = 0
6666
}
6767
}
6868

@@ -71,18 +71,18 @@ func (c *controller) updateFireButtons(player int) {
7171

7272
if ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonRightBottom) ||
7373
ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonRightTop) ||
74-
isKeyboardPressed(player, mem.ControllerO) {
75-
c.BtnDuration[mem.ControllerO] += 1
74+
isKeyboardPressed(player, pi.O) {
75+
c.BtnDuration[pi.O] += 1
7676
} else {
77-
c.BtnDuration[mem.ControllerO] = 0
77+
c.BtnDuration[pi.O] = 0
7878
}
7979

8080
if ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonRightRight) ||
8181
ebiten.IsStandardGamepadButtonPressed(gamepadID, ebiten.StandardGamepadButtonRightLeft) ||
82-
isKeyboardPressed(player, mem.ControllerX) {
83-
c.BtnDuration[mem.ControllerX] += 1
82+
isKeyboardPressed(player, pi.X) {
83+
c.BtnDuration[pi.X] += 1
8484
} else {
85-
c.BtnDuration[mem.ControllerX] = 0
85+
c.BtnDuration[pi.X] = 0
8686
}
8787
}
8888

0 commit comments

Comments
 (0)