(local pxl8 (require :pxl8)) (local music (require :mod.music)) (local world-mod (require :pxl8.world)) (local net-mod (require :pxl8.net)) (var paused false) (var wireframe false) (var gui nil) (var render-distance 3) (var sim-distance 4) (var current-panel :main) (var selected-item nil) (var current-items []) (var pending-action nil) (fn init [] (set gui (pxl8.create_gui)) (let [w (world-mod.World.get)] (when w (set render-distance (w:get_render_distance)) (set sim-distance (w:get_sim_distance))))) (fn show [] (set paused true) (set current-panel :main) (pxl8.set_relative_mouse_mode false) (pxl8.center_cursor)) (fn hide [] (set paused false) (pxl8.set_relative_mouse_mode true)) (fn toggle [] (when (not gui) (init)) (if paused (hide) (show))) (fn select-next [] (when (> (length current-items) 0) (var found-idx nil) (for [i 1 (length current-items)] (when (= (. current-items i) selected-item) (set found-idx i))) (if found-idx (let [next-idx (+ found-idx 1)] (if (<= next-idx (length current-items)) (set selected-item (. current-items next-idx)) (set selected-item (. current-items 1)))) (set selected-item (. current-items 1))))) (fn select-prev [] (when (> (length current-items) 0) (var found-idx nil) (for [i 1 (length current-items)] (when (= (. current-items i) selected-item) (set found-idx i))) (if found-idx (let [prev-idx (- found-idx 1)] (if (>= prev-idx 1) (set selected-item (. current-items prev-idx)) (set selected-item (. current-items (length current-items))))) (set selected-item (. current-items (length current-items)))))) (fn update [] (set pending-action nil) (when gui (let [(mx my) (pxl8.get_mouse_pos)] (gui:cursor_move mx my)) (when (pxl8.mouse_pressed 1) (gui:cursor_down)) (when (pxl8.mouse_released 1) (gui:cursor_up)) (when (or (pxl8.key_pressed "down") (and (pxl8.key_pressed "tab") (not (pxl8.key_down "lshift")) (not (pxl8.key_down "rshift")))) (select-next)) (when (or (pxl8.key_pressed "up") (and (pxl8.key_pressed "tab") (or (pxl8.key_down "lshift") (pxl8.key_down "rshift")))) (select-prev)) (when (or (pxl8.key_pressed "return") (pxl8.key_pressed "space")) (when selected-item (set pending-action selected-item))))) (fn menu-button [id x y w h label] (table.insert current-items label) (when (= selected-item nil) (set selected-item label)) (let [is-selected (= selected-item label)] (when is-selected (pxl8.rect (- x 3) (- y 3) (+ w 6) (+ h 6) 15)) (let [clicked (gui:button id x y w h label)] (when clicked (set selected-item label)) (or clicked (and is-selected (= pending-action label)))))) (fn draw-main-menu [] (pxl8.gui_window 200 80 240 235 "pxl8 demo") (when (menu-button 1 215 127 210 30 "Resume") (hide)) (let [wire-label (if wireframe "Wireframe: On" "Wireframe: Off")] (when (menu-button 4 215 162 210 30 wire-label) (set wireframe (not wireframe)))) (when (menu-button 5 215 197 210 30 "GFX") (set current-panel :gfx) (set selected-item nil)) (when (menu-button 6 215 232 210 30 "SFX") (set current-panel :sfx) (set selected-item nil)) (when (menu-button 2 215 267 210 30 "Quit") (pxl8.quit))) (fn draw-sfx-panel [] (pxl8.gui_window 200 100 240 145 "SFX") (let [music-label (if (music.is-playing) "Music: On" "Music: Off")] (when (menu-button 10 215 147 210 30 music-label) (if (music.is-playing) (music.stop) (music.start)))) (pxl8.gui_label 215 185 "Volume/Devices: TODO" 15) (when (menu-button 20 215 210 210 30 "Back") (set current-panel :main) (set selected-item nil))) (fn draw-gfx-panel [] (pxl8.gui_window 200 100 240 180 "GFX") (pxl8.gui_label 215 150 (.. "Render: " render-distance) 15) (let [(changed new-val) (gui:slider_int 30 215 165 210 16 render-distance 1 8)] (when changed (set render-distance new-val) (let [w (world-mod.World.get) n (net-mod.get)] (when w (w:set_render_distance new-val)) (when n (n:set_chunk_settings new-val sim-distance))))) (pxl8.gui_label 215 190 (.. "Sim: " sim-distance) 15) (let [(changed new-val) (gui:slider_int 31 215 205 210 16 sim-distance 1 8)] (when changed (set sim-distance new-val) (let [w (world-mod.World.get) n (net-mod.get)] (when w (w:set_sim_distance new-val)) (when n (n:set_chunk_settings render-distance new-val))))) (when (menu-button 32 215 240 210 30 "Back") (set current-panel :main) (set selected-item nil))) (fn draw [] (set current-items []) (when gui (gui:begin_frame) (case current-panel :main (draw-main-menu) :sfx (draw-sfx-panel) :gfx (draw-gfx-panel)) (if (gui:is_hovering) (pxl8.set_cursor :hand) (pxl8.set_cursor :arrow)) (gui:end_frame))) {:init init :is-paused (fn [] paused) :is-wireframe (fn [] wireframe) :toggle toggle :show show :hide hide :update update :draw draw}