Browse Source

Working on plugin to make them work again!

Godzil 4 years ago
parent
commit
2ec7a9c21e

+ 17 - 1
src/include/os_dependent.h

@@ -11,13 +11,18 @@
 #define OS_DEPENDENT_H
 
 #include <stdint.h>
+#include "text.h"
 
 /* File related functions */
 /* Graphics related functions */
 int graphics_init();
 int graphics_drawpixel(long x, long y, long color);
 int graphics_blit(long x, long y, long w, long h);
-int graphics_drawline(long x, long y, long x1, long y1, long color);
+int graphics_drawline(uint32_t x, uint32_t y, uint32_t x1, uint32_t y1, uint32_t colour);
+int graphics_drawRect(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint32_t colour);
+int graphics_drawFillrect(int x0, int y0, int w, int h, uint32_t colour);
+int graphics_getScreenSize(int *w, int *h);
+
 void vsync(void);
 
 typedef struct Palette_t
@@ -47,4 +52,15 @@ int console_init(ConsoleLevel DefaultLevel);
 int console_printf(const ConsoleLevel level, const char *format, ...);
 int console_printf_d(const char *format, ...);
 
+
+#define KEY_ENTER (257)
+#define KEY_LEFT (263)
+#define KEY_RIGHT (262)
+#define KEY_UP (265)
+#define KEY_DOWN (264)
+//#define KEY_ENTER 13
+
+
+
+
 #endif /* OS_DEPENDENT_H */

+ 1 - 1
src/include/plugins/manager.h

@@ -26,7 +26,7 @@ int plugin_remove_keypressHandler(uint8_t key, PluginKeypress);
 #else /* __TINES_PLUGINS__ */
 
 /* Available functions outside of plugins */
-int plugin_keypress(uint8_t key);
+int plugin_keypress();
 
 /* Real Prototype: TBD */
 void plugin_list();

+ 58 - 0
src/include/text.h

@@ -0,0 +1,58 @@
+/*
+ *  FbLib graphic library
+ *
+ *  Created by Manoël TRAPIER.
+ *  Copyright (c) 2003-2019 986-Studio. All rights reserved.
+ *
+ */
+
+#ifndef _FBLIB_INCLUDE_TEXT_H
+#define _FBLIB_INCLUDE_TEXT_H
+
+typedef struct FBLibFont
+{
+   char      *name;       /* Font name. */
+   int        height;     /* Height in pixels. */
+   int        index_mask; /* ((1 << N) - 1). */
+   int       *offset;     /* (1 << N) offsets into index. */
+   int       *index;
+   uint32_t  *content;
+   //void      *private;
+} FBLibFont;
+
+/* ? */
+FBLibFont *load_psf(char *filename);
+
+void graphics_text_line(int x, int y, int w, int charw, uint32_t color, int valign, void *font, char *text);
+
+int graphics_text_ex(int x, int y, int w, int h,
+                     void *font,
+                     uint32_t bgcolor, uint32_t fgcolor,
+                     char valign, char halign,
+                     uint16_t options,
+                     void *format, ...);
+
+void graphics_get_text_size(int *width, int *height,
+                            const FBLibFont  *font,
+                            const char *text);
+
+void graphics_draw_text (int x, int y,
+                         uint32_t colour,
+                         const FBLibFont *font,
+                         const char *text);
+
+#define TEXT_VALIGN_LEFT   (1)
+#define TEXT_VALIGN_RIGHT  (2)
+#define TEXT_VALIGN_CENTER (3)
+
+#define TEXT_HALIGN_TOP    (1)
+#define TEXT_HALIGN_CENTER (2)
+#define TEXT_HALIGN_BOTTOM (3)
+
+#define TEXT_OPT_WORDWRAP  (1<<0)
+
+#define TEXT_DEFAULTFONT   ((void*)(1))
+#define TEXT_SMALLFONT     ((void*)(2))
+#define TEXT_LARGEFONT     ((void*)(3))
+
+#endif /* _FBLIB_INCLUDE_TEXT_H */

+ 3 - 3
src/main.c

@@ -740,12 +740,12 @@ int main(int argc, char *argv[])
         ppu_setMirroring((Cart->Flags & iNES_MIRROR) ? PPU_MIRROR_VERTICAL : PPU_MIRROR_HORIZTAL);
     }
 
-    console_printf(Console_Default, "Init mapper...\t\t\t");
+    //console_printf(Console_Default, "Init mapper...\n");
     if (mapper_init(Cart) == -1)
     {
         return -1;
     }
-    console_printf(Console_Default, "[ OK ]\n");
+    //console_printf(Console_Default, "[ OK ]\n");
 
 //  set_palette(basicPalette);
 
@@ -933,7 +933,7 @@ void Loop6502(quick6502_cpu *R)
         quick6502_reset(R);
     }
 
-//      plugin_keypress(skey);
+    plugin_keypress();
 
     if (cpuSignal != 0)
     {

+ 2 - 2
src/os/unix/CMakeLists.txt

@@ -6,9 +6,9 @@
 #
 if (COVERALLS)
     set(COVERAGE_SRCS src/os/unix/loadfile.c src/os/unix/graphics_dummy.c src/os/unix/sound.c src/os/unix/io.c ${COVERAGE_SRCS} PARENT_SCOPE)
-    add_library(oslib loadfile.c graphics_dummy.c sound.c io.c)
+    add_library(oslib loadfile.c graphics_dummy.c sound.c io.c text.c)
 else()
-    add_library(oslib loadfile.c graphics.c sound.c io.c)
+    add_library(oslib loadfile.c graphics.c sound.c io.c text.c)
 endif()
 
 target_link_libraries(oslib glfw ${OPENGL_glu_LIBRARY} ${OPENGL_gl_LIBRARY})

BIN
src/os/unix/default_font.psf


+ 58 - 13
src/os/unix/graphics.c

@@ -158,8 +158,8 @@ void kbHandler(GLFWwindow *window, int key, int scan, int action, int mod)
     }
     keyArray[key].debounced |= (keyArray[key].lastState == GLFW_RELEASE) && (keyArray[key].curState == GLFW_PRESS);
     keyArray[key].window = window;
