136 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
			
		
		
	
	
			136 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			Zig
		
	
	
	
	
	
const std = @import("std");
 | 
						|
 | 
						|
const GBA = @import("gba").GBA;
 | 
						|
const Mode3 = @import("gba").Mode3;
 | 
						|
const LCD = @import("gba").LCD;
 | 
						|
const OAM = @import("gba").OAM;
 | 
						|
const Input = @import("gba").Input;
 | 
						|
 | 
						|
const sprites = @import("sprites.zig");
 | 
						|
 | 
						|
const sprite_attrs = [24]OAM.Attribute{
 | 
						|
    sprites.square.d2.bpp4.Sprite8x8.getAttribute(),
 | 
						|
    sprites.square.d2.bpp4.Sprite16x16.getAttribute(),
 | 
						|
    sprites.square.d2.bpp4.Sprite32x32.getAttribute(),
 | 
						|
    sprites.square.d2.bpp4.Sprite64x64.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite16x8.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite32x8.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite32x16.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite64x32.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp4.Sprite8x16.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp4.Sprite8x32.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp4.Sprite16x32.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp4.Sprite32x64.getAttribute(),
 | 
						|
 | 
						|
    sprites.square.d2.bpp8.Sprite8x8.getAttribute(),
 | 
						|
    sprites.square.d2.bpp8.Sprite16x16.getAttribute(),
 | 
						|
    sprites.square.d2.bpp8.Sprite32x32.getAttribute(),
 | 
						|
    sprites.square.d2.bpp8.Sprite64x64.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite16x8.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite32x8.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite32x16.getAttribute(),
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite64x32.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp8.Sprite8x16.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp8.Sprite8x32.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp8.Sprite16x32.getAttribute(),
 | 
						|
    sprites.vertical.d2.bpp8.Sprite32x64.getAttribute(),
 | 
						|
};
 | 
						|
 | 
						|
const sprite_load_fns = [24]fn () void{
 | 
						|
    sprites.square.d2.bpp4.Sprite8x8.load,
 | 
						|
    sprites.square.d2.bpp4.Sprite16x16.load,
 | 
						|
    sprites.square.d2.bpp4.Sprite32x32.load,
 | 
						|
    sprites.square.d2.bpp4.Sprite64x64.load,
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite16x8.load,
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite32x8.load,
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite32x16.load,
 | 
						|
    sprites.horizontal.d2.bpp4.Sprite64x32.load,
 | 
						|
    sprites.vertical.d2.bpp4.Sprite8x16.load,
 | 
						|
    sprites.vertical.d2.bpp4.Sprite8x32.load,
 | 
						|
    sprites.vertical.d2.bpp4.Sprite16x32.load,
 | 
						|
    sprites.vertical.d2.bpp4.Sprite32x64.load,
 | 
						|
 | 
						|
    sprites.square.d2.bpp8.Sprite8x8.load,
 | 
						|
    sprites.square.d2.bpp8.Sprite16x16.load,
 | 
						|
    sprites.square.d2.bpp8.Sprite32x32.load,
 | 
						|
    sprites.square.d2.bpp8.Sprite64x64.load,
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite16x8.load,
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite32x8.load,
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite32x16.load,
 | 
						|
    sprites.horizontal.d2.bpp8.Sprite64x32.load,
 | 
						|
    sprites.vertical.d2.bpp8.Sprite8x16.load,
 | 
						|
    sprites.vertical.d2.bpp8.Sprite8x32.load,
 | 
						|
    sprites.vertical.d2.bpp8.Sprite16x32.load,
 | 
						|
    sprites.vertical.d2.bpp8.Sprite32x64.load,
 | 
						|
};
 | 
						|
 | 
						|
// TODO: ZigGBA should support spaces, slashes, underscores, etc. in ROM Title
 | 
						|
export var gameHeader linksection(".gbaheader") = GBA.Header.setup("SPRITE", "PAOD", "00", 0);
 | 
						|
 | 
						|
const obj_mapping = .TwoDimension;
 | 
						|
 | 
						|
pub fn main() noreturn {
 | 
						|
    LCD.setupDisplayControl(.{
 | 
						|
        .mode = .Mode0,
 | 
						|
        .objectLayer = .Show, // Enable Sprites
 | 
						|
        .objVramCharacterMapping = obj_mapping, // 2D Sprite Mapping
 | 
						|
    });
 | 
						|
 | 
						|
    // FIXME: There are issues with OAM.Attribute and the ZigGBA API
 | 
						|
    // investigate what these issues are (could it just be my understanding?)
 | 
						|
    const attr_ptr = @intToPtr([*]OAM.Attribute, 0x0700_0000);
 | 
						|
 | 
						|
    // Attr0 is in the least significant u16
 | 
						|
    const oam_slice = @intToPtr([*]u32, 0x0700_0000)[0 .. 0x400 / @sizeOf(u32)];
 | 
						|
 | 
						|
    // Set bit 9 on all sprites, therefore disabling them all
 | 
						|
    for (oam_slice) |*attr| attr.* |= 0x0200;
 | 
						|
 | 
						|
    // Grab Default Sprite (Square 64x64 4bpp)
 | 
						|
    var sprite = sprite_attrs[0];
 | 
						|
    sprite_load_fns[0]();
 | 
						|
 | 
						|
    var x: i32 = 96;
 | 
						|
    var y: i32 = 32;
 | 
						|
 | 
						|
    var size_idx: u2 = 0;
 | 
						|
    var shape_idx: u2 = 0;
 | 
						|
    var is_4bpp: bool = true;
 | 
						|
 | 
						|
    while (true) {
 | 
						|
        LCD.naiveVSync();
 | 
						|
        Input.readInput();
 | 
						|
 | 
						|
        const shoulder = @truncate(u2, @bitCast(u32, Input.getShoulderJustPressed()));
 | 
						|
 | 
						|
        if (Input.isKeyJustPressed(Input.Keys.Start)) is_4bpp = !is_4bpp;
 | 
						|
        if (Input.isKeyJustPressed(Input.Keys.A)) shape_idx +%= 1;
 | 
						|
        if (Input.isKeyJustPressed(Input.Keys.B)) shape_idx -%= 1;
 | 
						|
 | 
						|
        const input_cond =
 | 
						|
            Input.isKeyJustPressed(Input.Keys.A) or Input.isKeyJustPressed(Input.Keys.B) or Input.isKeyJustPressed(Input.Keys.Start);
 | 
						|
 | 
						|
        if (shoulder != 0 or input_cond) {
 | 
						|
            size_idx +%= shoulder;
 | 
						|
            shape_idx %= 3;
 | 
						|
 | 
						|
            loadSprite(is_4bpp, shape_idx, size_idx, &sprite);
 | 
						|
        }
 | 
						|
 | 
						|
        x += Input.getHorizontal() * 2;
 | 
						|
        y += Input.getVertical() * 2;
 | 
						|
 | 
						|
        sprite.setPosition(x, y);
 | 
						|
        attr_ptr[0] = sprite;
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
fn loadSprite(is_4bpp: bool, shape: usize, size: usize, sprite: *OAM.Attribute) void {
 | 
						|
    GBA.memset32(GBA.SPRITE_VRAM, 0, 0x8000); // Clear Sprite VRAM
 | 
						|
 | 
						|
    const idx = @as(usize, 12) * @boolToInt(is_4bpp) + 4 * shape + size;
 | 
						|
 | 
						|
    sprite.* = sprite_attrs[idx];
 | 
						|
    sprite_load_fns[idx]();
 | 
						|
}
 |