[gnome-games] nintendo-ds: Add NintendoDsIcon
- From: Adrien Plazas <aplazas src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-games] nintendo-ds: Add NintendoDsIcon
- Date: Wed, 11 May 2016 23:01:39 +0000 (UTC)
commit 256dedf5ad2c3e967ea260bf2d0ba5e874398bdd
Author: Adrien Plazas <kekun plazas laposte net>
Date: Wed May 11 19:17:22 2016 +0200
nintendo-ds: Add NintendoDsIcon
This will be used in subsequent commits to represent Nintedo DS games
icons.
Fixes #291
plugins/nintendo-ds/src/Makefile.am | 2 +
plugins/nintendo-ds/src/nintendo-ds-icon-extract.c | 169 ++++++++++++++++++++
plugins/nintendo-ds/src/nintendo-ds-icon.vala | 30 ++++
3 files changed, 201 insertions(+), 0 deletions(-)
---
diff --git a/plugins/nintendo-ds/src/Makefile.am b/plugins/nintendo-ds/src/Makefile.am
index d058157..2401a36 100644
--- a/plugins/nintendo-ds/src/Makefile.am
+++ b/plugins/nintendo-ds/src/Makefile.am
@@ -6,6 +6,8 @@ libgames_nintendo_ds_plugin_la_DEPENDENCIES = \
$(NULL)
libgames_nintendo_ds_plugin_la_SOURCES = \
+ nintendo-ds-icon.vala \
+ nintendo-ds-icon-extract.c \
nintendo-ds-plugin.vala \
$(NULL)
diff --git a/plugins/nintendo-ds/src/nintendo-ds-icon-extract.c
b/plugins/nintendo-ds/src/nintendo-ds-icon-extract.c
new file mode 100644
index 0000000..833f8f9
--- /dev/null
+++ b/plugins/nintendo-ds/src/nintendo-ds-icon-extract.c
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2007, 2013 Bastien Nocera <hadess hadess net>
+ *
+ * Authors: Bastien Nocera <hadess hadess net>
+ * Thomas Köckerbauer <tkoecker gmx net>
+ * Adrien Plazas <kekun plazas laposte net>
+ *
+ * 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
+ *
+ */
+
+#include <string.h>
+#include <glib.h>
+#include <gio/gio.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+/* From specs at http://www.bottledlight.com/ds/index.php/FileFormats/NDSFormat
+ * and code at http://www.kde-apps.org/content/show.php?content=39247 */
+
+#define BOUND_ERROR(x) {
\
+ if (error != NULL)
\
+ return NULL;
\
+ else
\
+ g_set_error (error, 0, 0, "Couldn't access file data at 0x%x, probably not a NDS ROM", x);
\
+ if (stream != NULL)
\
+ g_object_unref (stream);
\
+ return NULL;
\
+}
+
+#define LOGO_OFFSET_OFFSET 0x068
+#define BANNER_LENGTH 2112
+#define TILE_DATA_OFFSET 32
+#define TILE_DATA_LENGTH 512
+#define PALETTE_DATA_OFFSET TILE_DATA_OFFSET + 512
+#define PALETTE_DATA_LENGTH 32
+
+struct palette_i {
+ guint8 r;
+ guint8 g;
+ guint8 b;
+ guint8 a;
+};
+
+static void
+put_pixel (guchar *pixels, int rowstride, int x, int y, struct palette_i item)
+{
+ int n_channels;
+ guchar *p;
+
+ n_channels = 4;
+
+ p = pixels + y * rowstride + x * n_channels;
+ p[0] = item.r;
+ p[1] = item.g;
+ p[2] = item.b;
+ p[3] = item.a;
+}
+
+static GdkPixbuf *
+load_icon (gchar *tile_data, guint16 *palette_data)
+{
+ struct palette_i palette[16];
+ int pos, j, i, y, x;
+
+ GdkPixbuf *pixbuf;
+ guchar *pixels;
+ int rowstride;
+
+ /* Parse the palette */
+ for (i = 0; i < 16; i++) {
+ palette[i].r = (palette_data[i] & 0x001F) << 3;
+ palette[i].g = (palette_data[i] & 0x03E0) >> 2;
+ palette[i].b = (palette_data[i] & 0x7C00) >> 7;
+ palette[i].a = (i == 0) ? 0x00 : 0xFF;
+ }
+
+ /* Create the pixbuf */
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 32, 32);
+ rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+ /* Put the grid of icon data into the pixbuf */
+ pos = 0;
+ for (j = 0; j < 4; j++) {
+ for (i = 0; i < 4; i++) {
+ for (y = 0; y < 8; y++) {
+ for (x = 0; x < 4; x++) {
+ put_pixel (pixels, rowstride, x * 2 + 8 * i, y + 8 * j,
palette[tile_data[pos] & 0x0F]);
+ put_pixel (pixels, rowstride, x * 2 + 1 + 8 * i, y + 8 * j,
palette[(tile_data[pos] & 0xF0)>>4]);
+ pos++;
+ }
+ }
+ }
+ }
+
+ return pixbuf;
+}
+
+GdkPixbuf *
+games_nintendo_ds_icon_extract (const char *uri,
+ GError **error)
+{
+ GFile *input;
+ GFileInputStream *stream;
+ GdkPixbuf *pixbuf;
+
+ guint32 offset;
+ gchar *tile_data;
+ guint16 *palette_data;
+
+ guint32 logo_offset[4];
+ char *banner_data;
+
+ /* Open the file for reading */
+ input = g_file_new_for_uri (uri);
+ stream = g_file_read (input, NULL, error);
+ g_object_unref (input);
+
+ if (stream == NULL)
+ return NULL;
+
+ /* Get the address of the logo */
+ if (g_input_stream_skip (G_INPUT_STREAM (stream), LOGO_OFFSET_OFFSET, NULL, error) == FALSE)
+ BOUND_ERROR(LOGO_OFFSET_OFFSET);
+ if (g_input_stream_read (G_INPUT_STREAM (stream), &logo_offset, sizeof(guint32), NULL, error) ==
FALSE)
+ BOUND_ERROR(LOGO_OFFSET_OFFSET);
+ offset = GUINT32_FROM_LE(*logo_offset) - g_seekable_tell (G_SEEKABLE (stream));
+
+ /* Get the icon data */
+ if (g_input_stream_skip (G_INPUT_STREAM (stream), offset, NULL, error) != offset)
+ BOUND_ERROR(offset);
+ banner_data = g_malloc0(BANNER_LENGTH);
+ if (g_input_stream_read (G_INPUT_STREAM (stream), banner_data, BANNER_LENGTH, NULL, error) !=
BANNER_LENGTH)
+ BOUND_ERROR(LOGO_OFFSET_OFFSET);
+
+ g_input_stream_close (G_INPUT_STREAM (stream), NULL, NULL);
+ g_object_unref (stream);
+
+ /* Check the version is version 1, 3 or 19 (NDSi) */
+ if ((banner_data[0] != 0x1 || banner_data[1] != 0x0) &&
+ (banner_data[0] != 0x3 || banner_data[1] != 0x0) &&
+ (banner_data[0] != 0x3 || banner_data[1] != 0x1)) {
+ g_free (banner_data);
+ g_set_error (error, 0, 0, "Unsupported icon version, probably not an NDS file");
+ return NULL;
+ }
+
+ /* Get the tile and palette data for the logo */
+ tile_data = g_memdup (banner_data + TILE_DATA_OFFSET, TILE_DATA_LENGTH);
+ palette_data = g_memdup (banner_data + PALETTE_DATA_OFFSET, PALETTE_DATA_LENGTH);
+ g_free (banner_data);
+ pixbuf = load_icon (tile_data, palette_data);
+ g_free (palette_data);
+ g_free (tile_data);
+
+ return pixbuf;
+}
diff --git a/plugins/nintendo-ds/src/nintendo-ds-icon.vala b/plugins/nintendo-ds/src/nintendo-ds-icon.vala
new file mode 100644
index 0000000..630daa8
--- /dev/null
+++ b/plugins/nintendo-ds/src/nintendo-ds-icon.vala
@@ -0,0 +1,30 @@
+// This file is part of GNOME Games. License: GPLv3
+
+public class Games.NintendoDsIcon : Object, Icon {
+ private string uri;
+ private bool extracted;
+ private Gdk.Pixbuf pixbuf;
+
+ public NintendoDsIcon (string uri) {
+ this.uri = uri;
+ extracted = false;
+ }
+
+ private static extern Gdk.Pixbuf extract (string uri) throws Error;
+
+ public GLib.Icon? get_icon () {
+ if (extracted)
+ return pixbuf;
+
+ extracted = true;
+
+ try {
+ pixbuf = extract (uri);
+ }
+ catch (Error e) {
+ warning (e.message);
+ }
+
+ return pixbuf;
+ }
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]