From ed72ea4495a654157c803501f5fa3e4f60a2ae96 Mon Sep 17 00:00:00 2001 From: jiepengtan Date: Wed, 11 Dec 2024 09:51:33 +0800 Subject: [PATCH] Add a test demo: for debugging goroutine scheduling issues with igop on the web platform. --- audio.go | 3 +- cmd/ispx/.gitignore | 3 + cmd/ispx/README.md | 28 + cmd/ispx/build.bat | 9 + cmd/ispx/build.sh | 2 + cmd/ispx/go.mod | 54 ++ cmd/ispx/go.sum | 174 ++++++ cmd/ispx/index.html | 34 ++ cmd/ispx/main.go | 89 +++ cmd/ispx/pkg/github.com/goplus/spx/export.go | 276 ++++++++++ .../hajimehoshi/ebiten/v2/export.go | 519 ++++++++++++++++++ cmd/ispx/runner.html | 30 + cmd/ispx/runweb.sh | 11 + cmd/ispx/test.zip | Bin 0 -> 45135 bytes cmd/ispx/zipfs/zipfs.go | 179 ++++++ game.go | 63 ++- internal/audiorecord/audiorecord_nojs.go | 7 +- internal/coroutine/coro.go | 252 ++++++++- internal/coroutine/queue.go | 128 +++++ internal/time/time.go | 75 +++ sprite.go | 14 + tutorial/.gitignore | 5 + tutorial/05-Animation/.gitignore | 5 + tutorial/05-Animation/Bullet.spx | 4 - tutorial/05-Animation/SmallEnemy.spx | 38 +- .../assets/sprites/SmallEnemy/index.json | 10 - tutorial/05-Animation/runweb.sh | 47 ++ tutorial/06-CoroDebug/.gitignore | 5 + tutorial/06-CoroDebug/Bullet.spx | 18 + tutorial/06-CoroDebug/SmallEnemy.spx | 37 ++ tutorial/06-CoroDebug/assets/1.png | Bin 0 -> 12663 bytes tutorial/06-CoroDebug/assets/index.json | 13 + .../06-CoroDebug/assets/sounds/explode/1.wav | Bin 0 -> 9276 bytes .../assets/sounds/explode/index.json | 3 + .../06-CoroDebug/assets/sprites/Bullet/30.png | Bin 0 -> 803 bytes .../assets/sprites/Bullet/index.json | 20 + .../assets/sprites/SmallEnemy/32.png | Bin 0 -> 3441 bytes .../assets/sprites/SmallEnemy/33.png | Bin 0 -> 3959 bytes .../assets/sprites/SmallEnemy/34.png | Bin 0 -> 4388 bytes .../assets/sprites/SmallEnemy/35.png | Bin 0 -> 5980 bytes .../assets/sprites/SmallEnemy/36.png | Bin 0 -> 1981 bytes .../assets/sprites/SmallEnemy/index.json | 47 ++ tutorial/06-CoroDebug/main.spx | 3 + tutorial/06-CoroDebug/run.sh | 49 ++ 44 files changed, 2173 insertions(+), 81 deletions(-) create mode 100644 cmd/ispx/.gitignore create mode 100644 cmd/ispx/README.md create mode 100644 cmd/ispx/build.bat create mode 100644 cmd/ispx/build.sh create mode 100644 cmd/ispx/go.mod create mode 100644 cmd/ispx/go.sum create mode 100644 cmd/ispx/index.html create mode 100644 cmd/ispx/main.go create mode 100644 cmd/ispx/pkg/github.com/goplus/spx/export.go create mode 100644 cmd/ispx/pkg/github.com/hajimehoshi/ebiten/v2/export.go create mode 100644 cmd/ispx/runner.html create mode 100644 cmd/ispx/runweb.sh create mode 100644 cmd/ispx/test.zip create mode 100644 cmd/ispx/zipfs/zipfs.go create mode 100644 internal/coroutine/queue.go create mode 100644 internal/time/time.go create mode 100644 tutorial/.gitignore create mode 100644 tutorial/05-Animation/.gitignore create mode 100644 tutorial/05-Animation/runweb.sh create mode 100644 tutorial/06-CoroDebug/.gitignore create mode 100644 tutorial/06-CoroDebug/Bullet.spx create mode 100644 tutorial/06-CoroDebug/SmallEnemy.spx create mode 100644 tutorial/06-CoroDebug/assets/1.png create mode 100644 tutorial/06-CoroDebug/assets/index.json create mode 100644 tutorial/06-CoroDebug/assets/sounds/explode/1.wav create mode 100644 tutorial/06-CoroDebug/assets/sounds/explode/index.json create mode 100644 tutorial/06-CoroDebug/assets/sprites/Bullet/30.png create mode 100644 tutorial/06-CoroDebug/assets/sprites/Bullet/index.json create mode 100644 tutorial/06-CoroDebug/assets/sprites/SmallEnemy/32.png create mode 100644 tutorial/06-CoroDebug/assets/sprites/SmallEnemy/33.png create mode 100644 tutorial/06-CoroDebug/assets/sprites/SmallEnemy/34.png create mode 100644 tutorial/06-CoroDebug/assets/sprites/SmallEnemy/35.png create mode 100644 tutorial/06-CoroDebug/assets/sprites/SmallEnemy/36.png create mode 100644 tutorial/06-CoroDebug/assets/sprites/SmallEnemy/index.json create mode 100644 tutorial/06-CoroDebug/main.spx create mode 100644 tutorial/06-CoroDebug/run.sh diff --git a/audio.go b/audio.go index a2b28a20..8961aa75 100644 --- a/audio.go +++ b/audio.go @@ -211,6 +211,7 @@ func (p *soundMgr) play(media Sound, wait, loop bool) (err error) { return } + var doneVal bool var done chan bool if wait { done = make(chan bool, 1) @@ -218,7 +219,7 @@ func (p *soundMgr) play(media Sound, wait, loop bool) (err error) { p.addPlayer(sp, done) sp.Play() if wait { - waitForChan(done) + waitForChan(done, &doneVal) } return } diff --git a/cmd/ispx/.gitignore b/cmd/ispx/.gitignore new file mode 100644 index 00000000..67183955 --- /dev/null +++ b/cmd/ispx/.gitignore @@ -0,0 +1,3 @@ +# We build / Copy-paste them before running project +main.wasm +wasm_exec.js diff --git a/cmd/ispx/README.md b/cmd/ispx/README.md new file mode 100644 index 00000000..6bcd1acd --- /dev/null +++ b/cmd/ispx/README.md @@ -0,0 +1,28 @@ +# ispx for Go+ Builder + +## Introduction + +This package (ispx) is forked from [goplus/ispx](https://github.com/goplus/ispx) with some modification for fs, so that we can run a project packed in a zip file. + +## Prepare + +```sh +./build.sh +cp $GOROOT/misc/wasm/wasm_exec.js ./ +``` + +Then put zip file of the project you want to test under directory `ispx/`, with name `test.zip`. + +## Run + +Serve directory `ispx/` with any HTTP server & open `index.html` + +## Upgrade deps + +If we want to upgrade deps like [spx](https://github.com/goplus/spx). First Modify `go.mod` to upgrade dependencies, then do + +```sh +go mod tidy +go install github.com/goplus/igop/cmd/qexp@latest # `qexp` is required to do `go generate` +go generate # `qexp` will update `pkg/github.com/goplus/spx/export.go`, see detail in `main.go` (`//go:generate qexp ...`) +``` diff --git a/cmd/ispx/build.bat b/cmd/ispx/build.bat new file mode 100644 index 00000000..6ae0f625 --- /dev/null +++ b/cmd/ispx/build.bat @@ -0,0 +1,9 @@ +@echo off +setlocal + +set GOOS=js +set GOARCH=wasm + +go build -tags canvas -o main.wasm main.go + +endlocal diff --git a/cmd/ispx/build.sh b/cmd/ispx/build.sh new file mode 100644 index 00000000..501abe2a --- /dev/null +++ b/cmd/ispx/build.sh @@ -0,0 +1,2 @@ +#!/bin/sh +GOOS=js GOARCH=wasm go build -tags canvas -o main.wasm main.go \ No newline at end of file diff --git a/cmd/ispx/go.mod b/cmd/ispx/go.mod new file mode 100644 index 00000000..84a26d46 --- /dev/null +++ b/cmd/ispx/go.mod @@ -0,0 +1,54 @@ +module github.com/goplus/builder/ispx + +go 1.21 + +require ( + github.com/goplus/igop v0.27.1 + github.com/goplus/reflectx v1.2.2 + github.com/goplus/spx v1.0.1-0.20241029011511-845f2c0e2e74 + github.com/hajimehoshi/ebiten/v2 v2.8.0-alpha.3 +) + +require ( + github.com/ajstarks/svgo v0.0.0-20210927141636-6d70534b1098 // indirect + github.com/ebitengine/gomobile v0.0.0-20240518074828-e86332849895 // indirect + github.com/ebitengine/hideconsole v1.0.0 // indirect + github.com/ebitengine/oto/v3 v3.3.0-alpha.3 // indirect + github.com/ebitengine/purego v0.8.0-alpha.3 // indirect + github.com/esimov/stackblur-go v1.0.1-0.20190121110005-00e727e3c7a9 // indirect + github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect + github.com/goplus/canvas v0.1.0 // indirect + github.com/goplus/gogen v1.15.2 // indirect + github.com/goplus/gop v1.2.6 // indirect + github.com/goplus/mod v0.13.10 // indirect + github.com/hajimehoshi/go-mp3 v0.3.4 // indirect + github.com/jezek/xgb v1.1.1 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/qiniu/audio v0.2.1 // indirect + github.com/qiniu/x v1.13.10 // indirect + github.com/srwiley/oksvg v0.0.0-20210519022825-9fc0c575d5fe // indirect + github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 // indirect + github.com/timandy/routine v1.1.1 // indirect + github.com/visualfc/funcval v0.1.4 // indirect + github.com/visualfc/gid v0.1.0 // indirect + github.com/visualfc/goembed v0.3.2 // indirect + github.com/visualfc/xtype v0.2.0 // indirect + golang.org/x/image v0.18.0 // indirect + golang.org/x/mobile v0.0.0-20220518205345-8578da9835fd // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/sync v0.7.0 // indirect + golang.org/x/sys v0.22.0 // indirect + golang.org/x/text v0.16.0 // indirect + golang.org/x/tools v0.23.0 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect +) + +replace ( + github.com/goplus/spx => ../../ + github.com/hajimehoshi/oto => github.com/hajimehoshi/oto v1.0.1 + github.com/srwiley/oksvg => github.com/qiniu/oksvg v0.2.0-no-charset + golang.org/x/image => golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d + golang.org/x/mobile => golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5 + golang.org/x/mod => golang.org/x/mod v0.5.1 +) diff --git a/cmd/ispx/go.sum b/cmd/ispx/go.sum new file mode 100644 index 00000000..5007428d --- /dev/null +++ b/cmd/ispx/go.sum @@ -0,0 +1,174 @@ +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/ajstarks/deck v0.0.0-20200831202436-30c9fc6549a9/go.mod h1:JynElWSGnm/4RlzPXRlREEwqTHAN3T56Bv2ITsFT3gY= +github.com/ajstarks/deck/generate v0.0.0-20210309230005-c3f852c02e19/go.mod h1:T13YZdzov6OU0A1+RfKZiZN9ca6VeKdBdyDV+BY97Tk= +github.com/ajstarks/svgo v0.0.0-20210927141636-6d70534b1098 h1:iiPTCsr/y6MEke5leED5Bi/0zlznD44tlHQvTgLOJcE= +github.com/ajstarks/svgo v0.0.0-20210927141636-6d70534b1098/go.mod h1:1KcenG0jGWcpt8ov532z81sp/kMMUG485J2InIOyADM= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/ebitengine/gomobile v0.0.0-20240518074828-e86332849895 h1:48bCqKTuD7Z0UovDfvpCn7wZ0GUZ+yosIteNDthn3FU= +github.com/ebitengine/gomobile v0.0.0-20240518074828-e86332849895/go.mod h1:XZdLv05c5hOZm3fM2NlJ92FyEZjnslcMcNRrhxs8+8M= +github.com/ebitengine/hideconsole v1.0.0 h1:5J4U0kXF+pv/DhiXt5/lTz0eO5ogJ1iXb8Yj1yReDqE= +github.com/ebitengine/hideconsole v1.0.0/go.mod h1:hTTBTvVYWKBuxPr7peweneWdkUwEuHuB3C1R/ielR1A= +github.com/ebitengine/oto/v3 v3.3.0-alpha.3 h1:L8Odh8gVr4F+0CzSfqOfw/nEnXXWkB+UhGOKUYrP+Nk= +github.com/ebitengine/oto/v3 v3.3.0-alpha.3/go.mod h1:yYvXK7mgNwsFawY5RsvGI6yhMHtD+0MfaPkDTl9/uv8= +github.com/ebitengine/purego v0.8.0-alpha.3 h1:qoFlpGuVwJ6J85kuj6Qpyp0DBgxsNYfSY9efidSNFgA= +github.com/ebitengine/purego v0.8.0-alpha.3/go.mod h1:b94LtM1jUWDZPKDyENVhB0WsLdLWFApjbNw5AyxmKyI= +github.com/esimov/stackblur-go v1.0.1-0.20190121110005-00e727e3c7a9 h1:TJdKpA5v3Xu24Vv0yQy1MyRJgpt7vk9AT58fGPfiZcs= +github.com/esimov/stackblur-go v1.0.1-0.20190121110005-00e727e3c7a9/go.mod h1:a3zzeKuJKUpCcReHmEsuPaEnq42D2b/bHoCI8UjIuMY= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/gopherjs/gopherjs v0.0.0-20180708170036-38b413be4187/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/goplus/c2go v0.7.26/go.mod h1:ePAStubV/ls8mmdPGQo6VfADTVd46rKuBemE4zzBDnA= +github.com/goplus/canvas v0.1.0 h1:Vx3f2+U8UANvWf5/01YsQYKNbZDm1GZCjhlEBFrQkeU= +github.com/goplus/canvas v0.1.0/go.mod h1:Rhcvo5qkpD9WuXFnvnXtrBSY97l6h7sXQuofrmiLNdM= +github.com/goplus/gogen v1.15.2 h1:Q6XaSx/Zi5tWnjfAziYsQI6Jv6MgODRpFtOYqNkiiqM= +github.com/goplus/gogen v1.15.2/go.mod h1:92qEzVgv7y8JEFICWG9GvYI5IzfEkxYdsA1DbmnTkqk= +github.com/goplus/gop v1.2.6 h1:kog3c5Js+8EopqmI4+CwueXsqibnBwYVt5q5N7juRVY= +github.com/goplus/gop v1.2.6/go.mod h1:uREWbR1MrFaviZ4Mbx4ZCcAYDoqzO0iv1Qo6Np0Xx4E= +github.com/goplus/igop v0.27.1 h1:nLfk+2a8TZ1XvMb6XZnD6f1DlJ6Owj5We1gt6BMKqaI= +github.com/goplus/igop v0.27.1/go.mod h1:V8Kf/b4nrw0OPPodwnOYZPCpXvU+hqzuhSAXIToT0ME= +github.com/goplus/mod v0.13.10 h1:5Om6KOvo31daN7N30kWU1vC5zhsJPM+uPbcEN/FnlzE= +github.com/goplus/mod v0.13.10/go.mod h1:HDuPZgpWiaTp3PUolFgsiX+Q77cbUWB/mikVHfYND3c= +github.com/goplus/reflectx v1.2.2 h1:T1p20OIH/HcnAvQQNnDLwl6AZOjU34icsfc6migD6L8= +github.com/goplus/reflectx v1.2.2/go.mod h1:wHOS9ilbB4zrecI0W1dMmkW9JMcpXV7VjALVbNU9xfM= +github.com/hajimehoshi/ebiten/v2 v2.8.0-alpha.3 h1:cKpQdzW3I+iLID68l25GaxzPZHSZVRdE9/Pz4SOPBR8= +github.com/hajimehoshi/ebiten/v2 v2.8.0-alpha.3/go.mod h1:iKp1U/H0J0rv9X4ztGSTXCyN6z/DKKrUL+D9sjg7SbI= +github.com/hajimehoshi/go-mp3 v0.3.2/go.mod h1:qMJj/CSDxx6CGHiZeCgbiq2DSUkbK0UbtXShQcnfyMM= +github.com/hajimehoshi/go-mp3 v0.3.4 h1:NUP7pBYH8OguP4diaTZ9wJbUbk3tC0KlfzsEpWmYj68= +github.com/hajimehoshi/go-mp3 v0.3.4/go.mod h1:fRtZraRFcWb0pu7ok0LqyFhCUrPeMsGRSVop0eemFmo= +github.com/hajimehoshi/oto v1.0.1/go.mod h1:wovJ8WWMfFKvP587mhHgot/MBr4DnNy9m6EepeVGnos= +github.com/hajimehoshi/oto/v2 v2.3.1/go.mod h1:seWLbgHH7AyUMYKfKYT9pg7PhUu9/SisyJvNTT+ASQo= +github.com/jezek/xgb v1.1.1 h1:bE/r8ZZtSv7l9gk6nU0mYx51aXrvnyb44892TwSaqS4= +github.com/jezek/xgb v1.1.1/go.mod h1:nrhwO0FX/enq75I7Y7G8iN1ubpSGZEiA3v9e9GyRFlk= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/peterh/liner v1.2.2/go.mod h1:xFwJyiKIXJZUKItq5dGHZSTBRAuG/CpeNpWLyiNRNwI= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/qiniu/audio v0.2.1 h1:lAc3dWfr7uAfn7mfee2u0/fl/QSQA9oTOqdBtxyFZAM= +github.com/qiniu/audio v0.2.1/go.mod h1:APMJRPaS4toviejZnDzzZ8wVyr12jqZhd3xfKr/qYnE= +github.com/qiniu/oksvg v0.2.0-no-charset h1:KKQg81v52pd5VyaxrF891igoOO50epKfFWkryYgntnE= +github.com/qiniu/oksvg v0.2.0-no-charset/go.mod h1:YCAOS1HFo2kMxfcFCjrJMeo93KGFYaBAKl7LvrAkltQ= +github.com/qiniu/x v1.11.5/go.mod h1:03Ni9tj+N2h2aKnAz+6N0Xfl8FwMEDRC2PAlxekASDs= +github.com/qiniu/x v1.13.10 h1:J4Z3XugYzAq85SlyAfqlKVrbf05glMbAOh+QncsDQpE= +github.com/qiniu/x v1.13.10/go.mod h1:INZ2TSWSJVWO/RuELQROERcslBwVgFG7MkTfEdaQz9E= +github.com/srwiley/rasterx v0.0.0-20200120212402-85cb7272f5e9/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= +github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780 h1:oDMiXaTMyBEuZMU53atpxqYsSB3U1CHkeAu2zr6wTeY= +github.com/srwiley/rasterx v0.0.0-20210519020934-456a8d69b780/go.mod h1:mvWM0+15UqyrFKqdRjY6LuAVJR0HOVhJlEgZ5JWtSWU= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/timandy/routine v1.1.1 h1:6/Z7qLFZj3GrzuRksBFzIG8YGUh8CLhjnnMePBQTrEI= +github.com/timandy/routine v1.1.1/go.mod h1:OZHPOKSvqL/ZvqXFkNZyit0xIVelERptYXdAHH00adQ= +github.com/visualfc/funcval v0.1.4 h1:lAI88zQYfRzmC7mKF4+swXeCZvb8wb1f3lMSDRAY2mQ= +github.com/visualfc/funcval v0.1.4/go.mod h1:3Izv+irhArmrTvy+lmL6pIq16gSOzx73CIka51J9eR0= +github.com/visualfc/gid v0.1.0 h1:sg95vChDrUS5hngkfg4yxN6JAF6qIwwvJ+TC8cuZVto= +github.com/visualfc/gid v0.1.0/go.mod h1:YiRDLgdRp89d4OduAkhv5AAtc6XjUlx74IRLYofu3+E= +github.com/visualfc/goembed v0.3.2 h1:a9m6o9VTzNk3mEF98C8cHp8f8P8BblyjsjajXGfTp8w= +github.com/visualfc/goembed v0.3.2/go.mod h1:jCVCz/yTJGyslo6Hta+pYxWWBuq9ADCcIVZBTQ0/iVI= +github.com/visualfc/xtype v0.2.0 h1:0ESNXyWHtK01kaOzOyqHsR1ZjEPdNu/IWPZkf0VOHl8= +github.com/visualfc/xtype v0.2.0/go.mod h1:183MDtzLqyDkCm5zCH42vJGq/aQE5W25k3Z6UOZxLF0= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs= +golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM= +golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5 h1:peBP2oZO/xVnGMaWMCyFEI0WENsGj71wx5K12mRELHQ= +golang.org/x/mobile v0.0.0-20210902104108-5d9a33257ab5/go.mod h1:c4YKU3ZylDmvbw+H/PSvm42vhdWbuxCzbonauEAP9B8= +golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= +golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190429190828-d89cdac9e872/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220712014510-0a85c31ab51e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= +golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.1.3/go.mod h1:NgwopIslSNH47DimFoV78dnkksY2EFtX0ajyb3K/las= diff --git a/cmd/ispx/index.html b/cmd/ispx/index.html new file mode 100644 index 00000000..769aae84 --- /dev/null +++ b/cmd/ispx/index.html @@ -0,0 +1,34 @@ + + + + + + + Document + + + +

WASM data loading test

+ + + + + diff --git a/cmd/ispx/main.go b/cmd/ispx/main.go new file mode 100644 index 00000000..d24c0760 --- /dev/null +++ b/cmd/ispx/main.go @@ -0,0 +1,89 @@ +package main + +//go:generate qexp -outdir pkg github.com/goplus/spx +//go:generate qexp -outdir pkg github.com/hajimehoshi/ebiten/v2 + +import ( + "archive/zip" + "bytes" + "log" + "syscall/js" + + _ "github.com/goplus/builder/ispx/pkg/github.com/goplus/spx" + _ "github.com/goplus/builder/ispx/pkg/github.com/hajimehoshi/ebiten/v2" + "github.com/goplus/builder/ispx/zipfs" + "github.com/goplus/igop" + "github.com/goplus/igop/gopbuild" + _ "github.com/goplus/igop/pkg/fmt" + _ "github.com/goplus/igop/pkg/math" + _ "github.com/goplus/reflectx/icall/icall8192" + spxfs "github.com/goplus/spx/fs" +) + +var dataChannel = make(chan []byte) + +func loadData(this js.Value, args []js.Value) interface{} { + inputArray := args[0] + + // Convert Uint8Array to Go byte slice + length := inputArray.Get("length").Int() + goBytes := make([]byte, length) + js.CopyBytesToGo(goBytes, inputArray) + + dataChannel <- goBytes + return nil +} + +func main() { + js.Global().Set("goLoadData", js.FuncOf(loadData)) + + zipData := <-dataChannel + + zipReader, err := zip.NewReader(bytes.NewReader(zipData), int64(len(zipData))) + if err != nil { + log.Fatalln("Failed to read zip data:", err) + } + fs := zipfs.NewZipFsFromReader(zipReader) + // Configure spx to load project files from zip-based file system. + spxfs.RegisterSchema("", func(path string) (spxfs.Dir, error) { + return fs.Chrooted(path), nil + }) + + var mode igop.Mode + ctx := igop.NewContext(mode) + + // NOTE(everyone): Keep sync with the config in spx [gop.mod](https://github.com/goplus/spx/blob/main/gop.mod) + gopbuild.RegisterClassFileType(".spx", "Game", []*gopbuild.Class{{Ext: ".spx", Class: "SpriteImpl"}}, "github.com/goplus/spx") + + // Register patch for spx to support functions with generic type like `Gopt_Game_Gopx_GetWidget`. + // See details in https://github.com/goplus/builder/issues/765#issuecomment-2313915805 + err = gopbuild.RegisterPackagePatch(ctx, "github.com/goplus/spx", ` +package spx + +import ( + . "github.com/goplus/spx" +) + +func Gopt_Game_Gopx_GetWidget[T any](sg ShapeGetter, name string) *T { + widget := GetWidget_(sg, name) + if result, ok := widget.(interface{}).(*T); ok { + return result + } else { + panic("GetWidget: type mismatch") + } +} +`) + if err != nil { + log.Fatalln("Failed to register package patch:", err) + } + + source, err := gopbuild.BuildFSDir(ctx, fs, "") + if err != nil { + log.Fatalln("Failed to build Go+ source:", err) + } + println("code", string(source)) + code, err := ctx.RunFile("main.go", source, nil) + if err != nil { + log.Fatalln("Failed to run Go+ source:", err, " Code:", code) + } +} diff --git a/cmd/ispx/pkg/github.com/goplus/spx/export.go b/cmd/ispx/pkg/github.com/goplus/spx/export.go new file mode 100644 index 00000000..520c58f7 --- /dev/null +++ b/cmd/ispx/pkg/github.com/goplus/spx/export.go @@ -0,0 +1,276 @@ +// export by github.com/goplus/igop/cmd/qexp + +package spx + +import ( + q "github.com/goplus/spx" + + "go/constant" + "reflect" + + "github.com/goplus/igop" +) + +func init() { + igop.RegisterPackage(&igop.Package{ + Name: "spx", + Path: "github.com/goplus/spx", + Deps: map[string]string{ + "encoding/json": "json", + "errors": "errors", + "flag": "flag", + "fmt": "fmt", + "github.com/goplus/spx/fs": "fs", + "github.com/goplus/spx/fs/asset": "asset", + "github.com/goplus/spx/fs/zip": "zip", + "github.com/goplus/spx/internal/anim": "anim", + "github.com/goplus/spx/internal/audiorecord": "audiorecord", + "github.com/goplus/spx/internal/camera": "camera", + "github.com/goplus/spx/internal/coroutine": "coroutine", + "github.com/goplus/spx/internal/effect": "effect", + "github.com/goplus/spx/internal/gdi": "gdi", + "github.com/goplus/spx/internal/gdi/clrutil": "clrutil", + "github.com/goplus/spx/internal/gdi/font": "font", + "github.com/goplus/spx/internal/math32": "math32", + "github.com/goplus/spx/internal/time": "time", + "github.com/goplus/spx/internal/tools": "tools", + "github.com/hajimehoshi/ebiten/v2": "ebiten", + "github.com/hajimehoshi/ebiten/v2/audio": "audio", + "github.com/pkg/errors": "errors", + "github.com/qiniu/audio": "audio", + "github.com/qiniu/audio/convert": "convert", + "github.com/qiniu/audio/mp3": "mp3", + "github.com/qiniu/audio/wav": "wav", + "github.com/qiniu/audio/wav/adpcm": "adpcm", + "golang.org/x/image/colornames": "colornames", + "golang.org/x/image/font": "font", + "image": "image", + "image/color": "color", + "image/jpeg": "jpeg", + "image/png": "png", + "io": "io", + "log": "log", + "math": "math", + "math/rand": "rand", + "os": "os", + "path": "path", + "path/filepath": "filepath", + "reflect": "reflect", + "strconv": "strconv", + "strings": "strings", + "sync": "sync", + "sync/atomic": "atomic", + "syscall": "syscall", + "time": "time", + "unsafe": "unsafe", + }, + Interfaces: map[string]reflect.Type{ + "Gamer": reflect.TypeOf((*q.Gamer)(nil)).Elem(), + "IEventSinks": reflect.TypeOf((*q.IEventSinks)(nil)).Elem(), + "Shape": reflect.TypeOf((*q.Shape)(nil)).Elem(), + "ShapeGetter": reflect.TypeOf((*q.ShapeGetter)(nil)).Elem(), + "Sprite": reflect.TypeOf((*q.Sprite)(nil)).Elem(), + "Widget": reflect.TypeOf((*q.Widget)(nil)).Elem(), + }, + NamedTypes: map[string]reflect.Type{ + "Camera": reflect.TypeOf((*q.Camera)(nil)).Elem(), + "Collider": reflect.TypeOf((*q.Collider)(nil)).Elem(), + "Config": reflect.TypeOf((*q.Config)(nil)).Elem(), + "EffectKind": reflect.TypeOf((*q.EffectKind)(nil)).Elem(), + "Game": reflect.TypeOf((*q.Game)(nil)).Elem(), + "List": reflect.TypeOf((*q.List)(nil)).Elem(), + "Monitor": reflect.TypeOf((*q.Monitor)(nil)).Elem(), + "MovingInfo": reflect.TypeOf((*q.MovingInfo)(nil)).Elem(), + "PlayAction": reflect.TypeOf((*q.PlayAction)(nil)).Elem(), + "PlayOptions": reflect.TypeOf((*q.PlayOptions)(nil)).Elem(), + "RotationStyle": reflect.TypeOf((*q.RotationStyle)(nil)).Elem(), + "Sound": reflect.TypeOf((*q.Sound)(nil)).Elem(), + "SpriteImpl": reflect.TypeOf((*q.SpriteImpl)(nil)).Elem(), + "StopKind": reflect.TypeOf((*q.StopKind)(nil)).Elem(), + "TurningInfo": reflect.TypeOf((*q.TurningInfo)(nil)).Elem(), + "Value": reflect.TypeOf((*q.Value)(nil)).Elem(), + }, + AliasTypes: map[string]reflect.Type{ + "BackdropName": reflect.TypeOf((*string)(nil)).Elem(), + "Color": reflect.TypeOf((*q.Color)(nil)).Elem(), + "Key": reflect.TypeOf((*q.Key)(nil)).Elem(), + "Pos": reflect.TypeOf((*int)(nil)).Elem(), + "SoundName": reflect.TypeOf((*string)(nil)).Elem(), + "SpriteAnimationName": reflect.TypeOf((*string)(nil)).Elem(), + "SpriteCostumeName": reflect.TypeOf((*string)(nil)).Elem(), + "SpriteName": reflect.TypeOf((*string)(nil)).Elem(), + "WidgetName": reflect.TypeOf((*string)(nil)).Elem(), + }, + Vars: map[string]reflect.Value{}, + Funcs: map[string]reflect.Value{ + "Exit__0": reflect.ValueOf(q.Exit__0), + "Exit__1": reflect.ValueOf(q.Exit__1), + "GetWidget_": reflect.ValueOf(q.GetWidget_), + "Gopt_Game_Main": reflect.ValueOf(q.Gopt_Game_Main), + "Gopt_Game_Reload": reflect.ValueOf(q.Gopt_Game_Reload), + "Gopt_Game_Run": reflect.ValueOf(q.Gopt_Game_Run), + "Gopt_SpriteImpl_Clone__0": reflect.ValueOf(q.Gopt_SpriteImpl_Clone__0), + "Gopt_SpriteImpl_Clone__1": reflect.ValueOf(q.Gopt_SpriteImpl_Clone__1), + "Iround": reflect.ValueOf(q.Iround), + "RGB": reflect.ValueOf(q.RGB), + "RGBA": reflect.ValueOf(q.RGBA), + "Rand__0": reflect.ValueOf(q.Rand__0), + "Rand__1": reflect.ValueOf(q.Rand__1), + "Sched": reflect.ValueOf(q.Sched), + "SchedNow": reflect.ValueOf(q.SchedNow), + "SetDebug": reflect.ValueOf(q.SetDebug), + }, + TypedConsts: map[string]igop.TypedConst{ + "AllOtherScripts": {reflect.TypeOf(q.AllOtherScripts), constant.MakeInt64(int64(q.AllOtherScripts))}, + "AllSprites": {reflect.TypeOf(q.AllSprites), constant.MakeInt64(int64(q.AllSprites))}, + "AnimChannelFrame": {reflect.TypeOf(q.AnimChannelFrame), constant.MakeString(string(q.AnimChannelFrame))}, + "AnimChannelGlide": {reflect.TypeOf(q.AnimChannelGlide), constant.MakeString(string(q.AnimChannelGlide))}, + "AnimChannelMove": {reflect.TypeOf(q.AnimChannelMove), constant.MakeString(string(q.AnimChannelMove))}, + "AnimChannelTurn": {reflect.TypeOf(q.AnimChannelTurn), constant.MakeString(string(q.AnimChannelTurn))}, + "BrightnessEffect": {reflect.TypeOf(q.BrightnessEffect), constant.MakeInt64(int64(q.BrightnessEffect))}, + "ColorEffect": {reflect.TypeOf(q.ColorEffect), constant.MakeInt64(int64(q.ColorEffect))}, + "DbgFlagAll": {reflect.TypeOf(q.DbgFlagAll), constant.MakeInt64(int64(q.DbgFlagAll))}, + "DbgFlagEvent": {reflect.TypeOf(q.DbgFlagEvent), constant.MakeInt64(int64(q.DbgFlagEvent))}, + "DbgFlagInstr": {reflect.TypeOf(q.DbgFlagInstr), constant.MakeInt64(int64(q.DbgFlagInstr))}, + "DbgFlagLoad": {reflect.TypeOf(q.DbgFlagLoad), constant.MakeInt64(int64(q.DbgFlagLoad))}, + "DbgFlagPerf": {reflect.TypeOf(q.DbgFlagPerf), constant.MakeInt64(int64(q.DbgFlagPerf))}, + "Down": {reflect.TypeOf(q.Down), constant.MakeInt64(int64(q.Down))}, + "Edge": {reflect.TypeOf(q.Edge), constant.MakeInt64(int64(q.Edge))}, + "EdgeBottom": {reflect.TypeOf(q.EdgeBottom), constant.MakeInt64(int64(q.EdgeBottom))}, + "EdgeLeft": {reflect.TypeOf(q.EdgeLeft), constant.MakeInt64(int64(q.EdgeLeft))}, + "EdgeRight": {reflect.TypeOf(q.EdgeRight), constant.MakeInt64(int64(q.EdgeRight))}, + "EdgeTop": {reflect.TypeOf(q.EdgeTop), constant.MakeInt64(int64(q.EdgeTop))}, + "GhostEffect": {reflect.TypeOf(q.GhostEffect), constant.MakeInt64(int64(q.GhostEffect))}, + "Invalid": {reflect.TypeOf(q.Invalid), constant.MakeInt64(int64(q.Invalid))}, + "Key0": {reflect.TypeOf(q.Key0), constant.MakeInt64(int64(q.Key0))}, + "Key1": {reflect.TypeOf(q.Key1), constant.MakeInt64(int64(q.Key1))}, + "Key2": {reflect.TypeOf(q.Key2), constant.MakeInt64(int64(q.Key2))}, + "Key3": {reflect.TypeOf(q.Key3), constant.MakeInt64(int64(q.Key3))}, + "Key4": {reflect.TypeOf(q.Key4), constant.MakeInt64(int64(q.Key4))}, + "Key5": {reflect.TypeOf(q.Key5), constant.MakeInt64(int64(q.Key5))}, + "Key6": {reflect.TypeOf(q.Key6), constant.MakeInt64(int64(q.Key6))}, + "Key7": {reflect.TypeOf(q.Key7), constant.MakeInt64(int64(q.Key7))}, + "Key8": {reflect.TypeOf(q.Key8), constant.MakeInt64(int64(q.Key8))}, + "Key9": {reflect.TypeOf(q.Key9), constant.MakeInt64(int64(q.Key9))}, + "KeyA": {reflect.TypeOf(q.KeyA), constant.MakeInt64(int64(q.KeyA))}, + "KeyAlt": {reflect.TypeOf(q.KeyAlt), constant.MakeInt64(int64(q.KeyAlt))}, + "KeyAny": {reflect.TypeOf(q.KeyAny), constant.MakeInt64(int64(q.KeyAny))}, + "KeyApostrophe": {reflect.TypeOf(q.KeyApostrophe), constant.MakeInt64(int64(q.KeyApostrophe))}, + "KeyB": {reflect.TypeOf(q.KeyB), constant.MakeInt64(int64(q.KeyB))}, + "KeyBackslash": {reflect.TypeOf(q.KeyBackslash), constant.MakeInt64(int64(q.KeyBackslash))}, + "KeyBackspace": {reflect.TypeOf(q.KeyBackspace), constant.MakeInt64(int64(q.KeyBackspace))}, + "KeyC": {reflect.TypeOf(q.KeyC), constant.MakeInt64(int64(q.KeyC))}, + "KeyCapsLock": {reflect.TypeOf(q.KeyCapsLock), constant.MakeInt64(int64(q.KeyCapsLock))}, + "KeyComma": {reflect.TypeOf(q.KeyComma), constant.MakeInt64(int64(q.KeyComma))}, + "KeyControl": {reflect.TypeOf(q.KeyControl), constant.MakeInt64(int64(q.KeyControl))}, + "KeyD": {reflect.TypeOf(q.KeyD), constant.MakeInt64(int64(q.KeyD))}, + "KeyDelete": {reflect.TypeOf(q.KeyDelete), constant.MakeInt64(int64(q.KeyDelete))}, + "KeyDown": {reflect.TypeOf(q.KeyDown), constant.MakeInt64(int64(q.KeyDown))}, + "KeyE": {reflect.TypeOf(q.KeyE), constant.MakeInt64(int64(q.KeyE))}, + "KeyEnd": {reflect.TypeOf(q.KeyEnd), constant.MakeInt64(int64(q.KeyEnd))}, + "KeyEnter": {reflect.TypeOf(q.KeyEnter), constant.MakeInt64(int64(q.KeyEnter))}, + "KeyEqual": {reflect.TypeOf(q.KeyEqual), constant.MakeInt64(int64(q.KeyEqual))}, + "KeyEscape": {reflect.TypeOf(q.KeyEscape), constant.MakeInt64(int64(q.KeyEscape))}, + "KeyF": {reflect.TypeOf(q.KeyF), constant.MakeInt64(int64(q.KeyF))}, + "KeyF1": {reflect.TypeOf(q.KeyF1), constant.MakeInt64(int64(q.KeyF1))}, + "KeyF10": {reflect.TypeOf(q.KeyF10), constant.MakeInt64(int64(q.KeyF10))}, + "KeyF11": {reflect.TypeOf(q.KeyF11), constant.MakeInt64(int64(q.KeyF11))}, + "KeyF12": {reflect.TypeOf(q.KeyF12), constant.MakeInt64(int64(q.KeyF12))}, + "KeyF2": {reflect.TypeOf(q.KeyF2), constant.MakeInt64(int64(q.KeyF2))}, + "KeyF3": {reflect.TypeOf(q.KeyF3), constant.MakeInt64(int64(q.KeyF3))}, + "KeyF4": {reflect.TypeOf(q.KeyF4), constant.MakeInt64(int64(q.KeyF4))}, + "KeyF5": {reflect.TypeOf(q.KeyF5), constant.MakeInt64(int64(q.KeyF5))}, + "KeyF6": {reflect.TypeOf(q.KeyF6), constant.MakeInt64(int64(q.KeyF6))}, + "KeyF7": {reflect.TypeOf(q.KeyF7), constant.MakeInt64(int64(q.KeyF7))}, + "KeyF8": {reflect.TypeOf(q.KeyF8), constant.MakeInt64(int64(q.KeyF8))}, + "KeyF9": {reflect.TypeOf(q.KeyF9), constant.MakeInt64(int64(q.KeyF9))}, + "KeyG": {reflect.TypeOf(q.KeyG), constant.MakeInt64(int64(q.KeyG))}, + "KeyGraveAccent": {reflect.TypeOf(q.KeyGraveAccent), constant.MakeInt64(int64(q.KeyGraveAccent))}, + "KeyH": {reflect.TypeOf(q.KeyH), constant.MakeInt64(int64(q.KeyH))}, + "KeyHome": {reflect.TypeOf(q.KeyHome), constant.MakeInt64(int64(q.KeyHome))}, + "KeyI": {reflect.TypeOf(q.KeyI), constant.MakeInt64(int64(q.KeyI))}, + "KeyInsert": {reflect.TypeOf(q.KeyInsert), constant.MakeInt64(int64(q.KeyInsert))}, + "KeyJ": {reflect.TypeOf(q.KeyJ), constant.MakeInt64(int64(q.KeyJ))}, + "KeyK": {reflect.TypeOf(q.KeyK), constant.MakeInt64(int64(q.KeyK))}, + "KeyKP0": {reflect.TypeOf(q.KeyKP0), constant.MakeInt64(int64(q.KeyKP0))}, + "KeyKP1": {reflect.TypeOf(q.KeyKP1), constant.MakeInt64(int64(q.KeyKP1))}, + "KeyKP2": {reflect.TypeOf(q.KeyKP2), constant.MakeInt64(int64(q.KeyKP2))}, + "KeyKP3": {reflect.TypeOf(q.KeyKP3), constant.MakeInt64(int64(q.KeyKP3))}, + "KeyKP4": {reflect.TypeOf(q.KeyKP4), constant.MakeInt64(int64(q.KeyKP4))}, + "KeyKP5": {reflect.TypeOf(q.KeyKP5), constant.MakeInt64(int64(q.KeyKP5))}, + "KeyKP6": {reflect.TypeOf(q.KeyKP6), constant.MakeInt64(int64(q.KeyKP6))}, + "KeyKP7": {reflect.TypeOf(q.KeyKP7), constant.MakeInt64(int64(q.KeyKP7))}, + "KeyKP8": {reflect.TypeOf(q.KeyKP8), constant.MakeInt64(int64(q.KeyKP8))}, + "KeyKP9": {reflect.TypeOf(q.KeyKP9), constant.MakeInt64(int64(q.KeyKP9))}, + "KeyKPDecimal": {reflect.TypeOf(q.KeyKPDecimal), constant.MakeInt64(int64(q.KeyKPDecimal))}, + "KeyKPDivide": {reflect.TypeOf(q.KeyKPDivide), constant.MakeInt64(int64(q.KeyKPDivide))}, + "KeyKPEnter": {reflect.TypeOf(q.KeyKPEnter), constant.MakeInt64(int64(q.KeyKPEnter))}, + "KeyKPEqual": {reflect.TypeOf(q.KeyKPEqual), constant.MakeInt64(int64(q.KeyKPEqual))}, + "KeyKPMultiply": {reflect.TypeOf(q.KeyKPMultiply), constant.MakeInt64(int64(q.KeyKPMultiply))}, + "KeyKPSubtract": {reflect.TypeOf(q.KeyKPSubtract), constant.MakeInt64(int64(q.KeyKPSubtract))}, + "KeyL": {reflect.TypeOf(q.KeyL), constant.MakeInt64(int64(q.KeyL))}, + "KeyLeft": {reflect.TypeOf(q.KeyLeft), constant.MakeInt64(int64(q.KeyLeft))}, + "KeyLeftBracket": {reflect.TypeOf(q.KeyLeftBracket), constant.MakeInt64(int64(q.KeyLeftBracket))}, + "KeyM": {reflect.TypeOf(q.KeyM), constant.MakeInt64(int64(q.KeyM))}, + "KeyMax": {reflect.TypeOf(q.KeyMax), constant.MakeInt64(int64(q.KeyMax))}, + "KeyMenu": {reflect.TypeOf(q.KeyMenu), constant.MakeInt64(int64(q.KeyMenu))}, + "KeyMinus": {reflect.TypeOf(q.KeyMinus), constant.MakeInt64(int64(q.KeyMinus))}, + "KeyN": {reflect.TypeOf(q.KeyN), constant.MakeInt64(int64(q.KeyN))}, + "KeyNumLock": {reflect.TypeOf(q.KeyNumLock), constant.MakeInt64(int64(q.KeyNumLock))}, + "KeyO": {reflect.TypeOf(q.KeyO), constant.MakeInt64(int64(q.KeyO))}, + "KeyP": {reflect.TypeOf(q.KeyP), constant.MakeInt64(int64(q.KeyP))}, + "KeyPageDown": {reflect.TypeOf(q.KeyPageDown), constant.MakeInt64(int64(q.KeyPageDown))}, + "KeyPageUp": {reflect.TypeOf(q.KeyPageUp), constant.MakeInt64(int64(q.KeyPageUp))}, + "KeyPause": {reflect.TypeOf(q.KeyPause), constant.MakeInt64(int64(q.KeyPause))}, + "KeyPeriod": {reflect.TypeOf(q.KeyPeriod), constant.MakeInt64(int64(q.KeyPeriod))}, + "KeyPrintScreen": {reflect.TypeOf(q.KeyPrintScreen), constant.MakeInt64(int64(q.KeyPrintScreen))}, + "KeyQ": {reflect.TypeOf(q.KeyQ), constant.MakeInt64(int64(q.KeyQ))}, + "KeyR": {reflect.TypeOf(q.KeyR), constant.MakeInt64(int64(q.KeyR))}, + "KeyRight": {reflect.TypeOf(q.KeyRight), constant.MakeInt64(int64(q.KeyRight))}, + "KeyRightBracket": {reflect.TypeOf(q.KeyRightBracket), constant.MakeInt64(int64(q.KeyRightBracket))}, + "KeyS": {reflect.TypeOf(q.KeyS), constant.MakeInt64(int64(q.KeyS))}, + "KeyScrollLock": {reflect.TypeOf(q.KeyScrollLock), constant.MakeInt64(int64(q.KeyScrollLock))}, + "KeySemicolon": {reflect.TypeOf(q.KeySemicolon), constant.MakeInt64(int64(q.KeySemicolon))}, + "KeyShift": {reflect.TypeOf(q.KeyShift), constant.MakeInt64(int64(q.KeyShift))}, + "KeySlash": {reflect.TypeOf(q.KeySlash), constant.MakeInt64(int64(q.KeySlash))}, + "KeySpace": {reflect.TypeOf(q.KeySpace), constant.MakeInt64(int64(q.KeySpace))}, + "KeyT": {reflect.TypeOf(q.KeyT), constant.MakeInt64(int64(q.KeyT))}, + "KeyTab": {reflect.TypeOf(q.KeyTab), constant.MakeInt64(int64(q.KeyTab))}, + "KeyU": {reflect.TypeOf(q.KeyU), constant.MakeInt64(int64(q.KeyU))}, + "KeyUp": {reflect.TypeOf(q.KeyUp), constant.MakeInt64(int64(q.KeyUp))}, + "KeyV": {reflect.TypeOf(q.KeyV), constant.MakeInt64(int64(q.KeyV))}, + "KeyW": {reflect.TypeOf(q.KeyW), constant.MakeInt64(int64(q.KeyW))}, + "KeyX": {reflect.TypeOf(q.KeyX), constant.MakeInt64(int64(q.KeyX))}, + "KeyY": {reflect.TypeOf(q.KeyY), constant.MakeInt64(int64(q.KeyY))}, + "KeyZ": {reflect.TypeOf(q.KeyZ), constant.MakeInt64(int64(q.KeyZ))}, + "Last": {reflect.TypeOf(q.Last), constant.MakeInt64(int64(q.Last))}, + "Left": {reflect.TypeOf(q.Left), constant.MakeInt64(int64(q.Left))}, + "LeftRight": {reflect.TypeOf(q.LeftRight), constant.MakeInt64(int64(q.LeftRight))}, + "Mouse": {reflect.TypeOf(q.Mouse), constant.MakeInt64(int64(q.Mouse))}, + "Next": {reflect.TypeOf(q.Next), constant.MakeInt64(int64(q.Next))}, + "None": {reflect.TypeOf(q.None), constant.MakeInt64(int64(q.None))}, + "Normal": {reflect.TypeOf(q.Normal), constant.MakeInt64(int64(q.Normal))}, + "OtherScriptsInSprite": {reflect.TypeOf(q.OtherScriptsInSprite), constant.MakeInt64(int64(q.OtherScriptsInSprite))}, + "PlayContinue": {reflect.TypeOf(q.PlayContinue), constant.MakeInt64(int64(q.PlayContinue))}, + "PlayPause": {reflect.TypeOf(q.PlayPause), constant.MakeInt64(int64(q.PlayPause))}, + "PlayResume": {reflect.TypeOf(q.PlayResume), constant.MakeInt64(int64(q.PlayResume))}, + "PlayRewind": {reflect.TypeOf(q.PlayRewind), constant.MakeInt64(int64(q.PlayRewind))}, + "PlayStop": {reflect.TypeOf(q.PlayStop), constant.MakeInt64(int64(q.PlayStop))}, + "Prev": {reflect.TypeOf(q.Prev), constant.MakeInt64(int64(q.Prev))}, + "Random": {reflect.TypeOf(q.Random), constant.MakeInt64(int64(q.Random))}, + "Right": {reflect.TypeOf(q.Right), constant.MakeInt64(int64(q.Right))}, + "StateDie": {reflect.TypeOf(q.StateDie), constant.MakeString(string(q.StateDie))}, + "StateGlide": {reflect.TypeOf(q.StateGlide), constant.MakeString(string(q.StateGlide))}, + "StateStep": {reflect.TypeOf(q.StateStep), constant.MakeString(string(q.StateStep))}, + "StateTurn": {reflect.TypeOf(q.StateTurn), constant.MakeString(string(q.StateTurn))}, + "ThisScript": {reflect.TypeOf(q.ThisScript), constant.MakeInt64(int64(q.ThisScript))}, + "ThisSprite": {reflect.TypeOf(q.ThisSprite), constant.MakeInt64(int64(q.ThisSprite))}, + "Up": {reflect.TypeOf(q.Up), constant.MakeInt64(int64(q.Up))}, + }, + UntypedConsts: map[string]igop.UntypedConst{ + "All": {"untyped int", constant.MakeInt64(int64(q.All))}, + "GopPackage": {"untyped bool", constant.MakeBool(bool(q.GopPackage))}, + "Gop_sched": {"untyped string", constant.MakeString(string(q.Gop_sched))}, + }, + }) +} diff --git a/cmd/ispx/pkg/github.com/hajimehoshi/ebiten/v2/export.go b/cmd/ispx/pkg/github.com/hajimehoshi/ebiten/v2/export.go new file mode 100644 index 00000000..a4017a86 --- /dev/null +++ b/cmd/ispx/pkg/github.com/hajimehoshi/ebiten/v2/export.go @@ -0,0 +1,519 @@ +// export by github.com/goplus/igop/cmd/qexp + +package ebiten + +import ( + q "github.com/hajimehoshi/ebiten/v2" + + "go/constant" + "reflect" + + "github.com/goplus/igop" +) + +func init() { + igop.RegisterPackage(&igop.Package{ + Name: "ebiten", + Path: "github.com/hajimehoshi/ebiten/v2", + Deps: map[string]string{ + "errors": "errors", + "fmt": "fmt", + "github.com/hajimehoshi/ebiten/v2/internal/affine": "affine", + "github.com/hajimehoshi/ebiten/v2/internal/atlas": "atlas", + "github.com/hajimehoshi/ebiten/v2/internal/builtinshader": "builtinshader", + "github.com/hajimehoshi/ebiten/v2/internal/clock": "clock", + "github.com/hajimehoshi/ebiten/v2/internal/debug": "debug", + "github.com/hajimehoshi/ebiten/v2/internal/gamepad": "gamepad", + "github.com/hajimehoshi/ebiten/v2/internal/gamepaddb": "gamepaddb", + "github.com/hajimehoshi/ebiten/v2/internal/graphics": "graphics", + "github.com/hajimehoshi/ebiten/v2/internal/graphicscommand": "graphicscommand", + "github.com/hajimehoshi/ebiten/v2/internal/graphicsdriver": "graphicsdriver", + "github.com/hajimehoshi/ebiten/v2/internal/shaderir": "shaderir", + "github.com/hajimehoshi/ebiten/v2/internal/ui": "ui", + "github.com/hajimehoshi/ebiten/v2/internal/vibrate": "vibrate", + "image": "image", + "image/color": "color", + "image/draw": "draw", + "io/fs": "fs", + "math": "math", + "os": "os", + "path/filepath": "filepath", + "runtime": "runtime", + "strings": "strings", + "sync": "sync", + "sync/atomic": "atomic", + "time": "time", + }, + Interfaces: map[string]reflect.Type{ + "FinalScreen": reflect.TypeOf((*q.FinalScreen)(nil)).Elem(), + "FinalScreenDrawer": reflect.TypeOf((*q.FinalScreenDrawer)(nil)).Elem(), + "Game": reflect.TypeOf((*q.Game)(nil)).Elem(), + "LayoutFer": reflect.TypeOf((*q.LayoutFer)(nil)).Elem(), + }, + NamedTypes: map[string]reflect.Type{ + "Address": reflect.TypeOf((*q.Address)(nil)).Elem(), + "Blend": reflect.TypeOf((*q.Blend)(nil)).Elem(), + "BlendFactor": reflect.TypeOf((*q.BlendFactor)(nil)).Elem(), + "BlendOperation": reflect.TypeOf((*q.BlendOperation)(nil)).Elem(), + "ColorM": reflect.TypeOf((*q.ColorM)(nil)).Elem(), + "ColorScale": reflect.TypeOf((*q.ColorScale)(nil)).Elem(), + "ColorScaleMode": reflect.TypeOf((*q.ColorScaleMode)(nil)).Elem(), + "CompositeMode": reflect.TypeOf((*q.CompositeMode)(nil)).Elem(), + "DebugInfo": reflect.TypeOf((*q.DebugInfo)(nil)).Elem(), + "DrawImageOptions": reflect.TypeOf((*q.DrawImageOptions)(nil)).Elem(), + "DrawRectShaderOptions": reflect.TypeOf((*q.DrawRectShaderOptions)(nil)).Elem(), + "DrawTrianglesOptions": reflect.TypeOf((*q.DrawTrianglesOptions)(nil)).Elem(), + "DrawTrianglesShaderOptions": reflect.TypeOf((*q.DrawTrianglesShaderOptions)(nil)).Elem(), + "FillRule": reflect.TypeOf((*q.FillRule)(nil)).Elem(), + "Filter": reflect.TypeOf((*q.Filter)(nil)).Elem(), + "GeoM": reflect.TypeOf((*q.GeoM)(nil)).Elem(), + "GraphicsLibrary": reflect.TypeOf((*q.GraphicsLibrary)(nil)).Elem(), + "Image": reflect.TypeOf((*q.Image)(nil)).Elem(), + "Key": reflect.TypeOf((*q.Key)(nil)).Elem(), + "MonitorType": reflect.TypeOf((*q.MonitorType)(nil)).Elem(), + "NewImageFromImageOptions": reflect.TypeOf((*q.NewImageFromImageOptions)(nil)).Elem(), + "NewImageOptions": reflect.TypeOf((*q.NewImageOptions)(nil)).Elem(), + "RunGameOptions": reflect.TypeOf((*q.RunGameOptions)(nil)).Elem(), + "Shader": reflect.TypeOf((*q.Shader)(nil)).Elem(), + "Vertex": reflect.TypeOf((*q.Vertex)(nil)).Elem(), + "VibrateGamepadOptions": reflect.TypeOf((*q.VibrateGamepadOptions)(nil)).Elem(), + "VibrateOptions": reflect.TypeOf((*q.VibrateOptions)(nil)).Elem(), + }, + AliasTypes: map[string]reflect.Type{ + "CursorModeType": reflect.TypeOf((*q.CursorModeType)(nil)).Elem(), + "CursorShapeType": reflect.TypeOf((*q.CursorShapeType)(nil)).Elem(), + "FPSModeType": reflect.TypeOf((*q.FPSModeType)(nil)).Elem(), + "GamepadAxisType": reflect.TypeOf((*int)(nil)).Elem(), + "GamepadButton": reflect.TypeOf((*q.GamepadButton)(nil)).Elem(), + "GamepadID": reflect.TypeOf((*q.GamepadID)(nil)).Elem(), + "MouseButton": reflect.TypeOf((*q.MouseButton)(nil)).Elem(), + "StandardGamepadAxis": reflect.TypeOf((*q.StandardGamepadAxis)(nil)).Elem(), + "StandardGamepadButton": reflect.TypeOf((*q.StandardGamepadButton)(nil)).Elem(), + "TouchID": reflect.TypeOf((*q.TouchID)(nil)).Elem(), + "WindowResizingModeType": reflect.TypeOf((*q.WindowResizingModeType)(nil)).Elem(), + }, + Vars: map[string]reflect.Value{ + "BlendClear": reflect.ValueOf(&q.BlendClear), + "BlendCopy": reflect.ValueOf(&q.BlendCopy), + "BlendDestination": reflect.ValueOf(&q.BlendDestination), + "BlendDestinationAtop": reflect.ValueOf(&q.BlendDestinationAtop), + "BlendDestinationIn": reflect.ValueOf(&q.BlendDestinationIn), + "BlendDestinationOut": reflect.ValueOf(&q.BlendDestinationOut), + "BlendDestinationOver": reflect.ValueOf(&q.BlendDestinationOver), + "BlendLighter": reflect.ValueOf(&q.BlendLighter), + "BlendSourceAtop": reflect.ValueOf(&q.BlendSourceAtop), + "BlendSourceIn": reflect.ValueOf(&q.BlendSourceIn), + "BlendSourceOut": reflect.ValueOf(&q.BlendSourceOut), + "BlendSourceOver": reflect.ValueOf(&q.BlendSourceOver), + "BlendXor": reflect.ValueOf(&q.BlendXor), + "Termination": reflect.ValueOf(&q.Termination), + }, + Funcs: map[string]reflect.Value{ + "ActualFPS": reflect.ValueOf(q.ActualFPS), + "ActualTPS": reflect.ValueOf(q.ActualTPS), + "AppendGamepadIDs": reflect.ValueOf(q.AppendGamepadIDs), + "AppendInputChars": reflect.ValueOf(q.AppendInputChars), + "AppendMonitors": reflect.ValueOf(q.AppendMonitors), + "AppendTouchIDs": reflect.ValueOf(q.AppendTouchIDs), + "CurrentFPS": reflect.ValueOf(q.CurrentFPS), + "CurrentTPS": reflect.ValueOf(q.CurrentTPS), + "CursorMode": reflect.ValueOf(q.CursorMode), + "CursorPosition": reflect.ValueOf(q.CursorPosition), + "CursorShape": reflect.ValueOf(q.CursorShape), + "DeviceScaleFactor": reflect.ValueOf(q.DeviceScaleFactor), + "DroppedFiles": reflect.ValueOf(q.DroppedFiles), + "FPSMode": reflect.ValueOf(q.FPSMode), + "GamepadAxis": reflect.ValueOf(q.GamepadAxis), + "GamepadAxisCount": reflect.ValueOf(q.GamepadAxisCount), + "GamepadAxisNum": reflect.ValueOf(q.GamepadAxisNum), + "GamepadAxisValue": reflect.ValueOf(q.GamepadAxisValue), + "GamepadButtonCount": reflect.ValueOf(q.GamepadButtonCount), + "GamepadButtonNum": reflect.ValueOf(q.GamepadButtonNum), + "GamepadIDs": reflect.ValueOf(q.GamepadIDs), + "GamepadName": reflect.ValueOf(q.GamepadName), + "GamepadSDLID": reflect.ValueOf(q.GamepadSDLID), + "InputChars": reflect.ValueOf(q.InputChars), + "IsFocused": reflect.ValueOf(q.IsFocused), + "IsFullscreen": reflect.ValueOf(q.IsFullscreen), + "IsGamepadButtonPressed": reflect.ValueOf(q.IsGamepadButtonPressed), + "IsKeyPressed": reflect.ValueOf(q.IsKeyPressed), + "IsMouseButtonPressed": reflect.ValueOf(q.IsMouseButtonPressed), + "IsRunnableOnUnfocused": reflect.ValueOf(q.IsRunnableOnUnfocused), + "IsScreenClearedEveryFrame": reflect.ValueOf(q.IsScreenClearedEveryFrame), + "IsScreenFilterEnabled": reflect.ValueOf(q.IsScreenFilterEnabled), + "IsScreenTransparent": reflect.ValueOf(q.IsScreenTransparent), + "IsStandardGamepadAxisAvailable": reflect.ValueOf(q.IsStandardGamepadAxisAvailable), + "IsStandardGamepadButtonAvailable": reflect.ValueOf(q.IsStandardGamepadButtonAvailable), + "IsStandardGamepadButtonPressed": reflect.ValueOf(q.IsStandardGamepadButtonPressed), + "IsStandardGamepadLayoutAvailable": reflect.ValueOf(q.IsStandardGamepadLayoutAvailable), + "IsVsyncEnabled": reflect.ValueOf(q.IsVsyncEnabled), + "IsWindowBeingClosed": reflect.ValueOf(q.IsWindowBeingClosed), + "IsWindowClosingHandled": reflect.ValueOf(q.IsWindowClosingHandled), + "IsWindowDecorated": reflect.ValueOf(q.IsWindowDecorated), + "IsWindowFloating": reflect.ValueOf(q.IsWindowFloating), + "IsWindowMaximized": reflect.ValueOf(q.IsWindowMaximized), + "IsWindowMinimized": reflect.ValueOf(q.IsWindowMinimized), + "IsWindowMousePassthrough": reflect.ValueOf(q.IsWindowMousePassthrough), + "IsWindowResizable": reflect.ValueOf(q.IsWindowResizable), + "KeyName": reflect.ValueOf(q.KeyName), + "MaxTPS": reflect.ValueOf(q.MaxTPS), + "MaximizeWindow": reflect.ValueOf(q.MaximizeWindow), + "MinimizeWindow": reflect.ValueOf(q.MinimizeWindow), + "Monitor": reflect.ValueOf(q.Monitor), + "NewImage": reflect.ValueOf(q.NewImage), + "NewImageFromImage": reflect.ValueOf(q.NewImageFromImage), + "NewImageFromImageWithOptions": reflect.ValueOf(q.NewImageFromImageWithOptions), + "NewImageWithOptions": reflect.ValueOf(q.NewImageWithOptions), + "NewShader": reflect.ValueOf(q.NewShader), + "ReadDebugInfo": reflect.ValueOf(q.ReadDebugInfo), + "RestoreWindow": reflect.ValueOf(q.RestoreWindow), + "RunGame": reflect.ValueOf(q.RunGame), + "RunGameWithOptions": reflect.ValueOf(q.RunGameWithOptions), + "ScheduleFrame": reflect.ValueOf(q.ScheduleFrame), + "ScreenSizeInFullscreen": reflect.ValueOf(q.ScreenSizeInFullscreen), + "SetCursorMode": reflect.ValueOf(q.SetCursorMode), + "SetCursorShape": reflect.ValueOf(q.SetCursorShape), + "SetFPSMode": reflect.ValueOf(q.SetFPSMode), + "SetFullscreen": reflect.ValueOf(q.SetFullscreen), + "SetInitFocused": reflect.ValueOf(q.SetInitFocused), + "SetMaxTPS": reflect.ValueOf(q.SetMaxTPS), + "SetMonitor": reflect.ValueOf(q.SetMonitor), + "SetRunnableOnUnfocused": reflect.ValueOf(q.SetRunnableOnUnfocused), + "SetScreenClearedEveryFrame": reflect.ValueOf(q.SetScreenClearedEveryFrame), + "SetScreenFilterEnabled": reflect.ValueOf(q.SetScreenFilterEnabled), + "SetScreenTransparent": reflect.ValueOf(q.SetScreenTransparent), + "SetTPS": reflect.ValueOf(q.SetTPS), + "SetVsyncEnabled": reflect.ValueOf(q.SetVsyncEnabled), + "SetWindowClosingHandled": reflect.ValueOf(q.SetWindowClosingHandled), + "SetWindowDecorated": reflect.ValueOf(q.SetWindowDecorated), + "SetWindowFloating": reflect.ValueOf(q.SetWindowFloating), + "SetWindowIcon": reflect.ValueOf(q.SetWindowIcon), + "SetWindowMousePassthrough": reflect.ValueOf(q.SetWindowMousePassthrough), + "SetWindowPosition": reflect.ValueOf(q.SetWindowPosition), + "SetWindowResizable": reflect.ValueOf(q.SetWindowResizable), + "SetWindowResizingMode": reflect.ValueOf(q.SetWindowResizingMode), + "SetWindowSize": reflect.ValueOf(q.SetWindowSize), + "SetWindowSizeLimits": reflect.ValueOf(q.SetWindowSizeLimits), + "SetWindowTitle": reflect.ValueOf(q.SetWindowTitle), + "StandardGamepadAxisValue": reflect.ValueOf(q.StandardGamepadAxisValue), + "StandardGamepadButtonValue": reflect.ValueOf(q.StandardGamepadButtonValue), + "TPS": reflect.ValueOf(q.TPS), + "TouchIDs": reflect.ValueOf(q.TouchIDs), + "TouchPosition": reflect.ValueOf(q.TouchPosition), + "UpdateStandardGamepadLayoutMappings": reflect.ValueOf(q.UpdateStandardGamepadLayoutMappings), + "Vibrate": reflect.ValueOf(q.Vibrate), + "VibrateGamepad": reflect.ValueOf(q.VibrateGamepad), + "Wheel": reflect.ValueOf(q.Wheel), + "WindowPosition": reflect.ValueOf(q.WindowPosition), + "WindowResizingMode": reflect.ValueOf(q.WindowResizingMode), + "WindowSize": reflect.ValueOf(q.WindowSize), + "WindowSizeLimits": reflect.ValueOf(q.WindowSizeLimits), + }, + TypedConsts: map[string]igop.TypedConst{ + "AddressClampToZero": {reflect.TypeOf(q.AddressClampToZero), constant.MakeInt64(int64(q.AddressClampToZero))}, + "AddressRepeat": {reflect.TypeOf(q.AddressRepeat), constant.MakeInt64(int64(q.AddressRepeat))}, + "AddressUnsafe": {reflect.TypeOf(q.AddressUnsafe), constant.MakeInt64(int64(q.AddressUnsafe))}, + "BlendFactorDefault": {reflect.TypeOf(q.BlendFactorDefault), constant.MakeInt64(int64(q.BlendFactorDefault))}, + "BlendFactorDestinationAlpha": {reflect.TypeOf(q.BlendFactorDestinationAlpha), constant.MakeInt64(int64(q.BlendFactorDestinationAlpha))}, + "BlendFactorDestinationColor": {reflect.TypeOf(q.BlendFactorDestinationColor), constant.MakeInt64(int64(q.BlendFactorDestinationColor))}, + "BlendFactorOne": {reflect.TypeOf(q.BlendFactorOne), constant.MakeInt64(int64(q.BlendFactorOne))}, + "BlendFactorOneMinusDestinationAlpha": {reflect.TypeOf(q.BlendFactorOneMinusDestinationAlpha), constant.MakeInt64(int64(q.BlendFactorOneMinusDestinationAlpha))}, + "BlendFactorOneMinusDestinationColor": {reflect.TypeOf(q.BlendFactorOneMinusDestinationColor), constant.MakeInt64(int64(q.BlendFactorOneMinusDestinationColor))}, + "BlendFactorOneMinusSourceAlpha": {reflect.TypeOf(q.BlendFactorOneMinusSourceAlpha), constant.MakeInt64(int64(q.BlendFactorOneMinusSourceAlpha))}, + "BlendFactorOneMinusSourceColor": {reflect.TypeOf(q.BlendFactorOneMinusSourceColor), constant.MakeInt64(int64(q.BlendFactorOneMinusSourceColor))}, + "BlendFactorSourceAlpha": {reflect.TypeOf(q.BlendFactorSourceAlpha), constant.MakeInt64(int64(q.BlendFactorSourceAlpha))}, + "BlendFactorSourceColor": {reflect.TypeOf(q.BlendFactorSourceColor), constant.MakeInt64(int64(q.BlendFactorSourceColor))}, + "BlendFactorZero": {reflect.TypeOf(q.BlendFactorZero), constant.MakeInt64(int64(q.BlendFactorZero))}, + "BlendOperationAdd": {reflect.TypeOf(q.BlendOperationAdd), constant.MakeInt64(int64(q.BlendOperationAdd))}, + "BlendOperationMax": {reflect.TypeOf(q.BlendOperationMax), constant.MakeInt64(int64(q.BlendOperationMax))}, + "BlendOperationMin": {reflect.TypeOf(q.BlendOperationMin), constant.MakeInt64(int64(q.BlendOperationMin))}, + "BlendOperationReverseSubtract": {reflect.TypeOf(q.BlendOperationReverseSubtract), constant.MakeInt64(int64(q.BlendOperationReverseSubtract))}, + "BlendOperationSubtract": {reflect.TypeOf(q.BlendOperationSubtract), constant.MakeInt64(int64(q.BlendOperationSubtract))}, + "ColorScaleModePremultipliedAlpha": {reflect.TypeOf(q.ColorScaleModePremultipliedAlpha), constant.MakeInt64(int64(q.ColorScaleModePremultipliedAlpha))}, + "ColorScaleModeStraightAlpha": {reflect.TypeOf(q.ColorScaleModeStraightAlpha), constant.MakeInt64(int64(q.ColorScaleModeStraightAlpha))}, + "CompositeModeClear": {reflect.TypeOf(q.CompositeModeClear), constant.MakeInt64(int64(q.CompositeModeClear))}, + "CompositeModeCopy": {reflect.TypeOf(q.CompositeModeCopy), constant.MakeInt64(int64(q.CompositeModeCopy))}, + "CompositeModeCustom": {reflect.TypeOf(q.CompositeModeCustom), constant.MakeInt64(int64(q.CompositeModeCustom))}, + "CompositeModeDestination": {reflect.TypeOf(q.CompositeModeDestination), constant.MakeInt64(int64(q.CompositeModeDestination))}, + "CompositeModeDestinationAtop": {reflect.TypeOf(q.CompositeModeDestinationAtop), constant.MakeInt64(int64(q.CompositeModeDestinationAtop))}, + "CompositeModeDestinationIn": {reflect.TypeOf(q.CompositeModeDestinationIn), constant.MakeInt64(int64(q.CompositeModeDestinationIn))}, + "CompositeModeDestinationOut": {reflect.TypeOf(q.CompositeModeDestinationOut), constant.MakeInt64(int64(q.CompositeModeDestinationOut))}, + "CompositeModeDestinationOver": {reflect.TypeOf(q.CompositeModeDestinationOver), constant.MakeInt64(int64(q.CompositeModeDestinationOver))}, + "CompositeModeLighter": {reflect.TypeOf(q.CompositeModeLighter), constant.MakeInt64(int64(q.CompositeModeLighter))}, + "CompositeModeMultiply": {reflect.TypeOf(q.CompositeModeMultiply), constant.MakeInt64(int64(q.CompositeModeMultiply))}, + "CompositeModeSourceAtop": {reflect.TypeOf(q.CompositeModeSourceAtop), constant.MakeInt64(int64(q.CompositeModeSourceAtop))}, + "CompositeModeSourceIn": {reflect.TypeOf(q.CompositeModeSourceIn), constant.MakeInt64(int64(q.CompositeModeSourceIn))}, + "CompositeModeSourceOut": {reflect.TypeOf(q.CompositeModeSourceOut), constant.MakeInt64(int64(q.CompositeModeSourceOut))}, + "CompositeModeSourceOver": {reflect.TypeOf(q.CompositeModeSourceOver), constant.MakeInt64(int64(q.CompositeModeSourceOver))}, + "CompositeModeXor": {reflect.TypeOf(q.CompositeModeXor), constant.MakeInt64(int64(q.CompositeModeXor))}, + "CursorModeCaptured": {reflect.TypeOf(q.CursorModeCaptured), constant.MakeInt64(int64(q.CursorModeCaptured))}, + "CursorModeHidden": {reflect.TypeOf(q.CursorModeHidden), constant.MakeInt64(int64(q.CursorModeHidden))}, + "CursorModeVisible": {reflect.TypeOf(q.CursorModeVisible), constant.MakeInt64(int64(q.CursorModeVisible))}, + "CursorShapeCrosshair": {reflect.TypeOf(q.CursorShapeCrosshair), constant.MakeInt64(int64(q.CursorShapeCrosshair))}, + "CursorShapeDefault": {reflect.TypeOf(q.CursorShapeDefault), constant.MakeInt64(int64(q.CursorShapeDefault))}, + "CursorShapeEWResize": {reflect.TypeOf(q.CursorShapeEWResize), constant.MakeInt64(int64(q.CursorShapeEWResize))}, + "CursorShapeMove": {reflect.TypeOf(q.CursorShapeMove), constant.MakeInt64(int64(q.CursorShapeMove))}, + "CursorShapeNESWResize": {reflect.TypeOf(q.CursorShapeNESWResize), constant.MakeInt64(int64(q.CursorShapeNESWResize))}, + "CursorShapeNSResize": {reflect.TypeOf(q.CursorShapeNSResize), constant.MakeInt64(int64(q.CursorShapeNSResize))}, + "CursorShapeNWSEResize": {reflect.TypeOf(q.CursorShapeNWSEResize), constant.MakeInt64(int64(q.CursorShapeNWSEResize))}, + "CursorShapeNotAllowed": {reflect.TypeOf(q.CursorShapeNotAllowed), constant.MakeInt64(int64(q.CursorShapeNotAllowed))}, + "CursorShapePointer": {reflect.TypeOf(q.CursorShapePointer), constant.MakeInt64(int64(q.CursorShapePointer))}, + "CursorShapeText": {reflect.TypeOf(q.CursorShapeText), constant.MakeInt64(int64(q.CursorShapeText))}, + "EvenOdd": {reflect.TypeOf(q.EvenOdd), constant.MakeInt64(int64(q.EvenOdd))}, + "FPSModeVsyncOffMaximum": {reflect.TypeOf(q.FPSModeVsyncOffMaximum), constant.MakeInt64(int64(q.FPSModeVsyncOffMaximum))}, + "FPSModeVsyncOffMinimum": {reflect.TypeOf(q.FPSModeVsyncOffMinimum), constant.MakeInt64(int64(q.FPSModeVsyncOffMinimum))}, + "FPSModeVsyncOn": {reflect.TypeOf(q.FPSModeVsyncOn), constant.MakeInt64(int64(q.FPSModeVsyncOn))}, + "FillAll": {reflect.TypeOf(q.FillAll), constant.MakeInt64(int64(q.FillAll))}, + "FillRuleEvenOdd": {reflect.TypeOf(q.FillRuleEvenOdd), constant.MakeInt64(int64(q.FillRuleEvenOdd))}, + "FillRuleFillAll": {reflect.TypeOf(q.FillRuleFillAll), constant.MakeInt64(int64(q.FillRuleFillAll))}, + "FillRuleNonZero": {reflect.TypeOf(q.FillRuleNonZero), constant.MakeInt64(int64(q.FillRuleNonZero))}, + "FilterLinear": {reflect.TypeOf(q.FilterLinear), constant.MakeInt64(int64(q.FilterLinear))}, + "FilterNearest": {reflect.TypeOf(q.FilterNearest), constant.MakeInt64(int64(q.FilterNearest))}, + "GamepadButton0": {reflect.TypeOf(q.GamepadButton0), constant.MakeInt64(int64(q.GamepadButton0))}, + "GamepadButton1": {reflect.TypeOf(q.GamepadButton1), constant.MakeInt64(int64(q.GamepadButton1))}, + "GamepadButton10": {reflect.TypeOf(q.GamepadButton10), constant.MakeInt64(int64(q.GamepadButton10))}, + "GamepadButton11": {reflect.TypeOf(q.GamepadButton11), constant.MakeInt64(int64(q.GamepadButton11))}, + "GamepadButton12": {reflect.TypeOf(q.GamepadButton12), constant.MakeInt64(int64(q.GamepadButton12))}, + "GamepadButton13": {reflect.TypeOf(q.GamepadButton13), constant.MakeInt64(int64(q.GamepadButton13))}, + "GamepadButton14": {reflect.TypeOf(q.GamepadButton14), constant.MakeInt64(int64(q.GamepadButton14))}, + "GamepadButton15": {reflect.TypeOf(q.GamepadButton15), constant.MakeInt64(int64(q.GamepadButton15))}, + "GamepadButton16": {reflect.TypeOf(q.GamepadButton16), constant.MakeInt64(int64(q.GamepadButton16))}, + "GamepadButton17": {reflect.TypeOf(q.GamepadButton17), constant.MakeInt64(int64(q.GamepadButton17))}, + "GamepadButton18": {reflect.TypeOf(q.GamepadButton18), constant.MakeInt64(int64(q.GamepadButton18))}, + "GamepadButton19": {reflect.TypeOf(q.GamepadButton19), constant.MakeInt64(int64(q.GamepadButton19))}, + "GamepadButton2": {reflect.TypeOf(q.GamepadButton2), constant.MakeInt64(int64(q.GamepadButton2))}, + "GamepadButton20": {reflect.TypeOf(q.GamepadButton20), constant.MakeInt64(int64(q.GamepadButton20))}, + "GamepadButton21": {reflect.TypeOf(q.GamepadButton21), constant.MakeInt64(int64(q.GamepadButton21))}, + "GamepadButton22": {reflect.TypeOf(q.GamepadButton22), constant.MakeInt64(int64(q.GamepadButton22))}, + "GamepadButton23": {reflect.TypeOf(q.GamepadButton23), constant.MakeInt64(int64(q.GamepadButton23))}, + "GamepadButton24": {reflect.TypeOf(q.GamepadButton24), constant.MakeInt64(int64(q.GamepadButton24))}, + "GamepadButton25": {reflect.TypeOf(q.GamepadButton25), constant.MakeInt64(int64(q.GamepadButton25))}, + "GamepadButton26": {reflect.TypeOf(q.GamepadButton26), constant.MakeInt64(int64(q.GamepadButton26))}, + "GamepadButton27": {reflect.TypeOf(q.GamepadButton27), constant.MakeInt64(int64(q.GamepadButton27))}, + "GamepadButton28": {reflect.TypeOf(q.GamepadButton28), constant.MakeInt64(int64(q.GamepadButton28))}, + "GamepadButton29": {reflect.TypeOf(q.GamepadButton29), constant.MakeInt64(int64(q.GamepadButton29))}, + "GamepadButton3": {reflect.TypeOf(q.GamepadButton3), constant.MakeInt64(int64(q.GamepadButton3))}, + "GamepadButton30": {reflect.TypeOf(q.GamepadButton30), constant.MakeInt64(int64(q.GamepadButton30))}, + "GamepadButton31": {reflect.TypeOf(q.GamepadButton31), constant.MakeInt64(int64(q.GamepadButton31))}, + "GamepadButton4": {reflect.TypeOf(q.GamepadButton4), constant.MakeInt64(int64(q.GamepadButton4))}, + "GamepadButton5": {reflect.TypeOf(q.GamepadButton5), constant.MakeInt64(int64(q.GamepadButton5))}, + "GamepadButton6": {reflect.TypeOf(q.GamepadButton6), constant.MakeInt64(int64(q.GamepadButton6))}, + "GamepadButton7": {reflect.TypeOf(q.GamepadButton7), constant.MakeInt64(int64(q.GamepadButton7))}, + "GamepadButton8": {reflect.TypeOf(q.GamepadButton8), constant.MakeInt64(int64(q.GamepadButton8))}, + "GamepadButton9": {reflect.TypeOf(q.GamepadButton9), constant.MakeInt64(int64(q.GamepadButton9))}, + "GamepadButtonMax": {reflect.TypeOf(q.GamepadButtonMax), constant.MakeInt64(int64(q.GamepadButtonMax))}, + "GraphicsLibraryAuto": {reflect.TypeOf(q.GraphicsLibraryAuto), constant.MakeInt64(int64(q.GraphicsLibraryAuto))}, + "GraphicsLibraryDirectX": {reflect.TypeOf(q.GraphicsLibraryDirectX), constant.MakeInt64(int64(q.GraphicsLibraryDirectX))}, + "GraphicsLibraryMetal": {reflect.TypeOf(q.GraphicsLibraryMetal), constant.MakeInt64(int64(q.GraphicsLibraryMetal))}, + "GraphicsLibraryOpenGL": {reflect.TypeOf(q.GraphicsLibraryOpenGL), constant.MakeInt64(int64(q.GraphicsLibraryOpenGL))}, + "GraphicsLibraryPlayStation5": {reflect.TypeOf(q.GraphicsLibraryPlayStation5), constant.MakeInt64(int64(q.GraphicsLibraryPlayStation5))}, + "GraphicsLibraryUnknown": {reflect.TypeOf(q.GraphicsLibraryUnknown), constant.MakeInt64(int64(q.GraphicsLibraryUnknown))}, + "Key0": {reflect.TypeOf(q.Key0), constant.MakeInt64(int64(q.Key0))}, + "Key1": {reflect.TypeOf(q.Key1), constant.MakeInt64(int64(q.Key1))}, + "Key2": {reflect.TypeOf(q.Key2), constant.MakeInt64(int64(q.Key2))}, + "Key3": {reflect.TypeOf(q.Key3), constant.MakeInt64(int64(q.Key3))}, + "Key4": {reflect.TypeOf(q.Key4), constant.MakeInt64(int64(q.Key4))}, + "Key5": {reflect.TypeOf(q.Key5), constant.MakeInt64(int64(q.Key5))}, + "Key6": {reflect.TypeOf(q.Key6), constant.MakeInt64(int64(q.Key6))}, + "Key7": {reflect.TypeOf(q.Key7), constant.MakeInt64(int64(q.Key7))}, + "Key8": {reflect.TypeOf(q.Key8), constant.MakeInt64(int64(q.Key8))}, + "Key9": {reflect.TypeOf(q.Key9), constant.MakeInt64(int64(q.Key9))}, + "KeyA": {reflect.TypeOf(q.KeyA), constant.MakeInt64(int64(q.KeyA))}, + "KeyAlt": {reflect.TypeOf(q.KeyAlt), constant.MakeInt64(int64(q.KeyAlt))}, + "KeyAltLeft": {reflect.TypeOf(q.KeyAltLeft), constant.MakeInt64(int64(q.KeyAltLeft))}, + "KeyAltRight": {reflect.TypeOf(q.KeyAltRight), constant.MakeInt64(int64(q.KeyAltRight))}, + "KeyApostrophe": {reflect.TypeOf(q.KeyApostrophe), constant.MakeInt64(int64(q.KeyApostrophe))}, + "KeyArrowDown": {reflect.TypeOf(q.KeyArrowDown), constant.MakeInt64(int64(q.KeyArrowDown))}, + "KeyArrowLeft": {reflect.TypeOf(q.KeyArrowLeft), constant.MakeInt64(int64(q.KeyArrowLeft))}, + "KeyArrowRight": {reflect.TypeOf(q.KeyArrowRight), constant.MakeInt64(int64(q.KeyArrowRight))}, + "KeyArrowUp": {reflect.TypeOf(q.KeyArrowUp), constant.MakeInt64(int64(q.KeyArrowUp))}, + "KeyB": {reflect.TypeOf(q.KeyB), constant.MakeInt64(int64(q.KeyB))}, + "KeyBackquote": {reflect.TypeOf(q.KeyBackquote), constant.MakeInt64(int64(q.KeyBackquote))}, + "KeyBackslash": {reflect.TypeOf(q.KeyBackslash), constant.MakeInt64(int64(q.KeyBackslash))}, + "KeyBackspace": {reflect.TypeOf(q.KeyBackspace), constant.MakeInt64(int64(q.KeyBackspace))}, + "KeyBracketLeft": {reflect.TypeOf(q.KeyBracketLeft), constant.MakeInt64(int64(q.KeyBracketLeft))}, + "KeyBracketRight": {reflect.TypeOf(q.KeyBracketRight), constant.MakeInt64(int64(q.KeyBracketRight))}, + "KeyC": {reflect.TypeOf(q.KeyC), constant.MakeInt64(int64(q.KeyC))}, + "KeyCapsLock": {reflect.TypeOf(q.KeyCapsLock), constant.MakeInt64(int64(q.KeyCapsLock))}, + "KeyComma": {reflect.TypeOf(q.KeyComma), constant.MakeInt64(int64(q.KeyComma))}, + "KeyContextMenu": {reflect.TypeOf(q.KeyContextMenu), constant.MakeInt64(int64(q.KeyContextMenu))}, + "KeyControl": {reflect.TypeOf(q.KeyControl), constant.MakeInt64(int64(q.KeyControl))}, + "KeyControlLeft": {reflect.TypeOf(q.KeyControlLeft), constant.MakeInt64(int64(q.KeyControlLeft))}, + "KeyControlRight": {reflect.TypeOf(q.KeyControlRight), constant.MakeInt64(int64(q.KeyControlRight))}, + "KeyD": {reflect.TypeOf(q.KeyD), constant.MakeInt64(int64(q.KeyD))}, + "KeyDelete": {reflect.TypeOf(q.KeyDelete), constant.MakeInt64(int64(q.KeyDelete))}, + "KeyDigit0": {reflect.TypeOf(q.KeyDigit0), constant.MakeInt64(int64(q.KeyDigit0))}, + "KeyDigit1": {reflect.TypeOf(q.KeyDigit1), constant.MakeInt64(int64(q.KeyDigit1))}, + "KeyDigit2": {reflect.TypeOf(q.KeyDigit2), constant.MakeInt64(int64(q.KeyDigit2))}, + "KeyDigit3": {reflect.TypeOf(q.KeyDigit3), constant.MakeInt64(int64(q.KeyDigit3))}, + "KeyDigit4": {reflect.TypeOf(q.KeyDigit4), constant.MakeInt64(int64(q.KeyDigit4))}, + "KeyDigit5": {reflect.TypeOf(q.KeyDigit5), constant.MakeInt64(int64(q.KeyDigit5))}, + "KeyDigit6": {reflect.TypeOf(q.KeyDigit6), constant.MakeInt64(int64(q.KeyDigit6))}, + "KeyDigit7": {reflect.TypeOf(q.KeyDigit7), constant.MakeInt64(int64(q.KeyDigit7))}, + "KeyDigit8": {reflect.TypeOf(q.KeyDigit8), constant.MakeInt64(int64(q.KeyDigit8))}, + "KeyDigit9": {reflect.TypeOf(q.KeyDigit9), constant.MakeInt64(int64(q.KeyDigit9))}, + "KeyDown": {reflect.TypeOf(q.KeyDown), constant.MakeInt64(int64(q.KeyDown))}, + "KeyE": {reflect.TypeOf(q.KeyE), constant.MakeInt64(int64(q.KeyE))}, + "KeyEnd": {reflect.TypeOf(q.KeyEnd), constant.MakeInt64(int64(q.KeyEnd))}, + "KeyEnter": {reflect.TypeOf(q.KeyEnter), constant.MakeInt64(int64(q.KeyEnter))}, + "KeyEqual": {reflect.TypeOf(q.KeyEqual), constant.MakeInt64(int64(q.KeyEqual))}, + "KeyEscape": {reflect.TypeOf(q.KeyEscape), constant.MakeInt64(int64(q.KeyEscape))}, + "KeyF": {reflect.TypeOf(q.KeyF), constant.MakeInt64(int64(q.KeyF))}, + "KeyF1": {reflect.TypeOf(q.KeyF1), constant.MakeInt64(int64(q.KeyF1))}, + "KeyF10": {reflect.TypeOf(q.KeyF10), constant.MakeInt64(int64(q.KeyF10))}, + "KeyF11": {reflect.TypeOf(q.KeyF11), constant.MakeInt64(int64(q.KeyF11))}, + "KeyF12": {reflect.TypeOf(q.KeyF12), constant.MakeInt64(int64(q.KeyF12))}, + "KeyF13": {reflect.TypeOf(q.KeyF13), constant.MakeInt64(int64(q.KeyF13))}, + "KeyF14": {reflect.TypeOf(q.KeyF14), constant.MakeInt64(int64(q.KeyF14))}, + "KeyF15": {reflect.TypeOf(q.KeyF15), constant.MakeInt64(int64(q.KeyF15))}, + "KeyF16": {reflect.TypeOf(q.KeyF16), constant.MakeInt64(int64(q.KeyF16))}, + "KeyF17": {reflect.TypeOf(q.KeyF17), constant.MakeInt64(int64(q.KeyF17))}, + "KeyF18": {reflect.TypeOf(q.KeyF18), constant.MakeInt64(int64(q.KeyF18))}, + "KeyF19": {reflect.TypeOf(q.KeyF19), constant.MakeInt64(int64(q.KeyF19))}, + "KeyF2": {reflect.TypeOf(q.KeyF2), constant.MakeInt64(int64(q.KeyF2))}, + "KeyF20": {reflect.TypeOf(q.KeyF20), constant.MakeInt64(int64(q.KeyF20))}, + "KeyF21": {reflect.TypeOf(q.KeyF21), constant.MakeInt64(int64(q.KeyF21))}, + "KeyF22": {reflect.TypeOf(q.KeyF22), constant.MakeInt64(int64(q.KeyF22))}, + "KeyF23": {reflect.TypeOf(q.KeyF23), constant.MakeInt64(int64(q.KeyF23))}, + "KeyF24": {reflect.TypeOf(q.KeyF24), constant.MakeInt64(int64(q.KeyF24))}, + "KeyF3": {reflect.TypeOf(q.KeyF3), constant.MakeInt64(int64(q.KeyF3))}, + "KeyF4": {reflect.TypeOf(q.KeyF4), constant.MakeInt64(int64(q.KeyF4))}, + "KeyF5": {reflect.TypeOf(q.KeyF5), constant.MakeInt64(int64(q.KeyF5))}, + "KeyF6": {reflect.TypeOf(q.KeyF6), constant.MakeInt64(int64(q.KeyF6))}, + "KeyF7": {reflect.TypeOf(q.KeyF7), constant.MakeInt64(int64(q.KeyF7))}, + "KeyF8": {reflect.TypeOf(q.KeyF8), constant.MakeInt64(int64(q.KeyF8))}, + "KeyF9": {reflect.TypeOf(q.KeyF9), constant.MakeInt64(int64(q.KeyF9))}, + "KeyG": {reflect.TypeOf(q.KeyG), constant.MakeInt64(int64(q.KeyG))}, + "KeyGraveAccent": {reflect.TypeOf(q.KeyGraveAccent), constant.MakeInt64(int64(q.KeyGraveAccent))}, + "KeyH": {reflect.TypeOf(q.KeyH), constant.MakeInt64(int64(q.KeyH))}, + "KeyHome": {reflect.TypeOf(q.KeyHome), constant.MakeInt64(int64(q.KeyHome))}, + "KeyI": {reflect.TypeOf(q.KeyI), constant.MakeInt64(int64(q.KeyI))}, + "KeyInsert": {reflect.TypeOf(q.KeyInsert), constant.MakeInt64(int64(q.KeyInsert))}, + "KeyIntlBackslash": {reflect.TypeOf(q.KeyIntlBackslash), constant.MakeInt64(int64(q.KeyIntlBackslash))}, + "KeyJ": {reflect.TypeOf(q.KeyJ), constant.MakeInt64(int64(q.KeyJ))}, + "KeyK": {reflect.TypeOf(q.KeyK), constant.MakeInt64(int64(q.KeyK))}, + "KeyKP0": {reflect.TypeOf(q.KeyKP0), constant.MakeInt64(int64(q.KeyKP0))}, + "KeyKP1": {reflect.TypeOf(q.KeyKP1), constant.MakeInt64(int64(q.KeyKP1))}, + "KeyKP2": {reflect.TypeOf(q.KeyKP2), constant.MakeInt64(int64(q.KeyKP2))}, + "KeyKP3": {reflect.TypeOf(q.KeyKP3), constant.MakeInt64(int64(q.KeyKP3))}, + "KeyKP4": {reflect.TypeOf(q.KeyKP4), constant.MakeInt64(int64(q.KeyKP4))}, + "KeyKP5": {reflect.TypeOf(q.KeyKP5), constant.MakeInt64(int64(q.KeyKP5))}, + "KeyKP6": {reflect.TypeOf(q.KeyKP6), constant.MakeInt64(int64(q.KeyKP6))}, + "KeyKP7": {reflect.TypeOf(q.KeyKP7), constant.MakeInt64(int64(q.KeyKP7))}, + "KeyKP8": {reflect.TypeOf(q.KeyKP8), constant.MakeInt64(int64(q.KeyKP8))}, + "KeyKP9": {reflect.TypeOf(q.KeyKP9), constant.MakeInt64(int64(q.KeyKP9))}, + "KeyKPAdd": {reflect.TypeOf(q.KeyKPAdd), constant.MakeInt64(int64(q.KeyKPAdd))}, + "KeyKPDecimal": {reflect.TypeOf(q.KeyKPDecimal), constant.MakeInt64(int64(q.KeyKPDecimal))}, + "KeyKPDivide": {reflect.TypeOf(q.KeyKPDivide), constant.MakeInt64(int64(q.KeyKPDivide))}, + "KeyKPEnter": {reflect.TypeOf(q.KeyKPEnter), constant.MakeInt64(int64(q.KeyKPEnter))}, + "KeyKPEqual": {reflect.TypeOf(q.KeyKPEqual), constant.MakeInt64(int64(q.KeyKPEqual))}, + "KeyKPMultiply": {reflect.TypeOf(q.KeyKPMultiply), constant.MakeInt64(int64(q.KeyKPMultiply))}, + "KeyKPSubtract": {reflect.TypeOf(q.KeyKPSubtract), constant.MakeInt64(int64(q.KeyKPSubtract))}, + "KeyL": {reflect.TypeOf(q.KeyL), constant.MakeInt64(int64(q.KeyL))}, + "KeyLeft": {reflect.TypeOf(q.KeyLeft), constant.MakeInt64(int64(q.KeyLeft))}, + "KeyLeftBracket": {reflect.TypeOf(q.KeyLeftBracket), constant.MakeInt64(int64(q.KeyLeftBracket))}, + "KeyM": {reflect.TypeOf(q.KeyM), constant.MakeInt64(int64(q.KeyM))}, + "KeyMax": {reflect.TypeOf(q.KeyMax), constant.MakeInt64(int64(q.KeyMax))}, + "KeyMenu": {reflect.TypeOf(q.KeyMenu), constant.MakeInt64(int64(q.KeyMenu))}, + "KeyMeta": {reflect.TypeOf(q.KeyMeta), constant.MakeInt64(int64(q.KeyMeta))}, + "KeyMetaLeft": {reflect.TypeOf(q.KeyMetaLeft), constant.MakeInt64(int64(q.KeyMetaLeft))}, + "KeyMetaRight": {reflect.TypeOf(q.KeyMetaRight), constant.MakeInt64(int64(q.KeyMetaRight))}, + "KeyMinus": {reflect.TypeOf(q.KeyMinus), constant.MakeInt64(int64(q.KeyMinus))}, + "KeyN": {reflect.TypeOf(q.KeyN), constant.MakeInt64(int64(q.KeyN))}, + "KeyNumLock": {reflect.TypeOf(q.KeyNumLock), constant.MakeInt64(int64(q.KeyNumLock))}, + "KeyNumpad0": {reflect.TypeOf(q.KeyNumpad0), constant.MakeInt64(int64(q.KeyNumpad0))}, + "KeyNumpad1": {reflect.TypeOf(q.KeyNumpad1), constant.MakeInt64(int64(q.KeyNumpad1))}, + "KeyNumpad2": {reflect.TypeOf(q.KeyNumpad2), constant.MakeInt64(int64(q.KeyNumpad2))}, + "KeyNumpad3": {reflect.TypeOf(q.KeyNumpad3), constant.MakeInt64(int64(q.KeyNumpad3))}, + "KeyNumpad4": {reflect.TypeOf(q.KeyNumpad4), constant.MakeInt64(int64(q.KeyNumpad4))}, + "KeyNumpad5": {reflect.TypeOf(q.KeyNumpad5), constant.MakeInt64(int64(q.KeyNumpad5))}, + "KeyNumpad6": {reflect.TypeOf(q.KeyNumpad6), constant.MakeInt64(int64(q.KeyNumpad6))}, + "KeyNumpad7": {reflect.TypeOf(q.KeyNumpad7), constant.MakeInt64(int64(q.KeyNumpad7))}, + "KeyNumpad8": {reflect.TypeOf(q.KeyNumpad8), constant.MakeInt64(int64(q.KeyNumpad8))}, + "KeyNumpad9": {reflect.TypeOf(q.KeyNumpad9), constant.MakeInt64(int64(q.KeyNumpad9))}, + "KeyNumpadAdd": {reflect.TypeOf(q.KeyNumpadAdd), constant.MakeInt64(int64(q.KeyNumpadAdd))}, + "KeyNumpadDecimal": {reflect.TypeOf(q.KeyNumpadDecimal), constant.MakeInt64(int64(q.KeyNumpadDecimal))}, + "KeyNumpadDivide": {reflect.TypeOf(q.KeyNumpadDivide), constant.MakeInt64(int64(q.KeyNumpadDivide))}, + "KeyNumpadEnter": {reflect.TypeOf(q.KeyNumpadEnter), constant.MakeInt64(int64(q.KeyNumpadEnter))}, + "KeyNumpadEqual": {reflect.TypeOf(q.KeyNumpadEqual), constant.MakeInt64(int64(q.KeyNumpadEqual))}, + "KeyNumpadMultiply": {reflect.TypeOf(q.KeyNumpadMultiply), constant.MakeInt64(int64(q.KeyNumpadMultiply))}, + "KeyNumpadSubtract": {reflect.TypeOf(q.KeyNumpadSubtract), constant.MakeInt64(int64(q.KeyNumpadSubtract))}, + "KeyO": {reflect.TypeOf(q.KeyO), constant.MakeInt64(int64(q.KeyO))}, + "KeyP": {reflect.TypeOf(q.KeyP), constant.MakeInt64(int64(q.KeyP))}, + "KeyPageDown": {reflect.TypeOf(q.KeyPageDown), constant.MakeInt64(int64(q.KeyPageDown))}, + "KeyPageUp": {reflect.TypeOf(q.KeyPageUp), constant.MakeInt64(int64(q.KeyPageUp))}, + "KeyPause": {reflect.TypeOf(q.KeyPause), constant.MakeInt64(int64(q.KeyPause))}, + "KeyPeriod": {reflect.TypeOf(q.KeyPeriod), constant.MakeInt64(int64(q.KeyPeriod))}, + "KeyPrintScreen": {reflect.TypeOf(q.KeyPrintScreen), constant.MakeInt64(int64(q.KeyPrintScreen))}, + "KeyQ": {reflect.TypeOf(q.KeyQ), constant.MakeInt64(int64(q.KeyQ))}, + "KeyQuote": {reflect.TypeOf(q.KeyQuote), constant.MakeInt64(int64(q.KeyQuote))}, + "KeyR": {reflect.TypeOf(q.KeyR), constant.MakeInt64(int64(q.KeyR))}, + "KeyRight": {reflect.TypeOf(q.KeyRight), constant.MakeInt64(int64(q.KeyRight))}, + "KeyRightBracket": {reflect.TypeOf(q.KeyRightBracket), constant.MakeInt64(int64(q.KeyRightBracket))}, + "KeyS": {reflect.TypeOf(q.KeyS), constant.MakeInt64(int64(q.KeyS))}, + "KeyScrollLock": {reflect.TypeOf(q.KeyScrollLock), constant.MakeInt64(int64(q.KeyScrollLock))}, + "KeySemicolon": {reflect.TypeOf(q.KeySemicolon), constant.MakeInt64(int64(q.KeySemicolon))}, + "KeyShift": {reflect.TypeOf(q.KeyShift), constant.MakeInt64(int64(q.KeyShift))}, + "KeyShiftLeft": {reflect.TypeOf(q.KeyShiftLeft), constant.MakeInt64(int64(q.KeyShiftLeft))}, + "KeyShiftRight": {reflect.TypeOf(q.KeyShiftRight), constant.MakeInt64(int64(q.KeyShiftRight))}, + "KeySlash": {reflect.TypeOf(q.KeySlash), constant.MakeInt64(int64(q.KeySlash))}, + "KeySpace": {reflect.TypeOf(q.KeySpace), constant.MakeInt64(int64(q.KeySpace))}, + "KeyT": {reflect.TypeOf(q.KeyT), constant.MakeInt64(int64(q.KeyT))}, + "KeyTab": {reflect.TypeOf(q.KeyTab), constant.MakeInt64(int64(q.KeyTab))}, + "KeyU": {reflect.TypeOf(q.KeyU), constant.MakeInt64(int64(q.KeyU))}, + "KeyUp": {reflect.TypeOf(q.KeyUp), constant.MakeInt64(int64(q.KeyUp))}, + "KeyV": {reflect.TypeOf(q.KeyV), constant.MakeInt64(int64(q.KeyV))}, + "KeyW": {reflect.TypeOf(q.KeyW), constant.MakeInt64(int64(q.KeyW))}, + "KeyX": {reflect.TypeOf(q.KeyX), constant.MakeInt64(int64(q.KeyX))}, + "KeyY": {reflect.TypeOf(q.KeyY), constant.MakeInt64(int64(q.KeyY))}, + "KeyZ": {reflect.TypeOf(q.KeyZ), constant.MakeInt64(int64(q.KeyZ))}, + "MouseButton0": {reflect.TypeOf(q.MouseButton0), constant.MakeInt64(int64(q.MouseButton0))}, + "MouseButton1": {reflect.TypeOf(q.MouseButton1), constant.MakeInt64(int64(q.MouseButton1))}, + "MouseButton2": {reflect.TypeOf(q.MouseButton2), constant.MakeInt64(int64(q.MouseButton2))}, + "MouseButton3": {reflect.TypeOf(q.MouseButton3), constant.MakeInt64(int64(q.MouseButton3))}, + "MouseButton4": {reflect.TypeOf(q.MouseButton4), constant.MakeInt64(int64(q.MouseButton4))}, + "MouseButtonLeft": {reflect.TypeOf(q.MouseButtonLeft), constant.MakeInt64(int64(q.MouseButtonLeft))}, + "MouseButtonMax": {reflect.TypeOf(q.MouseButtonMax), constant.MakeInt64(int64(q.MouseButtonMax))}, + "MouseButtonMiddle": {reflect.TypeOf(q.MouseButtonMiddle), constant.MakeInt64(int64(q.MouseButtonMiddle))}, + "MouseButtonRight": {reflect.TypeOf(q.MouseButtonRight), constant.MakeInt64(int64(q.MouseButtonRight))}, + "NonZero": {reflect.TypeOf(q.NonZero), constant.MakeInt64(int64(q.NonZero))}, + "StandardGamepadAxisLeftStickHorizontal": {reflect.TypeOf(q.StandardGamepadAxisLeftStickHorizontal), constant.MakeInt64(int64(q.StandardGamepadAxisLeftStickHorizontal))}, + "StandardGamepadAxisLeftStickVertical": {reflect.TypeOf(q.StandardGamepadAxisLeftStickVertical), constant.MakeInt64(int64(q.StandardGamepadAxisLeftStickVertical))}, + "StandardGamepadAxisMax": {reflect.TypeOf(q.StandardGamepadAxisMax), constant.MakeInt64(int64(q.StandardGamepadAxisMax))}, + "StandardGamepadAxisRightStickHorizontal": {reflect.TypeOf(q.StandardGamepadAxisRightStickHorizontal), constant.MakeInt64(int64(q.StandardGamepadAxisRightStickHorizontal))}, + "StandardGamepadAxisRightStickVertical": {reflect.TypeOf(q.StandardGamepadAxisRightStickVertical), constant.MakeInt64(int64(q.StandardGamepadAxisRightStickVertical))}, + "StandardGamepadButtonCenterCenter": {reflect.TypeOf(q.StandardGamepadButtonCenterCenter), constant.MakeInt64(int64(q.StandardGamepadButtonCenterCenter))}, + "StandardGamepadButtonCenterLeft": {reflect.TypeOf(q.StandardGamepadButtonCenterLeft), constant.MakeInt64(int64(q.StandardGamepadButtonCenterLeft))}, + "StandardGamepadButtonCenterRight": {reflect.TypeOf(q.StandardGamepadButtonCenterRight), constant.MakeInt64(int64(q.StandardGamepadButtonCenterRight))}, + "StandardGamepadButtonFrontBottomLeft": {reflect.TypeOf(q.StandardGamepadButtonFrontBottomLeft), constant.MakeInt64(int64(q.StandardGamepadButtonFrontBottomLeft))}, + "StandardGamepadButtonFrontBottomRight": {reflect.TypeOf(q.StandardGamepadButtonFrontBottomRight), constant.MakeInt64(int64(q.StandardGamepadButtonFrontBottomRight))}, + "StandardGamepadButtonFrontTopLeft": {reflect.TypeOf(q.StandardGamepadButtonFrontTopLeft), constant.MakeInt64(int64(q.StandardGamepadButtonFrontTopLeft))}, + "StandardGamepadButtonFrontTopRight": {reflect.TypeOf(q.StandardGamepadButtonFrontTopRight), constant.MakeInt64(int64(q.StandardGamepadButtonFrontTopRight))}, + "StandardGamepadButtonLeftBottom": {reflect.TypeOf(q.StandardGamepadButtonLeftBottom), constant.MakeInt64(int64(q.StandardGamepadButtonLeftBottom))}, + "StandardGamepadButtonLeftLeft": {reflect.TypeOf(q.StandardGamepadButtonLeftLeft), constant.MakeInt64(int64(q.StandardGamepadButtonLeftLeft))}, + "StandardGamepadButtonLeftRight": {reflect.TypeOf(q.StandardGamepadButtonLeftRight), constant.MakeInt64(int64(q.StandardGamepadButtonLeftRight))}, + "StandardGamepadButtonLeftStick": {reflect.TypeOf(q.StandardGamepadButtonLeftStick), constant.MakeInt64(int64(q.StandardGamepadButtonLeftStick))}, + "StandardGamepadButtonLeftTop": {reflect.TypeOf(q.StandardGamepadButtonLeftTop), constant.MakeInt64(int64(q.StandardGamepadButtonLeftTop))}, + "StandardGamepadButtonMax": {reflect.TypeOf(q.StandardGamepadButtonMax), constant.MakeInt64(int64(q.StandardGamepadButtonMax))}, + "StandardGamepadButtonRightBottom": {reflect.TypeOf(q.StandardGamepadButtonRightBottom), constant.MakeInt64(int64(q.StandardGamepadButtonRightBottom))}, + "StandardGamepadButtonRightLeft": {reflect.TypeOf(q.StandardGamepadButtonRightLeft), constant.MakeInt64(int64(q.StandardGamepadButtonRightLeft))}, + "StandardGamepadButtonRightRight": {reflect.TypeOf(q.StandardGamepadButtonRightRight), constant.MakeInt64(int64(q.StandardGamepadButtonRightRight))}, + "StandardGamepadButtonRightStick": {reflect.TypeOf(q.StandardGamepadButtonRightStick), constant.MakeInt64(int64(q.StandardGamepadButtonRightStick))}, + "StandardGamepadButtonRightTop": {reflect.TypeOf(q.StandardGamepadButtonRightTop), constant.MakeInt64(int64(q.StandardGamepadButtonRightTop))}, + "WindowResizingModeDisabled": {reflect.TypeOf(q.WindowResizingModeDisabled), constant.MakeInt64(int64(q.WindowResizingModeDisabled))}, + "WindowResizingModeEnabled": {reflect.TypeOf(q.WindowResizingModeEnabled), constant.MakeInt64(int64(q.WindowResizingModeEnabled))}, + "WindowResizingModeOnlyFullscreenEnabled": {reflect.TypeOf(q.WindowResizingModeOnlyFullscreenEnabled), constant.MakeInt64(int64(q.WindowResizingModeOnlyFullscreenEnabled))}, + }, + UntypedConsts: map[string]igop.UntypedConst{ + "ColorMDim": {"untyped int", constant.MakeInt64(int64(q.ColorMDim))}, + "DefaultTPS": {"untyped int", constant.MakeInt64(int64(q.DefaultTPS))}, + "GeoMDim": {"untyped int", constant.MakeInt64(int64(q.GeoMDim))}, + "MaxIndicesCount": {"untyped int", constant.MakeInt64(int64(q.MaxIndicesCount))}, + "MaxIndicesNum": {"untyped int", constant.MakeInt64(int64(q.MaxIndicesNum))}, + "MaxVertexCount": {"untyped int", constant.MakeInt64(int64(q.MaxVertexCount))}, + "MaxVerticesCount": {"untyped int", constant.MakeInt64(int64(q.MaxVerticesCount))}, + "SyncWithFPS": {"untyped int", constant.MakeInt64(int64(q.SyncWithFPS))}, + "UncappedTPS": {"untyped int", constant.MakeInt64(int64(q.UncappedTPS))}, + }, + }) +} diff --git a/cmd/ispx/runner.html b/cmd/ispx/runner.html new file mode 100644 index 00000000..aafb0119 --- /dev/null +++ b/cmd/ispx/runner.html @@ -0,0 +1,30 @@ + + + + + + + + + + + diff --git a/cmd/ispx/runweb.sh b/cmd/ispx/runweb.sh new file mode 100644 index 00000000..5ce3643c --- /dev/null +++ b/cmd/ispx/runweb.sh @@ -0,0 +1,11 @@ + + +if [ "$1" != "" ]; then + exit 1 +fi + +./build.sh + +python -m http.server 13511 + + diff --git a/cmd/ispx/test.zip b/cmd/ispx/test.zip new file mode 100644 index 0000000000000000000000000000000000000000..187bee8fc0fdf753353179b9be0743275e36bae7 GIT binary patch literal 45135 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 3e7 { - if me := gco.Current(); me != nil { - gco.Sched(me) - } - lastSched = now - } return 0 } @@ -1265,8 +1264,12 @@ func (p *Game) Username() string { // ----------------------------------------------------------------------------- +func (p *Game) WaitNextFrame() { + gco.WaitNextFrame() +} + func (p *Game) Wait(secs float64) { - gco.Sleep(time.Duration(secs * 1e9)) + gco.Wait(secs) } func (p *Game) Timer() float64 { diff --git a/internal/audiorecord/audiorecord_nojs.go b/internal/audiorecord/audiorecord_nojs.go index 1290d966..934a5d3d 100644 --- a/internal/audiorecord/audiorecord_nojs.go +++ b/internal/audiorecord/audiorecord_nojs.go @@ -6,7 +6,6 @@ package audiorecord import ( "encoding/binary" "math" - "time" "github.com/goplus/spx/internal/coroutine" ) @@ -18,7 +17,7 @@ const ( audioFrameSize = 6 * audioSampleRate / 100 // audioDefaultInterval is the default interval that audio packets are sent - audioInterval = 6 * 10 * time.Millisecond + audioInterval = 0.06 // 6 * 10 * time.Millisecond VOLUMEMAX = 32767.0 VOLUMEMIN = -32768.0 @@ -50,13 +49,13 @@ func Open(gco *coroutine.Coroutines) *Recorder { int16Buffer[i] = int16(binary.LittleEndian.Uint16(buff[i*2 : (i+1)*2])) } p.deviceVolume = p.doubleCalculateVolume(int16Buffer) - gco.Sleep(audioInterval) + gco.Wait(audioInterval) } }) return p } -//loudness scaled 0 to 100 +// loudness scaled 0 to 100 func (p *Recorder) doubleCalculateVolume(buffer []int16) float64 { var sum float64 = 0 diff --git a/internal/coroutine/coro.go b/internal/coroutine/coro.go index e37092bb..7eab63a1 100644 --- a/internal/coroutine/coro.go +++ b/internal/coroutine/coro.go @@ -2,11 +2,13 @@ package coroutine import ( "errors" + "fmt" "runtime" "sync" "sync/atomic" - "time" "unsafe" + + "github.com/goplus/spx/internal/time" ) var ( @@ -23,6 +25,7 @@ type ThreadObj interface { type threadImpl struct { Obj ThreadObj stopped_ bool + frame int } func (p *threadImpl) Stopped() bool { @@ -30,31 +33,69 @@ func (p *threadImpl) Stopped() bool { } // Thread represents a coroutine id. -// type Thread = *threadImpl // Coroutines represents a coroutine manager. -// type Coroutines struct { + hasInited bool suspended map[Thread]bool current Thread mutex sync.Mutex cond sync.Cond sema sync.Mutex + frame int + curQueue *Queue[*WaitJob] + nextQueue *Queue[*WaitJob] + curId int64 + + waiting map[Thread]bool + debug bool + waitMutex sync.Mutex + waitCond sync.Cond +} + +const ( + waitStatusAdd = iota + waitStatusDelete + waitStatusBlock + waitStatusIdle + waitNotify +) + +const ( + waitTypeFrame = iota + waitTypeTime + waitTypeMainThread +) + +type WaitJob struct { + Id int64 + Type int + Call func() + Time float64 + Frame int64 } // New creates a coroutine manager. -// func New() *Coroutines { p := &Coroutines{ suspended: make(map[Thread]bool), + waiting: make(map[Thread]bool), + debug: false, } p.cond.L = &p.mutex + p.curQueue = NewQueue[*WaitJob]() + p.nextQueue = NewQueue[*WaitJob]() + p.hasInited = false + p.waitCond.L = &p.waitMutex return p } +func (p *Coroutines) OnInited() { + p.hasInited = true +} + // Create creates a new coroutine. -// func (p *Coroutines) Create(tobj ThreadObj, fn func(me Thread) int) Thread { return p.CreateAndStart(false, tobj, fn) } @@ -68,9 +109,8 @@ func (p *Coroutines) Current() Thread { } // CreateAndStart creates and executes the new coroutine. -// func (p *Coroutines) CreateAndStart(start bool, tobj ThreadObj, fn func(me Thread) int) Thread { - id := &threadImpl{Obj: tobj} + id := &threadImpl{Obj: tobj, frame: p.frame} go func() { p.sema.Lock() p.setCurrent(id) @@ -78,6 +118,7 @@ func (p *Coroutines) CreateAndStart(start bool, tobj ThreadObj, fn func(me Threa p.mutex.Lock() delete(p.suspended, id) p.mutex.Unlock() + p.setWaitStatus(id, waitStatusDelete) p.sema.Unlock() if e := recover(); e != nil { if e != ErrAbortThread { @@ -85,6 +126,7 @@ func (p *Coroutines) CreateAndStart(start bool, tobj ThreadObj, fn func(me Threa } } }() + p.setWaitStatus(id, waitStatusAdd) fn(id) }() if start { @@ -108,7 +150,6 @@ func (p *Coroutines) StopIf(filter func(th Thread) bool) { } // Yield suspends a running coroutine. -// func (p *Coroutines) Yield(me Thread) { if p.Current() != me { panic(ErrCannotYieldANonrunningThread) @@ -120,6 +161,9 @@ func (p *Coroutines) Yield(me Thread) { p.cond.Wait() } p.mutex.Unlock() + + p.waitNotify() + p.sema.Lock() p.setCurrent(me) @@ -129,13 +173,12 @@ func (p *Coroutines) Yield(me Thread) { } // Resume resumes a suspended coroutine. -// -func (p *Coroutines) Resume(th Thread) { +func (p *Coroutines) Resume(me Thread) { for { done := false p.mutex.Lock() - if p.suspended[th] { - p.suspended[th] = false + if p.suspended[me] { + p.suspended[me] = false p.cond.Broadcast() done = true } @@ -147,22 +190,197 @@ func (p *Coroutines) Resume(th Thread) { } } -// Sched func. -// -func (p *Coroutines) Sched(me Thread) { +func (p *Coroutines) addWaitJob(job *WaitJob, isFront bool) { + p.waitMutex.Lock() + if isFront { + p.curQueue.PushFront(job) + } else { + p.curQueue.PushBack(job) + } + p.waitCond.Signal() + p.waitMutex.Unlock() +} + +func (p *Coroutines) waitNotify() { + p.waitMutex.Lock() + p.waitCond.Signal() + p.waitMutex.Unlock() +} + +func (p *Coroutines) setWaitStatus(me *threadImpl, typeId int) { + p.waitMutex.Lock() + switch typeId { + case waitStatusDelete: + delete(p.waiting, me) + case waitStatusAdd: + p.waiting[me] = false + case waitStatusBlock: + p.waiting[me] = true + case waitStatusIdle: + p.waiting[me] = false + } + p.waitCond.Signal() + p.waitMutex.Unlock() +} + +func (p *Coroutines) Wait(t float64) { + id := atomic.AddInt64(&p.curId, 1) + me := p.Current() + dstTime := time.TimeSinceLevelLoad() + t go func() { + done := make(chan int) + job := &WaitJob{ + Id: id, + Type: waitTypeTime, + Call: func() { + p.setWaitStatus(me, waitStatusIdle) + done <- 1 + }, + Time: dstTime, + } + p.addWaitJob(job, false) + <-done p.Resume(me) }() + p.setWaitStatus(me, waitStatusBlock) p.Yield(me) } -func (p *Coroutines) Sleep(t time.Duration) { +func (p *Coroutines) WaitNextFrame() { + id := atomic.AddInt64(&p.curId, 1) me := p.Current() + frame := time.Frame() go func() { - time.Sleep(t) + done := make(chan int) + job := &WaitJob{ + Id: id, + Type: waitTypeFrame, + Call: func() { + p.setWaitStatus(me, waitStatusIdle) + done <- 1 + }, + Frame: frame, + } + p.addWaitJob(job, false) + <-done p.Resume(me) }() + p.setWaitStatus(me, waitStatusBlock) p.Yield(me) } +func (p *Coroutines) WaitMainThread(call func()) { + id := atomic.AddInt64(&p.curId, 1) + done := make(chan int) + job := &WaitJob{ + Id: id, + Type: waitTypeMainThread, + Call: func() { + call() + done <- 1 + }, + } + // main thread call's priority is higher than other wait jobs + p.addWaitJob(job, true) + <-done +} + +func (p *Coroutines) WaitToDo(fn func()) { + me := p.Current() + go func() { + fn() + p.setWaitStatus(me, waitStatusIdle) + p.Resume(me) + }() + p.setWaitStatus(me, waitStatusBlock) + p.Yield(me) +} + +func WaitForChan[T any](p *Coroutines, done chan T, data *T) { + me := p.Current() + go func() { + *data = <-done + p.setWaitStatus(me, waitStatusIdle) + p.Resume(me) + }() + p.setWaitStatus(me, waitStatusBlock) + p.Yield(me) +} + +func (p *Coroutines) UpdateJobs() { + timestamp := time.RealTimeSinceStart() + curQueue := p.curQueue + nextQueue := p.nextQueue + curFrame := time.Frame() + curTime := time.TimeSinceLevelLoad() + debugStartTime := time.RealTimeSinceStart() + waitFrameCount := 0 + waitMainCount := 0 + for { + if !p.hasInited { + if curQueue.Count() == 0 { + time.Sleep(0.05) // 0.05ms + continue + } + } else { + done := false + isContinue := false + p.waitMutex.Lock() + if curQueue.Count() == 0 { + activeCount := 0 + for _, val := range p.waiting { + if !val { + activeCount++ + } + } + if activeCount == 0 { + done = true + } else { + p.waitCond.Wait() + isContinue = true + } + } + p.waitMutex.Unlock() + if done { + break + } + if isContinue { + continue + } + } + + task := curQueue.PopFront() + switch task.Type { + case waitTypeFrame: + if task.Frame >= curFrame { + nextQueue.PushBack(task) + } else { + task.Call() + waitFrameCount++ + } + case waitTypeTime: + if task.Time >= curTime { + nextQueue.PushBack(task) + } else { + task.Call() + } + case waitTypeMainThread: + task.Call() + waitMainCount++ + } + if time.RealTimeSinceStart()-debugStartTime > 1 { + println("Warning: engine update > 1 seconds, please check your code ! waitMainCount=", waitMainCount) + break + } + } + nextCount := nextQueue.Count() + curQueue.Move(nextQueue) + delta := (time.RealTimeSinceStart() - timestamp) * 1000 + if delta > 10 { + fmt.Printf("curFrame %d,useTime %fms,fps %d, taskCount %d,curTime %f , moveCount %d \n", curFrame, delta, int(time.FPS()), waitFrameCount, curTime, nextCount) + } else { + fmt.Printf("curFrame %d,useTime %fms\n", curFrame, delta) + } +} + // ------------------------------------------------------------------------------------- diff --git a/internal/coroutine/queue.go b/internal/coroutine/queue.go new file mode 100644 index 00000000..f5d68094 --- /dev/null +++ b/internal/coroutine/queue.go @@ -0,0 +1,128 @@ +package coroutine + +import "sync" + +type node[T any] struct { + value T + prev *node[T] + next *node[T] +} + +type Queue[T any] struct { + mu sync.Mutex + head *node[T] + tail *node[T] + count int +} + +func NewQueue[T any]() *Queue[T] { + return &Queue[T]{} +} + +// Move all tasks from the src queue to the current queue. +// Afterward, the src queue will be empty. +func (s *Queue[T]) Move(src *Queue[T]) { + s.mu.Lock() + defer s.mu.Unlock() + src.mu.Lock() + defer src.mu.Unlock() + + if src.count == 0 { + return + } + + if s.count == 0 { + s.head = src.head + s.tail = src.tail + } else { + s.tail.next = src.head + src.head.prev = s.tail + s.tail = src.tail + } + s.count += src.count + + // Clear source queue + src.head = nil + src.tail = nil + src.count = 0 +} + +func (s *Queue[T]) Count() int { + s.mu.Lock() + defer s.mu.Unlock() + return s.count +} + +func (s *Queue[T]) PushBack(value T) { + s.mu.Lock() + defer s.mu.Unlock() + + newNode := &node[T]{value: value} + if s.count == 0 { + s.head = newNode + s.tail = newNode + } else { + newNode.prev = s.tail + s.tail.next = newNode + s.tail = newNode + } + s.count++ +} + +func (s *Queue[T]) PushFront(value T) { + s.mu.Lock() + defer s.mu.Unlock() + + newNode := &node[T]{value: value} + if s.count == 0 { + s.head = newNode + s.tail = newNode + } else { + newNode.next = s.head + s.head.prev = newNode + s.head = newNode + } + s.count++ +} + +func (s *Queue[T]) PopFront() T { + s.mu.Lock() + defer s.mu.Unlock() + + if s.count == 0 { + panic("queue is empty") + } + + value := s.head.value + s.head = s.head.next + s.count-- + + if s.count == 0 { + s.tail = nil + } else { + s.head.prev = nil + } + + return value +} + +func (s *Queue[T]) PopBack() T { + s.mu.Lock() + defer s.mu.Unlock() + + if s.count == 0 { + panic("queue is empty") + } + + value := s.tail.value + s.tail = s.tail.prev + s.count-- + + if s.count == 0 { + s.head = nil + } else { + s.tail.next = nil + } + + return value +} diff --git a/internal/time/time.go b/internal/time/time.go new file mode 100644 index 00000000..77b2fcde --- /dev/null +++ b/internal/time/time.go @@ -0,0 +1,75 @@ +package time + +import ( + stime "time" +) + +var ( + unscaledTimeSinceLevelLoad float64 + timeSinceLevelLoad float64 + deltaTime float64 + unscaledDeltaTime float64 + timeScale float64 + curFrame int64 + setTimeScaleCallback func(float64) + startTimestamp stime.Time + fps float64 +) + +func Sleep(ms float64) { + stime.Sleep(stime.Microsecond * stime.Duration((ms * 1000))) +} + +func RealTimeSinceStart() float64 { + return stime.Since(startTimestamp).Seconds() +} +func FPS() float64 { + return fps +} +func Frame() int64 { + return curFrame +} + +func TimeScale() float64 { + return timeScale +} + +func SetTimeScale(value float64) { + if setTimeScaleCallback != nil { + setTimeScaleCallback(value) + } + timeScale = value +} + +func DeltaTime() float64 { + return deltaTime +} + +func UnscaledDeltaTime() float64 { + return unscaledDeltaTime +} + +// no time scale +func UnscaledTimeSinceLevelLoad() float64 { + return unscaledTimeSinceLevelLoad +} + +func TimeSinceLevelLoad() float64 { + return timeSinceLevelLoad +} + +func Start(setTimeScaleCB func(float64)) { + Update(1, 0, 0, 0, 0, 30) + setTimeScaleCallback = setTimeScaleCB + startTimestamp = stime.Now() +} + +func Update(scale float64, realDuration float64, duration float64, delta float64, unscaledDelta float64, pfps float64) { + timeScale = scale + unscaledDeltaTime = unscaledDelta + unscaledTimeSinceLevelLoad = realDuration + timeSinceLevelLoad = duration + deltaTime = delta + curFrame += 1 + fps = pfps +} diff --git a/sprite.go b/sprite.go index f7bf4149..199b9e30 100644 --- a/sprite.go +++ b/sprite.go @@ -26,6 +26,7 @@ import ( "github.com/goplus/spx/internal/anim" "github.com/goplus/spx/internal/gdi/clrutil" "github.com/goplus/spx/internal/math32" + "github.com/goplus/spx/internal/time" "github.com/goplus/spx/internal/tools" ) @@ -215,6 +216,9 @@ type Sprite interface { Visible() bool Xpos() float64 Ypos() float64 + TimeSinceLevelLoad() float64 + DeltaTime() float64 + RealTimeSinceStart() float64 } type SpriteName = string @@ -1866,3 +1870,13 @@ func (p *SpriteImpl) fixWorldRange(x, y float64) (float64, float64) { } // ----------------------------------------------------------------------------- +func (pself *SpriteImpl) DeltaTime() float64 { + return time.DeltaTime() +} + +func (pself *SpriteImpl) TimeSinceLevelLoad() float64 { + return time.TimeSinceLevelLoad() +} +func (pself *SpriteImpl) RealTimeSinceStart() float64 { + return time.RealTimeSinceStart() +} diff --git a/tutorial/.gitignore b/tutorial/.gitignore new file mode 100644 index 00000000..b5c057fd --- /dev/null +++ b/tutorial/.gitignore @@ -0,0 +1,5 @@ +/13-testv6 +/14-test +/15-game +/16-animation +/17-AlphaBound \ No newline at end of file diff --git a/tutorial/05-Animation/.gitignore b/tutorial/05-Animation/.gitignore new file mode 100644 index 00000000..9fe53863 --- /dev/null +++ b/tutorial/05-Animation/.gitignore @@ -0,0 +1,5 @@ +gop_autogen.go +index.html +wasm_exec.js +server.go +*.wasm \ No newline at end of file diff --git a/tutorial/05-Animation/Bullet.spx b/tutorial/05-Animation/Bullet.spx index 49d1e943..b98b0dfc 100644 --- a/tutorial/05-Animation/Bullet.spx +++ b/tutorial/05-Animation/Bullet.spx @@ -3,10 +3,6 @@ onTouchStart => { } onStart => { - for { - wait 0.3 - clone - } } onCloned => { diff --git a/tutorial/05-Animation/SmallEnemy.spx b/tutorial/05-Animation/SmallEnemy.spx index 28b2b39d..532311e0 100644 --- a/tutorial/05-Animation/SmallEnemy.spx +++ b/tutorial/05-Animation/SmallEnemy.spx @@ -1,26 +1,34 @@ var life int onStart => { - for { - wait 0.3 - clone - } + for i := 1; i <= 20; i++ { + wait 0.3 + clone + } + } onCloned => { - life = 3 - setXYpos rand(-131, 131), 237 - show - for { - wait 0.05 - changeYpos -2.4 - if touching(EdgeBottom) { - destroy - } - } + life = 3 + setXYpos rand(-0, 0), 200 + show + for { + //debugLog("====waitNextFrame ", this.GameFrame()) + waitNextFrame + startTimer := realTimeSinceStart + changeYpos -100 * deltaTime + if touching(EdgeBottom) { + setXYpos xpos, 200 + } + dt := (realTimeSinceStart - startTimer) *1000 + if(false){ + println(dt) + } + //debugLog("====frame ", gameFrame," dt = ", dt) + } } onTouchStart "Bullet", => { - if life > 0 { + if life > 0 { life -- if life <= 0 { die diff --git a/tutorial/05-Animation/assets/sprites/SmallEnemy/index.json b/tutorial/05-Animation/assets/sprites/SmallEnemy/index.json index 0b210864..c9bca3db 100644 --- a/tutorial/05-Animation/assets/sprites/SmallEnemy/index.json +++ b/tutorial/05-Animation/assets/sprites/SmallEnemy/index.json @@ -37,16 +37,6 @@ } ], "costumeIndex": 0, - "fAnimations": { - "die": { - "onStart":{ - "play": "explode" - }, - "frameFps": 20, - "frameFrom": "die-0", - "frameTo": "die-3" - } - }, "heading": 90, "isDraggable": false, "rotationStyle": "normal", diff --git a/tutorial/05-Animation/runweb.sh b/tutorial/05-Animation/runweb.sh new file mode 100644 index 00000000..bc2c0f70 --- /dev/null +++ b/tutorial/05-Animation/runweb.sh @@ -0,0 +1,47 @@ + +rm -rf wasm_exec.js +rm -rf index.html +rm -rf server.go +rm -rf *.wasm +if [ "$1" == "-i" ]; then + cd ../../cmd/ispx + cp -f "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./ + ./runweb.sh + cd ../../tutorial/05-Animation + exit 0 +fi + +gop go +GOEXPERIMENT=noregabi GOOS=js GOARCH=wasm go build --tags canvas -o test.wasm +cp -f "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./ +cp -f "$(go env GOROOT)/misc/wasm/wasm_exec.html" ./index.html + + + +echo '// test.go +package main + +import ( + "flag" + "log" + "net/http" + "strings" +) + +var ( + listen = flag.String("listen", ":8080", "listen address") + dir = flag.String("dir", ".", "directory to serve") +) + +func main() { + flag.Parse() + log.Printf("listening on %q...", *listen) + log.Fatal(http.ListenAndServe(*listen, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if strings.HasSuffix(req.URL.Path, ".wasm") { + resp.Header().Set("content-type", "application/wasm") + } + + http.FileServer(http.Dir(*dir)).ServeHTTP(resp, req) + }))) +}'> server.go +go run server.go \ No newline at end of file diff --git a/tutorial/06-CoroDebug/.gitignore b/tutorial/06-CoroDebug/.gitignore new file mode 100644 index 00000000..9fe53863 --- /dev/null +++ b/tutorial/06-CoroDebug/.gitignore @@ -0,0 +1,5 @@ +gop_autogen.go +index.html +wasm_exec.js +server.go +*.wasm \ No newline at end of file diff --git a/tutorial/06-CoroDebug/Bullet.spx b/tutorial/06-CoroDebug/Bullet.spx new file mode 100644 index 00000000..b98b0dfc --- /dev/null +++ b/tutorial/06-CoroDebug/Bullet.spx @@ -0,0 +1,18 @@ +onTouchStart => { + destroy +} + +onStart => { +} + +onCloned => { + setXYpos mouseX, mouseY + show + for { + wait 0.04 + step 10 + if touching(Edge) { + destroy + } + } +} diff --git a/tutorial/06-CoroDebug/SmallEnemy.spx b/tutorial/06-CoroDebug/SmallEnemy.spx new file mode 100644 index 00000000..532311e0 --- /dev/null +++ b/tutorial/06-CoroDebug/SmallEnemy.spx @@ -0,0 +1,37 @@ +var life int +onStart => { + for i := 1; i <= 20; i++ { + wait 0.3 + clone + } + +} + +onCloned => { + life = 3 + setXYpos rand(-0, 0), 200 + show + for { + //debugLog("====waitNextFrame ", this.GameFrame()) + waitNextFrame + startTimer := realTimeSinceStart + changeYpos -100 * deltaTime + if touching(EdgeBottom) { + setXYpos xpos, 200 + } + dt := (realTimeSinceStart - startTimer) *1000 + if(false){ + println(dt) + } + //debugLog("====frame ", gameFrame," dt = ", dt) + } +} + +onTouchStart "Bullet", => { + if life > 0 { + life -- + if life <= 0 { + die + } + } +} \ No newline at end of file diff --git a/tutorial/06-CoroDebug/assets/1.png b/tutorial/06-CoroDebug/assets/1.png new file mode 100644 index 0000000000000000000000000000000000000000..c2e6e964c1c5014e7ab35a96ff5d6848064a374b GIT binary patch literal 12663 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 W4SBLLb`p3|33dW;oPPAu?f(VzjZ{Pc literal 0 HcmV?d00001 diff --git a/tutorial/06-CoroDebug/assets/index.json b/tutorial/06-CoroDebug/assets/index.json new file mode 100644 index 00000000..4cd8a9c9 --- /dev/null +++ b/tutorial/06-CoroDebug/assets/index.json @@ -0,0 +1,13 @@ +{ + "backdrops": [ + { + "bitmapResolution": 2, + "name": "backdrop1", + "path": "1.png" + } + ], + "zorder": [ + "Bullet", + "SmallEnemy" + ] +} \ No newline at end of file diff --git a/tutorial/06-CoroDebug/assets/sounds/explode/1.wav b/tutorial/06-CoroDebug/assets/sounds/explode/1.wav new file mode 100644 index 0000000000000000000000000000000000000000..3835c4d8ccf531d5ccfb802f9f0d154969dd5d5d GIT binary patch literal 9276 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 literal 0 HcmV?d00001 diff --git a/tutorial/06-CoroDebug/assets/sounds/explode/index.json b/tutorial/06-CoroDebug/assets/sounds/explode/index.json new file mode 100644 index 00000000..af4acf82 --- /dev/null +++ b/tutorial/06-CoroDebug/assets/sounds/explode/index.json @@ -0,0 +1,3 @@ +{ + "path": "1.wav" +} \ No newline at end of file diff --git a/tutorial/06-CoroDebug/assets/sprites/Bullet/30.png b/tutorial/06-CoroDebug/assets/sprites/Bullet/30.png new file mode 100644 index 0000000000000000000000000000000000000000..86001818326f52b89dcf770ce15f3ea7ee419cdb GIT binary patch literal 803 zcmV+;1Kj+HP)<00089NklT!Olt-{!FYO76eNXQp*PNlje?QGS9{re8>fR-`6B z#Vjm9g;QW9S#^@{;!5ChriHc;BMoRd|PPhkIOLBZUeov|+_{l9sK`QE4p_sEwq<#G7 zz$@WV(g%ro3m*j_)d^yl3(O0>Cg%4)TP6y;3WhPVVjPeNe+udz1YyRc(F*2i_)N%M zwzHP5^OwIO8}b;(45V4S$=O=MJcF1O=>=%8VVTHeO?L8WWP_colU1%Qs7T>2$1Jdq z6xU|UGLc(qaE;+A@<;HGLTtnU1WxG)6SdjVUDDBU+gWq^$d;p)80iOMp!#KU7$iZ+zN*_M5_9;{$Z_s~DQV=s zM98u!cJN*hrih_*(KQNDwM-;EkmNCXb>M&`ccxAudcImXE=*b zLH6c8zcCp484}gKwfqEU#d(~}ghI7@5<9J)<$dtQum5(c<(TES(5m$;_bKc)-LSi} zg?4!T2GSJg{YW~ne*gdgEp$a#bW?9;ba!ELWdLG%E@EtNZ)9Y7E@N_eaCC1jX>DO= hWiC)oM=~@;Zewp`Wpbznf9?PP002ovPDHLkV1kRKZ<_!B literal 0 HcmV?d00001 diff --git a/tutorial/06-CoroDebug/assets/sprites/Bullet/index.json b/tutorial/06-CoroDebug/assets/sprites/Bullet/index.json new file mode 100644 index 00000000..1b1dca06 --- /dev/null +++ b/tutorial/06-CoroDebug/assets/sprites/Bullet/index.json @@ -0,0 +1,20 @@ +{ + "costumes": [ + { + "bitmapResolution": 2, + "name": "bullet", + "path": "30.png", + "faceRight": 90, + "x": 8, + "y": 20 + } + ], + "costumeIndex": 0, + "heading": 0, + "isDraggable": false, + "rotationStyle": "normal", + "size": 0.65, + "visible": false, + "x": 230, + "y": 185 +} \ No newline at end of file diff --git a/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/32.png b/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/32.png new file mode 100644 index 0000000000000000000000000000000000000000..0404db76eda51986336515594b2f289800e27346 GIT binary patch literal 3441 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 Ts0M%T00000NkvXXu0mjfV@{g# literal 0 HcmV?d00001 diff --git a/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/33.png b/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/33.png new file mode 100644 index 0000000000000000000000000000000000000000..27dffd6643c0aa5625e8741e66c4877b064bed30 GIT binary patch literal 3959 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 Rf9?PP002ovPDHLkV1g@+xDx;X literal 0 HcmV?d00001 diff --git a/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/34.png b/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/34.png new file mode 100644 index 0000000000000000000000000000000000000000..ad983dff1b868943b588d8686484c0b255077c07 GIT binary patch literal 4388 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 KMNUMnLSTXjAhpE+ literal 0 HcmV?d00001 diff --git a/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/36.png b/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/36.png new file mode 100644 index 0000000000000000000000000000000000000000..4dc09b99188c19e1f49e80a60a690f67e0c62b31 GIT binary patch literal 1981 zcmV;u2SWIXP)WrE zsTQ$UTLvrz2HOGx3>OwZza-^OuWxbAKor|#t(+>#OQSHd+`pAgmh^fkoVHIIH$$oN<*>2<`$8pPgH zqLX;O5;49C?&LMm*Fo|EV)Z|wtV(__dIYh5#0d8};je=1PJHv(HjTZ5a5HT6a6h*& zW0v6iZ#(+=PV^no_eJku#_j>(0ptyTU`;cZ;#b1e6*P%{jSSD#_Q9VIfn<{DYOHB! zKf6TB5yRsk^$yObgnkL%{vp(=`*T137be ze+iCLqDDo3LhR1=9%>phjQ42OZ=VD40S{M}G{SvCcoMF{YsXOu{I2@svp8-$GQk*L ze-y5y7ydd1qDpcko$s$k#_QUDqSePI@p)44`TgrztBmkXAUvHRIZ9?TGB)1f3Bo6{ zHGq@_2a);O2gBV5L9A6ge*~X%2C+MW+D@CO-dP%XP^>q?3n0_*wL02_HD?mXX@56R`>A};Of|xNK=?FblV*ywAmA2=CBbRLQmvzF{k+q| zM|-UuDUh6L)4F&&T*sux`&Qv<%!m7h@N&fDzeROV;2sd@`gPcvgQT4x)9ae)tHX%N zOF52B6>0 zO0kBl!aY=Ecz)&s`YXCiAp4$&zfWLH!$!Ez2-g^;`%ZLMtM0hceIqvzTi4sPR-t$8 zUvT*0Al8T=2#g}8do}gzFJWeB?AG6P{_4?BE%J~Rb16O}JOE#-`#7EzJ%m+0hS<)S zTL)c4jMjbL=N+qmJ^XkN+(iTWOJhdp-S~YV`%h%f<8V)GnrZ6Z#94e^BfL-v*XrMH zkkpG<`-|uk$k2|0tU1KED!7zE#7_P{$|$aH9wd|CI{5jmIPVs?qZzDC>bHOM7{d5CVch)GC1xmnnSF;hT6ss_~ZoKP9OU5sxvFO$FNoeaDDxVvAh$M z!VEr%HK)tNjdZ}pd?7k)gclg$N=!3|)ZaB;chpGsBi2sgaTJ2S9c+)|@lQO9DoCff7Cr7qa4r*~jrE{VbZy!!_JbR1@5T-s99=0-qrR z%(l6%oBO|`SkoppI<>c!Z)9b1s0M%T P00000NkvXXu0mjfVF=l! literal 0 HcmV?d00001 diff --git a/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/index.json b/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/index.json new file mode 100644 index 00000000..c9bca3db --- /dev/null +++ b/tutorial/06-CoroDebug/assets/sprites/SmallEnemy/index.json @@ -0,0 +1,47 @@ +{ + "costumes": [ + { + "bitmapResolution": 2, + "name": "normal", + "path": "32.png", + "x": 50, + "y": 36 + }, + { + "bitmapResolution": 2, + "name": "die-0", + "path": "33.png", + "x": 50, + "y": 36 + }, + { + "bitmapResolution": 2, + "name": "die-1", + "path": "34.png", + "x": 50, + "y": 44 + }, + { + "bitmapResolution": 2, + "name": "die-2", + "path": "35.png", + "x": 56, + "y": 50 + }, + { + "bitmapResolution": 2, + "name": "die-3", + "path": "36.png", + "x": 44, + "y": 38 + } + ], + "costumeIndex": 0, + "heading": 90, + "isDraggable": false, + "rotationStyle": "normal", + "size": 0.65, + "visible": false, + "x": -58, + "y": -179 +} \ No newline at end of file diff --git a/tutorial/06-CoroDebug/main.spx b/tutorial/06-CoroDebug/main.spx new file mode 100644 index 00000000..2fe990fc --- /dev/null +++ b/tutorial/06-CoroDebug/main.spx @@ -0,0 +1,3 @@ +var ( + explode Sound +) diff --git a/tutorial/06-CoroDebug/run.sh b/tutorial/06-CoroDebug/run.sh new file mode 100644 index 00000000..40d3c0e1 --- /dev/null +++ b/tutorial/06-CoroDebug/run.sh @@ -0,0 +1,49 @@ + +rm -rf wasm_exec.js +rm -rf index.html +rm -rf server.go +rm -rf *.wasm + +if [ "$1" == "-i" ]; then + lastdir=$(pwd) + cd ../../cmd/ispx || exit + cp -f "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./ + ./runweb.sh + cd $lastdir || exit + exit 0 +fi + +gop go +GOEXPERIMENT=noregabi GOOS=js GOARCH=wasm go build --tags canvas -o test.wasm +cp -f "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./ +cp -f "$(go env GOROOT)/misc/wasm/wasm_exec.html" ./index.html + + + +echo '// test.go +package main + +import ( + "flag" + "log" + "net/http" + "strings" +) + +var ( + listen = flag.String("listen", ":13511", "listen address") + dir = flag.String("dir", ".", "directory to serve") +) + +func main() { + flag.Parse() + log.Printf("listening on %q...", *listen) + log.Fatal(http.ListenAndServe(*listen, http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { + if strings.HasSuffix(req.URL.Path, ".wasm") { + resp.Header().Set("content-type", "application/wasm") + } + + http.FileServer(http.Dir(*dir)).ServeHTTP(resp, req) + }))) +}'> server.go +go run server.go \ No newline at end of file