//***************************************************************************** // //***************************************************************************** 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; }
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); }
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); }
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));/* (挿入処理.) */ }
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 } }
/* ==================== 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"); }