diff options
Diffstat (limited to 'src/Matris.c')
| -rw-r--r-- | src/Matris.c | 635 |
1 files changed, 635 insertions, 0 deletions
diff --git a/src/Matris.c b/src/Matris.c new file mode 100644 index 0000000..f2f6991 --- /dev/null +++ b/src/Matris.c @@ -0,0 +1,635 @@ +/*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
|