-    printf("key:%d, state:%d debounce:%d, laststate:%d\n", key, keyArray[key].curState,
-           keyArray[key].debounced, keyArray[key].lastState);
+    /*printf("key:%d, state:%d debounce:%d, laststate:%d\n", key, keyArray[key].curState,
+           keyArray[key].debounced, keyArray[key].lastState);*/
 }
 
 void sizeHandler(GLFWwindow *window, int xs, int ys)
@@ -206,13 +206,13 @@ void initDisplay(GLWindow *g)
     glfwSetWindowSizeCallback(g->windows, sizeHandler);
 }
 
-void drawPixel(GLWindow *gw, int x, int y, uint32_t colour)
+static void drawPixel(GLWindow *gw, uint32_t x, uint32_t y, uint32_t colour)
 {
     uint8_t r, g, b, a;
 
     uint32_t offset = (y * gw->WIDTH * 4U) + 4U * x;
 
-    if ((x < 0) || (x > gw->WIDTH) || (y < 0) || (y > gw->HEIGHT))
+    if ((x > (uint32_t)gw->WIDTH) || (y > (uint32_t)gw->HEIGHT))
     {
         return;
     }
@@ -228,9 +228,13 @@ void drawPixel(GLWindow *gw, int x, int y, uint32_t colour)
     gw->videoMemory[offset + 3] = b;
 }
 
-void drawLine(GLWindow *g, int x0, int y0, int x1, int y1, uint32_t colour)
+static void drawLine(GLWindow *g, uint32_t x0, uint32_t y0, uint32_t x1, uint32_t y1, uint32_t colour)
 {
-    int d, dx, dy, aincr, bincr, xincr, yincr, x, y;
+    printf("%s:%s(%p, %d, %d, %d, %d, %d) @ %d\n", __FILE__, __func__,
+            g, x0, y0, x1, y1, colour,
+            __LINE__);
+    int32_t d, dx, dy, aincr, bincr, xincr, yincr;
+    uint32_t x, y;
     if (abs(x1 - x0) < abs(y1 - y0))
     {
         /* parcours par l'axe vertical */
@@ -306,7 +310,7 @@ exit:
     return;
 }
 
-void drawCircle(GLWindow *g, int xc, int yc, int radius, uint32_t colour)
+static void drawCircle(GLWindow *g, int xc, int yc, int radius, uint32_t colour)
 {
     int f = 1 - radius;
     int ddF_x = 0;
@@ -364,17 +368,24 @@ void drawCircle(GLWindow *g, int xc, int yc, int radius, uint32_t colour)
     }
 }
 
-void drawRect(GLWindow *g, int x0, int y0, int w, int h, uint32_t colour)
+static void drawRect(GLWindow *g, uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint32_t colour)
 {
+    printf("%s:%s(%p, %d, %d, %d, %d, %d) @ %d\n", __FILE__, __func__,
+           g, x0, y0, w, h, colour,
+           __LINE__);
     drawLine(g, x0, y0, x0 + w, y0, colour);
     drawLine(g, x0 + w, y0, x0 + w, y0 + h, colour);
     drawLine(g, x0 + w, y0 + h, x0, y0 + h, colour);
     drawLine(g, x0, y0 + h, x0, y0, colour);
 }
 
