Skip to content

Commit

Permalink
Rename repo to Zig GBA to build more of a SDK
Browse files Browse the repository at this point in the history
* Add GBA static library
* Create examples folder and move "Hello World" to examples/first
* Add GBA/builder.zig helper for simplifying setup of building GBA ROM
  • Loading branch information
wendigojaeger committed Dec 14, 2019
1 parent 331e320 commit eeb42c7
Show file tree
Hide file tree
Showing 9 changed files with 93 additions and 43 deletions.
1 change: 1 addition & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"label": "Format current file",
"type": "shell",
"command": "zig fmt ${file}",
"problemMatcher": []
}
]
}
72 changes: 72 additions & 0 deletions GBA/builder.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
const Builder = @import("std").build.Builder;
const LibExeObjStep = @import("std").build.LibExeObjStep;
const builtin = @import("std").builtin;
const fmt = @import("std").fmt;
const FixedBufferAllocator = @import("std").heap.FixedBufferAllocator;
const std = @import("std");
const fs = @import("std").fs;

const GBALinkerScript = "GBA/gba.ld";

fn gbaThumbTarget() std.Target {
return std.Target{
.Cross = std.Target.Cross{
.arch = std.Target.Arch{ .thumb = std.Target.Arch.Arm32.v4t },
.os = .freestanding,
.abi = .none,
},
};
}

pub fn addGBAStaticLibrary(b: *Builder, libraryName: []const u8, sourceFile: []const u8) *LibExeObjStep {
const lib = b.addStaticLibrary(libraryName, sourceFile);

lib.setTheTarget(gbaThumbTarget());

lib.setLinkerScriptPath(GBALinkerScript);
lib.setBuildMode(builtin.Mode.ReleaseFast);

return lib;
}

pub fn createGBALib(b: *Builder) *LibExeObjStep {
return addGBAStaticLibrary(b, "ZigGBA", "GBA/gba.zig");
}

pub fn addGBAExecutable(b: *Builder, romName: []const u8, sourceFile: []const u8) *LibExeObjStep {
const exe = b.addExecutable(romName, sourceFile);

exe.setTheTarget(gbaThumbTarget());

exe.setOutputDir("zig-cache/raw");
exe.setLinkerScriptPath(GBALinkerScript);
exe.setBuildMode(builtin.Mode.ReleaseFast);

const gbaLib = createGBALib(b);
exe.addPackagePath("gba", "GBA/gba.zig");
exe.linkLibrary(gbaLib);

var allocBuffer: [4 * 1024]u8 = undefined;
var fixed = FixedBufferAllocator.init(allocBuffer[0..]);
const fixedAllocator = &fixed.allocator;

const outputPath = fmt.allocPrint(fixedAllocator, "zig-cache/bin/{}.gba", .{romName}) catch unreachable;

if (fs.path.dirname(outputPath)) |dirPath| {
_ = fs.makePath(fixedAllocator, dirPath) catch unreachable;
}

// TODO: Use builtin raw output when available in Zig compiler
const objCopyCommand = if (builtin.os == builtin.Os.windows) "C:\\Programmation\\Zig\\llvm+clang-9.0.0-win64-msvc-mt\\bin\\llvm-objcopy.exe" else "llvm-objcopy";
const buildGBARomCommand = b.addSystemCommand(&[_][]const u8{
objCopyCommand, exe.getOutputPath(),
"-O", "binary",
outputPath,
});

buildGBARomCommand.step.dependOn(&exe.step);

b.default_step.dependOn(&buildGBARomCommand.step);

return exe;
}
File renamed without changes.
14 changes: 9 additions & 5 deletions src/gba.zig → GBA/gba.zig
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ pub const GBA = struct {
pub const Object = 0x1000;
};

pub inline fn toNativeColor(comptime red: u32, comptime green: u32, comptime blue: u32) u16 {
return @as(u16, (red | (green << 5) | (blue << 10)));
pub inline fn toNativeColor(comptime red: u8, comptime green: u8, comptime blue: u8) u16 {
return @as(u16, red & 0x1f) | (@as(u16, green & 0x1f) << 5) | (@as(u16, blue & 0x1f) << 10);
}

pub inline fn setupDisplay(mode: DisplayMode, layers: u32) void {
Expand All @@ -158,7 +158,7 @@ pub const GBA = struct {

// TODO: Figure out how to pass the reset flags and don't get eaten up by the optimizer
pub fn BIOSRegisterRamReset() void {
asm volatile(
asm volatile (
\\movs r0, #0xFF
\\swi 1
);
Expand Down Expand Up @@ -187,5 +187,9 @@ export nakedcc fn GBAMain() noreturn {
GBA.BIOSRegisterRamReset();

// call user's main
root.main();
}
if (@hasDecl(root, "main")) {
root.main();
} else {
while (true) {}
}
}
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
# Zig GBA "Hello World"
# Zig GBA

This is a simple GBA program that display 3 color pixel as a hello world to the system. Also a testament to the Zig excellent cross-compile functionality !
This is a work in progress SDK for creating Game Boy Advance games using [Zig](https://ziglang.org/) programming language. Once Zig has a proper package manager, I hope that it would as easy as import the ZigGBA package. Inspired by [TONC GBA tutorial](https://www.coranac.com/tonc/text/)

## Build
This project assume current Zig master (0.5.0+d28aa38db). For now, you need llvm-objcopy in your PATH or change the hardcoded path in build.zig.
This project assume current Zig master (0.5.0+a3f6a58c7). For now, you need llvm-objcopy in your PATH or change the hardcoded path in GBA/builder.zig.

To build, simply use Zig's integrated build system
```Shell
zig build
```

## Running in a emulator
## First example running in a emulator

![Emulator image](docs/Emulator.png)
![First example emulator image](docs/images/FirstExampleEmulator.png)

## Running on real hardware
## First example running on real hardware

![Real hardware image](docs/RealHardware.png)
![First example real hardware image](docs/images/FirstExampleRealHardware.png)
31 changes: 2 additions & 29 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,33 +1,6 @@
const Builder = @import("std").build.Builder;
const builtin = @import("std").builtin;
const std = @import("std");
usingnamespace @import("GBA/builder.zig");

pub fn build(b: *Builder) void {
const exe = b.addExecutable("GBAHelloWorld", "src/main.zig");

exe.setTheTarget(std.Target {
.Cross = std.Target.Cross {
.arch = std.Target.Arch {
.thumb = std.Target.Arch.Arm32.v4t
},
.os = .freestanding,
.abi = .none
}
});

exe.setOutputDir("zig-cache/raw");
exe.setLinkerScriptPath("gba.ld");
exe.setBuildMode(builtin.Mode.ReleaseFast);

const objCopyCommand = if (builtin.os == builtin.Os.windows) "C:\\Programmation\\Zig\\llvm+clang-9.0.0-win64-msvc-mt\\bin\\llvm-objcopy.exe" else "llvm-objcopy";

const buildGBARomCommand = b.addSystemCommand(&[_][]const u8 {
objCopyCommand, exe.getOutputPath(),
"-O", "binary",
"zig-cache/bin/GBAHelloWorld.gba",
});

buildGBARomCommand.step.dependOn(&exe.step);

b.default_step.dependOn(&buildGBARomCommand.step);
const first = addGBAExecutable(b, "first", "examples/first/first.zig");
}
File renamed without changes
File renamed without changes
4 changes: 2 additions & 2 deletions src/main.zig → examples/first/first.zig
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const GBA = @import("gba.zig").GBA;
const GBA = @import("gba").GBA;

export var gameHeader linksection(".gbaheader") = GBA.Header.setup("HELLOWORLD", "AWJE", "00", 0);
export var gameHeader linksection(".gbaheader") = GBA.Header.setup("FIRST", "AFSE", "00", 0);

pub fn main() noreturn {
GBA.setupDisplay(GBA.DisplayMode.Mode3, GBA.DisplayLayers.Background2 | GBA.DisplayLayers.Background0);
Expand Down

0 comments on commit eeb42c7

Please sign in to comment.