]> Chaos Git - corbenik/corbenik.git/commitdiff
Multiple again:
authorroot <chaos.kagami@gmail.com>
Sun, 17 Jul 2016 01:57:08 +0000 (21:57 -0400)
committerroot <chaos.kagami@gmail.com>
Sun, 17 Jul 2016 01:57:08 +0000 (21:57 -0400)
 * Fix #26
 * Initialize in RGBA8 mode - I want that alpha channel.
 * (bug) Screeninit seems to produce screwed up results when partially done. Or I'm doing it wrong. For now, I force a screeninit on all systems.
 * Fix up drawing functions for RGBA8.
 * Use a precomputed table for the dimmer. This improves performance somewhat.

external/screeninit/source/main.c
external/screeninit/source/start.s
external/screeninit/source/types.h
source/chain.c
source/main.c
source/screeninit.c
source/screeninit.h
source/std/draw.c
source/std/draw.h

index 318911ae20d8fe7ceb25c0fc1e88d10428da3f21..932cb7e62c77511c51aeefa0fe3e6bcc12a3acea 100755 (executable)
@@ -1,12 +1,43 @@
 #include "types.h"
 
-void main(void)
-{
+#define FB_FMT(col, plx, screen) ((col & 0b111) | ((plx & 1) << 5) | ((screen & 1) << 6) | 0b10000000001100000000)
+
+#define RGBA8        0
+#define BGR8         1
+#define RGB565_OES   2
+#define RGB5_A1_OES  3
+#define RGBA4_OES    4
+
+#define INIT_FULL    0
+#define INIT_PARAMS  1
+#define INIT_DEINIT  2
+
+void main(void) {
    // FIXME - We could use some serious macros here...
 
-   u32 brightnessLevel = *(vu32 *)0x24FFFC08;
+   u32 do_init         = *(vu32 *)0x24FFFC08;
+   u32 brightnessLevel = *(vu32 *)0x24FFFC0C;
+   u32 mode            = *(vu32 *)0x24FFFC10;
+
+   u32 yaw, init_top, init_bottom;
+   switch(mode) {
+       case RGBA8:
+           yaw = 240 * 4;
+           break;
+       case BGR8:
+       case RGB565_OES:
+       case RGB5_A1_OES:
+       case RGBA4_OES:
+           yaw = 240 * 3;
+           break;
+   }
+
+   init_top    = FB_FMT(mode, 0, 1);
+   init_bottom = FB_FMT(mode, 0, 0);
+
    vu32 *const arm11 = (u32 *)0x1FFFFFF8;
 
+   if (do_init == INIT_FULL) {
    *(vu32 *)0x10141200 = 0x1007F;
    *(vu32 *)0x10202014 = 0x00000001;
    *(vu32 *)0x1020200C &= 0xFFFEFFFE;
@@ -35,14 +66,15 @@ void main(void)
    *(vu32 *)0x10400440 = 0x01960192;
    *(vu32 *)0x10400444 = 0x00000000;
    *(vu32 *)0x10400448 = 0x00000000;
+
    *(vu32 *)0x1040045C = 0x00f00190;
    *(vu32 *)0x10400460 = 0x01c100d1;
    *(vu32 *)0x10400464 = 0x01920002;
    *(vu32 *)0x10400468 = 0x18300000;
-   *(vu32 *)0x10400470 = 0x80341;
+   *(vu32 *)0x10400470 = init_top; // Format
    *(vu32 *)0x10400474 = 0x00010501;
    *(vu32 *)0x10400478 = 0;
-   *(vu32 *)0x10400490 = 0x000002D0;
+   *(vu32 *)0x10400490 = yaw;
    *(vu32 *)0x1040049C = 0x00000000;
 
    // Disco register
@@ -69,14 +101,15 @@ void main(void)
    *(vu32 *)0x10400540 = 0x01980194;
    *(vu32 *)0x10400544 = 0x00000000;
    *(vu32 *)0x10400548 = 0x00000011;
+
    *(vu32 *)0x1040055C = 0x00f00140;
    *(vu32 *)0x10400560 = 0x01c100d1;
    *(vu32 *)0x10400564 = 0x01920052;
-   *(vu32 *)0x10400568 = 0x18300000 + 0x46500;
-   *(vu32 *)0x10400570 = 0x80301;
+   *(vu32 *)0x10400568 = 0x18300000 + (yaw * 400);
+   *(vu32 *)0x10400570 = init_bottom; // Format
    *(vu32 *)0x10400574 = 0x00010501;
    *(vu32 *)0x10400578 = 0;
-   *(vu32 *)0x10400590 = 0x000002D0;
+   *(vu32 *)0x10400590 = yaw;
    *(vu32 *)0x1040059C = 0x00000000;
 
    // Disco register
@@ -87,13 +120,16 @@ void main(void)
    *(vu32 *)0x1040046c = 0x18300000;
    *(vu32 *)0x10400494 = 0x18300000;
    *(vu32 *)0x10400498 = 0x18300000;
-   *(vu32 *)0x10400568 = 0x18346500;
-   *(vu32 *)0x1040056c = 0x18346500;
+   *(vu32 *)0x10400568 = 0x18300000 + (yaw * 400);
+   *(vu32 *)0x1040056c = 0x18300000 + (yaw * 400);
 
    //Set CakeBrah framebuffers
    *((vu32 *)0x23FFFE00) = 0x18300000;
    *((vu32 *)0x23FFFE04) = 0x18300000;
-   *((vu32 *)0x23FFFE08) = 0x18346500;
+   *((vu32 *)0x23FFFE08) = 0x18300000 + (yaw * 400);
+   } else if (do_init == INIT_DEINIT) {
+
+   }
 
    //Clear ARM11 entry offset
    *arm11 = 0;
index 40392d13ab5bde3b3387cf3b3356b7ecc6b21e90..1ce301b4bfe70a245d92d08852fc616b977d3e70 100644 (file)
@@ -2,9 +2,11 @@
 .align 4
 .global _start
 _start:
-    @ Disable interrupts
+    // Disable interrupts
     CPSID aif
 
     b main
 
-    .word 0
+do_init_or_deinit: .int 0
+brightness: .int 0
+mode:       .int 0
index d27412b67961e5d47a2313b677131ef6b103bb89..f47ac07c3f6208420f3f96d82e0bdeeb9046eb6f 100755 (executable)
@@ -10,4 +10,9 @@ typedef uint64_t u64;
 typedef volatile u8 vu8;
 typedef volatile u16 vu16;
 typedef volatile u32 vu32;
-typedef volatile u64 vu64;
\ No newline at end of file
+typedef volatile u64 vu64;
+
+extern int do_init_or_deinit;
+extern int brightness;
+extern int mode;
+extern int brightness;
index 4efa5175e734532cdb9f2943cc80e319b8fbfbca..6f95a24b90d8ebf19b9b13d3f3d5b2b8acf461ac 100644 (file)
@@ -1,6 +1,7 @@
 #if defined(CHAINLOADER) && CHAINLOADER == 1
 
 #include "common.h"
+#include "screeninit.h"
 #include "firm/firm.h"
 #include "firm/headers.h"
 
@@ -67,6 +68,8 @@ void chainload_file(char* chain_file_data) {
 
     fprintf(stderr, "Chaining to copy payload...\n");
 
+    screen_mode(1); // TODO - Because RGBA8 screeninit is non-standard...ugh
+
     ((void(*)(void*, uint32_t))0x24F00000)(chain_data, size + 256 + 8); // Size of payload + argv.
 }
 
index 8a5316e7104c1247dfeb2b9c59aaf57b15e88ad9..172d1fc24f8966346e732eecab52724c0e6366b7 100644 (file)
@@ -23,7 +23,7 @@ main(int argc, char** argv)
     std_init();
 
     int c = fmount();
-    screen_init();
+    screen_mode(0);
     clear_bg();
     load_bg_top(PATH_BITS "/top.bin");
     load_bg_bottom(PATH_BITS "/bottom.bin"); // This is basically a menuhax splash (90deg rotated BGR8 pixel data)
index 42689fce850c916dae4b52527b32e82beb3b597f..1108ff1becc49c55d5d9faa0108aa08d3faa53df 100644 (file)
@@ -1,5 +1,7 @@
 #include <ctr9/io.h>
 #include <ctr9/ctr_screen.h>
+#include <ctr9/i2c.h>
+#include "common.h"
 #include "std/fs.h"
 #include "patch_format.h"
 
 static volatile uint32_t *const a11_entry = (volatile uint32_t *)0x1FFFFFF8;
 
 void
-screen_init()
+screen_mode(uint32_t mode)
 {
-    if (PDN_GPU_CNT == 1) {
-        uint32_t *screenInitAddress = (uint32_t *)0x24FFFC00;
+    uint32_t *screenInitAddress = (uint32_t *)0x24FFFC00;
 
-        FILE *f = fopen(PATH_SCREENINIT_CODE, "r");
-        fread(screenInitAddress, 1, fsize(f), f); // Read in the screeninit payload.
-        fclose(f);
+    FILE *f = fopen(PATH_SCREENINIT_CODE, "r");
+    fread(screenInitAddress, 1, fsize(f), f); // Read in the screeninit payload.
+    fclose(f);
+
+    // FIXME - At the moment, this seems mandatory to do full screeninit.
+
+    // I get very fucked up results from just changing the framebuffer offsets
+    // and display color mode. Until I figure out WHY a full screeninit has to
+    // be performed, I have to do a full screeninit.
+
+    // And no, 3dbrew didn't help. Partial init seems to be a superset of what
+    // I was attempting.
+
+//    if (PDN_GPU_CNT == 1) {
+        screenInitAddress[2] = 0; // Do a full init.
+        screenInitAddress[3] = 0xFF; // Brightness
+        screenInitAddress[4] = mode; // Mode
 
-        // Write brightness level for the stub to pick up
-        screenInitAddress[2] = 0x5F;
         *a11_entry = (uint32_t)screenInitAddress;
 
         while (*a11_entry);
 
         // Turn on backlight
+        i2cWriteRegister(I2C_DEV_MCU, 0x22, 1 << 1);
+
+        // FIXME - Time to yell at Gelex now. :|
         ctr_screen_enable_backlight(CTR_SCREEN_BOTH);
-    }
+//    }
 }
index 51057747a1211ae142df2738e09031d10749c8bb..c61684449526d3e8c8840822cc83ce49e586e5ca 100644 (file)
@@ -2,6 +2,6 @@
 #define __SCREENINIT_H
 
 // Inits the screen if needed.
-void screen_init();
+void screen_mode(uint32_t mode);
 
 #endif
index d2c7ae5fc26abfce33578ef99d78d69669b83e01..b5f88649856ab9bf021d0eb7d9cd21ef7c0c6eea 100644 (file)
@@ -30,9 +30,6 @@ static unsigned int text_top_height = 10;
 static unsigned int text_bottom_width = 20;
 static unsigned int text_bottom_height = 10;
 
-static int dim_factor_top = 0;
-static int dim_factor_bottom = 0;
-
 uint8_t *top_bg;
 uint8_t *bottom_bg;
 
@@ -42,7 +39,15 @@ int kill_output = 0;
 
 #define TRANSP_THRESH 178
 
+static uint8_t alphamap[256] = {0};
+
 void std_init() {
+       for(uint16_t i=0; i < 0x100; i++) {
+               alphamap[i] = 0;
+               if (i > 0x7F)
+                       alphamap[i] = i - 0x7F;
+       }
+
     top_bg     = static_allocate(TOP_SIZE);
     bottom_bg  = static_allocate(BOTTOM_SIZE);
     log_buffer = static_allocate(LOG_BUFFER_SIZE);
@@ -86,9 +91,10 @@ void rect(void* channel, int x, int y, int x2, int y2, uint8_t color) {
             int yDisplacement = ((height - y_a - 1) * SCREEN_DEPTH);
             int pos = xDisplacement + yDisplacement;
 
-            screen[pos]     = colors[color & 0xF];
-            screen[pos + 1] = colors[color & 0xF] >> 8;
-            screen[pos + 2] = colors[color & 0xF] >> 16;
+            screen[pos + 1] = colors[color & 0xF];
+            screen[pos + 2] = colors[color & 0xF] >> 8;
+            screen[pos + 3] = colors[color & 0xF] >> 16;
+            screen[pos] = 0xFF;
         }
     }
 }
@@ -120,9 +126,9 @@ void screenshot() {
             int yDisplacement = ((240 - y - 1) * SCREEN_DEPTH);
             int pos = xDisplacement + yDisplacement;
 
+            fwrite(& framebuffers->top_left[pos + 3], 1, 1, f);
             fwrite(& framebuffers->top_left[pos + 2], 1, 1, f);
             fwrite(& framebuffers->top_left[pos + 1], 1, 1, f);
-            fwrite(& framebuffers->top_left[pos],     1, 1, f);
         }
     }
 
