diff --git a/docs/gfx.md b/docs/gfx.md index c6723fc..f584b52 100644 --- a/docs/gfx.md +++ b/docs/gfx.md @@ -31,6 +31,20 @@ Enable or disable 3D on the top screen. ## `bool gfxIs3D(void);` Check whether the 3D is enabled on the top screen. +## `u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* height);` +Get all the data which will be display to be able to modify it. +If `gspInit()` was used, the return data is formatted as follow: +- Each byte is a color value. +- The colors are in order: blue, green, red. 3 bytes make a pixel. +- The pixels are from the bottom to the top of the screen. 'width' pixels make a pixel column. +- 'height' colums make the screen. +The size of the returned value is: 3 (colors) * width (rows) * height (colums). +Arguments: +- screen: screen to get the frame buffer from (either GFX_TOP or GFX_BOTTOM). +- side: for the 3D screen GFX_LEFT for the left eye image, GFX_RIGHT for the right. If bottom screen or if not 3D, use GFX_LEFT. +- width: height of the screen (yep) +- height: width of the screen (yep yep yep doesn't make any sense) + # TO SEE: ## `bool gspPresentBuffer(???);` diff --git a/docs/os.md b/docs/os.md new file mode 100644 index 0000000..929ceff --- /dev/null +++ b/docs/os.md @@ -0,0 +1,4 @@ +# OS + +## `float osGet3DSliderState(void);` +Get the slider level from 0.0 (no 3D) to 1.0 (full 3D). \ No newline at end of file diff --git a/source/graphics.cpp b/source/graphics.cpp new file mode 100644 index 0000000..dd08051 --- /dev/null +++ b/source/graphics.cpp @@ -0,0 +1,12 @@ +#include "graphics.hpp" + +void rgb_set(t_color &dest, u8 r, u8 g, u8 b) { + dest[0] = b; + dest[1] = g; + dest[2] = r; +} + +void rgb_set(t_color &dest, u32 rgb) { + u8 *rgb_u8 = (u8 *)&rgb; + rgb_set(dest, rgb_u8[2], rgb_u8[1], rgb_u8[0]); +} diff --git a/source/graphics.hpp b/source/graphics.hpp new file mode 100644 index 0000000..1c87fbc --- /dev/null +++ b/source/graphics.hpp @@ -0,0 +1,23 @@ +/** + * Utils for the graphics of the 3DS. + */ + +#pragma once + +#include <3ds.h> + +typedef u8 t_color[3]; + +/// @brief Create a t_color from each color value. +/// +/// @param dest The color to set. +/// @param r Red value from 0 to 255. +/// @param g Green value from 0 to 255. +/// @param b Blue value from 0 to 255. +void rgb_set(t_color &dest, u8 r, u8 g, u8 b); + +/// @brief Create a t_color from a number 0xRRGGBB. +/// +/// @param dest The color to set. +/// @param value Value to set the color to, in the form: 0xRRGGBB. +void rgb_set(t_color &dest, u32 rgb); \ No newline at end of file diff --git a/source/main.cpp b/source/main.cpp index 577a539..5b2de5b 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,49 +1,354 @@ #include <3ds.h> #include #include "utilsconsole.hpp" +#include "graphics.hpp" +#include using namespace std; +void mode_ugly_rainbow(void) { + cout << "mode ugly rainbow" << endl; + gfxSet3D(false); + gspWaitForVBlank(); + + u16 width, height; + t_color *frame = + (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); + for (int i = 0; i < width * height; i++) + { + if (i % 30 < 10) + rgb_set(frame[i], 0xFF0000); + else if (i % 30 < 20) + rgb_set(frame[i], 0x00FF00); + else + rgb_set(frame[i], 0x0000FF); + } + + gfxFlushBuffers(); + gfxSwapBuffers(); + uc_pause(); +} + +void mode_direction(void) { + cout << "mode direction" << endl; + gfxSet3D(false); + gspWaitForVBlank(); + + u16 width, height; + t_color *frame = + (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); + for (int i = 0; i < width * height; i++) + { + if (i / 100 == 0) + rgb_set(frame[i], 0xFF0000); + else if (i / 100 == 1) + rgb_set(frame[i], 0xFFFF00); + else if (i / 100 == 2) + rgb_set(frame[i], 0x00FF00); + else if (i / 100 == 3) + rgb_set(frame[i], 0x00FFFF); + else if (i / 100 == 4) + rgb_set(frame[i], 0x0000FF); + else if (i / 100 == 5) + rgb_set(frame[i], 0xFF00FF); + else + rgb_set(frame[i], 0); + if (i % 100 >= 10) { + frame[i][0] = frame[i][0] == 0xFF ? 0x7F : 0; + frame[i][1] = frame[i][1] == 0xFF ? 0x7F : 0; + frame[i][2] = frame[i][2] == 0xFF ? 0x7F : 0; + } + } + + gfxFlushBuffers(); + gfxSwapBuffers(); + uc_pause(); +} + +void mode_XY(void) { + cout << "mode XY" << endl; + cout << "the higher x is, the redder the pixel is." << endl; + cout << "the higher y is, the bluer the pixel is." << endl; + gfxSet3D(false); + gspWaitForVBlank(); + + u16 width, height; + t_color *frame = + (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); + for (int i = 0; i < width * height; i++) + { + int x = i / width; + int y = height - i % height - 1; + if (x < 0) + cout << "!!! x less than 0 !!!" << endl; + if (y < 0) + cout << "!!! y less than 0 !!!" << endl; + if (x >= width) + cout << "!!! x higher than width " << width << " !!!" << endl; + if (y >= height) + cout << "!!! y higher than height " << height << " !!!" << endl; + rgb_set(frame[i], + x > 255 ? 255 : x, + 0, + y > 255 ? 255 : y); + } + + gfxFlushBuffers(); + gfxSwapBuffers(); + uc_pause(); +} + +void mode_2d_square(void) { + cout << "mode 2d square" << endl; + gfxSet3D(false); + gspWaitForVBlank(); + + u32 color = 0xFB2B2B; + + u16 width, height; + t_color *frame = + (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); + for (int i = 0; i < width * height; i++) + { + int x = i / height; + int y = height - i % height - 1; + if (x > 20 && x < 40 && y > 20 && y < 40) + rgb_set(frame[i], 0xFFFFFF); + else + rgb_set(frame[i], color); + } + + gfxFlushBuffers(); + gfxSwapBuffers(); + uc_pause(); +} + +void mode_3d_square(void) { + cout << "mode 3d square" << endl; + + float slider3d; + slider3d = osGet3DSliderState(); + cout << "3D level: " << slider3d << endl; + gfxSet3D(true); + if (!slider3d) { + cout << "no 3D :(" << endl; + uc_pause(); + return; + } + gspWaitForVBlank(); + + u32 color = 0xFB2B2B; + + u16 width, height; + t_color *frame; + frame = (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); + for (int i = 0; i < width * height; i++) + { + int x = i / height; + int y = height - i % height - 1; + if (x > 15 && x < 35 && y > 20 && y < 40) + rgb_set(frame[i], 0xFFFFFF); + else + rgb_set(frame[i], color); + } + + frame = (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, &height, &width); + for (int i = 0; i < width * height; i++) + { + int x = i / height; + int y = height - i % height - 1; + if (x > 25 && x < 45 && y > 20 && y < 40) + rgb_set(frame[i], 0xFFFFFF); + else + rgb_set(frame[i], color); + } + + gfxFlushBuffers(); + gfxSwapBuffers(); + uc_pause(); +} + +static u32 rainbow_color(int i) { + while (i < 0) + i += 24; + switch (i % 24) { // sorry + case 0: + return 0xFF0000; + case 1: + return 0xFF3F00; + case 2: + return 0xFF7F00; + case 3: + return 0xFFBF00; + case 4: + return 0xFFFF00; + case 5: + return 0xBFFF00; + case 6: + return 0x7FFF00; + case 7: + return 0x3FFF00; + case 8: + return 0x00FF00; + case 9: + return 0x00FF3F; + case 10: + return 0x00FF7F; + case 11: + return 0x00FFBF; + case 12: + return 0x00FFFF; + case 13: + return 0x00BFFF; + case 14: + return 0x007FFF; + case 15: + return 0x003FFF; + case 16: + return 0x0000FF; + case 17: + return 0x3F00FF; + case 18: + return 0x7F00FF; + case 19: + return 0xBF00FF; + case 20: + return 0xFF00FF; + case 21: + return 0xFF00BF; + case 22: + return 0xFF007F; + case 23: + return 0xFF003F; + } + return 0xFFFFFF; +} + +void mode_ugly_3d_rainbow(void) { + cout << "mode ugly 3d rainbow" << endl; + cout << "A to return..." << endl; + + gfxSet3D(true); + + while (aptMainLoop()) { + gspWaitForVBlank(); + + int thick = 20; + float slider3d = osGet3DSliderState(); + int depth = slider3d * 30; + + u16 width, height; + t_color *frame; + + frame = (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); + for (int i = 0; i < width * height; i++) + { + int x = i / height; + int y = height - i % height - 1; + (void)y; + rgb_set(frame[i], rainbow_color((x + depth) / thick)); + } + + frame = (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, &height, &width); + for (int i = 0; i < width * height; i++) + { + int x = i / height; + int y = height - i % height - 1; + (void)y; + rgb_set(frame[i], rainbow_color((x - depth) / thick)); + } + + gfxFlushBuffers(); + gfxSwapBuffers(); + + hidScanInput(); + if (hidKeysDown() & KEY_A) + break; + } +} + +void mode_yellue(void) { + cout << "mode yellue" << endl; + + int left_red = 0; + int left_green = 0; + int left_blue = 2; + int right_red = 2; + int right_green = 2; + int right_blue = 0; + const auto to255 = [] (int value) { + return value > 0 ? value * 128 - 1 : 0; + }; + + static const int menu_size = 7; + static const s_uc_menu_element menu[] = { + {"left red ", true, &left_red, 0, 2}, + {"left green", true, &left_green, 0, 2}, + {"left blue ", true, &left_blue, 0, 2}, + {"right red ", true, &right_red, 0, 2}, + {"right green", true, &right_green, 0, 2}, + {"right blue ", true, &right_blue, 0, 2}, + {"back", false, NULL, 0, 0}, + }; + static auto menuVec = vector(menu, menu + menu_size); + + gfxSet3D(true); + + while (aptMainLoop()) { + gspWaitForVBlank(); + + u16 width, height; + t_color *frame; + frame = (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_LEFT, &height, &width); + for (int i = 0; i < width * height; i++) + rgb_set(frame[i], + to255(left_red), to255(left_green), to255(left_blue)); + + frame = (t_color *) gfxGetFramebuffer(GFX_TOP, GFX_RIGHT, &height, &width); + for (int i = 0; i < width * height; i++) + rgb_set(frame[i], + to255(right_red), to255(right_green), to255(right_blue)); + + gfxFlushBuffers(); + gfxSwapBuffers(); + + if (uc_menu(menuVec) == 6) + break; + } +} + int main(void) {; gfxInitDefault(); consoleInit(GFX_BOTTOM, NULL); - int a = 0; - int b = 2; - int c = -10; while (aptMainLoop()) { + static const int menu_size = 7; static const s_uc_menu_element menu[] = { - {"a", true, &a, 0, 10}, - {"b", true, &b, 0, 2}, - {"c", true, &c, -10, 10}, - {"Show", false, NULL, 0, 0}, - {"Test quick menu", false, NULL, 0, 0}, + {"ugly rainbow", false, NULL, 0, 0}, + {"direction", false, NULL, 0, 0}, + {"XY", false, NULL, 0, 0}, + {"2D square", false, NULL, 0, 0}, + {"3D square", false, NULL, 0, 0}, + {"ugly 3D rainbow", false, NULL, 0, 0}, + {"yellue", false, NULL, 0, 0}, }; - static auto menuVec = vector(menu, menu + 5); + static auto menuVec = vector(menu, menu + menu_size); int ans = uc_menu(menuVec); - if (ans == 3) { - cout << "a: " << a << ", b: " << b << ", c: " << c << endl; - uc_pause(); - } - else if (ans == 4) { - while (aptMainLoop()) { - ans = uc_menu_quick("hello", "hola", "bonjour", "Go back"); - switch (ans) { - case 0: - cout << "bye" << endl; - break; - case 1: - cout << "adios" << endl; - break; - case 2: - cout << "au revoir" << endl; - break; - } - if (ans == 3) - break; - uc_pause(); - } - } + if (ans == 0) + mode_ugly_rainbow(); + if (ans == 1) + mode_direction(); + if (ans == 2) + mode_XY(); + if (ans == 3) + mode_2d_square(); + if (ans == 4) + mode_3d_square(); + if (ans == 5) + mode_ugly_3d_rainbow(); + if (ans == 6) + mode_yellue(); + gfxSet3D(false); } gfxExit(); } \ No newline at end of file