Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <SPI.h>
- #include <Adafruit_GFX.h>
- #include <Adafruit_ST7735.h>
- //SRAM opcodes
- #define RDSR 5
- #define WRSR 1
- #define READ 3
- #define WRITE 2
- #define SD_SS 7
- #define RAM_SS 5
- #define GFX_SS 6
- #define GFX_DC 8
- #define GFX_RST 9
- #define MAP_OFFSET 2048
- #define SPRITE_OFFSET 1024
- #define TILEINFO_START 2066
- #define ERROR_LCD 13
- #include <Wire.h>
- #define SLAVE_ADDR 88
- // Wire Commands
- #define INIT 1
- #define INIT2 2
- #define ALIVE 0
- #define CHANGESONG 80
- #define BUFFER_SIZE 32
- int colors[] = {
- 0x0000,0x5AEB,0xA534,0xF7BE};
- unsigned int mapIndexes[] = {
- 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};
- unsigned char flyInfo[] = {
- 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};
- unsigned char flyNo = 0;
- unsigned char canFly = 1;
- Adafruit_ST7735 tft = Adafruit_ST7735(GFX_SS, GFX_DC, GFX_RST);
- unsigned char currentMap = 0;
- int xPos = 8;
- int yPos = 8;
- unsigned char keysDown;
- unsigned char direction;
- unsigned char moveState;
- unsigned char reflectCounter;
- #define LEFT 0
- #define UP 1
- #define RIGHT 2
- #define DOWN 3
- unsigned char mapBuffer[12][10];
- unsigned char mapBufXStart = 0;
- unsigned char mapBufYStart = 0;
- unsigned char passability[] = {
- 0xAF,0x3D,0xEF,0xEF,0x7F,0xFD,0xFD,0xBE,0x00,0x00,0x31,0x97,0xEE,0xBF,0xCF,0xFF,0xF5,0xFC};
- // Screen Layout (10x8 shown, 1 block border for buffer)
- // 4
- // 5 C 6
- // 5
- void setup()
- {
- Serial.begin(9600);
- pinMode(ERROR_LCD, OUTPUT);
- pinMode(RAM_SS, OUTPUT);
- pinMode(A0, INPUT);
- pinMode(A1, INPUT);
- SPI.begin();
- tft.initR(INITR_BLACKTAB);
- tft.fillScreen(0xFFFF);
- tft.setRotation(3);
- // Read sprite info
- delay(6000);
- Wire.begin();
- tft.setCursor(0, 0);
- tft.setTextColor(0x0000);
- tft.setTextWrap(true);
- tft.println("Loading");
- int connected = 0;
- while(!connected)
- {
- Wire.beginTransmission(SLAVE_ADDR);
- Wire.write(ALIVE);
- Wire.endTransmission();
- Wire.requestFrom(SLAVE_ADDR,1,false);
- connected = Wire.read();
- }
- unsigned int receivedBytes = 0;
- unsigned int receivedBytes2 = 0;
- Wire.beginTransmission(88);
- Wire.write(INIT);
- Wire.endTransmission();
- while(receivedBytes < 52333)
- {
- digitalWrite(ERROR_LCD,HIGH);
- Wire.requestFrom(SLAVE_ADDR,BUFFER_SIZE);
- while(Wire.available()<BUFFER_SIZE){
- };
- for(unsigned int i = 0; i < BUFFER_SIZE && receivedBytes < 52333; i++)
- {
- unsigned char val = Wire.read();
- Spi23LC1024Write8(receivedBytes + MAP_OFFSET, val);
- receivedBytes++;
- }
- if(receivedBytes%1000==0)
- {
- tft.print(receivedBytes/1000);
- }
- delay(1);
- }
- Wire.beginTransmission(88);
- Wire.write(INIT2);
- Wire.endTransmission();
- while(receivedBytes2 < 576)
- {
- Wire.requestFrom(SLAVE_ADDR,BUFFER_SIZE);
- while(Wire.available()<BUFFER_SIZE){
- };
- for(unsigned int i = 0; i < BUFFER_SIZE && receivedBytes2 < 576; i++)
- {
- unsigned char val = Wire.read();
- Spi23LC1024Write8(receivedBytes2 + SPRITE_OFFSET, val);
- receivedBytes2++;
- }
- delay(1);
- }
- digitalWrite(ERROR_LCD,LOW);
- //Load mapBuffer
- fly();
- }
- void fly()
- {
- if(canFly)
- {
- currentMap = flyInfo[flyNo*3];
- xPos = flyInfo[flyNo*3+1];
- yPos = flyInfo[flyNo*3+2];
- for(unsigned char x = 0; x < 12; x++)
- {
- for(unsigned char y = 0; y < 10; y++)
- {
- mapBuffer[x][y] = getTileValue(currentMap, xPos - 5 + x, yPos - 4 + y);
- }
- }
- mapBufXStart = 0;
- mapBufYStart = 0;
- setSong(getMemMapInfo(currentMap,11));
- updateSpriteInfo();
- canFly = 0;
- flyNo++;
- flyNo%=13;
- }
- }
- void setSong(int songID)
- {
- Wire.beginTransmission(88);
- Wire.write(CHANGESONG+songID);
- Wire.endTransmission();
- }
- void loop()
- {
- drawLoop();
- }
- #define KEY_THRESH 4
- void pollButtons()
- {
- int padRead = analogRead(A1);
- int buttonRead = analogRead(A0);
- // DPAD
- if(padRead < 100)
- {
- keysDown &= 0x0F;
- }
- else if(abs(padRead-512)<KEY_THRESH)
- {
- keysDown = (keysDown & 0x0F) | 0x80;
- }
- else if(abs(padRead-338)<KEY_THRESH)
- {
- digitalWrite(ERROR_LCD,HIGH);
- keysDown = (keysDown & 0x0F) | 0x40;
- }
- else if(abs(padRead-250)<KEY_THRESH)
- {
- keysDown = (keysDown & 0x0F) | 0x20;
- }
- else if(abs(padRead-204)<KEY_THRESH)
- {
- keysDown = (keysDown & 0x0F) | 0x10;
- }
- // BUTTONS
- if(buttonRead < 100)
- {
- keysDown &= 0xF0;
- }
- else if(abs(buttonRead-512)<KEY_THRESH)
- {
- keysDown = (keysDown & 0xF0) | 0x08;
- }
- else if(abs(buttonRead-338)<KEY_THRESH)
- {
- keysDown = (keysDown & 0xF0) | 0x04;
- }
- else if(abs(buttonRead-250)<KEY_THRESH)
- {
- keysDown = (keysDown & 0xF0) | 0x02;
- }
- else if(abs(buttonRead-204)<KEY_THRESH)
- {
- keysDown = (keysDown & 0xF0) | 0x01;
- }
- }
- unsigned char spriteNo = -1;
- unsigned char reflect = -1;
- void updateSpriteInfo()
- {
- switch(direction)
- {
- case LEFT:
- spriteNo = 2+(moveState == 3?3:0);
- reflect = 0;
- break;
- case UP:
- spriteNo = 1+(moveState == 3?3:0);
- reflect = reflectCounter;
- break;
- case RIGHT:
- spriteNo = 2+(moveState == 3?3:0);
- reflect = 1;
- break;
- case DOWN:
- spriteNo = 0+(moveState == 3?3:0);
- reflect = reflectCounter;
- break;
- }
- }
- void drawLoop()
- {
- pollButtons();
- if(moveState == 0)
- {
- if((keysDown&0x80)==0x80)
- {
- unsigned char leftTile = getMapBufferValue(4,4);
- if(((passability[leftTile/8]>>(7-leftTile%8))&0x1)==0)
- {
- moveState++;
- direction=LEFT;
- updateSpriteInfo();
- }
- canFly = 1;
- }
- else if((keysDown&0x40)==0x40)
- {
- unsigned char upTile = getMapBufferValue(5,3);
- if(((passability[upTile/8]>>(7-upTile%8))&0x1)==0)
- {
- moveState++;
- direction=UP;
- updateSpriteInfo();
- }
- canFly = 1;
- }
- else if((keysDown&0x20)==0x20)
- {
- unsigned char rightTile = getMapBufferValue(6,4);
- if(((passability[rightTile/8]>>(7-rightTile%8))&0x1)==0)
- {
- moveState++;
- direction=RIGHT;
- updateSpriteInfo();
- }
- canFly = 1;
- }
- else if((keysDown&0x10)==0x10)
- {
- unsigned char downTile = getMapBufferValue(5,5);
- if(((passability[downTile/8]>>(7-downTile%8))&0x1)==0)
- {
- moveState++;
- direction=DOWN;
- updateSpriteInfo();
- }
- canFly = 1;
- }
- else if((keysDown&0x0F)!=0 && canFly == 1)
- {
- fly();
- }
- }
- else
- {
- moveState+=1;
- updateSpriteInfo();
- if(moveState == 4)
- {
- if(direction == LEFT)
- {
- xPos--;
- if(xPos < 0)
- {
- unsigned char leftMapID = getMemMapInfo(currentMap,2);
- if(leftMapID<100)
- {
- unsigned char leftMapShift = getMemMapInfo(currentMap,3);
- unsigned char leftMapWidth = getMemMapInfo(leftMapID,0);
- currentMap = leftMapID;
- setSong(getMemMapInfo(currentMap,11));
- xPos = leftMapWidth+xPos;
- yPos -= leftMapShift;
- }
- }
- }
- else if(direction == UP)
- {
- yPos--;
- if(yPos < 0)
- {
- unsigned char upMapID = getMemMapInfo(currentMap,4);
- if(upMapID<100)
- {
- unsigned char upMapShift = getMemMapInfo(currentMap,5);
- unsigned char upMapHeight = getMemMapInfo(upMapShift,1);
- currentMap = upMapID;
- setSong(getMemMapInfo(currentMap,11));
- xPos -= upMapShift;
- yPos = upMapHeight+yPos;
- }
- }
- }
- else if(direction == RIGHT)
- {
- xPos++;
- unsigned char mapWidth = getMemMapInfo(currentMap,0);
- if(xPos>=mapWidth)
- {
- unsigned char rightMapID = getMemMapInfo(currentMap,6);
- if(rightMapID<100)
- {
- unsigned char rightMapShift = getMemMapInfo(currentMap,7);
- currentMap = rightMapID;
- setSong(getMemMapInfo(currentMap,11));
- xPos -= mapWidth;
- yPos -= rightMapShift;
- }
- }
- }
- else if(direction == DOWN)
- {
- yPos++;
- unsigned char mapHeight = getMemMapInfo(currentMap,1);
- if(yPos>=mapHeight)
- {
- unsigned char downMapID = getMemMapInfo(currentMap,8);
- if(downMapID<100)
- {
- unsigned char downMapShift = getMemMapInfo(currentMap,9);
- currentMap = downMapShift;
- setSong(getMemMapInfo(currentMap,11));
- yPos -= mapHeight;
- xPos -= downMapShift;
- }
- }
- }
- updateMapBuffer(direction);
- moveState = 0;
- reflectCounter++;
- reflectCounter%=2;
- }
- }
- // Draw sprite
- drawScreen();
- drawSprite();
- }
- void drawSprite()
- {
- for(unsigned char i = 0; i < 64; i++)
- {
- unsigned char dataByte = Spi23LC1024Read8(spriteNo * 64 + SPRITE_OFFSET + i);
- unsigned char transByte;
- if(i%2==0)
- {
- transByte = Spi23LC1024Read8(spriteNo * 32 +384+ SPRITE_OFFSET + i/2);
- }
- for(unsigned char j = 0; j < 4; j++)
- {
- if(!(transByte&0x1))
- {
- unsigned char currentColorIndex = (dataByte >> (j*2)) & 0x3;
- tft.drawPixel((reflect==0)?(i%4)*4+j+64:(15 - ((i%4)*4+j))+64, i/4+48, colors[currentColorIndex]);
- }
- transByte>>=1;
- }
- }
- }
- void drawPixel(int x, int y, unsigned int color)
- {
- if(x < 0 || x >= 160 || y < 0 || y >= 128)
- {
- return;
- }
- else
- {
- tft.drawPixel(x,y,color);
- }
- }
- void loadTileColors(unsigned char tileID, unsigned int colorArray[][16])
- {
- unsigned char tilePieces[4];
- tilePieces[0] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET);
- tilePieces[1] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET+1);
- tilePieces[2] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET+2);
- tilePieces[3] = Spi23LC1024Read8(TILEINFO_START + tileID*4 + MAP_OFFSET+3);
- for(unsigned char i = 0; i < 4; i++)
- {
- unsigned char baseX = (i%2) * 8;
- unsigned char baseY = (i/2) * 8;
- for(unsigned char byteNo = 0; byteNo < 16; byteNo++)
- {
- unsigned char readByte = Spi23LC1024Read8(1 + tilePieces[i]*16+byteNo + MAP_OFFSET);
- for(unsigned char twoBitNo = 0; twoBitNo < 4; twoBitNo++)
- {
- colorArray[baseX + twoBitNo + (byteNo%2)*4][baseY + byteNo/2] = colors[(readByte >> (3-twoBitNo)) & 0x03];
- }
- }
- }
- }
- unsigned char getMapBufferValue(unsigned char x, unsigned char y)
- {
- return mapBuffer[(x+mapBufXStart)%12][(y+mapBufYStart)%10];
- }
- void drawScreen()
- {
- char xOffset = (direction==LEFT?1:(direction==RIGHT?-1:0))*moveState*4;
- char yOffset = (direction==UP?1:(direction==DOWN?-1:0))*moveState*4;
- unsigned char seenTiles[16];
- unsigned char numSeenTiles = 0;
- unsigned int currentTileColors[16][16];
- for(unsigned char x = 0; x < 12; x++)
- {
- for(unsigned char y = 0; y < 10; y++)
- {
- unsigned char currentMapBufValue = getMapBufferValue(x,y);
- boolean seen = false;
- for(unsigned char a = 0; a < numSeenTiles && !seen; a++)
- {
- if(seenTiles[a] == currentMapBufValue)
- {
- seen = true;
- }
- }
- if(!seen)
- {
- seenTiles[numSeenTiles] = currentMapBufValue;
- numSeenTiles++;
- loadTileColors(currentMapBufValue,currentTileColors);
- for(unsigned char x2 = 0; x2 < 12; x2++)
- {
- for(unsigned char y2 = 0; y2 < 10; y2++)
- {
- unsigned char innerMapBufValue = getMapBufferValue(x2,y2);
- if(currentMapBufValue == innerMapBufValue)
- {
- for(unsigned char xTile = 0; xTile < 16; xTile++)
- {
- for(unsigned char yTile = 0; yTile < 16; yTile++)
- {
- drawPixel(xOffset+(x2-1)*16+xTile,yOffset+(y2-1)*16+yTile,currentTileColors[xTile][yTile]);
- }
- }
- }
- }
- }
- }
- }
- }
- }
- void updateMapBuffer(unsigned char updateDir)
- {
- if(updateDir == LEFT)
- {
- mapBufXStart = (mapBufXStart + 11)%12;
- for(unsigned char i = 0; i < 10; i++)
- {
- mapBuffer[mapBufXStart][(mapBufYStart+i)%10] = getTileValue(currentMap,xPos-5,yPos-4+i);
- }
- }
- else if(updateDir == UP)
- {
- mapBufYStart = (mapBufYStart + 9)%10;
- for(unsigned char i = 0; i < 12; i++)
- {
- mapBuffer[(mapBufXStart+i)%12][mapBufYStart] = getTileValue(currentMap,xPos-5+i,yPos-4);
- }
- }
- else if(updateDir == RIGHT)
- {
- for(unsigned char i = 0; i < 10; i++)
- {
- mapBuffer[mapBufXStart][(mapBufYStart+i)%10] = getTileValue(currentMap,xPos+6,yPos-4+i);
- }
- mapBufXStart = (mapBufXStart + 1)%12;
- }
- else if(updateDir == DOWN)
- {
- for(unsigned char i = 0; i < 12; i++)
- {
- mapBuffer[(mapBufXStart+i)%12][mapBufYStart] = getTileValue(currentMap,xPos-5+i,yPos+5);
- }
- mapBufYStart = (mapBufYStart + 1)%10;
- }
- }
- uint8_t Spi23LC1024Read8(uint32_t address)
- {
- uint8_t read_byte;
- digitalWrite(RAM_SS,LOW);
- SPI.transfer(READ);
- SPI.transfer((uint8_t)(address >> 16) & 0xff);
- SPI.transfer((uint8_t)(address >> 8) & 0xff);
- SPI.transfer((uint8_t)address);
- read_byte = SPI.transfer(0x00);
- digitalWrite(RAM_SS,HIGH);
- return read_byte;
- }
- void Spi23LC1024Write8(uint32_t address, uint8_t data_byte)
- {
- digitalWrite(RAM_SS,LOW);
- SPI.transfer(WRITE);
- SPI.transfer((uint8_t)(address >> 16) & 0xff);
- SPI.transfer((uint8_t)(address >> 8) & 0xff);
- SPI.transfer((uint8_t)address);
- SPI.transfer(data_byte);
- digitalWrite(RAM_SS,HIGH);
- }
- unsigned char getMemMapInfo(unsigned char map, unsigned int index)
- {
- return Spi23LC1024Read8(mapIndexes[map] + MAP_OFFSET + index);
- }
- unsigned char getTileValue(unsigned char map, int xCoord, int yCoord)
- {
- unsigned char width = getMemMapInfo(map,0);
- unsigned char height = getMemMapInfo(map,1);
- if(xCoord < 0)
- {
- unsigned char leftMapID = getMemMapInfo(map,2);
- if(leftMapID == 255)
- {
- return getMemMapInfo(map,10);
- }
- unsigned char leftMapOffset = getMemMapInfo(map,3);
- unsigned char leftMapWidth = getMemMapInfo(leftMapID,0);
- return getTileValue(leftMapID,leftMapWidth-1+xCoord, yCoord-leftMapOffset);
- }
- else if(xCoord >= width)
- {
- unsigned char rightMapID = getMemMapInfo(map,6);
- if(rightMapID == 255)
- {
- return getMemMapInfo(map,10);
- }
- int rightMapOffset = getMemMapInfo(map,7);
- return getTileValue(rightMapID, xCoord-width , yCoord-rightMapOffset);
- }
- else if(yCoord < 0)
- {
- unsigned char upMapID = getMemMapInfo(map,4);
- if(upMapID == 255)
- {
- return getMemMapInfo(map,10);
- }
- unsigned char upMapOffset = getMemMapInfo(map,5);
- unsigned char upMapHeight = getMemMapInfo(upMapID,1);
- return getTileValue(upMapID,xCoord - upMapOffset,upMapHeight-1+yCoord);
- }
- else if(yCoord >= height)
- {
- unsigned char downMapID = getMemMapInfo(map,8);
- if(downMapID == 255)
- {
- return getMemMapInfo(map,10);
- }
- unsigned char downMapOffset = getMemMapInfo(map,9);
- return getTileValue(downMapID,xCoord - downMapOffset,yCoord-height);
- }
- else
- {
- return getMemMapInfo(map,12+xCoord+yCoord*width);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement