Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@
# Cheers!
# -andrewrk

SDL2_image-devel-2.6.2-VC/
SDL2-devel-2.26.1-VC/
SDL2*/
zig-cache/
zig-out/
/release/
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ Aside from zig (obviously), you need both SDL2 and SDL_Image development release

1. Download the sdl development release SDL2-devel-2.26.1-VC and unzip in the main directory of this repo. [releases](https://github.com/libsdl-org/SDL/releases/tag/release-2.26.1)
2. Download the sdl2 image development release SDL2_image-devel-2.6.2-VC and unzip in the main directory of this repo. [releases](https://github.com/libsdl-org/SDL_image/releases/tag/release-2.6.2)
3. Run `zig build -Dnative=true` this builds a native executable that can be found in the `zig-out/bin` directory
4. Run `./game1.exe` and let the fun begin.
3. Download the sdl2 mixer development release SDL2_mixer-devel-2.6.2-VC and unzip in the main directory of this repo. [releases](https://github.com/libsdl-org/SDL_mixer/releases/tag/release-2.6.2)
4. Run `zig build -Dnative=true` this builds a native executable that can be found in the `zig-out/bin` directory
5. Run `./game1.exe` and let the fun begin.

### WASM

Expand Down Expand Up @@ -117,11 +118,12 @@ mset(x, y, v) -- set map value

#### Audio

##### Not Yet Implemented

##### Partially Implemented

```
music([n, [fade_len, [channel_mask]]]) -- play music; n = -1: stop
sfx(n, [channel, [offset]]) -- play sfx; n = -1: stop in channel; n = -2: release loop in channel
sfx(n) -- WASM only: play sfx N; sfx files are expected to be in .wav format in the resources folder, named numerically, (0.wav, 1.wav, etc). SFX files will play once, and if the same SFX file is called before the first completes, it will terminate the first preemptively.
music([n, [fade_len, [channel_mask]]]) -- WASM only: play "n" pattern music; n = -1: stop. fade_len will fade-in the music over fade_len milliseconds. channel_mask is not currently used. Music files are expected to be in mp3 format in the resources folder, named numerically (0.mp3, 1.mp3, etc).
```

## Current Status
Expand Down
10 changes: 10 additions & 0 deletions build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ pub fn build(b: *std.build.Builder) void {

if (build_native) {
const installSprites = b.addInstallFile(.{ .path = "assets/sprites.png" }, "bin/sprites.png");
const installMusic = b.addInstallFile(.{ .path = "assets/0.mp3" }, "bin/0.mp3");
const installSfx = b.addInstallFile(.{ .path = "assets/0.wav" }, "bin/0.wav");

// Standard release options allow the person running `zig build` to select
// between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall.
Expand All @@ -18,21 +20,29 @@ pub fn build(b: *std.build.Builder) void {
exe.addIncludePath("SDL2-devel-2.26.1-VC/SDL2-2.26.1/include");
exe.addLibraryPath("SDL2_image-devel-2.6.2-VC/SDL2_image-2.6.2/lib/x64");
exe.addIncludePath("SDL2_image-devel-2.6.2-VC/SDL2_image-2.6.2/include");
exe.addLibraryPath("SDL2_mixer-devel-2.6.2-VC/SDL2_mixer-2.6.2/lib/x64");
exe.addIncludePath("SDL2_mixer-devel-2.6.2-VC/SDL2_mixer-2.6.2/include");

const installSDLMixerDLL = b.addInstallFile(.{ .path = "SDL2_mixer-devel-2.6.2-VC/SDL2_mixer-2.6.2/lib/x64/SDL2_mixer.dll" }, "bin/SDL2_mixer.dll");
const installSDLImageDLL = b.addInstallFile(.{ .path = "SDL2_image-devel-2.6.2-VC/SDL2_image-2.6.2/lib/x64/SDL2_image.dll" }, "bin/SDL2_image.dll");
const installSDLDLL = b.addInstallFile(.{ .path = "SDL2-devel-2.26.1-VC/SDL2-2.26.1/lib/x64/SDL2.dll" }, "bin/SDL2.dll");

exe.linkLibC();
exe.linkSystemLibraryName("SDL2");
exe.linkSystemLibraryName("SDL2_image");
exe.linkSystemLibraryName("SDL2_mixer");

exe.setTarget(target);
exe.setBuildMode(mode);

exe.install();


exe.step.dependOn(&installSDLMixerDLL.step);
exe.step.dependOn(&installSDLImageDLL.step);
exe.step.dependOn(&installSDLDLL.step);
exe.step.dependOn(&installMusic.step);
exe.step.dependOn(&installSfx.step);
exe.step.dependOn(&installSprites.step);
}

Expand Down
52 changes: 52 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<body>
<p>The buttons are a, s and the arrow keys.</p>
<canvas id="canvas" width="512" height="512"></canvas>
<div id="music"></div>
<div id="sfx"></div>
<script>
class FPSCounter {
init() {
Expand Down Expand Up @@ -36,6 +38,9 @@
ctx.imageSmoothingEnabled = false;
ctx.scale(4, 4);

const music = document.getElementById("music");
const sfx = document.getElementById("sfx");

const img = await new Promise((resolve) => {
const img = new Image(); // Create new img element
img.src = "assets/sprites.png"; // Set source path
Expand All @@ -59,6 +64,53 @@
// Don't draw the image if its off screen.
ctx.drawImage(img, sx, sy, sw, sh, dx, dy, dw, dh);
},
wasmMusic: (track, fadems, channelMask) => {
console.log("Trying to play audio file with fadems and channelmask", track, fadems,channelMask);
if(track == -1) {
while (music.firstChild) {
music.removeChild(music.firstChild);
}
return;
}

const channel = "music-" + track;
const existingTrack = document.getElementById(channel);
if(existingTrack) {
existingTrack.remove();
}
const newTrack = new Audio("assets/"+track+".mp3");
const newChannel = music.appendChild(newTrack);
newChannel.id = channel;
newTrack.play();
newTrack.loop = true;

//Fade-in volume if appropriate
if (fadems != 0) {
newTrack.volume = 0;
var fAudio = setInterval(function(){
const newVolume = newTrack.volume + 0.1;
if(newVolume >= 1) {
newTrack.volume = 1;
clearInterval(fAudio);
} else {
newTrack.volume = newVolume;
}
},fadems/10);
}
},
wasmSfx: (track) => {
console.log("Trying to play sfx ", track);
const channel = "sfx-" + track;
const existingTrack = document.getElementById(channel);
if(existingTrack) {
existingTrack.remove();
}
const newTrack = new Audio("assets/"+track+".wav");
const newChannel = sfx.appendChild(newTrack);
newChannel.id = channel;
newTrack.loop = false;
newTrack.play();
}
},
};
fetch("zig-out/lib/wasm.wasm")
Expand Down
24 changes: 24 additions & 0 deletions src/api_sdl.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const sdl = @cImport(@cInclude("SDL.h"));
const sdl_image = @cImport(@cInclude("SDL_image.h"));
const sdl_mixer = @cImport(@cInclude("SDL_mixer.h"));

const math = std.math;

Expand Down Expand Up @@ -36,6 +37,8 @@ pub const ApiSDL = struct {
camera_x: f32 = 0.0,
camera_y: f32 = 0.0,
map_data: [4 * 256 * 256]u8 = [_]u8{0} ** (4 * 256 * 256),
playing_music: bool = false,
playing_sfx: bool = false,

pub fn init(renderer: *sdl.SDL_Renderer, texture: *sdl.SDL_Texture) ApiSDL {
return .{ .renderer = renderer, .texture = texture };
Expand All @@ -53,6 +56,27 @@ pub const ApiSDL = struct {
_ = sdl.SDL_RenderCopy(self.renderer, self.texture, &src, &dest);
}

pub fn music(self: *ApiSDL, audio: u32, fadems: u32, channelMask: u32) void {
self.playing_music = true;
var mus = sdl_mixer.Mix_LoadMUS("0.mp3");
_ = sdl_mixer.Mix_PlayMusic(mus, 1);

//Not implemented yet
_ = audio;
_ = fadems;
_ = channelMask;
}

pub fn sfx(self: *ApiSDL, audio: u32) void {
self.playing_sfx = true;

var sound = sdl_mixer.Mix_LoadWAV("0.wav");
_ = sdl_mixer.Mix_PlayChannel(-1, sound, 0);

//Not implemented yet
_ = audio;
}

pub fn btnp(self: ApiSDL, button: Button) bool {
return switch (button) {
Button.LEFT => self.input_state.left_pressed,
Expand Down
14 changes: 14 additions & 0 deletions src/api_wasm.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const Button = @import("api_modules.zig").Button;

// Javascript link
extern fn wasmSprite(f32, f32, f32, f32, f32, f32, f32, f32) void;
extern fn wasmMusic(u32, u32, u32) void;
extern fn wasmSfx(u32) void;

pub const InputState = struct {
left_down: bool = false,
Expand Down Expand Up @@ -35,6 +37,8 @@ pub const ApiWASM = struct {
camera_y: f32 = 0,
map_data: [4 * 256 * 256]u8 = [_]u8{0} ** (4 * 256 * 256),
input_state: InputState = .{},
playing_music: bool = false,
playing_sfx: bool = false,

pub fn init() ApiWASM {
return .{};
Expand All @@ -49,6 +53,16 @@ pub const ApiWASM = struct {
wasmSprite(tx, ty, w, h, src_x, src_y, 8, 8);
}

pub fn music(self: *ApiWASM, audio: u32, fadems: u32, channelMask: u32) void {
self.playing_music = true;
wasmMusic(audio, fadems, channelMask);
}

pub fn sfx(self: *ApiWASM, audio: u32) void {
self.playing_sfx = true;
wasmSfx(audio);
}

pub fn btnp(self: ApiWASM, button: Button) bool {
return switch (button) {
Button.LEFT => self.input_state.left_pressed,
Expand Down
12 changes: 10 additions & 2 deletions src/game.zig
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const RndGen = std.rand.DefaultPrng;

const Object = struct { x: f32 = 0, y: f32 = 0, spr: u32 = 4, draw: bool = true };

const NUM_OBJECTS = 5000;
const NUM_OBJECTS = 50;

fn makeObject() Object {
return Object{ .x = 0.0, .y = 0.0, .spr = 4, .draw = true };
Expand Down Expand Up @@ -140,6 +140,11 @@ pub const Game = struct {
dy = -1.0;
}

if (api.btnp(ApiTypes.Button.A)) {
//The user needs to interact with the game before the browser will allow any music to play;
api.music(0, 5000, 0);
}

// Our game objects are really 7x7 so they can fit into the cracks of the tile.
self.worldMove(api, self.x, self.y, 7.0, 7.0, &dx, &dy);

Expand All @@ -164,7 +169,10 @@ pub const Game = struct {

if (boxIntersect(self.x, self.y, 8.0, 8.0, o.*.x, o.*.y, 8.0, 8.0)) {
o.*.spr = 5;
o.*.draw = false;
if(o.*.draw) {
api.sfx(0);
o.*.draw = false;
}
}
}

Expand Down
3 changes: 3 additions & 0 deletions src/main_sdl.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const std = @import("std");
const sdl = @cImport(@cInclude("SDL.h"));
const sdl_image = @cImport(@cInclude("SDL_image.h"));
const sdl_mixer = @cImport(@cInclude("SDL_mixer.h"));

const Api = @import("api_sdl.zig");
const Game = @import("game.zig").Game;
Expand Down Expand Up @@ -47,6 +48,8 @@ pub fn main() !void {
const img = @ptrCast(?*sdl.SDL_Texture, sdl_image.IMG_LoadTexture(image_renderer, "sprites.png"));
defer sdl.SDL_DestroyTexture(img);

_ = sdl_mixer.Mix_OpenAudio(22050,sdl_mixer.AUDIO_S16SYS,2,640);

var api = Api.ApiSDL.init(renderer.?, img.?);
var game = Game.init(&api);

Expand Down