#include <ogcsys.h> #include <malloc.h> #include <string.h> #include "vga.h" #include "types.h" #include "screen.h" #include "globals.h" #define DEFAULT_FIFO_SIZE (256*1024) static unsigned char gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32); static void *xfb[2] = { NULL, NULL }; static GXRModeObj *vmode; static GXTexObj texObj; static Mtx44 perspective; static Mtx GXmodelView2D; static unsigned short palette[256]; void *textureMem = NULL; int whichbuffer = 0; int screenWidth, screenHeight; // resolution of TV screen int xOffset, yOffset; int scaledWidth, scaledHeight; int textureWidth, textureHeight; // dimensions of game screen float yscale; // scale factor from EFB to XFB void drawSpriteTex(int x, int y, int width, int height); static void video_gx_init() { GXColor background = { 0, 0, 0, 0xff }; // clear out FIFO area and initialize GX memset(gp_fifo,0,DEFAULT_FIFO_SIZE); GX_Init(gp_fifo,DEFAULT_FIFO_SIZE); // clears the screen to black and clears the z buffer GX_SetCopyClear(background, 0x00ffffff); // other GX setup GX_SetViewport(0,0,vmode->fbWidth,vmode->efbHeight,0,1); yscale = GX_GetYScaleFactor(vmode->efbHeight,vmode->xfbHeight); GX_SetDispCopyYScale(yscale); GX_SetScissor(0,0,vmode->fbWidth,vmode->efbHeight); GX_SetDispCopySrc(0,0,vmode->fbWidth,vmode->efbHeight); GX_SetDispCopyDst(vmode->fbWidth,vmode->xfbHeight); GX_SetCopyFilter(vmode->aa,vmode->sample_pattern,GX_TRUE,vmode->vfilter); GX_SetFieldMode(vmode->field_rendering,((vmode->viHeight==2*vmode->xfbHeight)?GX_ENABLE:GX_DISABLE)); if (vmode->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_SetDispCopyGamma(GX_GM_1_0); // setup the vertex descriptor // tells the flipper to expect direct data GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_F32, 0); GX_SetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); GX_SetNumChans(1); GX_SetNumTexGens(1); GX_SetTevOp(GX_TEVSTAGE0, GX_REPLACE); GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); GX_SetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); } void video_init() { VIDEO_Init(); vmode = VIDEO_GetPreferredMode(NULL); // Widescreen fix screenHeight = vmode->xfbHeight; if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) screenWidth = screenHeight*16/9; else screenWidth = vmode->fbWidth; VIDEO_Configure(vmode); // Allocate 2 video buffers for double buffering xfb[0] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode)); xfb[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(vmode)); // Clear framebuffers, etc. VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK); VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK); VIDEO_SetNextFramebuffer(xfb[whichbuffer]); VIDEO_SetBlack(FALSE); VIDEO_Flush(); VIDEO_WaitVSync(); if(vmode->viTVMode & VI_NON_INTERLACE) VIDEO_WaitVSync(); video_gx_init(); // Finally, the video is up and ready for use :) } int video_set_mode(s_videomodes videomodes) { float texScaleX, texScaleY; GX_InvalidateTexAll(); textureWidth = videomodes.hRes; textureHeight = videomodes.vRes; textureMem = memalign(32, GX_GetTexBufferSize(textureWidth, textureHeight, pixelformat==PIXEL_32?GX_TF_RGBA8:GX_TF_RGB565, 0, 0)); guOrtho(perspective,0,479,0,639,0,300); GX_LoadProjectionMtx(perspective, GX_ORTHOGRAPHIC); // Determine x and y scale factors texScaleX = (float)screenWidth / textureWidth; texScaleY = (float)screenHeight / textureHeight; if(texScaleX < texScaleY) texScaleY = texScaleX; else if (texScaleY < texScaleX) texScaleX = texScaleY; // Determine on-screen dimensions scaledWidth = (int)(textureWidth * texScaleX); scaledHeight = (int)(textureHeight * texScaleY) / yscale; // Determine offsets xOffset = (screenWidth-scaledWidth) / 2; yOffset = (vmode->efbHeight-scaledHeight) / 2; // Compensate for widescreen displays if(CONF_GetAspectRatio() == CONF_ASPECT_16_9) { scaledWidth = scaledWidth*3/4; xOffset = xOffset*3/4; } return 1; } void video_clearscreen() { GXColor background = { 0, 0, 0, 0xff }; GX_SetCopyClear (background, 0x00ffffff); } void vga_vwait(void) { VIDEO_WaitVSync(); } void vga_setpalette(unsigned char* pal) { int i; for(i=0;i<256;i++) { palette = (pal[0]>>3<<11) | (pal[1]>>2<<5) | (pal[2]>>3); pal+=3; } } /*********** Code to actually write the image data to the screen *************/ void drawSpriteTex(int x, int y, int width, int height) { GX_Begin(GX_QUADS, GX_VTXFMT0, 4); // Draw A Quad GX_Position2f32(x, y); // Top Left GX_TexCoord2f32(0.0, 0.0); GX_Position2f32(x+width-1, y); // Top Right GX_TexCoord2f32(1.0, 0.0); GX_Position2f32(x+width-1, y+height-1); // Bottom Right GX_TexCoord2f32(1.0, 1.0); GX_Position2f32(x, y+height-1); // Bottom Left GX_TexCoord2f32(0.0, 1.0); GX_End(); // Done Drawing The Quad } inline void Set_RGB565Pixel(int x, int y, u16 color) { u8 *truc = (u8*) textureMem; u32 offset; offset = (((y >> 2) << 3) * textureWidth) + ((x >> 2) << 5) + (((y % 4 << 2) + x % 4) << 1); *(truc + offset) = (color >> 8) & 0xFF; *(truc + offset + 1) = color & 0xFF; } inline void Set_RGBAPixel(int x, int y, u32 color) { u8* truc = (u8*) textureMem; u32 offset; offset = (((y >> 2) << 4) * textureWidth) + ((x >> 2) << 6) + (((y % 4 << 2) + x % 4) << 1); *(truc + offset) = color & 0xFF; *(truc + offset + 1) = (color >> 24) & 0xFF; *(truc + offset + 32) = (color >> 16) & 0xFF; *(truc + offset + 33) = (color >> 8) & 0xFF; } void copyscreen8(s_screen* src) { u16 x, y; u8* data = (u8*)src->data; for(y=0; yfbWidth, vmode->efbHeight, 0, 1); GX_InvVtxCache(); GX_InvalidateTexAll(); GX_ClearVtxDesc(); GX_SetVtxDesc(GX_VA_POS, GX_DIRECT); GX_SetVtxDesc(GX_VA_TEX0, GX_DIRECT); switch(pixelformat) { case PIXEL_8: case PIXEL_x8: copyscreen8(src); GX_InitTexObj (&texObj, textureMem, textureWidth, textureHeight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); break; case PIXEL_16: copyscreen16(src); GX_InitTexObj (&texObj, textureMem, textureWidth, textureHeight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); break; case PIXEL_32: copyscreen32(src); GX_InitTexObj (&texObj, textureMem, textureWidth, textureHeight, GX_TF_RGBA8, GX_CLAMP, GX_CLAMP, GX_FALSE); } GX_LoadTexObj(&texObj, GX_TEXMAP0); guMtxIdentity(GXmodelView2D); guMtxTransApply (GXmodelView2D, GXmodelView2D, 0.0F, 0.0F, 0.0F); GX_LoadPosMtxImm(GXmodelView2D, GX_PNMTX0); drawSpriteTex(xOffset, yOffset/yscale, scaledWidth, scaledHeight); GX_DrawDone(); GX_SetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); GX_SetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); GX_SetAlphaUpdate(GX_TRUE); GX_SetColorUpdate(GX_TRUE); GX_CopyDisp(xfb[whichbuffer],GX_TRUE); VIDEO_SetNextFramebuffer(xfb[whichbuffer]); VIDEO_Flush(); VIDEO_WaitVSync(); whichbuffer ^= 1; // flip framebuffer return 1; }
Re: GX issue May 22, 2010 09:22AM | Registered: 14 years ago Posts: 118 |
GX_CopyDisp(xfb[whichbuffer],GX_TRUE); VIDEO_SetNextFramebuffer(xfb[whichbuffer]); VIDEO_Flush(); VIDEO_WaitVSync(); whichbuffer ^= 1; // flip framebuffer
whichbuffer ^= 1; // flip framebuffer GX_CopyDisp(xfb[whichbuffer],GX_TRUE); VIDEO_SetNextFramebuffer(xfb[whichbuffer]); VIDEO_Flush(); VIDEO_WaitVSync();
Re: GX issue May 22, 2010 04:09PM | Registered: 14 years ago Posts: 12 |
Re: GX issue May 22, 2010 06:33PM | Registered: 14 years ago Posts: 12 |