Пример #1
0
//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;
}
Пример #2
0
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;
}
Пример #3
0
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;
}
Пример #4
0
//	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;
	}
}
Пример #5
0
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;
}
Пример #7
0
/* 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;
}
Пример #8
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;
}
Пример #9
0
//
// 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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
// 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
}
Пример #13
0
// 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;
}
Пример #14
0
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;
}
Пример #15
0
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];
}
Пример #16
0
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;

}
Пример #17
0
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;
}
Пример #18
0
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 */
}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
// 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;
}
Пример #22
0
/* 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;
}