Compare commits
No commits in common. "master" and "1.0" have entirely different histories.
|
@ -1,4 +0,0 @@
|
|||
release
|
||||
*.hex
|
||||
*.elf
|
||||
GNUmakefile
|
17
ISSUES.txt
17
ISSUES.txt
|
@ -1,17 +0,0 @@
|
|||
Outstanding
|
||||
-----------
|
||||
|
||||
|
||||
|
||||
Fixed
|
||||
-----
|
||||
|
||||
1. Scores should not go negative
|
||||
2. Konami Code position doesn't reset on non-sequence button
|
||||
3. It is too easy to mess up scores when adjusting period clock time
|
||||
4. Period clock adjustments take forever
|
||||
5. Make setup mode less confusing
|
||||
6. Allow jam clock adjustments in setup
|
||||
7. Unified build with multiple firmware targets
|
||||
8. Debounce buttons
|
||||
9. Pull-up NES data to prevent going apeshit when you unplug the controller
|
19
LICENSE.txt
19
LICENSE.txt
|
@ -1,19 +0,0 @@
|
|||
Copyright © 2014 Neale Pickett <neale@woozle.org>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
The software is provided "as is", without warranty of any kind, express or
|
||||
implied, including but not limited to the warranties of merchantability,
|
||||
fitness for a particular purpose and noninfringement. In no event shall the
|
||||
authors or copyright holders be liable for any claim, damages or other
|
||||
liability, whether in an action of contract, tort or otherwise, arising from,
|
||||
out of or in connection with the software or the use or other dealings in
|
||||
the software.
|
53
Makefile
53
Makefile
|
@ -1,7 +1,4 @@
|
|||
TARGETS += scoreboard-neale.hex
|
||||
TARGETS += scoreboard-susan1.hex
|
||||
TARGETS += scoreboard-susan2.hex
|
||||
TARGETS += scoreboard-std.hex
|
||||
PROG = main
|
||||
|
||||
MCU = attiny84
|
||||
|
||||
|
@ -12,34 +9,34 @@ CFLAGS += -w
|
|||
|
||||
LDFLAGS += -mmcu=$(MCU)
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
scoreboard-%.elf: main.c avr.c config.h avr.h
|
||||
$(CC) $(CFLAGS) -DVARIANT=$* $(LDFLAGS) -o $@ avr.c main.c
|
||||
|
||||
%.hex: %.elf
|
||||
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
|
||||
|
||||
clean:
|
||||
rm -f *.elf *.o *.hex .upload
|
||||
|
||||
|
||||
|
||||
##
|
||||
## Helpful targets for development
|
||||
##
|
||||
|
||||
VARIANT = neale
|
||||
|
||||
AVDFLAGS += -p $(MCU)
|
||||
AVDFLAGS += -c usbtiny
|
||||
|
||||
upload: scoreboard-$(VARIANT).hex
|
||||
avrdude $(AVDFLAGS) -U flash:w:$<
|
||||
FUSES += -U lfuse:w:0x7f:m
|
||||
FUSES += -U hfuse:w:0xdd:m
|
||||
FUSES += -U efuse:w:0xff:m
|
||||
|
||||
upload: .upload
|
||||
|
||||
.upload: $(PROG).hex
|
||||
avrdude $(AVDFLAGS) -U flash:w:$<
|
||||
touch $@
|
||||
|
||||
fuses: FUSES += -U lfuse:w:0x7f:m
|
||||
fuses: FUSES += -U hfuse:w:0xdd:m
|
||||
fuses: FUSES += -U efuse:w:0xff:m
|
||||
fuses:
|
||||
avrdude $(AVDFLAGS) $(FUSES)
|
||||
|
||||
main: main.o avr.o
|
||||
|
||||
blink: blink.o avr.o
|
||||
|
||||
avr.o: avr.c config.h
|
||||
|
||||
%.hex: %
|
||||
avr-objcopy -O ihex -R .eeprom -R .fuse -R .lock -R .signature $< $@
|
||||
|
||||
clean:
|
||||
rm -f $(PROG) *.o *.hex .upload
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
50
README.md
50
README.md
|
@ -1,50 +0,0 @@
|
|||
LED Roller Derby Scoreboard
|
||||
===========================
|
||||
|
||||
A do-it-yourself LED Roller Derby scoreboard.
|
||||
It's visible in full sunlight,
|
||||
doesn't use a computer at all,
|
||||
and can be easily operated by an 8-year-old.
|
||||
|
||||
If you're looking for a software scoreboard (using a projector)
|
||||
this [list of free derby scoreboard software](http://woozle.org/scoreboard/others.html) will help.
|
||||
|
||||
This scoreboard is operated with a Nintendo controller,
|
||||
and runs on an XBox 360 power supply.
|
||||
The rest of the parts need to be ordered from various sources online.
|
||||
The total should come out to around $200,
|
||||
with plenty of options for upgrades.
|
||||
|
||||
It will take about 6 weeks of work,
|
||||
and requires basic electronics understanding and
|
||||
elementary soldering skills.
|
||||
I provide updated firmware,
|
||||
so unless you feel like modifying the MIT-licensed source code,
|
||||
you don't need to do any programming.
|
||||
|
||||
![Original Build](https://lh3.googleusercontent.com/-xKiVBp0bv70/UuafY7lZxeI/AAAAAAAAd1g/6TlMNSDp9xc/s1600/IMG_20140125_094136.jpg)
|
||||
|
||||
![First duplicate](https://lh5.googleusercontent.com/-Mm23bx2F-wQ/Uip4SGmmzWI/AAAAAAAAMKI/48zmiHN6v6U/s1600/13%2B-%2B1)
|
||||
|
||||
![Second duplicate](https://lh6.googleusercontent.com/-hOKmDB5JRYY/UtXPLuY2bDI/AAAAAAAAdpE/PYxeqHQGxTA/s1600/2014-01-14)
|
||||
|
||||
|
||||
Resources
|
||||
---------
|
||||
|
||||
* [Discussion Group](https://groups.google.com/forum/#!forum/scoreboard-builders) for help from others who've built or are building one.
|
||||
* [Google Drive Folder](https://drive.google.com/folderview?id=0BzovkpI6mzWQNFc4eGN0aGoyTGM&usp=sharing) with
|
||||
schematics, documentation, and firmware releases.
|
||||
* [Firmware Source Code](https://woozle.org/neale/g.cgi/derby/hw-scoreboard)
|
||||
|
||||
|
||||
About Me
|
||||
--------
|
||||
|
||||
I'm Neale Pickett,
|
||||
also known as "Q" in the Derby world.
|
||||
Feel free to [email me](mailto:neale@woozle.org),
|
||||
but the group would be more appropriate for email relating to this scoreboard.
|
||||
|
||||
I've done a lot of [other derby stuff](/derby/)
|
||||
that you may be interested in.
|
8
avr.c
8
avr.c
|
@ -23,7 +23,7 @@ ISR(TIM1_COMPA_vect)
|
|||
}
|
||||
|
||||
void
|
||||
avr_init(void)
|
||||
init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -39,13 +39,7 @@ avr_init(void)
|
|||
TCCR1B |= _BV(CS11) | _BV(CS10); // prescale: clk_io / 64
|
||||
TIMSK1 |= _BV(OCIE1A);
|
||||
|
||||
// Pull-up NES data line
|
||||
bit(PORTA, _BV(NESOUT), true);
|
||||
|
||||
// Turn on Power Supply
|
||||
bit(PORTA, _BV(7), true);
|
||||
|
||||
PORTB = 0xff;
|
||||
|
||||
sei();
|
||||
}
|
||||
|
|
2
avr.h
2
avr.h
|
@ -15,6 +15,6 @@
|
|||
#define nesltch(on) bit(PORTA, _BV(NESLTCH), on)
|
||||
#define nesout() ((PINA & _BV(NESOUT)) << NESOUT)
|
||||
|
||||
void avr_init(void);
|
||||
void init(void);
|
||||
|
||||
#endif
|
||||
|
|
89
config.h
89
config.h
|
@ -4,13 +4,14 @@
|
|||
#define CLOCK_MHZ 16
|
||||
#define CLOCK_HZ (CLOCK_MHZ * 1000000)
|
||||
|
||||
#define LINEUP_DEFAULT (-30 * 10)
|
||||
#define JAM_DEFAULT (-2 * 60 * 10)
|
||||
#define PERIOD_DEFAULT (-30 * 60 * 10)
|
||||
#define SCORE_DIGITS 2
|
||||
#define JAM_DIGITS 3
|
||||
|
||||
// TPIC uses weird pin names
|
||||
#define SRCK SCLK
|
||||
#define RCK SLTCH
|
||||
// Show an indicator (J/L/t) to the left of the jam clock
|
||||
//#define JAM_INDICATOR
|
||||
|
||||
// The jam clock is split across the period clock (easier folding, harder wiring)
|
||||
//#define JAM_SPLIT
|
||||
|
||||
// Set these to the PORTA pins you use
|
||||
#define NESCLK 0
|
||||
|
@ -20,80 +21,4 @@
|
|||
#define SCLK 4
|
||||
#define SLTCH 5
|
||||
|
||||
#define JAM_DIGITS 3
|
||||
|
||||
#define std 0
|
||||
#define neale 1
|
||||
#define susan1 2
|
||||
#define susan2 3
|
||||
#define robbie 3
|
||||
|
||||
#if VARIANT == neale
|
||||
//
|
||||
// Neale variant
|
||||
//
|
||||
// With Jam indicator, split jam clock, and only 2 score digits.
|
||||
// Also featuring goofy brain wiring.
|
||||
//
|
||||
|
||||
#define SCORE_DIGITS 2
|
||||
#define JAM_INDICATOR
|
||||
#define JAM_SPLIT
|
||||
|
||||
// I wired mine differently and I'm too lazy to fix it.
|
||||
#undef NESCLK
|
||||
#undef NESLTCH
|
||||
#undef NESOUT
|
||||
#undef SIN
|
||||
#undef SCLK
|
||||
#undef SLTCH
|
||||
|
||||
#define SIN 0
|
||||
#define SCLK 1
|
||||
#define SLTCH 2
|
||||
#define NESCLK 3
|
||||
#define NESLTCH 4
|
||||
#define NESOUT 5
|
||||
|
||||
|
||||
|
||||
#elif VARIANT == susan1
|
||||
//
|
||||
// Susan 1 variant
|
||||
//
|
||||
// Like the neale variant but with correct brain wiring
|
||||
//
|
||||
|
||||
|
||||
#define SCORE_DIGITS 2
|
||||
#define JAM_INDICATOR
|
||||
#define JAM_SPLIT
|
||||
|
||||
|
||||
|
||||
#elif VARIANT == susan2
|
||||
//
|
||||
// Susan 2 variant
|
||||
//
|
||||
|
||||
|
||||
#define SCORE_DIGITS 3
|
||||
|
||||
|
||||
#else
|
||||
//
|
||||
// Default variant
|
||||
//
|
||||
// Nobody has built this yet!
|
||||
// But it's the one described by the instructions.
|
||||
//
|
||||
|
||||
|
||||
#define SCORE_DIGITS 3
|
||||
#define JAM_SPLIT
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,136 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="129.57692"
|
||||
height="209.82599"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="controller-conn.svg">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.83718329"
|
||||
inkscape:cx="49.790255"
|
||||
inkscape:cy="119.40543"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1259"
|
||||
inkscape:window-height="839"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-298.3437,-356.56045)">
|
||||
<path
|
||||
style="fill:none;stroke:#000000;stroke-width:20;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
d="m 308.43035,525.01817 c 0.0224,12.61936 10.90299,30.79285 29.01664,31.18674 18.11366,0.3939 46.59996,0.14703 57.65053,-1.01178 12.80286,-1.34256 22.45738,-21.53441 22.52553,-31.36944 0,0 0.64469,-87.18796 0,-91.56654 -0.64469,-4.37857 -13.29505,-15.39673 -28.53212,-31.75759 -15.23706,-16.36086 -25.30565,-33.68303 -48.51772,-33.94468 -17.74986,-0.20008 -31.03771,23.34467 -31.76769,28.18425 -0.72997,4.83959 -0.37517,130.27904 -0.37517,130.27904 z"
|
||||
id="path3050"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="szsszsszs" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3820"
|
||||
sodipodi:cx="342.81619"
|
||||
sodipodi:cy="402.56421"
|
||||
sodipodi:rx="8.361371"
|
||||
sodipodi:ry="8.6599913"
|
||||
d="m 351.17756,402.56421 c 0,4.78278 -3.74351,8.65999 -8.36137,8.65999 -4.61786,0 -8.36137,-3.87721 -8.36137,-8.65999 0,-4.78278 3.74351,-8.65999 8.36137,-8.65999 4.61786,0 8.36137,3.87721 8.36137,8.65999 z"
|
||||
transform="matrix(1.335243,0,0,1.335243,-114.92672,-134.95682)" />
|
||||
<path
|
||||
transform="matrix(1.335243,0,0,1.335243,-114.6281,-95.538929)"
|
||||
d="m 351.17756,402.56421 c 0,4.78278 -3.74351,8.65999 -8.36137,8.65999 -4.61786,0 -8.36137,-3.87721 -8.36137,-8.65999 0,-4.78278 3.74351,-8.65999 8.36137,-8.65999 4.61786,0 8.36137,3.87721 8.36137,8.65999 z"
|
||||
sodipodi:ry="8.6599913"
|
||||
sodipodi:rx="8.361371"
|
||||
sodipodi:cy="402.56421"
|
||||
sodipodi:cx="342.81619"
|
||||
id="path3822"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3824"
|
||||
sodipodi:cx="342.81619"
|
||||
sodipodi:cy="402.56421"
|
||||
sodipodi:rx="8.361371"
|
||||
sodipodi:ry="8.6599913"
|
||||
d="m 351.17756,402.56421 c 0,4.78278 -3.74351,8.65999 -8.36137,8.65999 -4.61786,0 -8.36137,-3.87721 -8.36137,-8.65999 0,-4.78278 3.74351,-8.65999 8.36137,-8.65999 4.61786,0 8.36137,3.87721 8.36137,8.65999 z"
|
||||
transform="matrix(1.335243,0,0,1.335243,-114.92672,-55.523797)" />
|
||||
<path
|
||||
transform="matrix(1.335243,0,0,1.335243,-114.6281,-15.508665)"
|
||||
d="m 351.17756,402.56421 c 0,4.78278 -3.74351,8.65999 -8.36137,8.65999 -4.61786,0 -8.36137,-3.87721 -8.36137,-8.65999 0,-4.78278 3.74351,-8.65999 8.36137,-8.65999 4.61786,0 8.36137,3.87721 8.36137,8.65999 z"
|
||||
sodipodi:ry="8.6599913"
|
||||
sodipodi:rx="8.361371"
|
||||
sodipodi:cy="402.56421"
|
||||
sodipodi:cx="342.81619"
|
||||
id="path3826"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3828"
|
||||
sodipodi:cx="342.81619"
|
||||
sodipodi:cy="402.56421"
|
||||
sodipodi:rx="8.361371"
|
||||
sodipodi:ry="8.6599913"
|
||||
d="m 351.17756,402.56421 c 0,4.78278 -3.74351,8.65999 -8.36137,8.65999 -4.61786,0 -8.36137,-3.87721 -8.36137,-8.65999 0,-4.78278 3.74351,-8.65999 8.36137,-8.65999 4.61786,0 8.36137,3.87721 8.36137,8.65999 z"
|
||||
transform="matrix(1.335243,0,0,1.335243,-74.314347,-94.344447)" />
|
||||
<path
|
||||
transform="matrix(1.335243,0,0,1.335243,-74.612967,-54.329315)"
|
||||
d="m 351.17756,402.56421 c 0,4.78278 -3.74351,8.65999 -8.36137,8.65999 -4.61786,0 -8.36137,-3.87721 -8.36137,-8.65999 0,-4.78278 3.74351,-8.65999 8.36137,-8.65999 4.61786,0 8.36137,3.87721 8.36137,8.65999 z"
|
||||
sodipodi:ry="8.6599913"
|
||||
sodipodi:rx="8.361371"
|
||||
sodipodi:cy="402.56421"
|
||||
sodipodi:cx="342.81619"
|
||||
id="path3830"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
sodipodi:type="arc" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:none;stroke:#000000;stroke-width:10;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3832"
|
||||
sodipodi:cx="342.81619"
|
||||
sodipodi:cy="402.56421"
|
||||
sodipodi:rx="8.361371"
|
||||
sodipodi:ry="8.6599913"
|
||||
d="m 351.17756,402.56421 c 0,4.78278 -3.74351,8.65999 -8.36137,8.65999 -4.61786,0 -8.36137,-3.87721 -8.36137,-8.65999 0,-4.78278 3.74351,-8.65999 8.36137,-8.65999 4.61786,0 8.36137,3.87721 8.36137,8.65999 z"
|
||||
transform="matrix(1.335243,0,0,1.335243,-74.314347,-14.314183)" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 6.5 KiB |
217
controller.svg
217
controller.svg
|
@ -1,217 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="744.09448819"
|
||||
height="1052.3622047"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="New document 1">
|
||||
<defs
|
||||
id="defs4" />
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="418.97372"
|
||||
inkscape:cy="520"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1436"
|
||||
inkscape:window-height="882"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="14"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1">
|
||||
<rect
|
||||
style="fill:#e0cece;fill-opacity:1;fill-rule:nonzero;"
|
||||
id="rect3050"
|
||||
width="600"
|
||||
height="259.28571"
|
||||
x="67.14286"
|
||||
y="400.93362"
|
||||
ry="1.9140695" />
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero"
|
||||
id="rect3052"
|
||||
width="561.42859"
|
||||
height="199.28572"
|
||||
x="85.714287"
|
||||
y="442.36218"
|
||||
ry="1.9140695" />
|
||||
<rect
|
||||
style="fill:#e0cece;fill-opacity:1;fill-rule:nonzero;"
|
||||
id="rect3084"
|
||||
width="169.28572"
|
||||
height="58.57143"
|
||||
x="262.14285"
|
||||
y="556.64789"
|
||||
ry="1.9140695" />
|
||||
<g
|
||||
id="g3094">
|
||||
<rect
|
||||
ry="1.9140695"
|
||||
y="497.36218"
|
||||
x="150"
|
||||
height="115"
|
||||
width="45.714287"
|
||||
id="rect3090"
|
||||
style="fill:#e0cece;fill-opacity:1;fill-rule:nonzero" />
|
||||
<rect
|
||||
transform="matrix(0,1,-1,0,0,0)"
|
||||
style="fill:#e0cece;fill-opacity:1;fill-rule:nonzero"
|
||||
id="rect3092"
|
||||
width="45.714287"
|
||||
height="115"
|
||||
x="532.00507"
|
||||
y="-230.35715"
|
||||
ry="1.9140695" />
|
||||
</g>
|
||||
<g
|
||||
id="g3072">
|
||||
<rect
|
||||
ry="1.9140695"
|
||||
y="548.79077"
|
||||
x="457.85715"
|
||||
height="65.714287"
|
||||
width="65"
|
||||
id="rect3054"
|
||||
style="fill:#e0cece;fill-opacity:1;fill-rule:nonzero" />
|
||||
<path
|
||||
transform="translate(-75,0)"
|
||||
d="m 592.14287,582.36218 a 26.428572,26.428572 0 1 1 -52.85715,0 26.428572,26.428572 0 1 1 52.85715,0 z"
|
||||
sodipodi:ry="26.428572"
|
||||
sodipodi:rx="26.428572"
|
||||
sodipodi:cy="582.36218"
|
||||
sodipodi:cx="565.71429"
|
||||
id="path3060"
|
||||
style="fill:#d40000;fill-opacity:1;fill-rule:nonzero"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
<g
|
||||
id="g3076"
|
||||
transform="translate(75,0)">
|
||||
<rect
|
||||
style="fill:#e0cece;fill-opacity:1;fill-rule:nonzero"
|
||||
id="rect3078"
|
||||
width="65"
|
||||
height="65.714287"
|
||||
x="457.85715"
|
||||
y="548.79077"
|
||||
ry="1.9140695" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:#d40000;fill-opacity:1;fill-rule:nonzero"
|
||||
id="path3080"
|
||||
sodipodi:cx="565.71429"
|
||||
sodipodi:cy="582.36218"
|
||||
sodipodi:rx="26.428572"
|
||||
sodipodi:ry="26.428572"
|
||||
d="m 592.14287,582.36218 c 0,14.5961 -11.83248,26.42857 -26.42858,26.42857 -14.59609,0 -26.42857,-11.83247 -26.42857,-26.42857 0,-14.59609 11.83248,-26.42857 26.42857,-26.42857 14.5961,0 26.42858,11.83248 26.42858,26.42857 z"
|
||||
transform="translate(-75,0)" />
|
||||
</g>
|
||||
<rect
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero"
|
||||
id="rect3086"
|
||||
width="49.285713"
|
||||
height="18.571428"
|
||||
x="286.42856"
|
||||
y="577.36218"
|
||||
ry="1.9140695"
|
||||
rx="7" />
|
||||
<rect
|
||||
rx="7"
|
||||
ry="1.9140695"
|
||||
y="577.36218"
|
||||
x="358.57141"
|
||||
height="18.571428"
|
||||
width="49.285713"
|
||||
id="rect3088"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero" />
|
||||
<g
|
||||
id="g3102"
|
||||
transform="translate(-0.35713959,-1.0714188)">
|
||||
<rect
|
||||
ry="1.9140695"
|
||||
y="501.64789"
|
||||
x="152.85715"
|
||||
height="108.57143"
|
||||
width="40.714287"
|
||||
id="rect3098"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero" />
|
||||
<rect
|
||||
transform="matrix(0,1,-1,0,0,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:nonzero"
|
||||
id="rect3100"
|
||||
width="40.714287"
|
||||
height="108.57143"
|
||||
x="535.57648"
|
||||
y="-227.5"
|
||||
ry="1.9140695" />
|
||||
</g>
|
||||
<rect
|
||||
style="fill:#76745b;fill-opacity:1;fill-rule:nonzero"
|
||||
id="rect3106"
|
||||
width="170.71428"
|
||||
height="28.571428"
|
||||
x="261.42856"
|
||||
y="515.93365"
|
||||
ry="1.9140695"
|
||||
rx="2" />
|
||||
<rect
|
||||
rx="2"
|
||||
ry="1.9140695"
|
||||
y="442.36221"
|
||||
x="261.42856"
|
||||
height="28.571428"
|
||||
width="170.71428"
|
||||
id="rect3108"
|
||||
style="fill:#76745b;fill-opacity:1;fill-rule:nonzero" />
|
||||
<rect
|
||||
style="fill:#76745b;fill-opacity:1;fill-rule:nonzero"
|
||||
id="rect3110"
|
||||
width="170.71428"
|
||||
height="28.571428"
|
||||
x="261.42856"
|
||||
y="478.79077"
|
||||
ry="1.9140695"
|
||||
rx="2" />
|
||||
<rect
|
||||
rx="2"
|
||||
ry="1.9140695"
|
||||
y="623.79077"
|
||||
x="261.42856"
|
||||
height="17.857143"
|
||||
width="170.71428"
|
||||
id="rect3112"
|
||||
style="fill:#76745b;fill-opacity:1;fill-rule:nonzero" />
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 6.0 KiB |
137
main.c
137
main.c
|
@ -21,20 +21,21 @@
|
|||
volatile uint32_t jiffies = 0; // Elapsed time in deciseconds (tenths of a second)
|
||||
volatile bool tick = false; // Set high when jiffy clock ticks
|
||||
|
||||
|
||||
// Clocks are in deciseconds
|
||||
int16_t score_a = 0;
|
||||
int16_t score_b = 0;
|
||||
int16_t period_clock = PERIOD_DEFAULT;
|
||||
int16_t jam_duration = JAM_DEFAULT;
|
||||
int16_t lineup_duration = LINEUP_DEFAULT;
|
||||
int16_t jam_clock = JAM_DEFAULT;
|
||||
uint16_t score_a = 0;
|
||||
uint16_t score_b = 0;
|
||||
int16_t period_clock = -(30 * 60 * 10);
|
||||
int16_t jam_duration = -(2 * 60 * 10);
|
||||
int16_t lineup_duration = (-30 * 10);
|
||||
int16_t jam_clock = 0;
|
||||
enum {
|
||||
TIMEOUT = 0,
|
||||
SETUP = 0,
|
||||
JAM,
|
||||
LINEUP,
|
||||
TIMEOUT,
|
||||
KONAMI
|
||||
} state = TIMEOUT;
|
||||
bool setup = true;
|
||||
} state = SETUP;
|
||||
|
||||
|
||||
// NES Controller buttons
|
||||
|
@ -64,17 +65,17 @@ const uint8_t seven_segment_digits[] = {
|
|||
0x7b, 0x60, 0x37, 0x76, 0x6c, 0x5e, 0x5f, 0x70, 0x7f, 0x7e
|
||||
};
|
||||
|
||||
const uint8_t setup_digits[] = {
|
||||
// [ = ]
|
||||
0x1b, 0x12, 0x72
|
||||
};
|
||||
|
||||
// keyed by state
|
||||
const uint8_t indicator[] = {
|
||||
// t, J, L, -
|
||||
0x0f, 0x63, 0x0b, 0x04
|
||||
// '' J L T -
|
||||
0x00, 0x63, 0x0b, 0x0f, 0x04
|
||||
};
|
||||
|
||||
#define max(a, b) ((a)>(b)?(a):(b))
|
||||
#define min(a, b) ((a)<(b)?(a):(b))
|
||||
|
||||
|
||||
void
|
||||
latch()
|
||||
{
|
||||
|
@ -153,6 +154,11 @@ write_pclock()
|
|||
write(0);
|
||||
write(0);
|
||||
write(0);
|
||||
} else if (state == SETUP) {
|
||||
write(setup_digits[2]);
|
||||
write(setup_digits[1]);
|
||||
write(setup_digits[1]);
|
||||
write(setup_digits[0]);
|
||||
} else {
|
||||
write_num(pclk, 4);
|
||||
}
|
||||
|
@ -232,40 +238,20 @@ nesprobe()
|
|||
void
|
||||
update_controller()
|
||||
{
|
||||
static uint8_t last_held = 0;
|
||||
static uint8_t last_val = 0;
|
||||
static uint32_t last_change = 0;
|
||||
static uint32_t last_typematic = 0;
|
||||
uint8_t held;
|
||||
uint8_t cur;
|
||||
uint8_t pressed;
|
||||
int typematic = 0;
|
||||
int inc = 1;
|
||||
|
||||
held = nesprobe();
|
||||
pressed = (last_held ^ held) & held;
|
||||
|
||||
// Set up typematic acceleration
|
||||
if (last_held != held) {
|
||||
// Debounce
|
||||
if (last_change == jiffies) {
|
||||
return;
|
||||
}
|
||||
cur = nesprobe();
|
||||
pressed = (last_val ^ cur) & cur;
|
||||
if (last_val != cur) {
|
||||
last_change = jiffies;
|
||||
last_typematic = jiffies;
|
||||
last_held = held;
|
||||
typematic = 1;
|
||||
} else if (jiffies > last_typematic) {
|
||||
last_typematic = jiffies;
|
||||
if (jiffies - last_change < 6) {
|
||||
typematic = 0;
|
||||
} else if (jiffies - last_change < 40) {
|
||||
typematic = 1;
|
||||
} else if (jiffies - last_change < 80) {
|
||||
typematic = 10;
|
||||
} else {
|
||||
typematic = 20;
|
||||
}
|
||||
last_val = cur;
|
||||
}
|
||||
|
||||
|
||||
if (pressed == konami_code[konami_pos]) {
|
||||
konami_pos += 1;
|
||||
|
||||
|
@ -276,21 +262,11 @@ update_controller()
|
|||
} else if (konami_pos > 3) {
|
||||
return;
|
||||
}
|
||||
} else if (pressed) {
|
||||
konami_pos = 0;
|
||||
}
|
||||
// Select means subtract
|
||||
if (held & BTN_SELECT) {
|
||||
if (cur & BTN_SELECT) {
|
||||
inc = -1;
|
||||
}
|
||||
|
||||
if (setup && (held & BTN_START) && (pressed & BTN_SELECT)) {
|
||||
jam_duration += 30 * 10;
|
||||
if (jam_duration > -60 * 10) {
|
||||
jam_duration = -120 * 10;
|
||||
}
|
||||
jam_clock = jam_duration;
|
||||
}
|
||||
|
||||
if ((pressed & BTN_A) && ((state != JAM) || (jam_clock == 0))) {
|
||||
state = JAM;
|
||||
|
@ -307,31 +283,27 @@ update_controller()
|
|||
jam_clock = 1;
|
||||
}
|
||||
|
||||
if ((held & BTN_START) && (state == TIMEOUT)) {
|
||||
if (held & BTN_UP) {
|
||||
period_clock -= typematic * 10;
|
||||
if ((state == TIMEOUT) || (state == SETUP)) {
|
||||
uint8_t v = pressed;
|
||||
|
||||
if ((jiffies - last_change > 10) && (last_typematic < jiffies)) {
|
||||
v = cur;
|
||||
last_typematic = jiffies;
|
||||
}
|
||||
if (held & BTN_DOWN) {
|
||||
period_clock += typematic * 10;
|
||||
if (v & BTN_UP) {
|
||||
period_clock -= 10;
|
||||
}
|
||||
|
||||
period_clock = min(period_clock, 0);
|
||||
period_clock = max(period_clock, -90 * 30 * 10);
|
||||
} else {
|
||||
// Score adjustment and clock adjustment are mutually exclusive
|
||||
if (held & BTN_LEFT) {
|
||||
score_a += typematic * inc;
|
||||
score_a = max(score_a, 0);
|
||||
}
|
||||
|
||||
if (held & BTN_RIGHT) {
|
||||
score_b += typematic * inc;
|
||||
score_b = max(score_b, 0);
|
||||
if (v & BTN_DOWN) {
|
||||
period_clock += 10;
|
||||
}
|
||||
}
|
||||
|
||||
if (state != TIMEOUT) {
|
||||
setup = false;
|
||||
|
||||
if (pressed & BTN_LEFT) {
|
||||
score_a += inc;
|
||||
}
|
||||
|
||||
if (pressed & BTN_RIGHT) {
|
||||
score_b += inc;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -342,6 +314,16 @@ update_controller()
|
|||
*/
|
||||
|
||||
|
||||
void
|
||||
setup()
|
||||
{
|
||||
// The TLC5941 required some setup.
|
||||
// The TPIC doesn't.
|
||||
// Hooray.
|
||||
|
||||
PORTB = 0xff;
|
||||
}
|
||||
|
||||
void
|
||||
loop()
|
||||
{
|
||||
|
@ -355,6 +337,8 @@ loop()
|
|||
}
|
||||
|
||||
switch (state) {
|
||||
case SETUP:
|
||||
break;
|
||||
case JAM:
|
||||
case LINEUP:
|
||||
if (period_clock) {
|
||||
|
@ -362,7 +346,7 @@ loop()
|
|||
}
|
||||
// fall through
|
||||
case TIMEOUT:
|
||||
if (jam_clock && !setup) {
|
||||
if (jam_clock) {
|
||||
jam_clock += 1;
|
||||
}
|
||||
}
|
||||
|
@ -374,7 +358,8 @@ loop()
|
|||
int
|
||||
main(void)
|
||||
{
|
||||
avr_init();
|
||||
init();
|
||||
setup();
|
||||
for (;;) {
|
||||
loop();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue