2024-10-04 21:16:58 +03:00
|
|
|
package main
|
|
|
|
|
|
|
|
import rl "vendor:raylib"
|
2024-10-05 20:44:32 +03:00
|
|
|
import "core:path/filepath"
|
|
|
|
import "core:strings"
|
2024-10-13 19:17:47 +03:00
|
|
|
import "core:fmt"
|
2024-10-04 21:16:58 +03:00
|
|
|
|
|
|
|
vec3 :: [3]f32
|
2024-10-13 19:17:47 +03:00
|
|
|
vec3i :: [3]i32
|
2024-10-04 21:16:58 +03:00
|
|
|
vec2 :: [2]f32
|
2024-10-13 19:17:47 +03:00
|
|
|
vec2i :: [2]i32
|
2024-10-04 21:16:58 +03:00
|
|
|
vec3right := vec3{1, 0, 0}
|
|
|
|
vec3left := vec3{-1, 0, 0}
|
|
|
|
vec3up := vec3{0, 1, 0}
|
|
|
|
vec3down := vec3{0, -1, 0}
|
|
|
|
vec3forward := vec3{0, 0, 1}
|
|
|
|
vec3backward := vec3{0, 0, -1}
|
|
|
|
|
|
|
|
|
|
|
|
WSize := [2]f32{}
|
|
|
|
WSizei := [2]i32{}
|
|
|
|
|
2024-10-13 19:17:47 +03:00
|
|
|
WSizeLast := vec2i{}
|
|
|
|
|
2024-10-04 21:16:58 +03:00
|
|
|
WindowShouldExit := false
|
|
|
|
|
2024-10-06 10:59:07 +03:00
|
|
|
NeedTutorial := true
|
|
|
|
KeyboardOnly := false
|
|
|
|
|
2024-10-05 20:44:32 +03:00
|
|
|
|
|
|
|
Overlay_Opacity : f32 = 0
|
|
|
|
|
|
|
|
Resources :: struct {
|
|
|
|
Fonts: struct {
|
|
|
|
UI: rl.Font,
|
|
|
|
Title: rl.Font,
|
|
|
|
},
|
|
|
|
Models: struct {
|
|
|
|
PlayerModel: rl.Model,
|
|
|
|
SnakeHeadTop: rl.Model,
|
|
|
|
SnakeHeadJaw: rl.Model,
|
|
|
|
SnakeBody: rl.Model,
|
|
|
|
Background: rl.Model,
|
|
|
|
},
|
|
|
|
Sfx: struct {
|
|
|
|
Drums: rl.Sound,
|
|
|
|
Lightning: rl.Sound,
|
|
|
|
LightningHit: rl.Sound,
|
|
|
|
Rocket: rl.Sound,
|
|
|
|
PlayerHit: rl.Sound,
|
|
|
|
PlayerSwoosh: rl.Sound,
|
|
|
|
PlayerDead: rl.Sound,
|
|
|
|
SnakeGrowl: rl.Sound,
|
|
|
|
SnakeRoarBlast: rl.Sound,
|
|
|
|
SnakeEarthHit: rl.Sound,
|
|
|
|
SnakeSegmentExplode: rl.Sound,
|
|
|
|
SnakeBeam: rl.Sound,
|
|
|
|
},
|
|
|
|
Music: struct {
|
|
|
|
First: rl.Music,
|
|
|
|
Second: rl.Music,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Res : Resources
|
|
|
|
|
2024-10-12 18:26:14 +03:00
|
|
|
res_paths := map[typeid]string{
|
|
|
|
rl.Music = "music",
|
|
|
|
rl.Sound = "sfx",
|
|
|
|
rl.Model = "models",
|
|
|
|
}
|
|
|
|
|
|
|
|
get_path :: proc(name: string, $T: typeid) -> cstring{
|
|
|
|
p := filepath.join([]string{"./assets", res_paths[T], name})
|
|
|
|
cstr := strings.clone_to_cstring(p)
|
|
|
|
return cstr
|
|
|
|
}
|
|
|
|
|
|
|
|
load_model :: proc(name: string) -> rl.Model {
|
|
|
|
p := get_path(name, rl.Model)
|
|
|
|
mdl := rl.LoadModel(p)
|
|
|
|
return mdl
|
|
|
|
}
|
2024-10-05 20:44:32 +03:00
|
|
|
|
|
|
|
load_sfx :: proc(name: string, volume: f32 = 1) -> rl.Sound {
|
2024-10-12 18:26:14 +03:00
|
|
|
p := get_path(name, rl.Sound)
|
|
|
|
snd := rl.LoadSound(p)
|
2024-10-05 20:44:32 +03:00
|
|
|
rl.SetSoundVolume(snd, volume)
|
|
|
|
return snd
|
|
|
|
}
|
|
|
|
|
|
|
|
load_music :: proc(name: string, volume: f32 = 1) -> rl.Music {
|
2024-10-12 18:26:14 +03:00
|
|
|
p := get_path(name, rl.Music)
|
|
|
|
snd := rl.LoadMusicStream(p)
|
2024-10-05 20:44:32 +03:00
|
|
|
rl.SetMusicVolume(snd, volume)
|
|
|
|
return snd
|
|
|
|
}
|
|
|
|
|
|
|
|
current_music : rl.Music
|
|
|
|
|
|
|
|
change_track :: proc(music: rl.Music) {
|
|
|
|
rl.StopMusicStream(current_music)
|
|
|
|
current_music = music
|
|
|
|
rl.PlayMusicStream(current_music)
|
|
|
|
}
|
|
|
|
|
2024-10-06 10:59:07 +03:00
|
|
|
Cursor : rl.Texture
|
2024-10-05 20:44:32 +03:00
|
|
|
load_resources :: proc() {
|
2024-10-06 10:59:07 +03:00
|
|
|
Res.Fonts.Title = rl.LoadFontEx("./assets/fonts/norse.otf", 96*2, nil, 2048)
|
|
|
|
Res.Fonts.UI = rl.LoadFontEx("./assets/fonts/PTSerif-Regular.ttf", 96, nil, 2048)
|
2024-10-05 20:44:32 +03:00
|
|
|
|
2024-10-12 18:26:14 +03:00
|
|
|
Res.Models = {
|
|
|
|
PlayerModel = load_model("chariot.glb"),
|
|
|
|
SnakeHeadTop = load_model("snake_head_top.obj"),
|
|
|
|
SnakeHeadJaw = load_model("snake_jaw.obj"),
|
|
|
|
SnakeBody = load_model("snake_body.obj"),
|
|
|
|
Background = load_model("background.obj"),
|
|
|
|
}
|
|
|
|
|
|
|
|
Res.Sfx = {
|
|
|
|
Drums = load_sfx("drums.ogg"),
|
|
|
|
Lightning = load_sfx("lightning.ogg", 0.5),
|
|
|
|
LightningHit = load_sfx("lightning-hit.ogg", 0.3),
|
|
|
|
Rocket = load_sfx("rocket.ogg", 0.5),
|
|
|
|
PlayerHit = load_sfx("player-hit.ogg", 0.5),
|
|
|
|
PlayerSwoosh = load_sfx("player-swoosh.ogg"),
|
|
|
|
PlayerDead = load_sfx("player-dead.ogg"),
|
|
|
|
SnakeGrowl = load_sfx("snake-growl.ogg", 0.7),
|
|
|
|
SnakeRoarBlast = load_sfx("snake-roar-blast.ogg", 0.8),
|
|
|
|
SnakeBeam = load_sfx("snake-beam.ogg"),
|
|
|
|
SnakeSegmentExplode = load_sfx("snake-segment-explode.ogg", 0.8),
|
|
|
|
SnakeEarthHit = load_sfx("snake-earth-hit.ogg", 0.6),
|
|
|
|
}
|
2024-10-05 20:44:32 +03:00
|
|
|
|
|
|
|
Res.Music.First = load_music("alexander-nakarada-mjolnir.mp3", 0.7)
|
|
|
|
Res.Music.Second = load_music("alexander-nakarada-the-northern-path.mp3", 0.7)
|
|
|
|
}
|
2024-10-04 21:16:58 +03:00
|
|
|
|
|
|
|
main :: proc() {
|
2024-10-13 19:17:47 +03:00
|
|
|
// rl.SetConfigFlags(rl.ConfigFlags{.MSAA_4X_HINT, .FULLSCREEN_MODE, .VSYNC_HINT, .WINDOW_RESIZABLE})
|
|
|
|
rl.SetConfigFlags(rl.ConfigFlags{.VSYNC_HINT, .WINDOW_RESIZABLE})
|
2024-10-06 10:59:07 +03:00
|
|
|
|
2024-10-13 19:17:47 +03:00
|
|
|
rl.InitWindow(800, 600, "Ragnarøkkr")
|
2024-10-05 20:44:32 +03:00
|
|
|
rl.InitAudioDevice()
|
2024-10-13 19:17:47 +03:00
|
|
|
rl.SetWindowMinSize(800, 600)
|
2024-10-04 21:16:58 +03:00
|
|
|
|
2024-10-06 10:59:07 +03:00
|
|
|
rl.HideCursor()
|
|
|
|
Cursor = rl.LoadTexture("./assets/gfx/crosshair.png")
|
2024-10-05 20:44:32 +03:00
|
|
|
load_resources()
|
2024-10-04 21:16:58 +03:00
|
|
|
|
2024-10-05 20:44:32 +03:00
|
|
|
WSizei = {rl.GetScreenWidth(), rl.GetScreenHeight()}
|
|
|
|
WSize = {f32(WSizei.x), f32(WSizei.y)}
|
2024-10-04 21:16:58 +03:00
|
|
|
|
|
|
|
game := game_init()
|
|
|
|
stack_push(game)
|
|
|
|
menu := menu_init(game)
|
|
|
|
stack_push(menu)
|
|
|
|
|
|
|
|
for !WindowShouldExit {
|
|
|
|
if rl.IsWindowResized() {
|
|
|
|
WSizei = {rl.GetScreenWidth(), rl.GetScreenHeight()}
|
|
|
|
WSize = {f32(WSizei.x), f32(WSizei.y)}
|
|
|
|
}
|
|
|
|
|
2024-10-05 20:44:32 +03:00
|
|
|
rl.UpdateMusicStream(current_music)
|
|
|
|
|
2024-10-04 21:16:58 +03:00
|
|
|
state := stack_top()
|
|
|
|
delta := rl.GetFrameTime()
|
|
|
|
timers_process(delta)
|
|
|
|
tweens_process(delta)
|
|
|
|
state->update(delta)
|
|
|
|
|
|
|
|
rl.BeginDrawing()
|
|
|
|
rl.ClearBackground(rl.SKYBLUE)
|
|
|
|
state->draw()
|
2024-10-05 20:44:32 +03:00
|
|
|
|
|
|
|
rl.DrawRectangleV({}, WSize, rl.Color{0, 0, 0, u8(Overlay_Opacity * 255)})
|
2024-10-06 10:59:07 +03:00
|
|
|
pos := rl.GetMousePosition()
|
|
|
|
rl.DrawTextureEx(Cursor, pos - {16, 16} * 3, 0, 3, rl.WHITE)
|
2024-10-04 21:16:58 +03:00
|
|
|
rl.EndDrawing()
|
|
|
|
}
|
2024-10-05 20:44:32 +03:00
|
|
|
}
|
2024-10-13 19:17:47 +03:00
|
|
|
|
|
|
|
Fullscreen := false
|
|
|
|
|
|
|
|
toggle_fullscreen :: proc() {
|
|
|
|
monitor := rl.GetCurrentMonitor()
|
|
|
|
rl.ToggleBorderlessWindowed()
|
2024-10-13 19:23:20 +03:00
|
|
|
WSizei = {rl.GetScreenWidth(), rl.GetScreenHeight()}
|
|
|
|
WSize = {f32(WSizei.x), f32(WSizei.y)}
|
2024-10-13 19:17:47 +03:00
|
|
|
Fullscreen = !Fullscreen
|
|
|
|
|
|
|
|
|
|
|
|
// rl.ToggleFullscreen()
|
|
|
|
}
|