EITF11. WormFight. Axel Eriksson, Felix Geuken Handledare: Bertil Lindvall EITF11

Relevanta dokument
Rapport. Fyra i rad-spel. Rapport Digitala Projekt EITF11 Grupp 9 Emma Rasmusson & Louise Ragnarsson Handledare: Bertil Lindvall

Digitala Projekt(EITF40) - Larm

Snake. Digitala Projekt (EITF11) Fredrik Jansson, I-12 Lunds Tekniska Högskola,

Helena Harrysson och Linnéa Wickberg

LARMANLÄGGNING. Digitala Projekt, EITF11. Oskar von Knorring Emin Karimov Henrik Akej Handledare: Bertil Lindvall

Lunds Tekniska Högskola Elektro- och informationsteknik Digitala projekt (EITF11)

Rapport Digitala Projekt EITF11 Grupp 4 Axel Sundberg, Jakob Wennerström Gille Handledare: Bertil Lindvall

#include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> unsigned char num;

Vi har i kursen Digitala Projekt EITF11 byggt en spelkonsol på vilken man kan spela Snake. Mjukvaran programmerades i C på en AVR Mega32 processor.

Pulsmätare Digitala Projekt EITF11

Digitala Projekt (EITF11) Hemlarm

The Phenomenal Doorbell Bilaga 2. Källkod

Temperaturmätare med lagringsfunktion DIGITALA PROJEKT EITF11 GRUPP 14, ERIK ENFORS, LUDWIG ROSENDAL, CARL MIKAEL WIDMAN

EITF11 Digitala Projekt TIC TAC TOE. Lukas Ljungblom & Johan Lyckenvik I-13 Handledare: Bertil Lindvall

Thunder s Truck projektrapport

Växtviskaren EITF11 Digitala projekt VT15, I12

Rapport Digitala Projekt EITF Grupp 12 Elin Blomstergren, Victor Sundgren Handledare: Bertil Lindvall. Fyra i rad

LARMANLÄGGNING. Digitala Projekt, EITF11. Oskar von Knorring Emin Karimov Henrik Akej Handledare: Bertil Lindvall

The Secure Light. Digitala Projekt EITF11. Hanna Tinglöf, I-12 Anna Horvath, I-12 Filippa Österlin, I-12. Handledare: Bertil Lindvall

TETRIS. LTH, Campus Helsingborg EITA15 Digitala System

TEMPERATURMÄTARE MED GRAFRITARE

Gustaf Backman, Anton Nystedt, Nicholas Peebo Battleships. Lunds tekniska högskola. EITF11 Digitala projekt

Digitala Projekt VT13. PING-Pong

EITF11 - Digitala projekt. Hastighetsmätare. Hugo Backmyr Mattias Karlsson

Digitala Projekt(EITF40) - Larm

High Core Remote Car X8000 Cool

Bilen som inte kan krocka

Larmcentral. Digitala Projekt. Cecilia Olsson & Erika Björck Handledare: Bertil Lindvall LUNDS TEKNISKA HÖGSKOLA

Projektrapport - Roterande digital LED-klocka

Digitala projekt Linjeföljande bil

Digitala Projekt (EITF11)

Laboration 4: Knappstuds Drivrutiner för att eliminera störningar.

LTH Ingenjörhögskolan vid Campus Helsingborg. Mastermindspel

Feeding Daisy. EITF11 Lunds Tekniska Högskola. Grupp 12: Pontus Akervall Louise Landare Anton Schölin. En automatisk blomvattnare

DIGITALA PROJEKT (EITF40) Fartmätare

The Intelligent Timer

Pulsmätare med varningsindikatorer

PlantPuppy Räddaren för den som inte kan hålla växterna vid liv

Digitala projekt VT Myran

Projektrapport Målgång

Lunds Tekniska Högskola EITF11 Digitala projekt. Bandspelaren

Digitala System Projekt - EITA15 VT *SUPER DUPER KLOCKAN*

EITF40 - RFID-terminal. Joakim Marculescu (dt08jm6), Eric Johansson (dt08ej6)

