commit 747ff207c0c28ee91d8ed329a959d985d68bcdaa Author: Maschell Date: Sun Dec 31 18:49:45 2017 +0100 First commit diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7dc3253 --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +ifeq ($(strip $(LIBTRANSISTOR_HOME)),) +$(error "Please set LIBTRANSISTOR_HOME in your environment. export LIBTRANSISTOR_HOME=") +endif + +PROGRAM := hello +OBJ := hello.o draw.o input.o + +include $(LIBTRANSISTOR_HOME)/libtransistor.mk + +all: $(PROGRAM).nro + +%.o: %.c + $(CC) $(CC_FLAGS) -Wno-pointer-arith -c -o $@ $< + +%.o: %.S + $(AS) $(AS_FLAGS) $< -filetype=obj -o $@ + +$(PROGRAM).nro.so: ${OBJ} $(LIBTRANSITOR_NRO_LIB) $(LIBTRANSISTOR_COMMON_LIBS) + $(LD) $(LD_FLAGS) -o $@ ${OBJ} $(LIBTRANSISTOR_NRO_LDFLAGS) + +clean: + rm -rf *.o *.nso *.nro *.so \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..4a4b4e5 --- /dev/null +++ b/README.md @@ -0,0 +1,50 @@ +# PUSH A for Switch + +Based on: https://github.com/vgmoose/sdl-hello-world + +Back to the roots. Back in 2008 I started with writing homebrew on Wii. The first "game" I created was "Push A". +Now, almost 10 years later, I quickly wrote a new version for the Switch. + +Maybe only works with detached Joy-Cons. + +Have fun! + +Huge thanks to vgmoose, based on his examples!. + +### Compiling +#### For Switch +Clone and setup libtransistor, for more detail [see this post](https://reswitchedweekly.github.io/Development-Setup/). +``` +git clone --recursive -b graphics-experimental-fs https://github.com/reswitched/libtransistor.git +cd libtransistor +make +cd .. +``` + +Then export an environment variable pointing to your libtransistor build, and run `make`: +``` +export LIBTRANSISTOR_HOME=./libtransistor +make +``` + +### Running +The below instructions are for 3.0.0, written on 12/30/2017: + +Build ace_loader in `./projects/ace_loader` of libtransistor, by running `make` + +Copy the built `ace.nro` into Pegaswitch's `nros` directory (overwrite the existing one) + +Run [Pegaswitch](https://github.com/reswitched/pegaswitch) on your computer, and set your Switch's DNS server to your computer's. + +Once pegaswitch connects, run ace_loader with `runnro nros/ace.nro`. If this is your first time running Pegaswitch, use `evalfile usefulscripts/SetupNew.js` first. + +If successful, the Switch should be back at the Wifi menu, and frozen. From here: +``` +nc 2991 < hello.nro +``` + +Where `` is the IP of your switch. + +See [here](https://github.com/reswitched/pegaswitch#usage) for more on Pegaswitch, and [here](https://github.com/reswitched/libtransistor) on ace_loader. + +[See this post](https://reswitchedweekly.github.io/Development-Setup/) for more troubleshooting diff --git a/draw.c b/draw.c new file mode 100644 index 0000000..c068295 --- /dev/null +++ b/draw.c @@ -0,0 +1,294 @@ +#include "draw.h" + +Graphics* init() +{ + if(SDL_Init(SDL_INIT_VIDEO) < 0) { + printf("SDL init failed: %s\n", SDL_GetError()); + return 0; + } + + printf("initialized SDL\n"); + Graphics* g = malloc(sizeof (Graphics)); + + g->window = SDL_CreateWindow("n/a", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 1280, 720, SDL_WINDOW_SHOWN); + if(g->window == NULL) { + printf("window could not be created: %s\n", SDL_GetError()); + return 0; + } + + printf("created window\n"); + + g->window_surface = SDL_GetWindowSurface(g->window); + + printf("got window surface\n"); + + // make background black + background(g, 0x00, 0x00, 0x00); + + return g; +} + +void deinit(struct Graphics* g) +{ + SDL_Delay(1); + SDL_DestroyWindow(g->window); + SDL_Quit(); + + free(g); +} + +void sleep(int s) +{ + SDL_Delay(s*1000); +} + +void usleep(int s) +{ + SDL_Delay(s); +} + +void background(struct Graphics* gr, int r, int g, int b) +{ + SDL_FillRect(gr->window_surface, NULL, SDL_MapRGBA(gr->window_surface->format, b, g, r, 0xFF)); +} + +void update(struct Graphics* g) +{ + SDL_UpdateWindowSurface(g->window); +} + +// puts a 3x3 "pixel" on screen at the given x, y with the given r, g, b +// will need update() called after to display any pixels that were created +// the switch resolution is 1280x720, but the "pixels" used by this grid are 426x240 +void putAPixel(struct Graphics* gr, int x, int y, int r, int g, int b) +{ + int num = (r << 24) | (g << 16) | (b << 8) | 0; + x *= 2; + y *= 2; + + int ax, ay, az; + for (ax=0; ax<2; ax++) + for (ay=0; ay<2; ay++) + for (az=0; az<2; az++) + { + SDL_Rect rect; + rect.x = x*1.5; + rect.y = y*1.5; + rect.w = 3; + rect.h = 3; + + SDL_FillRect(gr->window_surface, &rect, SDL_MapRGBA(gr->window_surface->format, b, g, r, 0xFF)); + } +} + +// draws a string using our bitmap font (below) at the given xi, yi +// the xi, yi given are on a 53x30 grid, (8x less than the "pixel" grid) +// optional: provide r, g, b values, otherwise white +void drawString(struct Graphics* gr, int xi, int yi, char* string) +{ + drawColorString(gr, xi, yi, string, 0xff, 0xff, 0xff); +} + +void drawStringf(struct Graphics* gr, int xi, int yi, const char* format, ...){ + char * tmp = NULL; + + va_list va; + va_start(va, format); + if((vasprintf(&tmp, format, va) >= 0) && tmp) + { + drawString(gr,xi,yi,tmp); + } + va_end(va); + + if(tmp){ + free(tmp); + } +} + +void drawColorString(struct Graphics* gr, int xi, int yi, char* string, int r, int g, int b) +{ + // for every character in the string, if it's within range, render it at the current position + // and move over 8 characters + + xi *= 8; + yi *= 8; + + char next = -1; + int i = 0; + while (next != '\0') + { + next = string[i++]; + + // actually draw this char pixel by pixel, if it's within range + if (next >= 0) + { + char* bitmap = fontLookup(next); + int x, y; + for (x=0; x < 8; x++) { + for (y=0; y < 8; y++) { + if (bitmap[x] & 1 << y) + putAPixel(gr, xi+y+i*8, yi+x, r, g, b); + } + } + } + } +} + + +/** + * 8x8 monochrome bitmap fonts for rendering + * Author: Daniel Hepper + * + * License: Public Domain + * + * Based on: + * // Summary: font8x8.h + * // 8x8 monochrome bitmap fonts for rendering + * // + * // Author: + * // Marcel Sondaar + * // International Business Machines (public domain VGA fonts) + * // + * // License: + * // Public Domain + * + * Fetched from: http://dimensionalrift.homelinux.net/combuster/mos3/?p=viewsource&file=/modules/gfx/font8_8.asm + **/ + +// Constant: font8x8_basic +// Contains an 8x8 font map for unicode points U+0000 - U+007F (basic latin) +char font[128][8] = { + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0000 (nul) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0001 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0002 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0003 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0004 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0005 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0006 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0007 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0008 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0009 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+000F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0010 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0011 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0012 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0013 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0014 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0015 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0016 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0017 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0018 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0019 + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001A + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001B + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001C + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001D + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001E + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+001F + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0020 (space) + { 0x18, 0x3C, 0x3C, 0x18, 0x18, 0x00, 0x18, 0x00}, // U+0021 (!) + { 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0022 (") + { 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00}, // U+0023 (#) + { 0x0C, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x0C, 0x00}, // U+0024 ($) + { 0x00, 0x63, 0x33, 0x18, 0x0C, 0x66, 0x63, 0x00}, // U+0025 (%) + { 0x1C, 0x36, 0x1C, 0x6E, 0x3B, 0x33, 0x6E, 0x00}, // U+0026 (&) + { 0x06, 0x06, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0027 (') + { 0x18, 0x0C, 0x06, 0x06, 0x06, 0x0C, 0x18, 0x00}, // U+0028 (() + { 0x06, 0x0C, 0x18, 0x18, 0x18, 0x0C, 0x06, 0x00}, // U+0029 ()) + { 0x00, 0x66, 0x3C, 0xFF, 0x3C, 0x66, 0x00, 0x00}, // U+002A (*) + { 0x00, 0x0C, 0x0C, 0x3F, 0x0C, 0x0C, 0x00, 0x00}, // U+002B (+) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+002C (,) + { 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00, 0x00}, // U+002D (-) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+002E (.) + { 0x60, 0x30, 0x18, 0x0C, 0x06, 0x03, 0x01, 0x00}, // U+002F (/) + { 0x3E, 0x63, 0x73, 0x7B, 0x6F, 0x67, 0x3E, 0x00}, // U+0030 (0) + { 0x0C, 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x3F, 0x00}, // U+0031 (1) + { 0x1E, 0x33, 0x30, 0x1C, 0x06, 0x33, 0x3F, 0x00}, // U+0032 (2) + { 0x1E, 0x33, 0x30, 0x1C, 0x30, 0x33, 0x1E, 0x00}, // U+0033 (3) + { 0x38, 0x3C, 0x36, 0x33, 0x7F, 0x30, 0x78, 0x00}, // U+0034 (4) + { 0x3F, 0x03, 0x1F, 0x30, 0x30, 0x33, 0x1E, 0x00}, // U+0035 (5) + { 0x1C, 0x06, 0x03, 0x1F, 0x33, 0x33, 0x1E, 0x00}, // U+0036 (6) + { 0x3F, 0x33, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00}, // U+0037 (7) + { 0x1E, 0x33, 0x33, 0x1E, 0x33, 0x33, 0x1E, 0x00}, // U+0038 (8) + { 0x1E, 0x33, 0x33, 0x3E, 0x30, 0x18, 0x0E, 0x00}, // U+0039 (9) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x00}, // U+003A (:) + { 0x00, 0x0C, 0x0C, 0x00, 0x00, 0x0C, 0x0C, 0x06}, // U+003B (//) + { 0x18, 0x0C, 0x06, 0x03, 0x06, 0x0C, 0x18, 0x00}, // U+003C (<) + { 0x00, 0x00, 0x3F, 0x00, 0x00, 0x3F, 0x00, 0x00}, // U+003D (=) + { 0x06, 0x0C, 0x18, 0x30, 0x18, 0x0C, 0x06, 0x00}, // U+003E (>) + { 0x1E, 0x33, 0x30, 0x18, 0x0C, 0x00, 0x0C, 0x00}, // U+003F (?) + { 0x3E, 0x63, 0x7B, 0x7B, 0x7B, 0x03, 0x1E, 0x00}, // U+0040 (@) + { 0x0C, 0x1E, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x00}, // U+0041 (A) + { 0x3F, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3F, 0x00}, // U+0042 (B) + { 0x3C, 0x66, 0x03, 0x03, 0x03, 0x66, 0x3C, 0x00}, // U+0043 (C) + { 0x1F, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1F, 0x00}, // U+0044 (D) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x46, 0x7F, 0x00}, // U+0045 (E) + { 0x7F, 0x46, 0x16, 0x1E, 0x16, 0x06, 0x0F, 0x00}, // U+0046 (F) + { 0x3C, 0x66, 0x03, 0x03, 0x73, 0x66, 0x7C, 0x00}, // U+0047 (G) + { 0x33, 0x33, 0x33, 0x3F, 0x33, 0x33, 0x33, 0x00}, // U+0048 (H) + { 0x1E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0049 (I) + { 0x78, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E, 0x00}, // U+004A (J) + { 0x67, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x67, 0x00}, // U+004B (K) + { 0x0F, 0x06, 0x06, 0x06, 0x46, 0x66, 0x7F, 0x00}, // U+004C (L) + { 0x63, 0x77, 0x7F, 0x7F, 0x6B, 0x63, 0x63, 0x00}, // U+004D (M) + { 0x63, 0x67, 0x6F, 0x7B, 0x73, 0x63, 0x63, 0x00}, // U+004E (N) + { 0x1C, 0x36, 0x63, 0x63, 0x63, 0x36, 0x1C, 0x00}, // U+004F (O) + { 0x3F, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x0F, 0x00}, // U+0050 (P) + { 0x1E, 0x33, 0x33, 0x33, 0x3B, 0x1E, 0x38, 0x00}, // U+0051 (Q) + { 0x3F, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x67, 0x00}, // U+0052 (R) + { 0x1E, 0x33, 0x07, 0x0E, 0x38, 0x33, 0x1E, 0x00}, // U+0053 (S) + { 0x3F, 0x2D, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0054 (T) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x3F, 0x00}, // U+0055 (U) + { 0x33, 0x33, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0056 (V) + { 0x63, 0x63, 0x63, 0x6B, 0x7F, 0x77, 0x63, 0x00}, // U+0057 (W) + { 0x63, 0x63, 0x36, 0x1C, 0x1C, 0x36, 0x63, 0x00}, // U+0058 (X) + { 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x0C, 0x1E, 0x00}, // U+0059 (Y) + { 0x7F, 0x63, 0x31, 0x18, 0x4C, 0x66, 0x7F, 0x00}, // U+005A (Z) + { 0x1E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x1E, 0x00}, // U+005B ([) + { 0x03, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x40, 0x00}, // U+005C (\) + { 0x1E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1E, 0x00}, // U+005D (]) + { 0x08, 0x1C, 0x36, 0x63, 0x00, 0x00, 0x00, 0x00}, // U+005E (^) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF}, // U+005F (_) + { 0x0C, 0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+0060 (`) + { 0x00, 0x00, 0x1E, 0x30, 0x3E, 0x33, 0x6E, 0x00}, // U+0061 (a) + { 0x07, 0x06, 0x06, 0x3E, 0x66, 0x66, 0x3B, 0x00}, // U+0062 (b) + { 0x00, 0x00, 0x1E, 0x33, 0x03, 0x33, 0x1E, 0x00}, // U+0063 (c) + { 0x38, 0x30, 0x30, 0x3e, 0x33, 0x33, 0x6E, 0x00}, // U+0064 (d) + { 0x00, 0x00, 0x1E, 0x33, 0x3f, 0x03, 0x1E, 0x00}, // U+0065 (e) + { 0x1C, 0x36, 0x06, 0x0f, 0x06, 0x06, 0x0F, 0x00}, // U+0066 (f) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0067 (g) + { 0x07, 0x06, 0x36, 0x6E, 0x66, 0x66, 0x67, 0x00}, // U+0068 (h) + { 0x0C, 0x00, 0x0E, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+0069 (i) + { 0x30, 0x00, 0x30, 0x30, 0x30, 0x33, 0x33, 0x1E}, // U+006A (j) + { 0x07, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x67, 0x00}, // U+006B (k) + { 0x0E, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x1E, 0x00}, // U+006C (l) + { 0x00, 0x00, 0x33, 0x7F, 0x7F, 0x6B, 0x63, 0x00}, // U+006D (m) + { 0x00, 0x00, 0x1F, 0x33, 0x33, 0x33, 0x33, 0x00}, // U+006E (n) + { 0x00, 0x00, 0x1E, 0x33, 0x33, 0x33, 0x1E, 0x00}, // U+006F (o) + { 0x00, 0x00, 0x3B, 0x66, 0x66, 0x3E, 0x06, 0x0F}, // U+0070 (p) + { 0x00, 0x00, 0x6E, 0x33, 0x33, 0x3E, 0x30, 0x78}, // U+0071 (q) + { 0x00, 0x00, 0x3B, 0x6E, 0x66, 0x06, 0x0F, 0x00}, // U+0072 (r) + { 0x00, 0x00, 0x3E, 0x03, 0x1E, 0x30, 0x1F, 0x00}, // U+0073 (s) + { 0x08, 0x0C, 0x3E, 0x0C, 0x0C, 0x2C, 0x18, 0x00}, // U+0074 (t) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x33, 0x6E, 0x00}, // U+0075 (u) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x1E, 0x0C, 0x00}, // U+0076 (v) + { 0x00, 0x00, 0x63, 0x6B, 0x7F, 0x7F, 0x36, 0x00}, // U+0077 (w) + { 0x00, 0x00, 0x63, 0x36, 0x1C, 0x36, 0x63, 0x00}, // U+0078 (x) + { 0x00, 0x00, 0x33, 0x33, 0x33, 0x3E, 0x30, 0x1F}, // U+0079 (y) + { 0x00, 0x00, 0x3F, 0x19, 0x0C, 0x26, 0x3F, 0x00}, // U+007A (z) + { 0x38, 0x0C, 0x0C, 0x07, 0x0C, 0x0C, 0x38, 0x00}, // U+007B ({) + { 0x18, 0x18, 0x18, 0x00, 0x18, 0x18, 0x18, 0x00}, // U+007C (|) + { 0x07, 0x0C, 0x0C, 0x38, 0x0C, 0x0C, 0x07, 0x00}, // U+007D (}) + { 0x6E, 0x3B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // U+007E (~) + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00} // U+007F +}; + +char* fontLookup(char c) +{ + return font[c]; +} diff --git a/draw.h b/draw.h new file mode 100644 index 0000000..b319984 --- /dev/null +++ b/draw.h @@ -0,0 +1,20 @@ +#include + +struct Graphics { + SDL_Window* window; + SDL_Surface* window_surface; +}; + +typedef struct Graphics Graphics; + +Graphics* init(); +void deinit(struct Graphics* g); +void update(struct Graphics* g); +void sleep(int s); +void usleep(int s); +void background(struct Graphics* gr, int r, int g, int b); +void putAPixel(struct Graphics* gr, int x, int y, int r, int g, int b); +void drawString(struct Graphics* gr, int xi, int yi, char* string); +void drawStringf(struct Graphics* gr, int xi, int yi, const char* format, ...); +void drawColorString(struct Graphics* gr, int xi, int yi, char * string, int r, int g, int b); +char* fontLookup(char c); diff --git a/hello.c b/hello.c new file mode 100644 index 0000000..6ec1bd6 --- /dev/null +++ b/hello.c @@ -0,0 +1,107 @@ +#include "draw.h" +#include "input.h" +#include + +#define IDLE 0 +#define IN_GAME 1 +#define RESULT 2 + +int main(){ + // initialize and get graphics context + Graphics* g = init(); + + struct PADData pad_data; + + PADInit(); + int x = 10; + int y = 8; + + int game_state = IDLE; + + int frame_counter = 0; + int round_duration = 60 * 10; //10 seconds; + int button_count = 0; + int last_buttons = 0; + int buttons_r = 0; + int score = 0; + int highscore = 0; + int isHighscore = 0; + + while(1){ + // draw backgroung + background(g, 0x00, 0x00, 0x00); + + //Read input data + PADRead(&pad_data); + + buttons_r = (last_buttons & (~pad_data.btns_h)); + + /*if(pad_data.btns_h & BUTTON_LEFT){ + x--; + } + if(pad_data.btns_h & BUTTON_RIGHT){ + x++; + } + if(pad_data.btns_h & BUTTON_DOWN){ + y++; + } + if(pad_data.btns_h & BUTTON_UP){ + y--; + }*/ + + drawStringf(g, 20, 0, "Highscore: %d", highscore); + drawStringf(g, 30, 28, "PUSH A by Maschell", highscore); + drawStringf(g, 0, 28, "Press PLUS to exit"); + + printf(" pad: %08X %08X\n", pad_data.btns_h,buttons_r); + + if(game_state == IDLE){ + drawStringf(g, x, y, "Press MINUS to start!"); + if(pad_data.btns_h & BUTTON_MINUS){ + game_state = IN_GAME; + } + }else if(game_state == IN_GAME){ + frame_counter++; + if(buttons_r & BUTTON_A){ + button_count++; + } + float secLeft = (round_duration - frame_counter) /60.0f; + drawStringf(g, x, y, "Press A as fast as you can!"); + drawStringf(g, x, y+2, "Time left: %0.2f seconds!",secLeft); + drawStringf(g, x, y+4, "Current score: %d", button_count); + if(frame_counter > round_duration){ + score = button_count; + button_count = 0; + frame_counter = 0; + if(score > highscore){ + highscore = score; + isHighscore = 1; + } + game_state = RESULT; + } + }else if(game_state == RESULT){ + drawStringf(g, x, y, "Score: %d", button_count); + drawStringf(g, x, y+2,"Press MINUS to try again."); + if(isHighscore){ + drawStringf(g, x, y+4,"NEW HIGHSCORE!"); + } + if(pad_data.btns_h & BUTTON_MINUS){ + game_state = IN_GAME; + isHighscore = 0; + } + } + + if(pad_data.btns_h & BUTTON_PLUS){ + break; + } + update(g); + usleep(16); + last_buttons = pad_data.btns_h; + } + + // clean up graphics + deinit(g); + PADDestroy(); + + return 0; +} diff --git a/hello.nro b/hello.nro new file mode 100644 index 0000000..cf901fb Binary files /dev/null and b/hello.nro differ diff --git a/input.c b/input.c new file mode 100644 index 0000000..befa971 --- /dev/null +++ b/input.c @@ -0,0 +1,30 @@ +#include "input.h" +#include + +void PADInit(){ + hid_init(); +} + +void PADDestroy(){ + hid_finalize(); +} + +void PADRead(struct PADData* data){ + // reset buttons + data->btns_h = 0b00000000; + + // scan for controller + hid_controller_t* num8 = hid_get_shared_memory()->controllers; + + hid_controller_state_entry_t ent = num8->main.entries[num8->main.latest_idx]; + + // process inputs + data->btns_h |= ((ent.button_state & JOYPAD_A)? BUTTON_A : 0); + data->btns_h |= ((ent.button_state & JOYPAD_B)? BUTTON_B : 0); + data->btns_h |= ((ent.button_state & JOYPAD_UP)? BUTTON_UP : 0); + data->btns_h |= ((ent.button_state & JOYPAD_DOWN)? BUTTON_DOWN : 0); + data->btns_h |= ((ent.button_state & JOYPAD_LEFT)? BUTTON_LEFT : 0); + data->btns_h |= ((ent.button_state & JOYPAD_RIGHT)? BUTTON_RIGHT : 0); + data->btns_h |= ((ent.button_state & JOYPAD_START)? BUTTON_PLUS : 0); + data->btns_h |= ((ent.button_state & JOYPAD_SELECT)? BUTTON_MINUS : 0); +} diff --git a/input.h b/input.h new file mode 100644 index 0000000..69631ce --- /dev/null +++ b/input.h @@ -0,0 +1,40 @@ +// "PAD" controls (unique to us) +#define BUTTON_LEFT 0b00000001 +#define BUTTON_RIGHT 0b00000010 +#define BUTTON_UP 0b00000100 +#define BUTTON_DOWN 0b00001000 + +#define BUTTON_MINUS 0b00010000 +#define BUTTON_PLUS 0b00100000 + +#define BUTTON_A 0b01000000 +#define BUTTON_B 0b10000000 + +// switch controls +#define JOYPAD_LEFT 0x1000 +#define JOYPAD_DOWN 0x8000 +#define JOYPAD_RIGHT 0x4000 +#define JOYPAD_UP 0x2000 +#define JOYPAD_START 0x0400 +#define JOYPAD_SELECT 0x0800 +#define JOYPAD_X 0x0004 +#define JOYPAD_Y 0x0008 +#define JOYPAD_B 0x0002 +#define JOYPAD_A 0x0001 +#define JOYPAD_R 0x0080 +#define JOYPAD_L 0x0040 +#define JOYPAD_R2 0x0200 +#define JOYPAD_L2 0x0100 + +// custom data structure for space game input +struct PADData { + int btns_h; + short rstick_x; + short lstick_x; + short rstick_y; + short lstick_y; +}; + +void PADInit(); +void PADDestroy(); +void PADRead(struct PADData* data);