From c695b3f8f607bb763e150f82bcab5e70ca8f31c7 Mon Sep 17 00:00:00 2001 From: Sebastian Benjamin Date: Tue, 4 Feb 2025 22:06:12 -0800 Subject: [PATCH] Replace bullet integrator with rust version --- .gitignore | 8 +- Makefile | 15 ++ server/bullets.go | 33 --- server/collision.go | 1 - server/consts.go | 11 + server/main.go | 56 ++++- shared/Cargo.lock | 478 +++++++++++++++++++++++++++++++++++++++++++ shared/Cargo.toml | 18 ++ shared/build.rs | 36 ++++ shared/src/bullet.rs | 46 +++++ shared/src/ffi.rs | 44 ++++ shared/src/godot.rs | 0 shared/src/lib.rs | 5 + 13 files changed, 705 insertions(+), 46 deletions(-) create mode 100644 Makefile delete mode 100644 server/bullets.go delete mode 100644 server/collision.go create mode 100644 server/consts.go create mode 100644 shared/Cargo.lock create mode 100644 shared/Cargo.toml create mode 100644 shared/build.rs create mode 100644 shared/src/bullet.rs create mode 100644 shared/src/ffi.rs create mode 100644 shared/src/godot.rs create mode 100644 shared/src/lib.rs diff --git a/.gitignore b/.gitignore index 248446e..28d591c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,10 @@ **/test_suite/addons/* **/test_suite/.import/* -**/.godot/ \ No newline at end of file +**/.godot/ + +debug/ +release/ +target/ + +lib/ \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b8f3314 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +.PHONY: all build_shared deploy_server + +all: build_shared deploy_server + +build_shared: + cd shared && cargo build --release --target x86_64-unknown-linux-musl --features ffi + +build_godot: + cd shared && cargo build --release --target x86_64-unknown-linux-musl --features godot + +deploy_server: build_shared + if not exist server\\lib mkdir server\\lib + copy shared\\target\\x86_64-unknown-linux-musl\\release\\libshared.a server\\lib\\ + copy shared\\target\\shared.h server\\lib\\ + cd server && docker compose up --build \ No newline at end of file diff --git a/server/bullets.go b/server/bullets.go deleted file mode 100644 index 421c4f2..0000000 --- a/server/bullets.go +++ /dev/null @@ -1,33 +0,0 @@ -package main - -const ( - BULLET_LINEAR = iota -) - -const ( - STAGE_WIDTH float64 = 90.0 - STAGE_HEIGHT float64 = 160.0 - BULLET_KILL_BUFFER_WIDTH float64 = 16.0 -) - -type Bullet struct { - Class int - SpawnTime int64 - SpawnX float64 - SpawnY float64 - Parameters []float64 -} - -func (b Bullet) GetCurrentPos(tick int64) (float64, float64) { - switch b.Class { - case BULLET_LINEAR: - return b.SpawnX + (b.Parameters[0] * float64(tick-b.SpawnTime)), b.SpawnY + (b.Parameters[1] * float64(tick-b.SpawnTime)) - default: - return b.SpawnX, b.SpawnY - } -} - -func (b Bullet) BeyondKillBoundary(tick int64) bool { - x, y := b.GetCurrentPos(tick) - return (x < 0.0-BULLET_KILL_BUFFER_WIDTH) || (x > STAGE_WIDTH+BULLET_KILL_BUFFER_WIDTH) || (y < 0.0-BULLET_KILL_BUFFER_WIDTH) || (y > STAGE_HEIGHT+BULLET_KILL_BUFFER_WIDTH) -} diff --git a/server/collision.go b/server/collision.go deleted file mode 100644 index 06ab7d0..0000000 --- a/server/collision.go +++ /dev/null @@ -1 +0,0 @@ -package main diff --git a/server/consts.go b/server/consts.go new file mode 100644 index 0000000..ed3ca32 --- /dev/null +++ b/server/consts.go @@ -0,0 +1,11 @@ +package main + +const ( + BULLET_LINEAR = 0 +) + +const ( + STAGE_WIDTH float64 = 90.0 + STAGE_HEIGHT float64 = 160.0 + BULLET_KILL_BUFFER_WIDTH float64 = 16.0 +) diff --git a/server/main.go b/server/main.go index 247327c..739a583 100644 --- a/server/main.go +++ b/server/main.go @@ -1,9 +1,18 @@ package main +/* +#cgo CFLAGS: -I ${SRCDIR}/lib +#cgo LDFLAGS: -L ${SRCDIR}/lib -l shared +#include "shared.h" +#include +*/ +import "C" + import ( "context" "database/sql" "encoding/json" + "fmt" "math/rand" "slices" @@ -23,7 +32,7 @@ type BattleRoyaleMatch struct{} type PlayerStageState struct { xPos float64 yPos float64 - bullets []Bullet + bullets []*C.Bullet } type PresenceState struct { // present time! hahahahahahahah! @@ -49,6 +58,7 @@ func (m *BattleRoyaleMatch) MatchInit(ctx context.Context, logger runtime.Logger currentMatchPhase: MATCH_LOADING, } label := "" + return state, tickRate, label } @@ -79,7 +89,7 @@ func (m *BattleRoyaleMatch) MatchJoin(ctx context.Context, logger runtime.Logger stageState: PlayerStageState{ xPos: STAGE_WIDTH * 0.5, yPos: STAGE_HEIGHT - STAGE_HEIGHT*0.1, - bullets: []Bullet{}, + bullets: []*C.Bullet{}, }, } } @@ -147,15 +157,29 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger if tick%20 == 0 { for _, v := range lobbyState.presences { vel := rand.Float64()*(STAGE_WIDTH/float64(lobbyState.tickRate)) + 1.0 - bullet := Bullet{ - BULLET_LINEAR, - tick, - STAGE_WIDTH * rand.Float64(), - STAGE_HEIGHT * rand.Float64(), - []float64{vel, vel}, + + bullet := C.new_bullet( + C.uint8_t(BULLET_LINEAR), + C.int64_t(tick), + C.double(STAGE_WIDTH*rand.Float64()), + C.double(STAGE_HEIGHT*rand.Float64()), + C.double(vel), + C.double(vel), + ) + + var x, y C.double + C.bullet_get_current_pos(bullet, C.int64_t(tick), &x, &y) + + bulletData := map[string]interface{}{ + "class": BULLET_LINEAR, + "tick": tick, + "x": float64(x), + "y": float64(y), + "vel_x": vel, + "vel_y": vel, } - data, err := json.Marshal(bullet) + data, err := json.Marshal(bulletData) if err != nil { logger.Error("Error marshalling bullet data", err) } else { @@ -168,8 +192,18 @@ func (m *BattleRoyaleMatch) MatchLoop(ctx context.Context, logger runtime.Logger // Bullet cleanup for _, v := range lobbyState.presences { - v.stageState.bullets = slices.DeleteFunc(v.stageState.bullets, func(b Bullet) bool { - return b.BeyondKillBoundary(tick) + for _, bullet := range v.stageState.bullets { + var x, y C.double + C.bullet_get_current_pos(bullet, C.int64_t(tick), &x, &y) + fmt.Printf("Bullet at (%.2f, %.2f)\n", float64(x), float64(y)) + } + + v.stageState.bullets = slices.DeleteFunc(v.stageState.bullets, func(b *C.Bullet) bool { + if C.bullet_beyond_kill_boundary(b, C.int64_t(tick)) { + C.destroy_bullet(b) + return true + } + return false }) } diff --git a/shared/Cargo.lock b/shared/Cargo.lock new file mode 100644 index 0000000..4834d8d --- /dev/null +++ b/shared/Cargo.lock @@ -0,0 +1,478 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys", +] + +[[package]] +name = "bitflags" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36" + +[[package]] +name = "cbindgen" +version = "0.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eadd868a2ce9ca38de7eeafdcec9c7065ef89b42b32f0839278d55f35c54d1ff" +dependencies = [ + "clap", + "heck", + "indexmap", + "log", + "proc-macro2", + "quote", + "serde", + "serde_json", + "syn", + "tempfile", + "toml", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b26884eb4b57140e4d2d93652abfa49498b938b3c9179f9fc487b0acc3edad7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "getrandom" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +dependencies = [ + "cfg-if", + "libc", + "wasi", + "windows-targets", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "indexmap" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "log" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + +[[package]] +name = "serde" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.217" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.138" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_spanned" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1" +dependencies = [ + "serde", +] + +[[package]] +name = "shared" +version = "0.1.0" +dependencies = [ + "cbindgen", + "libc", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "2.0.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "tempfile" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" +dependencies = [ + "cfg-if", + "fastrand", + "getrandom", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02a8b472d1a3d7c18e2d61a489aee3453fd9031c33e4f55bd533f4a7adca1bee" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "unicode-ident" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86e376c75f4f43f44db463cf729e0d3acbf954d13e22c51e26e4c264b4ab545f" +dependencies = [ + "memchr", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags", +] diff --git a/shared/Cargo.toml b/shared/Cargo.toml new file mode 100644 index 0000000..ece0af1 --- /dev/null +++ b/shared/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "shared" +version = "0.1.0" +edition = "2021" +build = "build.rs" + +[lib] +crate-type = ["staticlib"] + +[dependencies] +libc = "0.2.2" + +[build-dependencies] +cbindgen = "0.28.0" + +[features] +"ffi" = [] +"godot" = [] \ No newline at end of file diff --git a/shared/build.rs b/shared/build.rs new file mode 100644 index 0000000..0c80c49 --- /dev/null +++ b/shared/build.rs @@ -0,0 +1,36 @@ +extern crate cbindgen; + +use std::env; +use std::path::PathBuf; +use cbindgen::Config; + + +fn main() { + let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); + + let package_name = env::var("CARGO_PKG_NAME").unwrap(); + let output_file = target_dir() + .join(format!("{}.h", package_name)) + .display() + .to_string(); + + let config = Config { + language: cbindgen::Language::C, + ..Default::default() + }; + + cbindgen::generate_with_config(&crate_dir, config) + .unwrap() + .write_to_file(&output_file); +} + +/// Find the location of the `target/` directory. Note that this may be +/// overridden by `cmake`, so we also need to check the `CARGO_TARGET_DIR` +/// variable. +fn target_dir() -> PathBuf { + if let Ok(target) = env::var("CARGO_TARGET_DIR") { + PathBuf::from(target) + } else { + PathBuf::from(env::var("CARGO_MANIFEST_DIR").unwrap()).join("target") + } +} \ No newline at end of file diff --git a/shared/src/bullet.rs b/shared/src/bullet.rs new file mode 100644 index 0000000..f60baef --- /dev/null +++ b/shared/src/bullet.rs @@ -0,0 +1,46 @@ +#[repr(C)] +#[derive(Debug, Clone, Copy)] +pub struct Bullet { + pub class: u8, + pub spawn_time: i64, + pub spawn_x: f64, + pub spawn_y: f64, + pub parameters: [f64; 2], +} + +impl Bullet { + pub const BULLET_LINEAR: u8 = 0; + + pub fn new(class: u8, spawn_time: i64, spawn_x: f64, spawn_y: f64, parameters: [f64; 2]) -> Self { + Self { + class, + spawn_time, + spawn_x, + spawn_y, + parameters, + } + } + + pub fn get_current_pos(&self, tick: i64) -> (f64, f64) { + let dt = (tick - self.spawn_time) as f64; + match self.class { + Self::BULLET_LINEAR => ( + self.spawn_x + self.parameters[0] * dt, + self.spawn_y + self.parameters[1] * dt, + ), + _ => (self.spawn_x, self.spawn_y), + } + } + + pub fn beyond_kill_boundary(&self, tick: i64) -> bool { + const STAGE_WIDTH: f64 = 90.0; + const STAGE_HEIGHT: f64 = 160.0; + const BULLET_KILL_BUFFER_WIDTH: f64 = 16.0; + + let (x, y) = self.get_current_pos(tick); + x < -BULLET_KILL_BUFFER_WIDTH + || x > STAGE_WIDTH + BULLET_KILL_BUFFER_WIDTH + || y < -BULLET_KILL_BUFFER_WIDTH + || y > STAGE_HEIGHT + BULLET_KILL_BUFFER_WIDTH + } +} \ No newline at end of file diff --git a/shared/src/ffi.rs b/shared/src/ffi.rs new file mode 100644 index 0000000..3286e89 --- /dev/null +++ b/shared/src/ffi.rs @@ -0,0 +1,44 @@ +use crate::bullet::Bullet; + +#[no_mangle] +pub extern "C" fn new_bullet( + class: u8, spawn_time: i64, spawn_x: f64, spawn_y: f64, param_x: f64, param_y: f64 +) -> *mut Bullet { + let bullet = Bullet::new( + class, + spawn_time, + spawn_x, + spawn_y, + [param_x, param_y], + ); + Box::into_raw(Box::new(bullet)) +} + +#[no_mangle] +pub extern "C" fn bullet_get_current_pos(bullet: *const Bullet, tick: i64, x: *mut f64, y: *mut f64) { + if let Some(b) = unsafe { bullet.as_ref() } { + let (bx, by) = b.get_current_pos(tick); + unsafe { + *x = bx; + *y = by; + } + } +} + +#[no_mangle] +pub extern "C" fn bullet_beyond_kill_boundary(bullet: *const Bullet, tick: i64) -> bool { + if let Some(b) = unsafe { bullet.as_ref() } { + b.beyond_kill_boundary(tick) + } else { + false + } +} + +#[no_mangle] +pub extern "C" fn destroy_bullet(bullet: *mut Bullet) { + if !bullet.is_null() { + unsafe { + drop(Box::from_raw(bullet)); + } + } +} \ No newline at end of file diff --git a/shared/src/godot.rs b/shared/src/godot.rs new file mode 100644 index 0000000..e69de29 diff --git a/shared/src/lib.rs b/shared/src/lib.rs new file mode 100644 index 0000000..cd2f7a8 --- /dev/null +++ b/shared/src/lib.rs @@ -0,0 +1,5 @@ +mod bullet; +#[cfg(feature = "ffi")] +mod ffi; +#[cfg(feature = "godot")] +mod godot; \ No newline at end of file