Innehållsförteckning. Figur- och tabellförteckning. Figure 1 Blockschema över hårdvaran...4 Figure 2 Blockschema över programet...

Kla ggvisarskylt. -med en underton av rassel. av Jonathan So nnerup & Gabriel Jo nsson

1 Bakgrund 4. 2 Kravspecifikation Definitioner Grundläggande krav Användarfall 5

Digitala Projekt EITF11 Grupp 9 Projektarbete Hanna Bondesson Marcus Skog. Reaktionsspel EITF11

Liftmaestro. Lunds Tekniska Högskola Elektro- och informationsteknik. Olle Gemfors, I13 Dayanand Sagar, I13 Mattias Wendler, I13

Effektpedal för elgitarr

Rapportsammanfattning. Optima Sous Vide

Digitala Projekt (EITF11) Larmanläggning

Projektrapport - Feststation

DANCING ROBOT. EITF11, Grupp 10. Kajsa Salomonsson, Hugo Hedin och Petter Mårtensson

Rafiki Wa Kupanda. EITF11, Digitala projekt VT18. Linnea Håkansson, Anton Gunneberg, Ruben Schultz

AVR 5. Styrning av trafikljus. Digitala system 15 p

EDI021 Digitala projekt. Rapport LARMSYSTEM. Utförd av: Niklas Eklund E03 David Olsson E04. Inlämnad:

Pulsmätare. EITF11 Digitala Projekt VT15. Grupp 9: Emma Albertz, Mathilde Hagander & Alexandra Mansner Handledare: Andreas Johansson & Bertil Lindvall

Digitala projekt - Radiostyrd bil

RemoteBud. Inlämnas: Patrik Johnsson, e01pjo Viktor Karlsson, e01vk

Sebastian Nordqvist André Reis Malte Wallander Oliver Hedetoft Handledare: Lars-Göran Larsson & Bertil Lindvall. Projektrapport Digitala System

Datorteknik 1 (AVR 1)

Source code. #undef F_CPU. #define F_CPU UL. #include <avr/io.h> #include <avr/delay.h> #include <string.h> #include <avr/eeprom.

Digitala Projekt: Digitala Projekt, EITF11 - VT17 Oscar Ahlgren, Patrik Lorentsson och Sten Hellberg Handledare: Bertil Lindvall

Projektrapport i Digitala projekt EITF11. Institutionen för Elektro- och informationsteknik, Lunds tekniska högskola

Lunds Tekniska Högskola. I-10 Grupp 11: David Sundström Max Schulz Albert Lundberg Handledare: Bertil Lindvall

Väderstation. Digitala Projekt EITF11 Institutionen för Elektro- och Informationsteknik Lunds Tekniska Högskola

Linjeföljare Digitala projekt Johan Engström e02je Henrik Persson e02hp

Programmera i teknik - kreativa projekt med Arduino

SIMON SAYS Projekt i EITF11 Digitala Projekt

Department of Information Technology Digitala projekt. SuperKull. Daniel Öhman Alexander Persson

DIGITALA PROJEKT Väderstation

EIT. Digitala projekt EITF11. Larmanläggning. Handledare Bertil Lindvall Anna Lindberg I-11 Caroline Vitasp I-11 Eric Eliason I-10

Digitala projekt rapport

Whac A mole. Ett rektionstest i kursen Digitala Projekt EITF11 utfört av: Axel Spångberg I10 Marcus Witting I10. Handlett av: Bertil Lindvall

General Purpose registers ALU I T H S V N Z C SREG. Antag att vi behöver skriva in talet 25 till register R18

Design av inbyggda system

Musen. Författare: Joel Guedj e02jg Erik Dahlbäck e02ed. Handledare: Bertil Lindvall. Digitala Projekt SK 2005

Konstruktion av en radiostyrd legobil. Digitala projekt av Arbon Vata Leonardo Vukmanovic Amid Bhatia

EITF11: Bandkanon Grp 05

LOOKY LUKE. Caroline Hellström och Ville Orlander Arvola Industriell ekonomi I10. - Att välja en lyckosam väg EITF11 Digitala projekt

WALL E. WALL EVADER EDI021 DIGITALA PROJEKT

PROJEKTTYP: Rapportsammanfattning STUDENTER: Larsson, J. ( ) och Oredsson, J. ( ) DATUM: 26 april, 2015

Jan Babor och Oscar Ågren Handledare: Bertil Lindvall 5/16/2011

TEMPERATUR OCH VINDMÄTARE MED HÖGTALARFUNKTION

Projektrapport i Digitala System

Digitalt Projekt: Radiostyrd Bil

Digitala Projekt. Chip Quiz. Projektmedlemmar: Olov Nordenstam och Linus Hägerbrand. Grupp 9

Design vid utveckling av inbyggda system

Datorprojekt, del 1. Digitala system 15 p

ETSA01 Digitala Projekt (I) VT- 13. Projektarbete AC Handledare Bertil Lindvall

Datorteknik 2 (AVR 2)

Design av inbyggda system

Digital Projekt EDI 021 Konstruktion av talande nummerpresentatör VT1 2004

Digitala Projekt. Ljuskänslig riktningsautomatik. Rasmus Persson dt08rp9@student.lth.se Max Åkesson dt07ma4@student.lth.

THE VISUAL EGGTIMER. Skola: Lunds Tekniska Högskola Institution: Elektro- och informationsteknik Kurs: Digitala projekt (EITF11)

/* * dancing3.c * * Created: :53:20 * Author: digpi10 */ #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.

DIGITALA PROJEKT - EITF11

Montering av Wisp628.

Digitala projekt, EDI021 Rapport Handledare: Bertil Lindvall

Guitar Tuner EITF11 Digitala Projekt, Projektrapport Elektro- och informationsteknik

Transkript:

EITF11 WormFight Axel Eriksson, Felix Geuken Handledare: Bertil Lindvall EITF11

Innehåll Inledning... 3 Kravspecifikation... 3 Teori - Hårdvara... 3 Processor - AVR ATMega16... 3 Display - GDM12864C... 3 Knappar... 3 Lysdioder... 4 Resistorer... 4 Kondensator... 4 JTAG... 4 Metod... 4 Konstruktion... 4 Spelet... 5 Resultat... 5 Diskussion... 5 Referenser... 7 Bilagor... 8 Kopplingsschema... 8 Källkod... 9

WormFight Inledning För att utveckla våra färdigheter inom hårdvar- och mjukvaruutveckling har vi valt att utveckla en spelkonsol. Tanken är att göra ett spel som kallas WormFight. Det är ett spel som har inspirerats av det klassiska spelet Snake från slutet av 1970-talet. Tanken är man ska vara två spelare som spelar mot varandra med var sin mask och målet kommer att vara att överleva så länge som möjligt. Spelet avslutas om någon av spelarna kör in i väggarna eller kör in i den andra masken. Kravspecifikation Spelet ska fungera enligt ursprungsidén med tillägget att man även ska kunna krocka in i den andra spelaren. För att kunna navigera krävs fyra stycken knappar, två till varje spelare, som möjliggör riktningsändringar till både höger och vänster. Maskarnas framfart visas på en display och utgör också själva spelplanen där kampen utförs. Spelet ska avbrytas av att en mask kör in i någon av de fyra väggarna, motståndaren eller sig själv. En grön diod tänds då för vinnaren och en röd för förloraren. Krockar båda spelarna samtidigt tänds röda dioder för båda spelarna. För att starta spelet krävs också en knapp som man trycker på, vilket även ska fungera om man vill starta om spelet efter en avslutad spelomgång. Teori - Hårdvara Processor - AVR ATMega16 Processorn som vi har använt i det här projektet är en ATMega16 vilken har 1kb arbetsminne samt 40 ben där majoriteten är fördelade till fyra portar (A-D). Port A använder vi för att skicka och ta emot data från displayen. Port B används till övriga funktioner för displayen såsom Read/Write och ChipSelect. Porten används också till att reglera några av lysdioderna. Port C är till stora delar reserverad för debugging med JTAG men också några lysdioder. Port D används huvudsakligen till att lyssna på knapparna. Display - GDM12864C Displayen vi använder till det här projektet är en LED-display med 128x64 pixlar. Pixlarna är fördelade på två delar med vardera 64x64 pixlar. Pixlarna är ytterligare fördelade i 8 sidor (pages) i x-led där varje sida innehåller 8 pixlar (det vill säga en byte). Knappar Knapparna som vi har valt att använda inom det här projektet är av en mycket enkel modell. När knappen är nedtryckt blir strömmen till aktuellt ben på processorn låg,

annars hålls den hög. Processorn lyssnar i början av varje spelrunda på varje knapp genom att avgöra spänningen till ett specifikt ben och avgör sedan om en riktningsändring ska ske eller om masken ska fortsätta i befintlig riktning. Lysdioder Dioderna vi använder är enbart för ytterligare effekt samt avgöra fall då det ser ut som att båda spelarna har krockat. Dessa är kopplade till var sin pinne på processor som sänder ut en ström och tänder dioderna. Resistorer Resistorerna använder vi för att minska spänningen till processorn från knapparna och lysdioderna. Till dioderna är de nödvändiga då dioden inte tål för hög spänning. Vi har även använt oss av en reglerbar resistor för att kunna ställa in en behaglig vinkel på skärmen. Kondensator Kondensatorerna använde vi i vår konstruktion för att undvika att få spänningssvängningar, det vill säga få en jämnare spänning till framförallt skärm och processor. JTAG Modul som kopplas till processorn för att kunna köra processorn i AVR Studio 4. Nödvändig för att kunna felsöka och förbättra spelet. Metod Konstruktion Efter färdigställandet av kopplingsschemat och efter mottagande av nödvändig hårdvara började vi att konstruera själva WormFight-konsolen. Tanken var att skapa en konsol så att spelarna kan spela bekvämt utan att trängas samtidigt som att man ser displayen tydligt. Med hjälp av en basplatta av större modell genomfördes detta. Då vår prototyp inte har särkilt mycket hårdvara var den fysiska konstruktionen relativt snabbt monterad och klar för mjukvara. Efter några dagars effektivt lödande och kopplande verkade konsolen fungera som den skulle och benen mottog rätt signaler från exempelvis knapparna. Detta testades kontinuerligt med hjälp av logikpenna för att avgöra den specifika signalen. Efter en tids lärande genom att sköta varje pinne för sig i AVR Studio 4 verkade således hårdvaran fungera och utföra det den sades åt att utföra. Displayen ritade ut angiven data och lysdioderna tändes på begäran. C-funktionerna började sedan ta form som löste det vi hade knappat pinne-för-pinne mycket fortare och noggrannare. Vid senare tillfällen lades kondensatorerna till i konstruktionen då problem uppstod med spel utan JTAG inkopplat.

Spelet För att kontrollera de båda maskarna i spelet använde vi oss av ett flertal variabler och vektorer där aktuell data sparas. Försök gjordes även med matriser som bas, men på grund av begränsningar i arbetsminne fick dessa idéer skrotas. Masken i sig är en serie pixlar på rad. Dels för enkelhet, dels för känslan av större spelplan utgörs masken endast av en pixel i bredd. Längden avgörs sedan till viss del av hur länge masken överlever men också av en begränsning till 100 pixlar på grund av minnesbrist. Med hjälp av vektorer kan vi på så sätt hålla koll på hela masken och med hjälp av detta också få hela masken att flytta på sig. För att kontrollera maskens riktning introducerades en variabel som enbart håller koll på riktning. Knapparna reglerar sedan denna variabel som sedan genom en metod som sedan avgör om masken ska röra sig uppåt, nedåt, höger eller vänster. För att identifiera en krasch används metoder som kontrollerar om nästa pixel som masken ska röra sig till finns i någon av maskarnas vektorer eller om masken kommer att röra sig in i väggen. I sådana fall avbryts spelet. Har ingen krasch identifierats fortsätter spelet med en till runda med förflyttningar av de båda maskarna. Beroende på vilken mask det är som krockar utformade vi metoder som ger ytterligare feedback till spelarna genom att tända lysdioder med olika färg ovanför spelarnas knappar. Resultat Resultatet är en fullt fungerande spelkonsol enligt vår kravspecifikation. Det går att spela två spelare samtidigt mot varandra och så länge ingen av maskarna kör in i väggen, den egna masken eller motståndarmasken så fortsätter spelet. De fem knapparna fungerar som önskat och de styr maskarna åt rätt håll. Enda nackdelen med knapparna är att de är väldigt känsliga för knapptryckningar och spelarna kan lätt råka göra två svängningar när man bara vill göra en. Det finns möjlighet att göra knapparna mindre känsliga men då skulle spelet bli mycket långsammare vilket vi anser är sämre för spelupplevelsen. Vi fick även dioderna att lysa som önskat. Diskussion Sammanfattningsvis kan man säga att allting som kunde gå fel gick fel. Många gånger kändes det som att det var slumpen som avgjorde om det gick bra eller inte. Men på något sätt vi fick ihop konstruktionen och kunde konstatera att det varken var fel på processorn, skärmen eller AVR-studios vilket vi stundtals hade antagit. Av de problem som uppstod var många av den sort som är nästintill omöjliga att förutse. Ett handlade om en optimeringsfunktion som finns inbyggd i AVR-studio som vi inte visste förrän i slutet att den existerade. Efter att denna hade stängts slutade AVR att anropa funktioner utan att vi hade kodat anropen, vilket gjorde att allting fungerade mycket bättre..ett annat handlade om att spänningen till processorn och skärmen var ojämn vilket krävde att två kondensatorer fick läggas till i konstruktionen. Efter dessa

fungerade allt fysiskt som det skulle. På grund av våra begränsade tidigare erfarenheter tog dessa problem mycket längre tid att förstå än vad de borde ha tagit. I övrigt handlade de största problemen som vi mötte under projektets gång om kommunikationen mellan processorn och displayen. Det tog ett tag att förstå och kunna utnyttja skärmens uppbyggnad och framförallt hur sidorna i x-led fungerade. Ett annat problem som tog en del tid var uppbyggnaden av själva spelplanen. Ursprungsidén var en matris med samma dimensioner som skärmen men denna idé fick skrotas då arbetsminnet blev alldeles för högt belastat. Problemet med minnesbrist har vi inte stött på tidigare då vi har arbetat på kraftigare processorer som inte lider av samma problem. Att spara varje besökt pixel löste minnesproblemet men istället var skärmen nu tvungen att läsas av för att inte radera andra markerade pixlar på samma sida. Att markera varje besökt pixel ledde också till minnesproblem, men inte i samma utsträckning som tidigare. Den begränsning som uppkom är att vi max kunde spara undan omkring 200 pixlar. Grundtanken var att masken skulle bli längre och längre med spelets gång utan men detta gör att maskarna bara kunde bli 100 pixlar vardera. Den slutliga lösningen blev att maskarna också kunde röra sig framåt det vill säga att den sista pixeln tas bort efterhand. Det leder inte bara att spelet varar längre utan också gör att spelarna verkligen måste jobba ordentligt för att kunna stänga in sin motståndare. Sammantaget en bättre spelupplevelse. Problemet vi fortfarande har med att knapparna är väldigt känsliga kan eventuellt förbättras med hjälp av en OR -brygga. Detta kan dock leda till att om en spelare väljer att fortsätta hålla sin knapp inne blir den andra spelaren helt begränsad i sina rörelser. Vår lösning med att lyssna på varje spelare blir i vår mening rättvisare och bättre för vår användning. I allmänt har vi fått ökade kunskaper inom både hård- och mjukvaruutveckling. Svårighetsgraden kan dock ses som överkant trots en relativt enkel konstruktion. Att varken ha programmerat i C eller arbetat med hårdvara tidigare gjorde att även enkla problem kunde dra ut på tiden. De programmeringskunskaper vi hade sedan tidigare kunde i viss mån användas med till exempel grundförståelsen för språket men att göra metoder ben-specifika samt att C inte är objektorienterat som JAVA gjorde som sagt att tiden kunde stundtals springa iväg. Bristen på kunskap har dock gett ytterligare erfarenheter i att söka och hitta relevant information vilket kan ses som nyttigt.

