super basic drawing app

This commit is contained in:
array-in-a-matrix 2024-02-20 17:29:33 -05:00
commit d600fe0281
3 changed files with 181 additions and 0 deletions

9
.gitignore vendored Normal file
View file

@ -0,0 +1,9 @@
# cmake garbage
CMakeFiles/
CMakeCache.txt
cmake_install.cmake
Make
# binaries
*.rpx
*.elf

12
CMakeLists.txt Normal file
View file

@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.2)
set(CMAKE_TOOLCHAIN_FILE $ENV{DEVKITPRO}/wut/share/wut.toolchain.cmake)
project(SimpleDrawU C)
include("${DEVKITPRO}/wut/share/wut.cmake" REQUIRED)
add_executable(SimpleDrawU
main.c)
target_compile_options(SimpleDrawU PRIVATE -Wall)
wut_create_rpx(SimpleDrawU)

160
main.c Normal file
View file

@ -0,0 +1,160 @@
#include <stdint.h>
#include <stdbool.h>
#include <malloc.h>
#include <stdio.h>
#include <stdlib.h>
#include <coreinit/screen.h>
#include <coreinit/cache.h>
#include <whb/log_cafe.h>
#include <whb/log.h>
#include <whb/proc.h>
#include <vpad/input.h>
int main(int argc, char** argv) {
/* Init logging. We log both to Cafe's internal logger (shows up in Decaf, some
crash logs) and over UDP to be received with udplogserver. */
WHBLogCafeInit();
/* WHBLogPrint and WHBLogPrintf add new line characters for you */
WHBLogPrint("Hello World! Logging initialised.");
/* Init WHB's ProcUI wrapper. This will manage all the little Cafe OS bits and
pieces for us - home menu overlay, power saving features, etc. */
WHBProcInit();
/* Init OSScreen. This is the really simple graphics API we'll be using to
draw some text! */
OSScreenInit();
/* OSScreen needs buffers for each display - get the size of those now.
"DRC" is Nintendo's acronym for the Gamepad. */
size_t tvBufferSize = OSScreenGetBufferSizeEx(SCREEN_TV);
size_t drcBufferSize = OSScreenGetBufferSizeEx(SCREEN_DRC);
WHBLogPrintf("Will allocate 0x%X bytes for the TV, " \
"and 0x%X bytes for the DRC.",
tvBufferSize, drcBufferSize);
/* Try to allocate an area for the buffers. According to OSScreenSetBufferEx's
documentation, these need to be 0x100 aligned. */
void* tvBuffer = memalign(0x100, tvBufferSize);
void* drcBuffer = memalign(0x100, drcBufferSize);
/* Make sure the allocation actually succeeded! */
if (!tvBuffer || !drcBuffer) {
WHBLogPrint("Out of memory!");
/* It's vital to free everything - under certain circumstances, your memory
allocations can stay allocated even after you quit. */
if (tvBuffer) free(tvBuffer);
if (drcBuffer) free(drcBuffer);
/* Deinit everything */
OSScreenShutdown();
WHBProcShutdown();
WHBLogPrint("Quitting.");
WHBLogCafeDeinit();
WHBLogUdpDeinit();
/* Your exit code doesn't really matter, though that may be changed in
future. Don't use -3, that's reserved for HBL. */
return 1;
}
/* Buffers are all good, set them */
OSScreenSetBufferEx(SCREEN_TV, tvBuffer);
OSScreenSetBufferEx(SCREEN_DRC, drcBuffer);
/* Finally, enable OSScreen for each display! */
OSScreenEnableEx(SCREEN_TV, true);
OSScreenEnableEx(SCREEN_DRC, true);
/* WHBProcIsRunning will return false if the OS asks us to quit, so it's a
good candidate for a loop */
VPADStatus status;
VPADReadError error;
VPADTouchData gamepadTouchScreen;
bool vpad_fatal = false;
uint32_t penColor = 0xFFFFFF00;
while(WHBProcIsRunning()) {
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: {
WHBLogPrint("Gamepad disconnected!");
vpad_fatal = true;
break;
}
default: {
WHBLogPrintf("Unknown VPAD error! %08X", error);
vpad_fatal = true;
break;
}
}
if (vpad_fatal) break;
OSScreenPutFontEx(SCREEN_TV, 0, 0, "Simple Draw U (TV).");
OSScreenPutFontEx(SCREEN_DRC, 0, 0, "Simple Draw U (Gamepad).");
// clear screen
if(status.trigger & VPAD_BUTTON_MINUS){
OSScreenClearBufferEx(SCREEN_TV, 0x00000000);
OSScreenClearBufferEx(SCREEN_DRC, 0x00000000);
}
// select color
if(status.trigger & VPAD_BUTTON_PLUS){ penColor = 0xFFFFFF00;} // white
if(status.trigger & VPAD_BUTTON_A){ penColor = 0xBF5B5B00; } // red
if(status.trigger & VPAD_BUTTON_B){ penColor = 0xC6B95500; } // yellow
if(status.trigger & VPAD_BUTTON_X){ penColor = 0x3C8D8800; } // blue
if(status.trigger & VPAD_BUTTON_Y){ penColor = 0x86B46000; } // green
// draw on screen
if(gamepadTouchScreen.touched){
OSScreenPutPixelEx(SCREEN_TV, gamepadTouchScreen.x-1, gamepadTouchScreen.y-1, penColor);
OSScreenPutPixelEx(SCREEN_TV, gamepadTouchScreen.x+1, gamepadTouchScreen.y+1, penColor);
OSScreenPutPixelEx(SCREEN_TV, gamepadTouchScreen.x, gamepadTouchScreen.y, penColor);
OSScreenPutPixelEx(SCREEN_TV, gamepadTouchScreen.x-1, gamepadTouchScreen.y+1, penColor);
OSScreenPutPixelEx(SCREEN_TV, gamepadTouchScreen.x+1, gamepadTouchScreen.y-1, penColor);
OSScreenPutPixelEx(SCREEN_DRC, gamepadTouchScreen.x+1, gamepadTouchScreen.y+1, penColor);
OSScreenPutPixelEx(SCREEN_DRC, gamepadTouchScreen.x-1, gamepadTouchScreen.y-1, penColor);
OSScreenPutPixelEx(SCREEN_DRC, gamepadTouchScreen.x, gamepadTouchScreen.y, penColor);
OSScreenPutPixelEx(SCREEN_DRC, gamepadTouchScreen.x-1, gamepadTouchScreen.y+1, penColor);
OSScreenPutPixelEx(SCREEN_DRC, gamepadTouchScreen.x+1, gamepadTouchScreen.y-1, penColor);
}
/* Flush all caches - read the tutorial, please! */
DCFlushRange(tvBuffer, tvBufferSize);
DCFlushRange(drcBuffer, drcBufferSize);
/* Flip buffers - the text is now on screen! Flipping is kinda like
committing your graphics changes. */
OSScreenFlipBuffersEx(SCREEN_TV);
OSScreenFlipBuffersEx(SCREEN_DRC);
}
WHBLogPrint("Got shutdown request!");
/* It's vital to free everything - under certain circumstances, your memory
allocations can stay allocated even after you quit. */
if (tvBuffer) free(tvBuffer);
if (drcBuffer) free(drcBuffer);
/* Deinit everything */
OSScreenShutdown();
WHBProcShutdown();
WHBLogPrint("Quitting.");
WHBLogCafeDeinit();
/* Your exit code doesn't really matter, though that may be changed in
future. Don't use -3, that's reserved for HBL. */
return 1;
}