int main() { suInit(); gfxInitDefault(); consoleInit(GFX_TOP, &topConsole); consoleSelect(&topConsole); cfguInit(); fsInit(); amInit(); fbTopLeft = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); fbTopRight = gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL); fbBottom = gfxGetFramebuffer(GFX_BOTTOM, 0, NULL, NULL); u8 next = mainMenu(); while (aptMainLoop()) { switch (next) { case 0: break; case 1: next = mainMenu(); break; //case 2: next = legitInstallMenu(); break; case 3: next = downgradeMenu(); break; //case 4: next = downgradeMSETMenu(); break; //case 5: next = downgradeBrowserMenu(); break; default: next = mainMenu(); } if (next == 0) break; } gfxExit(); return 0; }
void CollisionMap::debugDraw() { u8* screenLeft = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); u8* screenRight = gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL); int depthSeparation = 2; int move = (int)(depthSeparation * CONFIG_3D_SLIDERSTATE); for (int i = 0; i < nMapWidth; i++) { for (int j = 0; j < nMapHeight; j++) { if (map[i][j]) { drawPixel(i + move, j, 255, 0, 0, screenLeft); drawPixel(i - move, j, 255, 0, 0, screenRight); } else { //drawPixel(i, j, 0, 0, 255, screen); } } } //consoleClear(); //printf("\x1b[0;0H%01d %01d %01d %01d %01d %01d %01d %01d %01d %01d", // map[0][0], map[1][0], map[2][0], map[3][0], map[4][0], map[5][0], map[6][0], map[7][0], map[8][0], map[9][0]); }
void gfxFlushBuffers(void) { u32 topSize = 400 * 240 * __get_bytes_per_pixel(gfxGetScreenFormat(GFX_TOP)); u32 bottomSize = 320 * 240 * __get_bytes_per_pixel(gfxGetScreenFormat(GFX_BOTTOM)); GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), topSize); if(enable3d)GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), topSize); GSPGPU_FlushDataCache(gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), bottomSize); }
void mvd_colorconvert() { Result ret; FILE *f = NULL; u8* bufAdr = gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL); u8* gfxtopadr = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); MVDSTD_Config config; printf("mvd color-format-conversion example.\n"); f = fopen("sdmc:/mvd_indata.bin", "r"); if(f) { fread(inaddr, 1, 0x46500, f); fclose(f); } else { memcpy(inaddr, bufAdr, 320*240*3); } memset(gfxtopadr, 0, 0x46500); GSPGPU_FlushDataCache(inaddr, 0x46500); GSPGPU_FlushDataCache(gfxtopadr, 0x46500); ret = mvdstdInit(MVDMODE_COLORFORMATCONV, MVD_INPUT_YUYV422, MVD_OUTPUT_BGR565, 0, NULL); printf("mvdstdInit(): 0x%08x\n", (unsigned int)ret); if(ret==0) { mvdstdGenerateDefaultConfig(&config, 320, 240, 320, 240, (u32*)inaddr, (u32*)outaddr, (u32*)&outaddr[0x12c00]); ret = mvdstdConvertImage(&config); printf("mvdstdConvertImage(): 0x%08x\n", (unsigned int)ret); } f = fopen("sdmc:/mvd_outdata.bin", "w"); if(f) { fwrite(outaddr, 1, 0x100000, f); fclose(f); } memcpy(gfxtopadr, outaddr, 0x46500); mvdstdExit(); gfxFlushBuffers(); gfxSwapBuffersGpu(); gspWaitForVBlank(); }
int main() { srvInit(); aptInit(); hidInit(NULL); irrstInit(NULL); gfxInitDefault(); yeti_init( &yeti, (framebuffer_t*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), (framebuffer_t*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), textures, palette, lua ); gfxSet3D(true); game_init(&yeti); while(aptMainLoop()) { int i; for(i=0;i<2;i++) { yeti.viewport.front = yeti.viewport.back; yeti.viewport.back = (framebuffer_t*)gfxGetFramebuffer(GFX_TOP, leftOrRight?GFX_LEFT:GFX_RIGHT, NULL, NULL); game_draw(&yeti); leftOrRight^=1; } yetiUpdateKeyboard(&yeti); game_tick(&yeti); if(hidKeysDown()&KEY_START)break; gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForEvent(GSPEVENT_VBlank0, true); } gfxExit(); irrstExit(); hidExit(); aptExit(); srvExit(); return 0; }
void saveScreenshot() { static char path[256]; getNextScreenshotCnt(); if(screenshotCnt<MAX_SCREENSHOTS) { snprintf(path, 256, "%s/scr_%d_left.bmp", configuration.path, screenshotCnt); saveBitmap(path, gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), 400, 240); if(CONFIG_3D_SLIDERSTATE>0.0f) { snprintf(path, 256, "%s/scr_%d_right.bmp", configuration.path, screenshotCnt); saveBitmap(path, gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, NULL, NULL), 400, 240); } } }
int splash_image(char *splash_path) { // load image in memory, doing proper error checking FILE *splash_file = fopen(splash_path, "rb"); if (!splash_file) { printf("\nCouldn't open splash image %s.\n", splash_path); goto force_splash_ascii; } fseek(splash_file, 0, SEEK_END); u32 splash_size = ftell(splash_file); fseek(splash_file, 0, SEEK_SET); u8 *splash_buf = malloc(splash_size); if (!splash_buf) { printf("\nSplash image %s is too big.\n", splash_path); goto force_splash_ascii; } size_t splash_read = fread(splash_buf, 1, splash_size, splash_file); if (splash_read != splash_size) { printf("\nError while reading splash image %s.\n", splash_path); goto force_splash_ascii; } // disable double buffering, to avoid flickering gfxSetDoubleBuffering(GFX_TOP, false); // copy splash image to framebuffer memcpy(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), splash_buf, splash_size); return 0; // force ASCII splash art in case of error force_splash_ascii: splash_ascii(); return -1; }
int main() { gfxInitDefault(); //gfxSet3D(true); // uncomment if using stereoscopic 3D // Main loop while (aptMainLoop()) { gspWaitForVBlank(); hidScanInput(); // Your code goes here u32 kDown = hidKeysDown(); if (kDown & KEY_START) break; // break in order to return to hbmenu // Example rendering code that displays a white pixel // Please note that the 3DS screens are sideways (thus 240x400 and 240x320) u8* fb = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, nullptr, nullptr); memset(fb, 127, 240*400*3); fb[3*(10+10*240)] = 0xFF; fb[3*(10+10*240)+1] = 0xFF; fb[3*(10+10*240)+2] = 0xFF; // Flush and swap framebuffers gfxFlushBuffers(); gfxSwapBuffers(); } gfxExit(); return 0; }
void gfxDrawRectangle(gfxScreen_t screen, gfx3dSide_t side, u8 rgbColor[3], s16 x, s16 y, u16 width, u16 height) { u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); if(x+width<0 || x>=fbWidth)return; if(y+height<0 || y>=fbHeight)return; if(x<0){width+=x; x=0;} if(y<0){height+=y; y=0;} if(x+width>=fbWidth)width=fbWidth-x; if(y+height>=fbHeight)height=fbHeight-y; u8 colorLine[width*3]; int j; for(j=0; j<width; j++) { colorLine[j*3+0]=rgbColor[2]; colorLine[j*3+1]=rgbColor[1]; colorLine[j*3+2]=rgbColor[0]; } fbAdr+=fbWidth*3*y; for(j=0; j<height; j++) { memcpy(&fbAdr[x*3], colorLine, width*3); fbAdr+=fbWidth*3; } }
void gfxDrawSprite(gfxScreen_t screen, gfx3dSide_t side, u8* spriteData, u16 width, u16 height, s16 x, s16 y) { if(!spriteData)return; u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); if(x+width<0 || x>=fbWidth)return; if(y+height<0 || y>=fbHeight)return; u16 xOffset=0, yOffset=0; u16 widthDrawn=width, heightDrawn=height; if(x<0)xOffset=-x; if(y<0)yOffset=-y; if(x+width>=fbWidth)widthDrawn=fbWidth-x; if(y+height>=fbHeight)heightDrawn=fbHeight-y; widthDrawn-=xOffset; heightDrawn-=yOffset; int j; for(j=yOffset; j<yOffset+heightDrawn; j++) { memcpy(&fbAdr[((x+xOffset)+(y+j)*fbWidth)*3], &spriteData[((xOffset)+(j)*width)*3], widthDrawn*3); } }
void gfxFillColorGradient(gfxScreen_t screen, gfx3dSide_t side, u8 rgbColorStart[3], u8 rgbColorEnd[3]) { u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); u8 colorLine[fbWidth*3]; //TODO : optimize; use GX command ? int i; float n; float total = (float)(fbWidth - 1); // make slightly bigger to prevent gradients from blending around. SHould be removed and have the gradient color be better later. total *= 1.5f; for(i=0; i<fbWidth; i++) { n = (float)i / total; colorLine[i*3+0]=(float)rgbColorStart[2] * (1.0f-n) + (float)rgbColorEnd[2] * n; colorLine[i*3+1]=(float)rgbColorStart[1] * (1.0f-n) + (float)rgbColorEnd[1] * n; colorLine[i*3+2]=(float)rgbColorStart[0] * (1.0f-n) + (float)rgbColorEnd[0] * n; } for(i=0; i<fbHeight; i++) { memcpy(fbAdr, colorLine, fbWidth*3); fbAdr+=fbWidth*3; } }
void drawFrame() { u8* bufAdr=gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); int i, j; for(i=1;i<400;i++) { for(j=1;j<240;j++) { u32 v=(j+i*240)*3; bufAdr[v]=(pcCos(i+cnt)+4096)/32; bufAdr[v+1]=(pcCos(j-256+cnt)+4096)/64; bufAdr[v+2]=(pcCos(i+128-cnt)+4096)/32; } } gfxDrawText(GFX_TOP, GFX_LEFT, NULL, "ftPONY v0.0003 gamma\n", 240-fontDefault.height*1, 10); u32 ip = gethostid(); char bof[256]; sprintf(bof, "IP: %lu.%lu.%lu.%lu\n", ip & 0xFF, (ip>>8)&0xFF, (ip>>16)&0xFF, (ip>>24)&0xFF); gfxDrawText(GFX_TOP, GFX_LEFT, NULL, bof, 240-fontDefault.height*2, 10); gfxDrawText(GFX_TOP, GFX_LEFT, NULL, quotes[curQuote], 240-fontDefault.height*3, 10); i = countLines(superStr); while(i>240/fontDefault.height-3){cutLine(superStr);i--;} gfxDrawText(GFX_TOP, GFX_LEFT, NULL, superStr, 240-fontDefault.height*4, 20); cnt++; gfxFlushBuffers(); gfxSwapBuffers(); }
// // I_TranslateFrameBuffer // // TODO: allow copying partial screens (for top screen borders) void I_TranslateFrameBuffer(unsigned scrn, gfxScreen_t scrndest, gfx3dSide_t side, int xoff, int yoff) { if (scrn >= NUM_SCREENS) I_Error("I_TranslateFrameBuffer: invalid screen number %u", scrn); // this is really hacky and obviously doesn't account for the possibility of // different color depths, etc. uint16_t width, height; char *fb = gfxGetFramebuffer(scrndest, side, &width, &height); // center screen horizontally if (xoff < 0) { xoff = (height - screens[scrn].width) / 2; } if (xoff > height - screens[scrn].width) I_Error("I_TranslateFrameBuffer: bad x-offset (%d > %u)", xoff, height - screens[scrn].width); // center screen vertically if (yoff < 0) { yoff = (width - screens[scrn].height) / 2; } if (yoff > width - screens[scrn].height) I_Error("I_TranslateFrameBuffer: bad y-offset (%d > %u)", yoff, width - screens[scrn].height); uint16_t x, y; // do palette lookups and rotate image 90' into the framebuffer here char *src = screens[scrn].data; for (x = yoff; x < screens[scrn].height + yoff; x++) { for (y = xoff; y < screens[scrn].width + xoff; y++) { char *dest = fb + ((y * width + (width - x - 1)) * 3); char px; switch (V_GetMode()) { case VID_MODE8: px = *src++; *dest++ = current_pal[px].b; *dest++ = current_pal[px].g; *dest++ = current_pal[px].r; break; case VID_MODE32: *dest++ = *src++; *dest++ = *src++; *dest++ = *src++; src++; break; default: I_Error("I_TranslateFrameBuffer: unsupported video mode"); } } } }
void gfxDrawText(gfxScreen_t screen, gfx3dSide_t side, font_s* font, const std::string& str, s16 x, s16 y) { if (!font) font = &fontDefault; u16 fbWidth, fbHeight; u8* fbAdr = gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); drawString(fbAdr, font, str, y, x, fbHeight, fbWidth); }
void gfxDrawTextN(gfxScreen_t screen, gfx3dSide_t side, font_s* f, char* str, u16 length, s16 x, s16 y) { if(!str)return; if(!f)f=&fontDefault; u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); drawStringN(fbAdr, f, str, length, y, x, fbHeight, fbWidth); }
void FillScreen(gfxScreen_t screen, u8 bg_r, u8 bg_g, u8 bg_b) { Rect screen_size = GetScreenSize(screen); u8* fb_addr = gfxGetFramebuffer(screen, GFX_LEFT, nullptr, nullptr); for (int i = 0; i < screen_size.w * screen_size.h * 3; i += 3) { fb_addr[i] = bg_b; fb_addr[i+1] = bg_g; fb_addr[i+2] = bg_r; } }
void gfxTakeScreenshot() { gfxScreen_t screen = gameScreen == 0 ? GFX_TOP : GFX_BOTTOM; if(gfxGetScreenFormat(screen) != GSP_BGR8_OES) { return; } u16 width = 0; u16 height = 0; u8* fb = gfxGetFramebuffer(screen, GFX_LEFT, &height, &width); if(fb == NULL) { return; } u32 headerSize = 0x36; u32 imageSize = (u32) (width * height * 3); u8* header = new u8[headerSize](); *(u16*) &header[0x0] = 0x4D42; *(u32*) &header[0x2] = headerSize + imageSize; *(u32*) &header[0xA] = headerSize; *(u32*) &header[0xE] = 0x28; *(u32*) &header[0x12] = width; *(u32*) &header[0x16] = height; *(u32*) &header[0x1A] = 0x00180001; *(u32*) &header[0x22] = imageSize; u8* image = new u8[imageSize](); for(u32 x = 0; x < width; x++) { for(u32 y = 0; y < height; y++) { u8* src = &fb[(x * height + y) * 3]; u8* dst = &image[(y * width + x) * 3]; *(u16*) dst = *(u16*) src; dst[2] = src[2]; } } std::stringstream fileStream; fileStream << "/gameyob_" << time(NULL) << ".bmp"; std::ofstream stream(fileStream.str(), std::ios::binary); if(stream.is_open()) { stream.write((char*) header, (size_t) headerSize); stream.write((char*) image, (size_t) imageSize); stream.close(); } else { systemPrintDebug("Failed to open screenshot file: %s\n", strerror(errno)); } delete[] header; delete[] image; }
void display(AVFrame *pFrame) { // gspWaitForVBlank(); // gfxSwapBuffers(); int i, j, c; const int width = 400 <= pFrame->width ? 400 : pFrame->width; const int height = 240 <= pFrame->height ? 240 : pFrame->height; if (gfxGetScreenFormat(GFX_TOP) == GSP_BGR8_OES) { u8 *const src = pFrame->data[0]; u8 *const fbuffer = gfxGetFramebuffer(GFX_TOP, GFX_LEFT, 0, 0); for (i = 0; i < width; ++i) { for (j = 0; j < height; ++j) { for (c = 0; c < 3; ++c) { fbuffer[3 * 240 * i + (239 - j) * 3 + c] = src[1024 * 3 * j + i * 3 + c]; } } } } else if (gfxGetScreenFormat(GFX_TOP) == GSP_RGBA8_OES) { u32 *const src = (u32 *) pFrame->data[0]; u32 *const fbuffer = (u32 *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, 0, 0); for (i = 0; i < width; ++i) { for (j = 0; j < height; ++j) { fbuffer[240 * i + (239 - j)] = src[1024 * j + i]; } } } else { printf("format not supported\n"); } }
void gpuSwapBuffers(bool vblank) { u16 fbWidth; u16 fbHeight; u32* fb = (u32*) gfxGetFramebuffer(viewportScreen == TOP_SCREEN ? GFX_TOP : GFX_BOTTOM, GFX_LEFT, &fbWidth, &fbHeight); GX_SetDisplayTransfer(NULL, gpuFrameBuffer, (viewportHeight << 16) | viewportWidth, fb, (fbHeight << 16) | fbWidth, (PIXEL_RGB8 << 12)); gpuSafeWait(GSPEVENT_PPF); if(vblank) { gpuSafeWait(GSPEVENT_VBlank0); } gfxSwapBuffersGpu(); }
void keyboard_draw() { int i, h; sregion_t *region; int count; u16 width, height; if (keyboard_visible == 0) { return; } keyboard_screen = (u16*)gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, &width, &height); //see if the keyboard layout has changed if (keyboard_visible != keyboard_visible_last) { keyboard_vofs = 152; keyboard_hofs = 32; if (keyboard_visible == 2) { keyboard_vofs = 216; } //clear the console and set window size consoleClear(); memset(keyboard_screen, 0, 320*240*2); h = keyboard_visible == 1 ? 19 : 24; consoleSetWindow(0, 0, 0, 40, h); //printf("full refresh: %d %d\n", keyboard_visible, keyboard_visible_last); keyboard_visible_last = keyboard_visible; } else { //the keyboard layout has not changed so no need to draw everything return; } region = key_array; count = sizeof(key_array) / sizeof(sregion_t); if (keyboard_visible == 2) { region = key_button_array; count = 2; } for (i = 0; i<count; i++) { keyboard_draw_region(®ion[i], -1, keyboard_fg); } }
// Graphics Functions void clear_screen(gfxScreen_t screen) { u8* buffer1; u8* buffer2 = NULL; u16 width, height; u32 bpp; GSPGPU_FramebufferFormats format = gfxGetScreenFormat(screen); if (screen == GFX_TOP) { buffer1 = gfxGetFramebuffer(screen, GFX_LEFT, &width, &height); buffer2 = gfxGetFramebuffer(screen, GFX_RIGHT, &width, &height); } else { buffer1 = gfxGetFramebuffer(screen, GFX_LEFT, &width, &height); } switch (format) { case GSP_RGBA8_OES: bpp = 4; case GSP_BGR8_OES: bpp = 3; case GSP_RGB565_OES: case GSP_RGB5_A1_OES: case GSP_RGBA4_OES: bpp = 2; default: bpp = 3; } memset(buffer1, 0, (width * height * bpp)); if (buffer2) memset(buffer2, 0, (width * height * bpp)); gfxFlushBuffers(); gfxSwapBuffers(); gspWaitForVBlank(); }
void gfxFillColor(gfxScreen_t screen, gfx3dSide_t side, u8 rgbColor[3]) { u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); //TODO : optimize; use GX command ? int i; for(i=0; i<fbWidth*fbHeight; i++) { *(fbAdr++)=rgbColor[2]; *(fbAdr++)=rgbColor[1]; *(fbAdr++)=rgbColor[0]; } }
int main() { gfxInitDefault(); hidInit(NULL); void* device = gfxCreateDevice(240, 400); gfxMakeCurrent(device); glViewport(0, 0, 240, 400); glMatrixMode(GL_PROJECTION); glLoadIdentity(); float near = 0.1f; float far = 100.0f; float fov = 90.0f; float aspect = 240.0f / 400.0f; float t = tan(fov * 3.14159 / 360.0) * near; float b = -t; float l = aspect * b; float r = aspect * t; glFrustumf(l, r, b, t, near, far); //3DS' framebuffers are sideways glRotatef(-90.0f, 0.0f, 0.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glClearColor(0.0f, 0.0f, 0.0f, 1.0f); glEnable(GL_DEPTH_TEST); while (aptMainLoop()) { hidScanInput(); if (keysDown() & KEY_START) break; DrawGLScene(); gfxFlush(gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL)); gfxFlushBuffers(); gfxSwapBuffersGpu(); gspWaitForVBlank(); } // Exit services gfxExit(); hidExit(); return 0; }
void sf2d_end_frame() { GPU_FinishDrawing(); GPUCMD_Finalize(); GPUCMD_FlushAndRun(); gspWaitForP3D(); //Copy the GPU rendered FB to the screen FB if (cur_screen == GFX_TOP) { GX_DisplayTransfer(gpu_fb_addr, GX_BUFFER_DIM(240, 400), (u32 *)gfxGetFramebuffer(GFX_TOP, cur_side, NULL, NULL), GX_BUFFER_DIM(240, 400), 0x1000); } else { GX_DisplayTransfer(gpu_fb_addr, GX_BUFFER_DIM(240, 320), (u32 *)gfxGetFramebuffer(GFX_BOTTOM, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(240, 320), 0x1000); } gspWaitForPPF(); //Clear the screen GX_MemoryFill(gpu_fb_addr, clear_color, &gpu_fb_addr[0x2EE00], 0x201, gpu_depth_fb_addr, 0x00000000, &gpu_depth_fb_addr[0x2EE00], 0x201); gspWaitForPSC0(); }
void gfxFadeScreen(gfxScreen_t screen, gfx3dSide_t side, u32 f) { u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); int i; for(i=0; i<fbWidth*fbHeight/2; i++) { *fbAdr=(*fbAdr*f)>>8;fbAdr++; *fbAdr=(*fbAdr*f)>>8;fbAdr++; *fbAdr=(*fbAdr*f)>>8;fbAdr++; *fbAdr=(*fbAdr*f)>>8;fbAdr++; *fbAdr=(*fbAdr*f)>>8;fbAdr++; *fbAdr=(*fbAdr*f)>>8;fbAdr++; } }
void gpuFrameEnd(void) { // Finish rendering GPU_FinishDrawing(); GPUCMD_Finalize(); GPUCMD_FlushAndRun(NULL); gspWaitForP3D(); // Wait for the rendering to complete // Transfer the GPU output to the framebuffer GX_SetDisplayTransfer(NULL, colorBuf, GX_BUFFER_DIM(240, 400), (u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL), GX_BUFFER_DIM(240, 400), DISPLAY_TRANSFER_FLAGS); gspWaitForPPF(); // Wait for the transfer to complete // Reset the command buffer GPUCMD_SetBufferOffset(0); };
void gfxDrawWave(gfxScreen_t screen, gfx3dSide_t side, u8 rgbColorStart[3], u8 rgbColorEnd[3], u16 level, u16 amplitude, u16 width, gfxWaveCallback cb, void* p) { u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); u8 colorLine[fbWidth*3]; int j; if(width) { for(j=0; j<fbWidth; j++) { colorLine[j*3+0]=rgbColorStart[2]; colorLine[j*3+1]=rgbColorStart[1]; colorLine[j*3+2]=rgbColorStart[0]; } for(j=0; j<fbHeight; j++) { u16 waveLevel=level+cb(p, j)*amplitude; memcpy(&fbAdr[(waveLevel-width)*3], colorLine, width*3); fbAdr+=fbWidth*3; } }else{ int i; float n; float total = (float)(fbWidth - 1); // make slightly bigger to prevent gradients from blending around. SHould be removed and have the gradient color be better later. total *= 1.5f; for(i=0; i<fbWidth; i++) { n = (float)i / total; colorLine[i*3+0]=(float)rgbColorStart[2] * (1.0f-n) + (float)rgbColorEnd[2] * n; colorLine[i*3+1]=(float)rgbColorStart[1] * (1.0f-n) + (float)rgbColorEnd[1] * n; colorLine[i*3+2]=(float)rgbColorStart[0] * (1.0f-n) + (float)rgbColorEnd[0] * n; } for(j=0; j<fbHeight; j++) { u16 waveLevel=level+cb(p, j)*amplitude; memcpy(fbAdr, colorLine, waveLevel*3); fbAdr+=fbWidth*3; } } }
/*! clear framebuffer * * @param[in] screen screen to clear * @param[in] side which side on the stereoscopic display * @param[in] rgbColor clear color */ static void clear_screen(gfxScreen_t screen, gfx3dSide_t side, u8 rgbColor[3]) { /* get the framebuffer information */ u16 fbWidth, fbHeight; u8 *fb = gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); /* fill the framebuffer with the clear color */ int i; for(i = 0; i < fbWidth*fbHeight; ++i) { *(fb++) = rgbColor[2]; *(fb++) = rgbColor[1]; *(fb++) = rgbColor[0]; } }
void gfxDrawSpriteAlphaBlendFade(gfxScreen_t screen, gfx3dSide_t side, u8* spriteData, u16 width, u16 height, s16 x, s16 y, u8 fadeValue) { if(!spriteData)return; u16 fbWidth, fbHeight; u8* fbAdr=gfxGetFramebuffer(screen, side, &fbWidth, &fbHeight); if(x+width<0 || x>=fbWidth)return; if(y+height<0 || y>=fbHeight)return; u16 xOffset=0, yOffset=0; u16 widthDrawn=width, heightDrawn=height; if(x<0)xOffset=-x; if(y<0)yOffset=-y; if(x+width>=fbWidth)widthDrawn=fbWidth-x; if(y+height>=fbHeight)heightDrawn=fbHeight-y; widthDrawn-=xOffset; heightDrawn-=yOffset; //TODO : optimize fbAdr+=(y+yOffset)*fbWidth*3; spriteData+=yOffset*width*4; int j, i; for(j=yOffset; j<yOffset+heightDrawn; j++) { u8* fbd=&fbAdr[(x+xOffset)*3]; u8* data=&spriteData[(xOffset)*4]; for(i=xOffset; i<xOffset+widthDrawn; i++) { if(data[3]) { u8 alphaSource = (fadeValue * data[3]) / 256; fbd[0]=((data[0] * alphaSource) / 256)+((fbd[0] * (255 - alphaSource)) / 256); fbd[1]=((data[1] * alphaSource) / 256)+((fbd[1] * (255 - alphaSource)) / 256); fbd[2]=((data[2] * alphaSource) / 256)+((fbd[2] * (255 - alphaSource)) / 256); } fbd+=3; data+=4; } fbAdr+=fbWidth*3; spriteData+=width*4; } }
void I_FinishUpdate (void) { static u64 lasttic = 0; u64 now, frametics; int height, width; u32 *bufAdr; int w, h; /* Update the display buffer (flipping video pages if supported) * If we need to change palette, that implicitely does a flip */ if (newpal != NO_PALETTE_CHANGE) { I_UploadNewPalette(newpal); newpal = NO_PALETTE_CHANGE; } height=screens[0].height; width=screens[0].width; bufAdr=(u32*)gfxGetFramebuffer(GFX_TOP, GFX_LEFT, NULL, NULL); for (h=0; h<height; h++) { u32 *dest=&bufAdr[239-h]; u8 *src=screens[0].data + (h * screens[0].byte_pitch); __builtin_prefetch(src); for (w=0; w<width; w++) { *(dest)=palettes[(*src++) + currentPalette]; dest += 240; } } gspWaitForVBlank(); gfxSwapBuffers(); gfxFlushBuffers(); now = svcGetSystemTick(); frametics = now - lasttic; lasttic = now; }