mirror of
https://github.com/sanni/cartreader.git
synced 2024-12-26 04:51:52 +01:00
813 lines
21 KiB
Arduino
813 lines
21 KiB
Arduino
|
/**********************************************************************************
|
||
|
Nintendo 64 Controller Test for Arduino Mega
|
||
|
|
||
|
Author: sanni
|
||
|
Date: 2016-04-15
|
||
|
Version: V2
|
||
|
|
||
|
OLED lib: http://www.rinkydinkelectronics.com/library.php?id=79
|
||
|
|
||
|
Thanks to:
|
||
|
Andrew Brown/Peter Den Hartog - N64 send/get functions
|
||
|
|
||
|
**********************************************************************************/
|
||
|
|
||
|
#include <OLED_I2C.h>
|
||
|
extern uint8_t SmallFont[];
|
||
|
|
||
|
// define LCD pins
|
||
|
OLED myOLED(SDA, SCL, 8);
|
||
|
|
||
|
//define LED pin
|
||
|
int ledPin = 10;
|
||
|
|
||
|
// These two macros toggle the eepDataPin/ControllerDataPin between input and output
|
||
|
// External 1K pull-up resistor from eepDataPin to VCC required
|
||
|
// 0x10 = 00010000 -> Port H Pin 4
|
||
|
#define N64_HIGH DDRH &= ~0x10
|
||
|
#define N64_LOW DDRH |= 0x10
|
||
|
// Read the current state(0/1) of the eepDataPin
|
||
|
#define N64_QUERY (PINH & 0x10)
|
||
|
|
||
|
// received Controller data
|
||
|
char N64_raw_dump[33]; // 1 received bit per byte
|
||
|
String rawStr = ""; // above char array read into a string
|
||
|
struct {
|
||
|
char stick_x;
|
||
|
char stick_y;
|
||
|
}
|
||
|
N64_status;
|
||
|
|
||
|
// on which screens do we start
|
||
|
int startscreen = 0;
|
||
|
int mode = 0;
|
||
|
int test = 1;
|
||
|
|
||
|
//stings that hold the buttons
|
||
|
String button = "N/A";
|
||
|
String lastbutton = "N/A";
|
||
|
|
||
|
//name of the current displayed result
|
||
|
String anastick = "";
|
||
|
|
||
|
// Graph
|
||
|
int xax = 22 + 24; // midpoint x
|
||
|
int yax = 24; // midpoint y
|
||
|
int zax = 24; // size
|
||
|
|
||
|
// variables to display test data of different sticks
|
||
|
int upx = 0;
|
||
|
int upy = 0;
|
||
|
int uprightx = 0;
|
||
|
int uprighty = 0;
|
||
|
int rightx = 0;
|
||
|
int righty = 0;
|
||
|
int downrightx = 0;
|
||
|
int downrighty = 0;
|
||
|
int downx = 0;
|
||
|
int downy = 0;
|
||
|
int downleftx = 0;
|
||
|
int downlefty = 0;
|
||
|
int leftx = 0;
|
||
|
int lefty = 0;
|
||
|
int upleftx = 0;
|
||
|
int uplefty = 0;
|
||
|
|
||
|
// variables to save test data
|
||
|
int bupx = 0;
|
||
|
int bupy = 0;
|
||
|
int buprightx = 0;
|
||
|
int buprighty = 0;
|
||
|
int brightx = 0;
|
||
|
int brighty = 0;
|
||
|
int bdownrightx = 0;
|
||
|
int bdownrighty = 0;
|
||
|
int bdownx = 0;
|
||
|
int bdowny = 0;
|
||
|
int bdownleftx = 0;
|
||
|
int bdownlefty = 0;
|
||
|
int bleftx = 0;
|
||
|
int blefty = 0;
|
||
|
int bupleftx = 0;
|
||
|
int buplefty = 0;
|
||
|
int results = 0;
|
||
|
|
||
|
void N64_send(unsigned char *buffer, char length);
|
||
|
void N64_get();
|
||
|
|
||
|
void setup()
|
||
|
{
|
||
|
// Communication with controller on this pin
|
||
|
// Don't remove these lines, we don't want to push +5V to the controller
|
||
|
// Output a low signal
|
||
|
PORTH &= ~(1 << 4);
|
||
|
// Set Controller Data Pin(PH4) to Input
|
||
|
DDRH &= ~(1 << 4);
|
||
|
|
||
|
// Led
|
||
|
pinMode(ledPin, OUTPUT);
|
||
|
|
||
|
// OLED
|
||
|
myOLED.begin();
|
||
|
myOLED.setFont(SmallFont);
|
||
|
}
|
||
|
|
||
|
// This sends the given byte sequence to the controller
|
||
|
// length must be at least 1
|
||
|
// Oh, it destroys the buffer passed in as it writes it
|
||
|
|
||
|
void N64_send(unsigned char *buffer, char length)
|
||
|
{
|
||
|
// Send these bytes
|
||
|
char bits;
|
||
|
|
||
|
bool bit;
|
||
|
|
||
|
// This routine is very carefully timed by examining the assembly output.
|
||
|
// Do not change any statements, it could throw the timings off
|
||
|
//
|
||
|
// We get 16 cycles per microsecond, which should be plenty, but we need to
|
||
|
// be conservative. Most assembly ops take 1 cycle, but a few take 2
|
||
|
//
|
||
|
// I use manually constructed for-loops out of gotos so I have more control
|
||
|
// over the outputted assembly. I can insert nops where it was impossible
|
||
|
// with a for loop
|
||
|
|
||
|
asm volatile (";Starting outer for loop");
|
||
|
outer_loop:
|
||
|
{
|
||
|
asm volatile (";Starting inner for loop");
|
||
|
bits = 8;
|
||
|
inner_loop:
|
||
|
{
|
||
|
// Starting a bit, set the line low
|
||
|
asm volatile (";Setting line to low");
|
||
|
N64_LOW; // 1 op, 2 cycles
|
||
|
|
||
|
asm volatile (";branching");
|
||
|
if (*buffer >> 7) {
|
||
|
asm volatile (";Bit is a 1");
|
||
|
// 1 bit
|
||
|
// remain low for 1us, then go high for 3us
|
||
|
// nop block 1
|
||
|
asm volatile ("nop\nnop\nnop\nnop\nnop\n");
|
||
|
|
||
|
asm volatile (";Setting line to high");
|
||
|
N64_HIGH;
|
||
|
|
||
|
// nop block 2
|
||
|
// we'll wait only 2us to sync up with both conditions
|
||
|
// at the bottom of the if statement
|
||
|
asm volatile ("nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
);
|
||
|
|
||
|
}
|
||
|
else {
|
||
|
asm volatile (";Bit is a 0");
|
||
|
// 0 bit
|
||
|
// remain low for 3us, then go high for 1us
|
||
|
// nop block 3
|
||
|
asm volatile ("nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\n");
|
||
|
|
||
|
asm volatile (";Setting line to high");
|
||
|
N64_HIGH;
|
||
|
|
||
|
// wait for 1us
|
||
|
asm volatile ("; end of conditional branch, need to wait 1us more before next bit");
|
||
|
|
||
|
}
|
||
|
// end of the if, the line is high and needs to remain
|
||
|
// high for exactly 16 more cycles, regardless of the previous
|
||
|
// branch path
|
||
|
|
||
|
asm volatile (";finishing inner loop body");
|
||
|
--bits;
|
||
|
if (bits != 0) {
|
||
|
// nop block 4
|
||
|
// this block is why a for loop was impossible
|
||
|
asm volatile ("nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\n");
|
||
|
// rotate bits
|
||
|
asm volatile (";rotating out bits");
|
||
|
*buffer <<= 1;
|
||
|
|
||
|
goto inner_loop;
|
||
|
} // fall out of inner loop
|
||
|
}
|
||
|
asm volatile (";continuing outer loop");
|
||
|
// In this case: the inner loop exits and the outer loop iterates,
|
||
|
// there are /exactly/ 16 cycles taken up by the necessary operations.
|
||
|
// So no nops are needed here (that was lucky!)
|
||
|
--length;
|
||
|
if (length != 0) {
|
||
|
++buffer;
|
||
|
goto outer_loop;
|
||
|
} // fall out of outer loop
|
||
|
}
|
||
|
|
||
|
// send a single stop (1) bit
|
||
|
// nop block 5
|
||
|
asm volatile ("nop\nnop\nnop\nnop\n");
|
||
|
N64_LOW;
|
||
|
// wait 1 us, 16 cycles, then raise the line
|
||
|
// 16-2=14
|
||
|
// nop block 6
|
||
|
asm volatile ("nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\n");
|
||
|
N64_HIGH;
|
||
|
|
||
|
}
|
||
|
|
||
|
void N64_get()
|
||
|
{
|
||
|
// listen for the expected 8 bytes of data back from the controller and
|
||
|
// blast it out to the N64_raw_dump array, one bit per byte for extra speed.
|
||
|
// Afterwards, call translate_raw_data() to interpret the raw data and pack
|
||
|
// it into the N64_status struct.
|
||
|
asm volatile (";Starting to listen");
|
||
|
unsigned char timeout;
|
||
|
char bitcount = 32;
|
||
|
char *bitbin = N64_raw_dump;
|
||
|
|
||
|
// Again, using gotos here to make the assembly more predictable and
|
||
|
// optimization easier (please don't kill me)
|
||
|
read_loop:
|
||
|
timeout = 0x3f;
|
||
|
// wait for line to go low
|
||
|
while (N64_QUERY) {
|
||
|
if (!--timeout)
|
||
|
return;
|
||
|
}
|
||
|
// wait approx 2us and poll the line
|
||
|
asm volatile (
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
"nop\nnop\nnop\nnop\nnop\n"
|
||
|
);
|
||
|
*bitbin = N64_QUERY;
|
||
|
++bitbin;
|
||
|
--bitcount;
|
||
|
if (bitcount == 0)
|
||
|
return;
|
||
|
|
||
|
// wait for line to go high again
|
||
|
// it may already be high, so this should just drop through
|
||
|
timeout = 0x3f;
|
||
|
while (!N64_QUERY) {
|
||
|
if (!--timeout)
|
||
|
return;
|
||
|
}
|
||
|
goto read_loop;
|
||
|
|
||
|
}
|
||
|
|
||
|
void get_button()
|
||
|
{
|
||
|
// Command to send to the gamecube
|
||
|
// The last bit is rumble, flip it to rumble
|
||
|
// yes this does need to be inside the loop, the
|
||
|
// array gets mutilated when it goes through N64_send
|
||
|
unsigned char command[] = {
|
||
|
0x01
|
||
|
};
|
||
|
|
||
|
// don't want interrupts getting in the way
|
||
|
noInterrupts();
|
||
|
// send those 3 bytes
|
||
|
N64_send(command, 1);
|
||
|
// read in data and dump it to N64_raw_dump
|
||
|
N64_get();
|
||
|
// end of time sensitive code
|
||
|
interrupts();
|
||
|
|
||
|
// The get_N64_status function sloppily dumps its data 1 bit per byte
|
||
|
// into the get_status_extended char array. It's our job to go through
|
||
|
// that and put each piece neatly into the struct N64_status
|
||
|
int i;
|
||
|
memset(&N64_status, 0, sizeof(N64_status));
|
||
|
|
||
|
// bits: joystick x value
|
||
|
// These are 8 bit values centered at 0x80 (128)
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
N64_status.stick_x |= N64_raw_dump[16 + i] ? (0x80 >> i) : 0;
|
||
|
}
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
N64_status.stick_y |= N64_raw_dump[24 + i] ? (0x80 >> i) : 0;
|
||
|
}
|
||
|
|
||
|
// read char array N64_raw_dump into string rawStr
|
||
|
rawStr = "";
|
||
|
for (i = 0; i < 16; i++) {
|
||
|
rawStr = rawStr + String(N64_raw_dump[i], DEC);
|
||
|
}
|
||
|
|
||
|
// Buttons (A,B,Z,S,DU,DD,DL,DR,0,0,L,R,CU,CD,CL,CR)
|
||
|
if (rawStr.substring(0, 16) == "0000000000000000") {
|
||
|
lastbutton = button;
|
||
|
button = "Press a button";
|
||
|
digitalWrite(ledPin, LOW);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
digitalWrite(ledPin, HIGH);
|
||
|
for (int i = 0; i < 16; i++)
|
||
|
{
|
||
|
// seems to be 16, 8 or 4 depending on what pin is used
|
||
|
if (N64_raw_dump[i] == 16)
|
||
|
{
|
||
|
switch (i)
|
||
|
{
|
||
|
case 7:
|
||
|
button = "D-Right";
|
||
|
break;
|
||
|
|
||
|
case 6:
|
||
|
button = "D-Left";
|
||
|
break;
|
||
|
|
||
|
case 5:
|
||
|
button = "D-Down";
|
||
|
break;
|
||
|
|
||
|
case 4:
|
||
|
button = "D-Up";
|
||
|
break;
|
||
|
|
||
|
case 3:
|
||
|
button = "START";
|
||
|
break;
|
||
|
|
||
|
case 2:
|
||
|
button = "Z";
|
||
|
break;
|
||
|
|
||
|
case 1:
|
||
|
button = "B";
|
||
|
break;
|
||
|
|
||
|
case 0:
|
||
|
button = "A";
|
||
|
break;
|
||
|
|
||
|
case 15:
|
||
|
button = "C-Right";
|
||
|
break;
|
||
|
|
||
|
case 14:
|
||
|
button = "C-Left";
|
||
|
break;
|
||
|
|
||
|
case 13:
|
||
|
button = "C-Down";
|
||
|
break;
|
||
|
|
||
|
case 12:
|
||
|
button = "C-Up";
|
||
|
break;
|
||
|
|
||
|
case 11:
|
||
|
button = "R";
|
||
|
break;
|
||
|
|
||
|
case 10:
|
||
|
button = "L";
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void printSTR(String st, int x, int y)
|
||
|
{
|
||
|
char buf[st.length() + 1];
|
||
|
|
||
|
st.toCharArray(buf, st.length() + 1);
|
||
|
myOLED.print(buf, x, y);
|
||
|
}
|
||
|
|
||
|
void nextscreen()
|
||
|
{
|
||
|
if (button == "Press a button" && lastbutton == "START")
|
||
|
{
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
if (startscreen != 4)
|
||
|
startscreen = startscreen + 1;
|
||
|
else
|
||
|
{
|
||
|
startscreen = 1;
|
||
|
test = 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void loop()
|
||
|
{
|
||
|
// Get Button and analog stick
|
||
|
get_button();
|
||
|
|
||
|
switch (startscreen)
|
||
|
{
|
||
|
case 0: // Logo Screen
|
||
|
{
|
||
|
myOLED.print("ControllerTest", CENTER, 8);
|
||
|
myOLED.print("V1.0", CENTER, 18);
|
||
|
myOLED.drawLine(22 + 0, 28, 22 + 84, 28);
|
||
|
myOLED.print("2013 sanni", CENTER, 32);
|
||
|
myOLED.update();
|
||
|
|
||
|
delay(1500);
|
||
|
startscreen = 1;
|
||
|
myOLED.clrScr();
|
||
|
break;
|
||
|
}
|
||
|
case 1:
|
||
|
{
|
||
|
myOLED.print("Button Test", CENTER, 0);
|
||
|
myOLED.drawLine(22 + 0, 10, 22 + 84, 10);
|
||
|
|
||
|
// Print Button
|
||
|
printSTR(" " + button + " ", CENTER, 20);
|
||
|
|
||
|
// Print Stick X Value
|
||
|
String stickx = String("X: " + String(N64_status.stick_x, DEC) + " ");
|
||
|
printSTR(stickx, 22 + 0, 38);
|
||
|
|
||
|
// Print Stick Y Value
|
||
|
String sticky = String("Y: " + String(N64_status.stick_y, DEC) + " ");
|
||
|
printSTR(sticky, 22 + 42, 38);
|
||
|
|
||
|
//Update LCD
|
||
|
myOLED.update();
|
||
|
|
||
|
// go to next screen
|
||
|
nextscreen();
|
||
|
break;
|
||
|
}
|
||
|
case 2:
|
||
|
{
|
||
|
myOLED.print("Range", 22 + 52, 5);
|
||
|
myOLED.print("Test", 22 + 52, 15);
|
||
|
myOLED.drawRect(22 + 50, 0, 22 + 83, 25);
|
||
|
|
||
|
// Print Stick X Value
|
||
|
String stickx = String("X:" + String(N64_status.stick_x, DEC) + " ");
|
||
|
printSTR(stickx, 22 + 50, 28);
|
||
|
|
||
|
// Print Stick Y Value
|
||
|
String sticky = String("Y:" + String(N64_status.stick_y, DEC) + " ");
|
||
|
printSTR(sticky, 22 + 50, 38);
|
||
|
|
||
|
// Draw Axis
|
||
|
myOLED.drawLine(xax - zax, yax, xax + zax, yax);
|
||
|
myOLED.drawLine(xax, yax - zax, xax, yax + zax);
|
||
|
myOLED.clrPixel(xax, yax - 80 / 4);
|
||
|
myOLED.clrPixel(xax, yax + 80 / 4);
|
||
|
myOLED.clrPixel(xax + 80 / 4, yax);
|
||
|
myOLED.clrPixel(xax - 80 / 4, yax);
|
||
|
|
||
|
//Draw Analog Stick
|
||
|
if (mode == 1)
|
||
|
{
|
||
|
myOLED.setPixel(xax + N64_status.stick_x / 4, yax - N64_status.stick_y / 4);
|
||
|
//Update LCD
|
||
|
myOLED.update();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
myOLED.drawCircle(xax + N64_status.stick_x / 4, yax - N64_status.stick_y / 4, 2);
|
||
|
//Update LCD
|
||
|
myOLED.update();
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
|
||
|
// switch mode
|
||
|
if (button == "Press a button" && lastbutton == "Z")
|
||
|
{
|
||
|
if (mode == 0)
|
||
|
{
|
||
|
mode = 1;
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
mode = 0;
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
}
|
||
|
// go to next screen
|
||
|
nextscreen();
|
||
|
break;
|
||
|
}
|
||
|
case 3:
|
||
|
{
|
||
|
myOLED.print("Skipping Test", CENTER, 0);
|
||
|
myOLED.drawLine(22 + 0, 10, 22 + 83, 10);
|
||
|
myOLED.drawRect(22 + 0, 20, 22 + 83, 44);
|
||
|
if (N64_status.stick_x > 0)
|
||
|
myOLED.drawLine(22 + N64_status.stick_x, 20, 22 + N64_status.stick_x, 44);
|
||
|
|
||
|
//Update LCD
|
||
|
myOLED.update();
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "Z")
|
||
|
{
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
// go to next screen
|
||
|
nextscreen();
|
||
|
break;
|
||
|
}
|
||
|
case 4:
|
||
|
{
|
||
|
switch ( test )
|
||
|
{
|
||
|
case 0: // Display results
|
||
|
{
|
||
|
switch (results)
|
||
|
{
|
||
|
case 0:
|
||
|
{
|
||
|
anastick = "YOURS";
|
||
|
upx = bupx;
|
||
|
upy = bupy;
|
||
|
uprightx = buprightx;
|
||
|
uprighty = buprighty;
|
||
|
rightx = brightx;
|
||
|
righty = brighty;
|
||
|
downrightx = bdownrightx;
|
||
|
downrighty = bdownrighty;
|
||
|
downx = bdownx;
|
||
|
downy = bdowny;
|
||
|
downleftx = bdownleftx;
|
||
|
downlefty = bdownlefty;
|
||
|
leftx = bleftx;
|
||
|
lefty = blefty;
|
||
|
upleftx = bupleftx;
|
||
|
uplefty = buplefty;
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
results = 1;
|
||
|
}
|
||
|
|
||
|
break;
|
||
|
}
|
||
|
case 1:
|
||
|
{
|
||
|
anastick = "ORIG";
|
||
|
upx = 1;
|
||
|
upy = 84;
|
||
|
uprightx = 67;
|
||
|
uprighty = 68;
|
||
|
rightx = 83;
|
||
|
righty = -2;
|
||
|
downrightx = 67;
|
||
|
downrighty = -69;
|
||
|
downx = 3;
|
||
|
downy = -85;
|
||
|
downleftx = -69;
|
||
|
downlefty = -70;
|
||
|
leftx = -85;
|
||
|
lefty = 0;
|
||
|
upleftx = -68;
|
||
|
uplefty = 68;
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
results = 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
} //results
|
||
|
myOLED.clrScr();
|
||
|
|
||
|
printSTR(anastick, 22 + 50, 0);
|
||
|
|
||
|
myOLED.print("U:", 22 + 50, 10);
|
||
|
myOLED.printNumI(upy, RIGHT, 10);
|
||
|
myOLED.print("D:", 22 + 50, 20);
|
||
|
myOLED.printNumI(downy, RIGHT, 20);
|
||
|
myOLED.print("L:", 22 + 50, 30);
|
||
|
myOLED.printNumI(leftx, RIGHT, 30);
|
||
|
myOLED.print("R:", 22 + 50, 40);
|
||
|
myOLED.printNumI(rightx, RIGHT, 40);
|
||
|
|
||
|
myOLED.drawLine(xax + upx / 4, yax - upy / 4, xax + uprightx / 4, yax - uprighty / 4);
|
||
|
myOLED.drawLine(xax + uprightx / 4, yax - uprighty / 4, xax + rightx / 4, yax - righty / 4);
|
||
|
myOLED.drawLine(xax + rightx / 4, yax - righty / 4, xax + downrightx / 4, yax - downrighty / 4);
|
||
|
myOLED.drawLine(xax + downrightx / 4, yax - downrighty / 4, xax + downx / 4, yax - downy / 4);
|
||
|
myOLED.drawLine(xax + downx / 4, yax - downy / 4, xax + downleftx / 4, yax - downlefty / 4);
|
||
|
myOLED.drawLine(xax + downleftx / 4, yax - downlefty / 4, xax + leftx / 4, yax - lefty / 4);
|
||
|
myOLED.drawLine(xax + leftx / 4, yax - lefty / 4, xax + upleftx / 4, yax - uplefty / 4);
|
||
|
myOLED.drawLine(xax + upleftx / 4, yax - uplefty / 4, xax + upx / 4, yax - upy / 4);
|
||
|
|
||
|
myOLED.setPixel(xax, yax);
|
||
|
|
||
|
//Update LCD
|
||
|
myOLED.update();
|
||
|
break;
|
||
|
} //display results
|
||
|
|
||
|
case 1:// +y Up
|
||
|
{
|
||
|
myOLED.print("Hold Stick Up", CENTER, 18);
|
||
|
myOLED.print("then press A", CENTER, 28);
|
||
|
//myOLED.drawBitmap(110, 60, ana1);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
bupx = N64_status.stick_x;
|
||
|
bupy = N64_status.stick_y;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
test = 2;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 2:// +y+x Up-Right
|
||
|
{
|
||
|
myOLED.print("Up-Right", CENTER, 22 );
|
||
|
//myOLED.drawBitmap(110, 60, ana2);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
buprightx = N64_status.stick_x;
|
||
|
buprighty = N64_status.stick_y;
|
||
|
test = 3;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 3:// +x Right
|
||
|
{
|
||
|
myOLED.print("Right", CENTER, 22 );
|
||
|
//myOLED.drawBitmap(110, 60, ana3);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
brightx = N64_status.stick_x;
|
||
|
brighty = N64_status.stick_y;
|
||
|
test = 4;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 4:// -y+x Down-Right
|
||
|
{
|
||
|
myOLED.print("Down-Right", CENTER, 22 );
|
||
|
//myOLED.drawBitmap(110, 60, ana4);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
bdownrightx = N64_status.stick_x;
|
||
|
bdownrighty = N64_status.stick_y;
|
||
|
test = 5;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 5:// -y Down
|
||
|
{
|
||
|
myOLED.print("Down", CENTER, 22 );
|
||
|
//myOLED.drawBitmap(110, 60, ana5);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
bdownx = N64_status.stick_x;
|
||
|
bdowny = N64_status.stick_y;
|
||
|
test = 6;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 6:// -y-x Down-Left
|
||
|
{
|
||
|
myOLED.print("Down-Left", CENTER, 22 );
|
||
|
//myOLED.drawBitmap(110, 60, ana6);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
bdownleftx = N64_status.stick_x;
|
||
|
bdownlefty = N64_status.stick_y;
|
||
|
test = 7;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 7:// -x Left
|
||
|
{
|
||
|
myOLED.print("Left", CENTER, 22 );
|
||
|
//myOLED.drawBitmap(110, 60, ana7);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
bleftx = N64_status.stick_x;
|
||
|
blefty = N64_status.stick_y;
|
||
|
test = 8;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
case 8:// +y+x Up-Left
|
||
|
{
|
||
|
myOLED.print("Up-Left", CENTER, 22);
|
||
|
//myOLED.drawBitmap(110, 60, ana8);
|
||
|
|
||
|
if (button == "Press a button" && lastbutton == "A")
|
||
|
{
|
||
|
bupleftx = N64_status.stick_x;
|
||
|
buplefty = N64_status.stick_y;
|
||
|
test = 0;
|
||
|
// reset button
|
||
|
lastbutton = "N/A";
|
||
|
|
||
|
myOLED.clrScr();
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
if (test != 0)
|
||
|
{
|
||
|
myOLED.print("Benchmark", CENTER, 0);
|
||
|
myOLED.drawLine(22 + 0, 9, 22 + 83, 9);
|
||
|
}
|
||
|
myOLED.update();
|
||
|
// go to next screen
|
||
|
nextscreen();
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|