#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <gccore.h>
#include <wiiuse/wpad.h>
#include <fat.h>
#include "libpng/pngu/pngu.h"
#define DEFAULT_FIFO_SIZE (256*1024)
typedef struct tagcamera {
guVector pos;
guVector up;
guVector view;
}camera;
s16 squares[] ATTRIBUTE_ALIGN(32) =
{
// x y z
-100, 70, 0, // 0
-40, 70, 0, // 1
-40, 10, 0, // 2
-100, 10, 0, // 3
-30, 70, 0, // 0
30, 70, 0, // 1
30, 10, 0, // 2
-30, 10, 0, // 3
40, 70, 0, // 0
100, 70, 0, // 1
100, 10, 0, // 2
40, 10, 0, // 3
-100, -10, 0, // 0
-40, -10, 0, // 1
-40, -70, 0, // 2
-100, -70, 0, // 3
-30, -10, 0, // 0
30, -10, 0, // 1
30, -70, 0, // 2
-30, -70, 0, // 3
40, -10, 0, // 0
100, -10, 0, // 1
100, -70, 0, // 2
40, -70, 0, // 3
};
// color data
u8 colors[] ATTRIBUTE_ALIGN(32) = {
// r, g, b, a
255, 255, 255, 255, // 0 white
240, 0, 0, 255, // 1 red
255, 180, 0, 255, // 2 orange
255, 255, 0, 255, // 3 yellow
10, 120, 40, 255, // 4 green
0, 20, 100, 255 // 5 blue
};
static void *xfb = NULL;
static GXRModeObj *rmode = NULL;
static u32 do_copy = GX_FALSE;
static float rotby=0;
GXTexObj texObj1;
GXTexObj texObj2;
GXTexObj texObj3;
GXTexObj texObj4;
GXTexObj texObj5;
GXTexObj texObj6;
camera cam = {{0.0F, 0.0F, 40.0F},
{0.0F, 1.0F, 0.0F},
{0.0F, 0.0F, -1.0F}};
void draw_init();
void draw_vert(u8 pos, u8 c, f32 s, f32 t);
void draw_square(Mtx v, int start);
static void copy_to_xfb(u32 count);
void movecamera(float speed);
void *texture_data1 = NULL;
void *texture_data2 = NULL;
void *texture_data3 = NULL;
void *texture_data4 = NULL;
void *texture_data5 = NULL;
void *texture_data6 = NULL;
PNGUPROP imgProp;
int main()
{
Mtx v,p; // view and perspective matrices
GXColor background = {0, 0, 0, 0xff};
IMGCTX ctx;
VIDEO_Init();
WPAD_Init();
// Init video system
rmode = VIDEO_GetPreferredMode(NULL);
xfb = MEM_K0_TO_K1(SYS_AllocateFramebuffer(rmode));
console_init(xfb,20,20,rmode->fbWidth,rmode->xfbHeight,rmode->fbWidth*VI_DISPLAY_PIX_SZ);
VIDEO_Configure(rmode);
VIDEO_SetNextFramebuffer(xfb);
VIDEO_SetPostRetraceCallback(copy_to_xfb);
VIDEO_SetBlack(FALSE);
VIDEO_Flush();
VIDEO_WaitVSync();
if(rmode->viTVMode&VI_NON_INTERLACE) VIDEO_WaitVSync();
// Init libfat
fatInitDefault ();
void *gp_fifo = NULL;
gp_fifo = MEM_K0_TO_K1(memalign(32,DEFAULT_FIFO_SIZE));
memset(gp_fifo,0,DEFAULT_FIFO_SIZE);
GX_Init(gp_fifo,DEFAULT_FIFO_SIZE);
GX_SetCopyClear(background, 0x00ffffff);
GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1);
GX_SetDispCopyYScale((f32)rmode->xfbHeight/(f32)rmode->efbHeight);
GX_SetScissor(0,0,rmode->fbWidth,rmode->efbHeight);
GX_SetDispCopySrc(0,0,rmode->fbWidth,rmode->efbHeight);
GX_SetDispCopyDst(rmode->fbWidth,rmode->xfbHeight);
GX_SetCopyFilter(rmode->aa,rmode->sample_pattern,GX_TRUE,rmode->vfilter);
GX_SetFieldMode(rmode->field_rendering,((rmode->viHeight==2*rmode->xfbHeight)?GX_ENABLE:GX_DISABLE));
if (rmode->aa)
GX_SetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR);
else
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
GX_SetCullMode(GX_CULL_NONE);
GX_CopyDisp(xfb,GX_TRUE);
GX_SetDispCopyGamma(GX_GM_1_0);
guPerspective(p, 60, 1.33F, 10.0F, 1000.0F);
GX_LoadProjectionMtx(p, GX_PERSPECTIVE);
draw_init();
// Load textures using PNGU
ctx = PNGU_SelectImageFromDevice ("textRGB.png");
PNGU_GetImageProperties (ctx, &imgProp);
texture_data1 = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 2);
GX_InitTexObj (&texObj1, texture_data1, imgProp.imgWidth, imgProp.imgHeight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
PNGU_DecodeTo4x4RGB565 (ctx, imgProp.imgWidth, imgProp.imgHeight, texture_data1);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (texture_data1, imgProp.imgWidth * imgProp.imgHeight * 2);
ctx = PNGU_SelectImageFromDevice ("textRGB.png");
PNGU_GetImageProperties (ctx, &imgProp);
texture_data2 = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 2);
GX_InitTexObj (&texObj2, texture_data2, imgProp.imgWidth, imgProp.imgHeight, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE);
PNGU_DecodeTo4x4RGB5A3 (ctx, imgProp.imgWidth, imgProp.imgHeight, texture_data2, 255);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (texture_data2, imgProp.imgWidth * imgProp.imgHeight * 2);
ctx = PNGU_SelectImageFromDevice ("textRGB.png");
PNGU_GetImageProperties (ctx, &imgProp);
texture_data3 = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 4);
GX_InitTexObj (&texObj3, texture_data3, imgProp.imgWidth, imgProp.imgHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, texture_data3, 255);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (texture_data3, imgProp.imgWidth * imgProp.imgHeight * 4);
ctx = PNGU_SelectImageFromDevice ("textRGBA.png");
PNGU_GetImageProperties (ctx, &imgProp);
texture_data4 = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 2);
GX_InitTexObj (&texObj4, texture_data4, imgProp.imgWidth, imgProp.imgHeight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE);
PNGU_DecodeTo4x4RGB565 (ctx, imgProp.imgWidth, imgProp.imgHeight, texture_data4);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (texture_data4, imgProp.imgWidth * imgProp.imgHeight * 2);
ctx = PNGU_SelectImageFromDevice ("textRGBA.png");
PNGU_GetImageProperties (ctx, &imgProp);
texture_data5 = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 2);
GX_InitTexObj (&texObj5, texture_data5, imgProp.imgWidth, imgProp.imgHeight, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, GX_FALSE);
PNGU_DecodeTo4x4RGB5A3 (ctx, imgProp.imgWidth, imgProp.imgHeight, texture_data5, 255);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (texture_data5, imgProp.imgWidth * imgProp.imgHeight * 2);
ctx = PNGU_SelectImageFromDevice ("textRGBA.png");
PNGU_GetImageProperties (ctx, &imgProp);
texture_data6 = memalign (32, imgProp.imgWidth * imgProp.imgHeight * 4);
GX_InitTexObj (&texObj6, texture_data6, imgProp.imgWidth, imgProp.imgHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE);
PNGU_DecodeTo4x4RGBA8 (ctx, imgProp.imgWidth, imgProp.imgHeight, texture_data6, 255);
PNGU_ReleaseImageContext (ctx);
DCFlushRange (texture_data6, imgProp.imgWidth * imgProp.imgHeight * 4);
while(1)
{
guLookAt(v, &cam.pos, &cam.up, &cam.view);
GX_SetViewport(0,0,rmode->fbWidth,rmode->efbHeight,0,1);
GX_InvVtxCache();
GX_InvalidateTexAll();
GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL);
GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GX_SetNumChans(1);
GX_LoadTexObj(&texObj1, GX_TEXMAP0);
draw_square(v, 0);
GX_LoadTexObj(&texObj2, GX_TEXMAP0);
draw_square(v, 4);
GX_LoadTexObj(&texObj3, GX_TEXMAP0);
draw_square(v, 8);
GX_LoadTexObj(&texObj4, GX_TEXMAP0);
draw_square(v, 12);
GX_LoadTexObj(&texObj5, GX_TEXMAP0);
draw_square(v, 16);
GX_LoadTexObj(&texObj6, GX_TEXMAP0);
draw_square(v, 20);
GX_DrawDone();
do_copy = GX_TRUE;
WPAD_ScanPads();
u32 pressed = WPAD_ButtonsDown(0);
if ( pressed & WPAD_BUTTON_HOME ) exit(0);
VIDEO_WaitVSync();
}
return 0;
}
void draw_init() {
GX_ClearVtxDesc();
GX_SetVtxDesc(GX_VA_POS, GX_INDEX8);
GX_SetVtxDesc(GX_VA_CLR0, GX_INDEX8);
GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
GX_SetArray(GX_VA_POS, squares, 3*sizeof(s16));
GX_SetArray(GX_VA_CLR0, colors, 4*sizeof(u8));
GX_SetNumTexGens(1);
GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GX_InvalidateTexAll();
}
void draw_vert(u8 pos, u8 c, f32 s, f32 t)
{
GX_Position1x8(pos);
GX_Color1x8(c);
GX_TexCoord2f32(s, t);
}
void draw_square (Mtx v, int start)
{
Mtx m; // model matrix.
Mtx mv; // modelview matrix.
guVector axis = {0,0,1};
guMtxIdentity(m);
guMtxRotAxisDeg(m, &axis, rotby);
guMtxTransApply(m, m, 0, 0, -100);
guMtxConcat(v,m,mv);
GX_LoadPosMtxImm(mv, GX_PNMTX0);
GX_Begin(GX_QUADS, GX_VTXFMT0, 4);
draw_vert(start, 0, 0.0, 0.0);
draw_vert(start+1, 0, 1.0, 0.0);
draw_vert(start+2, 0, 1.0, 1.0);
draw_vert(start+3, 0, 0.0, 1.0);
GX_End();
}
// copy efb to xfb when ready
static void copy_to_xfb(u32 count) {
if(do_copy==GX_TRUE) {
GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE);
GX_SetColorUpdate(GX_TRUE);
GX_CopyDisp(xfb,GX_TRUE);
GX_Flush();
do_copy = GX_FALSE;
}
}