bool DisplayManager::setGraphicsMode(int mode) { DEBUG_ENTER_FUNC(); _graphicsMode = mode; calculateScaleParams(); return true; }
/* Get the width and height of a png image */ bool PngLoader::findImageDimensions() { DEBUG_ENTER_FUNC(); bool status = basicImageLoad(); PSP_DEBUG_PRINT("width[%d], height[%d], paletteSize[%d], bitDepth[%d], channels[%d], rowBytes[%d]\n", _width, _height, _paletteSize, _bitDepth, _channels, _infoPtr->rowbytes); png_destroy_read_struct(&_pngPtr, &_infoPtr, png_infopp_NULL); return status; }
Mp3PspStream::~Mp3PspStream() { DEBUG_ENTER_FUNC(); deinitStream(); releaseStreamME(); // free the memory used for this stream if (_disposeAfterUse == DisposeAfterUse::YES) delete _inStream; }
bool PSPFilesystemNode::getChildren(AbstractFSList &myList, ListMode mode, bool hidden) const { DEBUG_ENTER_FUNC(); assert(_isDirectory); //TODO: honor the hidden flag bool ret = true; if (PowerMan.beginCriticalSection() == PowerManager::Blocked) PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend PSP_DEBUG_PRINT_FUNC("Current path[%s]\n", _path.c_str()); int dfd = sceIoDopen(_path.c_str()); if (dfd > 0) { SceIoDirent dir; memset(&dir, 0, sizeof(dir)); while (sceIoDread(dfd, &dir) > 0) { // Skip 'invisible files if (dir.d_name[0] == '.') continue; PSPFilesystemNode entry; entry._isValid = true; entry._displayName = dir.d_name; Common::String newPath(_path); if (newPath.lastChar() != '/') newPath += '/'; newPath += dir.d_name; entry._path = newPath; entry._isDirectory = dir.d_stat.st_attr & FIO_SO_IFDIR; PSP_DEBUG_PRINT_FUNC("Child[%s], %s\n", entry._path.c_str(), entry._isDirectory ? "dir" : "file"); // Honor the chosen mode if ((mode == Common::FSNode::kListFilesOnly && entry._isDirectory) || (mode == Common::FSNode::kListDirectoriesOnly && !entry._isDirectory)) continue; myList.push_back(new PSPFilesystemNode(entry)); } sceIoDclose(dfd); ret = true; } else { // dfd <= 0 ret = false; } PowerMan.endCriticalSection(); return ret; }
/* move the position the keyboard is currently drawn at */ void PSPKeyboard::increaseKeyboardLocationY(int amount) { DEBUG_ENTER_FUNC(); int newY = _movedY + amount; if (newY > PSP_SCREEN_HEIGHT - 5 || newY < 0 - 140) { // clamp return; } _movedY = newY; setDirty(); }
/* move the position the keyboard is currently drawn at */ void PSPKeyboard::increaseKeyboardLocationX(int amount) { DEBUG_ENTER_FUNC(); int newX = _movedX + amount; if (newX > PSP_SCREEN_WIDTH - 5 || newX < 0 - 140) { // clamp return; } _movedX = newX; setDirty(); }
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; }
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; }
// For the PSP, since we're building in suspend support, we moved opening // the actual file to an open function since we need an actual PspIoStream object to suspend. // PspIoStream *PspIoStream::makeFromPath(const Common::String &path, bool writeMode) { DEBUG_ENTER_FUNC(); PspIoStream *stream = new PspIoStream(path, writeMode); if (stream->open() <= 0) { delete stream; stream = 0; } return stream; }
PspIoStream::~PspIoStream() { DEBUG_ENTER_FUNC(); if (PowerMan.beginCriticalSection()) PSP_DEBUG_PRINT_FUNC("suspended\n"); PowerMan.unregisterForSuspend(this); // Unregister with powermanager to be suspended // Must do this before fclose() or resume() will reopen. sceIoClose(_handle); PowerMan.endCriticalSection(); }
// More challenging -- need to shift // We assume dst is aligned void PspMemorySwap::swap32Misaligned(uint32 *dst32, const uint16 *src16, uint32 bytes, PSPPixelFormat &format) { DEBUG_ENTER_FUNC(); const uint32 shiftValue = 16; uint32 *src32 = (uint32 *)(((uint32)src16) & 0xFFFFFFFC); // remove misalignment // Try to do groups of 4 words uint32 words4 = bytes >> 4; uint32 srcWord = src32[0]; // preload while (words4--) { uint32 dstWord = srcWord >> shiftValue; srcWord = src32[1]; dstWord |= srcWord << shiftValue; dst32[0] = format.swapRedBlue32(dstWord); dstWord = srcWord >> shiftValue; srcWord = src32[2]; dstWord |= srcWord << shiftValue; dst32[1] = format.swapRedBlue32(dstWord); dstWord = srcWord >> shiftValue; srcWord = src32[3]; dstWord |= srcWord << shiftValue; dst32[2] = format.swapRedBlue32(dstWord); dstWord = srcWord >> shiftValue; srcWord = src32[4]; dstWord |= srcWord << shiftValue; dst32[3] = format.swapRedBlue32(dstWord); src32 += 4; dst32 += 4; } uint32 words = (bytes & 0xF) >> 2; // we read one word ahead of what we write // setup the first read if (words) { //srcWord = *src32++; // don't need this. already loaded src32++; // we already have the value loaded in while (words--) { uint32 dstWord = srcWord >> shiftValue; srcWord = *src32++; dstWord |= srcWord << shiftValue; *dst32++ = format.swapRedBlue32(dstWord); } } uint32 bytesLeft = bytes & 3; if (bytesLeft) { // for swap, can only be 1 short left *((uint16 *)dst32) = format.swapRedBlue16((uint16)(srcWord >> shiftValue)); } }
Graphics::Surface *Screen::lockAndGetForEditing() { DEBUG_ENTER_FUNC(); _frameBuffer.pixels = _buffer.getPixels(); _frameBuffer.w = _buffer.getSourceWidth(); _frameBuffer.h = _buffer.getSourceHeight(); _frameBuffer.pitch = _buffer.getBytesPerPixel() * _buffer.getWidth(); _frameBuffer.format = _pixelFormat; // We'll set to dirty once we unlock the screen return &_frameBuffer; }
void Mp3PspStream::deinitStream() { DEBUG_ENTER_FUNC(); if (_state == MP3_STATE_INIT) return; // Deinit MAD mad_header_finish(&_header); mad_stream_finish(&_stream); _state = MP3_STATE_EOS; }
bool PSPKeyboard::handleCornersSelectedState(Common::Event &event, SceCtrlData &pad) { DEBUG_ENTER_FUNC(); // We care about 4 buttons + triggers (for letter selection) bool haveEvent = false; if (CHANGED(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER)) haveEvent = getInputChoice(event, pad); if (!DOWN(PSP_4BUTTONS | PSP_CTRL_RTRIGGER | PSP_CTRL_LTRIGGER)) // Must be up to move cursor getCursorMovement(pad); return haveEvent; }
// Destructor PSPKeyboard::~PSPKeyboard() { DEBUG_ENTER_FUNC(); if (!_init) { return; } for (int i = 0; i < guiStringsSize; i++) { _buffers[i].deallocate(); _palettes[i].deallocate(); } _init = false; }
// 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 }
void PSPKeyboard::handleRTriggerDownState(SceCtrlData &pad) { DEBUG_ENTER_FUNC(); if (UNPRESSED(PSP_CTRL_RTRIGGER)) { _dirty = true; if (_mode > 1) _mode = 0; else _mode = (_mode == 0) ? 1 : 0; _state = kDefault; } }
void PSPKeyboard::handleLTriggerDownState(SceCtrlData &pad) { DEBUG_ENTER_FUNC(); if (UNPRESSED(PSP_CTRL_LTRIGGER)) { _dirty = true; if (_mode < 2) _mode = 2; else _mode = (_mode == 2) ? 3 : 2; _state = kDefault; } }
bool PSPFilesystemNode::exists() const { DEBUG_ENTER_FUNC(); int ret = 0; if (PowerMan.beginCriticalSection() == PowerManager::Blocked) PSP_DEBUG_PRINT_FUNC("Suspended\n"); // Make sure to block in case of suspend PSP_DEBUG_PRINT_FUNC("path [%s]\n", _path.c_str()); ret = access(_path.c_str(), F_OK); PowerMan.endCriticalSection(); return (ret == 0); }
AbstractFSNode *PSPFilesystemNode::getParent() const { DEBUG_ENTER_FUNC(); if (_path == ROOT_PATH) return 0; PSP_DEBUG_PRINT_FUNC("current[%s]\n", _path.c_str()); const char *start = _path.c_str(); const char *end = lastPathComponent(_path, '/'); AbstractFSNode *node = new PSPFilesystemNode(Common::String(start, end - start), false); return node; }
// 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 PSPKeyboard::handleDefaultState(Common::Event &event, SceCtrlData &pad) { DEBUG_ENTER_FUNC(); bool haveEvent = false; if (PRESSED(PSP_CTRL_LTRIGGER)) // Don't say we used up the input _state = kLTriggerDown; else if (PRESSED(PSP_CTRL_RTRIGGER)) // Don't say we used up the input _state = kRTriggerDown; else if (CHANGED(PSP_4BUTTONS)) // We only care about the 4 buttons haveEvent = getInputChoice(event, pad); else if (!DOWN(PSP_4BUTTONS)) // Must be up to move cursor getCursorMovement(pad); return haveEvent; }
bool DisplayManager::setGraphicsMode(const char *name) { DEBUG_ENTER_FUNC(); int i = 0; while (_supportedModes[i].name) { if (!strcmpi(_supportedModes[i].name, name)) { setGraphicsMode(_supportedModes[i].id); return true; } i++; } return false; }
bool PngLoader::load() { DEBUG_ENTER_FUNC(); // Try to load the image _file.seek(0); // Go back to start if (!loadImageIntoBuffer()) { PSP_DEBUG_PRINT("failed to load image\n"); return false; } PSP_DEBUG_PRINT("succeded in loading image\n"); if (_paletteSize == 16) // 4-bit _buffer->flipNibbles(); // required because of PNG 4-bit format return true; }
void DisplayManager::setSizeAndPixelFormat(uint width, uint height, const Graphics::PixelFormat *format) { DEBUG_ENTER_FUNC(); PSP_DEBUG_PRINT("w[%u], h[%u], pformat[%p]\n", width, height, format); _screen->deallocate(); _screen->setScummvmPixelFormat(format); _screen->setSize(width, height); _screen->allocate(); _cursor->setScreenPaletteScummvmPixelFormat(format); _displayParams.screenSource.width = width; _displayParams.screenSource.height = height; calculateScaleParams(); }
void Overlay::setBytesPerPixel(uint32 size) { DEBUG_ENTER_FUNC(); switch (size) { case 1: _buffer.setPixelFormat(PSPPixelFormat::Type_Palette_8bit); _palette.setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit); break; case 2: _buffer.setPixelFormat(PSPPixelFormat::Type_4444); break; case 4: _buffer.setPixelFormat(PSPPixelFormat::Type_8888); break; } }
AbstractFSNode *PSPFilesystemNode::getChild(const Common::String &n) const { DEBUG_ENTER_FUNC(); // FIXME: Pretty lame implementation! We do no error checking to speak // of, do not check if this is a special node, etc. assert(_isDirectory); Common::String newPath(_path); if (_path.lastChar() != '/') newPath += '/'; newPath += n; PSP_DEBUG_PRINT_FUNC("child [%s]\n", newPath.c_str()); AbstractFSNode *node = new PSPFilesystemNode(newPath, true); return node; }
/* * Function to suspend the IO stream (called by PowerManager) * we can have no output here */ int PspIoStream::suspend() { DEBUG_ENTER_FUNC(); _suspendCount++; if (_handle > 0 && _pos < 0) { /* check for error */ _errorSuspend = SuspendError; _errorPos = _pos; _errorHandle = _handle; } if (_handle > 0) { sceIoClose(_handle); // close our file descriptor _handle = 0xFFFFFFFF; // Set handle to non-null invalid value so makeFromPath doesn't return error } return 0; }
void PspMemory::copy(byte *dst, const byte *src, uint32 bytes) { DEBUG_ENTER_FUNC(); #ifdef TEST_MEMORY_COPY uint32 debugBytes = bytes; const byte *debugDst = dst, *debugSrc = src; #endif PSP_DEBUG_PRINT("copy(): dst[%p], src[%p], bytes[%d]\n", dst, src, bytes); // align the destination pointer first uint32 prefixDst = (((uint32)dst) & 0x3); if (prefixDst) { prefixDst = 4 - prefixDst; // prefix only if we have address % 4 != 0 PSP_DEBUG_PRINT("prefixDst[%d]\n", prefixDst); bytes -= prefixDst; // remember we assume bytes >= 4 if (bytes < MIN_AMOUNT_FOR_COMPLEX_COPY) { // check if it's worthwhile to continue copy8(dst, src, bytes + prefixDst); #ifdef TEST_MEMORY_COPY testCopy(debugDst, debugSrc, debugBytes); #endif return; } while (prefixDst--) { *dst++ = *src++; } } // check the source pointer alignment now uint32 alignSrc = (((uint32)src) & 0x3); if (alignSrc) { // we'll need to realign our reads copy32Misaligned((uint32 *)dst, src, bytes, alignSrc); } else { copy32Aligned((uint32 *)dst, (uint32 *)src, bytes); } #ifdef TEST_MEMORY_COPY testCopy(debugDst, debugSrc, debugBytes); #endif }