First day
This commit is contained in:
commit
845a7d3aba
|
@ -0,0 +1 @@
|
||||||
|
build
|
|
@ -0,0 +1,32 @@
|
||||||
|
# Build dependencies
|
||||||
|
GO = tinygo
|
||||||
|
WASM_OPT = wasm-opt
|
||||||
|
|
||||||
|
# Whether to build for debugging instead of release
|
||||||
|
DEBUG = 0
|
||||||
|
|
||||||
|
# Compilation flags
|
||||||
|
GOFLAGS = -target ./target.json -panic trap
|
||||||
|
ifeq ($(DEBUG), 1)
|
||||||
|
GOFLAGS += -opt 1
|
||||||
|
else
|
||||||
|
GOFLAGS += -opt z -no-debug
|
||||||
|
endif
|
||||||
|
|
||||||
|
# wasm-opt flags
|
||||||
|
WASM_OPT_FLAGS = -Oz --zero-filled-memory --strip-producers --enable-bulk-memory
|
||||||
|
|
||||||
|
all:
|
||||||
|
@mkdir -p build
|
||||||
|
$(GO) build $(GOFLAGS) -o build/cart.wasm .
|
||||||
|
ifneq ($(DEBUG), 1)
|
||||||
|
ifeq (, $(shell command -v $(WASM_OPT)))
|
||||||
|
@echo Tip: $(WASM_OPT) was not found. Install it from binaryen for smaller builds!
|
||||||
|
else
|
||||||
|
$(WASM_OPT) $(WASM_OPT_FLAGS) build/cart.wasm -o build/cart.wasm
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf build
|
|
@ -0,0 +1,26 @@
|
||||||
|
# newyearkrendelki
|
||||||
|
|
||||||
|
A game written in Go for the [WASM-4](https://wasm4.org) fantasy console.
|
||||||
|
|
||||||
|
## Building
|
||||||
|
|
||||||
|
Build the cart by running:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
make
|
||||||
|
```
|
||||||
|
|
||||||
|
Then run it with:
|
||||||
|
|
||||||
|
```shell
|
||||||
|
w4 run build/cart.wasm
|
||||||
|
```
|
||||||
|
|
||||||
|
For more info about setting up WASM-4, see the [quickstart guide](https://wasm4.org/docs/getting-started/setup?code-lang=go#quickstart).
|
||||||
|
|
||||||
|
## Links
|
||||||
|
|
||||||
|
- [Documentation](https://wasm4.org/docs): Learn more about WASM-4.
|
||||||
|
- [Snake Tutorial](https://wasm4.org/docs/tutorials/snake/goal): Learn how to build a complete game
|
||||||
|
with a step-by-step tutorial.
|
||||||
|
- [GitHub](https://github.com/aduros/wasm4): Submit an issue or PR. Contributions are welcome!
|
|
@ -0,0 +1,65 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"cart/w4"
|
||||||
|
"math/rand"
|
||||||
|
)
|
||||||
|
|
||||||
|
var smiley = [8]byte{
|
||||||
|
0b11000011,
|
||||||
|
0b10000001,
|
||||||
|
0b00100100,
|
||||||
|
0b00100100,
|
||||||
|
0b00000000,
|
||||||
|
0b00100100,
|
||||||
|
0b10011001,
|
||||||
|
0b11000011,
|
||||||
|
}
|
||||||
|
|
||||||
|
var gravity = 0.2
|
||||||
|
var points []*Point = []*Point{}
|
||||||
|
var sticks []*Stick = []*Stick{}
|
||||||
|
var player *Player
|
||||||
|
var frame uint64 = 0
|
||||||
|
var lightIndex uint64 = 0
|
||||||
|
|
||||||
|
//go:export start
|
||||||
|
func start() {
|
||||||
|
rand.Seed(654654321348654)
|
||||||
|
points = []*Point{}
|
||||||
|
sticks = []*Stick{}
|
||||||
|
w4.PALETTE[0] = 0xfcdeea
|
||||||
|
w4.PALETTE[1] = 0x012824
|
||||||
|
w4.PALETTE[2] = 0x265935
|
||||||
|
w4.PALETTE[3] = 0xff4d6d
|
||||||
|
player = &Player{
|
||||||
|
Position: Vector{80, 80},
|
||||||
|
Speed: Vector{},
|
||||||
|
Gamepad: w4.GAMEPAD1,
|
||||||
|
}
|
||||||
|
for i := 0; i < 4; i++ {
|
||||||
|
p, s := CreateRope(
|
||||||
|
Vector{0, rand.Float64()*40 + float64(i*40)},
|
||||||
|
Vector{160, rand.Float64()*40 + float64(i*40)},
|
||||||
|
15,
|
||||||
|
)
|
||||||
|
points = append(points, p...)
|
||||||
|
sticks = append(sticks, s...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//go:export update
|
||||||
|
func update() {
|
||||||
|
frame += 1
|
||||||
|
*w4.DRAW_COLORS = 2
|
||||||
|
// w4.Text("Hello from Go!", 10, 10)
|
||||||
|
Simulate(points, sticks)
|
||||||
|
for _, s := range sticks {
|
||||||
|
s.Draw()
|
||||||
|
}
|
||||||
|
for _, p := range points {
|
||||||
|
p.Draw()
|
||||||
|
}
|
||||||
|
player.Update()
|
||||||
|
player.Draw()
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "cart/w4"
|
||||||
|
|
||||||
|
type Player struct {
|
||||||
|
Position Vector
|
||||||
|
Speed Vector
|
||||||
|
PointGrabbed *Point
|
||||||
|
GrabTimeout uint
|
||||||
|
Offset float64
|
||||||
|
Gamepad *uint8
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Update() {
|
||||||
|
p.Speed.X = 0
|
||||||
|
if p.GrabTimeout > 0 {
|
||||||
|
p.GrabTimeout--
|
||||||
|
}
|
||||||
|
if *p.Gamepad&w4.BUTTON_LEFT != 0 {
|
||||||
|
p.Speed.X -= 1
|
||||||
|
}
|
||||||
|
if *p.Gamepad&w4.BUTTON_RIGHT != 0 {
|
||||||
|
p.Speed.X += 1
|
||||||
|
}
|
||||||
|
isJumping := *p.Gamepad&w4.BUTTON_DOWN == 0
|
||||||
|
p.Speed.Y += gravity
|
||||||
|
if p.PointGrabbed != nil {
|
||||||
|
p.Speed.Y = 0
|
||||||
|
p.Position = p.PointGrabbed.Position
|
||||||
|
if *p.Gamepad&w4.BUTTON_2 != 0 {
|
||||||
|
p.GrabTimeout = 10
|
||||||
|
if isJumping {
|
||||||
|
p.GrabTimeout = 5
|
||||||
|
p.Speed.Y = -4.5
|
||||||
|
}
|
||||||
|
p.PointGrabbed = nil
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
p.Position.Move(p.Speed.X, p.Speed.Y)
|
||||||
|
if *p.Gamepad&w4.BUTTON_DOWN == 0 && p.GrabTimeout == 0 {
|
||||||
|
for _, point := range points {
|
||||||
|
diff := p.Position.Sub(point.Position)
|
||||||
|
if diff.LenSquared() < 25 {
|
||||||
|
// nearPoints = append(nearPoints, p)
|
||||||
|
*w4.DRAW_COLORS = 0x44
|
||||||
|
w4.Rect(int(point.Position.X), int(point.Position.Y), 3, 3)
|
||||||
|
p.PointGrabbed = point
|
||||||
|
point.PreviousPosition.Move(-p.Speed.X*2, -p.Speed.Y*2)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Player) Draw() {
|
||||||
|
*w4.DRAW_COLORS = 0x34
|
||||||
|
w4.Rect(int(p.Position.X)-4, int(p.Position.Y)-4, 8, 8)
|
||||||
|
}
|
|
@ -0,0 +1,104 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"cart/w4"
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Point struct {
|
||||||
|
Position Vector
|
||||||
|
PreviousPosition Vector
|
||||||
|
IsLocked bool
|
||||||
|
TimeOffset uint64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Point) Draw() {
|
||||||
|
*w4.DRAW_COLORS = 0x31
|
||||||
|
fr := (frame + p.TimeOffset) % 60
|
||||||
|
if fr > 20 {
|
||||||
|
*w4.DRAW_COLORS = 0x32
|
||||||
|
}
|
||||||
|
if fr > 40 {
|
||||||
|
*w4.DRAW_COLORS = 0x34
|
||||||
|
}
|
||||||
|
w4.Oval(int(p.Position.X)-2, int(p.Position.Y)-2, 4, 4)
|
||||||
|
}
|
||||||
|
|
||||||
|
type Stick struct {
|
||||||
|
PointA *Point
|
||||||
|
PointB *Point
|
||||||
|
Length float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stick) Draw() {
|
||||||
|
*w4.DRAW_COLORS = 0x3
|
||||||
|
w4.Line(int(s.PointA.Position.X), int(s.PointA.Position.Y),
|
||||||
|
int(s.PointB.Position.X), int(s.PointB.Position.Y))
|
||||||
|
}
|
||||||
|
|
||||||
|
func Simulate(points []*Point, sticks []*Stick) {
|
||||||
|
for _, p := range points {
|
||||||
|
if !p.IsLocked {
|
||||||
|
positionBeforeUpdate := p.Position
|
||||||
|
diff := p.Position.Sub(p.PreviousPosition)
|
||||||
|
p.Position = p.Position.Sum(diff)
|
||||||
|
p.Position.Y += gravity
|
||||||
|
p.PreviousPosition = positionBeforeUpdate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cycles := 20
|
||||||
|
for i := 0; i < cycles; i++ {
|
||||||
|
for _, s := range sticks {
|
||||||
|
centerX := (s.PointA.Position.X + s.PointB.Position.X) / 2
|
||||||
|
centerY := (s.PointA.Position.Y + s.PointB.Position.Y) / 2
|
||||||
|
diff := s.PointA.Position.Sub(s.PointB.Position)
|
||||||
|
direction := diff.Normalized()
|
||||||
|
if !s.PointA.IsLocked {
|
||||||
|
s.PointA.Position.X = centerX + direction.X*s.Length/2
|
||||||
|
s.PointA.Position.Y = centerY + direction.Y*s.Length/2
|
||||||
|
}
|
||||||
|
if !s.PointB.IsLocked {
|
||||||
|
s.PointB.Position.X = centerX - direction.X*s.Length/2
|
||||||
|
s.PointB.Position.Y = centerY - direction.Y*s.Length/2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func CreateRope(start Vector, end Vector, divisions int) ([]*Point, []*Stick) {
|
||||||
|
var points []*Point = []*Point{}
|
||||||
|
var sticks []*Stick = []*Stick{}
|
||||||
|
for i := 0; i <= divisions; i++ {
|
||||||
|
k := float64(i) / float64(divisions)
|
||||||
|
diffX := end.X - start.X
|
||||||
|
diffY := end.Y - start.Y
|
||||||
|
posX := start.X + diffX*k
|
||||||
|
posY := start.Y + diffY*k
|
||||||
|
pos := Vector{posX, posY}
|
||||||
|
// w4.Trace("Point created at " + pos.String())
|
||||||
|
point := Point{
|
||||||
|
Position: pos,
|
||||||
|
PreviousPosition: pos,
|
||||||
|
IsLocked: (i == 0 || i == divisions),
|
||||||
|
TimeOffset: lightIndex * 153,
|
||||||
|
}
|
||||||
|
lightIndex++
|
||||||
|
if i != 0 {
|
||||||
|
lastPoint := points[len(points)-1]
|
||||||
|
diffX := pos.X - lastPoint.Position.X
|
||||||
|
diffY := pos.Y - lastPoint.Position.Y
|
||||||
|
len := math.Sqrt(diffX*diffX + diffY*diffY)
|
||||||
|
w4.Trace("Length between points is " + strconv.FormatFloat(len, 'f', 3, 64))
|
||||||
|
stick := Stick{
|
||||||
|
PointA: lastPoint,
|
||||||
|
PointB: &point,
|
||||||
|
Length: len,
|
||||||
|
}
|
||||||
|
sticks = append(sticks, &stick)
|
||||||
|
}
|
||||||
|
points = append(points, &point)
|
||||||
|
}
|
||||||
|
return points, sticks
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"llvm-target": "wasm32--wasi",
|
||||||
|
"build-tags": [ "tinygo.wasm" ],
|
||||||
|
"goos": "js",
|
||||||
|
"goarch": "wasm",
|
||||||
|
"linker": "wasm-ld",
|
||||||
|
"libc": "wasi-libc",
|
||||||
|
"cflags": [
|
||||||
|
"--target=wasm32--wasi",
|
||||||
|
"--sysroot={root}/lib/wasi-libc/sysroot",
|
||||||
|
"-Oz"
|
||||||
|
],
|
||||||
|
"ldflags": [
|
||||||
|
"--allow-undefined",
|
||||||
|
"--no-demangle",
|
||||||
|
"--import-memory",
|
||||||
|
"--initial-memory=65536",
|
||||||
|
"--max-memory=65536",
|
||||||
|
"--stack-first",
|
||||||
|
"-zstack-size=14752",
|
||||||
|
"--strip-all"
|
||||||
|
],
|
||||||
|
"wasm-abi": "js"
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Vector struct {
|
||||||
|
X float64
|
||||||
|
Y float64
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) String() string {
|
||||||
|
return "(" + strconv.FormatFloat(v.X, 'f', 3, 64) + "; " + strconv.FormatFloat(v.Y, 'f', 3, 64) + ")"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) LenSquared() float64 {
|
||||||
|
return v.X*v.X + v.Y*v.Y
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) Len() float64 {
|
||||||
|
return math.Sqrt(v.LenSquared())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) Sum(v2 Vector) Vector {
|
||||||
|
return Vector{
|
||||||
|
v.X + v2.X,
|
||||||
|
v.Y + v2.Y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) Sub(v2 Vector) Vector {
|
||||||
|
return Vector{
|
||||||
|
v.X - v2.X,
|
||||||
|
v.Y - v2.Y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) MulScalar(c float64) Vector {
|
||||||
|
return Vector{
|
||||||
|
v.X * c,
|
||||||
|
v.Y * c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) DivScalar(c float64) Vector {
|
||||||
|
return Vector{
|
||||||
|
v.X * c,
|
||||||
|
v.Y * c,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) Normalized() Vector {
|
||||||
|
len := math.Sqrt(v.X*v.X + v.Y*v.Y)
|
||||||
|
x := v.X / len
|
||||||
|
y := v.Y / len
|
||||||
|
return Vector{x, y}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Vector) Move(x float64, y float64) {
|
||||||
|
v.X += x
|
||||||
|
v.Y += y
|
||||||
|
}
|
|
@ -0,0 +1,141 @@
|
||||||
|
//
|
||||||
|
// WASM-4: https://wasm4.org/docs
|
||||||
|
|
||||||
|
package w4
|
||||||
|
|
||||||
|
import "unsafe"
|
||||||
|
|
||||||
|
// ┌───────────────────────────────────────────────────────────────────────────┐
|
||||||
|
// │ │
|
||||||
|
// │ Platform Constants │
|
||||||
|
// │ │
|
||||||
|
// └───────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
const SCREEN_SIZE int = 160
|
||||||
|
|
||||||
|
// ┌───────────────────────────────────────────────────────────────────────────┐
|
||||||
|
// │ │
|
||||||
|
// │ Memory Addresses │
|
||||||
|
// │ │
|
||||||
|
// └───────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
var PALETTE = (*[4]uint32)(unsafe.Pointer(uintptr(0x04)))
|
||||||
|
var DRAW_COLORS = (*uint16)(unsafe.Pointer(uintptr(0x14)))
|
||||||
|
var GAMEPAD1 = (*uint8)(unsafe.Pointer(uintptr(0x16)))
|
||||||
|
var GAMEPAD2 = (*uint8)(unsafe.Pointer(uintptr(0x17)))
|
||||||
|
var GAMEPAD3 = (*uint8)(unsafe.Pointer(uintptr(0x18)))
|
||||||
|
var GAMEPAD4 = (*uint8)(unsafe.Pointer(uintptr(0x19)))
|
||||||
|
var MOUSE_X = (*int16)(unsafe.Pointer(uintptr(0x1a)))
|
||||||
|
var MOUSE_Y = (*int16)(unsafe.Pointer(uintptr(0x1c)))
|
||||||
|
var MOUSE_BUTTONS = (*uint8)(unsafe.Pointer(uintptr(0x1e)))
|
||||||
|
var SYSTEM_FLAGS = (*uint8)(unsafe.Pointer(uintptr(0x1f)));
|
||||||
|
var NETPLAY = (*uint8)(unsafe.Pointer(uintptr(0x20)));
|
||||||
|
var FRAMEBUFFER = (*[6400]uint8)(unsafe.Pointer(uintptr(0xa0)))
|
||||||
|
|
||||||
|
const BUTTON_1 byte = 1
|
||||||
|
const BUTTON_2 byte = 2
|
||||||
|
const BUTTON_LEFT byte = 16
|
||||||
|
const BUTTON_RIGHT byte = 32
|
||||||
|
const BUTTON_UP byte = 64
|
||||||
|
const BUTTON_DOWN byte = 128
|
||||||
|
|
||||||
|
const MOUSE_LEFT byte = 1
|
||||||
|
const MOUSE_RIGHT byte = 2
|
||||||
|
const MOUSE_MIDDLE byte = 4
|
||||||
|
|
||||||
|
const SYSTEM_PRESERVE_FRAMEBUFFER byte = 1
|
||||||
|
const SYSTEM_HIDE_GAMEPAD_OVERLAY byte = 2
|
||||||
|
|
||||||
|
// ┌───────────────────────────────────────────────────────────────────────────┐
|
||||||
|
// │ │
|
||||||
|
// │ Drawing Functions │
|
||||||
|
// │ │
|
||||||
|
// └───────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
/** Copies pixels to the framebuffer. */
|
||||||
|
//go:export blit
|
||||||
|
func Blit(sprite *byte, x int, y int, width uint, height uint, flags uint)
|
||||||
|
|
||||||
|
/** Copies a subregion within a larger sprite atlas to the framebuffer. */
|
||||||
|
//go:export blitSub
|
||||||
|
func BlitSub(sprite *byte, x int, y int, width uint, height uint,
|
||||||
|
srcX uint, srcY uint, stride int, flags uint)
|
||||||
|
|
||||||
|
const BLIT_2BPP = 1
|
||||||
|
const BLIT_1BPP = 0
|
||||||
|
const BLIT_FLIP_X = 2
|
||||||
|
const BLIT_FLIP_Y = 4
|
||||||
|
const BLIT_ROTATE = 8
|
||||||
|
|
||||||
|
/** Draws a line between two points. */
|
||||||
|
//go:export line
|
||||||
|
func Line(x1 int, y1 int, x2 int, y2 int)
|
||||||
|
|
||||||
|
/** Draws a horizontal line. */
|
||||||
|
//go:export hline
|
||||||
|
func HLine(x int, y int, len uint)
|
||||||
|
|
||||||
|
/** Draws a vertical line. */
|
||||||
|
//go:export vline
|
||||||
|
func VLine(x int, y int, len uint)
|
||||||
|
|
||||||
|
/** Draws an oval (or circle). */
|
||||||
|
//go:export oval
|
||||||
|
func Oval(x int, y int, width uint, height uint)
|
||||||
|
|
||||||
|
/** Draws a rectangle. */
|
||||||
|
//go:export rect
|
||||||
|
func Rect(x int, y int, width uint, height uint)
|
||||||
|
|
||||||
|
/** Draws text using the built-in system font. */
|
||||||
|
//go:export textUtf8
|
||||||
|
func Text(text string, x int, y int)
|
||||||
|
|
||||||
|
// ┌───────────────────────────────────────────────────────────────────────────┐
|
||||||
|
// │ │
|
||||||
|
// │ Sound Functions │
|
||||||
|
// │ │
|
||||||
|
// └───────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
/** Plays a sound tone. */
|
||||||
|
//go:export tone
|
||||||
|
func Tone(frequency uint, duration uint, volume uint, flags uint)
|
||||||
|
|
||||||
|
const TONE_PULSE1 = 0
|
||||||
|
const TONE_PULSE2 = 1
|
||||||
|
const TONE_TRIANGLE = 2
|
||||||
|
const TONE_NOISE = 3
|
||||||
|
const TONE_MODE1 = 0
|
||||||
|
const TONE_MODE2 = 4
|
||||||
|
const TONE_MODE3 = 8
|
||||||
|
const TONE_MODE4 = 12
|
||||||
|
const TONE_PAN_LEFT = 16
|
||||||
|
const TONE_PAN_RIGHT = 32
|
||||||
|
|
||||||
|
// ┌───────────────────────────────────────────────────────────────────────────┐
|
||||||
|
// │ │
|
||||||
|
// │ Storage Functions │
|
||||||
|
// │ │
|
||||||
|
// └───────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
/** Reads up to `size` bytes from persistent storage into the pointer `destPtr`. */
|
||||||
|
//go:export diskr
|
||||||
|
func DiskR(ptr unsafe.Pointer, count uint) uint
|
||||||
|
|
||||||
|
/** Writes up to `size` bytes from the pointer `srcPtr` into persistent storage. */
|
||||||
|
//go:export diskw
|
||||||
|
func DiskW(src unsafe.Pointer, count uint) uint
|
||||||
|
|
||||||
|
// ┌───────────────────────────────────────────────────────────────────────────┐
|
||||||
|
// │ │
|
||||||
|
// │ Other Functions │
|
||||||
|
// │ │
|
||||||
|
// └───────────────────────────────────────────────────────────────────────────┘
|
||||||
|
|
||||||
|
/** Prints a message to the debug console. */
|
||||||
|
//go:export traceUtf8
|
||||||
|
func Trace(str string)
|
||||||
|
|
||||||
|
// TinyGo requires a main function, so provide one
|
||||||
|
//go:linkname main main.main
|
||||||
|
func main() {}
|
Loading…
Reference in New Issue