static void build_disp_list(void) { DCInvalidateRange(display_list, sizeof(display_list)); GX_BeginDispList(display_list, sizeof(display_list)); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); for (unsigned i = 0; i < 4; i++) { GX_Position1x8(i); GX_TexCoord1x8(i); } GX_End(); display_list_size = GX_EndDispList(); }
model_t* MODEL_setup(const u8* model_bmb) { binheader_t* header = (binheader_t*) model_bmb; const u32 posOffset = sizeof(binheader_t); const u32 nrmOffset = posOffset + (sizeof(f32)* header->vcount * 3); const u32 texOffset = nrmOffset + (sizeof(f32)* header->vcount * 3); const u32 indOffset = texOffset + (sizeof(f32)* header->vcount * 2); f32* positions = (f32*) (model_bmb + posOffset); f32* normals = (f32*) (model_bmb + nrmOffset); f32* texcoords = (f32*) (model_bmb + texOffset); u16* indices = (u16*) (model_bmb + indOffset); /* Calculate cost */ const u32 indicesCount = header->fcount * 3; const u32 indicesSize = indicesCount * 3 * sizeof(u16); /* 3 indices per vertex index (p,n,t) that are u16 in size */ const u32 callSize = 89; /* Size of setup var */ /* Round up to nearest 32 multiplication */ const u32 dispSize = (((indicesSize + callSize + 63) >> 5) + 1) << 5; /* Build display list */ /* Allocate and clear */ u32 i; void* modelList = memalign(32, dispSize); memset(modelList, 0, dispSize); /* Set buffer data */ DCInvalidateRange(modelList, dispSize); GX_BeginDispList(modelList, dispSize); //GX_InvVtxCache(); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_INDEX16); GX_SetVtxDesc(GX_VA_NRM, GX_INDEX16); GX_SetVtxDesc(GX_VA_TEX0, GX_INDEX16); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetArray(GX_VA_POS, (void*) positions, 3 * sizeof(f32)); GX_SetArray(GX_VA_NRM, (void*) normals, 3 * sizeof(f32)); GX_SetArray(GX_VA_TEX0, (void*) texcoords, 2 * sizeof(f32)); /* Fill the list with indices */ GX_Begin(GX_TRIANGLES, GX_VTXFMT0, indicesCount); for (i = 0; i < indicesCount; i++) { GX_Position1x16(indices[i]); GX_Normal1x16(indices[i]); GX_TexCoord1x16(indices[i]); } GX_End(); /* Close display list */ u32 modelListSize = GX_EndDispList(); if (modelListSize == 0) { printf("Error: Display list not big enough [%u]\n", dispSize); return NULL; } /* Return model info */ model_t* model = malloc(sizeof(model_t)); model->modelList = modelList; model->modelListSize = modelListSize; model->modelFaceCount = header->fcount; model->modelPositions = positions; model->modelNormals = normals; model->modelTexcoords = texcoords; model->modelIndices = indices; return model; }
void GuiFrameImage::CreateDrawList() { GX_BeginDispList(DrawList, DrawListSize+64); GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); GX_SetVtxDesc (GX_VA_TEX0, GX_NONE); oldWidth = GetWidth(); oldHeight = GetHeight(); oldX = GetLeft(); oldY = GetTop(); oldZ = 0; oldAlpha = GetAlpha(); f32 alpha = oldAlpha; f32 z = oldZ; f32 x1 = oldX; f32 y1 = oldY; f32 x2 = x1+oldWidth; f32 y2 = y1+oldHeight; //! Upper QUAD GX_Begin(GX_QUADS, GX_VTXFMT0,4); GX_Position3f32(x1+Margin, y1, z); GX_Color4u8(UpperQuadUpper.r,UpperQuadUpper.g,UpperQuadUpper.b,alpha); GX_Position3f32(x2-Margin, y1, z); GX_Color4u8(UpperQuadUpper.r,UpperQuadUpper.g,UpperQuadUpper.b,alpha); GX_Position3f32(x2-Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); GX_Position3f32(x1+Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); GX_End(); //! Upper/Left Corner Circle GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, Precision+1); { f32 deg; int r = SideQuadUpper.r; int g = SideQuadUpper.g; int b = SideQuadUpper.b; f32 r_p = (float) (UpperQuadUpper.r - r)/(float) (Precision-1); f32 g_p = (float) (UpperQuadUpper.g - g)/(float) (Precision-1); f32 b_p = (float) (UpperQuadUpper.b - b)/(float) (Precision-1); GX_Position3f32(x1+Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); for(int i = 0; i < Precision; ++i) { deg = DegToRad(180+i*90/(f32)(Precision-1)); GX_Position3f32(x1+Margin+Margin*cos(deg), y1+Margin+Margin*sin(deg), z); GX_Color4u8(r+r_p*i, g+g_p*i, b+b_p*i,alpha); } } GX_End(); //! Left QUAD GX_Begin(GX_QUADS, GX_VTXFMT0,4); GX_Position3f32(x1, y1+Margin, z); GX_Color4u8(SideQuadUpper.r,SideQuadUpper.g,SideQuadUpper.b,alpha); GX_Position3f32(x1+Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); GX_Position3f32(x1+Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); GX_Position3f32(x1, y2-Margin, z); GX_Color4u8(SideQuadLower.r,SideQuadLower.g,SideQuadLower.b,alpha); GX_End(); //! Lower Left Corner Circle GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, Precision*2+2); { //! Transparent shadow f32 deg; int r = ShadowLower.r; int g = ShadowLower.g; int b = ShadowLower.b; f32 a = 0.1f*alpha; f32 r_p = (float) (SideQuadLower.r - r)/(float) (Precision-1); f32 g_p = (float) (SideQuadLower.g - g)/(float) (Precision-1); f32 b_p = (float) (SideQuadLower.b - b)/(float) (Precision-1); f32 a_p = (float) (alpha - a)/(float) (Precision-1); GX_Position3f32(x1+Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); for(int i = 0; i < Precision; ++i) { deg = DegToRad(90+i*90/(f32)(Precision-1)); GX_Position3f32(x1+Margin+Margin*cos(deg), y2-Margin+Margin*sin(deg), z); GX_Color4u8(r+r_p*i, g+g_p*i, b+b_p*i, a+a_p*i); } //! Opaque r = ShadowUpper.r; g = ShadowUpper.g; b = ShadowUpper.b; r_p = (float) (SideQuadLower.r - r)/(float) (Precision-1); g_p = (float) (SideQuadLower.g - g)/(float) (Precision-1); b_p = (float) (SideQuadLower.b - b)/(float) (Precision-1); GX_Position3f32(x1+Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); for(int i = 0; i < Precision; ++i) { deg = DegToRad(90+i*90/(f32)(Precision-1)); GX_Position3f32(x1+Margin+Margin*cos(deg), y2-Margin+(Margin-ShadowWidth)*sin(deg), z); GX_Color4u8(r+r_p*i, g+g_p*i, b+b_p*i, alpha); } } GX_End(); //! Lower QUAD GX_Begin(GX_QUADS, GX_VTXFMT0,8); //! Transparent shadow quad GX_Position3f32(x1+Margin, y2-Margin, z); GX_Color4u8(ShadowUpper.r,ShadowUpper.g,ShadowUpper.b,alpha); GX_Position3f32(x2-Margin, y2-Margin, z); GX_Color4u8(ShadowUpper.r,ShadowUpper.g,ShadowUpper.b,alpha); GX_Position3f32(x2-Margin, y2, z); GX_Color4u8(ShadowLower.r,ShadowLower.g,ShadowLower.b,0.1f*alpha); GX_Position3f32(x1+Margin, y2, z); GX_Color4u8(ShadowLower.r,ShadowLower.g,ShadowLower.b,0.1f*alpha); //! Opaque quad GX_Position3f32(x1+Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); GX_Position3f32(x2-Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); GX_Position3f32(x2-Margin, y2-ShadowWidth, z); GX_Color4u8(ShadowUpper.r,ShadowUpper.g,ShadowUpper.b,alpha); GX_Position3f32(x1+Margin, y2-ShadowWidth, z); GX_Color4u8(ShadowUpper.r,ShadowUpper.g,ShadowUpper.b,alpha); GX_End(); //! Lower Right Corner Circle GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, Precision*2+2); { f32 deg; int r = SideQuadLower.r; int g = SideQuadLower.g; int b = SideQuadLower.b; f32 a = alpha; f32 r_p = (float) (ShadowLower.r - r)/(float) (Precision-1); f32 g_p = (float) (ShadowLower.g - g)/(float) (Precision-1); f32 b_p = (float) (ShadowLower.b - b)/(float) (Precision-1); f32 a_p = (float) (0.1f*alpha - a)/(float) (Precision-1); GX_Position3f32(x2-Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); for(int i = 0; i < Precision; ++i) { deg = DegToRad(i*90/(f32)(Precision-1)); GX_Position3f32(x2-Margin+Margin*cos(deg), y2-Margin+Margin*sin(deg), z); GX_Color4u8(r+r_p*i, g+g_p*i, b+b_p*i, a+a_p*i); } r_p = (float) (ShadowUpper.r - r)/(float) (Precision-1); g_p = (float) (ShadowUpper.g - g)/(float) (Precision-1); b_p = (float) (ShadowUpper.b - b)/(float) (Precision-1); GX_Position3f32(x2-Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); for(int i = 0; i < Precision; ++i) { deg = DegToRad(i*90/(f32)(Precision-1)); GX_Position3f32(x2-Margin+Margin*cos(deg), y2-Margin+(Margin-ShadowWidth)*sin(deg), z); GX_Color4u8(r+r_p*i, g+g_p*i, b+b_p*i, alpha); } } GX_End(); //! Right QUAD GX_Begin(GX_QUADS, GX_VTXFMT0,4); GX_Position3f32(x2-Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); GX_Position3f32(x2, y1+Margin, z); GX_Color4u8(SideQuadUpper.r,SideQuadUpper.g,SideQuadUpper.b,alpha); GX_Position3f32(x2, y2-Margin, z); GX_Color4u8(SideQuadLower.r,SideQuadLower.g,SideQuadLower.b,alpha); GX_Position3f32(x2-Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); GX_End(); //! Upper/Left Corner Circle GX_Begin(GX_TRIANGLEFAN, GX_VTXFMT0, Precision+1); { f32 deg; int r = UpperQuadUpper.r; int g = UpperQuadUpper.g; int b = UpperQuadUpper.b; f32 r_p = (float) (SideQuadUpper.r - r)/(float) (Precision-1); f32 g_p = (float) (SideQuadUpper.g - g)/(float) (Precision-1); f32 b_p = (float) (SideQuadUpper.b - b)/(float) (Precision-1); GX_Position3f32(x2-Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); for(int i = 0; i < Precision; ++i) { deg = DegToRad(270+i*90/(f32)(Precision-1)); GX_Position3f32(x2-Margin+Margin*cos(deg), y1+Margin+Margin*sin(deg), z); GX_Color4u8(r+r_p*i, g+g_p*i, b+b_p*i,alpha); } } GX_End(); //! Main QUAD GX_Begin(GX_QUADS, GX_VTXFMT0,4); GX_Position3f32(x1+Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); GX_Position3f32(x2-Margin, y1+Margin, z); GX_Color4u8(MainQuadUpper.r,MainQuadUpper.g,MainQuadUpper.b,alpha); GX_Position3f32(x2-Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); GX_Position3f32(x1+Margin, y2-Margin, z); GX_Color4u8(MainQuadLower.r,MainQuadLower.g,MainQuadLower.b,alpha); GX_End(); GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE); DrawListSize = GX_EndDispList(); }
int BuildLists(GXTexObj texture) { // Make the new display list // For display lists, each command has an associated "cost" in bytes. // Add all these up to calculate the size of your display list before rounding up. // eke-eke says GX_Begin() costs 3 bytes (u8 + u16) // According to my research: // GX_Position3f32() is 12 bytes (f32*3) // GX_Normal3f32() is 12 bytes (f32*3) // GX_Color3f32() is actually 3 bytes ((f32 -> u8) * 3) // GX_TexCoord2f32() is 8 bytes (f32*2) // GX_End() seems to cost zero (there's no actual code in it) // Size -must- be multiple of 32, so (12*24) + (12*24) + (3*24) + (8*24) + 3 = 843 // Rounded up to the nearest 32 is 864. // NOTE: Actual size may be up to 63 bytes -larger- than you calculate it to be due to padding and cache alignment. for (int i=0; i<5;i++) { boxList[i] = memalign(32,896); memset(boxList[i],0,896); DCInvalidateRange(boxList[i],896); GX_BeginDispList(boxList[i],896); GX_Begin(GX_QUADS,GX_VTXFMT0,24); // Start drawing // Bottom face GX_Position3f32(-1.0f,-1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,1.0f); // Top right GX_Position3f32( 1.0f,-1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,1.0f); // Top left GX_Position3f32( 1.0f,-1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,0.0f); // Bottom left GX_Position3f32(-1.0f,-1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,0.0f); // Bottom right // Front face GX_Position3f32(-1.0f,-1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,0.0f); // Bottom left GX_Position3f32( 1.0f,-1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,0.0f); // Bottom right GX_Position3f32( 1.0f, 1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,1.0f); // Top right GX_Position3f32(-1.0f, 1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,1.0f); // Top left // Back face GX_Position3f32(-1.0f,-1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,0.0f); // Bottom right GX_Position3f32(-1.0f, 1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,1.0f); // Top right GX_Position3f32( 1.0f, 1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,1.0f); // Top left GX_Position3f32( 1.0f,-1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,0.0f); // Bottom left // Right face GX_Position3f32( 1.0f,-1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,0.0f); // Bottom right GX_Position3f32( 1.0f, 1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,1.0f); // Top right GX_Position3f32( 1.0f, 1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,1.0f); // Top left GX_Position3f32( 1.0f,-1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,0.0f); // Bottom left // Left face GX_Position3f32(-1.0f,-1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,0.0f); // Bottom right GX_Position3f32(-1.0f,-1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,0.0f); // Top right GX_Position3f32(-1.0f, 1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(1.0f,1.0f); // Top left GX_Position3f32(-1.0f, 1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(BoxColors[i][0],BoxColors[i][1],BoxColors[i][2]); GX_TexCoord2f32(0.0f,1.0f); // Bottom left // Top face GX_Position3f32(-1.0f, 1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(TopColors[i][0],TopColors[i][1],TopColors[i][2]); GX_TexCoord2f32(0.0f,1.0f); // Top left GX_Position3f32(-1.0f, 1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(TopColors[i][0],TopColors[i][1],TopColors[i][2]); GX_TexCoord2f32(0.0f,0.0f); // Bottom left GX_Position3f32( 1.0f, 1.0f, 1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(TopColors[i][0],TopColors[i][1],TopColors[i][2]); GX_TexCoord2f32(1.0f,0.0f); // Bottom rught GX_Position3f32( 1.0f, 1.0f,-1.0f); GX_Normal3f32((f32)0,(f32)0,(f32)1); GX_Color3f32(TopColors[i][0],TopColors[i][1],TopColors[i][2]); GX_TexCoord2f32(1.0f,1.0f); // Top right GX_End(); // Done drawing quads // GX_EndDispList() returns the size of the display list, so store that value and use it with GX_CallDispList(). boxSize[i] = GX_EndDispList(); // Done building the box list if (boxSize[i] == 0) return 1; } // setup texture coordinate generation // args: texcoord slot 0-7, matrix type, source to generate texture coordinates from, matrix to use GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); // Set up TEV to paint the textures properly. GX_SetTevOp(GX_TEVSTAGE0,GX_MODULATE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); // Load up the textures (just one this time). GX_LoadTexObj(&texture, GX_TEXMAP0); return 0; }