2022-07-02 00:22:38 +00:00
const w4 = @import ( " ./wasm4.zig " ) ;
const sh0rk = @import ( " ./sh0rk.zig " ) ;
const sprites = @import ( " ./sprites.zig " ) ;
const palette = @import ( " ./palette.zig " ) ;
const tframe = @import ( " ./tframe.zig " ) ;
2022-07-01 21:10:57 +00:00
const std = @import ( " std " ) ;
const fmt = std . fmt ;
2022-04-24 09:46:36 +00:00
2022-06-27 03:39:57 +00:00
const Direction = sh0rk . Direction ;
const Point = sh0rk . Point ;
const Rect = sh0rk . Rect ;
2022-07-02 01:46:56 +00:00
const map = @import ( " ./maps/overworld.zig " ) ;
2022-07-01 22:05:55 +00:00
2022-06-27 03:39:57 +00:00
var frame_count : u32 = 0 ;
var mara_direction : Direction = Direction . Right ;
var mara_frame : bool = false ;
2022-07-01 22:05:55 +00:00
var mara_box : Rect = Rect { . base = map . start_point , . width = 16 , . height = 16 } ;
2022-07-02 00:22:38 +00:00
var mara_speed : u16 = 0 ;
2022-06-27 03:39:57 +00:00
var screen = Rect { . base = Point { . x = 0 , . y = 0 } , . width = 160 , . height = 160 } ;
2022-07-02 01:18:54 +00:00
const screen_width = 20 ;
const screen_height = 20 ;
2022-07-02 00:22:38 +00:00
2022-07-01 18:23:39 +00:00
var sound_timer : u8 = 0 ;
2022-07-01 17:11:52 +00:00
var textBuf : [ 160 ] u8 = undefined ;
2022-07-02 01:18:54 +00:00
var done : bool = false ;
2022-07-01 21:10:57 +00:00
2022-07-02 01:46:13 +00:00
var camera : [ 400 ] u9 = [ ] u9 { } * * 400 ;
2022-07-02 02:51:31 +00:00
var state : sh0rk . State = . Title ;
2022-06-27 03:39:57 +00:00
export fn start ( ) void {
2022-07-02 02:51:31 +00:00
palette . tamtam ( ) ;
2022-07-02 00:22:38 +00:00
}
2022-07-01 17:11:52 +00:00
2022-07-01 18:23:39 +00:00
fn bonk ( ) void {
if ( sound_timer ! = 0 ) {
return ;
}
w4 . tone (
w4 . Tone . Frequency { . start = 220 , . end = 40 } ,
w4 . Tone . Duration {
. attack = 0 ,
. decay = 0 ,
. sustain = 6 ,
. release = 6 ,
} ,
w4 . Tone . Volume {
. sustain = 100 ,
. attack = 100 ,
} ,
w4 . Tone . Flags {
. channel = . triangle ,
2022-07-01 21:10:57 +00:00
. pulse_duty = . @ " 1/4 " ,
2022-07-01 18:23:39 +00:00
} ,
) ;
sound_timer = 12 ;
}
2022-07-01 17:11:52 +00:00
fn drawMap ( ) ! void {
w4 . m . colors . * = . {
2022-07-01 21:10:57 +00:00
. _0 = . p3 ,
. _1 = . p2 ,
. _2 = . p1 ,
. _3 = . p0 ,
2022-07-01 17:11:52 +00:00
} ;
2022-07-01 21:10:57 +00:00
var col : u32 = 0 ;
while ( col < screen_width ) {
var row : u32 = 0 ;
defer col + = 1 ;
while ( row < screen_height ) {
defer row + = 1 ;
2022-07-02 01:18:54 +00:00
var tile = map . data [ col * map . width + row ] ;
2022-07-01 21:10:57 +00:00
var tileX = tile % map . ts_width ;
var tileY = tile / map . ts_width ;
2022-07-02 01:43:22 +00:00
// if (!done) {
// var buf = fmt.bufPrint(&textBuf, "{},{}: {}: {},{}", .{col, row, tile, tileX, tileY}) catch unreachable;
// w4.trace(buf);
// }
2022-07-01 21:10:57 +00:00
w4 . blitSub (
& sprites . kenney_rpg ,
2022-07-02 01:18:54 +00:00
row * 8 ,
col * 8 ,
8 ,
8 ,
@intCast ( u32 , tileX ) * 8 ,
@intCast ( u32 , tileY ) * 8 ,
2022-07-01 21:10:57 +00:00
sprites . kenney_rpg_width ,
w4 . BlitFlags { . two_bits = true } ,
) ;
}
2022-07-01 17:11:52 +00:00
}
}
2022-07-01 18:23:39 +00:00
fn move_mara ( gamepad : w4 . GamePad ) void {
2022-07-02 00:22:38 +00:00
if ( mara_speed > 0 ) {
mara_speed - = 1 ;
2022-06-27 12:56:16 +00:00
}
2022-06-27 03:39:57 +00:00
if ( gamepad . up ) {
mara_direction = Direction . Up ;
2022-07-01 15:06:47 +00:00
mara_speed = 1 ;
2022-06-27 03:39:57 +00:00
} else if ( gamepad . down ) {
mara_direction = Direction . Down ;
2022-07-01 15:06:47 +00:00
mara_speed = 1 ;
2022-06-27 03:39:57 +00:00
} else if ( gamepad . left ) {
mara_direction = Direction . Left ;
2022-07-01 15:06:47 +00:00
mara_speed = 1 ;
2022-06-27 03:39:57 +00:00
} else if ( gamepad . right ) {
mara_direction = Direction . Right ;
2022-07-01 15:06:47 +00:00
mara_speed = 1 ;
2022-06-27 03:39:57 +00:00
}
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 ;
} ,
}
2022-07-01 18:23:39 +00:00
}
2022-07-02 02:51:31 +00:00
fn title ( ) ! void {
2022-07-01 21:10:57 +00:00
w4 . m . colors . _0 = . p3 ;
w4 . m . colors . _1 = . p0 ;
2022-07-02 02:51:31 +00:00
w4 . text ( " Mara 2: \n Tamamo'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 \n the evil mage, \n Malto was at \n peace. \n \n One day Mara was \n walking along the \n beach when she saw \n the killing stone \n was split in two. \n Tamamo-no-Mae was \n free to wreak havoc \n across the land. \n \n Help us again Mara! \n Save Kanar from \n Tamamo-no-Mae! \n \n Press 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 ( ) ;
}
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 ( ) ;
}
}
2022-07-01 21:10:57 +00:00
}
2022-07-01 18:23:39 +00:00
export fn update ( ) void {
2022-07-02 02:51:31 +00:00
switch ( state ) {
. Title = > title ( ) catch unreachable ,
. StoryDump = > storydump ( ) catch unreachable ,
. Gameplay = > gameplay ( ) catch unreachable ,
}
}
fn gameplay ( ) ! void {
2022-07-01 21:10:57 +00:00
defer done = true ;
2022-07-01 18:23:39 +00:00
if ( sound_timer ! = 0 ) {
sound_timer - = 1 ;
}
drawMap ( ) catch unreachable ;
const gamepad = w4 . m . gamepads [ 0 ] ;
const old_speed = mara_speed ;
2022-07-01 21:10:57 +00:00
2022-07-01 22:05:55 +00:00
if ( ! tframe . enabled ) {
move_mara ( gamepad ) ;
} else {
tframe . update ( gamepad ) ;
2022-07-01 21:10:57 +00:00
}
2022-07-01 17:37:13 +00:00
for ( map . coll ) | box | {
if ( mara_box . collides ( box ) ) {
2022-07-01 18:23:39 +00:00
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 ;
} ,
}
2022-07-01 17:37:13 +00:00
mara_speed = 0 ;
2022-07-01 18:23:39 +00:00
bonk ( ) ;
2022-07-01 17:37:13 +00:00
}
}
2022-07-01 22:05:55 +00:00
for ( map . triggers ) | trig | {
if ( mara_box . collides ( trig . aura ) and mara_direction = = trig . direction and gamepad . b ) {
tframe . set_text ( trig . dialogue ) ;
}
}
2022-06-27 03:39:57 +00:00
if ( mara_box . base . x < 0 ) {
mara_box . base . x = 0 ;
2022-07-01 21:10:57 +00:00
bonk ( ) ;
2022-06-27 03:39:57 +00:00
} else if ( mara_box . base . x > 160 - mara_box . width ) {
mara_box . base . x = 160 - mara_box . width ;
2022-07-01 21:10:57 +00:00
bonk ( ) ;
2022-06-27 03:39:57 +00:00
}
if ( mara_box . base . y < 0 ) {
mara_box . base . y = 0 ;
2022-07-01 21:10:57 +00:00
bonk ( ) ;
2022-06-27 03:39:57 +00:00
} else if ( mara_box . base . y > 160 - mara_box . height ) {
mara_box . base . y = 160 - mara_box . height ;
2022-07-01 21:10:57 +00:00
bonk ( ) ;
2022-04-24 09:46:36 +00:00
}
2022-07-01 15:06:47 +00:00
var flags : w4 . BlitFlags = w4 . BlitFlags {
. two_bits = true ,
} ;
2022-07-01 17:11:52 +00:00
// w4.m.colors._0 = .p0;
// w4.m.colors._1 = .p1;
// w4.m.colors._2 = .p3;
// w4.m.colors._3 = .transparent;
2022-07-01 15:06:47 +00:00
2022-07-01 21:10:57 +00:00
// w4.blit(&sprites.glaceon, 0, 0, sprites.glaceon_width, sprites.glaceon_height, flags);
2022-07-01 15:06:47 +00:00
2022-07-01 17:11:52 +00:00
w4 . m . colors . * = . {
. _0 = . transparent ,
. _1 = . p0 ,
. _2 = . p1 ,
. _3 = . p3 ,
} ;
2022-06-27 03:39:57 +00:00
if ( mara_direction = = Direction . Left ) {
flags . flip_x = true ;
}
if ( frame_count % 15 = = 0 and mara_speed > 0 ) {
mara_frame = ! mara_frame ;
}
2022-06-27 12:56:16 +00:00
if ( old_speed ! = mara_speed ) {
mara_frame = ! mara_frame ;
}
2022-06-27 03:39:57 +00:00
var frame : u32 = switch ( mara_direction ) {
. Left = > 4 ,
. Right = > 4 ,
. Up = > 2 ,
. Down = > 0 ,
} ;
var step : u32 = if ( mara_frame ) 1 else 0 ;
w4 . blitSub ( & sprites . Mara , @intCast ( u32 , mara_box . base . x ) , @intCast ( u32 , mara_box . base . y ) , 16 , 16 , 16 * ( frame + step ) , 0 , 96 , flags ) ;
frame_count + = 1 ;
2022-04-24 09:46:36 +00:00
}
2022-06-27 03:39:57 +00:00