//Load a PSP audio module bool Mp3PspStream::loadStartAudioModule(const char *modname, int partition){ DEBUG_ENTER_FUNC(); SceKernelLMOption option; SceUID modid; memset(&option, 0, sizeof(option)); option.size = sizeof(option); option.mpidtext = partition; option.mpiddata = partition; option.position = 0; option.access = 1; modid = sceKernelLoadModule(modname, 0, &option); if (modid < 0) { PSP_ERROR("Failed to load module %s. Got error 0x%x\n", modname, modid); return false; } int ret = sceKernelStartModule(modid, 0, NULL, NULL, NULL); if (ret < 0) { PSP_ERROR("Failed to start module %s. Got error 0x%x\n", modname, ret); return false; } return true; }
bool Mp3PspStream::initStreamME() { // The following will eventually go into the thread memset(_codecParams, 0, sizeof(_codecParams)); // Init the MP3 hardware int ret = 0; ret = sceAudiocodecCheckNeedMem(_codecParams, 0x1002); if (ret < 0) { PSP_ERROR("failed to init MP3 ME module. sceAudiocodecCheckNeedMem returned 0x%x.\n", ret); return false; } PSP_DEBUG_PRINT("sceAudiocodecCheckNeedMem returned %d\n", ret); ret = sceAudiocodecGetEDRAM(_codecParams, 0x1002); if (ret < 0) { PSP_ERROR("failed to init MP3 ME module. sceAudiocodecGetEDRAM returned 0x%x.\n", ret); return false; } PSP_DEBUG_PRINT("sceAudioCodecGetEDRAM returned %d\n", ret); PSP_DEBUG_PRINT("samplerate[%d]\n", _sampleRate); _codecParams[10] = _sampleRate; ret = sceAudiocodecInit(_codecParams, 0x1002); if (ret < 0) { PSP_ERROR("failed to init MP3 ME module. sceAudiocodecInit returned 0x%x.\n", ret); return false; } return true; }
bool PspAudio::open(uint32 freq, uint32 numOfChannels, uint32 numOfSamples, callbackFunc callback, void *userData) { DEBUG_ENTER_FUNC(); if (_init) { PSP_ERROR("audio device already initialized\n"); return true; } PSP_DEBUG_PRINT("freq[%d], numOfChannels[%d], numOfSamples[%d], callback[%p], userData[%x]\n", freq, numOfChannels, numOfSamples, callback, (uint32)userData); numOfSamples = PSP_AUDIO_SAMPLE_ALIGN(numOfSamples); uint32 bufLen = numOfSamples * numOfChannels * NUM_BUFFERS * sizeof(uint16); PSP_DEBUG_PRINT("total buffer size[%d]\n", bufLen); _buffers[0] = (byte *)memalign(64, bufLen); if (!_buffers[0]) { PSP_ERROR("failed to allocate memory for audio buffers\n"); return false; } memset(_buffers[0], 0, bufLen); // clean the buffer // Fill in the rest of the buffer pointers byte *pBuffer = _buffers[0]; for (int i = 1; i < NUM_BUFFERS; i++) { pBuffer += numOfSamples * numOfChannels * sizeof(uint16); _buffers[i] = pBuffer; } // Reserve a HW channel for our audio _pspChannel = sceAudioChReserve(PSP_AUDIO_NEXT_CHANNEL, numOfSamples, numOfChannels == 2 ? PSP_AUDIO_FORMAT_STEREO : PSP_AUDIO_FORMAT_MONO); if (_pspChannel < 0) { PSP_ERROR("failed to reserve audio channel\n"); return false; } PSP_DEBUG_PRINT("reserved channel[%d] for audio\n", _pspChannel); // Save our data _numOfChannels = numOfChannels; _numOfSamples = numOfSamples; _bufferSize = numOfSamples * numOfChannels * sizeof(uint16); // should be the right size to send the app _callback = callback; _userData = userData; _bufferToFill = 0; _bufferToPlay = 0; _init = true; _paused = true; // start in paused mode threadCreateAndStart("audioThread", PRIORITY_AUDIO_THREAD, STACK_AUDIO_THREAD); // start the consumer thread return true; }
// Handler events coming in from the inputHandler // void ImageViewer::handleEvent(uint32 event) { DEBUG_ENTER_FUNC(); switch (event) { case EVENT_HIDE: setVisible(false); break; case EVENT_SHOW: setVisible(true); break; case EVENT_ZOOM_IN: modifyZoom(true); break; case EVENT_ZOOM_OUT: modifyZoom(false); break; case EVENT_MOVE_LEFT: case EVENT_MOVE_UP: case EVENT_MOVE_RIGHT: case EVENT_MOVE_DOWN: case EVENT_MOVE_STOP: _movement = (Event)event; break; case EVENT_NEXT_IMAGE: loadNextImage(); break; case EVENT_LAST_IMAGE: loadLastImage(); break; default: PSP_ERROR("Unknown event %d\n", event); break; } }
bool ImageViewer::load(int imageNum) { if (_init) unload(); // build string char number[8]; sprintf(number, "%d", imageNum); Common::String imageNameStr(imageName); Common::String specificImageName = imageNameStr + Common::String(number) + Common::String(".png"); // search for image file if (!SearchMan.hasFile(specificImageName)) { PSP_ERROR("file %s not found\n", specificImageName.c_str()); return false; } Common::ScopedPtr<Common::SeekableReadStream> file(SearchMan.createReadStreamForMember(specificImageName)); _buffer = new Buffer(); _palette = new Palette(); _renderer = new GuRenderer(); assert(_buffer); assert(_palette); assert(_renderer); // Load a PNG into our buffer and palette. Size it by the actual size of the image PngLoader image(*file, *_buffer, *_palette, Buffer::kSizeBySourceSize); PngLoader::Status status = image.allocate(); // allocate the buffers for the file char error[100]; if (status == PngLoader::BAD_FILE) { sprintf(error, "Cannot display %s. Not a proper PNG file", specificImageName.c_str()); GUI::TimedMessageDialog dialog(error, 4000); dialog.runModal(); return false; } else if (status == PngLoader::OUT_OF_MEMORY) { sprintf(error, "Out of memory loading %s. Try making the image smaller", specificImageName.c_str()); GUI::TimedMessageDialog dialog(error, 4000); dialog.runModal(); return false; } // try to load the image file if (!image.load()) { sprintf(error, "Cannot display %s. Not a proper PNG file", specificImageName.c_str()); GUI::TimedMessageDialog dialog(error, 4000); dialog.runModal(); return false; } setConstantRendererOptions(); setFullScreenImageParams(); // prepare renderer for full screen view _imageNum = imageNum; // now we can say we displayed this image _init = true; return true; }
bool DefaultDisplayClient::allocate(bool bufferInVram /* = false */, bool paletteInVram /* = false */) { DEBUG_ENTER_FUNC(); if (!_buffer.allocate(bufferInVram)) { PSP_ERROR("Couldn't allocate buffer.\n"); return false; } if (_buffer.hasPalette()) { PSP_DEBUG_PRINT("_palette[%p]\n", &_palette); if (!_palette.allocate()) { PSP_ERROR("Couldn't allocate palette.\n"); return false; } } return true; }
/* Callback thread */ int CallbackThread(SceSize /*size*/, void *arg) { int cbid; cbid = sceKernelCreateCallback("Exit Callback", (SceKernelCallbackFunction)exit_callback, NULL); sceKernelRegisterExitCallback(cbid); /* Set up callbacks for PSPIoStream */ cbid = sceKernelCreateCallback("Power Callback", (SceKernelCallbackFunction)power_callback, 0); if (cbid >= 0) { if (scePowerRegisterCallback(-1, cbid) < 0) { PSP_ERROR("Couldn't register callback for power_callback\n"); } } else { PSP_ERROR("Couldn't create a callback for power_callback\n"); } sceKernelSleepThreadCB(); return 0; }
bool PspIoStream::err() const { DEBUG_ENTER_FUNC(); if (_error) // We dump since no printing to screen with suspend callback PSP_ERROR("mem_error[%d], source[%d], suspend error[%d], pos[%d]," "_errorPos[%d], _errorHandle[%p], suspendCount[%d]\n", _error, _errorSource, _errorSuspend, _pos, _errorPos, _errorHandle, _suspendCount); return _error; }
// // Load a texture from a png image // bool PngLoader::loadImageIntoBuffer() { DEBUG_ENTER_FUNC(); if (!basicImageLoad()) { png_destroy_read_struct(&_pngPtr, &_infoPtr, png_infopp_NULL); return false; } png_set_strip_16(_pngPtr); // Strip off 16 bit channels in case they occur if (_paletteSize) { // Copy the palette png_colorp srcPal = _infoPtr->palette; for (int i = 0; i < _infoPtr->num_palette; i++) { unsigned char alphaVal = (i < _infoPtr->num_trans) ? _infoPtr->trans[i] : 0xFF; // Load alpha if it's there _palette->setSingleColorRGBA(i, srcPal->red, srcPal->green, srcPal->blue, alphaVal); srcPal++; } } else { // Not a palettized image if (_colorType == PNG_COLOR_TYPE_GRAY && _bitDepth < 8) png_set_gray_1_2_4_to_8(_pngPtr); // Round up grayscale images if (png_get_valid(_pngPtr, _infoPtr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(_pngPtr); // Convert trans channel to alpha for 32 bits png_set_add_alpha(_pngPtr, 0xff, PNG_FILLER_AFTER); // Filler for alpha if none exists } uint32 rowBytes = png_get_rowbytes(_pngPtr, _infoPtr); // there seems to be a bug in libpng where it doesn't increase the rowbytes or the // channel even after we add the alpha channel if (_channels == 3 && (rowBytes / _width) == 3) { _channels = 4; rowBytes = _width * _channels; } PSP_DEBUG_PRINT("rowBytes[%d], channels[%d]\n", rowBytes, _channels); unsigned char *line = (unsigned char*) malloc(rowBytes); if (!line) { png_destroy_read_struct(&_pngPtr, png_infopp_NULL, png_infopp_NULL); PSP_ERROR("Couldn't allocate line\n"); return false; } for (size_t y = 0; y < _height; y++) { png_read_row(_pngPtr, line, png_bytep_NULL); _buffer->copyFromRect(line, rowBytes, 0, y, _width, 1); // Copy into buffer } free(line); png_read_end(_pngPtr, _infoPtr); png_destroy_read_struct(&_pngPtr, &_infoPtr, png_infopp_NULL); return true; }
bool PspIoStream::physicalSeekFromCur(int32 offset) { int ret = sceIoLseek32(_handle, offset, PSP_SEEK_CUR); if (ret < 0) { _error = true; PSP_ERROR("failed to seek in file[%s] to [%x]. Error[%x]\n", _path.c_str(), offset, ret); return false; } _physicalPos += offset; return true; }
PngLoader::Status PngLoader::allocate() { DEBUG_ENTER_FUNC(); if (!findImageDimensions()) { PSP_ERROR("failed to get image dimensions\n"); return BAD_FILE; } _buffer->setSize(_width, _height, _sizeBy); uint32 bitsPerPixel = _bitDepth * _channels; if (_paletteSize) { // 8 or 4-bit image if (bitsPerPixel == 4) { _buffer->setPixelFormat(PSPPixelFormat::Type_Palette_4bit); _palette->setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_4bit); _paletteSize = 16; // round up } else if (bitsPerPixel == 8) { // 8-bit image _buffer->setPixelFormat(PSPPixelFormat::Type_Palette_8bit); _palette->setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit); _paletteSize = 256; // round up } else { PSP_ERROR("too many bits per pixel[%d] for a palette\n", bitsPerPixel); return BAD_FILE; } } else { // 32-bit image _buffer->setPixelFormat(PSPPixelFormat::Type_8888); } if (!_buffer->allocate()) { PSP_ERROR("failed to allocate buffer\n"); return OUT_OF_MEMORY; } if (_buffer->hasPalette() && !_palette->allocate()) { PSP_ERROR("failed to allocate palette\n"); return OUT_OF_MEMORY; } return OK; }
// this function gets called by PspThread when starting the new thread void MasterGuRenderer::threadFunction() { DEBUG_ENTER_FUNC(); // Create the callback. It should always get the pointer to MasterGuRenderer _callbackId = sceKernelCreateCallback("Display Callback", guCallback, this); if (_callbackId < 0) { PSP_ERROR("failed to create display callback\n"); } PSP_DEBUG_PRINT("created callback. Going to sleep\n"); sceKernelSleepThreadCB(); // sleep until we get a callback }
// Don't do it with blocking inline bool PspAudio::playBuffer() { DEBUG_ENTER_FUNC(); int ret; if (_numOfChannels == 1) ret = sceAudioOutputBlocking(_pspChannel, PSP_AUDIO_VOLUME_MAX, _buffers[_bufferToPlay]); else ret = sceAudioOutputPannedBlocking(_pspChannel, PSP_AUDIO_VOLUME_MAX, PSP_AUDIO_VOLUME_MAX, _buffers[_bufferToPlay]); if (ret < 0) { PSP_ERROR("failed to output audio. Error[%d]\n", ret); return false; } return true; }
bool Mp3PspStream::initDecoder() { DEBUG_ENTER_FUNC(); if (_decoderInit) { PSP_ERROR("Already initialized!"); return true; } // Based on PSP firmware version, we need to do different things to do Media Engine processing uint32 firmware = sceKernelDevkitVersion(); PSP_DEBUG_PRINT("Firmware version 0x%x\n", firmware); if (firmware == 0x01050001){ if (!loadStartAudioModule((char *)(void *)"flash0:/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL)) { PSP_ERROR("failed to load me_for_vsh.prx. ME cannot start.\n"); _decoderFail = true; return false; } if (!loadStartAudioModule((char *)(void *)"flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL)) { PSP_ERROR("failed to load audiocodec.prx. ME cannot start.\n"); _decoderFail = true; return false; } } else { if (sceUtilityLoadAvModule(PSP_AV_MODULE_AVCODEC) < 0) { PSP_ERROR("failed to load AVCODEC module. ME cannot start.\n"); _decoderFail = true; return false; } } PSP_DEBUG_PRINT("Using PSP's ME for MP3\n"); // important to know this is happening _decoderInit = true; return true; }
inline void Mp3PspStream::updatePcmLength() { uint32 mpegVer = HEADER_GET_MPEG_VERSION(_stream.this_frame); // sadly, MAD can't do this for us PSP_DEBUG_PRINT("mpeg ver[%x]\n", mpegVer); switch (mpegVer) { case MPEG_VER1_HEADER: mpegVer = MPEG_VER1; break; case MPEG_VER2_HEADER: mpegVer = MPEG_VER2; break; case MPEG_VER2_5_HEADER: mpegVer = MPEG_VER2_5; break; default: PSP_ERROR("Unknown MPEG version %x\n", mpegVer); break; } PSP_DEBUG_PRINT("layer[%d]\n", _header.layer); _pcmLength = mp3SamplesPerFrame[(mpegVer * 3) + _header.layer - 1]; }
void DisplayManager::calculateScaleParams() { if (!_displayParams.screenSource.width || !_displayParams.screenSource.height) return; // we can't calculate anything without these switch (_graphicsMode) { case ORIGINAL_RESOLUTION: // check if we can fit the original resolution inside the screen if ((_displayParams.screenSource.width < PSP_SCREEN_WIDTH) && (_displayParams.screenSource.height < PSP_SCREEN_HEIGHT)) { _displayParams.screenOutput.width = _displayParams.screenSource.width; _displayParams.screenOutput.height = _displayParams.screenSource.height; } else { // revert to stretch to fit _displayParams.screenOutput.width = PSP_SCREEN_WIDTH; _displayParams.screenOutput.height = PSP_SCREEN_HEIGHT; } break; case KEEP_ASPECT_RATIO: { // maximize the height while keeping aspect ratio float aspectRatio = (float)_displayParams.screenSource.width / (float)_displayParams.screenSource.height; _displayParams.screenOutput.height = PSP_SCREEN_HEIGHT; // always full height _displayParams.screenOutput.width = (uint32)(PSP_SCREEN_HEIGHT * aspectRatio); if (_displayParams.screenOutput.width > PSP_SCREEN_WIDTH) // we can't have wider than the screen _displayParams.screenOutput.width = PSP_SCREEN_WIDTH; } break; case STRETCHED_FULL_SCREEN: // we simply stretch to the whole screen _displayParams.screenOutput.width = PSP_SCREEN_WIDTH; _displayParams.screenOutput.height = PSP_SCREEN_HEIGHT; break; default: PSP_ERROR("Unsupported graphics mode[%d].\n", _graphicsMode); } // calculate scale factors for X and Y _displayParams.scaleX = ((float)_displayParams.screenOutput.width) / _displayParams.screenSource.width; _displayParams.scaleY = ((float)_displayParams.screenOutput.height) / _displayParams.screenSource.height; }
uint32 PspIoStream::read(void *ptr, uint32 len) { DEBUG_ENTER_FUNC(); PSP_DEBUG_PRINT_FUNC("filename[%s], len[0x%x], ptr[%p], _pos[%x], _physPos[%x]\n", _path.c_str(), len, ptr, _pos, _physicalPos); if (_error || _eos || len <= 0) return 0; uint32 lenRemainingInFile = _fileSize - _pos; // check for getting EOS if (len > lenRemainingInFile) { len = lenRemainingInFile; _eos = true; } if (PowerMan.beginCriticalSection()) PSP_DEBUG_PRINT_FUNC("suspended\n"); // check if we need to seek if (_pos != _physicalPos) PSP_DEBUG_PRINT("seeking from %x to %x\n", _physicalPos, _pos); if (!physicalSeekFromCur(_pos - _physicalPos)) { _error = true; return 0; } int ret = sceIoRead(_handle, ptr, len); PowerMan.endCriticalSection(); _physicalPos += ret; // Update position _pos = _physicalPos; if (ret != (int)len) { // error PSP_ERROR("sceIoRead returned [0x%x] instead of len[0x%x]\n", ret, len); _error = true; _errorSource = 4; } return ret; }
inline void MasterGuRenderer::guPostRender() { DEBUG_ENTER_FUNC(); sceGuFinish(); #ifdef USE_DISPLAY_CALLBACK if (_callbackId < 0) PSP_ERROR("bad callbackId[%d]\n", _callbackId); else sceKernelNotifyCallback(_callbackId, 0); // notify the callback. Nothing extra to pass #else sceGuSync(0, 0); #ifdef ENABLE_RENDER_MEASURE uint32 now = g_system->getMillis(); PSP_INFO_PRINT("Render took %d milliseconds\n", now - _lastRenderTime); #endif /* ENABLE_RENDER_MEASURE */ sceDisplayWaitVblankStart(); sceGuSwapBuffers(); _renderFinished = true; #endif /* !USE_DISPLAY_CALLBACK */ }
uint32 PspIoStream::write(const void *ptr, uint32 len) { DEBUG_ENTER_FUNC(); PSP_DEBUG_PRINT_FUNC("filename[%s], len[0x%x], ptr[%p], _pos[%x], _physPos[%x]\n", _path.c_str(), len, ptr, _pos, _physicalPos); if (!len || _error) // we actually get some calls with len == 0! return 0; _eos = false; // we can't have eos with write if (PowerMan.beginCriticalSection()) PSP_DEBUG_PRINT_FUNC("suspended\n"); // check if we need to seek if (_pos != _physicalPos) if (!physicalSeekFromCur(_pos - _physicalPos)) { _error = true; return 0; } int ret = sceIoWrite(_handle, ptr, len); PowerMan.endCriticalSection(); if (ret != (int)len) { _error = true; _errorSource = 5; PSP_ERROR("sceIoWrite returned[0x%x] instead of len[0x%x]\n", ret, len); } _physicalPos += ret; _pos = _physicalPos; if (_pos > _fileSize) _fileSize = _pos; return ret; }
bool Mp3PspStream::stopDecoder() { DEBUG_ENTER_FUNC(); if (!_decoderInit) return true; // Based on PSP firmware version, we need to do different things to do Media Engine processing if (sceKernelDevkitVersion() == 0x01050001){ // TODO: how do we unload? /* if (!unloadAudioModule("flash0:/kd/me_for_vsh.prx", PSP_MEMORY_PARTITION_KERNEL) || !unloadAudioModule("flash0:/kd/audiocodec.prx", PSP_MEMORY_PARTITION_KERNEL) { PSP_ERROR("failed to unload audio module\n"); return false; } */ }else{ if (sceUtilityUnloadModule(PSP_MODULE_AV_AVCODEC) < 0) { PSP_ERROR("failed to unload avcodec module\n"); return false; } } _decoderInit = false; return true; }
// This function leaks. For now I don't care bool PspUnitTests::testFileSystem() { // create memory const uint32 BufSize = 32 * 1024; char* buffer = new char[BufSize]; int i; Common::WriteStream *wrStream; Common::SeekableReadStream *rdStream; PSP_INFO_PRINT("testing fileSystem...\n"); // fill buffer for (i=0; i<(int)BufSize; i += 4) { buffer[i] = 'A'; buffer[i + 1] = 'B'; buffer[i + 2] = 'C'; buffer[i + 3] = 'D'; } // create a file const char *path = "./file.test"; Common::FSNode file(path); PSP_INFO_PRINT("creating write stream...\n"); wrStream = file.createWriteStream(); if (!wrStream) { PSP_ERROR("%s couldn't be created.\n", path); return false; } // write contents char* index = buffer; int32 totalLength = BufSize; int32 curLength = 50; PSP_INFO_PRINT("writing...\n"); while(totalLength - curLength > 0) { if ((int)wrStream->write(index, curLength) != curLength) { PSP_ERROR("couldn't write %d bytes\n", curLength); return false; } totalLength -= curLength; index += curLength; //curLength *= 2; //PSP_INFO_PRINT("write\n"); } // write the rest if ((int)wrStream->write(index, totalLength) != totalLength) { PSP_ERROR("couldn't write %d bytes\n", curLength); return false; } delete wrStream; PSP_INFO_PRINT("reading...\n"); rdStream = file.createReadStream(); if (!rdStream) { PSP_ERROR("%s couldn't be created.\n", path); return false; } // seek to beginning if (!rdStream->seek(0, SEEK_SET)) { PSP_ERROR("couldn't seek to the beginning after writing the file\n"); return false; } // read the contents char *readBuffer = new char[BufSize + 4]; memset(readBuffer, 0, (BufSize + 4)); index = readBuffer; while (rdStream->read(index, 100) == 100) { index += 100; } if (!rdStream->eos()) { PSP_ERROR("didn't find EOS at end of stream\n"); return false; } // compare for (i=0; i<(int)BufSize; i++) if (buffer[i] != readBuffer[i]) { PSP_ERROR("reading/writing mistake at %x. Got %x instead of %x\n", i, readBuffer[i], buffer[i]); return false; } // Check for exceeding limit for (i=0; i<4; i++) { if (readBuffer[BufSize + i]) { PSP_ERROR("read exceeded limits. %d = %x\n", BufSize + i, readBuffer[BufSize + i]); } } delete rdStream; PSP_INFO_PRINT("writing...\n"); wrStream = file.createWriteStream(); if (!wrStream) { PSP_ERROR("%s couldn't be created.\n", path); return false; } const char *phrase = "Jello is really fabulous"; uint32 phraseLen = strlen(phrase); int ret; if ((ret = wrStream->write(phrase, phraseLen)) != (int)phraseLen) { PSP_ERROR("couldn't write phrase. Got %d instead of %d\n", ret, phraseLen); return false; } PSP_INFO_PRINT("reading...\n"); delete wrStream; rdStream = file.createReadStream(); if (!rdStream) { PSP_ERROR("%s couldn't be created.\n", path); return false; } char *readPhrase = new char[phraseLen + 2]; memset(readPhrase, 0, phraseLen + 2); if ((ret = rdStream->read(readPhrase, phraseLen) != phraseLen)) { PSP_ERROR("read error on phrase. Got %d instead of %d\n", ret, phraseLen); return false; } for (i=0; i<(int)phraseLen; i++) { if (readPhrase[i] != phrase[i]) { PSP_ERROR("bad read/write in phrase. At %d, %x != %x\n", i, readPhrase[i], phrase[i]); return false; } } // check for exceeding if (readPhrase[i] != 0) { PSP_ERROR("found excessive copy in phrase. %c at %d\n", readPhrase[i], i); return false; } PSP_INFO_PRINT("trying to read end...\n"); // seek to end if (!rdStream->seek(0, SEEK_END)) { PSP_ERROR("couldn't seek to end for append\n"); return false; }; // try to read if (rdStream->read(readPhrase, 2) || !rdStream->eos()) { PSP_ERROR("was able to read at end of file\n"); return false; } PSP_INFO_PRINT("ok\n"); return true; }
/* load the keyboard into memory */ bool PSPKeyboard::load() { DEBUG_ENTER_FUNC(); if (_init) { PSP_DEBUG_PRINT("keyboard already loaded into memory\n"); return true; } // For the shell, we must use a hack #ifdef PSP_KB_SHELL Common::FSNode node(PSP_KB_SHELL_PATH); #else /* normal mode */ Common::FSNode node("."); // Look in current directory #endif PSP_DEBUG_PRINT("path[%s]\n", node.getPath().c_str()); Common::Archive *fileArchive = NULL; Common::Archive *zipArchive = NULL; Common::SeekableReadStream * file = 0; if (node.getChild("kbd").exists() && node.getChild("kbd").isDirectory()) { PSP_DEBUG_PRINT("found directory ./kbd\n"); fileArchive = new Common::FSDirectory(node.getChild("kbd")); } if (node.getChild("kbd.zip").exists()) { PSP_DEBUG_PRINT("found kbd.zip\n"); zipArchive = Common::makeZipArchive(node.getChild("kbd.zip")); } int i; // Loop through all png images for (i = 0; i < guiStringsSize; i++) { PSP_DEBUG_PRINT("Opening %s.\n", _guiStrings[i]); // Look for the file in the kbd directory if (fileArchive && fileArchive->hasFile(_guiStrings[i])) { PSP_DEBUG_PRINT("found it in kbd directory.\n"); file = fileArchive->createReadStreamForMember(_guiStrings[i]); if (!file) { PSP_ERROR("Can't open kbd/%s for keyboard. No keyboard will load.\n", _guiStrings[i]); goto ERROR; } } // We didn't find it. Look for it in the zip file else if (zipArchive && zipArchive->hasFile(_guiStrings[i])) { PSP_DEBUG_PRINT("found it in kbd.zip.\n"); file = zipArchive->createReadStreamForMember(_guiStrings[i]); if (!file) { PSP_ERROR("Can't open %s in kbd.zip for keyboard. No keyboard will load.\n", _guiStrings[i]); goto ERROR; } } else { // Couldn't find the file PSP_ERROR("Can't find %s for keyboard. No keyboard will load.\n", _guiStrings[i]); goto ERROR; } PngLoader image(file, _buffers[i], _palettes[i]); if (image.allocate() != PngLoader::OK) { PSP_ERROR("Failed to allocate memory for keyboard image %s\n", _guiStrings[i]); goto ERROR; } if (!image.load()) { PSP_ERROR("Failed to load image from file %s\n", _guiStrings[i]); goto ERROR; } delete file; } /* for loop */ _init = true; delete fileArchive; delete zipArchive; return true; ERROR: delete file; delete fileArchive; delete zipArchive; for (int j = 0; j < i; j++) { _buffers[j].deallocate(); _palettes[j].deallocate(); } _init = false; return false; }