Created
March 1, 2015 17:06
-
-
Save crowell/b43a88a12323f5085a8a to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Hello World example made by Aurelio Mannara for ctrulib | |
This code was modified for the last time on: 12/12/2014 21:00 UTC+1 | |
This wouldn't be possible without the amazing work done by: | |
-Smealum | |
-fincs | |
-WinterMute | |
-yellows8 | |
-plutoo | |
-mtheall | |
-Many others who worked on 3DS and I'm surely forgetting about | |
*/ | |
#include <3ds.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define OPENSHiT \ | |
"ZPSSxUpRddddddddddidp,xEzpSo" \ | |
"ggzzSPSPzzddddda cz" \ | |
"j\x01rW" \ | |
"gzzSPSzzPSPSiiiPdddcrJ\x06WSPWSPWWWWWW" \ | |
"gxtgx_zx,poSPP" \ | |
"iiiiiiiiiiiiiiiiiiSPdiiiiiiiiiiiiiiiiiii" \ | |
"c+J\x01WW" \ | |
"gc3J\x02WWWizW" \ | |
"xApAcAcdJ\x05WWWWWWWWidxMdgigdxA" \ | |
"gx\x18gx\x27gdgigx\x18gx\x16gx\x17giczj\x01rWzzz?zzePeP" \ | |
"caJ\x01WWWixMz" \ | |
"xjcAJ\x01WWWixMz" \ | |
"xycAJ\x01WWWixMz" \ | |
"J\x01WWWiceiJ\x02WWWWWdxMz" \ | |
"WiidWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW" \ | |
"ZcaZcbZcdZcccAJ\x03WWWWWWdxMiz" \ | |
"didididiZcfZckWididcGJ\x04zWWWiiWWWWdxMizdxMxA" \ | |
"c J\x02WWWWWxDMizdxMxAzx|" \ | |
"ccJ\x04WWWWWWWWWcoJ\x02WWWWx/iiiiiiiiiiiiiiii" \ | |
"x]c\x00J\x01WWWWWWr" | |
struct node { | |
char info; | |
struct node* ptr; | |
}* top, *top1, *temp; | |
char topelement(); | |
void push(char data); | |
char pop(); | |
int empty(); | |
void display(); | |
void destroy(); | |
int stack_count(); | |
void create(); | |
int vm(char* code); | |
char val(char* code, int pc); | |
int count = 0; | |
int winner = 0; | |
int main(int argc, char** argv) { | |
gfxInitDefault(); | |
// Initialize console on top screen. Using NULL as the second argument tells | |
// the console library to use the internal console structure as current one | |
consoleInit(GFX_TOP, NULL); | |
// Move the cursor to row 15 and column 19 and then prints "Hello World!" | |
// To move the cursor you have to print "\x1b[r;cH", where r and c are | |
// respectively | |
// the row and column where you want your cursor to move | |
// The top screen has 30 rows and 50 columns | |
// The bottom screen has 30 rows and 40 columns | |
create(); | |
vm(OPENSHiT); | |
if (winner == 100) { | |
printf("\x1b[15;19HWinner, please submit your flag!"); | |
} else { | |
printf("\x1b[15;19HGo adjust your 3d slider and try again!"); | |
} | |
printf("\x1b[29;15HPress Start to exit."); | |
// Main loop | |
while (aptMainLoop()) { | |
// Scan all the inputs. This should be done once for each frame | |
hidScanInput(); | |
// hidKeysDown returns information about which buttons have been just | |
// pressed (and they weren't in the previous frame) | |
u32 kDown = hidKeysDown(); | |
if (kDown & KEY_START) break; // break in order to return to hbmenu | |
// Flush and swap framebuffers | |
gfxFlushBuffers(); | |
gfxSwapBuffers(); | |
// Wait for VBlank | |
gspWaitForVBlank(); | |
} | |
gfxExit(); | |
return 0; | |
} | |
int vm(char* code) { | |
int pc = 0; | |
int eq = 0; | |
int zf = 0; | |
int num = 0; | |
int num2 = 0; | |
int ii = 0; | |
char str[1024] = {0}; | |
FILE* pFile; | |
for (;;) { | |
char instr = val(code, pc); | |
++pc; | |
switch (instr) { | |
case 'p': // push | |
num = val(code, pc); | |
push(num); | |
++pc; | |
break; | |
case 'P': // pop | |
num = pop(); | |
break; | |
case 'e': // push "isempty" | |
num = empty(); | |
push(num); | |
break; | |
case 'S': // push stack size | |
num = stack_count(); | |
push(num); | |
break; | |
case 'c': // cmp <val>, next thing on stack | |
num = val(code, pc); | |
num2 = pop(); | |
++pc; | |
if (num == num2) { | |
eq = 1; | |
} else { | |
eq = 0; | |
} | |
break; | |
case 'a': // add | |
num = val(code, pc); | |
num2 = pop(); | |
++pc; | |
push(num2 + num); | |
break; | |
case 's': // subtract | |
num = val(code, pc); | |
num2 = pop(); | |
++pc; | |
push(num2 - num); | |
break; | |
case 'g': // get from file | |
num = fgetc(pFile); | |
if (num == EOF) { | |
return 1; | |
} | |
push(num); | |
break; | |
case 'w': // write to stdout | |
num = pop(); | |
break; | |
case 'o': // open file | |
ii = 0; | |
do { | |
num = pop(); | |
str[ii] = num; | |
++ii; | |
} while (num != '\0'); | |
pFile = fopen(str, "r"); | |
for (ii = 0; ii < 1024; ++ii) { | |
str[ii] = '\0'; | |
} | |
break; | |
case 'r': // ret | |
return 0; | |
case 'j': // jump on equality | |
num = val(code, pc); | |
++pc; | |
if (eq) { | |
pc = pc + num; | |
} | |
break; | |
case 'J': // jump on not equality | |
num = val(code, pc); | |
++pc; | |
if (!eq) { | |
pc = pc + num; | |
} | |
case 'x': // xor | |
num = val(code, pc); | |
++pc; | |
num2 = pop(); | |
push(num ^ num2); | |
break; | |
case 'm': // multiply | |
num = val(code, pc); | |
++pc; | |
num2 = pop(); | |
push(num * num2); | |
break; | |
case 'z': // zwap | |
num = pop(); | |
num2 = pop(); | |
push(num); | |
push(num2); | |
break; | |
case 'i': // inc | |
num = pop(); | |
++num; | |
push(num); | |
break; | |
case 'd': // dec | |
num = pop(); | |
--num; | |
push(num); | |
break; | |
case 'W': // win | |
++winner; | |
break; | |
case '?': // close | |
fclose(pFile); | |
break; | |
case 'Z': // push zero | |
push('\0'); | |
break; | |
} | |
} | |
} | |
char val(char* code, int pc) { return code[pc]; } | |
// empty stack | |
void create() { top = NULL; } | |
// stack size | |
int stack_count() { return count; } | |
// pushes onto stack | |
void push(char data) { | |
if (top == NULL) { | |
top = (struct node*)malloc(1 * sizeof(struct node)); | |
top->ptr = NULL; | |
top->info = data; | |
} else { | |
temp = (struct node*)malloc(1 * sizeof(struct node)); | |
temp->ptr = top; | |
temp->info = data; | |
top = temp; | |
} | |
count++; | |
} | |
// prints for debugging | |
void display() { | |
top1 = top; | |
if (top1 == NULL) { | |
return; | |
} | |
while (top1 != NULL) { | |
top1 = top1->ptr; | |
} | |
} | |
// stack pop | |
char pop() { | |
char val; | |
top1 = top; | |
if (top1 == NULL) { | |
return; | |
} else { | |
top1 = top1->ptr; | |
} | |
val = top->info; | |
free(top); | |
top = top1; | |
count--; | |
return val; | |
} | |
// peek without popping | |
char topelement() { return (top->info); } | |
// isempty? | |
int empty() { return top == NULL ? 1 : 0; } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment