void __pspgl_vram_dump (void) { unsigned long vram_start = (unsigned long) sceGeEdramGetAddr(); unsigned long vram_size = (unsigned long) sceGeEdramGetSize() * 4; unsigned long header [4]; unsigned char vram_copy [0x10000]; int fd; int i; fd = sceIoOpen(PSPGL_GE_DUMPFILE, PSP_O_CREAT | PSP_O_APPEND | PSP_O_WRONLY, 0644); if (pspgl_curctx) { struct pspgl_surface *s = pspgl_curctx->draw; struct pspgl_dump_surfaces surf; header[0] = PSPGL_GE_DUMP_SURFACES; header[1] = sizeof(header) + sizeof(surf); header[2] = 0; header[3] = 0; memset(&surf, 0, sizeof(surf)); surf.pixfmt = s->pixfmt; surf.alpha_mask = s->alpha_mask; surf.stencil_mask = s->stencil_mask; surf.front.start = s->color_front->base - sceGeEdramGetAddr(); surf.front.size = s->height * s->pixelperline * (s->pixfmt == GE_RGBA_8888 ? 4 : 2); surf.front.stride = s->pixelperline; surf.back.start = s->color_back->base - sceGeEdramGetAddr(); surf.back.size = s->height * s->pixelperline * (s->pixfmt == GE_RGBA_8888 ? 4 : 2); surf.back.stride = s->pixelperline; if (s->depth_buffer) { surf.depth.start = s->depth_buffer->base - sceGeEdramGetAddr(); surf.depth.size = s->height * s->pixelperline * 2; surf.depth.stride = s->pixelperline; } sceIoWrite(fd, header, sizeof(header)); sceIoWrite(fd, &surf, sizeof(surf)); } header[0] = PSPGL_GE_DUMP_VRAM; header[1] = sizeof(header) + vram_size; header[2] = vram_start; header[3] = vram_size; sceIoWrite(fd, header, sizeof(header)); /* copy in blocks, direct writes from VRAM to file don't seem to work... */ for (i=0; i<vram_size/sizeof(vram_copy); i++, vram_start+=sizeof(vram_copy)) { memcpy(vram_copy, (void *) vram_start, sizeof(vram_copy)); sceIoWrite(fd, (void *) vram_copy, sizeof(vram_copy)); } sceIoClose(fd); }
//***************************************************************************** // //***************************************************************************** IVideoMemoryManager::IVideoMemoryManager() : mVideoMemoryHeap( CMemoryHeap::Create( MAKE_UNCACHED_PTR( sceGeEdramGetAddr() ), sceGeEdramGetSize() ) ) , mRamMemoryHeap( CMemoryHeap::Create( MAKE_UNCACHED_PTR( (void*)(((u32)malloc_volatile(ERAM + 0xF) + 0xF) & ~0xF) ), ERAM ) ) //, mRamMemoryHeap( CMemoryHeap::Create( 1 * 1024 * 1024 ) ) { printf( "vram base: %p\n", sceGeEdramGetAddr() ); printf( "vram size: %d KB\n", sceGeEdramGetSize() / 1024 ); }
/** * display_init: Initialize the PSP display. * * [Parameters] * None * [Return value] * Nonzero on success, zero on error */ int display_init(void) { /* Have we already initialized? */ static int initted = 0; if (initted) { return 1; } /* Clear out VRAM */ memset(sceGeEdramGetAddr(), 0, sceGeEdramGetSize()); sceKernelDcacheWritebackInvalidateAll(); /* Set display mode */ int32_t res = sceDisplaySetMode(0, DISPLAY_WIDTH, DISPLAY_HEIGHT); if (res < 0) { DMSG("sceDisplaySetMode() failed: %s", psp_strerror(res)); return 0; } display_width = DISPLAY_WIDTH; display_height = DISPLAY_HEIGHT; display_mode = PSP_DISPLAY_PIXEL_FORMAT_8888; display_bpp = 32; /* Initialize VRAM pointers */ uint8_t *vram_addr = sceGeEdramGetAddr(); uint32_t vram_size = sceGeEdramGetSize(); const uint32_t frame_size = DISPLAY_STRIDE * DISPLAY_HEIGHT * (display_bpp/8); int i; for (i = 0; i < lenof(surfaces); i++) { surfaces[i] = vram_addr + i*frame_size; } vram_spare_ptr = (uint8_t *)(vram_addr + lenof(surfaces)*frame_size); vram_next_alloc = vram_spare_ptr; vram_top = vram_addr + vram_size; displayed_surface = 0; work_surface = 1; swap_pending = 0; /* Set the currently-displayed buffer */ sceDisplaySetFrameBuf(surfaces[displayed_surface], DISPLAY_STRIDE, display_mode, PSP_DISPLAY_SETBUF_IMMEDIATE); /* Set up the GU library */ guInit(); guStart(GU_DIRECT, display_list); guDispBuffer(DISPLAY_WIDTH, DISPLAY_HEIGHT, surfaces[displayed_surface], DISPLAY_STRIDE); guFinish(); guSync(0, 0); /* Success */ initted = 1; return 1; }
static int is_edram_addr(void *p) { static void *edram_start, *edram_end; if (edram_end == NULL) { edram_start = sceGeEdramGetAddr(); edram_end = sceGeEdramGetAddr() + sceGeEdramGetSize(); } return (p >= edram_start) && (p < edram_end); }
void displayBuffer(const char *reason) { sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(copybuf, sceGeEdramGetAddr(), sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); const u32 *buf = copybuf; checkpoint("%s: COLOR=%08x", reason, buf[0]); // Reset. memset(copybuf, 0x44, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
void testBlendFunc(const char *title, u32 prev, u32 c, int op, int src, int dst, u32 fixa, u32 fixb) { for (size_t i = 0; i < sizeof(copybuf) / 4; ++i) { copybuf[i] = prev; } sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceGuStart(GU_DIRECT, list); sceGuEnable(GU_BLEND); sceGuBlendFunc(op, src, dst, fixa, fixb); sceGuEnable(GU_STENCIL_TEST); sceGuStencilFunc(GU_ALWAYS, 0xAA, 0xFF); sceGuStencilOp(GU_REPLACE, GU_REPLACE, GU_REPLACE); drawBoxCommands(c); sceGuFinish(); sceGuSync(GU_SYNC_WAIT, GU_SYNC_WHAT_DONE); displayBuffer(title); sceGuDisable(GU_BLEND); }
byte* RenderTexture_GetTex(void) { byte *texture; sceGuDrawBufferList(GU_PSM_4444,vrelptr(renderTarget), texture); return reinterpret_cast<char*>(sceGeEdramGetAddr()) + reinterpret_cast<std::size_t>(vrelptr(renderTarget)); }
void init() { void *fbp0 = 0; drawbuf = (u32 *)sceGeEdramGetAddr(); sceGuInit(); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(GU_PSM_8888, fbp0, BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, fbp0, BUF_WIDTH); sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(1); resetBuffer(); }
void init() { sceGuInit(); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(GU_PSM_8888, fbp0, 512); sceGuDispBuffer(480, 272, fbp0, 512); sceGuDepthBuffer(dbp0, 512); sceGuOffset(2048 - (240 / 2), 2048 - (136 / 2)); sceGuViewport(2048, 2048, 240, 136); sceGuDepthRange(65535, 0); sceGuDepthMask(0); sceGuScissor(0, 0, 480, 272); sceGuEnable(GU_SCISSOR_TEST); sceGuFrontFace(GU_CW); sceGuShadeModel(GU_SMOOTH); sceGuDisable(GU_TEXTURE_2D); ScePspFMatrix4 ones = { {1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, }; sceGuSetMatrix(GU_MODEL, &ones); sceGuSetMatrix(GU_VIEW, &ones); sceGuSetMatrix(GU_PROJECTION, &ones); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(1); memset(copybuf, 0x44, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(sceGeEdramGetAddr(), copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); displayBuffer("Initial"); }
void init() { void *fbp0 = 0; drawbuf = (u32 *)sceGeEdramGetAddr(); sceGuInit(); sceGuStart(GU_DIRECT, list); sceGuDrawBuffer(GU_PSM_8888, fbp0, BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH, SCR_HEIGHT, fbp0, BUF_WIDTH); sceGuScissor(0, 0, SCR_WIDTH, SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuFinish(); sceGuSync(0, 0); sceDisplayWaitVblankStart(); sceGuDisplay(1); memset(copybuf, 0, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); sceDmacMemcpy(drawbuf, copybuf, sizeof(copybuf)); sceKernelDcacheWritebackInvalidateAll(); }
static void* vidmem_alloc(unsigned int size) { /*(16[bytes]境界へ .align 調整処理.)*/ unsigned int i; /* round the size up to the nearest 16 bytes and all hwsurfaces are safe to use as textures. */ i = (size & (16-1));//(size % 16) // if (0 != i) { size += 16 - i; } if (0 != i) { size += 16; size -= i; } /*(リストに挿入処理.)*/ unsigned int start_addr; unsigned int temp_addr; start_addr = ((unsigned int)sceGeEdramGetAddr()); temp_addr = start_addr; /*(残りvramのある限り調べる)*/ for (i=0; i<vidmem_map_len; i++) { if (vidmem_map[i].ptr != NULL) { unsigned int new_addr; new_addr = ((unsigned int)vidmem_map[i].ptr); if (size <= new_addr - temp_addr) { goto my_insert_end;/*(その場所に挿入)*/ } temp_addr = new_addr + vidmem_map[i].len; } } /*(失敗判定)*/ if (temp_addr + size > start_addr + sceGeEdramGetSize()) {return (NULL);/*(挿入できない)*/} /*(最後に挿入)*/ i = vidmem_map_len; my_insert_end: return (vidmem_map_insert_new(i, temp_addr, size));/* (挿入処理.) */ }
void sceGuInit(void) { PspGeCallbackData callback; callback.signal_func = callbackSig; callback.signal_arg = &gu_settings; callback.finish_func = callbackFin; callback.finish_arg = &gu_settings; gu_settings.ge_callback_id = sceGeSetCallback(&callback); gu_settings.swapBuffersCallback = 0; gu_settings.swapBuffersBehaviour = PSP_DISPLAY_SETBUF_IMMEDIATE; ge_edram_address = sceGeEdramGetAddr(); // initialize graphics hardware ge_list_executed[0] = sceGeListEnQueue((void*)((unsigned int)ge_init_list & 0x1fffffff),0,gu_settings.ge_callback_id,0); resetValues(); gu_settings.kernel_event_flag = sceKernelCreateEventFlag("SceGuSignal",512,3,0); // wait for init to complete sceGeListSync(ge_list_executed[0],0); }
void *getBufAddr(int i) { int off = (i * 512 * 272 * 4); return ((u8 *)sceGeEdramGetAddr() + off); }
namespace vram { typedef std::vector<unsigned short> allocated_list; static char* const base = static_cast<char*>(sceGeEdramGetAddr()); static const std::size_t block_size = 32 * 32; static const std::size_t block_count = sceGeEdramGetSize() / block_size; static allocated_list allocated(block_count, 0); static std::size_t bytes_required = 0; static std::size_t bytes_allocated = 0; void* allocate(std::size_t size) { // How many blocks to allocate? bytes_required += size; std::size_t blocks_required = (size + block_size - 1) / block_size; #if VRAM_DEBUGGING Con_Printf("vram::allocate %u bytes (%u blocks)\n", size, blocks_required); Con_Printf("\tblock_size = %u\n", block_size); Con_Printf("\tblock_count = %u\n", block_count); #endif // Find a sequential area this big. for (std::size_t start = 0; start < (block_count - blocks_required);) { // Is this block allocated? const std::size_t allocated_blocks = allocated.at(start); if (allocated_blocks) { // Skip the allocated block. start += allocated_blocks; #if VRAM_DEBUGGING //Con_Printf("\tskipping from block %u to %u\n", start - allocated_blocks, start); #endif } else { // Where would the allocated block end? const std::size_t end = start + blocks_required; #if VRAM_DEBUGGING //Con_Printf("\ttrying blocks %u to %u\n", start, end - 1); #endif // Check for allocated blocks in the area we want. std::size_t free_blocks_here = 1; for (std::size_t b = start + 1; b < end; ++b) { if (allocated.at(b)) { break; } else { ++free_blocks_here; } } // Is the block big enough? if (free_blocks_here >= blocks_required) { // Mark it as allocated. #if VRAM_DEBUGGING Con_Printf("\tmarking blocks %u to %u as allocated\n", start, end - 1); #endif bytes_allocated += (blocks_required * block_size); for (std::size_t b = start; b < end; ++b) { allocated.at(b) = blocks_required--; } // Done. #if VRAM_DEBUGGING Con_Printf("\tdone (%u allocated, %u required)\n", bytes_allocated, bytes_required); #endif return base + (block_size * start); } else { // Move on. start += free_blocks_here; #if VRAM_DEBUGGING Con_Printf("\tskipping from block %u to %u, because there wasn't a big enough run of free blocks\n", start - free_blocks_here, start); #endif } } } // Failed. #if VRAM_DEBUGGING Con_Printf("\tfailed, no free blocks big enough (%u allocated, %u required)\n", bytes_allocated, bytes_required); #endif return 0; } void free(void* memory) { // Which block is this? const std::size_t relative_address = static_cast<char*>(memory) - base; const std::size_t block_index = relative_address / block_size; #if VRAM_DEBUGGING Con_Printf("vram::free freeing blocks starting with %u\n", block_index); #endif // Mark the blocks as deallocated. const std::size_t blocks_to_free = allocated.at(block_index); #if VRAM_DEBUGGING Con_Printf("\tfreeing to %u\n", block_index + blocks_to_free - 1); #endif for (std::size_t block = 0; block < blocks_to_free; ++block) { allocated.at(block_index + block) = 0; } const std::size_t bytes_to_free = blocks_to_free * block_size; bytes_allocated -= bytes_to_free; bytes_required -= bytes_to_free; #if VRAM_DEBUGGING Con_Printf("\tnow %u allocated, %u required\n", bytes_allocated, bytes_required); #endif } }
int main(int argc, char* argv[]) { SetupCallbacks(); // generate geometry genTorus( TORUS_ROWS, TORUS_SLICES, TORUS_RADIUS, TORUS_THICKNESS, torus_vertices, torus_indices ); // flush cache so that no stray data remains sceKernelDcacheWritebackAll(); // setup Edram buffers void* frameBuffer = (void*)0; const void* doubleBuffer = (void*)0x44000; const void* renderTarget = (void*)0x88000; const void* depthBuffer = (void*)0x110000; // setup GU sceGuInit(); sceGuStart(GU_DIRECT,list); sceGuDrawBuffer(GU_PSM_4444,frameBuffer,BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)doubleBuffer,BUF_WIDTH); sceGuDepthBuffer((void*)depthBuffer,BUF_WIDTH); sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); sceGuDepthRange(0xc350,0x2710); sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuDepthFunc(GU_GEQUAL); sceGuEnable(GU_DEPTH_TEST); sceGuFrontFace(GU_CW); sceGuShadeModel(GU_SMOOTH); sceGuEnable(GU_CULL_FACE); sceGuEnable(GU_TEXTURE_2D); sceGuFinish(); sceGuSync(0,0); sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); // run sample int val = 0; Texture offscreenTexture = { GU_PSM_4444, 0, 128, 128, 128, sceGeEdramGetAddr() + (int)renderTarget }; for(;;) { sceGuStart(GU_DIRECT,list); { sceGuDrawBufferList(GU_PSM_4444,(void*)renderTarget,offscreenTexture.stride); // setup viewport sceGuOffset(2048 - (offscreenTexture.width/2),2048 - (offscreenTexture.height/2)); sceGuViewport(2048,2048,offscreenTexture.width,offscreenTexture.height); // clear screen sceGuClearColor(0xffffffff); sceGuClearDepth(0); sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); // draw torus to offscreen texture drawTorus( val ); } { // set frame buffer sceGuDrawBufferList(GU_PSM_4444,(void*)frameBuffer,BUF_WIDTH); // setup viewport sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); // clear screen sceGuClearColor(0xff554433); sceGuClearDepth(0); sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); // draw cube using offscreen texture drawCube( &offscreenTexture, val ); } sceGuFinish(); sceGuSync(0,0); sceDisplayWaitVblankStart(); frameBuffer = sceGuSwapBuffers(); val++; } sceGuTerm(); sceKernelExitGame(); return 0; }
/* ==================== Host_Init ==================== */ void Host_Init (quakeparms_t *parms) { #if defined(_WIN32) && defined(GLQUAKE) FILE *fp = fopen("opengl32.dll","r"); if (fp) { // exists fclose(fp); Sys_Error ("OpenGL32.dll found in Quake folder. You must delete this file from your Quake folder to run this engine."); } #endif // Windows only if (standard_quake) minimum_memory = MINIMUM_MEMORY; else minimum_memory = MINIMUM_MEMORY_LEVELPAK; if (COM_CheckParm ("-minmemory")) parms->memsize = minimum_memory; host_parms = *parms; if (parms->memsize < minimum_memory) Sys_Error ("Only %4.1f megs of memory available, can't execute game and memsize = %i and minimum memory is %i", parms->memsize / (float)0x100000, parms->memsize, minimum_memory); com_argc = parms->argc; com_argv = parms->argv; #ifdef SUPPORTS_CHEATFREE // JPG 3.00 - moved this here #if defined(_WIN32) srand(time(NULL) ^ _getpid()); #else srand(time(NULL) ^ getpid()); #endif #endif Memory_Init (parms->membase, parms->memsize); Cbuf_Init (); Cmd_Init (); Cvar_Init (); V_Init (); Chase_Init (); Host_InitVCR (parms); COM_Init (parms->basedir); Host_InitLocal (); W_LoadWadFile ("gfx.wad"); Key_Init (); Con_Init (); M_Init (); PR_Init (); Mod_Init (); #ifdef PROQUAKE_EXTENSION Security_Init (); // JPG 3.20 - cheat free #endif NET_Init (); SV_Init (); #ifdef PROQUAKE_EXTENSION IPLog_Init (); // JPG 1.05 - ip address logging Con_Printf ("Exe: "__TIME__" "__DATE__"\n"); #endif #ifdef PSP_SYSTEM_STATS Con_Printf ("Insomnia ProQuake Engine v 4.71 Rev4\n"); //(EBOOT: "__TIME__" "__DATE__")\n"); int currentCPU = scePowerGetCpuClockFrequency(); int currentVRAM = sceGeEdramGetSize(); int currentVRAMADD = sceGeEdramGetAddr(); int currentRAMAVAIL = sceKernelTotalFreeMemSize(); #ifdef NORMAL_MODEL Con_Printf ("PSP Normal 32MB RAM Mode \n"); #endif #ifdef SLIM_MODEL Con_Printf ("PSP Slim 64MB RAM Mode \n"); #endif Con_Printf ("%4.1f megabyte heap \n",parms->memsize/ (1024*1024.0)); Con_Printf ("%4.1f PSP application heap \n",1.0f*PSP_HEAP_SIZE_MB); Con_Printf ("%d VRAM \n",currentVRAM); Con_Printf ("%d VRAM Address \n",currentVRAMADD); Con_Printf ("%d Current Total RAM \n",currentRAMAVAIL); Con_Printf ("CPU Speed %d MHz\n", currentCPU); Con_Printf ("%s \n", com_gamedir); R_InitTextures (); // needed even for dedicated servers #else Con_Printf ("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0)); #endif if (cls.state != ca_dedicated) { host_basepal = (byte *)COM_LoadHunkFile ("gfx/palette.lmp"); if (!host_basepal) Sys_Error ("Couldn't load gfx/palette.lmp"); host_colormap = (byte *)COM_LoadHunkFile ("gfx/colormap.lmp"); if (!host_colormap) Sys_Error ("Couldn't load gfx/colormap.lmp"); #ifndef _WIN32 // on non win32, mouse comes before video for security reasons IN_Init (); #endif VID_Init (host_basepal); Draw_Init (); SCR_Init (); R_Init (); #ifndef _WIN32 // on Win32, sound initialization has to come before video initialization, so we // can put up a popup if the sound hardware is in use S_Init (); #else #ifdef GLQUAKE // FIXME: doesn't use the new one-window approach yet S_Init (); #endif #endif // _WIN32 CDAudio_Init (); Sbar_Init (); CL_Init (); #ifdef _WIN32 // on non win32, mouse comes before video for security reasons IN_Init (); #endif #ifdef _WIN32 // Baker: 3.99m to get sys info // must be AFTER video init stuff Sys_InfoInit(); // We don't care about dedicated servers for this // Baker 3.76 - Autoplay demo if (com_argc >= 2) { char *infile = com_argv[1]; if (infile[0] && infile[0] != '-' && infile[0] != '+') { char tmp[1024] = {0}, *ext = COM_FileExtension(infile); if (!strncasecmp(ext, "dem", sizeof("dem"))) snprintf(tmp, sizeof(tmp), "playdemo \"%s\"\n", infile); if (tmp[0]) { nostartdemos = true; Cbuf_AddText(tmp); } } } #endif } Cbuf_InsertText ("exec quake.rc\n"); #ifdef PROQUAKE_EXTENSION // Baker 3.80x: this is a hack if (!isDedicated) { Cbuf_AddText ("\nsavefov\n"); Cbuf_AddText ("savesensitivity\n"); } #endif Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); host_hunklevel = Hunk_LowMark (); host_initialized = true; Con_Printf ("Host Initialized\n"); Sys_Printf ("========Quake Initialized=========\n"); }
//********************************************************************************** // //********************************************************************************** void CTextureManager::ResetVRAM() { s_pVRAM = ( ( u8 * )sceGeEdramGetAddr() ); s_pVRAM += 512 * 272 * 4 * 2; // Frame buffer // s_pVRAM += 512 * 272 * 4; // Z-Buffer }
extern "C" int main(int argc, char *argv[]) { init(); schedf("framebuf: %08x\n", sceDisplaySetFrameBuf(sceGeEdramGetAddr(), 512, GU_PSM_8888, PSP_DISPLAY_SETBUF_IMMEDIATE)); schedf("dispmode: %08x\n", sceDisplaySetMode(0, 480, 272)); checkpointNext("Common:"); testBlendFunc(" One + Zero", 0x44444444, 0xEEDDCCBB, GU_ADD, GU_FIX, GU_FIX, 0xFFFFFFFF, 0x00000000); testBlendFunc(" Zero + One", 0x44444444, 0xEEDDCCBB, GU_ADD, GU_FIX, GU_FIX, 0x00000000, 0xFFFFFFFF); testBlendFunc(" Alpha + Inverse alpha", 0x44444444, 0xEEDDCCBB, GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0x80808080, 0x80808080); checkpointNext("Doubling:"); testBlendFunc(" Double source alpha + Zero", 0x40404040, 0x80808080, GU_ADD, GU_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Double source alpha + Zero", 0x40404040, 0x80909090, GU_ADD, GU_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Double source alpha + Zero", 0x40404040, 0x90808080, GU_ADD, GU_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse double source alpha + Zero", 0x40404040, 0x80808080, GU_ADD, GU_ONE_MINUS_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse double source alpha + Zero", 0x40404040, 0x80909090, GU_ADD, GU_ONE_MINUS_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse double source alpha + Zero", 0x40404040, 0x90808080, GU_ADD, GU_ONE_MINUS_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse double source alpha + Zero", 0x40404040, 0x40808080, GU_ADD, GU_ONE_MINUS_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Double dest alpha + Zero", 0x40404040, 0x80808080, GU_ADD, GU_DOUBLE_DST_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Double dest alpha + Zero", 0x90404040, 0x80808080, GU_ADD, GU_DOUBLE_DST_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Double dest alpha + Zero", 0x40404040, 0x80909090, GU_ADD, GU_DOUBLE_DST_ALPHA, GU_FIX, 0x00000000, 0x00000000); checkpointNext("Factors:"); testBlendFunc(" Dest color + Zero", 0x50404040, 0x90808080, GU_ADD, GU_DST_COLOR, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse dest color + Zero", 0x50404040, 0x90808080, GU_ADD, GU_ONE_MINUS_DST_COLOR, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Src alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse src alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_ONE_MINUS_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Dest alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_DST_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse dest alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_ONE_MINUS_DST_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Double src alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse double src alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_ONE_MINUS_DOUBLE_SRC_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Double dest alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_DOUBLE_DST_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Inverse double dest alpha + Zero", 0x50404040, 0x90808080, GU_ADD, GU_ONE_MINUS_DOUBLE_DST_ALPHA, GU_FIX, 0x00000000, 0x00000000); testBlendFunc(" Fix + Zero", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_FIX, 0x90808080, 0x00000000); testBlendFunc(" Zero + Src color", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_SRC_COLOR, 0x00000000, 0x00000000); testBlendFunc(" Zero + Inverse dest color", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_COLOR, 0x00000000, 0x00000000); testBlendFunc(" Zero + Src alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_SRC_ALPHA, 0x00000000, 0x00000000); testBlendFunc(" Zero + Inverse src alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_ONE_MINUS_SRC_ALPHA, 0x00000000, 0x00000000); testBlendFunc(" Zero + Dest alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_DST_ALPHA, 0x00000000, 0x00000000); testBlendFunc(" Zero + Inverse dest alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_ONE_MINUS_DST_ALPHA, 0x00000000, 0x00000000); testBlendFunc(" Zero + Double src alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_DOUBLE_SRC_ALPHA, 0x00000000, 0x00000000); testBlendFunc(" Zero + Inverse double src alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_ONE_MINUS_DOUBLE_SRC_ALPHA, 0x00000000, 0x00000000); testBlendFunc(" Zero + Double dest alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_DOUBLE_DST_ALPHA, 0x00000000, 0x00000000); testBlendFunc(" Zero + Inverse double dest alpha", 0x50404040, 0x90808080, GU_ADD, GU_FIX, GU_ONE_MINUS_DOUBLE_DST_ALPHA, 0x00000000, 0x00000000); checkpointNext("Add:"); testBlendFunc(" F0 + 0F", 0xFFFFFFFF, 0xFFFFFFFF, GU_ADD, GU_FIX, GU_FIX, 0xF0F0F0F0, 0x0F0F0F0F); testBlendFunc(" 0F + F0", 0xFFFFFFFF, 0xFFFFFFFF, GU_ADD, GU_FIX, GU_FIX, 0x0F0F0F0F, 0xF0F0F0F0); checkpointNext("Subtract:"); testBlendFunc(" F0 - 0F", 0xFFFFFFFF, 0xFFFFFFFF, GU_SUBTRACT, GU_FIX, GU_FIX, 0xF0F0F0F0, 0x0F0F0F0F); testBlendFunc(" 0F - F0", 0xFFFFFFFF, 0xFFFFFFFF, GU_SUBTRACT, GU_FIX, GU_FIX, 0x0F0F0F0F, 0xF0F0F0F0); checkpointNext("Reverse subtract:"); testBlendFunc(" Reverse F0 - 0F", 0xFFFFFFFF, 0xFFFFFFFF, GU_REVERSE_SUBTRACT, GU_FIX, GU_FIX, 0xF0F0F0F0, 0x0F0F0F0F); testBlendFunc(" Reverse 0F - F0", 0xFFFFFFFF, 0xFFFFFFFF, GU_REVERSE_SUBTRACT, GU_FIX, GU_FIX, 0x0F0F0F0F, 0xF0F0F0F0); checkpointNext("Min:"); testBlendFunc(" Min 0F, F0", 0xF0F0F0F0, 0x0F0F0F0F, GU_MIN, GU_FIX, GU_FIX, 0x80808080, 0x80808080); testBlendFunc(" Min F0, 0F", 0x0F0F0F0F, 0xF0F0F0F0, GU_MIN, GU_FIX, GU_FIX, 0x80808080, 0x80808080); checkpointNext("Max:"); testBlendFunc(" Max 0F, F0", 0xF0F0F0F0, 0x0F0F0F0F, GU_MAX, GU_FIX, GU_FIX, 0x80808080, 0x80808080); testBlendFunc(" Max F0, 0F", 0x0F0F0F0F, 0xF0F0F0F0, GU_MAX, GU_FIX, GU_FIX, 0x80808080, 0x80808080); checkpointNext("Absolute difference:"); testBlendFunc(" Abs 0F - F0", 0xF0F0F0F0, 0x0F0F0F0F, GU_ABS, GU_FIX, GU_FIX, 0x80808080, 0x80808080); testBlendFunc(" Abs F0 - 0F", 0x0F0F0F0F, 0xF0F0F0F0, GU_ABS, GU_FIX, GU_FIX, 0x80808080, 0x80808080); sceGuTerm(); return 0; }
int main(int argc, char* argv[]) { SetupCallbacks(); // generate geometry genGrid( GRID_ROWS, GRID_COLUMNS, GRID_SIZE, grid_vertices, grid_indices ); genTorus( TORUS_ROWS, TORUS_SLICES, TORUS_RADIUS, TORUS_THICKNESS, torus_vertices, torus_indices ); // flush cache so that no stray data remains sceKernelDcacheWritebackAll(); // setup VRAM buffers void* frameBuffer = (void*)0; const void* doubleBuffer = (void*)0x44000; const void* renderTarget = (void*)0x88000; const void* depthBuffer = (void*)0x110000; // setup GU sceGuInit(); sceGuStart(GU_DIRECT,list); sceGuDrawBuffer(GU_PSM_4444,frameBuffer,BUF_WIDTH); sceGuDispBuffer(SCR_WIDTH,SCR_HEIGHT,(void*)doubleBuffer,BUF_WIDTH); sceGuDepthBuffer((void*)depthBuffer,BUF_WIDTH); sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); sceGuDepthRange(0xc350,0x2710); sceGuScissor(0,0,SCR_WIDTH,SCR_HEIGHT); sceGuEnable(GU_SCISSOR_TEST); sceGuDepthFunc(GU_GEQUAL); sceGuEnable(GU_DEPTH_TEST); sceGuFrontFace(GU_CW); sceGuShadeModel(GU_SMOOTH); sceGuEnable(GU_CULL_FACE); sceGuEnable(GU_TEXTURE_2D); sceGuEnable(GU_DITHER); sceGuFinish(); sceGuSync(0,0); sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); // setup matrices ScePspFMatrix4 identity; ScePspFMatrix4 projection; ScePspFMatrix4 view; gumLoadIdentity(&identity); gumLoadIdentity(&projection); gumPerspective(&projection,75.0f,16.0f/9.0f,0.5f,1000.0f); { ScePspFVector3 pos = {0,0,-5.0f}; gumLoadIdentity(&view); gumTranslate(&view,&pos); } ScePspFMatrix4 textureProjScaleTrans; gumLoadIdentity(&textureProjScaleTrans); textureProjScaleTrans.x.x = 0.5; textureProjScaleTrans.y.y = -0.5; textureProjScaleTrans.w.x = 0.5; textureProjScaleTrans.w.y = 0.5; ScePspFMatrix4 lightProjection; ScePspFMatrix4 lightProjectionInf; ScePspFMatrix4 lightView; ScePspFMatrix4 lightMatrix; gumLoadIdentity(&lightProjection); gumPerspective(&lightProjection,75.0f,1.0f,0.1f,1000.0f); gumLoadIdentity(&lightProjectionInf); gumPerspective(&lightProjectionInf,75.0f,1.0f,0.0f,1000.0f); gumLoadIdentity(&lightView); gumLoadIdentity(&lightMatrix); // define shadowmap Texture shadowmap = { GU_PSM_4444, 0, 128, 128, 128, sceGeEdramGetAddr() + (int)renderTarget }; // define geometry Geometry torus = { identity, sizeof(torus_indices)/sizeof(unsigned short), torus_indices, torus_vertices, 0xffffff }; Geometry grid = { identity, sizeof(grid_indices)/sizeof(unsigned short), grid_indices, grid_vertices, 0xff7777 }; // run sample int val = 0; for(;;) { // update matrices // grid { ScePspFVector3 pos = {0,-1.5f,0}; gumLoadIdentity(&grid.world); gumTranslate(&grid.world,&pos); } // torus { ScePspFVector3 pos = {0,0.5f,0.0f}; ScePspFVector3 rot = {val * 0.79f * (GU_PI/180.0f), val * 0.98f * (GU_PI/180.0f), val * 1.32f * (GU_PI/180.0f)}; gumLoadIdentity(&torus.world); gumTranslate(&torus.world,&pos); gumRotateXYZ(&torus.world,&rot); } // orbiting light { ScePspFVector3 lightLookAt = { torus.world.w.x, torus.world.w.y, torus.world.w.z }; ScePspFVector3 rot1 = {0,val * 0.79f * (GU_PI/180.0f),0}; ScePspFVector3 rot2 = {-(GU_PI/180.0f)*60.0f,0,0}; ScePspFVector3 pos = {0,0,LIGHT_DISTANCE}; gumLoadIdentity(&lightMatrix); gumTranslate(&lightMatrix,&lightLookAt); gumRotateXYZ(&lightMatrix,&rot1); gumRotateXYZ(&lightMatrix,&rot2); gumTranslate(&lightMatrix,&pos); } gumFastInverse(&lightView,&lightMatrix); // render to shadow map { sceGuStart(GU_DIRECT,list); // set offscreen texture as a render target sceGuDrawBufferList(GU_PSM_4444,(void*)renderTarget,shadowmap.stride); // setup viewport sceGuOffset(2048 - (shadowmap.width/2),2048 - (shadowmap.height/2)); sceGuViewport(2048,2048,shadowmap.width,shadowmap.height); // clear screen sceGuClearColor(0xffffffff); sceGuClearDepth(0); sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); // setup view/projection from light sceGuSetMatrix(GU_PROJECTION,&lightProjection); sceGuSetMatrix(GU_VIEW,&lightView); // shadow casters are drawn in black // disable lighting and texturing sceGuDisable(GU_LIGHTING); sceGuDisable(GU_TEXTURE_2D); // draw torus to shadow map drawShadowCaster( &torus ); sceGuFinish(); sceGuSync(0,0); } // render to frame buffer { sceGuStart(GU_DIRECT,list); // set frame buffer sceGuDrawBufferList(GU_PSM_4444,(void*)frameBuffer,BUF_WIDTH); // setup viewport sceGuOffset(2048 - (SCR_WIDTH/2),2048 - (SCR_HEIGHT/2)); sceGuViewport(2048,2048,SCR_WIDTH,SCR_HEIGHT); // clear screen sceGuClearColor(0xff554433); sceGuClearDepth(0); sceGuClear(GU_COLOR_BUFFER_BIT|GU_DEPTH_BUFFER_BIT); // setup view/projection from camera sceGuSetMatrix(GU_PROJECTION,&projection); sceGuSetMatrix(GU_VIEW,&view); sceGuSetMatrix(GU_MODEL,&identity); // setup a light ScePspFVector3 lightPos = { lightMatrix.w.x, lightMatrix.w.y, lightMatrix.w.z }; ScePspFVector3 lightDir = { lightMatrix.z.x, lightMatrix.z.y, lightMatrix.z.z }; sceGuLight(0,GU_SPOTLIGHT,GU_DIFFUSE,&lightPos); sceGuLightSpot(0,&lightDir, 5.0, 0.6); sceGuLightColor(0,GU_DIFFUSE,0x00ff4040); sceGuLightAtt(0,1.0f,0.0f,0.0f); sceGuAmbient(0x00202020); sceGuEnable(GU_LIGHTING); sceGuEnable(GU_LIGHT0); // draw torus drawGeometry( &torus ); // setup texture projection sceGuTexMapMode( GU_TEXTURE_MATRIX, 0, 0 ); sceGuTexProjMapMode( GU_POSITION ); // set shadowmap as a texture sceGuTexMode(shadowmap.format,0,0,0); sceGuTexImage(shadowmap.mipmap,shadowmap.width,shadowmap.height,shadowmap.stride,shadowmap.data); sceGuTexFunc(GU_TFX_MODULATE,GU_TCC_RGB); sceGuTexFilter(GU_LINEAR,GU_LINEAR); sceGuTexWrap(GU_CLAMP,GU_CLAMP); sceGuEnable(GU_TEXTURE_2D); // calculate texture projection matrix for shadowmap ScePspFMatrix4 shadowProj; gumMultMatrix(&shadowProj, &lightProjectionInf, &lightView); gumMultMatrix(&shadowProj, &textureProjScaleTrans, &shadowProj); // draw grid receiving shadow drawShadowReceiver( &grid, shadowProj ); sceGuFinish(); sceGuSync(0,0); } sceDisplayWaitVblankStart(); frameBuffer = sceGuSwapBuffers(); val++; } sceGuTerm(); sceKernelExitGame(); return 0; }
void* getStaticVramTexture(unsigned int width, unsigned int height, unsigned int psm) { void* result = getStaticVramBuffer(width,height,psm); return (void*)(((unsigned int)result) + ((unsigned int)sceGeEdramGetAddr())); }