Compare commits

..

1 Commits

Author SHA1 Message Date
Cadey Ratio 2ebc85fc68 try getting a map type working
Signed-off-by: Xe Iaso <me@christine.website>
2022-07-01 23:26:55 -04:00
12 changed files with 838 additions and 1082 deletions

View File

@ -5,17 +5,14 @@ fn mapgen(b: *std.build.Step) !void {
var alloc = std.heap.page_allocator;
const maps = [_][2][]const u8{
[2][]const u8{ "./maps/dungeon.json", "./src/maps/dungeon.zig" },
[2][]const u8{ "./maps/RPGmap.json", "./src/maps/overworld.zig" },
[2][]const u8{"./maps/dungeon.json", "./src/maps/dungeon.zig"},
[2][]const u8{"./maps/RPGmap.json", "./src/maps/overworld.zig"},
};
for (&maps) |map| {
var deno = std.ChildProcess.init(&.{ "deno", "run", "-A", "./src/tools/genmap.js", map[0], map[1] }, alloc);
var deno = std.ChildProcess.init(&.{"deno", "run", "-A", "./src/tools/genmap.js", map[0], map[1]}, alloc);
try deno.spawn();
_ = try deno.wait();
var zig = std.ChildProcess.init(&.{ "zig", "fmt", map[1] }, alloc);
try zig.spawn();
_ = try zig.wait();
std.log.info("generated map {s}", .{map[1]});
}
@ -25,7 +22,7 @@ fn release(b: *std.build.Step) !void {
_ = b;
var alloc = std.heap.page_allocator;
var rel = std.ChildProcess.init(&.{ "bash", "./release.sh" }, alloc);
var rel = std.ChildProcess.init(&.{"bash", "./release.sh"}, alloc);
try rel.spawn();
_ = try rel.wait();
@ -33,15 +30,16 @@ fn release(b: *std.build.Step) !void {
}
pub fn build(b: *std.build.Builder) !void {
const map_step = b.step("mapgen", "Generate maps from Tiled JSON");
const map_step = b.step("mapgen", "generate maps");
map_step.makeFn = mapgen;
const release_step = b.step("release", "Generate release binaries");
const release_step = b.step("release", "generate release binaries");
release_step.makeFn = release;
release_step.dependOn(map_step);
const mode = b.standardReleaseOptions();
const lib = b.addSharedLibrary("cart", "src/main.zig", .unversioned);
//lib.step.dependOn(map_step);
lib.setBuildMode(mode);
lib.setTarget(.{ .cpu_arch = .wasm32, .os_tag = .freestanding });

File diff suppressed because one or more lines are too long

View File

@ -1,104 +1,79 @@
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.4" tiledversion="1.4.3" orientation="orthogonal" renderorder="right-down" width="40" height="40" tilewidth="8" tileheight="8" infinite="0" nextlayerid="6" nextobjectid="39">
<editorsettings>
<export target="RPGmap.json" format="json"/>
</editorsettings>
<tileset firstgid="1" source="../sprites/kenney_rpg.tsx"/>
<layer id="1" name="map" width="40" height="40">
<data encoding="csv">
1,2,39,40,1,2,137,138,1,2,71,72,73,74,75,76,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
35,36,73,74,35,36,171,172,35,36,105,106,107,108,109,110,35,39,40,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
69,70,205,206,69,70,205,206,69,70,139,140,207,208,143,144,69,73,74,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,239,240,103,104,239,240,103,104,173,174,241,242,177,178,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
137,138,137,138,307,274,137,138,341,342,345,346,411,412,137,138,1,2,33,34,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
171,172,171,172,307,307,171,172,375,376,379,380,445,446,171,172,35,36,67,68,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
205,206,205,206,69,70,205,206,413,414,39,40,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
239,240,239,240,103,104,39,40,447,448,73,74,307,104,239,274,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
1,2,137,307,1,2,73,74,413,414,137,39,40,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
35,36,171,172,35,36,171,172,447,448,171,73,74,36,171,172,331,332,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
69,70,205,206,69,70,274,206,413,414,235,236,233,234,205,364,365,366,367,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,239,240,39,40,239,240,447,448,269,270,267,268,397,398,399,400,401,402,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
1,2,237,238,73,74,137,138,413,414,233,234,235,236,431,432,433,434,435,436,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
35,36,271,272,35,353,354,172,447,448,267,268,269,270,465,466,467,468,469,470,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
69,70,351,352,69,387,388,206,347,348,349,350,343,344,499,500,439,440,503,504,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,385,386,103,104,239,240,381,121,121,121,121,378,403,404,473,474,405,406,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
1,2,409,410,345,346,345,346,417,121,121,121,121,418,345,346,417,418,345,346,345,346,345,346,345,346,345,346,345,346,345,346,345,346,345,346,345,346,345,346,
35,36,443,444,379,380,379,380,451,452,451,452,451,452,379,380,451,452,379,380,379,380,379,380,379,380,379,380,379,380,379,380,379,380,379,380,379,380,379,380,
69,57,58,206,69,70,205,206,69,307,205,206,69,70,205,206,39,40,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
90,91,92,93,57,58,57,58,103,104,239,240,103,104,239,240,73,74,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
91,92,91,92,91,92,91,92,93,21,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
125,126,125,126,125,126,125,126,127,94,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
159,160,159,160,159,160,159,160,70,26,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,
1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,1,2,137,138,
35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,35,36,171,172,
69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,69,70,205,206,
103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240,103,104,239,240
</data>
</layer>
<objectgroup id="2" name="coll">
<object id="1" x="80.3013" y="-0.325766" width="47.399" height="16.4512"/>
<object id="6" x="127.863" y="70.3655" width="16.2883" height="9.44722"/>
<object id="16" x="146.182" y="32" width="11.4545" height="15.8182"/>
<object id="17" x="18" y="97.8182" width="11.8182" height="12.7273"/>
<object id="18" x="113.818" y="16.3636" width="12" height="13.4545"/>
<object id="19" x="81.2727" y="16.3636" width="13.0909" height="14.5455"/>
<object id="20" x="82.9091" y="85.2727" width="26" height="26.7273"/>
<object id="21" x="99.6364" y="80.9091" width="8.18182" height="4.54545"/>
<object id="22" x="112" y="94.1818" width="47.6364" height="17.2727"/>
<object id="23" x="120.727" y="86.9091" width="30.3636" height="7.27273"/>
<object id="24" x="127.636" y="80" width="16.3636" height="7.09091"/>
<object id="25" x="114.364" y="111.818" width="11.4545" height="12.5455"/>
<object id="26" x="145.091" y="111.273" width="12.1818" height="12.5455"/>
<object id="28" x="11.2727" y="146.182" width="8.90909" height="7.09091"/>
<object id="36" x="0.397535" y="153.846" width="61.2204" height="27.4299"/>
<object id="37" x="62.0155" y="162.194" width="8.34824" height="11.131"/>
</objectgroup>
<objectgroup id="3" name="act">
<object id="30" name="sign" x="16" y="96" width="16" height="20">
<properties>
<property name="dialogue" value="Kanar News\nThe mayor is\nacting weird today."/>
<property name="direction" value="Up"/>
</properties>
</object>
<object id="31" name="gravestone 1" x="82.64" y="103" width="7" height="16">
<properties>
<property name="dialogue" value="Ded."/>
<property name="direction" value="Up"/>
</properties>
</object>
<object id="32" name="gravestone 2" x="96.18" y="103.36" width="7" height="16">
<properties>
<property name="dialogue" value="Moar ded."/>
<property name="direction" value="Up"/>
</properties>
</object>
</objectgroup>
<objectgroup id="5" name="warps">
<object id="35" name="dungeon 1" x="96.4758" y="17.0705" width="14.978" height="10">
<properties>
<property name="warpTarget" type="int" value="1"/>
</properties>
</object>
<object id="38" name="house 1" x="128.801" y="112.9" width="14.7088" height="7.95071">
<properties>
<property name="warpTarget" type="int" value="2"/>
</properties>
</object>
</objectgroup>
<objectgroup id="4" name="spc">
<object id="33" name="mara_start" x="32" y="31" width="16" height="16"/>
</objectgroup>
</map>
<?xml version="1.0" encoding="UTF-8"?>
<map version="1.9" tiledversion="1.9.0" orientation="orthogonal" renderorder="right-down" width="20" height="20" tilewidth="8" tileheight="8" infinite="0" nextlayerid="6" nextobjectid="36">
<editorsettings>
<export target="RPGmap.json" format="json"/>
</editorsettings>
<tileset firstgid="1" source="../sprites/kenney_rpg.tsx"/>
<layer id="1" name="map" width="20" height="20">
<data encoding="csv">
1,2,39,40,1,2,137,138,1,2,71,72,73,74,75,76,1,2,137,138,
35,36,73,74,35,36,171,172,35,36,105,106,107,108,109,110,35,39,40,172,
69,70,205,206,69,70,205,206,69,70,139,140,207,208,143,144,69,73,74,206,
103,104,239,240,103,104,239,240,103,104,173,174,241,242,177,178,103,104,239,240,
137,138,137,138,307,274,137,138,341,342,345,346,411,412,137,138,1,2,33,34,
171,172,171,172,307,307,171,172,375,376,379,380,445,446,171,172,35,36,67,68,
205,206,205,206,69,70,205,206,413,414,39,40,69,70,205,206,69,70,205,206,
239,240,239,240,103,104,39,40,447,448,73,74,307,104,239,274,103,104,239,240,
1,2,137,307,1,2,73,74,413,414,137,39,40,2,137,138,1,2,137,138,
35,36,171,172,35,36,171,172,447,448,171,73,74,36,171,172,331,332,171,172,
69,70,205,206,69,70,274,206,413,414,235,236,233,234,205,364,365,366,367,206,
103,104,239,240,39,40,239,240,447,448,269,270,267,268,397,398,399,400,401,402,
1,2,237,238,73,74,137,138,413,414,233,234,235,236,431,432,433,434,435,436,
35,36,271,272,35,353,354,172,447,448,267,268,269,270,465,466,467,468,469,470,
69,70,351,352,69,387,388,206,347,348,349,350,343,344,499,500,439,440,503,504,
103,104,385,386,103,104,239,240,381,121,121,121,121,378,403,404,473,474,405,406,
1,2,409,410,345,346,345,346,417,121,121,121,121,418,345,346,417,418,345,346,
35,36,443,444,379,380,379,380,451,452,451,452,451,452,379,380,451,452,379,380,
69,57,58,206,69,70,205,206,69,307,205,206,69,70,205,206,39,40,205,206,
90,91,92,93,103,104,57,58,103,104,239,240,103,104,239,240,73,74,239,240
</data>
</layer>
<objectgroup id="2" name="coll">
<object id="1" x="80.3013" y="-0.325766" width="47.399" height="16.4512"/>
<object id="6" x="127.863" y="70.3655" width="16.2883" height="9.44722"/>
<object id="16" x="146.182" y="32" width="11.4545" height="15.8182"/>
<object id="17" x="18" y="97.8182" width="11.8182" height="12.7273"/>
<object id="18" x="113.818" y="16.3636" width="12" height="13.4545"/>
<object id="19" x="81.2727" y="16.3636" width="13.0909" height="14.5455"/>
<object id="20" x="82.9091" y="85.2727" width="26" height="26.7273"/>
<object id="21" x="99.6364" y="80.9091" width="8.18182" height="4.54545"/>
<object id="22" x="112" y="94.1818" width="47.6364" height="17.2727"/>
<object id="23" x="120.727" y="86.9091" width="30.3636" height="7.27273"/>
<object id="24" x="127.636" y="80" width="16.3636" height="7.09091"/>
<object id="25" x="114.364" y="111.818" width="11.4545" height="12.5455"/>
<object id="26" x="145.091" y="111.273" width="12.1818" height="12.5455"/>
<object id="27" x="0.363636" y="153.273" width="31.0909" height="6.54545"/>
<object id="28" x="11.2727" y="146.182" width="8.90909" height="7.09091"/>
<object id="29" x="51.8182" y="154" width="8" height="5.81818"/>
</objectgroup>
<objectgroup id="3" name="act">
<object id="30" name="sign" x="16" y="96" width="16" height="20">
<properties>
<property name="dialogue" value="18 chars per line\nallowed. Or else!"/>
<property name="direction" value="Up"/>
</properties>
</object>
<object id="31" name="gravestone 1" x="82.64" y="103" width="7" height="16">
<properties>
<property name="dialogue" value="Ded."/>
<property name="direction" value="Up"/>
</properties>
</object>
<object id="32" name="gravestone 2" x="96.18" y="103.36" width="7" height="16">
<properties>
<property name="dialogue" value="Moar ded."/>
<property name="direction" value="Up"/>
</properties>
</object>
</objectgroup>
<objectgroup id="5" name="warps">
<object id="35" name="dungeon 1" x="96.4758" y="17.0705" width="14.978" height="10">
<properties>
<property name="warpTarget" type="int" value="1"/>
</properties>
</object>
</objectgroup>
<objectgroup id="4" name="spc">
<object id="33" name="mara_start" x="32" y="32" width="16" height="16"/>
</objectgroup>
</map>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 B

After

Width:  |  Height:  |  Size: 326 B

View File

@ -3,7 +3,6 @@ const sh0rk = @import("./sh0rk.zig");
const sprites = @import("./sprites.zig");
const palette = @import("./palette.zig");
const tframe = @import("./tframe.zig");
const overhead = @import("./overhead.zig");
const std = @import("std");
const fmt = std.fmt;
@ -12,40 +11,29 @@ const Direction = sh0rk.Direction;
const Point = sh0rk.Point;
const Rect = sh0rk.Rect;
const map = @import("./maps/overworld.zig");
const map = @import("./maps/overworld.zig").map;
var frame_count: u32 = 0;
var mara_direction: Direction = Direction.Right;
var mara_frame: bool = false;
var mara_box: Rect = Rect{ .base = map.start_point, .width = 16, .height = 16 };
var mara_speed: i16 = 0;
var old_speed: i16 = 0;
var mara_box: Rect = Rect{.base = map.start, .width = 16, .height = 16};
var mara_speed: u16 = 0;
var screen = Rect{.base = Point{.x = 0, .y = 0}, .width = 160, .height = 160};
const screen_width = 20;
const screen_height = 20;
const tile_size: i16 = 8;
var sound_timer: u8 = 0;
var textBuf: [160]u8 = undefined;
var done: bool = false;
var camera = Point{ .x = 0, .y = 0 };
var camera: [400]u9 = []u9{} ** 400;
fn world_to_screen(p: Point) Point {
return p.sub(camera);
}
fn screen_to_world(p: Point) Point {
p.add(camera);
}
var state: sh0rk.State = .Gameplay;
export fn start() void {
if (sh0rk.state == .Gameplay) {
palette.mist();
} else {
palette.tamtam();
}
palette.mist();
}
fn bonk() void {
@ -54,7 +42,7 @@ fn bonk() void {
}
w4.tone(
w4.Tone.Frequency{ .start = 220, .end = 40 },
w4.Tone.Frequency{.start = 220, .end = 40},
w4.Tone.Duration{
.attack = 0,
.decay = 0,
@ -71,154 +59,166 @@ fn bonk() void {
},
);
sound_timer = 30;
}
fn map_colors() void {
switch (map.tileset) {
.Dungeon => {
w4.m.colors.* = .{
._0 = .p2,
._1 = .p0,
._2 = .p1,
._3 = .p3,
};
},
.Rpg => {
w4.m.colors.* = .{
._0 = .p3,
._1 = .p2,
._2 = .p1,
._3 = .p0,
};
},
}
}
fn clampCamera() void {
if (camera.x < 0) {
camera.x = 0;
}
if (camera.y < 0) {
camera.y = 0;
}
if (camera.x >= (map.width * 8) - screen_width * 8) {
camera.x = (map.width * 8) - screen_width * 8;
}
if (camera.y >= (map.height * 8) - screen_height * 8) {
camera.y = (map.height * 8) - screen_height * 8;
}
sound_timer = 12;
}
fn drawMap() !void {
map_colors();
w4.m.colors.* = .{
._0 = .p3,
._1 = .p2,
._2 = .p1,
._3 = .p0,
};
var startCol = @divTrunc(camera.x, tile_size);
var endCol = startCol + screen_width;
var startRow = @divTrunc(camera.y, tile_size);
var endRow = startRow + screen_height;
var col: i16 = startCol;
while (col < endCol + 1) {
var row: i16 = startRow;
var col: u32 = 0;
while (col < screen_width) {
var row: u32 = 0;
defer col += 1;
while (row < endRow + 1) {
while (row < screen_height) {
defer row += 1;
if (col < map.width and row < map.height) {
var tile = map.get_tile(col, row);
var world = Point{ .x = col * 8, .y = row * 8 };
var scr = world_to_screen(world);
// if(!done) {
// var buf = fmt.bufPrint(&textBuf, "{},{}: {},{}", .{ row, col, scr.x, scr.y }) catch unreachable;
// w4.trace(buf);
// }
var tile = map.tiles[col * map.width + row];
var tileX = tile % map.tileset.width();
var tileY = tile / map.tileset.height();
draw_tile(tile, scr.x, scr.y);
if (!done) {
var buf = fmt.bufPrint(&textBuf, "{},{}: {}: {},{}", .{col, row, tile, tileX, tileY}) catch unreachable;
w4.trace(buf);
}
w4.blitSub(
&sprites.kenney_rpg,
row * 8,
col * 8,
8,
8,
@intCast(u32, tileX) * 8,
@intCast(u32, tileY) * 8,
sprites.kenney_rpg_width,
w4.BlitFlags{.two_bits = true},
);
}
}
}
fn draw_tile(tile: u32, x: i32, y: i32) void {
if (tile == 0) {
w4.rect(x, y, 8, 8);
return;
}
var tileX = (tile - 1) % map.ts_width;
var tileY = (tile - 1) / map.ts_width;
switch (map.tileset) {
.Rpg => w4.blitSub(
&sprites.kenney_rpg,
x,
y,
8,
8,
tileX * 8,
tileY * 8,
sprites.kenney_rpg_width,
w4.BlitFlags{ .two_bits = true },
),
.Dungeon => w4.blitSub(
&sprites.dungeon,
x,
y,
8,
8,
tileX * 8,
tileY * 8,
sprites.dungeon_width,
w4.BlitFlags{ .two_bits = true },
),
}
}
fn move_mara(gamepad: w4.GamePad) void {
if (mara_speed > 0) {
mara_speed -= 1;
}
if (gamepad.up) {
mara_direction = Direction.Up;
mara_speed = 1;
camera.y -= mara_speed;
mara_box.base.y -= mara_speed;
} else if (gamepad.down) {
mara_direction = Direction.Down;
mara_speed = 1;
camera.y += mara_speed;
mara_box.base.y += mara_speed;
} else if (gamepad.left) {
mara_direction = Direction.Left;
mara_speed = 1;
camera.x -= mara_speed;
mara_box.base.x -= mara_speed;
} else if (gamepad.right) {
mara_direction = Direction.Right;
mara_speed = 1;
camera.x += mara_speed;
mara_box.base.x += mara_speed;
}
switch (mara_direction) {
.Up => {
mara_box.base.y -= mara_speed;
},
.Down => {
mara_box.base.y += mara_speed;
},
.Left => {
mara_box.base.x -= mara_speed;
},
.Right => {
mara_box.base.x += mara_speed;
},
}
}
export fn update() void {
defer frame_count += 1;
if (frame_count % 60 == 0) {
done = false;
fn title() !void {
w4.m.colors._0 = .p3;
w4.m.colors._1 = .p0;
w4.text("Mara 2:\nTamamo's Fury", 28, 8);
w4.text("Press z or x", 32, 136);
w4.text("From Within 2022", 16, 152);
w4.m.colors._0 = .p0;
w4.m.colors._1 = .p1;
w4.m.colors._2 = .p2;
w4.m.colors._3 = .p3;
w4.blit(&sprites.tamamotitle, 48, 60, sprites.tamamotitle_width, sprites.tamamotitle_height, w4.BlitFlags{.two_bits = true});
const gamepad = w4.m.gamepads[0];
if (gamepad.a or gamepad.b) {
state = .StoryDump;
}
}
const story = "After defeating\nthe evil mage,\nMalto was at\npeace.\n\nOne day Mara was\nwalking along the\nbeach when she saw\nthe killing stone\nwas split in two.\nTamamo-no-Mae was\nfree to wreak havoc\nacross the land.\n\nHelp us again Mara!\nSave Kanar from\nTamamo-no-Mae!\n\nPress x.";
var story_idx: usize = 0;
var story_counter: u8 = 4;
fn storydump() !void {
w4.m.colors._0 = .p3;
w4.m.colors._1 = .p0;
w4.text(story[0..story_idx], 4, 4);
const gamepad = w4.m.gamepads[0];
if (gamepad.b) {
state = .Gameplay;
palette.mist();
}
switch (sh0rk.state) {
.Title => overhead.title() catch unreachable,
.StoryDump => overhead.storydump() catch unreachable,
if (story_idx < story.len) {
story_counter -= 1;
if (gamepad.a) {
story_counter = 0;
}
if (story_counter == 0) {
story_idx += 1;
story_counter = 4;
w4.tone(
w4.Tone.Frequency{.start = 280, .end = 310},
w4.Tone.Duration{
.attack = 0,
.decay = 0,
.sustain = 2,
.release = 0,
},
w4.Tone.Volume{
.sustain = 100,
.attack = 100,
},
w4.Tone.Flags{
.channel = .triangle,
.pulse_duty = .@"1/4",
},
);
}
} else {
if (gamepad.a) {
state = .Gameplay;
palette.mist();
}
}
}
export fn update() void {
switch (state) {
.Title => title() catch unreachable,
.StoryDump => storydump() catch unreachable,
.Gameplay => gameplay() catch unreachable,
}
}
fn gameplay() !void {
defer done = true;
defer clampCamera();
if (sound_timer != 0) {
sound_timer -= 1;
}
@ -226,11 +226,12 @@ fn gameplay() !void {
drawMap() catch unreachable;
const gamepad = w4.m.gamepads[0];
const old_speed = mara_speed;
if (!tframe.enabled) {
move_mara(gamepad);
} else {
tframe.update(gamepad);
tframe.update(gamepad);
}
for (map.coll) |box| {
@ -263,33 +264,29 @@ fn gameplay() !void {
if (mara_box.base.x < 0) {
mara_box.base.x = 0;
bonk();
} else if (mara_box.base.x > 160 - mara_box.width) {
mara_box.base.x = 160 - mara_box.width;
bonk();
}
if (mara_box.base.y < 0) {
mara_box.base.y = 0;
bonk();
} else if (mara_box.base.y > 160 - mara_box.height) {
mara_box.base.y = 160 - mara_box.height;
bonk();
}
draw_mara();
}
fn draw_glaceon(p: Point) void {
palette.mist();
w4.m.colors.* = .{
._0 = .p0,
._1 = .p1,
._2 = .p3,
._3 = .transparent,
};
w4.blit(&sprites.glaceon, p.x, p.y, sprites.glaceon_width, sprites.glaceon_height, w4.BlitFlags{ .two_bits = true });
}
fn draw_mara() void {
var flags: w4.BlitFlags = w4.BlitFlags{
var flags: w4.BlitFlags = w4.BlitFlags {
.two_bits = true,
};
// w4.m.colors._0 = .p0;
// w4.m.colors._1 = .p1;
// w4.m.colors._2 = .p3;
// w4.m.colors._3 = .transparent;
// w4.blit(&sprites.glaceon, 0, 0, sprites.glaceon_width, sprites.glaceon_height, flags);
w4.m.colors.* = .{
._0 = .transparent,
._1 = .p0,
@ -301,7 +298,11 @@ fn draw_mara() void {
flags.flip_x = true;
}
if (frame_count % 16 == 0 and mara_speed > 0) {
if (frame_count % 15 == 0 and mara_speed > 0) {
mara_frame = !mara_frame;
}
if (old_speed != mara_speed) {
mara_frame = !mara_frame;
}
@ -311,26 +312,10 @@ fn draw_mara() void {
.Up => 2,
.Down => 0,
};
var step: u32 = if (mara_frame) 1 else 0;
var step: u32 = if (mara_frame) 1 else 0;
var scr = world_to_screen(mara_box.base);
w4.blitSub(&sprites.Mara, @intCast(u32, mara_box.base.x), @intCast(u32, mara_box.base.y), 16, 16, 16 * (frame + step), 0, 96, flags);
w4.blitSub(
&sprites.Mara,
scr.x,
scr.y,
16,
16,
16 * (frame + step),
0,
96,
flags,
);
frame_count += 1;
}
pub fn panic(msg: []const u8, st: ?*std.builtin.StackTrace) noreturn {
_ = st;
w4.trace("!!! PANIC !!!");
w4.trace(msg);
unreachable;
}

View File

@ -7,70 +7,69 @@ const Tileset = sh0rk.Tileset;
const Trigger = sh0rk.Trigger;
const Rect = sh0rk.Rect;
pub const width = 20;
pub const height = 20;
pub fn get_tile(x: i32, y: i32) u9 {
if (x < 0 or y < 0) {
return 0;
}
if (x >= width or y >= height) {
return 0;
}
return data[@intCast(u32, y) * width + @intCast(u32, x)];
}
pub const tileset: Tileset = .Dungeon;
pub const ts_width = 14;
pub const ts_height = 13;
pub const data = [400]u9{
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 58, 59, 71, 59, 18, 59,
18, 15, 16, 17, 59, 76, 43, 43, 43, 43, 43,
43, 43, 43, 72, 79, 32, 73, 32, 73, 32, 29,
30, 31, 57, 90, 43, 43, 43, 43, 43, 43, 43,
43, 105, 106, 105, 106, 105, 106, 105, 106, 105, 106,
105, 106, 43, 43, 43, 43, 43, 43, 43, 43, 117,
118, 117, 118, 117, 118, 117, 118, 117, 118, 117, 118,
43, 43, 43, 43, 43, 43, 43, 43, 131, 132, 103,
104, 103, 104, 103, 104, 103, 104, 103, 104, 43, 43,
43, 43, 43, 43, 43, 43, 145, 146, 117, 118, 117,
118, 117, 118, 117, 118, 117, 118, 43, 43, 43, 43,
43, 43, 43, 43, 105, 106, 103, 104, 103, 104, 103,
104, 103, 104, 103, 104, 43, 43, 43, 43, 43, 43,
43, 43, 117, 118, 117, 118, 117, 118, 117, 118, 117,
118, 137, 138, 43, 43, 43, 43, 43, 43, 43, 43,
103, 104, 103, 104, 103, 104, 103, 104, 103, 104, 151,
152, 43, 43, 43, 43, 43, 43, 43, 43, 117, 118,
117, 118, 117, 118, 117, 118, 117, 118, 117, 118, 43,
43, 43, 43, 43, 43, 43, 43, 93, 94, 121, 94,
121, 94, 121, 94, 121, 94, 121, 94, 43, 43, 43,
43, 43, 43, 43, 43, 107, 108, 108, 108, 108, 108,
108, 108, 108, 108, 108, 108, 43, 43, 43, 43, 43,
43, 43, 43, 123, 122, 123, 122, 123, 122, 123, 122,
123, 122, 122, 123, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43,
pub const data = [_]u9{
42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 57, 58, 70, 58, 17, 58, 17,
14, 15, 16, 58, 75, 42, 42, 42, 42, 42,
42, 42, 42, 71, 78, 31, 72, 31, 72, 31,
28, 29, 30, 56, 89, 42, 42, 42, 42, 42,
42, 42, 42, 104, 105, 104, 105, 104, 105, 104,
105, 104, 105, 104, 105, 42, 42, 42, 42, 42,
42, 42, 42, 116, 117, 116, 117, 116, 117, 116,
117, 116, 117, 116, 117, 42, 42, 42, 42, 42,
42, 42, 42, 130, 131, 102, 103, 102, 103, 102,
103, 102, 103, 102, 103, 42, 42, 42, 42, 42,
42, 42, 42, 144, 145, 116, 117, 116, 117, 116,
117, 116, 117, 116, 117, 42, 42, 42, 42, 42,
42, 42, 42, 104, 105, 102, 103, 102, 103, 102,
103, 102, 103, 102, 103, 42, 42, 42, 42, 42,
42, 42, 42, 116, 117, 116, 117, 116, 117, 116,
117, 116, 117, 136, 137, 42, 42, 42, 42, 42,
42, 42, 42, 102, 103, 102, 103, 102, 103, 102,
103, 102, 103, 150, 151, 42, 42, 42, 42, 42,
42, 42, 42, 116, 117, 116, 117, 116, 117, 116,
117, 116, 117, 116, 117, 42, 42, 42, 42, 42,
42, 42, 42, 92, 93, 120, 93, 120, 93, 120,
93, 120, 93, 120, 93, 42, 42, 42, 42, 42,
42, 42, 42, 106, 107, 107, 107, 107, 107, 107,
107, 107, 107, 107, 107, 42, 42, 42, 42, 42,
42, 42, 42, 122, 121, 122, 121, 122, 121, 122,
121, 122, 121, 121, 122, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42, 42,
};
pub const coll = [_]Rect{
Rect{ .base = Point{ .x = 0, .y = 0 }, .width = 159, .height = 54 },
Rect{ .base = Point{ .x = 0, .y = 55 }, .width = 31, .height = 104 },
Rect{ .base = Point{ .x = 32, .y = 121 }, .width = 95, .height = 39 },
Rect{ .base = Point{ .x = 127, .y = 55 }, .width = 32, .height = 105 },
Rect{ .base = Point{ .x = 112, .y = 98 }, .width = 15, .height = 14 },
Rect{.base = Point{.x = 0, .y = 0}, .width = 159, .height = 54},
Rect{.base = Point{.x = 0, .y = 55}, .width = 31, .height = 104},
Rect{.base = Point{.x = 32, .y = 121}, .width = 95, .height = 39},
Rect{.base = Point{.x = 127, .y = 55}, .width = 32, .height = 105},
Rect{.base = Point{.x = 112, .y = 98}, .width = 15, .height = 14},
};
pub const start_point = Point{ .x = 40, .y = 73 };
pub const triggers = [_]Trigger{
};
pub const triggers = [_]Trigger{};
pub const map = sh0rk.Map{
.width = 20,
.height = 20,
.tileset = .Dungeon,
.tiles = data[0..data.len],
.coll = coll[0..coll.len],
.triggers = triggers[0..triggers.len],
.start = Point{ .x = 40, .y = 73 },
};

View File

@ -7,194 +7,83 @@ const Tileset = sh0rk.Tileset;
const Trigger = sh0rk.Trigger;
const Rect = sh0rk.Rect;
pub const width = 40;
pub const height = 40;
pub fn get_tile(x: i32, y: i32) u9 {
if (x < 0 or y < 0) {
return 0;
}
if (x >= width or y >= height) {
return 0;
}
return data[@intCast(u32, y) * width + @intCast(u32, x)];
}
pub const tileset: Tileset = .Rpg;
pub const ts_width = 34;
pub const ts_height = 16;
pub const data = [1600]u9{
1, 2, 39, 40, 1, 2, 137, 138, 1, 2, 71,
72, 73, 74, 75, 76, 1, 2, 137, 138, 1, 2,
137, 138, 1, 2, 137, 138, 1, 2, 137, 138, 1,
2, 137, 138, 1, 2, 137, 138, 35, 36, 73, 74,
35, 36, 171, 172, 35, 36, 105, 106, 107, 108, 109,
110, 35, 39, 40, 172, 35, 36, 171, 172, 35, 36,
171, 172, 35, 36, 171, 172, 35, 36, 171, 172, 35,
36, 171, 172, 69, 70, 205, 206, 69, 70, 205, 206,
69, 70, 139, 140, 207, 208, 143, 144, 69, 73, 74,
206, 69, 70, 205, 206, 69, 70, 205, 206, 69, 70,
205, 206, 69, 70, 205, 206, 69, 70, 205, 206, 103,
104, 239, 240, 103, 104, 239, 240, 103, 104, 173, 174,
241, 242, 177, 178, 103, 104, 239, 240, 103, 104, 239,
240, 103, 104, 239, 240, 103, 104, 239, 240, 103, 104,
239, 240, 103, 104, 239, 240, 137, 138, 137, 138, 307,
274, 137, 138, 341, 342, 345, 346, 411, 412, 137, 138,
1, 2, 33, 34, 1, 2, 137, 138, 1, 2, 137,
138, 1, 2, 137, 138, 1, 2, 137, 138, 1, 2,
137, 138, 171, 172, 171, 172, 307, 307, 171, 172, 375,
376, 379, 380, 445, 446, 171, 172, 35, 36, 67, 68,
35, 36, 171, 172, 35, 36, 171, 172, 35, 36, 171,
172, 35, 36, 171, 172, 35, 36, 171, 172, 205, 206,
205, 206, 69, 70, 205, 206, 413, 414, 39, 40, 69,
70, 205, 206, 69, 70, 205, 206, 69, 70, 205, 206,
69, 70, 205, 206, 69, 70, 205, 206, 69, 70, 205,
206, 69, 70, 205, 206, 239, 240, 239, 240, 103, 104,
39, 40, 447, 448, 73, 74, 307, 104, 239, 274, 103,
104, 239, 240, 103, 104, 239, 240, 103, 104, 239, 240,
103, 104, 239, 240, 103, 104, 239, 240, 103, 104, 239,
240, 1, 2, 137, 307, 1, 2, 73, 74, 413, 414,
137, 39, 40, 2, 137, 138, 1, 2, 137, 138, 1,
2, 137, 138, 1, 2, 137, 138, 1, 2, 137, 138,
1, 2, 137, 138, 1, 2, 137, 138, 35, 36, 171,
172, 35, 36, 171, 172, 447, 448, 171, 73, 74, 36,
171, 172, 331, 332, 171, 172, 35, 36, 171, 172, 35,
36, 171, 172, 35, 36, 171, 172, 35, 36, 171, 172,
35, 36, 171, 172, 69, 70, 205, 206, 69, 70, 274,
206, 413, 414, 235, 236, 233, 234, 205, 364, 365, 366,
367, 206, 69, 70, 205, 206, 69, 70, 205, 206, 69,
70, 205, 206, 69, 70, 205, 206, 69, 70, 205, 206,
103, 104, 239, 240, 39, 40, 239, 240, 447, 448, 269,
270, 267, 268, 397, 398, 399, 400, 401, 402, 103, 104,
239, 240, 103, 104, 239, 240, 103, 104, 239, 240, 103,
104, 239, 240, 103, 104, 239, 240, 1, 2, 237, 238,
73, 74, 137, 138, 413, 414, 233, 234, 235, 236, 431,
432, 433, 434, 435, 436, 1, 2, 137, 138, 1, 2,
137, 138, 1, 2, 137, 138, 1, 2, 137, 138, 1,
2, 137, 138, 35, 36, 271, 272, 35, 353, 354, 172,
447, 448, 267, 268, 269, 270, 465, 466, 467, 468, 469,
470, 35, 36, 171, 172, 35, 36, 171, 172, 35, 36,
171, 172, 35, 36, 171, 172, 35, 36, 171, 172, 69,
70, 351, 352, 69, 387, 388, 206, 347, 348, 349, 350,
343, 344, 499, 500, 439, 440, 503, 504, 69, 70, 205,
206, 69, 70, 205, 206, 69, 70, 205, 206, 69, 70,
205, 206, 69, 70, 205, 206, 103, 104, 385, 386, 103,
104, 239, 240, 381, 121, 121, 121, 121, 378, 403, 404,
473, 474, 405, 406, 103, 104, 239, 240, 103, 104, 239,
240, 103, 104, 239, 240, 103, 104, 239, 240, 103, 104,
239, 240, 1, 2, 409, 410, 345, 346, 345, 346, 417,
121, 121, 121, 121, 418, 345, 346, 417, 418, 345, 346,
345, 346, 345, 346, 345, 346, 345, 346, 345, 346, 345,
346, 345, 346, 345, 346, 345, 346, 345, 346, 35, 36,
443, 444, 379, 380, 379, 380, 451, 452, 451, 452, 451,
452, 379, 380, 451, 452, 379, 380, 379, 380, 379, 380,
379, 380, 379, 380, 379, 380, 379, 380, 379, 380, 379,
380, 379, 380, 379, 380, 69, 57, 58, 206, 69, 70,
205, 206, 69, 307, 205, 206, 69, 70, 205, 206, 39,
40, 205, 206, 69, 70, 205, 206, 69, 70, 205, 206,
69, 70, 205, 206, 69, 70, 205, 206, 69, 70, 205,
206, 90, 91, 92, 93, 57, 58, 57, 58, 103, 104,
239, 240, 103, 104, 239, 240, 73, 74, 239, 240, 103,
104, 239, 240, 103, 104, 239, 240, 103, 104, 239, 240,
103, 104, 239, 240, 103, 104, 239, 240, 91, 92, 91,
92, 91, 92, 91, 92, 93, 21, 137, 138, 1, 2,
137, 138, 1, 2, 137, 138, 1, 2, 137, 138, 1,
2, 137, 138, 1, 2, 137, 138, 1, 2, 137, 138,
1, 2, 137, 138, 125, 126, 125, 126, 125, 126, 125,
126, 127, 94, 171, 172, 35, 36, 171, 172, 35, 36,
171, 172, 35, 36, 171, 172, 35, 36, 171, 172, 35,
36, 171, 172, 35, 36, 171, 172, 35, 36, 171, 172,
159, 160, 159, 160, 159, 160, 159, 160, 70, 26, 205,
206, 69, 70, 205, 206, 69, 70, 205, 206, 69, 70,
205, 206, 69, 70, 205, 206, 69, 70, 205, 206, 69,
70, 205, 206, 69, 70, 205, 206, 103, 104, 239, 240,
103, 104, 239, 240, 103, 104, 239, 240, 103, 104, 239,
240, 103, 104, 239, 240, 103, 104, 239, 240, 103, 104,
239, 240, 103, 104, 239, 240, 103, 104, 239, 240, 103,
104, 239, 240, 1, 2, 137, 138, 1, 2, 137, 138,
1, 2, 137, 138, 1, 2, 137, 138, 1, 2, 137,
138, 1, 2, 137, 138, 1, 2, 137, 138, 1, 2,
137, 138, 1, 2, 137, 138, 1, 2, 137, 138, 35,
36, 171, 172, 35, 36, 171, 172, 35, 36, 171, 172,
35, 36, 171, 172, 35, 36, 171, 172, 35, 36, 171,
172, 35, 36, 171, 172, 35, 36, 171, 172, 35, 36,
171, 172, 35, 36, 171, 172, 69, 70, 205, 206, 69,
70, 205, 206, 69, 70, 205, 206, 69, 70, 205, 206,
69, 70, 205, 206, 69, 70, 205, 206, 69, 70, 205,
206, 69, 70, 205, 206, 69, 70, 205, 206, 69, 70,
205, 206, 103, 104, 239, 240, 103, 104, 239, 240, 103,
104, 239, 240, 103, 104, 239, 240, 103, 104, 239, 240,
103, 104, 239, 240, 103, 104, 239, 240, 103, 104, 239,
240, 103, 104, 239, 240, 103, 104, 239, 240, 1, 2,
137, 138, 1, 2, 137, 138, 1, 2, 137, 138, 1,
2, 137, 138, 1, 2, 137, 138, 1, 2, 137, 138,
1, 2, 137, 138, 1, 2, 137, 138, 1, 2, 137,
138, 1, 2, 137, 138, 35, 36, 171, 172, 35, 36,
171, 172, 35, 36, 171, 172, 35, 36, 171, 172, 35,
36, 171, 172, 35, 36, 171, 172, 35, 36, 171, 172,
35, 36, 171, 172, 35, 36, 171, 172, 35, 36, 171,
172, 69, 70, 205, 206, 69, 70, 205, 206, 69, 70,
205, 206, 69, 70, 205, 206, 69, 70, 205, 206, 69,
70, 205, 206, 69, 70, 205, 206, 69, 70, 205, 206,
69, 70, 205, 206, 69, 70, 205, 206, 103, 104, 239,
240, 103, 104, 239, 240, 103, 104, 239, 240, 103, 104,
239, 240, 103, 104, 239, 240, 103, 104, 239, 240, 103,
104, 239, 240, 103, 104, 239, 240, 103, 104, 239, 240,
103, 104, 239, 240, 1, 2, 137, 138, 1, 2, 137,
138, 1, 2, 137, 138, 1, 2, 137, 138, 1, 2,
137, 138, 1, 2, 137, 138, 1, 2, 137, 138, 1,
2, 137, 138, 1, 2, 137, 138, 1, 2, 137, 138,
35, 36, 171, 172, 35, 36, 171, 172, 35, 36, 171,
172, 35, 36, 171, 172, 35, 36, 171, 172, 35, 36,
171, 172, 35, 36, 171, 172, 35, 36, 171, 172, 35,
36, 171, 172, 35, 36, 171, 172, 69, 70, 205, 206,
69, 70, 205, 206, 69, 70, 205, 206, 69, 70, 205,
206, 69, 70, 205, 206, 69, 70, 205, 206, 69, 70,
205, 206, 69, 70, 205, 206, 69, 70, 205, 206, 69,
70, 205, 206, 103, 104, 239, 240, 103, 104, 239, 240,
103, 104, 239, 240, 103, 104, 239, 240, 103, 104, 239,
240, 103, 104, 239, 240, 103, 104, 239, 240, 103, 104,
239, 240, 103, 104, 239, 240, 103, 104, 239, 240, 1,
2, 137, 138, 1, 2, 137, 138, 1, 2, 137, 138,
1, 2, 137, 138, 1, 2, 137, 138, 1, 2, 137,
138, 1, 2, 137, 138, 1, 2, 137, 138, 1, 2,
137, 138, 1, 2, 137, 138, 35, 36, 171, 172, 35,
36, 171, 172, 35, 36, 171, 172, 35, 36, 171, 172,
35, 36, 171, 172, 35, 36, 171, 172, 35, 36, 171,
172, 35, 36, 171, 172, 35, 36, 171, 172, 35, 36,
171, 172, 69, 70, 205, 206, 69, 70, 205, 206, 69,
70, 205, 206, 69, 70, 205, 206, 69, 70, 205, 206,
69, 70, 205, 206, 69, 70, 205, 206, 69, 70, 205,
206, 69, 70, 205, 206, 69, 70, 205, 206, 103, 104,
239, 240, 103, 104, 239, 240, 103, 104, 239, 240, 103,
104, 239, 240, 103, 104, 239, 240, 103, 104, 239, 240,
103, 104, 239, 240, 103, 104, 239, 240, 103, 104, 239,
240, 103, 104, 239, 240,
pub const data = [400]u9{
0, 1, 38, 39, 0, 1, 136, 137, 0, 1, 70,
71, 72, 73, 74, 75, 0, 1, 136, 137, 34,
35, 72, 73, 34, 35, 170, 171, 34, 35, 104,
105, 106, 107, 108, 109, 34, 38, 39, 171, 68,
69, 204, 205, 68, 69, 204, 205, 68, 69, 138,
139, 206, 207, 142, 143, 68, 72, 73, 205, 102,
103, 238, 239, 102, 103, 238, 239, 102, 103, 172,
173, 240, 241, 176, 177, 102, 103, 238, 239, 136,
137, 136, 137, 306, 273, 136, 137, 340, 341, 344,
345, 410, 411, 136, 137, 0, 1, 32, 33, 170,
171, 170, 171, 306, 306, 170, 171, 374, 375, 378,
379, 444, 445, 170, 171, 34, 35, 66, 67, 204,
205, 204, 205, 68, 69, 204, 205, 412, 413, 38,
39, 68, 69, 204, 205, 68, 69, 204, 205, 238,
239, 238, 239, 102, 103, 38, 39, 446, 447, 72,
73, 306, 103, 238, 273, 102, 103, 238, 239, 0,
1, 136, 306, 0, 1, 72, 73, 412, 413, 136,
38, 39, 1, 136, 137, 0, 1, 136, 137, 34,
35, 170, 171, 34, 35, 170, 171, 446, 447, 170,
72, 73, 35, 170, 171, 330, 331, 170, 171, 68,
69, 204, 205, 68, 69, 273, 205, 412, 413, 234,
235, 232, 233, 204, 363, 364, 365, 366, 205, 102,
103, 238, 239, 38, 39, 238, 239, 446, 447, 268,
269, 266, 267, 396, 397, 398, 399, 400, 401, 0,
1, 236, 237, 72, 73, 136, 137, 412, 413, 232,
233, 234, 235, 430, 431, 432, 433, 434, 435, 34,
35, 270, 271, 34, 352, 353, 171, 446, 447, 266,
267, 268, 269, 464, 465, 466, 467, 468, 469, 68,
69, 350, 351, 68, 386, 387, 205, 346, 347, 348,
349, 342, 343, 498, 499, 438, 439, 502, 503, 102,
103, 384, 385, 102, 103, 238, 239, 380, 120, 120,
120, 120, 377, 402, 403, 472, 473, 404, 405, 0,
1, 408, 409, 344, 345, 344, 345, 416, 120, 120,
120, 120, 417, 344, 345, 416, 417, 344, 345, 34,
35, 442, 443, 378, 379, 378, 379, 450, 451, 450,
451, 450, 451, 378, 379, 450, 451, 378, 379, 68,
56, 57, 205, 68, 69, 204, 205, 68, 306, 204,
205, 68, 69, 204, 205, 38, 39, 204, 205, 89,
90, 91, 92, 102, 103, 56, 57, 102, 103, 238,
239, 102, 103, 238, 239, 72, 73, 238, 239,
};
pub const coll = [_]Rect{
Rect{ .base = Point{ .x = 80, .y = 0 }, .width = 47, .height = 16 },
Rect{ .base = Point{ .x = 128, .y = 70 }, .width = 16, .height = 9 },
Rect{ .base = Point{ .x = 146, .y = 32 }, .width = 11, .height = 16 },
Rect{ .base = Point{ .x = 18, .y = 98 }, .width = 12, .height = 13 },
Rect{ .base = Point{ .x = 114, .y = 16 }, .width = 12, .height = 13 },
Rect{ .base = Point{ .x = 81, .y = 16 }, .width = 13, .height = 15 },
Rect{ .base = Point{ .x = 83, .y = 85 }, .width = 26, .height = 27 },
Rect{ .base = Point{ .x = 100, .y = 81 }, .width = 8, .height = 5 },
Rect{ .base = Point{ .x = 112, .y = 94 }, .width = 48, .height = 17 },
Rect{ .base = Point{ .x = 121, .y = 87 }, .width = 30, .height = 7 },
Rect{ .base = Point{ .x = 128, .y = 80 }, .width = 16, .height = 7 },
Rect{ .base = Point{ .x = 114, .y = 112 }, .width = 11, .height = 13 },
Rect{ .base = Point{ .x = 145, .y = 111 }, .width = 12, .height = 13 },
Rect{ .base = Point{ .x = 11, .y = 146 }, .width = 9, .height = 7 },
Rect{ .base = Point{ .x = 0, .y = 154 }, .width = 61, .height = 27 },
Rect{ .base = Point{ .x = 62, .y = 162 }, .width = 8, .height = 11 },
Rect{.base = Point{.x = 80, .y = 0}, .width = 47, .height = 16},
Rect{.base = Point{.x = 128, .y = 70}, .width = 16, .height = 9},
Rect{.base = Point{.x = 146, .y = 32}, .width = 11, .height = 16},
Rect{.base = Point{.x = 18, .y = 98}, .width = 12, .height = 13},
Rect{.base = Point{.x = 114, .y = 16}, .width = 12, .height = 13},
Rect{.base = Point{.x = 81, .y = 16}, .width = 13, .height = 15},
Rect{.base = Point{.x = 83, .y = 85}, .width = 26, .height = 27},
Rect{.base = Point{.x = 100, .y = 81}, .width = 8, .height = 5},
Rect{.base = Point{.x = 112, .y = 94}, .width = 48, .height = 17},
Rect{.base = Point{.x = 121, .y = 87}, .width = 30, .height = 7},
Rect{.base = Point{.x = 128, .y = 80}, .width = 16, .height = 7},
Rect{.base = Point{.x = 114, .y = 112}, .width = 11, .height = 13},
Rect{.base = Point{.x = 145, .y = 111}, .width = 12, .height = 13},
Rect{.base = Point{.x = 0, .y = 153}, .width = 31, .height = 7},
Rect{.base = Point{.x = 11, .y = 146}, .width = 9, .height = 7},
Rect{.base = Point{.x = 52, .y = 154}, .width = 8, .height = 6},
};
pub const triggers = [_]Trigger{
Trigger{ .aura = Rect{ .base = Point{ .x = 16, .y = 96 }, .width = 16, .height = 20 }, .direction = Direction.Up, .dialogue = "Kanar News\nThe mayor is\nacting weird today." }, // sign
Trigger{ .aura = Rect{ .base = Point{ .x = 83, .y = 103 }, .width = 7, .height = 16 }, .direction = Direction.Up, .dialogue = "Ded." }, // gravestone 1
Trigger{ .aura = Rect{ .base = Point{ .x = 96, .y = 103 }, .width = 7, .height = 16 }, .direction = Direction.Up, .dialogue = "Moar ded." }, // gravestone 2
Trigger{.aura = Rect{.base = Point{.x = 16, .y = 96}, .width = 16, .height = 20}, .direction = Direction.Up, .dialogue = "18 chars per line\nallowed. Or else!"}, // sign
Trigger{.aura = Rect{.base = Point{.x = 83, .y = 103}, .width = 7, .height = 16}, .direction = Direction.Up, .dialogue = "Ded."}, // gravestone 1
Trigger{.aura = Rect{.base = Point{.x = 96, .y = 103}, .width = 7, .height = 16}, .direction = Direction.Up, .dialogue = "Moar ded."}, // gravestone 2
};
pub const start_point = Point{ .x = 32, .y = 31 };
pub const map = sh0rk.Map{
.width = 20,
.height = 20,
.tileset = .Rpg,
.tiles = data[0..data.len],
.coll = coll[0..coll.len],
.triggers = triggers[0..triggers.len],
.start = Point{ .x = 32, .y = 32 },
};

View File

@ -1,77 +0,0 @@
const palette = @import("./palette.zig");
const sh0rk = @import("./sh0rk.zig");
const sprites = @import("./sprites.zig");
const w4 = @import("./wasm4.zig");
pub fn title() !void {
w4.m.colors._0 = .p3;
w4.m.colors._1 = .p0;
w4.text("Mara 2:\nTamamo's Fury", 28, 8);
w4.text("Press z or x", 32, 136);
w4.text("From Within 2022", 16, 152);
w4.m.colors._0 = .p0;
w4.m.colors._1 = .p1;
w4.m.colors._2 = .p2;
w4.m.colors._3 = .p3;
w4.blit(&sprites.tamamotitle, 48, 60, sprites.tamamotitle_width, sprites.tamamotitle_height, w4.BlitFlags{ .two_bits = true });
const gamepad = w4.m.gamepads[0];
if (gamepad.a or gamepad.b) {
sh0rk.state = .StoryDump;
}
}
const story = "After defeating\nthe evil mage,\nMalto was at\npeace.\n\nOne day Mara was\nwalking along the\nbeach when she saw\nthe killing stone\nwas split in two.\nTamamo-no-Mae was\nfree to wreak havoc\nacross the land.\n\nHelp us again Mara!\nSave Malto from\nTamamo-no-Mae!\n\nPress x.";
var story_idx: u16 = 0;
var story_counter: u8 = 4;
pub fn storydump() !void {
w4.m.colors._0 = .p3;
w4.m.colors._1 = .p0;
w4.text(story[0..story_idx], 4, 4);
const gamepad = w4.m.gamepads[0];
if (gamepad.b) {
sh0rk.state = .Gameplay;
palette.mist();
}
if (story_idx < story.len) {
story_counter -= 1;
if (gamepad.a) {
story_counter = 0;
}
if (story_counter == 0) {
story_idx += 1;
story_counter = 4;
w4.tone(
w4.Tone.Frequency{ .start = 280, .end = 310 },
w4.Tone.Duration{
.attack = 0,
.decay = 0,
.sustain = 2,
.release = 0,
},
w4.Tone.Volume{
.sustain = 100,
.attack = 100,
},
w4.Tone.Flags{
.channel = .triangle,
.pulse_duty = .@"1/4",
},
);
}
} else {
if (gamepad.a) {
sh0rk.state = .Gameplay;
palette.mist();
}
}
}

View File

@ -1,7 +1,7 @@
pub const Point = packed struct {
x: i16,
y: i16,
pub fn init(x: i16, y: i16) @This() {
x: u16,
y: u16,
pub fn init(x: u16, y: u16) @This() {
return @This() {
.x = x,
.y = y,
@ -11,20 +11,6 @@ pub const Point = packed struct {
pub fn equals(this: @This(), other: @This()) bool {
return this.x == other.x and this.y == other.y;
}
pub fn add(this: @This(), other: @This()) @This() {
return @This() {
.x = this.x + other.x,
.y = this.y + other.y,
};
}
pub fn sub(this: @This(), other: @This()) @This() {
return @This() {
.x = this.x - other.x,
.y = this.y - other.y,
};
}
};
pub const Rect = packed struct {
@ -44,11 +30,7 @@ pub const Rect = packed struct {
}
pub fn collides(this: @This(), other: @This()) bool {
return
this.base.x < other.base.x + other.width and
this.base.x + this.width > other.base.x and
this.base.y < other.base.y + other.height and
this.base.y + this.height > other.base.y;
return this.base.x < other.base.x + other.width and this.base.x + this.width > other.base.x and this.base.y < other.base.y + other.height and this.base.y + this.height > other.base.y;
}
};
@ -75,8 +57,25 @@ pub const Trigger = struct {
};
pub const Tileset = enum(u2) {
Cave,
Rpg,
Dungeon,
pub fn width(this: @This()) u9 {
switch (this) {
.Cave => return 28,
.Rpg => return 34,
.Dungeon => return 14,
}
}
pub fn height(this: @This()) u9 {
switch (this) {
.Cave => return 10,
.Rpg => return 16,
.Dungeon => return 13,
}
}
};
pub const State = enum {
@ -85,4 +84,12 @@ pub const State = enum {
Gameplay,
};
pub var state: State = .Gameplay;
pub const Map = struct {
width: u8,
height: u8,
tileset: Tileset = .Rpg,
tiles: []const u9,
coll: []const Rect,
triggers: []const Trigger,
start: Point,
};

View File

@ -176,8 +176,8 @@ pub fn update(gamepad: w4.GamePad) void {
frame();
w4.m.colors._0 = .p3;
w4.m.colors._1 = .transparent;
w4.text(curr_text[0..text_index], 6, 132);
w4.m.colors._1 = .p0;
w4.text(curr_text[0..text_index], 8, 136);
if (gamepad.a) {
w4.trace("dismissing");

View File

@ -1,3 +1,58 @@
const genMap = (tiles) => {
out += `pub const data = [_]u9{\n `;
tiles.data.forEach((tile, index) => {
tile -= 1;
out += `${tile},`;
if (index !== 0 && index % 10 === 0) {
out += "\n ";
} else {
out += " ";
}
});
out += "\n};\n\n";
};
const genColl = coll => {
out += `pub const coll = [_]Rect{\n`;
coll.objects.forEach(obj => {
const x = Math.round(obj.x);
const y = Math.round(obj.y);
const width = Math.round(obj.width);
const height = Math.round(obj.height);
let comment = "";
if (obj.name !== "") {
comment = ` // ${obj.name}`;
}
out += ` Rect{.base = Point{.x = ${x}, .y = ${y}}, .width = ${width}, .height = ${height}},${comment}\n`;
});
out += "};\n\n";
};
const genAct = act => {
out += `pub const triggers = [_]Trigger{\n`;
act.objects.forEach(obj => {
const x = Math.round(obj.x);
const y = Math.round(obj.y);
const width = Math.round(obj.width);
const height = Math.round(obj.height);
let direction = "";
let dialogue = "";
obj.properties.forEach(prop => {
if (prop.name === "direction") {
direction = prop.value;
}
if (prop.name === "dialogue") {
dialogue = prop.value;
}
});
if (direction === "" || dialogue === "") {
throw new Error("Missing direction or dialogue");
}
out += ` Trigger{.aura = Rect{.base = Point{.x = ${x}, .y = ${y}}, .width = ${width}, .height = ${height}}, .direction = Direction.${direction}, .dialogue = "${dialogue}"}, // ${obj.name}\n`;
});
out += "};\n\n";
};
if (Deno.args.length !== 2) {
console.log("Usage: ./genmap.js <path-to-map-file> <output-fname>");
Deno.exit(1);
@ -21,20 +76,6 @@ out += `const Tileset = sh0rk.Tileset;\n`;
out += `const Trigger = sh0rk.Trigger;\n`;
out += `const Rect = sh0rk.Rect;\n\n`;
out += `pub const width = ${map.width};\n`;
out += `pub const height = ${map.height};\n\n`;
out += `pub fn get_tile(x: i32, y: i32) u9 {
if (x < 0 or y < 0) {
return 0;
}
if (x >= width or y >= height) {
return 0;
}
return data[@intCast(u32, y) * width + @intCast(u32, x)];
}
`;
let tiles = map.layers[0];
let tilesheet = {
@ -68,76 +109,9 @@ map.tilesets.forEach(tset => {
}
});
out += `pub const tileset: Tileset = .${tilesheet.name};\n`;
out += `pub const ts_width = ${tilesheet.width};\n`;
out += `pub const ts_height = ${tilesheet.height};\n\n`;
const genMap = (tiles) => {
out += `pub const data = [${tiles.data.length}]u9{\n `;
tiles.data.forEach((tile, index) => {
out += `${tile},`;
if (index !== 0 && index % 10 === 0) {
out += "\n ";
} else {
out += " ";
}
});
out += "\n};\n\n";
};
const genColl = coll => {
out += `pub const coll = [_]Rect{\n`;
coll.objects.forEach(obj => {
const x = Math.round(obj.x);
const y = Math.round(obj.y);
const width = Math.round(obj.width);
const height = Math.round(obj.height);
let comment = "";
if (obj.name !== "") {
comment = ` // ${obj.name}`;
}
out += ` Rect{.base = Point{.x = ${x}, .y = ${y}}, .width = ${width}, .height = ${height}},${comment}\n`;
});
out += "};\n\n";
};
const genAct = act => {
out += `pub const triggers = [_]Trigger{\n`;
act.objects.forEach(obj => {
const x = Math.round(obj.x);
const y = Math.round(obj.y);
const width = Math.round(obj.width);
const height = Math.round(obj.height);
let direction = "";
let dialogue = "";
obj.properties.forEach(prop => {
if (prop.name === "direction") {
direction = prop.value;
}
if (prop.name === "dialogue") {
dialogue = prop.value;
}
});
if (direction === "" || dialogue === "") {
throw new Error("Missing direction or dialogue");
}
out += ` Trigger{.aura = Rect{.base = Point{.x = ${x}, .y = ${y}}, .width = ${width}, .height = ${height}}, .direction = Direction.${direction}, .dialogue = "${dialogue}"}, // ${obj.name}\n`;
});
out += "};\n\n";
};
map.layers.forEach(layer => {
if (layer.name == "map") {
genMap(layer);
@ -150,14 +124,26 @@ map.layers.forEach(layer => {
if (layer.name == "act") {
genAct(layer);
}
});
out += `pub const map = sh0rk.Map{\n`;
out += ` .width = ${map.width},\n`;
out += ` .height = ${map.height},\n`;
out += ` .tileset = .${tilesheet.name},\n`;
out += ` .tiles = data[0..data.len],\n`;
out += ` .coll = coll[0..coll.len],\n`;
out += ` .triggers = triggers[0..triggers.len],\n`;
map.layers.forEach(layer => {
if (layer.name == "spc") {
layer.objects.forEach(obj => {
if (obj.name === "mara_start") {
out += `pub const start_point = Point{ .x = ${Math.round(obj.x)}, .y = ${Math.round(obj.y)} };\n\n`;
out += ` .start = Point{ .x = ${Math.round(obj.x)}, .y = ${Math.round(obj.y)} },\n`;
}
});
}
});
out += `};\n`;
await Deno.writeTextFile(outFname, out);

View File

@ -116,8 +116,8 @@ pub const SystemFlags = packed struct {
//
const raw_api = struct {
extern fn blit(sprite: [*]const u8, x: i32, y: i32, width: u32, height: u32, flags: u32) void;
extern fn blitSub(sprite: [*]const u8, x: i32, y: i32, width: u32, height: u32, src_x: u32, src_y: u32, stride: u32, flags: u32) void;
extern fn blit(sprite: [*]const u8, x: u32, y: u32, width: u32, height: u32, flags: u32) void;
extern fn blitSub(sprite: [*]const u8, x: u32, y: u32, width: u32, height: u32, src_x: u32, src_y: u32, stride: u32, flags: u32) void;
extern fn tone(frequency: u32, duration: u32, volume: u32, flags: u32) void;
};
@ -137,7 +137,7 @@ pub const BlitFlags = packed struct {
};
/// Copies pixels to the framebuffer.
pub fn blit(sprite: []const u8, x: i32, y: i32, width: u32, height: u32, flags: BlitFlags) void {
pub fn blit(sprite: []const u8, x: u32, y: u32, width: u32, height: u32, flags: BlitFlags) void {
raw_api.blit(sprite.ptr, x, y, width, height, @bitCast(u32, flags));
}
@ -145,24 +145,24 @@ pub fn blit(sprite: []const u8, x: i32, y: i32, width: u32, height: u32, flags:
/// srcX: Source X position of the sprite region.
/// srcY: Source Y position of the sprite region.
/// stride: Total width of the overall sprite atlas. This is typically larger than width.
pub fn blitSub(sprite: []const u8, x: i32, y: i32, width: u32, height: u32, src_x: u32, src_y: u32, stride: u32, flags: BlitFlags) void {
pub fn blitSub(sprite: []const u8, x: u32, y: u32, width: u32, height: u32, src_x: u32, src_y: u32, stride: u32, flags: BlitFlags) void {
raw_api.blitSub(sprite.ptr, x, y, width, height, src_x, src_y, stride, @bitCast(u32, flags));
}
/// Draws a line between two points.
pub extern fn line(x1: i32, y1: i32, x2: i32, y2: i32) void;
pub extern fn line(x1: u32, y1: u32, x2: u32, y2: u32) void;
/// Draws an oval (or circle).
pub extern fn oval(x: i32, y: i32, width: u32, height: u32) void;
pub extern fn oval(x: u32, y: u32, width: u32, height: u32) void;
/// Draws a rectangle.
pub extern fn rect(x: i32, y: i32, width: u32, height: u32) void;
pub extern fn rect(x: u32, y: u32, width: u32, height: u32) void;
/// Draws text using the built-in system font.
pub fn text(str: []const u8, x: i32, y: i32) void {
pub fn text(str: []const u8, x: u32, y: u32) void {
textUtf8(str.ptr, str.len, x, y);
}
extern fn textUtf8(strPtr: [*]const u8, strLen: usize, x: i32, y: i32) void;
extern fn textUtf8(strPtr: [*]const u8, strLen: usize, x: u32, y: u32) void;
/// Draws a vertical line
pub extern fn vline(x: u32, y: u32, len: u32) void;