aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backends/platform/psp/Makefile1
-rw-r--r--backends/platform/psp/module.mk1
-rw-r--r--backends/platform/psp/png_loader.cpp187
-rw-r--r--backends/platform/psp/png_loader.h70
-rw-r--r--backends/platform/psp/pspkeyboard.cpp183
-rw-r--r--backends/platform/psp/pspkeyboard.h3
6 files changed, 270 insertions, 175 deletions
diff --git a/backends/platform/psp/Makefile b/backends/platform/psp/Makefile
index 617ef7c8cc..b9a2b45013 100644
--- a/backends/platform/psp/Makefile
+++ b/backends/platform/psp/Makefile
@@ -148,6 +148,7 @@ OBJS := powerman.o \
thread.o \
rtc.o \
mp3.o \
+ png_loader.o \
tests.o
BACKEND := psp
diff --git a/backends/platform/psp/module.mk b/backends/platform/psp/module.mk
index 4652189ab4..f96c4ef583 100644
--- a/backends/platform/psp/module.mk
+++ b/backends/platform/psp/module.mk
@@ -17,6 +17,7 @@ MODULE_OBJS := powerman.o \
thread.o \
rtc.o \
mp3.o \
+ png_loader.o \
tests.o
# We don't use rules.mk but rather manually update OBJS and MODULE_DIRS.
diff --git a/backends/platform/psp/png_loader.cpp b/backends/platform/psp/png_loader.cpp
new file mode 100644
index 0000000000..417c502e54
--- /dev/null
+++ b/backends/platform/psp/png_loader.cpp
@@ -0,0 +1,187 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#include "common/scummsys.h"
+#include "common/stream.h"
+#include "backends/platform/psp/psppixelformat.h"
+#include "backends/platform/psp/display_client.h"
+#include "backends/platform/psp/png_loader.h"
+
+PngLoader::Status PngLoader::allocate() {
+ if (!findImageDimensions()) {
+ PSP_ERROR("failed to get image dimensions\n");
+ return BAD_FILE;
+ }
+
+ PSP_DEBUG_PRINT("width[%d], height[%d], paletteSize[%d], bitDepth[%d]\n", _width, _height, _paletteSize, _bitDepth);
+ _buffer->setSize(_width, _height, _sizeBy);
+
+ if (_paletteSize) { // 8 or 4-bit image
+ if (_paletteSize <= 16) { // 4 bit
+ _buffer->setPixelFormat(PSPPixelFormat::Type_Palette_4bit);
+ _palette->setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_4bit);
+ _paletteSize = 16;
+ } else if (_paletteSize <= 256) { // 8-bit image
+ _paletteSize = 256;
+ _buffer->setPixelFormat(PSPPixelFormat::Type_Palette_8bit);
+ _palette->setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit);
+ } else {
+ PSP_ERROR("palette of %d too big!\n", _paletteSize);
+ 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 (!_palette->allocate()) {
+ PSP_ERROR("failed to allocate palette\n");
+ return OUT_OF_MEMORY;
+ }
+ return OK;
+}
+
+bool PngLoader::load() {
+ // 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 PngLoader::warningFn(png_structp png_ptr, png_const_charp warning_msg) {
+ // ignore PNG warnings
+}
+
+// Read function for png library to be able to read from our SeekableReadStream
+//
+void PngLoader::libReadFunc(png_structp pngPtr, png_bytep data, png_size_t length) {
+ Common::SeekableReadStream *file;
+
+ file = (Common::SeekableReadStream *)pngPtr->io_ptr;
+
+ file->read(data, length);
+}
+
+bool PngLoader::basicImageLoad() {
+ _pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
+ if (!_pngPtr)
+ return false;
+
+ png_set_error_fn(_pngPtr, (png_voidp) NULL, (png_error_ptr) NULL, warningFn);
+
+ _infoPtr = png_create_info_struct(_pngPtr);
+ if (!_infoPtr) {
+ png_destroy_read_struct(&_pngPtr, png_infopp_NULL, png_infopp_NULL);
+ return false;
+ }
+ // Set the png lib to use our read function
+ png_set_read_fn(_pngPtr, (void *)_file, libReadFunc);
+
+ unsigned int sig_read = 0;
+
+ png_set_sig_bytes(_pngPtr, sig_read);
+ png_read_info(_pngPtr, _infoPtr);
+ int interlaceType;
+ png_get_IHDR(_pngPtr, _infoPtr, (png_uint_32 *)&_width, (png_uint_32 *)&_height, &_bitDepth,
+ &_colorType, &interlaceType, int_p_NULL, int_p_NULL);
+
+ if (_colorType & PNG_COLOR_MASK_PALETTE)
+ _paletteSize = _infoPtr->num_palette;
+
+ return true;
+}
+
+/* Get the width and height of a png image */
+bool PngLoader::findImageDimensions() {
+ DEBUG_ENTER_FUNC();
+
+ if (!basicImageLoad())
+ return false;
+
+ png_destroy_read_struct(&_pngPtr, &_infoPtr, png_infopp_NULL);
+ return true;
+}
+
+//
+// Load a texture from a png image
+//
+bool PngLoader::loadImageIntoBuffer() {
+ DEBUG_ENTER_FUNC();
+
+ if (!basicImageLoad())
+ return false;
+
+ // Strip off 16 bit channels. Not really needed but whatever
+ png_set_strip_16(_pngPtr);
+
+ if (_paletteSize) {
+ // Copy the palette
+ png_colorp srcPal = _infoPtr->palette;
+ for (int i = 0; i < (int)_paletteSize; 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_filler(_pngPtr, 0xff, PNG_FILLER_AFTER); // Filler for alpha?
+ }
+
+ unsigned char *line = (unsigned char*) malloc(_infoPtr->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, _infoPtr->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;
+}
diff --git a/backends/platform/psp/png_loader.h b/backends/platform/psp/png_loader.h
new file mode 100644
index 0000000000..5f2064bf96
--- /dev/null
+++ b/backends/platform/psp/png_loader.h
@@ -0,0 +1,70 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * $URL$
+ * $Id$
+ *
+ */
+
+#ifndef PSP_PNG_IMAGE_H
+#define PSP_PNG_IMAGE_H
+
+#include <png.h>
+
+class PngLoader {
+private:
+ bool basicImageLoad(); // common operation
+ bool findImageDimensions(); // find dimensions of a given PNG file
+ bool loadImageIntoBuffer();
+
+ static void warningFn(png_structp png_ptr, png_const_charp warning_msg);
+ static void libReadFunc(png_structp pngPtr, png_bytep data, png_size_t length);
+
+ Common::SeekableReadStream *_file;
+ Buffer *_buffer;
+ Palette *_palette;
+
+ uint32 _width;
+ uint32 _height;
+ uint32 _paletteSize;
+ int _bitDepth;
+ Buffer::HowToSize _sizeBy;
+ png_structp _pngPtr;
+ png_infop _infoPtr;
+ int _colorType;
+
+public:
+ enum Status {
+ OK,
+ OUT_OF_MEMORY,
+ BAD_FILE
+ };
+
+ PngLoader(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette,
+ Buffer::HowToSize sizeBy = Buffer::kSizeByTextureSize) :
+ _file(file), _buffer(&buffer), _palette(&palette),
+ _width(0), _height(0), _paletteSize(0),
+ _bitDepth(0), _sizeBy(sizeBy), _pngPtr(0), _infoPtr(0), _colorType(0) {}
+
+ PngLoader::Status allocate();
+ bool load();
+};
+
+#endif /* PSP_PNG_IMAGE_H */
diff --git a/backends/platform/psp/pspkeyboard.cpp b/backends/platform/psp/pspkeyboard.cpp
index b83b1c873a..be084d4d38 100644
--- a/backends/platform/psp/pspkeyboard.cpp
+++ b/backends/platform/psp/pspkeyboard.cpp
@@ -32,10 +32,10 @@
#include <malloc.h>
#include <pspkernel.h>
-#include <png.h>
#include "backends/platform/psp/psppixelformat.h"
#include "backends/platform/psp/pspkeyboard.h"
+#include "backends/platform/psp/png_loader.h"
#include "backends/platform/psp/input.h"
#include "common/keyboard.h"
#include "common/fs.h"
@@ -92,16 +92,6 @@ short PSPKeyboard::_modeChar[MODE_COUNT][5][6] = {
}
};
-// Read function for png library to be able to read from our SeekableReadStream
-//
-void pngReadStreamRead(png_structp png_ptr, png_bytep data, png_size_t length) {
- Common::SeekableReadStream *file;
-
- file = (Common::SeekableReadStream *)png_ptr->io_ptr;
-
- file->read(data, length);
-}
-
// Array with file names
const char *PSPKeyboard::_guiStrings[] = {
"keys4.png", "keys_s4.png",
@@ -282,8 +272,6 @@ bool PSPKeyboard::load() {
// Loop through all png images
for (i = 0; i < guiStringsSize; i++) {
- uint32 height = 0, width = 0, paletteSize = 0;
-
PSP_DEBUG_PRINT("Opening %s.\n", _guiStrings[i]);
// Look for the file in the kbd directory
@@ -310,49 +298,18 @@ bool PSPKeyboard::load() {
goto ERROR;
}
- if (getPngImageSize(file, &width, &height, &paletteSize) == 0) { // Check image size and palette size
- // Allocate memory for image
- PSP_DEBUG_PRINT("width[%d], height[%d], paletteSize[%d]\n", width, height, paletteSize);
- _buffers[i].setSize(width, height, Buffer::kSizeByTextureSize);
-
- if (paletteSize) { // 8 or 4-bit image
- if (paletteSize <= 16) { // 4 bit
- _buffers[i].setPixelFormat(PSPPixelFormat::Type_Palette_4bit);
- _palettes[i].setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_4bit);
- paletteSize = 16;
- } else if (paletteSize <= 256) { // 8-bit image
- paletteSize = 256;
- _buffers[i].setPixelFormat(PSPPixelFormat::Type_Palette_8bit);
- _palettes[i].setPixelFormats(PSPPixelFormat::Type_4444, PSPPixelFormat::Type_Palette_8bit);
- } else {
- PSP_ERROR("palette of %d too big!\n", paletteSize);
- goto ERROR;
- }
-
- } else { // 32-bit image
- _buffers[i].setPixelFormat(PSPPixelFormat::Type_8888);
- }
-
- _buffers[i].allocate();
- _palettes[i].allocate();
-
- // Try to load the image
- file->seek(0); // Go back to start
-
- if (loadPngImage(file, _buffers[i], _palettes[i]) != 0)
- goto ERROR;
- else { // Success
- PSP_DEBUG_PRINT("Managed to load the image\n");
-
- if (paletteSize == 16) // 4-bit
- _buffers[i].flipNibbles();
-
- delete file;
- }
- } else {
- PSP_ERROR("couldn't obtain PNG image size\n");
+ 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;
@@ -377,124 +334,6 @@ ERROR:
return false;
}
-static void user_warning_fn(png_structp png_ptr, png_const_charp warning_msg) {
- // ignore PNG warnings
-}
-
-/* Get the width and height of a png image */
-int PSPKeyboard::getPngImageSize(Common::SeekableReadStream *file, uint32 *png_width, uint32 *png_height, u32 *paletteSize) {
- DEBUG_ENTER_FUNC();
-
- png_structp png_ptr;
- png_infop info_ptr;
- unsigned int sig_read = 0;
- png_uint_32 width, height;
- int bit_depth, color_type, interlace_type;
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (png_ptr == NULL) {
- return -1;
- }
- png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
- return -1;
- }
- // Set the png lib to use our read function
- png_set_read_fn(png_ptr, (void *)file, pngReadStreamRead);
-
- png_set_sig_bytes(png_ptr, sig_read);
- png_read_info(png_ptr, info_ptr);
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
- if (color_type & PNG_COLOR_MASK_PALETTE)
- *paletteSize = info_ptr->num_palette;
- else
- *paletteSize = 0;
-
- png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
-
- *png_width = width;
- *png_height = height;
-
- return 0;
-}
-
-// Load a texture from a png image
-//
-int PSPKeyboard::loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette) {
- DEBUG_ENTER_FUNC();
-
- png_structp png_ptr;
- png_infop info_ptr;
- unsigned int sig_read = 0;
- png_uint_32 width, height;
- int bit_depth, color_type, interlace_type;
- size_t y;
-
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (png_ptr == NULL) {
- PSP_ERROR("Couldn't create read struct to load keyboard\n");
- return -1;
- }
- // Use dummy error function
- png_set_error_fn(png_ptr, (png_voidp) NULL, (png_error_ptr) NULL, user_warning_fn);
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- PSP_ERROR("Couldn't create info struct to load keyboard\n");
- png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
- return -1;
- }
-
- // Set the png lib to use our customized read function
- png_set_read_fn(png_ptr, (void *)file, pngReadStreamRead);
-
- png_set_sig_bytes(png_ptr, sig_read);
- png_read_info(png_ptr, info_ptr);
- png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, int_p_NULL, int_p_NULL);
-
- // Strip off 16 bit channels. Not really needed but whatever
- png_set_strip_16(png_ptr);
-
- if (color_type == PNG_COLOR_TYPE_PALETTE) {
- // Copy the palette
- png_colorp srcPal = info_ptr->palette;
- for (int i = 0; i < info_ptr->num_palette; i++) {
- unsigned char alphaVal = (i < info_ptr->num_trans) ? info_ptr->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
- // Round up grayscale images
- if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);
- // Convert trans channel to alpha for 32 bits
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);
- // Filler for alpha?
- png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
- }
-
- unsigned char *line = (unsigned char*) malloc(info_ptr->rowbytes);
- if (!line) {
- png_destroy_read_struct(&png_ptr, png_infopp_NULL, png_infopp_NULL);
- PSP_ERROR("Couldn't allocate line\n");
- return -1;
- }
-
- for (y = 0; y < height; y++) {
- png_read_row(png_ptr, line, png_bytep_NULL);
- buffer.copyFromRect(line, info_ptr->rowbytes, 0, y, width, 1); // Copy into buffer
- //memcpy(buffer.getPixels()[y * buffer.getWidthInBytes()], line, info_ptr->rowbytes);
- }
-
- free(line);
-
- png_read_end(png_ptr, info_ptr);
- png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
-
- return 0;
-}
-
// Defines for working with PSP buttons
#define CHANGED(x) (_buttonsChanged & (x))
#define PRESSED(x) ((_buttonsChanged & (x)) && (pad.Buttons & (x)))
diff --git a/backends/platform/psp/pspkeyboard.h b/backends/platform/psp/pspkeyboard.h
index 1bd394c15a..ebf21cfd54 100644
--- a/backends/platform/psp/pspkeyboard.h
+++ b/backends/platform/psp/pspkeyboard.h
@@ -77,9 +77,6 @@ private:
Palette _palettes[guiStringsSize];
GuRenderer _renderer;
- int loadPngImage(Common::SeekableReadStream *file, Buffer &buffer, Palette &palette);
- int getPngImageSize(Common::SeekableReadStream *, uint32 *png_width, uint32 *png_height, uint32 *paletteSize);
- uint32 convert_pow2(uint32 size);
void increaseKeyboardLocationX(int amount); // Move keyboard onscreen
void increaseKeyboardLocationY(int amount);
void convertCursorToXY(CursorDirections cur, int &x, int &y);