summaryrefslogtreecommitdiff
path: root/Matris.c
diff options
context:
space:
mode:
authorschneefux <schneefux+commit@schneefux.xyz>2016-06-12 20:08:57 +0200
committerschneefux <schneefux+commit@schneefux.xyz>2016-06-12 20:08:57 +0200
commitba07c2bc98fdba991b6d6444d57f0f897cf5959f (patch)
tree6ff34bf1bf181a6eebcd59bbeba2ad05ffe4408b /Matris.c
parent847d1a917f6cb17493c66398ce4ce53b89d8c438 (diff)
downloadfx-matris-ba07c2bc98fdba991b6d6444d57f0f897cf5959f.tar.gz
fx-matris-ba07c2bc98fdba991b6d6444d57f0f897cf5959f.zip
import full projectHEADmaster
Diffstat (limited to 'Matris.c')
-rw-r--r--Matris.c1272
1 files changed, 635 insertions, 637 deletions
diff --git a/Matris.c b/Matris.c
index 37b0ab1..6ba8152 100644
--- a/Matris.c
+++ b/Matris.c
@@ -1,637 +1,635 @@
-/*
- * Matris (C) by Casimo, summer 2012
- * licensed as GPLv3+
- */
-
-#include "stdio.h"
-#include "key.h"
-#include "draw.h"
-#include "global.h"
-
-short*APP_EnableRestart()
-{
- unsigned int ea;
- unsigned int j;
- short*pEnableRestartFlag;
- ea = *(unsigned int*)0x8001007C;
- ea += 0x0490*4;
- if ( ea < 0x8001007C ) return 0;
- if ( ea > 0x81000000 ) return 0;
- ea = *(unsigned int*)( ea );
- if ( ea < 0x8001007C ) return 0;
- if ( ea > 0x81000000 ) return 0;
- j = *(unsigned char*)( ea + 1 );
- j *= 4;
- ea = ( ea + j + 4 ) & 0xFFFFFFFC;
- if ( ea < 0x8001007C ) return 0;
- if ( ea > 0x81000000 ) return 0;
- pEnableRestartFlag = (short*)(*( unsigned int*)( ea ) + 8 );
- if ( ( (unsigned int)pEnableRestartFlag & 0xFF000000 ) != 0x88000000 ) return 0;
- if ( pEnableRestartFlag ) *pEnableRestartFlag = 1;
- return pEnableRestartFlag;
-}
-
-//restart addin after return 1
-
-static unsigned int seed = 123456789;
-unsigned int kiss()
-{
- // interner Zustand
- static unsigned int y = 362436000;
- static unsigned int z = 521288629;
- static unsigned int c = 7654321;
-
- unsigned long t;
-
- // Linearer Kongruenzgenerator
- seed = 69069 * seed + 12345;
-
- // Xorshift
- y ^= y << 13;
- y ^= y >> 17;
- y ^= y << 5;
-
- // Multiply-with-carry
- t = (unsigned long)698769069 * z + c;
- c = t >> 32;
- z = (unsigned int) t;
-
- return seed + y + z;
-}
-
-void seedkiss()
-{
- seed = RTC_GetTicks();
-}
-
-//kiss is a random number generator
-
-char *Disp_GetVRAMPtr(void);
-void DrawLineVRAM(int x1, int y1, int x2, int y2);
-void AllClr_DD(void);
-void AllClr_VRAM(void);
-void AllClr_DDVRAM(void);
-void locate(int x, int y);
-void Print(const unsigned char *str);
-int Timer_Install(int TimerID, void (*handler)(void), int delay);
-int Timer_Uninstall(int TimerID);
-int Timer_Start(int TimerID);
-void App_RUN_MAT();
-
-//some prototypes
-
-char swit;
-
-char pause = False;
-//pause the game
-
-char quit = False;
-
-char levelchanged = False;
-//has the level changed during two actions?
-
-char exit = False;
-
-char ready;
-
-char onoff = True;
-//used for timers
-
-char canswap;
-//brick already swapped?
-
-char slowyposdown = 0;
-
-char connected;
-//multiplayer activated?
-
-unsigned char receiveline = 0;
-unsigned char sendline = 0;
-//what to send or receive?
-
-char cantrans = False;
-//allowed to transfer?
-
-//taken from MonochromeLib by PierrotLL
-
-void drawbuffer(char *buffer)
-{
- char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
- int i, j;
- for(i=0 ; i<64 ; i++)
- {
- *LCD_register_selector = 4;
- *LCD_data_register = i|192;
- *LCD_register_selector = 4;
- *LCD_data_register = 0;
- *LCD_register_selector = 7;
- for(j=0 ; j<16 ; j++) *LCD_data_register = *buffer++;
- }
-}
-
-void RestGray(void)
-{
- drawbuffer(pScreen);
- drawbuffer(pScreen + 1024);
- drawbuffer(pScreen + 2048);
-}
-
-
-void Disconnect()
-{
- Serial_Close(1);
- connected = False;
-}
-
-void TeacherMode()
-{
- Timer_Uninstall(6);
- Timer_Uninstall(7);
- Disconnect();
-
- App_RUN_MAT();
-}
-
-int round(float num)
-{
- return (int) (num + 0.5);
-}
-
-void clrbuffer(char *buffer)
-{
- memset(buffer, 0, 3072);
-}
-
-
-void CreateBlock()
-{
- block = nextblock;
- canswap = True;
- nextblock = (kiss() % 7) + 1;
- xpos = 7;
- ypos = 3;
- dir = 0;
- left = True;
- right = True;
- cantrans = True;
-}
-
-void ResetValues()
-{
- int x,y;
-
- char text[30];
-
- memset(&changemap, 0, 210);
- memset(&globalmap, 0, 210);
-
- ypos = 3;
- xpos = 0;
- block = 0;
- onoff = True;
- levelchanged = False;
- right = True;
- left = True;
- hold = 0;
- exit = False;
- nextdir = Down;
- nextblock = (kiss() % 7) + 1;
- CreateBlock();
- clrbuffer(pScreen);
- Timer_Uninstall(6);
- Timer_Uninstall(7);
- ready = True;
- connected = False;
-
- AllClr_DDVRAM();
-
- PopUpWin(2);
- sprintf(&text, "Points: %d", points);
- locate(3, 3);
- Print(&text);
- sprintf(&text, "Level: %d", level);
- locate(3, 4);
- Print(&text);
- PutDisp_DD();
-
- points = 0;
- level = 0;
-
- while(!KeyDown(31));
-}
-
-void Transfer()
-{
- int xcount, ycount;
- char space = kiss() % 10; //where is the hole?
-
- if(connected == True)
- {
- if(receiveline > sendline)
- {
- //if there are lines arriving, but there can be send lines back, erase the lines, for example: receiving 3 lines, sending 1 -> 0 are send, 2 are received
- receiveline -= sendline;
- sendline = 0;
- }
- else
- {
- sendline -= receiveline;
- receiveline = 0;
- }
- if(sendline > 0)
- {
- while(Serial_BufferedTransmitOneByte(sendline) != 0);
- //send the number of lines
- sendline = 0;
- }
- if(receiveline > 0)
- {
- for(ycount = 0; ycount < 20 - receiveline; ycount++)
- {
- for(xcount = 0; xcount < 10; xcount++)
- {
- globalmap[ycount][xcount] = globalmap[ycount + receiveline][xcount];
- //move all lines upwards
- }
- }
-
- for(ycount = 19; ycount > 19 - receiveline; ycount --)
- {
- for(xcount = 0; xcount < 10; xcount ++)
- {
- globalmap[ycount][xcount] = (xcount == space) ? 0 : (kiss() % 7) + 1;
- //add lines at the bottom
- }
- }
- receiveline = 0;
- }
- }
-}
-
-void receive(void)
-{
- unsigned char receiveadd = 0;
-
- if(Serial_ReadOneByte(&receiveadd) != 0)
- {
- receiveadd = 0;
- }
-
- receiveline += (receiveadd > 20)?0:receiveadd;
-}
-
-void Connect()
-{
- unsigned char connstart = 111;
- unsigned char answer;
- char open_mode[6];
-
- PopUpWin(1);
- locate( 5 , 4);
- Print("Connecting...");
- PutDisp_DD();
-
- open_mode[ 0 ] = 0; // always 0
- open_mode[ 1 ] = 9; // 0=300, 1=600, 2=1200, 3=2400, 4=4800, 5=9600, 6=19200, 7=38400, 8=57600, 9=115200 baud
- open_mode[ 2 ] = 2; // parity: 0=no; 1=odd; 2=even
- open_mode[ 3 ] = 0; // datalength: 0=8 bit; 1=7 bit
- open_mode[ 4 ] = 0; // stop bits: 0=one; 1=two
- open_mode[ 5 ] = 0; // always 0
-
- Serial_Open( &open_mode );
-
- do
- {
- Serial_BufferedTransmitOneByte(connstart);
- Serial_ReadOneByte(&answer);
- }while(answer != connstart && !KeyDown(47));
-
- if(!KeyDown(47))connected = True;
-
- if(connected != True)
- {
- Disconnect();
- }
-}
-
-void SwapPieces()
-{
- char save;
- if(canswap == True)
- {
- save = block;
- if(hold == 0)
- {
- block = nextblock;
- nextblock = (kiss() % 7) + 1;
- }
- else
- {
- block = hold;
- }
- hold = save;
- xpos = 7;
- ypos = 3;
- dir = 0;
- }
- canswap = False;
-}
-
-void Rotate()
-{
- if(++dir == 4)
- {
- dir = 0;
- }
-
- if(DrawSprite() == False)
- {
- dir = (dir == 0)? 3 : dir - 1;
- }
-}
-
-void MoveBlock()
-{
- switch (nextdir)
- {
- case Left : if(left == True) {xpos ++;} nextdir = Down;break;
- case Right: if(right == True){xpos --;}nextdir = Down;break;
- case Rot : Rotate();nextdir = Down;break;
- case Swap: SwapPieces();nextdir = Down;break;
- }
-
- if(nextdir == Fast && (int)slowyposdown == slowyposdown)
- {
- points += 1;
- }
-}
-
-void CheckPoints()
-{
- char typecount = 0;
- char oldlevel;
- int xcount, ycount;
- int ycount2, ycount3;
- char fulllinecount = 0;
-
- for(xcount = 0; xcount < 10; xcount ++)
- {
- if(globalmap[0][xcount] != 0)
- {
- exit = True;
- //game over
- }
- }
-
- for(ycount = 0; ycount < 20; ycount ++)
- {
- fulllinecount = 0;
- for(xcount = 0; xcount < 10; xcount ++)
- {
- if(globalmap[ycount][xcount] != 0)
- {
- fulllinecount ++;
- }
- else
- {
- break;
- }
- }
-
- if(fulllinecount == 10)
- {
- typecount ++;
-
- //1: single, 2: double, 3: triple line, 4: tetris (maximum)
-
- for(ycount2 = ycount; ycount2 > 0; ycount2 --)
- {
- for(xcount = 0; xcount < 10; xcount ++)
- {
- globalmap[ycount2][xcount] = globalmap[ycount2 - 1][xcount];
- //move averything
- }
- }
-
- line(pScreen, 0 , 0 , 81 , 0, 1);
- line(pScreen, 0 , 0 , 0 , 41, 1);
- line(pScreen, 81 , 0 , 81 , 41, 1);
- line(pScreen, 81 , 41 , 0 , 41, 1);
-
- for(ycount3 = 0; ycount3 < 20; ycount3 ++)
- {
- for(xcount = 0; xcount < 10; xcount ++)
- {
- if(globalmap[ycount3][xcount] != 0 || changemap[ycount3][xcount] != 0)
- {
- fillbox(pScreen, ycount3, xcount, (globalmap[ycount3][xcount] != 0)? globalmap[ycount3][xcount] - 1 : changemap[ycount3][xcount] - 1);
- }
- }
- }
- }
- }
- if(typecount > 0)
- {
- int blink;
-
- points += (typecount == 1)? 40 * (level + 1): (typecount == 2)? 100 * level : (typecount == 3)? 300 *(level + 1): (typecount == 4)? 1200 * (level + 1) : 0;
- //increment points
-
- sendline = (typecount == 4)? 4 : typecount - 1;
- //send a line, if not tetris send lines - 1
- oldlevel = level;
- level += typecount;
- if((int)(level / 10) != (int)(oldlevel / 10) && level < 200)
- {
- levelchanged = True;
- //level = round cleared lines / 10
- }
- }
- Transfer();
-}
-
-void ReadKey()
-{
- nextdir =Down;
-
- if(KeyDown(38)) nextdir = Rot;
- if(KeyDown(37)) nextdir = Left ;
- if(KeyDown(28)) nextdir = Right;
- if(KeyDown(27)) nextdir = Fast;
- if(KeyDown(47)) exit = True;
- if(KeyDown(26)) nextdir = Swap;
- if(KeyDown(31)) TeacherMode();
- if(KeyDown(39)) {pause = (pause == True)? False : True; while(KeyDown(39));}
-}
-
-void Main(void)
-{
- cantrans = False;
- ready = False;
- if(pause == False)
- {
- receive();
- ypos += (slowyposdown % 10 == 0 || nextdir == Fast)? 1 : 0;
- if(nextdir == Left || nextdir == Right || nextdir == Fast || nextdir == Rot || slowyposdown % 10 == 0)
- {
- MoveBlock();
- DrawBlock();
- if(cantrans == True)
- {
- CheckPoints();
- DrawBlock();
- }
- }
- slowyposdown++;
- }
- ready = True;
- drawNumber(pScreen, connected, 0, 62);
- drawNumber(pScreen + 1024, connected, 0, 62);
- drawNumber(pScreen + 2048, connected, 0, 62);
-}
-
-void CallMain(void)
-{
- ReadKey();
- if(nextdir == Fast && onoff == False)
- {
- while(ready == False);
- onoff = True;
- Timer_Uninstall(7);
- Timer_Install(7, &Main, 50);
- Timer_Start(7);
- if(nextdir == Down)
- {
- nextdir = Fast;
- }
- }
- else
- {
- if(nextdir != Fast && onoff == True || levelchanged == True)
- {
- while(ready == False);
- onoff = False;
- Timer_Uninstall(7);
-
- if(level < 20)
- {
- Timer_Install(7, &Main, 100 - level * 5);
- }
- else
- {
- Timer_Install(7, &Main, 0);
- }
-
- Timer_Start(7);
- levelchanged = False;
- }
- }
-}
-
-//the code above is not good, CallMain handles the keys and sets the timer of Main
-
-void ReadMenuKeys()
-{
- if(KeyDown(31)) TeacherMode();
- if(KeyDown(47)) quit = True;
-}
-
-int AddIn_main(int isAppli, unsigned short OptionNum)
-{
- char c[] = {0xE6, 0x9B, 0};
- char mode = 0;
-
- level = 0;
-
- pScreen = (char*)malloc(3072);
-
- nextblock = (kiss() % 7) + 1;
- CreateBlock();
-
- ready = True;
-
- APP_EnableRestart();//thx to SimonLothar
-
- seedkiss();//seed random numbers
-
- while(mode != 3)
- {
- quit = False;
- Timer_Install(10, &ReadMenuKeys, 200);
- Timer_Start(10);
- while(!KeyDown(31) && mode != 3)
- {
- AllClr_VRAM();
-
- locate( 6, 3 );
- Print(&"Singleplayer");
- locate( 6, 4 );
- Print(&"Multiplayer");
- locate( 2, 8);
- Print(&"Copyright by Casimo");
-
- locate( 4, 3 + mode);
- PrintC(&c);
-
- PutDisp_DD();
-
- if(KeyDown(37))
- {
- mode += (mode == 1)? -1 : 1;
- while(KeyDown(37));
- }
- else
- {
- if(KeyDown(28))
- {
- mode -= (mode == 0)? -1 : 1;
- while(KeyDown(28));
- }
- else
- {
- if(KeyDown(47))
- {
- mode = 3;
- while(KeyDown(47));
- }
- }
-
- }
- }
-
- Timer_Uninstall(10);
-
- if(mode != 3)
- {
- if(mode == 1)
- {
- Serial_ClearReceiveBuffer();
- Connect();
- }
-
- Timer_Install(6,&CallMain, 150);
- Timer_Start(6);
-
- while(exit == False){RestGray();}
-
- ResetValues();
-
- while(KeyDown(47));
- while(KeyDown(31));
- }
- }
- Timer_Uninstall(6);
- Timer_Uninstall(7);
- Disconnect();
- free(pScreen);
-}
-
-//I'm sure there are unused variables
-
-#pragma section _BR_Size
-unsigned long BR_Size;
-#pragma section
-#pragma section _TOP
-int InitializeSystem(int isAppli, unsigned short OptionNum)
-{return INIT_ADDIN_APPLICATION(isAppli, OptionNum);}
-#pragma section
+/*Matris by Casimo is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License.
+see here: http://creativecommons.org/licenses/by-nc-sa/3.0/
+*/
+#include "stdio.h"
+#include "key.h"
+#include "draw.h"
+#include "global.h"
+
+short*APP_EnableRestart()
+{
+ unsigned int ea;
+ unsigned int j;
+ short*pEnableRestartFlag;
+ ea = *(unsigned int*)0x8001007C;
+ ea += 0x0490*4;
+ if ( ea < 0x8001007C ) return 0;
+ if ( ea > 0x81000000 ) return 0;
+ ea = *(unsigned int*)( ea );
+ if ( ea < 0x8001007C ) return 0;
+ if ( ea > 0x81000000 ) return 0;
+ j = *(unsigned char*)( ea + 1 );
+ j *= 4;
+ ea = ( ea + j + 4 ) & 0xFFFFFFFC;
+ if ( ea < 0x8001007C ) return 0;
+ if ( ea > 0x81000000 ) return 0;
+ pEnableRestartFlag = (short*)(*( unsigned int*)( ea ) + 8 );
+ if ( ( (unsigned int)pEnableRestartFlag & 0xFF000000 ) != 0x88000000 ) return 0;
+ if ( pEnableRestartFlag ) *pEnableRestartFlag = 1;
+ return pEnableRestartFlag;
+}
+
+//restart addin after return 1
+
+static unsigned int seed = 123456789;
+unsigned int kiss()
+{
+ // interner Zustand
+ static unsigned int y = 362436000;
+ static unsigned int z = 521288629;
+ static unsigned int c = 7654321;
+
+ unsigned long t;
+
+ // Linearer Kongruenzgenerator
+ seed = 69069 * seed + 12345;
+
+ // Xorshift
+ y ^= y << 13;
+ y ^= y >> 17;
+ y ^= y << 5;
+
+ // Multiply-with-carry
+ t = (unsigned long)698769069 * z + c;
+ c = t >> 32;
+ z = (unsigned int) t;
+
+ return seed + y + z;
+}
+
+void seedkiss()
+{
+ seed = RTC_GetTicks();
+}
+
+//kiss is a random number generator
+
+char *Disp_GetVRAMPtr(void);
+void DrawLineVRAM(int x1, int y1, int x2, int y2);
+void AllClr_DD(void);
+void AllClr_VRAM(void);
+void AllClr_DDVRAM(void);
+void locate(int x, int y);
+void Print(const unsigned char *str);
+int Timer_Install(int TimerID, void (*handler)(void), int delay);
+int Timer_Uninstall(int TimerID);
+int Timer_Start(int TimerID);
+void App_RUN_MAT();
+
+//some prototypes
+
+char swit;
+
+char pause = False;
+//pause the game
+
+char quit = False;
+
+char levelchanged = False;
+//has the level changed during two actions?
+
+char exit = False;
+
+char ready;
+
+char onoff = True;
+//used for timers
+
+char canswap;
+//brick already swapped?
+
+char slowyposdown = 0;
+
+char connected;
+//multiplayer activated?
+
+unsigned char receiveline = 0;
+unsigned char sendline = 0;
+//what to send or receive?
+
+char cantrans = False;
+//allowed to transfer?
+
+//taken from MonochromeLib by PierrotLL
+
+void drawbuffer(char *buffer)
+{
+ char *LCD_register_selector = (char*)0xB4000000, *LCD_data_register = (char*)0xB4010000;
+ int i, j;
+ for(i=0 ; i<64 ; i++)
+ {
+ *LCD_register_selector = 4;
+ *LCD_data_register = i|192;
+ *LCD_register_selector = 4;
+ *LCD_data_register = 0;
+ *LCD_register_selector = 7;
+ for(j=0 ; j<16 ; j++) *LCD_data_register = *buffer++;
+ }
+}
+
+void RestGray(void)
+{
+ drawbuffer(pScreen);
+ drawbuffer(pScreen + 1024);
+ drawbuffer(pScreen + 2048);
+}
+
+
+void Disconnect()
+{
+ Serial_Close(1);
+ connected = False;
+}
+
+void TeacherMode()
+{
+ Timer_Uninstall(6);
+ Timer_Uninstall(7);
+ Disconnect();
+
+ App_RUN_MAT();
+}
+
+int round(float num)
+{
+ return (int) (num + 0.5);
+}
+
+void clrbuffer(char *buffer)
+{
+ memset(buffer, 0, 3072);
+}
+
+
+void CreateBlock()
+{
+ block = nextblock;
+ canswap = True;
+ nextblock = (kiss() % 7) + 1;
+ xpos = 7;
+ ypos = 3;
+ dir = 0;
+ left = True;
+ right = True;
+ cantrans = True;
+}
+
+void ResetValues()
+{
+ int x,y;
+
+ char text[30];
+
+ memset(&changemap, 0, 210);
+ memset(&globalmap, 0, 210);
+
+ ypos = 3;
+ xpos = 0;
+ block = 0;
+ onoff = True;
+ levelchanged = False;
+ right = True;
+ left = True;
+ hold = 0;
+ exit = False;
+ nextdir = Down;
+ nextblock = (kiss() % 7) + 1;
+ CreateBlock();
+ clrbuffer(pScreen);
+ Timer_Uninstall(6);
+ Timer_Uninstall(7);
+ ready = True;
+ connected = False;
+
+ AllClr_DDVRAM();
+
+ PopUpWin(2);
+ sprintf(&text, "Points: %d", points);
+ locate(3, 3);
+ Print(&text);
+ sprintf(&text, "Level: %d", level);
+ locate(3, 4);
+ Print(&text);
+ PutDisp_DD();
+
+ points = 0;
+ level = 0;
+
+ while(!KeyDown(31));
+}
+
+void Transfer()
+{
+ int xcount, ycount;
+ char space = kiss() % 10; //where is the hole?
+
+ if(connected == True)
+ {
+ if(receiveline > sendline)
+ {
+ //if there are lines arriving, but there can be send lines back, erase the lines, for example: receiving 3 lines, sending 1 -> 0 are send, 2 are received
+ receiveline -= sendline;
+ sendline = 0;
+ }
+ else
+ {
+ sendline -= receiveline;
+ receiveline = 0;
+ }
+ if(sendline > 0)
+ {
+ while(Serial_BufferedTransmitOneByte(sendline) != 0);
+ //send the number of lines
+ sendline = 0;
+ }
+ if(receiveline > 0)
+ {
+ for(ycount = 0; ycount < 20 - receiveline; ycount++)
+ {
+ for(xcount = 0; xcount < 10; xcount++)
+ {
+ globalmap[ycount][xcount] = globalmap[ycount + receiveline][xcount];
+ //move all lines upwards
+ }
+ }
+
+ for(ycount = 19; ycount > 19 - receiveline; ycount --)
+ {
+ for(xcount = 0; xcount < 10; xcount ++)
+ {
+ globalmap[ycount][xcount] = (xcount == space) ? 0 : (kiss() % 7) + 1;
+ //add lines at the bottom
+ }
+ }
+ receiveline = 0;
+ }
+ }
+}
+
+void receive(void)
+{
+ unsigned char receiveadd = 0;
+
+ if(Serial_ReadOneByte(&receiveadd) != 0)
+ {
+ receiveadd = 0;
+ }
+
+ receiveline += (receiveadd > 20)?0:receiveadd;
+}
+
+void Connect()
+{
+ unsigned char connstart = 111;
+ unsigned char answer;
+ char open_mode[6];
+
+ PopUpWin(1);
+ locate( 5 , 4);
+ Print("Connecting...");
+ PutDisp_DD();
+
+ open_mode[ 0 ] = 0; // always 0
+ open_mode[ 1 ] = 9; // 0=300, 1=600, 2=1200, 3=2400, 4=4800, 5=9600, 6=19200, 7=38400, 8=57600, 9=115200 baud
+ open_mode[ 2 ] = 2; // parity: 0=no; 1=odd; 2=even
+ open_mode[ 3 ] = 0; // datalength: 0=8 bit; 1=7 bit
+ open_mode[ 4 ] = 0; // stop bits: 0=one; 1=two
+ open_mode[ 5 ] = 0; // always 0
+
+ Serial_Open( &open_mode );
+
+ do
+ {
+ Serial_BufferedTransmitOneByte(connstart);
+ Serial_ReadOneByte(&answer);
+ }while(answer != connstart && !KeyDown(47));
+
+ if(!KeyDown(47))connected = True;
+
+ if(connected != True)
+ {
+ Disconnect();
+ }
+}
+
+void SwapPieces()
+{
+ char save;
+ if(canswap == True)
+ {
+ save = block;
+ if(hold == 0)
+ {
+ block = nextblock;
+ nextblock = (kiss() % 7) + 1;
+ }
+ else
+ {
+ block = hold;
+ }
+ hold = save;
+ xpos = 7;
+ ypos = 3;
+ dir = 0;
+ }
+ canswap = False;
+}
+
+void Rotate()
+{
+ if(++dir == 4)
+ {
+ dir = 0;
+ }
+
+ if(DrawSprite() == False)
+ {
+ dir = (dir == 0)? 3 : dir - 1;
+ }
+}
+
+void MoveBlock()
+{
+ switch (nextdir)
+ {
+ case Left : if(left == True) {xpos ++;} nextdir = Down;break;
+ case Right: if(right == True){xpos --;}nextdir = Down;break;
+ case Rot : Rotate();nextdir = Down;break;
+ case Swap: SwapPieces();nextdir = Down;break;
+ }
+
+ if(nextdir == Fast && (int)slowyposdown == slowyposdown)
+ {
+ points += 1;
+ }
+}
+
+void CheckPoints()
+{
+ char typecount = 0;
+ char oldlevel;
+ int xcount, ycount;
+ int ycount2, ycount3;
+ char fulllinecount = 0;
+
+ for(xcount = 0; xcount < 10; xcount ++)
+ {
+ if(globalmap[0][xcount] != 0)
+ {
+ exit = True;
+ //game over
+ }
+ }
+
+ for(ycount = 0; ycount < 20; ycount ++)
+ {
+ fulllinecount = 0;
+ for(xcount = 0; xcount < 10; xcount ++)
+ {
+ if(globalmap[ycount][xcount] != 0)
+ {
+ fulllinecount ++;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if(fulllinecount == 10)
+ {
+ typecount ++;
+
+ //1: single, 2: double, 3: triple line, 4: tetris (maximum)
+
+ for(ycount2 = ycount; ycount2 > 0; ycount2 --)
+ {
+ for(xcount = 0; xcount < 10; xcount ++)
+ {
+ globalmap[ycount2][xcount] = globalmap[ycount2 - 1][xcount];
+ //move averything
+ }
+ }
+
+ line(pScreen, 0 , 0 , 81 , 0, 1);
+ line(pScreen, 0 , 0 , 0 , 41, 1);
+ line(pScreen, 81 , 0 , 81 , 41, 1);
+ line(pScreen, 81 , 41 , 0 , 41, 1);
+
+ for(ycount3 = 0; ycount3 < 20; ycount3 ++)
+ {
+ for(xcount = 0; xcount < 10; xcount ++)
+ {
+ if(globalmap[ycount3][xcount] != 0 || changemap[ycount3][xcount] != 0)
+ {
+ fillbox(pScreen, ycount3, xcount, (globalmap[ycount3][xcount] != 0)? globalmap[ycount3][xcount] - 1 : changemap[ycount3][xcount] - 1);
+ }
+ }
+ }
+ }
+ }
+ if(typecount > 0)
+ {
+ int blink;
+
+ points += (typecount == 1)? 40 * (level + 1): (typecount == 2)? 100 * level : (typecount == 3)? 300 *(level + 1): (typecount == 4)? 1200 * (level + 1) : 0;
+ //increment points
+
+ sendline = (typecount == 4)? 4 : typecount - 1;
+ //send a line, if not tetris send lines - 1
+ oldlevel = level;
+ level += typecount;
+ if((int)(level / 10) != (int)(oldlevel / 10) && level < 200)
+ {
+ levelchanged = True;
+ //level = round cleared lines / 10
+ }
+ }
+ Transfer();
+}
+
+void ReadKey()
+{
+ nextdir =Down;
+
+ if(KeyDown(38)) nextdir = Rot;
+ if(KeyDown(37)) nextdir = Left ;
+ if(KeyDown(28)) nextdir = Right;
+ if(KeyDown(27)) nextdir = Fast;
+ if(KeyDown(47)) exit = True;
+ if(KeyDown(26)) nextdir = Swap;
+ if(KeyDown(31)) TeacherMode();
+ if(KeyDown(39)) {pause = (pause == True)? False : True; while(KeyDown(39));}
+}
+
+void Main(void)
+{
+ cantrans = False;
+ ready = False;
+ if(pause == False)
+ {
+ receive();
+ ypos += (slowyposdown % 10 == 0 || nextdir == Fast)? 1 : 0;
+ if(nextdir == Left || nextdir == Right || nextdir == Fast || nextdir == Rot || slowyposdown % 10 == 0)
+ {
+ MoveBlock();
+ DrawBlock();
+ if(cantrans == True)
+ {
+ CheckPoints();
+ DrawBlock();
+ }
+ }
+ slowyposdown++;
+ }
+ ready = True;
+ drawNumber(pScreen, connected, 0, 62);
+ drawNumber(pScreen + 1024, connected, 0, 62);
+ drawNumber(pScreen + 2048, connected, 0, 62);
+}
+
+void CallMain(void)
+{
+ ReadKey();
+ if(nextdir == Fast && onoff == False)
+ {
+ while(ready == False);
+ onoff = True;
+ Timer_Uninstall(7);
+ Timer_Install(7, &Main, 50);
+ Timer_Start(7);
+ if(nextdir == Down)
+ {
+ nextdir = Fast;
+ }
+ }
+ else
+ {
+ if(nextdir != Fast && onoff == True || levelchanged == True)
+ {
+ while(ready == False);
+ onoff = False;
+ Timer_Uninstall(7);
+
+ if(level < 20)
+ {
+ Timer_Install(7, &Main, 100 - level * 5);
+ }
+ else
+ {
+ Timer_Install(7, &Main, 0);
+ }
+
+ Timer_Start(7);
+ levelchanged = False;
+ }
+ }
+}
+
+//the code above is not good, CallMain handles the keys and sets the timer of Main
+
+void ReadMenuKeys()
+{
+ if(KeyDown(31)) TeacherMode();
+ if(KeyDown(47)) quit = True;
+}
+
+int AddIn_main(int isAppli, unsigned short OptionNum)
+{
+ char c[] = {0xE6, 0x9B, 0};
+ char mode = 0;
+
+ level = 0;
+
+ pScreen = (char*)malloc(3072);
+
+ nextblock = (kiss() % 7) + 1;
+ CreateBlock();
+
+ ready = True;
+
+ APP_EnableRestart();//thx to SimonLothar
+
+ seedkiss();//seed random numbers
+
+ while(mode != 3)
+ {
+ quit = False;
+ Timer_Install(10, &ReadMenuKeys, 200);
+ Timer_Start(10);
+ while(!KeyDown(31) && mode != 3)
+ {
+ AllClr_VRAM();
+
+ locate( 6, 3 );
+ Print(&"Singleplayer");
+ locate( 6, 4 );
+ Print(&"Multiplayer");
+ locate( 2, 8);
+ Print(&"Copyright by Casimo");
+
+ locate( 4, 3 + mode);
+ PrintC(&c);
+
+ PutDisp_DD();
+
+ if(KeyDown(37))
+ {
+ mode += (mode == 1)? -1 : 1;
+ while(KeyDown(37));
+ }
+ else
+ {
+ if(KeyDown(28))
+ {
+ mode -= (mode == 0)? -1 : 1;
+ while(KeyDown(28));
+ }
+ else
+ {
+ if(KeyDown(47))
+ {
+ mode = 3;
+ while(KeyDown(47));
+ }
+ }
+
+ }
+ }
+
+ Timer_Uninstall(10);
+
+ if(mode != 3)
+ {
+ if(mode == 1)
+ {
+ Serial_ClearReceiveBuffer();
+ Connect();
+ }
+
+ Timer_Install(6,&CallMain, 150);
+ Timer_Start(6);
+
+ while(exit == False){RestGray();}
+
+ ResetValues();
+
+ while(KeyDown(47));
+ while(KeyDown(31));
+ }
+ }
+ Timer_Uninstall(6);
+ Timer_Uninstall(7);
+ Disconnect();
+ free(pScreen);
+}
+
+//I'm sure there are unused variables
+
+#pragma section _BR_Size
+unsigned long BR_Size;
+#pragma section
+#pragma section _TOP
+int InitializeSystem(int isAppli, unsigned short OptionNum)
+{return INIT_ADDIN_APPLICATION(isAppli, OptionNum);}
+#pragma section