summaryrefslogtreecommitdiff
path: root/apps/plugins/xrick/system/sysvid_rockbox.c
diff options
context:
space:
mode:
authorSebastian Leonhardt <sebastian.leonhardt@web.de>2016-01-08 01:05:36 +0100
committerFranklin Wei <frankhwei536@gmail.com>2016-06-13 22:49:35 -0400
commitb33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76 (patch)
tree1226f0ab0c06d71b7f5a336dcb317f456bd68551 /apps/plugins/xrick/system/sysvid_rockbox.c
parent9a6700d52e8dfb2e93623e7143204ae34f798bbf (diff)
downloadrockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.zip
rockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.tar.gz
rockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.tar.bz2
rockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.tar.xz
added xrick game
original xrick code by 'BigOrno' at: http://www.bigorno.net/xrick/ Rockbox port, plus bugfixes at: https://github.com/pierluigi-vicinanza/xrick Change-Id: Id83928bc2539901b0221692f65cbca41389c58e7
Diffstat (limited to 'apps/plugins/xrick/system/sysvid_rockbox.c')
-rw-r--r--apps/plugins/xrick/system/sysvid_rockbox.c395
1 files changed, 395 insertions, 0 deletions
diff --git a/apps/plugins/xrick/system/sysvid_rockbox.c b/apps/plugins/xrick/system/sysvid_rockbox.c
new file mode 100644
index 0000000..c7586aa
--- /dev/null
+++ b/apps/plugins/xrick/system/sysvid_rockbox.c
@@ -0,0 +1,395 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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 software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+
+#include "xrick/config.h"
+#include "xrick/draw.h"
+#include "xrick/game.h"
+#include "xrick/data/img.h"
+#include "xrick/debug.h"
+
+#include "plugin.h"
+#include "lib/helper.h"
+
+/*
+ * Global variables
+ */
+U8 *sysvid_fb = NULL; /* xRick generic 320x200 8bpp frame buffer */
+
+/*
+ * Local variables
+ */
+static fb_data palette[256] IBSS_ATTR;
+static bool isVideoInitialised = false;
+#ifndef HAVE_LCD_COLOR
+# include "lib/grey.h"
+GREY_INFO_STRUCT_IRAM
+static unsigned char greybuffer[LCD_HEIGHT * LCD_WIDTH] IBSS_ATTR; /* off screen buffer */
+static unsigned char *gbuf;
+# if LCD_PIXELFORMAT == HORIZONTAL_PACKING
+enum { GREYBUFSIZE = (((LCD_WIDTH+7)/8)*LCD_HEIGHT*16+200) };
+# else
+enum { GREYBUFSIZE = (LCD_WIDTH*((LCD_HEIGHT+7)/8)*16+200) };
+# endif
+#endif /* ndef HAVE_LCD_COLOR */
+
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+enum { ROW_RESIZE_STEP = (LCD_HEIGHT << 16) / SYSVID_HEIGHT };
+
+static bool rowsToSkip[SYSVID_HEIGHT];
+
+/*
+ *
+ */
+static void calculateRowsToSkip(void)
+{
+ U32 currentRow, prevResizedRow;
+
+ prevResizedRow = 0;
+ rowsToSkip[0] = false;
+
+ for (currentRow = 1; currentRow < SYSVID_HEIGHT; ++currentRow)
+ {
+ U32 resizedRow = (currentRow * ROW_RESIZE_STEP) >> 16;
+ if (resizedRow == prevResizedRow)
+ {
+ rowsToSkip[currentRow] = true;
+ }
+ prevResizedRow = resizedRow;
+ }
+}
+#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
+
+#if (LCD_WIDTH < SYSVID_WIDTH)
+enum { COLUMN_RESIZE_STEP = (LCD_WIDTH << 16) / (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)) };
+
+static bool columnsToSkip[SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)];
+
+/*
+ *
+ */
+static void calculateColumnsToSkip(void)
+{
+ U32 currentColumn, prevResizedColumn;
+
+ prevResizedColumn = 0;
+ columnsToSkip[0] = false;
+
+ for (currentColumn = 1; currentColumn < (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)); ++currentColumn)
+ {
+ U32 resizedColumn = (currentColumn * COLUMN_RESIZE_STEP) >> 16;
+ if (resizedColumn == prevResizedColumn)
+ {
+ columnsToSkip[currentColumn] = true;
+ }
+ prevResizedColumn = resizedColumn;
+ }
+}
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+/*
+ *
+ */
+void sysvid_setPalette(img_color_t *pal, U16 n)
+{
+ U16 i;
+
+ for (i = 0; i < n; i++)
+ {
+#ifdef HAVE_LCD_COLOR
+ palette[i] = LCD_RGBPACK(pal[i].r, pal[i].g, pal[i].b);
+#else
+ palette[i] = ((3 * pal[i].r) + (6 * pal[i].g) + pal[i].b) / 10;
+#endif
+ }
+}
+
+/*
+ *
+ */
+void sysvid_setGamePalette()
+{
+ sysvid_setPalette(game_colors, game_color_count);
+}
+
+/*
+ * Update screen
+ */
+void sysvid_update(const rect_t *rects)
+{
+ unsigned sourceRow, sourceLastRow;
+ unsigned sourceColumn, sourceLastColumn;
+ unsigned resizedRow, resizedColumn;
+ unsigned resizedWidth, resizedHeight;
+ unsigned x, y;
+ U8 *sourceBuf, *sourceTemp;
+ fb_data *destBuf, *destTemp;
+
+ if (!rects)
+ {
+ return;
+ }
+
+ while (rects)
+ {
+ sourceRow = rects->y;
+ sourceLastRow = sourceRow + rects->height;
+ sourceColumn = rects->x;
+ sourceLastColumn = sourceColumn + rects->width;
+
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ /* skip black borders */
+ if (sourceColumn < -DRAW_XYMAP_SCRLEFT)
+ {
+ sourceColumn = -DRAW_XYMAP_SCRLEFT;
+ }
+ if (sourceLastColumn > (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT))
+ {
+ sourceLastColumn = SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT;
+ }
+
+ /* skip unwanted columns */
+ while (columnsToSkip[sourceColumn + DRAW_XYMAP_SCRLEFT] /* && sourceColumn < (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT) */)
+ {
+ ++sourceColumn;
+ }
+
+ resizedColumn = ((sourceColumn + DRAW_XYMAP_SCRLEFT) * COLUMN_RESIZE_STEP) >> 16;
+ resizedWidth = 0;
+#else
+ resizedColumn = sourceColumn;
+ resizedWidth = rects->width;
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+ /* skip unwanted rows */
+ while (rowsToSkip[sourceRow] /* && sourceRow < SYSVID_HEIGHT */)
+ {
+ ++sourceRow;
+ }
+
+ resizedRow = (sourceRow * ROW_RESIZE_STEP) >> 16;
+ resizedHeight = 0;
+#else
+ resizedRow = sourceRow;
+ resizedHeight = rects->height;
+#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
+
+ sourceBuf = sysvid_fb;
+ sourceBuf += sourceColumn + sourceRow * SYSVID_WIDTH;
+
+#ifdef HAVE_LCD_COLOR
+ destBuf = rb->lcd_framebuffer;
+#else
+ destBuf = greybuffer;
+#endif /* HAVE_LCD_COLOR */
+ destBuf += resizedColumn + resizedRow * LCD_WIDTH;
+
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ sourceColumn += DRAW_XYMAP_SCRLEFT;
+ sourceLastColumn += DRAW_XYMAP_SCRLEFT;
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+ for (y = sourceRow; y < sourceLastRow; ++y)
+ {
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+ if (rowsToSkip[y])
+ {
+ sourceBuf += SYSVID_WIDTH;
+ continue;
+ }
+
+ ++resizedHeight;
+#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
+
+ sourceTemp = sourceBuf;
+ destTemp = destBuf;
+ for (x = sourceColumn; x < sourceLastColumn; ++x)
+ {
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ if (columnsToSkip[x])
+ {
+ ++sourceTemp;
+ continue;
+ }
+
+ if (y == sourceRow)
+ {
+ ++resizedWidth;
+ }
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+ *destTemp = palette[*sourceTemp];
+
+ ++sourceTemp;
+ ++destTemp;
+ }
+
+ sourceBuf += SYSVID_WIDTH;
+ destBuf += LCD_WIDTH;
+ }
+
+#ifdef HAVE_LCD_COLOR
+ IFDEBUG_VIDEO2(
+ for (y = resizedRow; y < resizedRow + resizedHeight; ++y)
+ {
+ destBuf = rb->lcd_framebuffer + resizedColumn + y * LCD_WIDTH;
+ *destBuf = palette[0x01];
+ *(destBuf + resizedWidth - 1) = palette[0x01];
+ }
+
+ for (x = resizedColumn; x < resizedColumn + resizedWidth; ++x)
+ {
+ destBuf = rb->lcd_framebuffer + x + resizedRow * LCD_WIDTH;
+ *destBuf = palette[0x01];
+ *(destBuf + (resizedHeight - 1) * LCD_WIDTH) = palette[0x01];
+ }
+ );
+
+ rb->lcd_update_rect(resizedColumn, resizedRow, resizedWidth, resizedHeight);
+#else
+ grey_ub_gray_bitmap_part(greybuffer, resizedColumn, resizedRow, LCD_WIDTH, resizedColumn, resizedRow, resizedWidth, resizedHeight);
+#endif /* HAVE_LCD_COLOR */
+
+ rects = rects->next;
+ }
+}
+
+/*
+ * Clear screen
+ * (077C)
+ */
+void sysvid_clear(void)
+{
+ rb->memset(sysvid_fb, 0, sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT);
+}
+
+/*
+ * Initialise video
+ */
+bool sysvid_init()
+{
+ bool success;
+
+ if (isVideoInitialised)
+ {
+ return true;
+ }
+
+ IFDEBUG_VIDEO(sys_printf("xrick/video: start\n"););
+
+ success = false;
+ do
+ {
+ /* allocate xRick generic frame buffer into memory */
+ sysvid_fb = sysmem_push(sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT);
+ if (!sysvid_fb)
+ {
+ sys_error("(video) unable to allocate frame buffer");
+ break;
+ }
+
+#ifndef HAVE_LCD_COLOR
+ gbuf = sysmem_push(GREYBUFSIZE);
+ if (!gbuf)
+ {
+ sys_error("(video) unable to allocate buffer for greyscale functions");
+ break;
+ }
+
+ if (!grey_init(gbuf, GREYBUFSIZE, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL))
+ {
+ sys_error("(video) not enough memory to initialise greyscale functions");
+ break;
+ }
+#endif /* ndef HAVE_LCD_COLOR */
+
+ success = true;
+ } while (false);
+
+ if (!success)
+ {
+#ifndef HAVE_LCD_COLOR
+ sysmem_pop(gbuf);
+#endif
+ sysmem_pop(sysvid_fb);
+ return false;
+ }
+
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+ calculateRowsToSkip();
+#endif
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ calculateColumnsToSkip();
+#endif
+
+#if LCD_DEPTH > 1
+ rb->lcd_set_backdrop(NULL);
+#endif
+ /* Turn off backlight timeout */
+ backlight_ignore_timeout();
+
+ rb->lcd_set_foreground(LCD_WHITE);
+ rb->lcd_set_background(LCD_BLACK);
+ rb->lcd_clear_display();
+
+#ifdef HAVE_LCD_COLOR
+ rb->lcd_update();
+#else
+ /* switch on greyscale overlay */
+ grey_show(true);
+#endif /* HAVE_LCD_COLOR */
+
+ isVideoInitialised = true;
+ IFDEBUG_VIDEO(sys_printf("xrick/video: ready\n"););
+ return true;
+}
+
+/*
+ * Shutdown video
+ */
+void sysvid_shutdown(void)
+{
+ if (!isVideoInitialised)
+ {
+ return;
+ }
+
+#ifndef HAVE_LCD_COLOR
+ grey_show(false);
+ grey_release();
+
+ sysmem_pop(gbuf);
+#endif /* ndef HAVE_LCD_COLOR */
+ sysmem_pop(sysvid_fb);
+
+ /* Turn on backlight timeout (revert to settings) */
+ backlight_use_settings();
+
+ isVideoInitialised = false;
+ IFDEBUG_VIDEO(sys_printf("xrick/video: stop\n"););
+}
+
+/* eof */