Archived
1
0
Fork 0
This repository has been archived on 2026-01-19. You can view files and clone it, but cannot push or open issues or pull requests.
Danmaku/server/ffi/ffi.go
2025-09-09 16:51:13 -07:00

144 lines
2.8 KiB
Go

package ffi
/*
#cgo CFLAGS: -I ${SRCDIR}/lib
#cgo LDFLAGS: -L ${SRCDIR}/lib -l ffi_wrapper
#include "ffi-wrapper.h"
#include <stdlib.h>
*/
import "C"
import "strconv"
// Circles
type Circle struct {
cptr *C.Circle
}
func NewCircle(x float64, y float64, rad float64) *Circle {
return &Circle{
cptr: C.new_circle(C.double(x), C.double(y), C.double(rad)),
}
}
func (c *Circle) Clone() *Circle {
if c == nil {
return nil
}
x, y := c.GetPos()
return NewCircle(x, y, float64(c.cptr.radius))
}
func (c *Circle) UpdatePos(x float64, y float64) {
c.cptr.x = C.double(x)
c.cptr.y = C.double(y)
}
func DestroyCircle(circle *Circle) {
if circle.cptr == nil {
return
}
C.destroy_circle(circle.cptr)
circle.cptr = nil
}
func (c *Circle) GetPos() (float64, float64) {
return float64(c.cptr.x), float64(c.cptr.y)
}
// Bullets
type Bullet struct {
cptr *C.Bullet
}
// Values for selecting bullet paths
const (
BULLET_LINEAR = 0
)
func NewLinearBullet(tick int64, spawnX float64, spawnY float64, radius float64, velX float64, velY float64) *Bullet {
return &Bullet{
cptr: C.new_bullet(
C.uint8_t(BULLET_LINEAR),
C.int64_t(tick),
C.double(spawnX),
C.double(spawnY),
C.double(radius),
C.double(velX),
C.double(velY),
),
}
}
func (b *Bullet) Clone() *Bullet {
if b == nil {
return nil
}
switch int(b.cptr.class_) {
case BULLET_LINEAR:
nb := NewLinearBullet(
int64(b.cptr.spawn_time),
float64(b.cptr.spawn_x),
float64(b.cptr.spawn_y),
float64(b.cptr.radius),
float64(b.cptr.parameters[0]), // vel_x
float64(b.cptr.parameters[1]), // vel_y
)
return nb
default:
// Mirror other bullet classes here with their exact constructors.
panic("ffi.Bullet.Clone: unsupported bullet class: " + strconv.Itoa(int(b.cptr.class_)))
}
}
func DestroyBullet(bullet *Bullet) {
if bullet.cptr == nil {
return
}
C.destroy_bullet(bullet.cptr)
bullet.cptr = nil
}
func (b *Bullet) BeyondKillBoundary(tick int64) bool {
return bool(C.bullet_beyond_kill_boundary(b.cptr, C.int64_t(tick)))
}
func (b *Bullet) CollidesWith(circle *Circle, tick int64) bool {
return bool(C.bullet_collides_with(b.cptr, C.int64_t(tick), circle.cptr))
}
func (b *Bullet) GetPos(tick int64) (float64, float64) {
var x, y C.double
C.bullet_get_current_pos(b.cptr, C.int64_t(tick), &x, &y)
return float64(x), float64(y)
}
func (b *Bullet) GetType() int {
return int(b.cptr.class_)
}
func (b *Bullet) GetRadius() float64 {
return float64(b.cptr.radius)
}
func (b *Bullet) GetSpawnTick() int64 {
return int64(b.cptr.spawn_time)
}
func (b *Bullet) Serialize( /*tick int64*/ ) map[string]any {
//x, y := b.GetPos(tick)
return map[string]any{
"class": b.GetType(),
"tick": b.GetSpawnTick(),
//"x": x,
//"y": y,
"radius": b.GetRadius(),
"vel_x": float64(b.cptr.parameters[0]),
"vel_y": float64(b.cptr.parameters[1]),
}
}