-void drawFillrect(GLWindow *g, int x0, int y0, int w, int h, uint32_t colour)
+static void drawFillrect(GLWindow *g, uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint32_t colour)
 {
-    int i;
+    printf("%s:%s(%p, %d, %d, %d, %d, %d) @ %d\n", __FILE__, __func__,
+           g, x0, y0, w, h, colour,
+           __LINE__);
+    uint32_t i;
+
     for (i = 0 ; i < h ; i++)
     {
         drawLine(g, x0, y0 + i, x0 + w, y0 + i, colour);
@@ -388,7 +399,7 @@ void clearScreen(GLWindow *g)
 
 void updateScreen(GLWindow *g)
 {
-    /*Update windows code */
+    /* Update windows code */
     glfwMakeContextCurrent(g->windows);
     ShowScreen(g, g->WIDTH, g->HEIGHT);
     glfwSwapBuffers(g->windows);
@@ -431,15 +442,49 @@ static uint32_t getColour(long color)
     return (b << 24) | (g << 16) | (r << 8) | a;
 }
 
+int graphics_getScreenSize(int *w, int *h)
+{
+    *w = mainWindow.WIDTH;
+    *h = mainWindow.HEIGHT;
+    return 0;
+}
+
+int graphics_drawRect(uint32_t x0, uint32_t y0, uint32_t w, uint32_t h, uint32_t colour)
+{
+    printf("%s:%s(%d, %d, %d, %d, %d) @ %d\n", __FILE__, __func__,
+           x0, y0, w, h, colour,
+           __LINE__);
+    drawRect(&mainWindow, x0, y0, w, h, colour);
+    return 0;
+}
+
+int graphics_drawFillrect(int x0, int y0, int w, int h, uint32_t colour)
+{
+    printf("%s:%s(%d, %d, %d, %d, %d) @ %d\n", __FILE__, __func__,
+           x0, y0, w, h, colour,
+           __LINE__);
+    drawFillrect(&mainWindow, x0, y0, w, h, colour);
+    return 0;
+}
+
 int graphics_drawpixel(long x, long y, long color)
 {
     drawPixel(&mainWindow, x, y, getColour(color));
     return 0;
 }
 
-int graphics_drawline(long x, long y, long x1, long y1, long color)
+int graphics_drawCircle(int xc, int yc, int radius, uint32_t colour)
+{
+    drawCircle(&mainWindow, xc, yc, radius, colour);
+    return 0;
+}
+
+int graphics_drawline(uint32_t x, uint32_t y, uint32_t x1, uint32_t y1, uint32_t colour)
 {
-    drawLine(&mainWindow, x, y, x1, y1, getColour(color));
+    printf("%s:%s(%d, %d, %d, %d, %d) @ %d\n", __FILE__, __func__,
+           x, y, x1, y1, colour,
+           __LINE__);
+    drawLine(&mainWindow, x, y, x1, y1, getColour(colour));
     return 0;
 }
 

+ 512 - 0
src/os/unix/text.c

@@ -0,0 +1,512 @@
+/*
+ *  FbLib graphic library
+ *
+ *  Created by Manoël TRAPIER.
+ *  Copyright (c) 2003-2019 986-Studio. All rights reserved.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <stdarg.h>
+
+#include <os_dependent.h>
+
+#define DEFAULT_FONT "default_font.psf"
+FBLibFont *defaultFont = NULL;
+
+/* Function will fail, if no string terminator */
+static int getNextWordLen(char *str)
+{
+    int ret = 0, i;
+    /* Word delimiters */
+    char word_lim[] = { ' ', '\t', '\n', 0 };
+
+    while (1)
+    {
+        for (i = 0 ; word_lim[i] != 0 ; i++)
+        {
+            if (*str == word_lim[i])
+            {
+                return ret;
+            }
+        }
+        str++;
+        ret++;
+    }
+}
+
+void graphics_text_line(int x, int y, int w, int charw, uint32_t color, int valign, void *font, char *text)
+{
+    uint32_t len = strlen(text);
+
+    switch (valign)
+    {
+    default:
+    case TEXT_VALIGN_LEFT:
+        graphics_draw_text(x, y, color, (const FBLibFont *)font, text);
+        break;
+    case TEXT_VALIGN_CENTER:
+        graphics_draw_text(x + ((w - len * charw) / 2), y, color, (const FBLibFont *)font, text);
+        break;
+    case TEXT_VALIGN_RIGHT:
+        graphics_draw_text(x + (w - (len * charw)), y, color, (const FBLibFont *)font, text);
+        break;
+    }
+}
+
+/* Currently halign is not honored, but valign is */
+int graphics_text_ex(int x, int y, int w, int h,
+                     void *font,
+                     uint32_t bgcolor, uint32_t fgcolor,
+                     char valign, char halign,
+                     uint16_t options,
+                     void *format, ...)
+{
+    char string[1024];
+    char line[300];
+    int charWidth, charHeight;
+    int textPos = 0;
+    int wordLen = 0;
+    int nextWordLen = 0;
+
+    va_list va;
+    uint16_t curColPos = 0, curLinePos = 0;
+    uint16_t maxCharPerLine, maxTextLine;
+
+    FBLibFont *userFont = font;
+    if (defaultFont == NULL)
+    {
+        defaultFont = load_psf(DEFAULT_FONT);
+    }
+
+    if (font == NULL)
+    {
+        userFont = defaultFont;
+    }
+
+    /* Do some usefull calculation */
+    /* We use fixed size font */
+    graphics_get_text_size(&charWidth, &charHeight, userFont, "A");
+    maxCharPerLine = w / charWidth;
+    maxTextLine = h / charHeight;
+
+    /* Now convert to a useable string */
+    va_start(va, format);
+    vsnprintf(string, 1024, format, va);
+    va_end(va);
+
+    /* Fill rect with bg color */
+    graphics_drawFillrect(x, y, w, h, bgcolor);
+
+    /* Now fill as much as possible */
+    memset(line, 0, 300);
+    while (curLinePos < maxTextLine)
+    {
+        if (options & TEXT_OPT_WORDWRAP)
+        {
+            /* Do thoses check only one time per word, not per characters */
+            if (wordLen <= 0)
+            {
+                /* check if next word is too large for width */
+                nextWordLen = getNextWordLen(&string[textPos]);
+                //printf("\nNextword len = %d", nextWordLen);
+                if (nextWordLen <= maxCharPerLine)
+                {
+                    if ((curColPos + nextWordLen) > maxCharPerLine)
+                    {
+                        /* Go next line... */
+                        line[curColPos] = 0;
+                        graphics_text_line(x, y + curLinePos * charHeight, w, charWidth, fgcolor, valign, userFont,
+                                           line);
+                        curColPos = 0;
+                        curLinePos++;
+                        memset(line, 0, 300);
+                    }
+                }
+                wordLen = nextWordLen;
+            }
+            /* Now when the word is too long for a line, it will be automatically wrapped to the next line */
+        }
+
+        if ((string[textPos] == '\n') || (string[textPos] == '\r'))
+        {
+            textPos++;
+            line[curColPos] = 0;
+            graphics_text_line(x, y + curLinePos * charHeight, w, charWidth, fgcolor, valign, userFont, line);
+            curColPos = 0;
+            curLinePos++;
+            memset(line, 0, 300);
+        }
+        else if (string[textPos] == 0)
+        {
+            line[curColPos] = 0;
+            graphics_text_line(x, y + curLinePos * charHeight, w, charWidth, fgcolor, valign, userFont, line);
+            goto exit;
+        }
+        else if (curColPos >= maxCharPerLine)
+        {
+            /* display the line */
+            line[curColPos] = 0;
+            graphics_text_line(x, y + curLinePos * charHeight, w, charWidth, fgcolor, valign, userFont, line);
+            /* skip until a "\n" (and exit is "\0" found)) */
+            if (options & TEXT_OPT_WORDWRAP)
+            {
+                curColPos = 0;
+                curLinePos++;
+                memset(line, 0, 300);
+            }
+            else
+            {
+                while (1)
+                {
+                    if ((string[textPos] == '\r') || (string[textPos] == '\n'))
+                    {
+                        curColPos = 0;
+                        curLinePos++;
+                        memset(line, 0, 300);
+                        break;
+                    }
+                    else if (string[textPos] == 0)
+                    {
+                        goto exit;
+                    }
+
+                    textPos++;
+                }
+            }
+        }
+        else
+        {
+            line[curColPos++] = string[textPos++];
+        }
+
+        if (options & TEXT_OPT_WORDWRAP)
+        {
+            wordLen--;
+        }
+    }
+
+exit:
+    return 0;
+}
+
+void *fblib_loadfont(char *filename)
+{
+    return (void *)load_psf(filename);
+}
+
+
+/* PSF management */
+#define PSF1_MAGIC0     0x36
+#define PSF1_MAGIC1     0x04
+
+#define PSF1_MODE512    0x01
+#define PSF1_MODEHASTAB 0x02
+#define PSF1_MODEHASSEQ 0x04
+#define PSF1_MAXMODE    0x05
+
+#define PSF1_SEPARATOR  0xFFFF
+#define PSF1_STARTSEQ   0xFFFE
+
+struct psf1_header
+{
+    unsigned char magic[2];     /* Magic number */
+    unsigned char mode;         /* PSF font mode */
+    unsigned char charsize;     /* Character size */
+};
+
+#define PSF2_MAGIC0     0x72
+#define PSF2_MAGIC1     0xb5
+#define PSF2_MAGIC2     0x4a
+#define PSF2_MAGIC3     0x86
+
+/* bits used in flags */
+#define PSF2_HAS_UNICODE_TABLE 0x01
+
+/* max version recognized so far */
+#define PSF2_MAXVERSION 0
+
+/* UTF8 separators */
+#define PSF2_SEPARATOR  0xFF
+#define PSF2_STARTSEQ   0xFE
+
+struct psf2_header
+{
+    unsigned char magic[4];
+    unsigned int version;
+    unsigned int headersize;    /* offset of bitmaps in file */
+    unsigned int flags;
+    unsigned int length;        /* number of glyphs */
+    unsigned int charsize;      /* number of bytes for each character */
+    unsigned int height, width; /* max dimensions of glyphs */
+    /* charsize = height * ((width + 7) / 8) */
+};
+
+static FBLibFont *load_psf1(char *filename, FILE *fp)
+{
+    struct psf1_header head;
+    struct FBLibFont *font;
+    fread(&head, sizeof(head), 1, fp);
+
+    if ((head.magic[0] != PSF1_MAGIC0) || (head.magic[1] != PSF1_MAGIC1))
+    {
+        return NULL;
+    }
+
+    font = (FBLibFont *)malloc(sizeof(FBLibFont));
+
+    if (font != NULL)
+    {
+        font->height = head.charsize;
+        font->index_mask = 0xFF;
+
+
+    }
+
+    return NULL;
+}
+
+void printbin(uint32_t val, uint8_t bitlen)
+{
+    int i;
+    for (i = 0 ; i < bitlen ; i++)
+    {
+        if (val & (1 << (bitlen - 1)))
+        {
+            printf("*");
+        }
+        else
+        {
+            printf("_");
+        }
+        val <<= 1;
+    }
+}
+
+static FBLibFont *load_psf2(char *filename, FILE *fp)
+{
+    struct psf2_header head;
+    struct FBLibFont *font, *ret = NULL;
+    uint32_t charWidth;
+    uint32_t i, j, k;
+    uint8_t *bitmap;
+
+    fread(&head, sizeof(head), 1, fp);
+
+    if ((head.magic[0] != PSF2_MAGIC0) || (head.magic[1] != PSF2_MAGIC1) ||
+        (head.magic[2] != PSF2_MAGIC2) || (head.magic[3] != PSF2_MAGIC3)
+            )
+    {
+        goto exit;
+    }
+
+    font = (FBLibFont *)malloc(sizeof(FBLibFont));
+
+    assert(head.width <= 32); /* For now, do not support font with width larger than 32 pixels */
+
+    if (font != NULL)
+    {
+        font->height = head.height;
+
+        bitmap = (uint8_t *)malloc(sizeof(uint8_t) * head.charsize * head.length);
+        font->index_mask = 0xFF;
+        font->offset = (int *)malloc(sizeof(int) * head.length);
+        font->index = (int *)malloc(sizeof(int) * head.length * 3);
+        font->content = (uint32_t *)malloc(sizeof(uint32_t) * head.length * head.height);
+
+        charWidth = ((head.width + 7) / 8);
+
+        assert(bitmap != NULL);
+        assert(font->offset != NULL);
+        assert(font->index != NULL);
+        assert(font->content != NULL);
+
+        fread(bitmap, sizeof(uint8_t), head.charsize * head.length, fp);
+
+        for (i = 0 ; i < head.length ; i++)
+        {
+            font->offset[i] = i * 3;
+            font->index[(i * 3) + 0] = head.width;
+            font->index[(i * 3) + 1] = i * head.height;
+            font->index[(i * 3) + 2] = 0;
+
+            for (j = 0 ; j < head.height ; j++)
+            {
+                font->content[(i * head.height) + j] = 0;
+                for (k = 0 ; k < charWidth ; k++)
+                {
+                    font->content[(i * head.height) + j] |=
+                            (bitmap[(i * head.charsize) + (j * charWidth) + k]) << 8 * (3 - k);
+                }
+            }
+        }
+        ret = font;
+        free(bitmap);
+    }
+
+exit:
+    fclose(fp);
+    return ret;
+}
+
+FBLibFont *load_psf(char *filename)
+{
+    FILE *fp;
+    uint8_t byte;
+    console_printf(Console_Default, "Loading font '%s'\n", filename);
+    fp = fopen(filename, "rb");
+    if (fp != NULL)
+    {
+        byte = fgetc(fp);
+        rewind(fp);
+        switch (byte)
+        {
+        default:
+            fclose(fp);
+            return NULL; // Unsuported format
+        case PSF1_MAGIC0:
+            return load_psf1(filename, fp);
+        case PSF2_MAGIC0:
+            return load_psf2(filename, fp);
+        }
+    }
+
+    return NULL;
+}
+
+/* Font rendering code based on BOGL by Ben Pfaff */
+
+static int fblib_draw_glyph(const FBLibFont *font, uint8_t wc, uint32_t **bitmap)
+{
+    int mask = font->index_mask;
+    int i;
+
+    for (;;)
+    {
+        for (i = font->offset[wc & mask] ; font->index[i] ; i += 3)
+        {
+            if ((font->index[i] & ~mask) == (wc & ~mask))
+            {
+                if (bitmap != NULL)
+                {
+                    *bitmap = &font->content[font->index[i + 1]];
+                }
+                return font->index[i] & mask;
+            }
+        }
+    }
+    return 0;
+}
+
+void graphics_get_text_size(int *width, int *height,
+                            const FBLibFont *font,
+                            const char *text)
+{
+    uint8_t *c = (uint8_t *)text;
+    uint8_t wc;
+    int k, n, w, h, mw;
+
+    if (defaultFont == NULL)
+    {
+        defaultFont = load_psf(DEFAULT_FONT);
+    }
+
+    if (font == NULL)
+    {
+        font = defaultFont;
+    }
+
+    n = strlen(text);
+    mw = h = w = 0;
+
+    for (k = 0 ; k < n ; k++)
+    {
+        wc = *(c++);
+        if (wc == '\n')
+        {
+            if (w > mw)
+            {
+                mw = 0;
+            }
+
+            h += font->height;
+            continue;
+        }
+
+        w += fblib_draw_glyph(font, wc, NULL);
+    }
+
+    if (width != NULL)
+    {
+        *width = (w > mw) ? w : mw;
+    }
+    if (height != NULL)
+    {
+        *height = (h == 0) ? font->height : h;
+    }
+}
+
+void graphics_draw_text(int x, int y,
+                        uint32_t colour,
+                        const FBLibFont *font,
+                        const char *text)
+{
+    int32_t h, w, k, n, cx, cy, dx, dy;
+    uint8_t *c = (uint8_t *)text;
+    uint8_t wc;
+
+    if (defaultFont == NULL)
+    {
+        defaultFont = load_psf(DEFAULT_FONT);
+    }
+
+    if (font == NULL)
+    {
+        font = defaultFont;
+    }
+
+    n = strlen(text);
+    h = font->height;
+    dx = dy = 0;
+
+    for (k = 0 ; k < n ; k++)
+    {
+        uint32_t *glyph = NULL;
+        wc = *(c++);
+
+        if (wc == '\n')
+        {
+            dy += h;
+            dx = 0;
+            continue;
+        }
+
+        w = fblib_draw_glyph(font, wc, &glyph);
+
+        if (glyph == NULL)
+        {
+            continue;
+        }
+
+        for (cy = 0 ; cy < h ; cy++)
+        {
+            uint32_t g = *glyph++;
+
+            for (cx = 0 ; cx < w ; cx++)
+            {
+                if (g & 0x80000000)
+                {
+                    graphics_drawpixel(x + dx + cx, y + dy + cy, colour);
+                }
+                g <<= 1;
+            }
+        }
+
+        dx += w;
+    }
+}
+
+/* End of PSF */

+ 5 - 4
src/pluginsmanager/manager.c

@@ -55,11 +55,11 @@ int plugin_load(int id)
     Plugin *ptr = &(Plugins[0]);
     int i = id;
 
-    console_printf(Console_Default, "%s(%d)", __func__, id);
+    //console_printf(Console_Default, "%s(%d)", __func__, id);
 
     for (; i > 1 && ptr->name != NULL ; i--)
     {
-        console_printf(Console_Default, "%d - %s\n", i, ptr->name);
+        //console_printf(Console_Default, "%d - %s\n", i, ptr->name);
         ptr++;
     }
 
@@ -131,14 +131,15 @@ int plugin_remove_keypressHandler(uint8_t key, PluginKeypress func)
 
 
 /* Available functions outside of plugins */
-int plugin_keypress(uint8_t key)
+int plugin_keypress()
 {
     KeyHandler *ptr = keyHandlersList;
 
     while (ptr != NULL)
     {
-        if (ptr->key == key)
+        if (getKeyStatus(ptr->key))
         {
+            console_printf(Console_Default, "Keyrrr [%d].....\n", ptr->key);
             ptr->func();
         }
         ptr = ptr->next;

+ 105 - 88
src/pluginsmanager/plugins/gamegenie.c

@@ -9,6 +9,8 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
 
 #include <os_dependent.h>
 
@@ -17,12 +19,11 @@
 #include <plugins/manager.h>
 
 #undef  __TINES_PLUGINS_
+#include <os_dependent.h>
 
 #include <memory/manager.h>
 #include <types.h>
 
-#if 0
-
 typedef enum gg_States_
 {
     GG_S00_MAIN_STATE = 0,
@@ -51,7 +52,7 @@ uint8_t gg_PatchedValue[10];
 func_rdhook gg_rdhookPtr[10];
 
 #define GG_RDHOOKPATCH(d) \
-uint8_t gg_RdHookPatch##d(uint8_t addr) \
+static uint8_t gg_RdHookPatch##d(uint8_t addr) \
 { \
     if (addr == gg_PatchedAddr[d]) \
     { \
@@ -67,30 +68,22 @@ uint8_t gg_RdHookPatch##d(uint8_t addr) \
 }
 
 #define GG_MAX_PATCH 10
-/* Defines the rdhook patches */
+/* Defines the read hook patches */
 GG_RDHOOKPATCH(0)
-
 GG_RDHOOKPATCH(1)
-
 GG_RDHOOKPATCH(2)
-
 GG_RDHOOKPATCH(3)
-
 GG_RDHOOKPATCH(4)
-
 GG_RDHOOKPATCH(5)
-
 GG_RDHOOKPATCH(6)
-
 GG_RDHOOKPATCH(7)
-
 GG_RDHOOKPATCH(8)
-
 GG_RDHOOKPATCH(9)
 
 void gg_SetPatch(int id, uint8_t page, uint8_t addr, uint8_t value)
 {
     func_rdhook fptr;
+    func_rdhook cur_ptr;
 
     if (id >= GG_MAX_PATCH)
     {
@@ -154,30 +147,28 @@ void gg_SetPatch(int id, uint8_t page, uint8_t addr, uint8_t value)
         break;
     }
 
-    set_page_rd_hook(page, fptr);
+    cur_ptr = get_page_rdhook(page);
+    if (cur_ptr != fptr)
+    {
+        set_page_rd_hook(page, fptr);
+    }
 }
 
-
-/* Access to the bitmap Buffer */
-extern BITMAP *Buffer;
-BITMAP *gg_Buffer;
-
 void MessageBox(char *title, char *msg)
 {
-
     int sc_w, sc_h;
     int box_h, box_t, box_l, box_w;
 
-    sc_w = screen->w;
-    sc_h = screen->h;
+    sc_w = 640; //screen->w;
+    sc_h = 480; //screen->h;
 
-    gg_Buffer = create_bitmap(sc_w, sc_h);
+    /*gg_Buffer = create_bitmap(sc_w, sc_h);
 
-    blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
+    blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);*/
 
-    box_w = text_length(font, title) + 10;
+    box_w = 0;// text_length(font, title) + 10;
 
-    box_w = (box_w > text_length(font, msg)) ? box_w : text_length(font, msg);
+    //box_w = (box_w > text_length(font, msg)) ? box_w : text_length(font, msg);
 
     box_w += 15 * 2; /*sc_w/2;*/
     box_h = 15 * 2 + 10;
@@ -186,70 +177,72 @@ void MessageBox(char *title, char *msg)
     box_t = (sc_h - box_h) / 2;
     box_l = (sc_w - box_w) / 2;
 
-    rectfill(gg_Buffer, box_l, box_t, box_l + box_w, box_t + box_h, 60);
-    rect(gg_Buffer, box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
+    graphics_drawFillrect(box_l, box_t, box_l + box_w, box_t + box_h, 60);
+    graphics_drawRect(box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
 
     /* Display the title */
-    textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
+    //textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
 
     /* Display the message */
-    textout_centre_ex(gg_Buffer, font, msg, box_w / 2 + box_l, 15 + box_t + 2, 34, 60);
+    //textout_centre_ex(gg_Buffer, font, msg, box_w / 2 + box_l, 15 + box_t + 2, 34, 60);
 
-    blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
+    //blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
 
-    sleep(1);
+    sleep(1000);
 
-    release_bitmap(gg_Buffer);
+    //release_bitmap(gg_Buffer);
 
 }
 
 uint16_t SelectNumber(char *title, char *msg, uint8_t size)
 {
 
-    int sc_w, sc_h;
-    int box_h, box_t, box_l, box_w;
+    //int sc_w, sc_h;
+    //int box_h;
+    int box_w;
+    //int box_t, box_l;
 
     char valueText[10];
 
     uint16_t value;
     uint8_t digit = 0;
 
-    sc_w = screen->w;
-    sc_h = screen->h;
+    //sc_w = 640; //screen->w;
+    //sc_h = 480; //screen->h;
 
-    gg_Buffer = create_bitmap(sc_w, sc_h);
+    //gg_Buffer = create_bitmap(sc_w, sc_h);
 
-    blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
+    //blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
 
-    box_w = text_length(font, title) + 10;
+    //box_w = text_length(font, title) + 10;
 
-    box_w = (box_w > text_length(font, msg)) ? box_w : text_length(font, msg);
+    box_w = 0; //(box_w > text_length(font, msg)) ? box_w : text_length(font, msg);
 
     sprintf(valueText, "0000");
 
-    box_w = (box_w > text_length(font, valueText)) ? box_w : text_length(font, msg);
+    //box_w = (box_w > text_length(font, valueText)) ? box_w : text_length(font, msg);
 
     box_w += 15 * 2; /*sc_w/2;*/
-    box_h = 15 * 2 + 30;
+    //box_h = 15 * 2 + 30;
 
     /* Set the box center */
-    box_t = (sc_h - box_h) / 2;
-    box_l = (sc_w - box_w) / 2;
+    //box_t = (sc_h - box_h) / 2;
+    //box_l = (sc_w - box_w) / 2;
 
 
     value = 0;
 
-    while (!key[KEY_ENTER])
+    while (getKeyStatus(KEY_ENTER)) // ENTER
     {
 
-        rectfill(gg_Buffer, box_l, box_t, box_l + box_w, box_t + box_h, 60);
-        rect(gg_Buffer, box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
+        //rectfill(gg_Buffer, box_l, box_t, box_l + box_w, box_t + box_h, 60);
+        //rect(gg_Buffer, box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
 
         /* Display the title */
-        textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
+        //textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
 
         /* Display the message */
-        textout_centre_ex(gg_Buffer, font, msg, box_w / 2 + box_l, 15 + box_t + 2, 34, 60);
+        //textout_centre_ex(gg_Buffer, font, msg, box_w / 2 + box_l, 15 + box_t + 2, 34, 60);
 
         if (size == 2)
         {
@@ -260,44 +253,44 @@ uint16_t SelectNumber(char *title, char *msg, uint8_t size)
             sprintf(valueText, "%04X", value);
         }
 
-        textout_centre_ex(gg_Buffer, font, valueText, box_w / 2 + box_l, 15 + box_t + 2 + 10, 34, 60);
+        //textout_centre_ex(gg_Buffer, font, valueText, box_w / 2 + box_l, 15 + box_t + 2 + 10, 34, 60);
 
         switch (digit)
         {
         default:
         case 0:
-            textout_centre_ex(gg_Buffer, font, "   ^", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
+            //textout_centre_ex(gg_Buffer, font, "   ^", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
             break;
         case 1:
-            textout_centre_ex(gg_Buffer, font, "  ^ ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
+            //textout_centre_ex(gg_Buffer, font, "  ^ ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
             break;
 
         case 2:
-            textout_centre_ex(gg_Buffer, font, " ^  ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
+            //textout_centre_ex(gg_Buffer, font, " ^  ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
             break;
 
         case 3:
-            textout_centre_ex(gg_Buffer, font, "^   ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
+            //textout_centre_ex(gg_Buffer, font, "^   ", box_w / 2 + box_l, 15 + box_t + 2 + 20, 34, 60);
             break;
         }
 
-        blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
+        //blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
 
-        if (key[KEY_UP])
+        if (getKeyStatus(KEY_UP)) // UP
         {
             usleep(100000);
             value += ((digit == 0) ? 0x0001 : ((digit == 1) ? 0x0010 : ((digit == 2) ? 0x0100 : 0x1000)));
             value &= (size == 2) ? 0xFF : 0xFFFF;
         }
 
-        if (key[KEY_DOWN])
+        if (getKeyStatus(KEY_DOWN)) // DOWN
         {
             usleep(100000);
             value -= ((digit == 0) ? 0x0001 : ((digit == 1) ? 0x0010 : ((digit == 2) ? 0x0100 : 0x1000)));
             value &= (size == 2) ? 0xFF : 0xFFFF;
         }
 
-        if (key[KEY_RIGHT])
+        if (getKeyStatus(KEY_RIGHT)) // RIGHT
         {
             usleep(100000);
             if (digit <= 0)
@@ -310,7 +303,7 @@ uint16_t SelectNumber(char *title, char *msg, uint8_t size)
             }
         }
 
-        if (key[KEY_LEFT])
+        if (getKeyStatus(KEY_LEFT))
         {
             usleep(100000);
             if (digit >= size - 1)
@@ -324,8 +317,8 @@ uint16_t SelectNumber(char *title, char *msg, uint8_t size)
         }
 
     }
-    release_bitmap(gg_Buffer);
-    while (key[KEY_ENTER])
+    //release_bitmap(gg_Buffer);
+    while (getKeyStatus(KEY_ENTER))
     {
     }
     return value;
@@ -338,20 +331,27 @@ int DispMenu(int itemc, char *itemv[], char *title)
     int selection = 0;
     int i;
     int sc_w, sc_h;
-    int box_h, box_t, box_l, box_w;
+    int32_t box_h, box_t, box_l, box_w;
+    int32_t text_h;
+
+    graphics_getScreenSize(&sc_w, &sc_h);
 
-    sc_w = screen->w;
-    sc_h = screen->h;
+    //gg_Buffer = create_bitmap(sc_w, sc_h);
 
-    gg_Buffer = create_bitmap(sc_w, sc_h);
+    //blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
 
-    blit(Buffer, gg_Buffer, 0, 0, 0, 0, 512 + 256, 480);
+    graphics_get_text_size(&box_w, &text_h, NULL, title);
+    box_w += 10;
 
-    box_w = text_length(font, title) + 10;
 
     for (i = 0 ; i < itemc ; i++)
     {
-        box_w = (box_w > text_length(font, itemv[i])) ? box_w : text_length(font, itemv[i]);
+        int32_t tmp;
+        graphics_get_text_size(&tmp, NULL, NULL, itemv[i]);
+        if (box_w < tmp)
+        {
+            box_w = tmp;
+        }
     }
 
     box_w += 15 * 2; /*sc_w/2;*/
@@ -362,36 +362,51 @@ int DispMenu(int itemc, char *itemv[], char *title)
     box_l = (sc_w - box_w) / 2;
 
 
-    while (!key[KEY_ENTER])
+    while (!getKeyStatus(KEY_ENTER))
     {
         /* Draw the box and highlight the selected item */
-        rectfill(gg_Buffer, box_l, box_t, box_l + box_w, box_t + box_h, 60);
-        rect(gg_Buffer, box_l + 5, box_t + 5, box_l + box_w - 5, box_t + box_h - 5, 34);
+        int i;
+        for (i = 0; i < box_h; i++)
+        {
+            graphics_drawline(box_l, box_t+i, box_w, box_t + i, 1);
+        }
+        graphics_drawline(5, 121, 251, 121, 41);
+
+        //graphics_drawFillrect(box_l, box_t, box_w, box_h, 5);
+        //graphics_drawRect(box_l + 5, box_t + 5, box_w - 5, box_h - 5, 1);
 
         /* Display the title */
-        textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
+        graphics_text_ex(box_l, box_t + 2, box_w, text_h,
+                         NULL,
+                         34, 60,
+                         TEXT_VALIGN_CENTER, TEXT_HALIGN_CENTER,
+                         0,
+                         title);
+        //textout_centre_ex(gg_Buffer, font, title, box_w / 2 + box_l, box_t + 2, 34, 60);
 
         /* Display the highlight item */
-        rectfill(gg_Buffer, box_l + 15, 15 + box_t + (selection * 10), box_l + box_w - 15,
-                 15 + box_t + (selection * 10) + 10, 34);
-        textout_centre_ex(gg_Buffer, font, itemv[selection], box_w / 2 + box_l, 15 + box_t + (selection * 10) + 2, 60,
-                          34);
+        //graphics_drawFillrect(box_l + 15, 15 + box_t + (selection * 10), box_l + box_w - 15,
+        //        15 + box_t + (selection * 10) + 10, 34);
+        graphics_draw_text(box_w / 2 + box_l, 15 + box_t + (selection * 10) + 2, 60, NULL, itemv[selection]);
+        //textout_centre_ex(gg_Buffer, font, itemv[selection], box_w / 2 + box_l, 15 + box_t + (selection * 10) + 2, 60,
+        //                  34);
 
         /* Display other items */
         for (i = 0 ; i < itemc ; i++)
         {
             if (i != selection)
             {
-                textout_centre_ex(gg_Buffer, font, itemv[i], box_w / 2 + box_l, 15 + box_t + (i * 10) + 2, 34, 60);
+                //textout_centre_ex(gg_Buffer, font, itemv[i], box_w / 2 + box_l, 15 + box_t + (i * 10) + 2, 34, 60);
             }
         }
 
 
         /* Blit the screen buffer */
-        blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
+        vsync();
+        //blit(gg_Buffer, screen, 0, 0, 0, 0, 512 + 256, 480);
 
         /* Now get the keyboard state */
-        if (key[KEY_UP])
+        if (getKeyStatus(KEY_UP))
         {
             usleep(100000);
             if (selection <= 0)
@@ -404,7 +419,7 @@ int DispMenu(int itemc, char *itemv[], char *title)
             }
         }
 
-        if (key[KEY_DOWN])
+        if (getKeyStatus(KEY_DOWN))
         {
             usleep(100000);
             if (selection >= (itemc - 1))
@@ -419,9 +434,10 @@ int DispMenu(int itemc, char *itemv[], char *title)
 
     }
 
-    release_bitmap(gg_Buffer);
-    while (key[KEY_ENTER])
+    //release_bitmap(gg_Buffer);
+    while (getKeyStatus(KEY_ENTER))
     {
+        vsync();
     }
     return selection;
 }
@@ -474,7 +490,7 @@ uint8_t gg_SelectPatch()
         }
         else
         {
-            sprintf(tmp, "Patch %d: Put 0x%02X on address 0x%02X%02X (Code: %08lX)",
+            sprintf(tmp, "Patch %d: Put 0x%02X on address 0x%02X%02X (Code: %08X)",
                     i, gg_PatchedValue[i], gg_PatchedPage[i], gg_PatchedAddr[i],
                     gg_MakeCode((gg_PatchedPage[i] << 8) | gg_PatchedAddr[i], gg_PatchedValue[i]));
         }
@@ -698,6 +714,9 @@ void gg_Start()
     int ret;
     uint8_t value;
     uint16_t addr;
+
+    console_printf(Console_Default, "Open GG plugin...\n");
+
     switch (gg_state)
     {
     default:
@@ -863,7 +882,7 @@ int gg_Init()
     int i;
     console_printf(Console_Default, "Initializing GG plugin...\n");
 
-    plugin_install_keypressHandler('g', gg_Start);
+    plugin_install_keypressHandler('G', gg_Start);
 
     for (i = 0 ; i < GG_MAX_PATCH ; i++)
     {
@@ -877,6 +896,4 @@ int gg_Init()
 int gg_Deinit()
 {
     return 0;
-}
-
-#endif
+}

+ 1 - 1
src/pluginsmanager/plugins_list.h

@@ -12,7 +12,7 @@
 #include "plugins/gamegenie.h"
 
 Plugin Plugins[] = {
-        //    { "Game Genie", gg_Init, gg_Deinit },
+        { "Game Genie", gg_Init, gg_Deinit },
 
 /* EOL tag */
         { NULL, NULL, NULL }