Advertisement
Guest User

EE 47 Kevin Zheng Final Project Code (Arduino Master)

a guest
Jun 4th, 2013
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 15.71 KB | None | 0 0
  1. #include <SPI.h>
  2. #include <Adafruit_GFX.h>
  3. #include <Adafruit_ST7735.h>
  4.  
  5. //SRAM opcodes
  6. #define RDSR        5
  7. #define WRSR        1
  8. #define READ        3
  9. #define WRITE       2
  10.  
  11. #define SD_SS 7
  12. #define RAM_SS 5
  13. #define GFX_SS 6
  14. #define GFX_DC 8
  15. #define GFX_RST 9
  16.  
  17. #define MAP_OFFSET 2048
  18. #define SPRITE_OFFSET 1024
  19.  
  20. #define TILEINFO_START 2066
  21.  
  22. #define ERROR_LCD 13
  23.  
  24. #include <Wire.h>
  25. #define SLAVE_ADDR 88
  26.  
  27. //  Wire Commands
  28. #define INIT 1
  29. #define INIT2 2
  30. #define ALIVE 0
  31. #define CHANGESONG 80
  32.  
  33. #define BUFFER_SIZE 32
  34.  
  35. int colors[] = {
  36.   0x0000,0x5AEB,0xA534,0xF7BE};
  37.  
  38. unsigned int mapIndexes[] = {
  39.   2635,4747,6199,6694,8226,8425,8797,9169,10701,11541,13033,14605,16777,17869,18961,20053,20925,24825,25950,27082,29182,31494,33306,34158,38230,38962,40054,41344,43156,44140,45196,45648,46740,47952,49404,50886};
  40.  
  41. unsigned char flyInfo[] = {
  42.   0,41,13,1,19,18,2,14,12,3,19,30,4,4,5,5,3,6,6,5,6,7,13,28,9,11,22,27,11,8,33,9,30,34,13,4,35,23,26};
  43. unsigned char flyNo = 0;
  44. unsigned char canFly = 1;
  45.  
  46. Adafruit_ST7735 tft = Adafruit_ST7735(GFX_SS, GFX_DC, GFX_RST);
  47.  
  48. unsigned char currentMap = 0;
  49. int xPos = 8;
  50. int yPos = 8;
  51.  
  52. unsigned char keysDown;
  53. unsigned char direction;
  54. unsigned char moveState;
  55. unsigned char reflectCounter;
  56.  
  57. #define LEFT   0
  58. #define UP     1
  59. #define RIGHT  2
  60. #define DOWN   3
  61.  
  62. unsigned char mapBuffer[12][10];
  63. unsigned char mapBufXStart = 0;
  64. unsigned char mapBufYStart = 0;
  65.  
  66. unsigned char passability[] = {
  67.   0xAF,0x3D,0xEF,0xEF,0x7F,0xFD,0xFD,0xBE,0x00,0x00,0x31,0x97,0xEE,0xBF,0xCF,0xFF,0xF5,0xFC};
  68.  
  69. //  Screen Layout (10x8 shown, 1 block border for buffer)
  70. //   4
  71. // 5 C 6
  72. //   5
  73.  
  74. void setup()
  75. {
  76.   Serial.begin(9600);
  77.   pinMode(ERROR_LCD, OUTPUT);
  78.   pinMode(RAM_SS, OUTPUT);
  79.   pinMode(A0, INPUT);
  80.   pinMode(A1, INPUT);
  81.   SPI.begin();
  82.   tft.initR(INITR_BLACKTAB);
  83.   tft.fillScreen(0xFFFF);
  84.   tft.setRotation(3);
  85.   //  Read sprite info
  86.   delay(6000);
  87.   Wire.begin();
  88.  
  89.   tft.setCursor(0, 0);
  90.   tft.setTextColor(0x0000);
  91.   tft.setTextWrap(true);
  92.   tft.println("Loading");
  93.  
  94.  
  95.   int connected = 0;
  96.   while(!connected)
  97.   {
  98.     Wire.beginTransmission(SLAVE_ADDR);
  99.     Wire.write(ALIVE);  
  100.     Wire.endTransmission();
  101.     Wire.requestFrom(SLAVE_ADDR,1,false);
  102.     connected = Wire.read();
  103.   }
  104.  
  105.   unsigned int receivedBytes = 0;
  106.   unsigned int receivedBytes2 = 0;
  107.   Wire.beginTransmission(88);
  108.   Wire.write(INIT);  
  109.   Wire.endTransmission();
  110.   while(receivedBytes < 52333)
  111.   {
  112.     digitalWrite(ERROR_LCD,HIGH);
  113.     Wire.requestFrom(SLAVE_ADDR,BUFFER_SIZE);
  114.     while(Wire.available()<BUFFER_SIZE){
  115.     };
  116.     for(unsigned int i = 0; i < BUFFER_SIZE && receivedBytes < 52333; i++)
  117.     {
  118.       unsigned char val = Wire.read();
  119.       Spi23LC1024Write8(receivedBytes + MAP_OFFSET, val);  
  120.       receivedBytes++;
  121.     }  
  122.     if(receivedBytes%1000==0)
  123.     {
  124.       tft.print(receivedBytes/1000);
  125.     }
  126.     delay(1);
  127.   }
  128.   Wire.beginTransmission(88);
  129.   Wire.write(INIT2);  
  130.   Wire.endTransmission();
  131.   while(receivedBytes2 < 576)
  132.   {
  133.     Wire.requestFrom(SLAVE_ADDR,BUFFER_SIZE);
  134.     while(Wire.available()<BUFFER_SIZE){
  135.     };
  136.     for(unsigned int i = 0; i < BUFFER_SIZE && receivedBytes2 < 576; i++)
  137.     {
  138.       unsigned char val = Wire.read();
  139.       Spi23LC1024Write8(receivedBytes2 + SPRITE_OFFSET, val);  
  140.       receivedBytes2++;
  141.     }  
  142.     delay(1);
  143.   }
  144.   digitalWrite(ERROR_LCD,LOW);
  145.   //Load mapBuffer
  146.   fly();
  147. }
  148.  
  149. void fly()
  150. {
  151.   if(canFly)
  152.   {
  153.     currentMap = flyInfo[flyNo*3];
  154.     xPos = flyInfo[flyNo*3+1];
  155.     yPos = flyInfo[flyNo*3+2];
  156.     for(unsigned char x = 0; x < 12; x++)
  157.     {
  158.       for(unsigned char y = 0; y < 10; y++)
  159.       {
  160.         mapBuffer[x][y] = getTileValue(currentMap, xPos - 5 + x, yPos - 4 + y);
  161.       }
  162.     }
  163.     mapBufXStart = 0;
  164.     mapBufYStart = 0;
  165.     setSong(getMemMapInfo(currentMap,11));
  166.     updateSpriteInfo();  
  167.     canFly = 0;
  168.     flyNo++;
  169.     flyNo%=13;
  170.   }
  171. }
  172.  
  173. void setSong(int songID)
  174. {
  175.   Wire.beginTransmission(88);
  176.   Wire.write(CHANGESONG+songID);  
  177.   Wire.endTransmission();
  178. }
  179.  
  180. void loop()
  181. {
  182.   drawLoop();
  183. }
  184.  
  185. #define KEY_THRESH 4
  186.  
  187. void pollButtons()
  188. {
  189.   int padRead = analogRead(A1);
  190.   int buttonRead = analogRead(A0);
  191.  
  192.   //  DPAD
  193.   if(padRead < 100)
  194.   {
  195.     keysDown &= 0x0F;  
  196.   }
  197.   else if(abs(padRead-512)<KEY_THRESH)
  198.   {
  199.     keysDown = (keysDown & 0x0F) | 0x80;
  200.   }
  201.   else if(abs(padRead-338)<KEY_THRESH)
  202.   {
  203.     digitalWrite(ERROR_LCD,HIGH);
  204.     keysDown = (keysDown & 0x0F) | 0x40;
  205.   }
  206.   else if(abs(padRead-250)<KEY_THRESH)
  207.   {
  208.     keysDown = (keysDown & 0x0F) | 0x20;
  209.   }
  210.   else if(abs(padRead-204)<KEY_THRESH)
  211.   {
  212.     keysDown = (keysDown & 0x0F) | 0x10;
  213.   }
  214.  
  215.   //  BUTTONS
  216.   if(buttonRead < 100)
  217.   {
  218.     keysDown &= 0xF0;  
  219.   }
  220.   else if(abs(buttonRead-512)<KEY_THRESH)
  221.   {
  222.     keysDown = (keysDown & 0xF0) | 0x08;
  223.   }
  224.   else if(abs(buttonRead-338)<KEY_THRESH)
  225.   {
  226.     keysDown = (keysDown & 0xF0) | 0x04;
  227.   }
  228.   else if(abs(buttonRead-250)<KEY_THRESH)
  229.   {
  230.     keysDown = (keysDown & 0xF0) | 0x02;
  231.   }
  232.   else if(abs(buttonRead-204)<KEY_THRESH)
  233.   {
  234.     keysDown = (keysDown & 0xF0) | 0x01;
  235.   }
  236. }
  237.  
  238. unsigned char spriteNo = -1;
  239. unsigned char reflect = -1;
  240.  
  241. void updateSpriteInfo()
  242. {
  243.   switch(direction)
  244.   {
  245.   case LEFT:
  246.     spriteNo = 2+(moveState == 3?3:0);
  247.     reflect = 0;
  248.     break;
  249.   case UP:
  250.     spriteNo = 1+(moveState == 3?3:0);
  251.     reflect = reflectCounter;
  252.     break;
  253.   case RIGHT:
  254.     spriteNo = 2+(moveState == 3?3:0);
  255.     reflect = 1;
  256.     break;
  257.   case DOWN:
  258.     spriteNo = 0+(moveState == 3?3:0);
  259.     reflect = reflectCounter;
  260.     break;
  261.   }
  262. }
  263.  
  264. void drawLoop()
  265. {
  266.   pollButtons();
  267.   if(moveState == 0)
  268.   {
  269.     if((keysDown&0x80)==0x80)
  270.     {
  271.       unsigned char leftTile = getMapBufferValue(4,4);
  272.       if(((passability[leftTile/8]>>(7-leftTile%8))&0x1)==0)
  273.       {
  274.         moveState++;
  275.         direction=LEFT;
  276.         updateSpriteInfo();
  277.       }
  278.       canFly = 1;
  279.     }
  280.     else if((keysDown&0x40)==0x40)
  281.     {
  282.       unsigned char upTile = getMapBufferValue(5,3);
  283.       if(((passability[upTile/8]>>(7-upTile%8))&0x1)==0)
  284.       {
  285.         moveState++;
  286.         direction=UP;
  287.         updateSpriteInfo();
  288.       }
  289.       canFly = 1;
  290.     }
  291.     else if((keysDown&0x20)==0x20)
  292.     {
  293.       unsigned char rightTile = getMapBufferValue(6,4);
  294.       if(((passability[rightTile/8]>>(7-rightTile%8))&0x1)==0)
  295.       {
  296.         moveState++;
  297.         direction=RIGHT;
  298.         updateSpriteInfo();
  299.       }
  300.       canFly = 1;
  301.     }
  302.     else if((keysDown&0x10)==0x10)
  303.     {
  304.       unsigned char downTile = getMapBufferValue(5,5);
  305.       if(((passability[downTile/8]>>(7-downTile%8))&0x1)==0)
  306.       {
  307.         moveState++;
  308.         direction=DOWN;
  309.         updateSpriteInfo();
  310.       }
  311.       canFly = 1;
  312.     }
  313.     else if((keysDown&0x0F)!=0 && canFly == 1)
  314.     {
  315.       fly();  
  316.     }
  317.   }  
  318.   else
  319.   {
  320.     moveState+=1;
  321.     updateSpriteInfo();
  322.     if(moveState == 4)
  323.     {
  324.       if(direction == LEFT)
  325.       {
  326.         xPos--;
  327.         if(xPos < 0)
  328.         {
  329.           unsigned char leftMapID = getMemMapInfo(currentMap,2);
  330.           if(leftMapID<100)
  331.           {
  332.             unsigned char leftMapShift = getMemMapInfo(currentMap,3);
  333.             unsigned char leftMapWidth = getMemMapInfo(leftMapID,0);
  334.             currentMap = leftMapID;
  335.             setSong(getMemMapInfo(currentMap,11));
  336.             xPos = leftMapWidth+xPos;
  337.             yPos -= leftMapShift;
  338.           }    
  339.         }
  340.       }
  341.       else if(direction == UP)
  342.       {
  343.         yPos--;
  344.         if(yPos < 0)
  345.         {
  346.           unsigned char upMapID = getMemMapInfo(currentMap,4);
  347.           if(upMapID<100)
  348.           {
  349.             unsigned char upMapShift = getMemMapInfo(currentMap,5);
  350.             unsigned char upMapHeight = getMemMapInfo(upMapShift,1);
  351.             currentMap = upMapID;
  352.             setSong(getMemMapInfo(currentMap,11));
  353.             xPos -= upMapShift;
  354.             yPos = upMapHeight+yPos;
  355.           }    
  356.         }
  357.       }
  358.       else if(direction == RIGHT)
  359.       {
  360.         xPos++;
  361.         unsigned char mapWidth = getMemMapInfo(currentMap,0);
  362.         if(xPos>=mapWidth)
  363.         {
  364.           unsigned char rightMapID = getMemMapInfo(currentMap,6);
  365.           if(rightMapID<100)
  366.           {
  367.             unsigned char rightMapShift = getMemMapInfo(currentMap,7);
  368.             currentMap = rightMapID;
  369.             setSong(getMemMapInfo(currentMap,11));
  370.             xPos -= mapWidth;
  371.             yPos -= rightMapShift;
  372.           }
  373.         }
  374.       }
  375.       else if(direction == DOWN)
  376.       {
  377.         yPos++;
  378.         unsigned char mapHeight = getMemMapInfo(currentMap,1);
  379.         if(yPos>=mapHeight)
  380.         {
  381.           unsigned char downMapID = getMemMapInfo(currentMap,8);
  382.           if(downMapID<100)
  383.           {
  384.             unsigned char downMapShift = getMemMapInfo(currentMap,9);
  385.             currentMap = downMapShift;
  386.             setSong(getMemMapInfo(currentMap,11));
  387.             yPos -= mapHeight;
  388.             xPos -= downMapShift;
  389.           }
  390.         }
  391.       }
  392.       updateMapBuffer(direction);
  393.       moveState = 0;
  394.       reflectCounter++;
  395.       reflectCounter%=2;
  396.     }
  397.   }
  398.   //  Draw sprite
  399.   drawScreen();
  400.   drawSprite();
  401. }
  402.  
  403. void drawSprite()
  404. {
  405.   for(unsigned char i = 0; i < 64; i++)
  406.   {
  407.     unsigned char dataByte = Spi23LC1024Read8(spriteNo * 64 + SPRITE_OFFSET + i);
  408.     unsigned char transByte;
  409.     if(i%2==0)
  410.     {
  411.       transByte = Spi23LC1024Read8(spriteNo * 32 +384+ SPRITE_OFFSET + i/2);
  412.     }
  413.     for(unsigned char j = 0; j < 4; j++)
  414.     {
  415.       if(!(transByte&0x1))
  416.       {
  417.         unsigned char currentColorIndex = (dataByte >> (j*2)) & 0x3;
  418.         tft.drawPixel((reflect==0)?(i%4)*4+j+64:(15 - ((i%4)*4+j))+64, i/4+48, colors[currentColorIndex]);  
  419.       }
  420.       transByte>>=1;
  421.     }
  422.   }  
  423. }
  424.  
  425.  
  426. void drawPixel(int x, int y, unsigned int color)
  427. {
  428.   if(x < 0 || x >= 160 || y < 0 || y >=  128)
  429.   {
  430.     return;  
  431.   }
  432.   else
  433.   {
  434.     tft.drawPixel(x,y,color);
  435.   }
  436. }
  437.  
  438. void loadTileColors(unsigned char tileID, unsigned int colorArray[][16])
  439. {
  440.   unsigned char tilePieces[4];
  441.   tilePieces[0] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET);
  442.   tilePieces[1] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET+1);
  443.   tilePieces[2] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET+2);
  444.   tilePieces[3] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET+3);
  445.   for(unsigned char i = 0; i < 4; i++)
  446.   {
  447.     unsigned char baseX = (i%2) * 8;
  448.     unsigned char baseY = (i/2) * 8;
  449.     for(unsigned char byteNo = 0; byteNo < 16; byteNo++)
  450.     {
  451.       unsigned char readByte = Spi23LC1024Read8(1 + tilePieces[i]*16+byteNo + MAP_OFFSET);
  452.       for(unsigned char twoBitNo = 0; twoBitNo < 4; twoBitNo++)
  453.       {
  454.         colorArray[baseX + twoBitNo + (byteNo%2)*4][baseY + byteNo/2] = colors[(readByte >> (3-twoBitNo)) & 0x03];
  455.       }
  456.     }  
  457.   }
  458. }
  459.  
  460. unsigned char getMapBufferValue(unsigned char x, unsigned char y)
  461. {
  462.   return mapBuffer[(x+mapBufXStart)%12][(y+mapBufYStart)%10];
  463. }
  464.  
  465. void drawScreen()
  466. {
  467.   char xOffset = (direction==LEFT?1:(direction==RIGHT?-1:0))*moveState*4;
  468.   char yOffset = (direction==UP?1:(direction==DOWN?-1:0))*moveState*4;
  469.   unsigned char seenTiles[16];
  470.   unsigned char numSeenTiles = 0;
  471.   unsigned int currentTileColors[16][16];
  472.   for(unsigned char x = 0; x < 12; x++)
  473.   {
  474.     for(unsigned char y = 0; y < 10; y++)
  475.     {
  476.       unsigned char currentMapBufValue = getMapBufferValue(x,y);
  477.       boolean seen = false;
  478.       for(unsigned char a = 0; a < numSeenTiles && !seen; a++)
  479.       {
  480.         if(seenTiles[a] == currentMapBufValue)
  481.         {
  482.           seen = true;
  483.         }
  484.       }
  485.       if(!seen)
  486.       {
  487.         seenTiles[numSeenTiles] = currentMapBufValue;
  488.         numSeenTiles++;
  489.         loadTileColors(currentMapBufValue,currentTileColors);
  490.         for(unsigned char x2 = 0; x2 < 12; x2++)
  491.         {
  492.           for(unsigned char y2 = 0; y2 < 10; y2++)
  493.           {
  494.             unsigned char innerMapBufValue = getMapBufferValue(x2,y2);
  495.             if(currentMapBufValue == innerMapBufValue)
  496.             {
  497.               for(unsigned char xTile = 0; xTile < 16; xTile++)
  498.               {
  499.                 for(unsigned char yTile = 0; yTile < 16; yTile++)
  500.                 {
  501.                   drawPixel(xOffset+(x2-1)*16+xTile,yOffset+(y2-1)*16+yTile,currentTileColors[xTile][yTile]);
  502.                 }
  503.               }
  504.             }
  505.           }
  506.         }
  507.       }
  508.     }  
  509.   }
  510. }
  511.  
  512. void updateMapBuffer(unsigned char updateDir)
  513. {
  514.   if(updateDir == LEFT)
  515.   {
  516.     mapBufXStart = (mapBufXStart + 11)%12;
  517.     for(unsigned char i = 0; i < 10; i++)
  518.     {
  519.       mapBuffer[mapBufXStart][(mapBufYStart+i)%10] = getTileValue(currentMap,xPos-5,yPos-4+i);
  520.     }
  521.   }  
  522.   else if(updateDir == UP)
  523.   {
  524.     mapBufYStart = (mapBufYStart + 9)%10;
  525.     for(unsigned char i = 0; i < 12; i++)
  526.     {
  527.       mapBuffer[(mapBufXStart+i)%12][mapBufYStart] = getTileValue(currentMap,xPos-5+i,yPos-4);
  528.     }
  529.   }  
  530.   else if(updateDir == RIGHT)
  531.   {
  532.     for(unsigned char i = 0; i < 10; i++)
  533.     {
  534.       mapBuffer[mapBufXStart][(mapBufYStart+i)%10] = getTileValue(currentMap,xPos+6,yPos-4+i);
  535.     }
  536.     mapBufXStart = (mapBufXStart + 1)%12;
  537.   }  
  538.   else if(updateDir == DOWN)
  539.   {
  540.     for(unsigned char i = 0; i < 12; i++)
  541.     {
  542.       mapBuffer[(mapBufXStart+i)%12][mapBufYStart] = getTileValue(currentMap,xPos-5+i,yPos+5);
  543.     }
  544.     mapBufYStart = (mapBufYStart + 1)%10;
  545.   }
  546. }
  547.  
  548.  
  549. uint8_t Spi23LC1024Read8(uint32_t address)
  550. {
  551.   uint8_t read_byte;
  552.   digitalWrite(RAM_SS,LOW);
  553.   SPI.transfer(READ);
  554.   SPI.transfer((uint8_t)(address >> 16) & 0xff);
  555.   SPI.transfer((uint8_t)(address >> 8) & 0xff);
  556.   SPI.transfer((uint8_t)address);
  557.   read_byte = SPI.transfer(0x00);
  558.   digitalWrite(RAM_SS,HIGH);
  559.   return read_byte;
  560. }
  561.  
  562. void Spi23LC1024Write8(uint32_t address, uint8_t data_byte)
  563. {
  564.   digitalWrite(RAM_SS,LOW);
  565.   SPI.transfer(WRITE);
  566.   SPI.transfer((uint8_t)(address >> 16) & 0xff);
  567.   SPI.transfer((uint8_t)(address >> 8) & 0xff);
  568.   SPI.transfer((uint8_t)address);
  569.   SPI.transfer(data_byte);
  570.   digitalWrite(RAM_SS,HIGH);
  571. }
  572.  
  573. unsigned char getMemMapInfo(unsigned char map, unsigned int index)
  574. {
  575.   return Spi23LC1024Read8(mapIndexes[map] + MAP_OFFSET + index);
  576. }
  577.  
  578. unsigned char getTileValue(unsigned char map, int xCoord, int yCoord)
  579. {
  580.   unsigned char width = getMemMapInfo(map,0);
  581.   unsigned char height = getMemMapInfo(map,1);
  582.   if(xCoord < 0)
  583.   {
  584.     unsigned char leftMapID = getMemMapInfo(map,2);
  585.     if(leftMapID == 255)
  586.     {
  587.       return getMemMapInfo(map,10);
  588.     }
  589.     unsigned char leftMapOffset = getMemMapInfo(map,3);
  590.     unsigned char leftMapWidth = getMemMapInfo(leftMapID,0);
  591.     return getTileValue(leftMapID,leftMapWidth-1+xCoord, yCoord-leftMapOffset);
  592.   }
  593.   else if(xCoord >= width)
  594.   {
  595.     unsigned char rightMapID = getMemMapInfo(map,6);
  596.     if(rightMapID == 255)
  597.     {
  598.       return getMemMapInfo(map,10);
  599.     }
  600.     int rightMapOffset = getMemMapInfo(map,7);
  601.     return getTileValue(rightMapID, xCoord-width , yCoord-rightMapOffset);
  602.   }
  603.   else if(yCoord < 0)
  604.   {
  605.     unsigned char upMapID = getMemMapInfo(map,4);
  606.     if(upMapID == 255)
  607.     {
  608.       return getMemMapInfo(map,10);
  609.     }
  610.     unsigned char upMapOffset = getMemMapInfo(map,5);
  611.     unsigned char upMapHeight = getMemMapInfo(upMapID,1);
  612.     return getTileValue(upMapID,xCoord - upMapOffset,upMapHeight-1+yCoord);
  613.   }
  614.   else if(yCoord >= height)
  615.   {
  616.     unsigned char downMapID = getMemMapInfo(map,8);
  617.     if(downMapID == 255)
  618.     {
  619.       return getMemMapInfo(map,10);
  620.     }
  621.     unsigned char downMapOffset = getMemMapInfo(map,9);
  622.     return getTileValue(downMapID,xCoord - downMapOffset,yCoord-height);
  623.   }
  624.   else
  625.   {
  626.     return getMemMapInfo(map,12+xCoord+yCoord*width);
  627.   }
  628. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement