#include #include #include #include #include #include #include #include #include #include #include "together_8_img_bin.h" #include "together_8_pal_bin.h" // Define any soundbank includes here #include "soundbank.h" #include "soundbank_bin.h" // Global mixing buffer for maxmod u8 mixing_buffer[MM_MIXLEN_16KHZ] __attribute__((aligned(4))); // Set the two variables below to start the palette fade // The number of steps to fade the palette to black const u8 palette_fade_steps = 12; // The current step of the palette fade, set this to above to start the fade, the fade will decrement this value until it reaches 0 u8 palette_fade_step = 0; const u8 fade_pause_frames = 120; u8 fade_pause_frame_count = 0; // Function Prototypes void initializeSystem(void); void loadIntroScreen(void); void fadePaletteStep(void); int main(void) { // Initialize GBA system and maxmod initializeSystem(); // Load intro screen loadIntroScreen(); // Wait for VBlank before starting music VBlankIntrWait(); mmStart(MOD_MOZARTSONATA, MM_PLAY_LOOP); // Main game loop while(1) { VBlankIntrWait(); // Update sound system mmFrame(); // Game logic goes here scanKeys(); u16 keys = keysDown(); // Check for key presses if (keys & KEY_A) { mmEffect(SFX_WEAPON); } if ((keys & KEY_START) && palette_fade_step == 0) { // Start the palette fade palette_fade_step = palette_fade_steps; } else if (keys & KEY_SELECT) { // Reset the palette to the original DMA3COPY(together_8_pal_bin, BG_PALETTE, together_8_pal_bin_size >> 1); } fadePaletteStep(); } return 0; } void initializeSystem(void) { // Initialize GBA display and interrupt system irqInit(); irqSet(IRQ_VBLANK, mmVBlank); irqEnable(IRQ_VBLANK); // Initialize display registers for Mode 4 (8-bit paletted bitmap) SetMode(MODE_4 | BG2_ON); // Mode 4 + Enable BG2 mmInitDefault((mm_addr)soundbank_bin, 8); } void loadIntroScreen(void) { // Wait for VBlank before copying VBlankIntrWait(); // Load the palette // Palette size needs to be in 16-bit units (divide by 2) DMA3COPY(together_8_pal_bin, BG_PALETTE, together_8_pal_bin_size >> 1); // Copy image data to first frame buffer // Image size needs to be in 16-bit units (divide by 2) DMA3COPY(together_8_img_bin, (void*)VRAM, together_8_img_bin_size >> 1); } // increment the palette fade step by 1 void fadePaletteStep(void) { if (fade_pause_frame_count > fade_pause_frames) { ++fade_pause_frame_count; return; } fade_pause_frame_count = 0; if (palette_fade_steps && palette_fade_step) { // Calculate how much to keep of each color component in this step // As palette_fade_step goes from palette_fade_steps down to 1, // this ratio goes from 1.0 down to nearly 0.0 // -1 is so the last step is fully black. u16 keep_ratio = (((u16)palette_fade_step - 1) << 7) / (u16)palette_fade_steps; // fade the palette to black, by iterating over the palette memory one position at a time for (u16 i = 0; i < 256; ++i) { u16 color = ((u16*)together_8_pal_bin)[i]; // Extract RGB components (GBA uses 5 bits per component) u16 r = (color & 0x1F); u16 g = (color >> 5) & 0x1F; u16 b = (color >> 10) & 0x1F; // Reduce each component based on current step r = (r * keep_ratio) >> 7; g = (g * keep_ratio) >> 7; b = (b * keep_ratio) >> 7; // Recombine the components u16 new_color = (b << 10) | (g << 5) | r; BG_PALETTE[i] = new_color; } --palette_fade_step; } }