Skip to content

Instantly share code, notes, and snippets.

@felixjones
Created October 13, 2019 22:53
Show Gist options
  • Save felixjones/b52b2df1f9d5aeecb1306aaba628173c to your computer and use it in GitHub Desktop.
Save felixjones/b52b2df1f9d5aeecb1306aaba628173c to your computer and use it in GitHub Desktop.
gba++ clone of rust gba-console's hello_world.rs example
#include <gba/gba.hpp>
#define EVER ;;
using namespace gba;
static auto& DISPCNT = io::display::control;
static auto& DISPSTAT = io::display::status;
static auto& IE = io::interrupt::enable_mask;
static auto& IME = io::interrupt::master_enable;
static auto& KEYINPUT = io::keypad::input;
static uint16 * const MODE_3 = reinterpret_cast<uint16 *>( 0x6000000 );
static volatile const uint32 ZERO = 0; // volatile keeps this out of ROM for DMA fill use
int main( int argc, char * argv[] ) {
io::interrupt::vector = irq::empty_handler();
DISPCNT.write( display::control { .mode = 3, .background_layer2 = true } );
DISPSTAT.write( display::status { .emit_vblank = true, .emit_vcount = true, .vcount = 0 } );
IE.write( irq::bits { .vblank = true, .vcount = true } );
IME.write( true );
uint8 px = video::mode_limits<3>::width() / 2;
uint8 py = video::mode_limits<3>::height() / 2;
auto color = color::from_rgb24( 0xff0000 );
// Prepare DMA fill
io::dma::channel3.source( &ZERO ).destination( MODE_3 ).words( 240 * 80 );
for ( EVER ) {
// Read our keys for this frame
const auto this_frame_keys = keypad::state( KEYINPUT.read().value() );
// Adjust game state
px += 2 * this_frame_keys.axis_x();
py -= 2 * this_frame_keys.axis_y();
if ( this_frame_keys.button_l() ) {
color = color.rotl( 5 );
}
if ( this_frame_keys.button_r() ) {
color = color.rotr( 5 );
}
// Wait for VBlank
bios::vblank_intr_wait();
// Draw the new game state
if ( px >= video::mode_limits<3>::width() || py >= video::mode_limits<3>::height() ) {
// Out of bounds; reset screen
io::dma::channel3.control( dma::control {
.source = dma::src_fix,
.long_word = true,
.enabled = true
} );
// Reset position
px = video::mode_limits<3>::width() / 2;
py = video::mode_limits<3>::height() / 2;
} else {
// Draw next part of the line
MODE_3[( py * 240 ) + px] = color.to_uint16();
MODE_3[( py + 1 ) * 240 + px] = color.to_uint16();
MODE_3[( py * 240 ) + px + 1] = color.to_uint16();
MODE_3[( py + 1 ) * 240 + px + 1] = color.to_uint16();
}
// Wait for VDraw
bios::intr_wait( true, irq::bits { .vcount = true } );
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment