add networking, 3d improvements, reorganize src structure
This commit is contained in:
parent
39b604b333
commit
415d424057
122 changed files with 5358 additions and 721 deletions
208
src/lua/pxl8.lua
Normal file
208
src/lua/pxl8.lua
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
local anim = require("pxl8.anim")
|
||||
local bytes = require("pxl8.bytes")
|
||||
local core = require("pxl8.core")
|
||||
local gfx2d = require("pxl8.gfx2d")
|
||||
local gfx3d = require("pxl8.gfx3d")
|
||||
local gui = require("pxl8.gui")
|
||||
local input = require("pxl8.input")
|
||||
local math3d = require("pxl8.math")
|
||||
local net = require("pxl8.net")
|
||||
local particles = require("pxl8.particles")
|
||||
local sfx = require("pxl8.sfx")
|
||||
local tilemap = require("pxl8.tilemap")
|
||||
local transition = require("pxl8.transition")
|
||||
local world = require("pxl8.world")
|
||||
local pxl8 = {}
|
||||
|
||||
core.init(pxl8_gfx, pxl8_input, pxl8_rng, pxl8_sfx, pxl8_sys)
|
||||
|
||||
pxl8.get_fps = core.get_fps
|
||||
pxl8.get_height = core.get_height
|
||||
pxl8.get_title = core.get_title
|
||||
pxl8.get_width = core.get_width
|
||||
pxl8.info = core.info
|
||||
pxl8.warn = core.warn
|
||||
pxl8.error = core.error
|
||||
pxl8.debug = core.debug
|
||||
pxl8.trace = core.trace
|
||||
pxl8.quit = core.quit
|
||||
|
||||
pxl8.rng_seed = core.rng_seed
|
||||
pxl8.rng_next = core.rng_next
|
||||
pxl8.rng_f32 = core.rng_f32
|
||||
pxl8.rng_range = core.rng_range
|
||||
|
||||
pxl8.find_color = core.find_color
|
||||
pxl8.palette_color = core.palette_color
|
||||
pxl8.palette_index = core.palette_index
|
||||
pxl8.ramp_index = core.ramp_index
|
||||
pxl8.set_palette_rgb = core.set_palette_rgb
|
||||
|
||||
pxl8.clear = gfx2d.clear
|
||||
pxl8.pixel = gfx2d.pixel
|
||||
pxl8.line = gfx2d.line
|
||||
pxl8.rect = gfx2d.rect
|
||||
pxl8.rect_fill = gfx2d.rect_fill
|
||||
pxl8.circle = gfx2d.circle
|
||||
pxl8.circle_fill = gfx2d.circle_fill
|
||||
pxl8.text = gfx2d.text
|
||||
pxl8.sprite = gfx2d.sprite
|
||||
pxl8.load_palette = gfx2d.load_palette
|
||||
pxl8.load_sprite = gfx2d.load_sprite
|
||||
pxl8.create_texture = gfx2d.create_texture
|
||||
pxl8.gfx_color_ramp = gfx2d.color_ramp
|
||||
pxl8.gfx_fade_palette = gfx2d.fade_palette
|
||||
pxl8.gfx_cycle_palette = gfx2d.cycle_palette
|
||||
pxl8.add_palette_cycle = gfx2d.add_palette_cycle
|
||||
pxl8.remove_palette_cycle = gfx2d.remove_palette_cycle
|
||||
pxl8.set_palette_cycle_speed = gfx2d.set_palette_cycle_speed
|
||||
pxl8.clear_palette_cycles = gfx2d.clear_palette_cycles
|
||||
|
||||
pxl8.key_down = input.key_down
|
||||
pxl8.key_pressed = input.key_pressed
|
||||
pxl8.key_released = input.key_released
|
||||
pxl8.mouse_dx = input.mouse_dx
|
||||
pxl8.mouse_dy = input.mouse_dy
|
||||
pxl8.mouse_wheel_x = input.mouse_wheel_x
|
||||
pxl8.mouse_wheel_y = input.mouse_wheel_y
|
||||
pxl8.mouse_x = input.mouse_x
|
||||
pxl8.mouse_y = input.mouse_y
|
||||
pxl8.get_mouse_pos = input.get_mouse_pos
|
||||
pxl8.mouse_pressed = input.mouse_pressed
|
||||
pxl8.mouse_released = input.mouse_released
|
||||
pxl8.center_cursor = input.center_cursor
|
||||
pxl8.set_cursor = input.set_cursor
|
||||
pxl8.set_relative_mouse_mode = input.set_relative_mouse_mode
|
||||
|
||||
pxl8.Anim = anim.Anim
|
||||
pxl8.create_anim = anim.Anim.new
|
||||
pxl8.create_anim_from_ase = anim.Anim.from_ase
|
||||
|
||||
pxl8.bounds = math3d.bounds
|
||||
|
||||
pxl8.Camera3D = gfx3d.Camera3D
|
||||
pxl8.create_camera_3d = gfx3d.Camera3D.new
|
||||
pxl8.begin_frame_3d = gfx3d.begin_frame
|
||||
pxl8.clear_3d = gfx3d.clear
|
||||
pxl8.clear_depth = gfx3d.clear_depth
|
||||
pxl8.draw_line_3d = gfx3d.draw_line
|
||||
pxl8.draw_mesh = gfx3d.draw_mesh
|
||||
pxl8.end_frame_3d = gfx3d.end_frame
|
||||
pxl8.Mesh = gfx3d.Mesh
|
||||
pxl8.create_mesh = gfx3d.Mesh.new
|
||||
|
||||
pxl8.Compressor = sfx.Compressor
|
||||
pxl8.create_compressor = sfx.Compressor.new
|
||||
pxl8.Delay = sfx.Delay
|
||||
pxl8.create_delay = sfx.Delay.new
|
||||
pxl8.Reverb = sfx.Reverb
|
||||
pxl8.create_reverb = sfx.Reverb.new
|
||||
|
||||
pxl8.Gui = gui.Gui
|
||||
pxl8.create_gui = gui.Gui.new
|
||||
pxl8.gui_label = gui.label
|
||||
pxl8.gui_window = gui.window
|
||||
|
||||
pxl8.mat4_identity = math3d.mat4_identity
|
||||
pxl8.mat4_lookat = math3d.mat4_lookat
|
||||
pxl8.mat4_multiply = math3d.mat4_multiply
|
||||
pxl8.mat4_ortho = math3d.mat4_ortho
|
||||
pxl8.mat4_perspective = math3d.mat4_perspective
|
||||
pxl8.mat4_rotate_x = math3d.mat4_rotate_x
|
||||
pxl8.mat4_rotate_y = math3d.mat4_rotate_y
|
||||
pxl8.mat4_rotate_z = math3d.mat4_rotate_z
|
||||
pxl8.mat4_scale = math3d.mat4_scale
|
||||
pxl8.mat4_translate = math3d.mat4_translate
|
||||
|
||||
pxl8.Net = net.Net
|
||||
pxl8.create_net = net.Net.new
|
||||
pxl8.NET_MODE_LOCAL = net.MODE_LOCAL
|
||||
pxl8.NET_MODE_REMOTE = net.MODE_REMOTE
|
||||
|
||||
pxl8.pack_f32_be = bytes.pack_f32_be
|
||||
pxl8.pack_f32_le = bytes.pack_f32_le
|
||||
pxl8.pack_f64_be = bytes.pack_f64_be
|
||||
pxl8.pack_f64_le = bytes.pack_f64_le
|
||||
pxl8.pack_i8 = bytes.pack_i8
|
||||
pxl8.pack_i16_be = bytes.pack_i16_be
|
||||
pxl8.pack_i16_le = bytes.pack_i16_le
|
||||
pxl8.pack_i32_be = bytes.pack_i32_be
|
||||
pxl8.pack_i32_le = bytes.pack_i32_le
|
||||
pxl8.pack_i64_be = bytes.pack_i64_be
|
||||
pxl8.pack_i64_le = bytes.pack_i64_le
|
||||
pxl8.pack_u8 = bytes.pack_u8
|
||||
pxl8.pack_u16_be = bytes.pack_u16_be
|
||||
pxl8.pack_u16_le = bytes.pack_u16_le
|
||||
pxl8.pack_u32_be = bytes.pack_u32_be
|
||||
pxl8.pack_u32_le = bytes.pack_u32_le
|
||||
pxl8.pack_u64_be = bytes.pack_u64_be
|
||||
pxl8.pack_u64_le = bytes.pack_u64_le
|
||||
|
||||
pxl8.Particles = particles.Particles
|
||||
pxl8.create_particles = particles.Particles.new
|
||||
|
||||
pxl8.PROCGEN_ROOMS = world.PROCGEN_ROOMS
|
||||
pxl8.PROCGEN_TERRAIN = world.PROCGEN_TERRAIN
|
||||
pxl8.procgen_tex = world.procgen_tex
|
||||
|
||||
pxl8.SfxContext = sfx.SfxContext
|
||||
pxl8.SfxNode = sfx.SfxNode
|
||||
pxl8.create_sfx_context = sfx.SfxContext.new
|
||||
pxl8.sfx_get_master_volume = sfx.get_master_volume
|
||||
pxl8.sfx_note_to_freq = sfx.note_to_freq
|
||||
pxl8.sfx_set_master_volume = sfx.set_master_volume
|
||||
pxl8.sfx_voice_params = sfx.voice_params
|
||||
|
||||
pxl8.SFX_FILTER_BANDPASS = sfx.FILTER_BANDPASS
|
||||
pxl8.SFX_FILTER_HIGHPASS = sfx.FILTER_HIGHPASS
|
||||
pxl8.SFX_FILTER_LOWPASS = sfx.FILTER_LOWPASS
|
||||
pxl8.SFX_FILTER_NONE = sfx.FILTER_NONE
|
||||
pxl8.SFX_LFO_AMPLITUDE = sfx.LFO_AMPLITUDE
|
||||
pxl8.SFX_LFO_FILTER = sfx.LFO_FILTER
|
||||
pxl8.SFX_LFO_PITCH = sfx.LFO_PITCH
|
||||
pxl8.SFX_NODE_COMPRESSOR = sfx.NODE_COMPRESSOR
|
||||
pxl8.SFX_NODE_DELAY = sfx.NODE_DELAY
|
||||
pxl8.SFX_NODE_REVERB = sfx.NODE_REVERB
|
||||
pxl8.SFX_WAVE_NOISE = sfx.WAVE_NOISE
|
||||
pxl8.SFX_WAVE_PULSE = sfx.WAVE_PULSE
|
||||
pxl8.SFX_WAVE_SAW = sfx.WAVE_SAW
|
||||
pxl8.SFX_WAVE_SINE = sfx.WAVE_SINE
|
||||
pxl8.SFX_WAVE_SQUARE = sfx.WAVE_SQUARE
|
||||
pxl8.SFX_WAVE_TRIANGLE = sfx.WAVE_TRIANGLE
|
||||
|
||||
pxl8.TILE_FLIP_X = tilemap.TILE_FLIP_X
|
||||
pxl8.TILE_FLIP_Y = tilemap.TILE_FLIP_Y
|
||||
pxl8.TILE_SOLID = tilemap.TILE_SOLID
|
||||
pxl8.TILE_TRIGGER = tilemap.TILE_TRIGGER
|
||||
pxl8.Tilemap = tilemap.Tilemap
|
||||
pxl8.create_tilemap = tilemap.Tilemap.new
|
||||
pxl8.Tilesheet = tilemap.Tilesheet
|
||||
pxl8.create_tilesheet = tilemap.Tilesheet.new
|
||||
|
||||
pxl8.Transition = transition.Transition
|
||||
pxl8.create_transition = transition.Transition.new
|
||||
pxl8.TRANSITION_TYPES = transition.TYPES
|
||||
|
||||
pxl8.unpack_f32_be = bytes.unpack_f32_be
|
||||
pxl8.unpack_f32_le = bytes.unpack_f32_le
|
||||
pxl8.unpack_f64_be = bytes.unpack_f64_be
|
||||
pxl8.unpack_f64_le = bytes.unpack_f64_le
|
||||
pxl8.unpack_i8 = bytes.unpack_i8
|
||||
pxl8.unpack_i16_be = bytes.unpack_i16_be
|
||||
pxl8.unpack_i16_le = bytes.unpack_i16_le
|
||||
pxl8.unpack_i32_be = bytes.unpack_i32_be
|
||||
pxl8.unpack_i32_le = bytes.unpack_i32_le
|
||||
pxl8.unpack_i64_be = bytes.unpack_i64_be
|
||||
pxl8.unpack_i64_le = bytes.unpack_i64_le
|
||||
pxl8.unpack_u8 = bytes.unpack_u8
|
||||
pxl8.unpack_u16_be = bytes.unpack_u16_be
|
||||
pxl8.unpack_u16_le = bytes.unpack_u16_le
|
||||
pxl8.unpack_u32_be = bytes.unpack_u32_be
|
||||
pxl8.unpack_u32_le = bytes.unpack_u32_le
|
||||
pxl8.unpack_u64_be = bytes.unpack_u64_be
|
||||
pxl8.unpack_u64_le = bytes.unpack_u64_le
|
||||
|
||||
pxl8.World = world.World
|
||||
pxl8.create_world = world.World.new
|
||||
|
||||
return pxl8
|
||||
126
src/lua/pxl8/anim.lua
Normal file
126
src/lua/pxl8/anim.lua
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local anim = {}
|
||||
|
||||
local Anim = {}
|
||||
Anim.__index = Anim
|
||||
|
||||
function Anim.new(frame_ids, frame_durations)
|
||||
local frame_count = #frame_ids
|
||||
local c_frame_ids = ffi.new("u32[?]", frame_count)
|
||||
local c_frame_durations = nil
|
||||
|
||||
for i = 1, frame_count do
|
||||
c_frame_ids[i-1] = frame_ids[i]
|
||||
end
|
||||
|
||||
if frame_durations then
|
||||
c_frame_durations = ffi.new("u16[?]", frame_count)
|
||||
for i = 1, frame_count do
|
||||
c_frame_durations[i-1] = frame_durations[i]
|
||||
end
|
||||
end
|
||||
|
||||
local a = C.pxl8_anim_create(c_frame_ids, c_frame_durations, frame_count)
|
||||
if a == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = a }, Anim)
|
||||
end
|
||||
|
||||
function Anim.from_ase(filepath)
|
||||
local a = C.pxl8_anim_create_from_ase(core.gfx, filepath)
|
||||
if a == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = a }, Anim)
|
||||
end
|
||||
|
||||
function Anim:add_state(name, state_anim)
|
||||
return C.pxl8_anim_add_state(self._ptr, name, state_anim._ptr)
|
||||
end
|
||||
|
||||
function Anim:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_anim_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Anim:get_current_frame()
|
||||
return C.pxl8_anim_get_current_frame(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:get_current_frame_id()
|
||||
return C.pxl8_anim_get_current_frame_id(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:get_state()
|
||||
local state_name = C.pxl8_anim_get_state(self._ptr)
|
||||
if state_name ~= nil then
|
||||
return ffi.string(state_name)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function Anim:has_state_machine()
|
||||
return C.pxl8_anim_has_state_machine(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:is_complete()
|
||||
return C.pxl8_anim_is_complete(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:is_playing()
|
||||
return C.pxl8_anim_is_playing(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:pause()
|
||||
C.pxl8_anim_pause(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:play()
|
||||
C.pxl8_anim_play(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:render(x, y, w, h, flip_x, flip_y)
|
||||
C.pxl8_anim_render_sprite(self._ptr, core.gfx, x, y, w, h, flip_x or false, flip_y or false)
|
||||
end
|
||||
|
||||
function Anim:reset()
|
||||
C.pxl8_anim_reset(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:set_frame(frame)
|
||||
C.pxl8_anim_set_frame(self._ptr, frame)
|
||||
end
|
||||
|
||||
function Anim:set_loop(loop)
|
||||
C.pxl8_anim_set_loop(self._ptr, loop)
|
||||
end
|
||||
|
||||
function Anim:set_reverse(reverse)
|
||||
C.pxl8_anim_set_reverse(self._ptr, reverse)
|
||||
end
|
||||
|
||||
function Anim:set_speed(speed)
|
||||
C.pxl8_anim_set_speed(self._ptr, speed)
|
||||
end
|
||||
|
||||
function Anim:set_state(name)
|
||||
return C.pxl8_anim_set_state(self._ptr, name)
|
||||
end
|
||||
|
||||
function Anim:stop()
|
||||
C.pxl8_anim_stop(self._ptr)
|
||||
end
|
||||
|
||||
function Anim:update(dt)
|
||||
C.pxl8_anim_update(self._ptr, dt)
|
||||
end
|
||||
|
||||
anim.Anim = Anim
|
||||
|
||||
return anim
|
||||
44
src/lua/pxl8/bytes.lua
Normal file
44
src/lua/pxl8/bytes.lua
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
|
||||
local bytes = {}
|
||||
|
||||
bytes.pack_f32_be = C.pxl8_pack_f32_be
|
||||
bytes.pack_f32_le = C.pxl8_pack_f32_le
|
||||
bytes.pack_f64_be = C.pxl8_pack_f64_be
|
||||
bytes.pack_f64_le = C.pxl8_pack_f64_le
|
||||
bytes.pack_i8 = C.pxl8_pack_i8
|
||||
bytes.pack_i16_be = C.pxl8_pack_i16_be
|
||||
bytes.pack_i16_le = C.pxl8_pack_i16_le
|
||||
bytes.pack_i32_be = C.pxl8_pack_i32_be
|
||||
bytes.pack_i32_le = C.pxl8_pack_i32_le
|
||||
bytes.pack_i64_be = C.pxl8_pack_i64_be
|
||||
bytes.pack_i64_le = C.pxl8_pack_i64_le
|
||||
bytes.pack_u8 = C.pxl8_pack_u8
|
||||
bytes.pack_u16_be = C.pxl8_pack_u16_be
|
||||
bytes.pack_u16_le = C.pxl8_pack_u16_le
|
||||
bytes.pack_u32_be = C.pxl8_pack_u32_be
|
||||
bytes.pack_u32_le = C.pxl8_pack_u32_le
|
||||
bytes.pack_u64_be = C.pxl8_pack_u64_be
|
||||
bytes.pack_u64_le = C.pxl8_pack_u64_le
|
||||
|
||||
bytes.unpack_f32_be = C.pxl8_unpack_f32_be
|
||||
bytes.unpack_f32_le = C.pxl8_unpack_f32_le
|
||||
bytes.unpack_f64_be = C.pxl8_unpack_f64_be
|
||||
bytes.unpack_f64_le = C.pxl8_unpack_f64_le
|
||||
bytes.unpack_i8 = C.pxl8_unpack_i8
|
||||
bytes.unpack_i16_be = C.pxl8_unpack_i16_be
|
||||
bytes.unpack_i16_le = C.pxl8_unpack_i16_le
|
||||
bytes.unpack_i32_be = C.pxl8_unpack_i32_be
|
||||
bytes.unpack_i32_le = C.pxl8_unpack_i32_le
|
||||
bytes.unpack_i64_be = C.pxl8_unpack_i64_be
|
||||
bytes.unpack_i64_le = C.pxl8_unpack_i64_le
|
||||
bytes.unpack_u8 = C.pxl8_unpack_u8
|
||||
bytes.unpack_u16_be = C.pxl8_unpack_u16_be
|
||||
bytes.unpack_u16_le = C.pxl8_unpack_u16_le
|
||||
bytes.unpack_u32_be = C.pxl8_unpack_u32_be
|
||||
bytes.unpack_u32_le = C.pxl8_unpack_u32_le
|
||||
bytes.unpack_u64_be = C.pxl8_unpack_u64_be
|
||||
bytes.unpack_u64_le = C.pxl8_unpack_u64_le
|
||||
|
||||
return bytes
|
||||
122
src/lua/pxl8/core.lua
Normal file
122
src/lua/pxl8/core.lua
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
|
||||
local core = {}
|
||||
|
||||
function core.init(gfx, input, rng, sfx, sys)
|
||||
core.gfx = gfx
|
||||
core.input = input
|
||||
core.rng = rng
|
||||
core.sfx = sfx
|
||||
core.sys = sys
|
||||
end
|
||||
|
||||
function core.find_color(color)
|
||||
return C.pxl8_gfx_find_color(core.gfx, color)
|
||||
end
|
||||
|
||||
function core.get_fps()
|
||||
return C.pxl8_get_fps(core.sys)
|
||||
end
|
||||
|
||||
function core.palette_color(index)
|
||||
local pal = C.pxl8_gfx_get_palette(core.gfx)
|
||||
if pal == nil then return 0 end
|
||||
return C.pxl8_palette_color(pal, index)
|
||||
end
|
||||
|
||||
function core.palette_index(color)
|
||||
local pal = C.pxl8_gfx_get_palette(core.gfx)
|
||||
if pal == nil then return -1 end
|
||||
return C.pxl8_palette_index(pal, color)
|
||||
end
|
||||
|
||||
function core.set_palette_rgb(index, r, g, b)
|
||||
local pal = C.pxl8_gfx_get_palette(core.gfx)
|
||||
if pal == nil then return end
|
||||
C.pxl8_palette_set_rgb(pal, index, r, g, b)
|
||||
C.pxl8_gfx_blend_tables_update(core.gfx)
|
||||
C.pxl8_gfx_colormap_update(core.gfx)
|
||||
end
|
||||
|
||||
function core.ramp_index(position)
|
||||
local pal = C.pxl8_gfx_get_palette(core.gfx)
|
||||
if pal == nil then return 0 end
|
||||
return C.pxl8_palette_ramp_index(pal, position)
|
||||
end
|
||||
|
||||
function core.get_width()
|
||||
return C.pxl8_gfx_get_width(core.gfx)
|
||||
end
|
||||
|
||||
function core.get_height()
|
||||
return C.pxl8_gfx_get_height(core.gfx)
|
||||
end
|
||||
|
||||
function core.get_title()
|
||||
local cart = C.pxl8_get_cart()
|
||||
if cart ~= nil then
|
||||
local title = C.pxl8_cart_get_title(cart)
|
||||
if title ~= nil then
|
||||
return ffi.string(title)
|
||||
end
|
||||
end
|
||||
return "pxl8"
|
||||
end
|
||||
|
||||
local function is_user_script(info)
|
||||
local src = info and info.short_src
|
||||
return src and (src:match("%.fnl$") or src:match("%.lua$"))
|
||||
end
|
||||
|
||||
local function get_caller_info()
|
||||
for level = 2, 10 do
|
||||
local info = debug.getinfo(level, "Sl")
|
||||
if not info then break end
|
||||
if is_user_script(info) then
|
||||
return info.short_src, info.currentline or 0
|
||||
end
|
||||
end
|
||||
return "?", 0
|
||||
end
|
||||
|
||||
core.LOG_TRACE = 0
|
||||
core.LOG_DEBUG = 1
|
||||
core.LOG_INFO = 2
|
||||
core.LOG_WARN = 3
|
||||
core.LOG_ERROR = 4
|
||||
|
||||
local function make_logger(level)
|
||||
return function(msg)
|
||||
local src, line = get_caller_info()
|
||||
C.pxl8_lua_log(level, src, line, msg)
|
||||
end
|
||||
end
|
||||
|
||||
core.trace = make_logger(core.LOG_TRACE)
|
||||
core.debug = make_logger(core.LOG_DEBUG)
|
||||
core.info = make_logger(core.LOG_INFO)
|
||||
core.warn = make_logger(core.LOG_WARN)
|
||||
core.error = make_logger(core.LOG_ERROR)
|
||||
|
||||
function core.quit()
|
||||
C.pxl8_set_running(core.sys, false)
|
||||
end
|
||||
|
||||
function core.rng_seed(seed)
|
||||
C.pxl8_rng_seed(core.rng, seed)
|
||||
end
|
||||
|
||||
function core.rng_next()
|
||||
return C.pxl8_rng_next(core.rng)
|
||||
end
|
||||
|
||||
function core.rng_f32()
|
||||
return C.pxl8_rng_f32(core.rng)
|
||||
end
|
||||
|
||||
function core.rng_range(min, max)
|
||||
return C.pxl8_rng_range(core.rng, min, max)
|
||||
end
|
||||
|
||||
return core
|
||||
32
src/lua/pxl8/effects.lua
Normal file
32
src/lua/pxl8/effects.lua
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local effects = {}
|
||||
|
||||
effects.GLOW_CIRCLE = 0
|
||||
effects.GLOW_DIAMOND = 1
|
||||
effects.GLOW_SHAFT = 2
|
||||
|
||||
function effects.glows(glows)
|
||||
if not glows or #glows == 0 then return end
|
||||
|
||||
local count = #glows
|
||||
local glow_array = ffi.new("pxl8_glow_source[?]", count)
|
||||
|
||||
for i, g in ipairs(glows) do
|
||||
local idx = i - 1
|
||||
glow_array[idx].x = g.x or 0
|
||||
glow_array[idx].y = g.y or 0
|
||||
glow_array[idx].radius = g.radius or 8
|
||||
glow_array[idx].intensity = g.intensity or 255
|
||||
glow_array[idx].color = g.color or 15
|
||||
glow_array[idx].depth = g.depth or 0xFFFF
|
||||
glow_array[idx].height = g.height or 0
|
||||
glow_array[idx].shape = g.shape or 0
|
||||
end
|
||||
|
||||
C.pxl8_gfx_apply_effect(core.gfx, C.PXL8_GFX_EFFECT_GLOWS, glow_array, count)
|
||||
end
|
||||
|
||||
return effects
|
||||
109
src/lua/pxl8/gfx2d.lua
Normal file
109
src/lua/pxl8/gfx2d.lua
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local graphics = {}
|
||||
|
||||
function graphics.clear(color)
|
||||
C.pxl8_2d_clear(core.gfx, color or 0)
|
||||
end
|
||||
|
||||
function graphics.pixel(x, y, color)
|
||||
if color then
|
||||
C.pxl8_2d_pixel(core.gfx, x, y, color)
|
||||
else
|
||||
return C.pxl8_2d_get_pixel(core.gfx, x, y)
|
||||
end
|
||||
end
|
||||
|
||||
function graphics.line(x0, y0, x1, y1, color)
|
||||
C.pxl8_2d_line(core.gfx, x0, y0, x1, y1, color)
|
||||
end
|
||||
|
||||
function graphics.rect(x, y, w, h, color)
|
||||
C.pxl8_2d_rect(core.gfx, x, y, w, h, color)
|
||||
end
|
||||
|
||||
function graphics.rect_fill(x, y, w, h, color)
|
||||
C.pxl8_2d_rect_fill(core.gfx, x, y, w, h, color)
|
||||
end
|
||||
|
||||
function graphics.circle(x, y, r, color)
|
||||
C.pxl8_2d_circle(core.gfx, x, y, r, color)
|
||||
end
|
||||
|
||||
function graphics.circle_fill(x, y, r, color)
|
||||
C.pxl8_2d_circle_fill(core.gfx, x, y, r, color)
|
||||
end
|
||||
|
||||
function graphics.text(str, x, y, color)
|
||||
C.pxl8_2d_text(core.gfx, str, x or 0, y or 0, color or 15)
|
||||
end
|
||||
|
||||
function graphics.sprite(id, x, y, w, h, flip_x, flip_y)
|
||||
C.pxl8_2d_sprite(core.gfx, id or 0, x or 0, y or 0, w or 16, h or 16, flip_x or false, flip_y or false)
|
||||
end
|
||||
|
||||
function graphics.load_palette(filepath)
|
||||
return C.pxl8_gfx_load_palette(core.gfx, filepath)
|
||||
end
|
||||
|
||||
function graphics.load_sprite(filepath)
|
||||
local sprite_id = ffi.new("unsigned int[1]")
|
||||
local result = C.pxl8_gfx_load_sprite(core.gfx, filepath, sprite_id)
|
||||
if result == 0 then
|
||||
return sprite_id[0]
|
||||
else
|
||||
return nil, result
|
||||
end
|
||||
end
|
||||
|
||||
function graphics.create_texture(pixels, width, height)
|
||||
local pixel_data = ffi.new("u8[?]", width * height)
|
||||
for i = 0, width * height - 1 do
|
||||
pixel_data[i] = pixels[i + 1] or 0
|
||||
end
|
||||
local result = C.pxl8_gfx_create_texture(core.gfx, pixel_data, width, height)
|
||||
if result < 0 then
|
||||
return nil
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function graphics.color_ramp(start, count, from_color, to_color)
|
||||
C.pxl8_gfx_color_ramp(core.gfx, start, count, from_color, to_color)
|
||||
end
|
||||
|
||||
function graphics.fade_palette(start, count, amount, target_color)
|
||||
C.pxl8_gfx_fade_palette(core.gfx, start, count, amount, target_color)
|
||||
end
|
||||
|
||||
function graphics.cycle_palette(start, count, step)
|
||||
C.pxl8_gfx_cycle_palette(core.gfx, start, count, step or 1)
|
||||
end
|
||||
|
||||
function graphics.add_palette_cycle(start_index, end_index, speed)
|
||||
return C.pxl8_gfx_add_palette_cycle(core.gfx, start_index, end_index, speed or 1.0)
|
||||
end
|
||||
|
||||
function graphics.remove_palette_cycle(cycle_id)
|
||||
C.pxl8_gfx_remove_palette_cycle(core.gfx, cycle_id)
|
||||
end
|
||||
|
||||
function graphics.set_palette_cycle_speed(cycle_id, speed)
|
||||
C.pxl8_gfx_set_palette_cycle_speed(core.gfx, cycle_id, speed)
|
||||
end
|
||||
|
||||
function graphics.clear_palette_cycles()
|
||||
C.pxl8_gfx_clear_palette_cycles(core.gfx)
|
||||
end
|
||||
|
||||
function graphics.push_target()
|
||||
return C.pxl8_gfx_push_target(core.gfx)
|
||||
end
|
||||
|
||||
function graphics.pop_target()
|
||||
C.pxl8_gfx_pop_target(core.gfx)
|
||||
end
|
||||
|
||||
return graphics
|
||||
208
src/lua/pxl8/gfx3d.lua
Normal file
208
src/lua/pxl8/gfx3d.lua
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local gfx3d = {}
|
||||
|
||||
local Camera3D = {}
|
||||
Camera3D.__index = Camera3D
|
||||
|
||||
function Camera3D.new()
|
||||
local cam = C.pxl8_3d_camera_create()
|
||||
if cam == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = cam }, Camera3D)
|
||||
end
|
||||
|
||||
function Camera3D:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_3d_camera_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Camera3D:get_forward()
|
||||
local v = C.pxl8_3d_camera_get_forward(self._ptr)
|
||||
return {v.x, v.y, v.z}
|
||||
end
|
||||
|
||||
function Camera3D:get_position()
|
||||
local v = C.pxl8_3d_camera_get_position(self._ptr)
|
||||
return {v.x, v.y, v.z}
|
||||
end
|
||||
|
||||
function Camera3D:get_right()
|
||||
local v = C.pxl8_3d_camera_get_right(self._ptr)
|
||||
return {v.x, v.y, v.z}
|
||||
end
|
||||
|
||||
function Camera3D:get_up()
|
||||
local v = C.pxl8_3d_camera_get_up(self._ptr)
|
||||
return {v.x, v.y, v.z}
|
||||
end
|
||||
|
||||
function Camera3D:get_view()
|
||||
return C.pxl8_3d_camera_get_view(self._ptr)
|
||||
end
|
||||
|
||||
function Camera3D:get_projection()
|
||||
return C.pxl8_3d_camera_get_projection(self._ptr)
|
||||
end
|
||||
|
||||
function Camera3D:lookat(eye, target, up)
|
||||
up = up or {0, 1, 0}
|
||||
local eye_vec = ffi.new("pxl8_vec3", {x = eye[1], y = eye[2], z = eye[3]})
|
||||
local target_vec = ffi.new("pxl8_vec3", {x = target[1], y = target[2], z = target[3]})
|
||||
local up_vec = ffi.new("pxl8_vec3", {x = up[1], y = up[2], z = up[3]})
|
||||
C.pxl8_3d_camera_lookat(self._ptr, eye_vec, target_vec, up_vec)
|
||||
end
|
||||
|
||||
function Camera3D:set_perspective(fov, aspect, near, far)
|
||||
C.pxl8_3d_camera_set_perspective(self._ptr, fov, aspect, near, far)
|
||||
end
|
||||
|
||||
function Camera3D:set_position(x, y, z)
|
||||
local pos = ffi.new("pxl8_vec3", {x = x, y = y, z = z})
|
||||
C.pxl8_3d_camera_set_position(self._ptr, pos)
|
||||
end
|
||||
|
||||
function Camera3D:set_rotation(pitch, yaw, roll)
|
||||
C.pxl8_3d_camera_set_rotation(self._ptr, pitch, yaw or 0, roll or 0)
|
||||
end
|
||||
|
||||
function Camera3D:update(dt)
|
||||
C.pxl8_3d_camera_update(self._ptr, dt)
|
||||
end
|
||||
|
||||
gfx3d.Camera3D = Camera3D
|
||||
|
||||
local Mesh = {}
|
||||
Mesh.__index = Mesh
|
||||
|
||||
function Mesh.new(vertices, indices)
|
||||
local vertex_count = #vertices
|
||||
local index_count = #indices
|
||||
local mesh = C.pxl8_mesh_create(vertex_count, index_count)
|
||||
if mesh == nil then
|
||||
return nil
|
||||
end
|
||||
local self = setmetatable({ _ptr = mesh }, Mesh)
|
||||
for _, v in ipairs(vertices) do
|
||||
local vert = ffi.new("pxl8_vertex", {
|
||||
position = {x = v.x or 0, y = v.y or 0, z = v.z or 0},
|
||||
normal = {x = v.nx or 0, y = v.ny or 0, z = v.nz or 0},
|
||||
u = v.u or 0,
|
||||
v = v.v or 0,
|
||||
color = v.color or 0,
|
||||
light = v.light or 255,
|
||||
})
|
||||
C.pxl8_mesh_push_vertex(mesh, vert)
|
||||
end
|
||||
for i = 1, #indices, 3 do
|
||||
C.pxl8_mesh_push_triangle(mesh, indices[i], indices[i+1], indices[i+2])
|
||||
end
|
||||
return self
|
||||
end
|
||||
|
||||
function Mesh:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_mesh_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Mesh:clear()
|
||||
if self._ptr then
|
||||
C.pxl8_mesh_clear(self._ptr)
|
||||
end
|
||||
end
|
||||
|
||||
gfx3d.Mesh = Mesh
|
||||
|
||||
function gfx3d.draw_mesh(mesh, opts)
|
||||
opts = opts or {}
|
||||
local model = ffi.new("pxl8_mat4")
|
||||
model.m[0] = 1
|
||||
model.m[5] = 1
|
||||
model.m[10] = 1
|
||||
model.m[15] = 1
|
||||
if opts.x then model.m[12] = opts.x end
|
||||
if opts.y then model.m[13] = opts.y end
|
||||
if opts.z then model.m[14] = opts.z end
|
||||
local material = ffi.new("pxl8_material", {
|
||||
texture_id = opts.texture or 0,
|
||||
alpha = opts.alpha or 255,
|
||||
blend_mode = opts.blend_mode or 0,
|
||||
dither = opts.dither ~= false,
|
||||
double_sided = opts.double_sided or false,
|
||||
dynamic_lighting = opts.lighting or false,
|
||||
per_pixel = opts.per_pixel or false,
|
||||
vertex_color_passthrough = opts.passthrough or false,
|
||||
emissive_intensity = opts.emissive or 0.0,
|
||||
})
|
||||
C.pxl8_3d_draw_mesh(core.gfx, mesh._ptr, model, material)
|
||||
end
|
||||
|
||||
function gfx3d.begin_frame(camera, uniforms)
|
||||
uniforms = uniforms or {}
|
||||
local u = ffi.new("pxl8_3d_uniforms")
|
||||
|
||||
u.ambient = uniforms.ambient or 0
|
||||
u.fog_color = uniforms.fog_color or 0
|
||||
u.fog_density = uniforms.fog_density or 0.0
|
||||
u.time = uniforms.time or 0.0
|
||||
|
||||
if uniforms.celestial_dir then
|
||||
u.celestial_dir.x = uniforms.celestial_dir[1] or 0
|
||||
u.celestial_dir.y = uniforms.celestial_dir[2] or -1
|
||||
u.celestial_dir.z = uniforms.celestial_dir[3] or 0
|
||||
else
|
||||
u.celestial_dir.x = 0
|
||||
u.celestial_dir.y = -1
|
||||
u.celestial_dir.z = 0
|
||||
end
|
||||
u.celestial_intensity = uniforms.celestial_intensity or 0.0
|
||||
|
||||
u.num_lights = 0
|
||||
if uniforms.lights then
|
||||
for i, light in ipairs(uniforms.lights) do
|
||||
if i > 16 then break end
|
||||
local idx = i - 1
|
||||
u.lights[idx].position.x = light.x or 0
|
||||
u.lights[idx].position.y = light.y or 0
|
||||
u.lights[idx].position.z = light.z or 0
|
||||
u.lights[idx].r = light.r or 255
|
||||
u.lights[idx].g = light.g or 255
|
||||
u.lights[idx].b = light.b or 255
|
||||
u.lights[idx].intensity = light.intensity or 255
|
||||
u.lights[idx].radius = light.radius or 100
|
||||
local radius_sq = u.lights[idx].radius * u.lights[idx].radius
|
||||
u.lights[idx].radius_sq = radius_sq
|
||||
u.lights[idx].inv_radius_sq = radius_sq > 0 and (1.0 / radius_sq) or 0
|
||||
u.num_lights = i
|
||||
end
|
||||
end
|
||||
|
||||
C.pxl8_3d_begin_frame(core.gfx, camera._ptr, u)
|
||||
end
|
||||
|
||||
function gfx3d.clear(color)
|
||||
C.pxl8_3d_clear(core.gfx, color or 0)
|
||||
end
|
||||
|
||||
function gfx3d.clear_depth()
|
||||
C.pxl8_3d_clear_depth(core.gfx)
|
||||
end
|
||||
|
||||
function gfx3d.draw_line(p0, p1, color)
|
||||
local vec0 = ffi.new("pxl8_vec3", {x = p0[1], y = p0[2], z = p0[3]})
|
||||
local vec1 = ffi.new("pxl8_vec3", {x = p1[1], y = p1[2], z = p1[3]})
|
||||
C.pxl8_3d_draw_line(core.gfx, vec0, vec1, color)
|
||||
end
|
||||
|
||||
function gfx3d.end_frame()
|
||||
C.pxl8_3d_end_frame(core.gfx)
|
||||
end
|
||||
|
||||
return gfx3d
|
||||
70
src/lua/pxl8/gui.lua
Normal file
70
src/lua/pxl8/gui.lua
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local gui = {}
|
||||
|
||||
local Gui = {}
|
||||
Gui.__index = Gui
|
||||
|
||||
function Gui.new()
|
||||
local s = C.pxl8_gui_state_create()
|
||||
if s == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = s }, Gui)
|
||||
end
|
||||
|
||||
function Gui:begin_frame()
|
||||
C.pxl8_gui_begin_frame(self._ptr)
|
||||
end
|
||||
|
||||
function Gui:button(id, x, y, w, h, label)
|
||||
return C.pxl8_gui_button(self._ptr, core.gfx, id, x, y, w, h, label)
|
||||
end
|
||||
|
||||
function Gui:cursor_down()
|
||||
C.pxl8_gui_cursor_down(self._ptr)
|
||||
end
|
||||
|
||||
function Gui:cursor_move(x, y)
|
||||
C.pxl8_gui_cursor_move(self._ptr, x, y)
|
||||
end
|
||||
|
||||
function Gui:cursor_up()
|
||||
C.pxl8_gui_cursor_up(self._ptr)
|
||||
end
|
||||
|
||||
function Gui:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_gui_state_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Gui:end_frame()
|
||||
C.pxl8_gui_end_frame(self._ptr)
|
||||
end
|
||||
|
||||
function Gui:get_cursor_pos()
|
||||
local x = ffi.new("i32[1]")
|
||||
local y = ffi.new("i32[1]")
|
||||
C.pxl8_gui_get_cursor_pos(self._ptr, x, y)
|
||||
return x[0], y[0]
|
||||
end
|
||||
|
||||
function Gui:is_hovering()
|
||||
return C.pxl8_gui_is_hovering(self._ptr)
|
||||
end
|
||||
|
||||
gui.Gui = Gui
|
||||
|
||||
function gui.label(x, y, text, color)
|
||||
C.pxl8_gui_label(core.gfx, x, y, text, color)
|
||||
end
|
||||
|
||||
function gui.window(x, y, w, h, title)
|
||||
C.pxl8_gui_window(core.gfx, x, y, w, h, title)
|
||||
end
|
||||
|
||||
return gui
|
||||
75
src/lua/pxl8/input.lua
Normal file
75
src/lua/pxl8/input.lua
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local input = {}
|
||||
|
||||
function input.key_down(key)
|
||||
return C.pxl8_key_down(core.input, key)
|
||||
end
|
||||
|
||||
function input.key_pressed(key)
|
||||
return C.pxl8_key_pressed(core.input, key)
|
||||
end
|
||||
|
||||
function input.key_released(key)
|
||||
return C.pxl8_key_released(core.input, key)
|
||||
end
|
||||
|
||||
function input.mouse_wheel_x()
|
||||
return C.pxl8_mouse_wheel_x(core.input)
|
||||
end
|
||||
|
||||
function input.mouse_wheel_y()
|
||||
return C.pxl8_mouse_wheel_y(core.input)
|
||||
end
|
||||
|
||||
function input.mouse_x()
|
||||
return C.pxl8_mouse_x(core.input)
|
||||
end
|
||||
|
||||
function input.mouse_y()
|
||||
return C.pxl8_mouse_y(core.input)
|
||||
end
|
||||
|
||||
function input.mouse_dx()
|
||||
return C.pxl8_mouse_dx(core.input)
|
||||
end
|
||||
|
||||
function input.mouse_dy()
|
||||
return C.pxl8_mouse_dy(core.input)
|
||||
end
|
||||
|
||||
function input.get_mouse_pos()
|
||||
return C.pxl8_mouse_x(core.input), C.pxl8_mouse_y(core.input)
|
||||
end
|
||||
|
||||
function input.mouse_pressed(button)
|
||||
return C.pxl8_mouse_pressed(core.input, button)
|
||||
end
|
||||
|
||||
function input.mouse_released(button)
|
||||
return C.pxl8_mouse_released(core.input, button)
|
||||
end
|
||||
|
||||
function input.set_relative_mouse_mode(enabled)
|
||||
C.pxl8_set_relative_mouse_mode(core.sys, enabled)
|
||||
end
|
||||
|
||||
function input.center_cursor()
|
||||
C.pxl8_center_cursor(core.sys)
|
||||
end
|
||||
|
||||
function input.set_cursor(cursor_type)
|
||||
local cursor_enum
|
||||
if cursor_type == "arrow" then
|
||||
cursor_enum = C.PXL8_CURSOR_ARROW
|
||||
elseif cursor_type == "hand" then
|
||||
cursor_enum = C.PXL8_CURSOR_HAND
|
||||
else
|
||||
cursor_enum = C.PXL8_CURSOR_ARROW
|
||||
end
|
||||
C.pxl8_set_cursor(core.sys, cursor_enum)
|
||||
end
|
||||
|
||||
return input
|
||||
53
src/lua/pxl8/math.lua
Normal file
53
src/lua/pxl8/math.lua
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
|
||||
local math3d = {}
|
||||
|
||||
function math3d.mat4_identity()
|
||||
return C.pxl8_mat4_identity()
|
||||
end
|
||||
|
||||
function math3d.mat4_mul(a, b)
|
||||
return C.pxl8_mat4_mul(a, b)
|
||||
end
|
||||
|
||||
function math3d.mat4_translate(x, y, z)
|
||||
return C.pxl8_mat4_translate(x, y, z)
|
||||
end
|
||||
|
||||
function math3d.mat4_rotate_x(angle)
|
||||
return C.pxl8_mat4_rotate_x(angle)
|
||||
end
|
||||
|
||||
function math3d.mat4_rotate_y(angle)
|
||||
return C.pxl8_mat4_rotate_y(angle)
|
||||
end
|
||||
|
||||
function math3d.mat4_rotate_z(angle)
|
||||
return C.pxl8_mat4_rotate_z(angle)
|
||||
end
|
||||
|
||||
function math3d.mat4_scale(x, y, z)
|
||||
return C.pxl8_mat4_scale(x, y, z)
|
||||
end
|
||||
|
||||
function math3d.mat4_ortho(left, right, bottom, top, near, far)
|
||||
return C.pxl8_mat4_ortho(left, right, bottom, top, near, far)
|
||||
end
|
||||
|
||||
function math3d.mat4_perspective(fov, aspect, near, far)
|
||||
return C.pxl8_mat4_perspective(fov, aspect, near, far)
|
||||
end
|
||||
|
||||
function math3d.mat4_lookat(eye, center, up)
|
||||
local eye_vec = ffi.new("pxl8_vec3", {x = eye[1], y = eye[2], z = eye[3]})
|
||||
local center_vec = ffi.new("pxl8_vec3", {x = center[1], y = center[2], z = center[3]})
|
||||
local up_vec = ffi.new("pxl8_vec3", {x = up[1], y = up[2], z = up[3]})
|
||||
return C.pxl8_mat4_lookat(eye_vec, center_vec, up_vec)
|
||||
end
|
||||
|
||||
function math3d.bounds(x, y, w, h)
|
||||
return ffi.new("pxl8_bounds", {x = x, y = y, w = w, h = h})
|
||||
end
|
||||
|
||||
return math3d
|
||||
182
src/lua/pxl8/net.lua
Normal file
182
src/lua/pxl8/net.lua
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
|
||||
local net = {}
|
||||
|
||||
local Net = {}
|
||||
Net.__index = Net
|
||||
|
||||
net.MODE_LOCAL = C.PXL8_NET_LOCAL
|
||||
net.MODE_REMOTE = C.PXL8_NET_REMOTE
|
||||
|
||||
function Net.new(config)
|
||||
config = config or {}
|
||||
local cfg = ffi.new("pxl8_net_config")
|
||||
cfg.address = config.address or "127.0.0.1"
|
||||
cfg.mode = config.mode or C.PXL8_NET_REMOTE
|
||||
cfg.port = config.port or 7777
|
||||
|
||||
local n = C.pxl8_net_create(cfg)
|
||||
if n == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = n }, Net)
|
||||
end
|
||||
|
||||
function Net:connect()
|
||||
return C.pxl8_net_connect(self._ptr) == 0
|
||||
end
|
||||
|
||||
function Net:connected()
|
||||
return C.pxl8_net_connected(self._ptr)
|
||||
end
|
||||
|
||||
function Net:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_net_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Net:disconnect()
|
||||
C.pxl8_net_disconnect(self._ptr)
|
||||
end
|
||||
|
||||
function Net:entities()
|
||||
local snap = C.pxl8_net_snapshot(self._ptr)
|
||||
if snap == nil then
|
||||
return {}
|
||||
end
|
||||
local ents = C.pxl8_net_entities(self._ptr)
|
||||
if ents == nil then
|
||||
return {}
|
||||
end
|
||||
local result = {}
|
||||
for i = 0, snap.entity_count - 1 do
|
||||
result[i + 1] = {
|
||||
entity_id = tonumber(ents[i].entity_id),
|
||||
userdata = ents[i].userdata
|
||||
}
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function Net:entity_prev_userdata(entity_id)
|
||||
return C.pxl8_net_entity_prev_userdata(self._ptr, entity_id)
|
||||
end
|
||||
|
||||
function Net:entity_userdata(entity_id)
|
||||
return C.pxl8_net_entity_userdata(self._ptr, entity_id)
|
||||
end
|
||||
|
||||
function Net:input_at(tick)
|
||||
local input = C.pxl8_net_input_at(self._ptr, tick)
|
||||
if input == nil then return nil end
|
||||
return {
|
||||
buttons = input.buttons,
|
||||
look_dx = input.look_dx,
|
||||
look_dy = input.look_dy,
|
||||
move_x = input.move_x,
|
||||
move_y = input.move_y,
|
||||
yaw = input.yaw,
|
||||
tick = tonumber(input.tick),
|
||||
timestamp = tonumber(input.timestamp)
|
||||
}
|
||||
end
|
||||
|
||||
function Net:input_oldest_tick()
|
||||
return tonumber(C.pxl8_net_input_oldest_tick(self._ptr))
|
||||
end
|
||||
|
||||
function Net:input_push(input)
|
||||
local msg = ffi.new("pxl8_input_msg")
|
||||
msg.buttons = input.buttons or 0
|
||||
msg.look_dx = input.look_dx or 0
|
||||
msg.look_dy = input.look_dy or 0
|
||||
msg.move_x = input.move_x or 0
|
||||
msg.move_y = input.move_y or 0
|
||||
msg.yaw = input.yaw or 0
|
||||
msg.tick = input.tick or 0
|
||||
msg.timestamp = input.timestamp or 0
|
||||
C.pxl8_net_input_push(self._ptr, msg)
|
||||
end
|
||||
|
||||
function Net:lerp_alpha()
|
||||
return C.pxl8_net_lerp_alpha(self._ptr)
|
||||
end
|
||||
|
||||
function Net:needs_correction()
|
||||
return C.pxl8_net_needs_correction(self._ptr)
|
||||
end
|
||||
|
||||
function Net:player_id()
|
||||
return tonumber(C.pxl8_net_player_id(self._ptr))
|
||||
end
|
||||
|
||||
function Net:poll()
|
||||
return C.pxl8_net_poll(self._ptr)
|
||||
end
|
||||
|
||||
function Net:predicted_state()
|
||||
return C.pxl8_net_predicted_state(self._ptr)
|
||||
end
|
||||
|
||||
function Net:predicted_tick_set(tick)
|
||||
C.pxl8_net_predicted_tick_set(self._ptr, tick)
|
||||
end
|
||||
|
||||
function Net:send_command(cmd)
|
||||
return C.pxl8_net_send_command(self._ptr, cmd) == 0
|
||||
end
|
||||
|
||||
function Net:send_input(input)
|
||||
local msg = ffi.new("pxl8_input_msg")
|
||||
msg.buttons = input.buttons or 0
|
||||
msg.look_dx = input.look_dx or 0
|
||||
msg.look_dy = input.look_dy or 0
|
||||
msg.move_x = input.move_x or 0
|
||||
msg.move_y = input.move_y or 0
|
||||
msg.yaw = input.yaw or 0
|
||||
msg.tick = input.tick or 0
|
||||
msg.timestamp = input.timestamp or 0
|
||||
return C.pxl8_net_send_input(self._ptr, msg) == 0
|
||||
end
|
||||
|
||||
function Net:snapshot()
|
||||
local snap = C.pxl8_net_snapshot(self._ptr)
|
||||
if snap == nil then
|
||||
return nil
|
||||
end
|
||||
return {
|
||||
entity_count = snap.entity_count,
|
||||
event_count = snap.event_count,
|
||||
player_id = tonumber(snap.player_id),
|
||||
tick = tonumber(snap.tick),
|
||||
time = snap.time
|
||||
}
|
||||
end
|
||||
|
||||
function Net:spawn(x, y, z, yaw, pitch)
|
||||
local cmd = ffi.new("pxl8_command_msg")
|
||||
cmd.cmd_type = C.PXL8_CMD_SPAWN_ENTITY
|
||||
C.pxl8_pack_f32_be(cmd.payload, 0, x or 0)
|
||||
C.pxl8_pack_f32_be(cmd.payload, 4, y or 0)
|
||||
C.pxl8_pack_f32_be(cmd.payload, 8, z or 0)
|
||||
C.pxl8_pack_f32_be(cmd.payload, 12, yaw or 0)
|
||||
C.pxl8_pack_f32_be(cmd.payload, 16, pitch or 0)
|
||||
cmd.payload_size = 20
|
||||
cmd.tick = 0
|
||||
return self:send_command(cmd)
|
||||
end
|
||||
|
||||
function Net:tick()
|
||||
return tonumber(C.pxl8_net_tick(self._ptr))
|
||||
end
|
||||
|
||||
function Net:update(dt)
|
||||
C.pxl8_net_update(self._ptr, dt)
|
||||
end
|
||||
|
||||
net.Net = Net
|
||||
|
||||
return net
|
||||
103
src/lua/pxl8/particles.lua
Normal file
103
src/lua/pxl8/particles.lua
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local particles = {}
|
||||
|
||||
local Particles = {}
|
||||
Particles.__index = Particles
|
||||
|
||||
function Particles.new(max_count)
|
||||
local ps = C.pxl8_particles_create(max_count or 1000, core.rng)
|
||||
if ps == nil then
|
||||
return nil
|
||||
end
|
||||
local pal = C.pxl8_gfx_get_palette(core.gfx)
|
||||
if pal ~= nil then
|
||||
C.pxl8_particles_set_palette(ps, pal)
|
||||
end
|
||||
return setmetatable({ _ptr = ps }, Particles)
|
||||
end
|
||||
|
||||
function Particles:clear()
|
||||
C.pxl8_particles_clear(self._ptr)
|
||||
end
|
||||
|
||||
function Particles:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_particles_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Particles:emit(count)
|
||||
C.pxl8_particles_emit(self._ptr, count or 1)
|
||||
end
|
||||
|
||||
function Particles:render()
|
||||
C.pxl8_particles_render(self._ptr, core.gfx)
|
||||
end
|
||||
|
||||
function Particles:update(dt)
|
||||
C.pxl8_particles_update(self._ptr, dt)
|
||||
end
|
||||
|
||||
function Particles:count()
|
||||
return C.pxl8_particles_count(self._ptr)
|
||||
end
|
||||
|
||||
function Particles:get(index)
|
||||
return C.pxl8_particles_get(self._ptr, index)
|
||||
end
|
||||
|
||||
function Particles:set_position(x, y)
|
||||
C.pxl8_particles_set_position(self._ptr, x, y)
|
||||
end
|
||||
|
||||
function Particles:set_gravity(gx, gy)
|
||||
C.pxl8_particles_set_gravity(self._ptr, gx, gy)
|
||||
end
|
||||
|
||||
function Particles:set_spread(sx, sy)
|
||||
C.pxl8_particles_set_spread(self._ptr, sx, sy)
|
||||
end
|
||||
|
||||
function Particles:set_drag(drag)
|
||||
C.pxl8_particles_set_drag(self._ptr, drag)
|
||||
end
|
||||
|
||||
function Particles:set_turbulence(turbulence)
|
||||
C.pxl8_particles_set_turbulence(self._ptr, turbulence)
|
||||
end
|
||||
|
||||
function Particles:set_spawn_rate(rate)
|
||||
C.pxl8_particles_set_spawn_rate(self._ptr, rate)
|
||||
end
|
||||
|
||||
function Particles:set_colors(ramp_min, ramp_max)
|
||||
ramp_max = ramp_max or ramp_min
|
||||
if ramp_min > ramp_max then
|
||||
ramp_min, ramp_max = ramp_max, ramp_min
|
||||
end
|
||||
C.pxl8_particles_set_colors(self._ptr, ramp_min, ramp_max)
|
||||
end
|
||||
|
||||
function Particles:set_palette(palette)
|
||||
C.pxl8_particles_set_palette(self._ptr, palette)
|
||||
end
|
||||
|
||||
function Particles:set_life(life_min, life_max)
|
||||
C.pxl8_particles_set_life(self._ptr, life_min, life_max or life_min)
|
||||
end
|
||||
|
||||
function Particles:set_size(size_min, size_max)
|
||||
C.pxl8_particles_set_size(self._ptr, size_min, size_max or size_min)
|
||||
end
|
||||
|
||||
function Particles:set_velocity(vx_min, vx_max, vy_min, vy_max)
|
||||
C.pxl8_particles_set_velocity(self._ptr, vx_min, vx_max, vy_min, vy_max)
|
||||
end
|
||||
|
||||
particles.Particles = Particles
|
||||
|
||||
return particles
|
||||
239
src/lua/pxl8/sfx.lua
Normal file
239
src/lua/pxl8/sfx.lua
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local sfx = {}
|
||||
|
||||
sfx.FILTER_BANDPASS = C.PXL8_SFX_FILTER_BANDPASS
|
||||
sfx.FILTER_HIGHPASS = C.PXL8_SFX_FILTER_HIGHPASS
|
||||
sfx.FILTER_LOWPASS = C.PXL8_SFX_FILTER_LOWPASS
|
||||
sfx.FILTER_NONE = C.PXL8_SFX_FILTER_NONE
|
||||
|
||||
sfx.LFO_AMPLITUDE = C.PXL8_SFX_LFO_AMPLITUDE
|
||||
sfx.LFO_FILTER = C.PXL8_SFX_LFO_FILTER
|
||||
sfx.LFO_PITCH = C.PXL8_SFX_LFO_PITCH
|
||||
|
||||
sfx.NODE_COMPRESSOR = C.PXL8_SFX_NODE_COMPRESSOR
|
||||
sfx.NODE_DELAY = C.PXL8_SFX_NODE_DELAY
|
||||
sfx.NODE_REVERB = C.PXL8_SFX_NODE_REVERB
|
||||
|
||||
sfx.WAVE_NOISE = C.PXL8_SFX_WAVE_NOISE
|
||||
sfx.WAVE_PULSE = C.PXL8_SFX_WAVE_PULSE
|
||||
sfx.WAVE_SAW = C.PXL8_SFX_WAVE_SAW
|
||||
sfx.WAVE_SINE = C.PXL8_SFX_WAVE_SINE
|
||||
sfx.WAVE_SQUARE = C.PXL8_SFX_WAVE_SQUARE
|
||||
sfx.WAVE_TRIANGLE = C.PXL8_SFX_WAVE_TRIANGLE
|
||||
|
||||
local SfxNode = {}
|
||||
SfxNode.__index = SfxNode
|
||||
|
||||
function SfxNode:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_sfx_node_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
sfx.SfxNode = SfxNode
|
||||
|
||||
local SfxContext = {}
|
||||
SfxContext.__index = SfxContext
|
||||
|
||||
function SfxContext.new()
|
||||
local ctx = C.pxl8_sfx_context_create()
|
||||
if ctx == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = ctx }, SfxContext)
|
||||
end
|
||||
|
||||
function SfxContext:append_node(node)
|
||||
C.pxl8_sfx_context_append_node(self._ptr, node._ptr)
|
||||
end
|
||||
|
||||
function SfxContext:attach()
|
||||
C.pxl8_sfx_mixer_attach(core.sfx, self._ptr)
|
||||
end
|
||||
|
||||
function SfxContext:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_sfx_context_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function SfxContext:detach()
|
||||
C.pxl8_sfx_mixer_detach(core.sfx, self._ptr)
|
||||
end
|
||||
|
||||
function SfxContext:get_head()
|
||||
local ptr = C.pxl8_sfx_context_get_head(self._ptr)
|
||||
if ptr == nil then return nil end
|
||||
return setmetatable({ _ptr = ptr }, SfxNode)
|
||||
end
|
||||
|
||||
function SfxContext:get_volume()
|
||||
return C.pxl8_sfx_context_get_volume(self._ptr)
|
||||
end
|
||||
|
||||
function SfxContext:insert_node(after, node)
|
||||
C.pxl8_sfx_context_insert_node(self._ptr, after._ptr, node._ptr)
|
||||
end
|
||||
|
||||
function SfxContext:play_note(note, params, volume, duration)
|
||||
return C.pxl8_sfx_play_note(self._ptr, note, params, volume or 0.8, duration or 0)
|
||||
end
|
||||
|
||||
function SfxContext:release_voice(voice_id)
|
||||
C.pxl8_sfx_release_voice(self._ptr, voice_id)
|
||||
end
|
||||
|
||||
function SfxContext:remove_node(node)
|
||||
C.pxl8_sfx_context_remove_node(self._ptr, node._ptr)
|
||||
end
|
||||
|
||||
function SfxContext:set_volume(volume)
|
||||
C.pxl8_sfx_context_set_volume(self._ptr, volume)
|
||||
end
|
||||
|
||||
function SfxContext:stop_all()
|
||||
C.pxl8_sfx_stop_all(self._ptr)
|
||||
end
|
||||
|
||||
function SfxContext:stop_voice(voice_id)
|
||||
C.pxl8_sfx_stop_voice(self._ptr, voice_id)
|
||||
end
|
||||
|
||||
sfx.SfxContext = SfxContext
|
||||
|
||||
local Compressor = setmetatable({}, { __index = SfxNode })
|
||||
Compressor.__index = Compressor
|
||||
|
||||
function Compressor.new(opts)
|
||||
opts = opts or {}
|
||||
local cfg = ffi.new("pxl8_sfx_compressor_config")
|
||||
cfg.attack = opts.attack or 10
|
||||
cfg.ratio = opts.ratio or 4
|
||||
cfg.release = opts.release or 100
|
||||
cfg.threshold = opts.threshold or -12
|
||||
local ptr = C.pxl8_sfx_compressor_create(cfg)
|
||||
if ptr == nil then return nil end
|
||||
return setmetatable({ _ptr = ptr }, Compressor)
|
||||
end
|
||||
|
||||
function Compressor:set_attack(attack)
|
||||
C.pxl8_sfx_compressor_set_attack(self._ptr, attack)
|
||||
end
|
||||
|
||||
function Compressor:set_ratio(ratio)
|
||||
C.pxl8_sfx_compressor_set_ratio(self._ptr, ratio)
|
||||
end
|
||||
|
||||
function Compressor:set_release(release)
|
||||
C.pxl8_sfx_compressor_set_release(self._ptr, release)
|
||||
end
|
||||
|
||||
function Compressor:set_threshold(threshold)
|
||||
C.pxl8_sfx_compressor_set_threshold(self._ptr, threshold)
|
||||
end
|
||||
|
||||
sfx.Compressor = Compressor
|
||||
|
||||
local Delay = setmetatable({}, { __index = SfxNode })
|
||||
Delay.__index = Delay
|
||||
|
||||
function Delay.new(opts)
|
||||
opts = opts or {}
|
||||
local cfg = ffi.new("pxl8_sfx_delay_config")
|
||||
cfg.feedback = opts.feedback or 0.4
|
||||
cfg.mix = opts.mix or 0.25
|
||||
cfg.time_l = opts.time_l or 350
|
||||
cfg.time_r = opts.time_r or 500
|
||||
local ptr = C.pxl8_sfx_delay_create(cfg)
|
||||
if ptr == nil then return nil end
|
||||
return setmetatable({ _ptr = ptr }, Delay)
|
||||
end
|
||||
|
||||
function Delay:set_feedback(feedback)
|
||||
C.pxl8_sfx_delay_set_feedback(self._ptr, feedback)
|
||||
end
|
||||
|
||||
function Delay:set_mix(mix)
|
||||
C.pxl8_sfx_delay_set_mix(self._ptr, mix)
|
||||
end
|
||||
|
||||
function Delay:set_time(time_l, time_r)
|
||||
C.pxl8_sfx_delay_set_time(self._ptr, time_l, time_r)
|
||||
end
|
||||
|
||||
sfx.Delay = Delay
|
||||
|
||||
local Reverb = setmetatable({}, { __index = SfxNode })
|
||||
Reverb.__index = Reverb
|
||||
|
||||
function Reverb.new(opts)
|
||||
opts = opts or {}
|
||||
local cfg = ffi.new("pxl8_sfx_reverb_config")
|
||||
cfg.damping = opts.damping or 0.5
|
||||
cfg.mix = opts.mix or 0.3
|
||||
cfg.room = opts.room or 0.5
|
||||
local ptr = C.pxl8_sfx_reverb_create(cfg)
|
||||
if ptr == nil then return nil end
|
||||
return setmetatable({ _ptr = ptr }, Reverb)
|
||||
end
|
||||
|
||||
function Reverb:set_damping(damping)
|
||||
C.pxl8_sfx_reverb_set_damping(self._ptr, damping)
|
||||
end
|
||||
|
||||
function Reverb:set_mix(mix)
|
||||
C.pxl8_sfx_reverb_set_mix(self._ptr, mix)
|
||||
end
|
||||
|
||||
function Reverb:set_room(room)
|
||||
C.pxl8_sfx_reverb_set_room(self._ptr, room)
|
||||
end
|
||||
|
||||
sfx.Reverb = Reverb
|
||||
|
||||
function sfx.get_master_volume()
|
||||
return C.pxl8_sfx_mixer_get_master_volume(core.sfx)
|
||||
end
|
||||
|
||||
sfx.note_to_freq = C.pxl8_sfx_note_to_freq
|
||||
|
||||
function sfx.set_master_volume(volume)
|
||||
C.pxl8_sfx_mixer_set_master_volume(core.sfx, volume)
|
||||
end
|
||||
|
||||
function sfx.voice_params(opts)
|
||||
opts = opts or {}
|
||||
local params = ffi.new("pxl8_sfx_voice_params")
|
||||
|
||||
params.amp_env.attack = opts.attack or 0.01
|
||||
params.amp_env.decay = opts.decay or 0.1
|
||||
params.amp_env.sustain = opts.sustain or 0.5
|
||||
params.amp_env.release = opts.release or 0.2
|
||||
|
||||
params.filter_env.attack = opts.filter_attack or 0.01
|
||||
params.filter_env.decay = opts.filter_decay or 0.1
|
||||
params.filter_env.sustain = opts.filter_sustain or 0.3
|
||||
params.filter_env.release = opts.filter_release or 0.1
|
||||
|
||||
params.filter_type = opts.filter_type or C.PXL8_SFX_FILTER_NONE
|
||||
params.lfo_target = opts.lfo_target or C.PXL8_SFX_LFO_PITCH
|
||||
params.lfo_waveform = opts.lfo_waveform or C.PXL8_SFX_WAVE_SINE
|
||||
params.waveform = opts.waveform or C.PXL8_SFX_WAVE_SINE
|
||||
|
||||
params.filter_cutoff = opts.filter_cutoff or 4000
|
||||
params.filter_env_depth = opts.filter_env_depth or 0
|
||||
params.filter_resonance = opts.filter_resonance or 0
|
||||
params.fx_send = opts.fx_send or 0
|
||||
params.lfo_depth = opts.lfo_depth or 0
|
||||
params.lfo_rate = opts.lfo_rate or 0
|
||||
params.pulse_width = opts.pulse_width or 0.5
|
||||
|
||||
return params
|
||||
end
|
||||
|
||||
return sfx
|
||||
106
src/lua/pxl8/tilemap.lua
Normal file
106
src/lua/pxl8/tilemap.lua
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local tilemap = {}
|
||||
|
||||
tilemap.TILE_FLIP_X = 1
|
||||
tilemap.TILE_FLIP_Y = 2
|
||||
tilemap.TILE_SOLID = 4
|
||||
tilemap.TILE_TRIGGER = 8
|
||||
|
||||
local Tilesheet = {}
|
||||
Tilesheet.__index = Tilesheet
|
||||
|
||||
function Tilesheet.new(tile_size)
|
||||
local ts = C.pxl8_tilesheet_create(tile_size or 16)
|
||||
if ts == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = ts }, Tilesheet)
|
||||
end
|
||||
|
||||
function Tilesheet:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_tilesheet_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Tilesheet:load(filepath)
|
||||
return C.pxl8_tilesheet_load(self._ptr, filepath, core.gfx)
|
||||
end
|
||||
|
||||
tilemap.Tilesheet = Tilesheet
|
||||
|
||||
local Tilemap = {}
|
||||
Tilemap.__index = Tilemap
|
||||
|
||||
local tile_data = setmetatable({}, {__mode = "k"})
|
||||
|
||||
function Tilemap.new(width, height, tile_size)
|
||||
local tm = C.pxl8_tilemap_create(width, height, tile_size or 16)
|
||||
if tm == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = tm }, Tilemap)
|
||||
end
|
||||
|
||||
function Tilemap:check_collision(x, y, w, h)
|
||||
return C.pxl8_tilemap_check_collision(self._ptr, x, y, w, h)
|
||||
end
|
||||
|
||||
function Tilemap:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_tilemap_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Tilemap:get_tile_data(tile_id)
|
||||
if tile_id == 0 then return nil end
|
||||
if not tile_data[self] then return nil end
|
||||
return tile_data[self][tile_id]
|
||||
end
|
||||
|
||||
function Tilemap:get_tile_id(layer, x, y)
|
||||
return C.pxl8_tilemap_get_tile_id(self._ptr, layer or 0, x, y)
|
||||
end
|
||||
|
||||
function Tilemap:is_solid(x, y)
|
||||
return C.pxl8_tilemap_is_solid(self._ptr, x, y)
|
||||
end
|
||||
|
||||
function Tilemap:load_ase(filepath, layer)
|
||||
return C.pxl8_tilemap_load_ase(self._ptr, filepath, layer or 0)
|
||||
end
|
||||
|
||||
function Tilemap:render()
|
||||
C.pxl8_tilemap_render(self._ptr, core.gfx)
|
||||
end
|
||||
|
||||
function Tilemap:render_layer(layer)
|
||||
C.pxl8_tilemap_render_layer(self._ptr, core.gfx, layer)
|
||||
end
|
||||
|
||||
function Tilemap:set_camera(x, y)
|
||||
C.pxl8_tilemap_set_camera(self._ptr, x, y)
|
||||
end
|
||||
|
||||
function Tilemap:set_tile(layer, x, y, tile_id, flags)
|
||||
C.pxl8_tilemap_set_tile(self._ptr, layer or 0, x, y, tile_id or 0, flags or 0)
|
||||
end
|
||||
|
||||
function Tilemap:set_tile_data(tile_id, data)
|
||||
if tile_id == 0 then return end
|
||||
if not tile_data[self] then tile_data[self] = {} end
|
||||
tile_data[self][tile_id] = data
|
||||
end
|
||||
|
||||
function Tilemap:set_tilesheet(tilesheet)
|
||||
return C.pxl8_tilemap_set_tilesheet(self._ptr, tilesheet._ptr)
|
||||
end
|
||||
|
||||
tilemap.Tilemap = Tilemap
|
||||
|
||||
return tilemap
|
||||
82
src/lua/pxl8/transition.lua
Normal file
82
src/lua/pxl8/transition.lua
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local transition = {}
|
||||
|
||||
local TYPES = {
|
||||
fade = 0,
|
||||
wipe_left = 1,
|
||||
wipe_right = 2,
|
||||
wipe_up = 3,
|
||||
wipe_down = 4,
|
||||
circle_open = 5,
|
||||
circle_close = 6,
|
||||
dissolve = 7,
|
||||
pixelate = 8
|
||||
}
|
||||
|
||||
transition.TYPES = TYPES
|
||||
|
||||
local Transition = {}
|
||||
Transition.__index = Transition
|
||||
|
||||
function Transition.new(type_name, duration)
|
||||
local type_id = TYPES[type_name] or 0
|
||||
local t = C.pxl8_transition_create(type_id, duration or 1.0)
|
||||
if t == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = t }, Transition)
|
||||
end
|
||||
|
||||
function Transition:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_transition_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Transition:get_progress()
|
||||
return C.pxl8_transition_get_progress(self._ptr)
|
||||
end
|
||||
|
||||
function Transition:is_active()
|
||||
return C.pxl8_transition_is_active(self._ptr)
|
||||
end
|
||||
|
||||
function Transition:is_complete()
|
||||
return C.pxl8_transition_is_complete(self._ptr)
|
||||
end
|
||||
|
||||
function Transition:render()
|
||||
C.pxl8_transition_render(self._ptr, core.gfx)
|
||||
end
|
||||
|
||||
function Transition:reset()
|
||||
C.pxl8_transition_reset(self._ptr)
|
||||
end
|
||||
|
||||
function Transition:set_color(color)
|
||||
C.pxl8_transition_set_color(self._ptr, color)
|
||||
end
|
||||
|
||||
function Transition:set_reverse(reverse)
|
||||
C.pxl8_transition_set_reverse(self._ptr, reverse)
|
||||
end
|
||||
|
||||
function Transition:start()
|
||||
C.pxl8_transition_start(self._ptr)
|
||||
end
|
||||
|
||||
function Transition:stop()
|
||||
C.pxl8_transition_stop(self._ptr)
|
||||
end
|
||||
|
||||
function Transition:update(dt)
|
||||
C.pxl8_transition_update(self._ptr, dt)
|
||||
end
|
||||
|
||||
transition.Transition = Transition
|
||||
|
||||
return transition
|
||||
120
src/lua/pxl8/world.lua
Normal file
120
src/lua/pxl8/world.lua
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
local ffi = require("ffi")
|
||||
local C = ffi.C
|
||||
local core = require("pxl8.core")
|
||||
|
||||
local world = {}
|
||||
|
||||
world.PROCGEN_ROOMS = C.PXL8_PROCGEN_ROOMS
|
||||
world.PROCGEN_TERRAIN = C.PXL8_PROCGEN_TERRAIN
|
||||
|
||||
local World = {}
|
||||
World.__index = World
|
||||
|
||||
function World.new()
|
||||
local w = C.pxl8_world_create()
|
||||
if w == nil then
|
||||
return nil
|
||||
end
|
||||
return setmetatable({ _ptr = w }, World)
|
||||
end
|
||||
|
||||
function World:apply_textures(texture_defs)
|
||||
local count = #texture_defs
|
||||
local textures = ffi.new("pxl8_world_texture[?]", count)
|
||||
|
||||
for i, def in ipairs(texture_defs) do
|
||||
local idx = i - 1
|
||||
ffi.copy(textures[idx].name, def.name or "", math.min(#(def.name or ""), 15))
|
||||
textures[idx].texture_id = def.texture_id or 0
|
||||
|
||||
if def.rule then
|
||||
textures[idx].rule = ffi.cast("bool (*)(const pxl8_vec3*, const pxl8_bsp_face*, const pxl8_bsp*)",
|
||||
function(normal, face, bsp)
|
||||
return def.rule(normal[0], face, bsp)
|
||||
end)
|
||||
else
|
||||
textures[idx].rule = nil
|
||||
end
|
||||
end
|
||||
|
||||
return C.pxl8_world_apply_textures(self._ptr, textures, count)
|
||||
end
|
||||
|
||||
function World:check_collision(x, y, z, radius)
|
||||
local pos = ffi.new("pxl8_vec3", {x = x, y = y, z = z})
|
||||
return C.pxl8_world_check_collision(self._ptr, pos, radius)
|
||||
end
|
||||
|
||||
function World:destroy()
|
||||
if self._ptr then
|
||||
C.pxl8_world_destroy(self._ptr)
|
||||
self._ptr = nil
|
||||
end
|
||||
end
|
||||
|
||||
function World:generate(params)
|
||||
local c_params = ffi.new("pxl8_procgen_params")
|
||||
c_params.type = params.type or C.PXL8_PROCGEN_ROOMS
|
||||
c_params.width = params.width or 32
|
||||
c_params.height = params.height or 32
|
||||
c_params.depth = params.depth or 0
|
||||
c_params.seed = params.seed or 0
|
||||
c_params.min_room_size = params.min_room_size or 5
|
||||
c_params.max_room_size = params.max_room_size or 10
|
||||
c_params.num_rooms = params.num_rooms or 8
|
||||
return C.pxl8_world_generate(self._ptr, core.gfx, c_params)
|
||||
end
|
||||
|
||||
function World:is_loaded()
|
||||
return C.pxl8_world_is_loaded(self._ptr)
|
||||
end
|
||||
|
||||
function World:load(filepath)
|
||||
return C.pxl8_world_load(self._ptr, filepath)
|
||||
end
|
||||
|
||||
function World:render(camera_pos)
|
||||
local vec = ffi.new("pxl8_vec3", {x = camera_pos[1], y = camera_pos[2], z = camera_pos[3]})
|
||||
C.pxl8_world_render(self._ptr, core.gfx, vec)
|
||||
end
|
||||
|
||||
function World:resolve_collision(from_x, from_y, from_z, to_x, to_y, to_z, radius)
|
||||
local from = ffi.new("pxl8_vec3", {x = from_x, y = from_y, z = from_z})
|
||||
local to = ffi.new("pxl8_vec3", {x = to_x, y = to_y, z = to_z})
|
||||
local result = C.pxl8_world_resolve_collision(self._ptr, from, to, radius)
|
||||
return result.x, result.y, result.z
|
||||
end
|
||||
|
||||
function World:unload()
|
||||
C.pxl8_world_unload(self._ptr)
|
||||
end
|
||||
|
||||
world.World = World
|
||||
|
||||
function world.procgen_tex(params)
|
||||
local width = params.width or 64
|
||||
local height = params.height or 64
|
||||
local buffer = ffi.new("u8[?]", width * height)
|
||||
local tex_params = ffi.new("pxl8_procgen_tex_params")
|
||||
|
||||
local name = params.name or ""
|
||||
ffi.copy(tex_params.name, name, math.min(#name, 15))
|
||||
|
||||
tex_params.seed = params.seed or 0
|
||||
tex_params.width = width
|
||||
tex_params.height = height
|
||||
tex_params.scale = params.scale or 1.0
|
||||
tex_params.roughness = params.roughness or 0.0
|
||||
tex_params.base_color = params.base_color or 0
|
||||
tex_params.variation = params.variation or 0
|
||||
|
||||
C.pxl8_procgen_tex(buffer, tex_params)
|
||||
|
||||
local tex_id = C.pxl8_gfx_create_texture(core.gfx, buffer, width, height)
|
||||
if tex_id < 0 then
|
||||
return nil
|
||||
end
|
||||
return tex_id
|
||||
end
|
||||
|
||||
return world
|
||||
Loading…
Add table
Add a link
Reference in a new issue