Skip to content

Instantly share code, notes, and snippets.

@rw-r-r-0644
Last active May 31, 2019 16:47
Show Gist options
  • Save rw-r-r-0644/e76cac673d476682d2ca1b17f4286502 to your computer and use it in GitHub Desktop.
Save rw-r-r-0644/e76cac673d476682d2ca1b17f4286502 to your computer and use it in GitHub Desktop.
Wii U framebuffer library
/**
* @file fb.c
* @brief Wii U framebuffer library
* This file is under GNU GPL
* Copiright(c) 2017 rw-r-r_0644, QuarkTheAwesome
*/
#include "fb.h"
u32* gx2_regs;
fb_info_t fb_infos[2];
/* Setup screen buffer mode */
void fb_mode_setup(u32 device)
{
u32 reg_offset = device * 512;
u32 gx2_mode_reg = gx2_regs[reg_offset + WIIU_REG_FB_MODE];
gx2_regs[reg_offset + WIIU_REG_FB_MODE] = (gx2_mode_reg & 0xFF0FF8FC) | 0x100002;
gx2_regs[reg_offset + WIIU_REG_FB_MODE_UPDATE] = 1;
}
/* Sets up screen width for the buffer */
void fb_set_width(u32 device, u32 width)
{
u32 reg_offset = device * 512;
gx2_regs[reg_offset + WIIU_REG_FB_WIDTH1] = width & 0x3FFF;
gx2_regs[reg_offset + WIIU_REG_FB_WIDTH2] = width & 0x3FFF;
}
/* Set framebuffer hardware registers */
void fb_set_buffer(u32 device, u32* buffer)
{
u32 reg_offset = device * 512;
u32 buffer_phys = (u32)OSEffectiveToPhysical(buffer);
gx2_regs[reg_offset ^ WIIU_REG_FB_ADDR_UPDATE] = 0;
gx2_regs[reg_offset ^ WIIU_REG_FB_PHYS_ADDR] = (buffer_phys & 0xFFFFFF00) | 1;
fb_update(device);
}
/* Enable screen buffer */
void fb_enable(u32 device, int enable)
{
u32 reg_offset = device * 512;
u32 gx2_state_reg = gx2_regs[reg_offset + WIIU_REG_FB_STATE];
gx2_regs[reg_offset + WIIU_REG_FB_STATE] = (gx2_state_reg & 0xFFFFFEFF) | (!enable * 0x100); // 0x100 is the SCREEN_DISABLE flag
}
/* Update framebuffer */
void fb_update(u32 device)
{
fb_info_t* fb_info = &fb_infos[device];
DCFlushRange(fb_info->buffer, fb_info->buffer_size);
}
/* Clear the screen */
void fb_clear(u32 device, u32 color)
{
fb_info_t* fb_info = &fb_infos[device];
for (u32 i = 0; i < (fb_info->buffer_size / 4); i++)
fb_info->buffer[i] = color;
}
/* Init framebuffer */
void fb_init()
{
gx2_regs = __OSPhysicalToEffectiveUncached((void*)0xC200000);
/* Setup TV framebuffer */
fb_infos[SCREEN_TV].width = 1280;
fb_infos[SCREEN_TV].height = 720;
fb_infos[SCREEN_TV].buffer_size = ((fb_infos[SCREEN_TV].width * 4 + 0xFF) & 0xFFFFFF00) * fb_infos[SCREEN_TV].height;
fb_infos[SCREEN_TV].buffer = MEM1_alloc(fb_infos[SCREEN_TV].buffer_size, 0x40);
fb_mode_setup(SCREEN_TV);
fb_set_width(SCREEN_TV, fb_infos[SCREEN_TV].width);
fb_enable(SCREEN_TV, 1);
fb_clear(SCREEN_TV, 0);
fb_set_buffer(SCREEN_TV, fb_infos[SCREEN_TV].buffer);
/* Setup DRC framebuffer */
fb_infos[SCREEN_DRC].width = 896;
fb_infos[SCREEN_DRC].height = 480;
fb_infos[SCREEN_DRC].buffer_size = ((fb_infos[SCREEN_DRC].width * 4 + 0xFF) & 0xFFFFFF00) * fb_infos[SCREEN_DRC].height;
fb_infos[SCREEN_DRC].buffer = MEM1_alloc(fb_infos[SCREEN_DRC].buffer_size, 0x40);
fb_mode_setup(SCREEN_DRC);
fb_set_width(SCREEN_DRC, fb_infos[SCREEN_DRC].width);
fb_enable(SCREEN_DRC, 1);
fb_clear(SCREEN_DRC, 0);
fb_set_buffer(SCREEN_DRC, fb_infos[SCREEN_DRC].buffer);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment