#include #include #include #include #include #include #include void quit(void); void welcome(OSScreenID screen); void drawScreen(OSScreenID screen, VPADTouchData gamepad, int color); int main(int argc, char **argv) { // initialize ProcUI and OSScreen WHBProcInit(); OSScreenInit(); // allocate memory to render both displays and align them size_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV); size_t drcBufferSize = OSScreenGetBufferSizeEx(SCREEN_DRC); void *tvBuffer = memalign(0x100, tvBufferSize); void *drcBuffer = memalign(0x100, drcBufferSize); // free used video memory and deinitialize OSScreen and ProcUI void quit(void) { if (tvBuffer) free(tvBuffer); if (drcBuffer) free(drcBuffer); OSScreenShutdown(); WHBProcShutdown(); }; // check if memory allocation was successful otherwise kill program if (!tvBuffer || !drcBuffer) { quit(); return 1; } // tell the screens where the allocated memory is OSScreenSetBufferEx(SCREEN_TV, tvBuffer); OSScreenSetBufferEx(SCREEN_DRC, drcBuffer); // enable control of the displays OSScreenEnableEx(SCREEN_TV, true); OSScreenEnableEx(SCREEN_DRC, true); VPADStatus status; VPADReadError error; VPADTouchData gamepadTouchScreen; bool vpad_fatal = false; uint32_t penColor = 0xFFFFFF00; // welcome message void welcome(OSScreenID screen) { OSScreenPutFontEx(screen, 0, 0, "Welcome to SimpleDrawU!"); OSScreenPutFontEx(screen, 0, 1, "A is red."); OSScreenPutFontEx(screen, 0, 2, "B is yellow."); OSScreenPutFontEx(screen, 0, 3, "X is blue."); OSScreenPutFontEx(screen, 0, 4, "Y is green."); OSScreenPutFontEx(screen, 0, 5, "Plus is white."); OSScreenPutFontEx(screen, 0, 6, "Minus is black (erase)."); OSScreenPutFontEx(screen, 0, 7, "Press both Plus and Minus"); OSScreenPutFontEx(screen, 0, 8, "to clear the screen, enjoy!"); } welcome(SCREEN_TV); welcome(SCREEN_DRC); // define color palette enum penColor { white = 0xFFFFFF00, black = 0x00000000, red = 0xBF5B5B00, yellow = 0xC6B95500, blue = 0x3C8D8800, green = 0x86B46000, }; // draw pixels to screen void drawScreen(OSScreenID screen, VPADTouchData gamepad, int color) { OSScreenPutPixelEx(screen, gamepad.x - 1, gamepad.y - 1, color); OSScreenPutPixelEx(screen, gamepad.x + 1, gamepad.y + 1, color); OSScreenPutPixelEx(screen, gamepad.x + 1, gamepad.y, color); OSScreenPutPixelEx(screen, gamepad.x - 1, gamepad.y, color); OSScreenPutPixelEx(screen, gamepad.x, gamepad.y, color); OSScreenPutPixelEx(screen, gamepad.x, gamepad.y + 1, color); OSScreenPutPixelEx(screen, gamepad.x, gamepad.y - 1, color); OSScreenPutPixelEx(screen, gamepad.x - 1, gamepad.y + 1, color); OSScreenPutPixelEx(screen, gamepad.x + 1, gamepad.y - 1, color); }; // while ProcUI is running while (WHBProcIsRunning()) { // read gamepad inputs and check if error VPADRead(VPAD_CHAN_0, &status, 1, &error); switch (error) { case VPAD_READ_SUCCESS: { VPADGetTPCalibratedPoint(VPAD_CHAN_0, &gamepadTouchScreen, &status.tpNormal); break; } case VPAD_READ_NO_SAMPLES: { continue; } case VPAD_READ_INVALID_CONTROLLER: { vpad_fatal = true; break; } default: { vpad_fatal = true; break; } } if (vpad_fatal) break; // clear screen if ((status.hold & VPAD_BUTTON_PLUS) && (status.hold & VPAD_BUTTON_MINUS)) { OSScreenClearBufferEx(SCREEN_TV, black); OSScreenClearBufferEx(SCREEN_DRC, black); } // select color if (status.hold & VPAD_BUTTON_PLUS) { penColor = white; } if (status.hold & VPAD_BUTTON_MINUS) { penColor = black; } if (status.hold & VPAD_BUTTON_A) { penColor = red; } if (status.hold & VPAD_BUTTON_B) { penColor = yellow; } if (status.hold & VPAD_BUTTON_X) { penColor = blue; } if (status.hold & VPAD_BUTTON_Y) { penColor = green; } // draw on screen if (gamepadTouchScreen.touched) { drawScreen(SCREEN_TV, gamepadTouchScreen, penColor); drawScreen(SCREEN_DRC, gamepadTouchScreen, penColor); } // commit drawing to the screen DCFlushRange(tvBuffer, tvBufferSize); DCFlushRange(drcBuffer, drcBufferSize); OSScreenFlipBuffersEx(SCREEN_TV); OSScreenFlipBuffersEx(SCREEN_DRC); } quit(); return 0; }