Referenser Kernghan, Brian W. och Ritchie, Dennis M. 1988. The C Programming Language. 2. uppl. Englewood Cliffs: Prentice Hall. Datablad för display (GDM12864HLCM.http://www.eit.lth.se/fileadmin/eit/courses/edi021/datablad/Displ ay/gdm12864h.pdf) (Hämtad 2013-05-09) Datablad för processor AVR ATMega16 (http://www.eit.lth.se/fileadmin/eit/courses/edi021/datablad/processors/atmega16. pdf) (Hämtad 2013-05-09)

Bilagor Kopplingsschema WormFight.sch-1 - Thu May 09 12:46:02 2013

Källkod #include <avr/io.h> unsigned short int snakeonex; unsigned short int snakeoney; short int snakeoneangle; unsigned short int snaketwox; unsigned short int snaketwoy; short int snaketwoangle; short int cause; unsigned short int buttons; unsigned short int snaketwo[100][2]; unsigned short int snakeone[100][2]; unsigned short int count; unsigned short int gamenbr = 1; void actionevente() PORTB = PORTB 0x10; PORTB = PORTB & 0xEF; PORTB = PORTB 0x10; // Tänder den vänstra gröna lampan void lightleftgreen() PORTB = PORTB 0x20; // Släcker den vänstra gröna lampan void unlightleftgreen() PORTB = PORTB & 0xDF; // Tänder den vänstra röda lampan void lightleftred() PORTB = PORTB 0x40; // Släcker den vänstra röda lampan void unlightleftred() PORTB = PORTB & 0xBF; // Tänder den högra gröna lampan

void lightrightgreen() PORTC = PORTC 0x40; // Släcker den högra gröna lampan void unlightrightgreen() PORTC = PORTC & 0xBF; // Tänder den högra vänstra lampan void lightrightred() PORTC = PORTC 0x01; // Släcker den högra vänstra lampan void unlightrightred() PORTC = PORTC & 0xFE; unlightall() unlightleftgreen(); unlightleftred(); unlightrightgreen(); unlightrightred(); // Kontrollerar att skärmen är redo att mottaga ny information. void checkifready() DDRA = 0x00; short int tmp = PORTB; PORTB = PORTB 0x15; PORTB = PORTB & 0xF5; while(pina!= 0x00) PORTB = PORTB 0x16; PORTB = PORTB & 0xF6; while(pina!= 0x00)

DDRA = 0xFF; PORTB = tmp; int transformtopinout(int z) if(z == 0) return 0x01; else if (z == 1) return 0x02; else if (z == 2) return 0x04; else if (z == 3) return 0x08; else if (z == 4) return 0x10; else if (z == 5) return 0x20; else if (z == 6) return 0x40; else return 0x80; // Lyssnar på den vänstra svarta knappen void readleftblackbutton() short int directions = PIND 0xDF; if(directions == 0xDF) snaketwoangle -= 1;

// Lyssnar på den högra svarta knappen void readrightblackbutton() short int directions = PIND 0xBF; if(directions == 0xBF) snaketwoangle += 1; // Lyssnar på den vänstra röda knappen void readleftredbutton() short int directions = PIND 0xFB; if(directions == 0xFB) snakeoneangle -= 1; // Lyssnar på den högra röda knappen void readrightredbutton() short int directions = PIND 0xF7; if(directions == 0xF7) snakeoneangle += 1; void delay(short int t) while(t > 0) // Kontrollerar knapparna void readbuttons() readleftblackbutton(); delay(20); readrightblackbutton(); delay(20); readleftredbutton(); delay(20); for(int i = 800; i >= 0; i--); t--;

readrightredbutton(); // Ger nästa x-koordinat int getnextx(int snakeangle, int snakex) if(snakeangle % 4 == 0) return snakex - 1; else return snakex + 1; // Ger nästa y-koordinat int getnexty(int snakeangle, int snakey) if(snakeangle % 4 == 1) return snakey + 1 ; else return snakey - 1; // Kontrollerar om pixeln är markerad eller ej. int isoccupied(short int x, short int y) for(short int i = 0; i < 100; i++) if((x == snakeone[i][0] && y == snakeone[i][1]) (x == snaketwo[i][0] && y == snaketwo[i][1])) return 1; return 0; // Kontrollerar om masken är utanför banan. int outofbounds(short int x, short int y) if(x > 62 x < 1 y < 1 y > 126) return 1; return 0;

// Kontrollerar om angiven mask har kraschat. int hascrashed(int snakeangle, int snakex, int snakey) short int direction = snakeangle % 2; short int x; short int y; if (direction == 0) x = getnextx(snakeangle, snakex); y = snakey; else y = getnexty(snakeangle, snakey); x = snakex; int out = outofbounds(x, y); int is = isoccupied(x, y); if (out == 1 is == 1) return 1; return 0; // Kontrollerar om någon mask har kraschat. void checkifcrashed() short int statusone = hascrashed(snakeoneangle, snakeonex, snakeoney); short int statustwo = hascrashed(snaketwoangle, snaketwox, snaketwoy); if(statusone == 1 && statustwo == 0) // spelare ett har krockat cause = 1; else if(statusone == 0 && statustwo == 1) // spelare två har krockat cause = 2; else if(statusone == 1 && statustwo == 1) // båda spelarna har krockat cause = 3; else if(getnextx(snakeoneangle,snakeonex) == getnextx(snaketwoangle,snaketwox) && getnexty(snakeoneangle,snakeoney) == getnexty(snaketwoangle,snaketwoy)) // båda spelarna har krockat

cause = 3; int readcurrentpage(short int xpage, short int y) short int tmp = 0; for(int i = 0; i < 100; i++) if(snakeone[i][1] == y && snakeone[i][0] / 8 == xpage) tmp += transformtopinout(snakeone[i][0] % 8); if(snaketwo[i][1] == y && snaketwo[i][0] / 8 == xpage) tmp += transformtopinout(snaketwo[i][0] % 8); if(xpage == 0) tmp += transformtopinout(0); if(xpage == 7) tmp += transformtopinout(7); return tmp; void unmarkpixel(short int x, short int y) DDRA = 0xFF; PORTB = PORTB & 0xF0; int yaddress; if(y < 64) yaddress = y; else int xpage = x / 8; short int xdot = x % 8; PORTB = PORTB 0x01; // Markerar ena skärmhalvan yaddress = y - 64; // Markerar andra skärmhalvan PORTB = PORTB 0x02; PORTA = 0x40 + yaddress;

PORTA = 0xB8 + xpage; PORTA = 0xC0; // Sätter z = 0 PORTA = readcurrentpage(xpage, y) & (0xFF - transformtopinout(xdot)); PORTB = PORTB 0x08; PORTB = PORTB & 0xF7; PORTA = 0x00; // Markerar angiven pixel. void markpixel(short int x, short int y) DDRA = 0xFF; PORTB = PORTB & 0xF0; int yaddress; if(y < 64) yaddress = y; else int xpage = x / 8; short int xdot = x % 8; PORTB = PORTB 0x01; // Markerar ena skärmhalvan yaddress = y - 64; // Markerar andra skärmhalvan PORTB = PORTB 0x02; PORTA = 0x40 + yaddress; PORTA = 0xB8 + xpage;

PORTA = 0xC0; // Sätter z = 0 PORTA = readcurrentpage(xpage, y) transformtopinout(xdot); PORTB = PORTB 0x08; PORTB = PORTB & 0xF7; PORTA = 0x00; // Flyttar mask 1. void moveone() if (snakeoneangle % 2 == 0) snakeonex = getnextx(snakeoneangle, snakeonex); else snakeoney = getnexty(snakeoneangle, snakeoney); markpixel(snakeonex, snakeoney); if(count > 99) unmarkpixel(snakeone[count % 100][0], snakeone[count % 100][1]); snakeone[count % 100][0] = snakeonex; snakeone[count % 100][1] = snakeoney; // Flyttar mask 2. void movetwo() if (snaketwoangle % 2 == 0) snaketwox = getnextx(snaketwoangle, snaketwox); else snaketwoy = getnexty(snaketwoangle, snaketwoy); markpixel(snaketwox, snaketwoy); if(count > 99) unmarkpixel(snaketwo[count % 100][0], snaketwo[count % 100][1]);

snaketwo[count % 100][0] = snaketwox; snaketwo[count % 100][1] = snaketwoy; // Metod för effekt vid slut. void gameover() if (cause == 1) lightrightgreen(); lightleftred(); else if (cause == 2) lightleftgreen(); lightrightred(); else if(cause == 3) lightleftred(); lightrightred(); // Huvudloop för spelet. Den yttre while-loopen möjliggör för flera omgångar av spelet // efter varandra. void game() while(1) buttons = PIND 0xEF; if (buttons == 0xEF) if (gamenbr > 1) unlightall(); unmarkrows(); gamesetup(); delay(500); while(1) readbuttons(); delay(1); checkifcrashed(); if(cause == 1 cause == 2 cause == 3)

break; moveone(); movetwo(); count++; gameover(); gamenbr++; void markwholepage(short int xpage, short int y) DDRA = 0xFF; PORTB = PORTB & 0xF0; int yaddress; if(y < 64) yaddress = y; else PORTB = PORTB 0x01; // Markerar ena skärmhalvan yaddress = y - 64; // Markerar andra skärmhalvan PORTB = PORTB 0x02; PORTA = 0x40 + yaddress; PORTA = 0xB8 + xpage; PORTA = 0xC0; // Sätter z = 0 PORTA = 0xFF; PORTB = PORTB 0x08; PORTB = PORTB & 0xF7;

PORTA = 0x00; void makeframe() for (short int k = 0; k < 128; k++) markpixel(0,k); markpixel(63,k); for (short int i = 0; i < 8; i++) markwholepage(i,0); markwholepage(i,126); void unmarkrow(int x, int y) DDRA = 0xFF; PORTB = PORTB & 0xF0; int yaddress; if(y < 64) yaddress = y; PORTB = PORTB 0x02; else yaddress = y - 64; PORTB = PORTB 0x01; PORTA = 0x40 + yaddress; PORTA = x; PORTA = 0xB8 + x; PORTA = 0x00; PORTB = PORTB 0x08; PORTB = PORTB & 0xF7; PORTA = 0x00; void unmarkrows()

for(int y = 0; y < 128; y++) for(int x = 0; x < 8; x++) unmarkrow(x,y); void ddrset() DDRA = 0xFF; DDRB = 0x7F; DDRC = 0x41; DDRD = 0x80; void checkifreadycs1() DDRA = 0x00; short int tmp = PORTB; PORTB = PORTB 0x15; PORTB = PORTB & 0xF5; while(pina!= 0x20) DDRA = 0xFF; PORTB = tmp; void checkifreadycs2() DDRA = 0x00; short int tmp = PORTB; PORTB = PORTB 0x16; PORTB = PORTB & 0xF6; while(pina!= 0x20) DDRA = 0xFF; PORTB = tmp; void startupscreen()

PORTA = 0x3F; PORTB = 0x01; checkifreadycs1(); PORTB = 0x02; checkifreadycs2(); void clearmemorysnakeone() for(int i = 0; i < 100; i++) for(int j = 0; j < 2; j++) snakeone[i][j] = 0; void clearmemorysnaketwo() for(int i = 0; i < 100; i++) for(int j = 0; j < 2; j++) snaketwo[i][j] = 0; void gamesetup() clearmemorysnakeone(); clearmemorysnaketwo(); makeframe(); snakeonex = 30; snakeoney = 90; snakeoneangle = 102; markpixel(30,30); snaketwox = 30; snaketwoy = 30; snaketwoangle = 102; markpixel(30,90); cause = 0; count = 0;

void reset() PORTD = 0x00; PORTD = 0x80; PORTD = 0x00; PORTD = 0x80; void setup() ddrset(); reset(); startupscreen(); unmarkrows(); gamesetup(); void main(void) setup(); game();