@@ -137,9 +143,9 @@ void screenshot() {
             int yDisplacement = ((240 - y - 1) * SCREEN_DEPTH);
             int pos = xDisplacement + yDisplacement;
 
+            fwrite(& framebuffers->bottom[pos + 3], 1, 1, f);
             fwrite(& framebuffers->bottom[pos + 2], 1, 1, f);
             fwrite(& framebuffers->bottom[pos + 1], 1, 1, f);
-            fwrite(& framebuffers->bottom[pos],     1, 1, f);
         }
 
         for (int i = 0; i < 40 * 3; i++)
@@ -163,18 +169,6 @@ void load_bg_top(char* fname_top) {
     fread(top_bg, 1, TOP_SIZE, f);
 
     fclose(f);
-
-    // TODO - Needs finetuning. Median color intensity isn't exactly accurate.
-    int max = 0;
-    for(int i=0; i < TOP_SIZE; i++) {
-        if (max < top_bg[i])
-            max = top_bg[i];
-    }
-
-    // See load_bg_bottom for an explanation on the magic value.
-    dim_factor_top = 0;
-    if (max > TRANSP_THRESH)
-        dim_factor_top = max - TRANSP_THRESH;
 }
 
 void load_bg_bottom(char* fname_bottom) {
@@ -184,23 +178,6 @@ void load_bg_bottom(char* fname_bottom) {
 
     fread(bottom_bg, 1, BOTTOM_SIZE, f);
     fclose(f);
-
-    // TODO - Needs finetuning. Median color intensity isn't exactly accurate.
-    //        It's good enough for right now, though.
-    int max = 0;
-    for(int i=0; i < BOTTOM_SIZE; i++) {
-        if (max < bottom_bg[i])
-            max = bottom_bg[i];
-    }
-
-    // Why 178? Quick explanation:
-    //   A pixel color channel is 255 at absolute white here.
-    //   The minimum transparency with pure black overlay (I find) is 70% to be readable.
-    //   70% of 255 is approximately 178, and 255 - 178 is 77. That's therefore the maximum we want to subtract.
-    //   Thus this is the value for 70% transparency.
-    dim_factor_bottom = 0;
-    if (max > TRANSP_THRESH)
-        dim_factor_bottom = max - TRANSP_THRESH;
 }
 
 void set_font(const char* filename) {
@@ -263,27 +240,33 @@ clear_disp(uint8_t *screen)
         screen = framebuffers->bottom;
 
     if (screen == framebuffers->top_left || screen == framebuffers->top_right) {
-        if (kill_output || !config.options[OPTION_DIM_MODE]) {
-            memcpy(screen, top_bg, TOP_SIZE);
-        } else {
-            for(int i=0; i < TOP_SIZE; i++) {
-                screen[i] = 0;
-                if (top_bg[i] > dim_factor_top)
-                    screen[i] = top_bg[i] - dim_factor_top;
+        for(int i=0, j=0; j < TOP_SIZE; i += 3, j += 4) {
+            screen[j] = 0xFF;
+            screen[j + 1] = top_bg[i];
+            screen[j + 2] = top_bg[i + 1];
+            screen[j + 3] = top_bg[i + 2];
+            if (!kill_output && config.options[OPTION_DIM_MODE]) {
+                screen[j + 1] = alphamap[screen[j + 1]];
+                screen[j + 2] = alphamap[screen[j + 2]];
+                screen[j + 3] = alphamap[screen[j + 3]];
             }
         }
+
         top_cursor_x = 0;
         top_cursor_y = 0;
     } else if (screen == framebuffers->bottom) {
-        if (kill_output || !config.options[OPTION_DIM_MODE]) {
-            memcpy(screen, bottom_bg, BOTTOM_SIZE);
-        } else {
-            for(int i=0; i < BOTTOM_SIZE; i++) {
-                screen[i] = 0;
-                if (bottom_bg[i] >= dim_factor_bottom)
-                    screen[i] = bottom_bg[i] - dim_factor_bottom;
+        for(int i=0, j=0; j < BOTTOM_SIZE; i += 3, j += 4) {
+            screen[j] = 0x7F;
+            screen[j + 1] = bottom_bg[i];
+            screen[j + 2] = bottom_bg[i + 1];
+            screen[j + 3] = bottom_bg[i + 2];
+            if (!kill_output && config.options[OPTION_DIM_MODE]) {
+                screen[j + 1] = alphamap[screen[j + 1]];
+                screen[j + 2] = alphamap[screen[j + 2]];
+                screen[j + 3] = alphamap[screen[j + 3]];
             }
         }
+
         bottom_cursor_x = 0;
         bottom_cursor_y = 0;
     }
@@ -310,17 +293,14 @@ draw_character(uint8_t *screen, const uint32_t character, int ch_x, int ch_y, co
     _UNUSED int width = 0;
     int height = 0;
     uint8_t* buffer_bg;
-    int dim_factor;
     if (screen == framebuffers->top_left || screen == framebuffers->top_right) {
         width = TOP_WIDTH;
         height = TOP_HEIGHT;
         buffer_bg = top_bg;
-        dim_factor = dim_factor_top;
     } else if (screen == framebuffers->bottom) {
         width = BOTTOM_WIDTH;
         height = BOTTOM_HEIGHT;
         buffer_bg = bottom_bg;
-        dim_factor = dim_factor_bottom;
     } else {
         return; // Invalid buffer.
     }
@@ -334,59 +314,54 @@ draw_character(uint8_t *screen, const uint32_t character, int ch_x, int ch_y, co
     unsigned int c_font_w = (font_w / 8) + (font_w % 8 ? 1 : 0);
 
     for (unsigned int yy = 0; yy < font_h; yy++) {
-        int xDisplacement = (x * SCREEN_DEPTH * height);
-        int yDisplacement = ((height - (y + yy) - 1) * SCREEN_DEPTH);
-        unsigned int pos = xDisplacement + yDisplacement;
+        int xDisplacement   = (x * SCREEN_DEPTH * height);
+        int yDisplacement   = ((height - (y + yy) - 1) * SCREEN_DEPTH);
+        unsigned int pos    = xDisplacement + yDisplacement;
+
+        int xDisplacementBg = (x * 3 * height);
+        int yDisplacementBg = ((height - (y + yy) - 1) * 3);
+        unsigned int pos_b  = xDisplacementBg + yDisplacementBg;
+
         unsigned char char_dat = ((char*)FCRAM_FONT_LOC)[(character - ' ') * (c_font_w * font_h) + yy];
+
         for(unsigned int i=0; i < font_w + font_kern; i++) {
+            screen[pos] = 0xFF;
+
             if (color_bg == 0) {
-                if (!config.options[OPTION_DIM_MODE]) {
-                    screen[pos]     = buffer_bg[pos];
-                    screen[pos + 1] = buffer_bg[pos + 1];
-                    screen[pos + 2] = buffer_bg[pos + 2];
-                } else {
-                    screen[pos]     = 0;
-                    screen[pos + 1] = 0;
-                    screen[pos + 2] = 0;
-                    if (buffer_bg[pos] >= dim_factor)
-                        screen[pos]     = buffer_bg[pos] - dim_factor;
-                    if (buffer_bg[pos + 1] >= dim_factor)
-                        screen[pos + 1]     = buffer_bg[pos + 1] - dim_factor;
-                    if (buffer_bg[pos + 2] >= dim_factor)
-                        screen[pos + 2] = buffer_bg[pos + 2] - dim_factor;
+                screen[pos + 1] = buffer_bg[pos_b];
+                screen[pos + 2] = buffer_bg[pos_b + 1];
+                screen[pos + 3] = buffer_bg[pos_b + 2];
+                if (config.options[OPTION_DIM_MODE]) {
+                    screen[pos + 1] = alphamap[screen[pos + 1]];
+                    screen[pos + 2] = alphamap[screen[pos + 2]];
+                    screen[pos + 3] = alphamap[screen[pos + 3]];
                 }
             } else {
-                screen[pos]     = color_bg;
-                screen[pos + 1] = color_bg >> 8;
-                screen[pos + 2] = color_bg >> 16;
+                screen[pos + 1] = color_bg;
+                screen[pos + 2] = color_bg >> 8;
+                screen[pos + 3] = color_bg >> 16;
             }
 
             if (char_dat & 0x80) {
                 if (color_fg == 0) {
-                    if (!config.options[OPTION_DIM_MODE]) {
-                        screen[pos]     = buffer_bg[pos];
-                        screen[pos + 1] = buffer_bg[pos + 1];
-                        screen[pos + 2] = buffer_bg[pos + 2];
-                    } else {
-                        screen[pos]     = 0;
-                        screen[pos + 1] = 0;
-                        screen[pos + 2] = 0;
-                        if (buffer_bg[pos] >= dim_factor)
-                            screen[pos]     = buffer_bg[pos] - dim_factor;
-                        if (buffer_bg[pos + 1] >= dim_factor)
-                            screen[pos + 1]     = buffer_bg[pos + 1] - dim_factor;
-                        if (buffer_bg[pos + 2] >= dim_factor)
-                            screen[pos + 2] = buffer_bg[pos + 2] - dim_factor;
+                    screen[pos + 1] = buffer_bg[pos_b];
+                    screen[pos + 2] = buffer_bg[pos_b + 1];
+                    screen[pos + 3] = buffer_bg[pos_b + 2];
+                    if (config.options[OPTION_DIM_MODE]) {
+                        screen[pos + 1] = alphamap[screen[pos + 1]];
+                        screen[pos + 2] = alphamap[screen[pos + 2]];
+                        screen[pos + 3] = alphamap[screen[pos + 3]];
                     }
                 } else {
-                    screen[pos]     = color_fg;
-                    screen[pos + 1] = color_fg >> 8;
-                    screen[pos + 2] = color_fg >> 16;
+                    screen[pos + 1] = color_fg;
+                    screen[pos + 2] = color_fg >> 8;
+                    screen[pos + 3] = color_fg >> 16;
                 }
             }
 
             char_dat <<= 1;
-            pos += SCREEN_DEPTH * height;
+            pos      += SCREEN_DEPTH * height;
+            pos_b    += 3 * height;
         }
     }
 }
index fb2b4512de5fa0e96b977962b600e153ab198971..28b7ef9aaf8aac91e2b506f505799c8e5747b75a 100644 (file)
@@ -13,7 +13,7 @@
 #define BOTTOM_WIDTH 320
 #define BOTTOM_HEIGHT 240
 
-#define SCREEN_DEPTH 3
+#define SCREEN_DEPTH 4
 
 #define TOP_SIZE (TOP_WIDTH * TOP_HEIGHT * SCREEN_DEPTH)
 #define BOTTOM_SIZE (BOTTOM_WIDTH * BOTTOM_HEIGHT * SCREEN_DEPTH)