void ultraDraw4(byte data[], char x, char y){
uint8_t* buf = ((y&0xF8)>>1) * 21 + gb.display.getBuffer() + x;
asm volatile(
"ldi R16,8\n\t"
"cpi %[rotnumber],0\n\t"
"breq LoopAligned\n"
"LoopStart:\n\t"
"ld R17,Z+\n\t"
"eor R18,R18\n\t"
"mov R19,%[rotnumber]\n\t"
"LoopShift:\n\t" // carry is still reset from the cpi instruction or from the dec
"rol R17\n\t"
"rol R18\n\t"
"dec R19\n\t"
"brne LoopShift\n\t"
"ld R19,X\n\t"
"eor R19,R17\n\t"
"st X+,R19\n\t"
"ld R19,Y\n\t"
"eor R19,R18\n\t"
"st Y+,R19\n\t"
"dec R16\n\t"
"brne LoopStart\n\t"
"rjmp End\n"
"LoopAligned:\n\t"
"ld R17,Z+\n\t"
"ld R18,X\n\t"
"eor R18,R17\n\t"
"st X+,R18\n\t"
"dec R16\n\t"
"brne LoopAligned\n"
"End:\n"
::"x" (buf),"y" (buf + 84),"z" (data),[rotnumber] "r" (y%8):"r16","r17","r18","r19");
}
#include <SPI.h>
#include <Gamebuino.h>
#define MAP_WIDTH 15
#define MAP_HEIGHT 15
const int PROGMEM map_test[]={
0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
0x05,0x01,0x01,0x01,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
0x05,0x01,0x00,0x00,0x01,0x07,0x01,0x01,0x01,0x01,0x05,0x05,0x05,0x05,0x05,
0x05,0x01,0x00,0x00,0x00,0x00,0x07,0x07,0x07,0x00,0x01,0x05,0x05,0x05,0x05,
0x05,0x01,0x00,0x03,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x05,0x05,0x05,
0x05,0x01,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,0x01,0x05,0x05,
0x05,0x01,0x00,0x01,0x01,0x02,0x02,0x02,0x01,0x01,0x00,0x00,0x01,0x05,0x05,
0x05,0x05,0x01,0x01,0x02,0x02,0x02,0x02,0x02,0x01,0x09,0x0b,0x01,0x05,0x05,
0x05,0x01,0x00,0x01,0x01,0x02,0x02,0x02,0x01,0x01,0x0a,0x0c,0x01,0x05,0x05,
0x05,0x01,0x00,0x09,0x0b,0x01,0x02,0x02,0x01,0x00,0x00,0x00,0x01,0x05,0x05,
0x05,0x05,0x01,0x0a,0x0c,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x05,0x05,0x05,
0x05,0x05,0x01,0x01,0x00,0x00,0x03,0x02,0x08,0x01,0x01,0x01,0x05,0x05,0x05,
0x05,0x05,0x05,0x05,0x01,0x01,0x00,0x02,0x01,0x05,0x05,0x05,0x05,0x05,0x05,
0x05,0x05,0x05,0x05,0x05,0x05,0x01,0x02,0x05,0x05,0x05,0x05,0x05,0x05,0x05,
0x05,0x05,0x05,0x05,0x05,0x05,0x02,0x01,0x05,0x05,0x05,0x05,0x05,0x05,0x05 };
#define TILE_WIDTH 8
#define TILE_HEIGHT 8
#define TILES_PASSABLE_6End 4
#define TILES_ANIMATED_START 3
#define TILES_ANIMATED_6End 5
#define ANIMATION_FREQUENCY 500 // ms
const byte tiles[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x08,0x00,0x40,0x04,0x00,0x00,
0x02,0x01,0x48,0x24,0x00,0x04,0x42,0x20,
0x00,0x40,0x10,0x60,0x00,0x40,0x20,0x00,
0x00,0x40,0x00,0x70,0x00,0x40,0x20,0x00,
0xff,0xf7,0x7b,0xf7,0xdf,0xef,0xdd,0xff,
0xff,0xfb,0xbd,0xfb,0xef,0xf7,0xee,0xff,
0x70,0xdc,0xaa,0xf1,0xf5,0xea,0xfc,0x78,
0x1e,0x21,0x2d,0xe9,0xe5,0x29,0x21,0x1e,
0x80,0x70,0x4c,0x12,0x26,0x12,0x01,0x01,
0x03,0x0d,0x16,0x3a,0x34,0x68,0xbc,0x99,
0xa1,0x01,0xa2,0x46,0x92,0x4c,0xf0,0x80,
0x98,0xb5,0x7a,0x2d,0x3a,0x1d,0x0c,0x03,
};
const byte* tiles_pointer = tiles;
const byte player_charset[]={
0x00,0x1e,0xed,0xa5,0xed,0xa5,0x1e,0x04,
0x00,0xde,0xed,0xe5,0xad,0xe5,0x9e,0x04,
0x00,0xde,0xad,0xe5,0xed,0xe5,0x9e,0x04,
0x00,0x5e,0xa5,0xe5,0x65,0xe5,0xa5,0x5e,
0x00,0x7e,0xd5,0xe5,0x65,0xa5,0xa5,0x7e,
0x00,0x7e,0xa5,0xa5,0x65,0xe5,0xd5,0x7e,
0x00,0x04,0x1e,0xa5,0xed,0xa5,0xed,0x1e,
0x00,0x04,0x9e,0xe5,0xad,0xe5,0xed,0xde,
0x00,0x04,0x9e,0xe5,0xed,0xe5,0xad,0xde,
0x00,0x5e,0xa5,0xed,0x65,0xed,0xa5,0x5e,
0x00,0x7e,0xd5,0xed,0x65,0xed,0xe5,0x7e,
0x00,0x7e,0xe5,0xed,0x65,0xed,0xd5,0x7e,
};
const byte* player_charset_pointer = player_charset;
const byte PROGMEM player_mask01[]={
8,8,0x3c,0x7e,0x7f,0x7e,0x7e,0x3c,0x38,0x3c };
const byte PROGMEM player_mask02[]={
8,8,0x3c,0x7e,0x7f,0x7e,0x7e,0x3c,0x7c,0x7e };
const byte PROGMEM player_mask03[]={
8,8,0x3e,0x7f,0x7f,0x7f,0x7f,0x3e,0x7f,0x36 };
const byte PROGMEM player_mask04[]={
8,8,0x3e,0x7f,0x7f,0x7f,0x7f,0x7f,0x7f,0x36 };
const byte PROGMEM player_mask05[]={
8,8,0x1e,0x3f,0x7f,0x3f,0x3f,0x1e,0x0e,0x1e };
const byte PROGMEM player_mask06[]={
8,8,0x1e,0x3f,0x7f,0x3f,0x3f,0x1e,0x1f,0x3f };
const byte* player_masks_pointer[]={
player_mask01,player_mask02,player_mask02,player_mask03,player_mask04,player_mask04,player_mask05,player_mask06,player_mask06,player_mask03,player_mask04,player_mask04 };
Gamebuino gb;
void setup(){
gb.begin();
byte player_x = 2;
byte player_y = 2;
byte player_direction = 3;
byte player_animation = 0;
int camera_x = player_x*TILE_WIDTH-LCDWIDTH/2+4;
camera_x = camera_x*(camera_x > 0)+(MAP_WIDTH*TILE_WIDTH-LCDWIDTH-camera_x)*(camera_x > MAP_WIDTH*TILE_WIDTH-LCDWIDTH);
int camera_y = player_y*TILE_HEIGHT-LCDHEIGHT/2+4;
camera_y = camera_y*(camera_y > 0)+(MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT-camera_y)*(camera_y > MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT);
while(1){
if(gb.update()){
draw_map(camera_x, camera_y);
draw_player(player_x*TILE_WIDTH-camera_x, player_y*TILE_WIDTH-camera_y, player_direction, player_animation);
char x_temp = -gb.buttons.repeat(BTN_LEFT, 1)*(player_x > 0)+gb.buttons.repeat(BTN_RIGHT, 1)*(player_x < MAP_WIDTH-1);
char y_temp = -gb.buttons.repeat(BTN_UP, 1)*(player_y > 0)+gb.buttons.repeat(BTN_DOWN, 1)*(player_y < MAP_HEIGHT-1);
if(x_temp || y_temp){
player_direction = (1+x_temp)*(x_temp != 0);
player_direction = (2+y_temp)*(y_temp != 0 || player_direction == 0);
if(TILES_PASSABLE_6End-pgm_read_byte(map_test+(player_y+y_temp)*MAP_WIDTH+player_x+x_temp) > 0){
for(byte i = 1; i <=8; i++){
player_animation += 1;
player_animation *= (player_animation < 3 && i < 8);
camera_x = (player_x*TILE_WIDTH-LCDWIDTH/2+4+i*x_temp);
camera_x = camera_x*(camera_x > 0)+(MAP_WIDTH*TILE_WIDTH-LCDWIDTH-camera_x)*(camera_x > MAP_WIDTH*TILE_WIDTH-LCDWIDTH);
camera_y = player_y*TILE_HEIGHT-LCDHEIGHT/2+4+i*y_temp;
camera_y = camera_y*(camera_y > 0)+(MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT-camera_y)*(camera_y > MAP_HEIGHT*TILE_HEIGHT-LCDHEIGHT);
gb.display.clear();
draw_map(camera_x, camera_y);
draw_player(player_x*TILE_WIDTH-camera_x+i*x_temp, player_y*TILE_WIDTH-camera_y+i*y_temp, player_direction, player_animation);
gb.display.update();
}
player_x += x_temp;
player_y += y_temp;
}
}
}
}
}
void loop(){
}
void draw_map(int camera_x, int camera_y){
for(byte y = 0; y <= 6; y++){
for(byte x = 0; x <= 11; x++){
int tile_x = camera_x/TILE_WIDTH+x;
int tile_y = camera_y/TILE_HEIGHT+y;
if(tile_x >= 0 && tile_x < MAP_WIDTH && tile_y >= 0 && tile_y < MAP_HEIGHT){
byte tile_num = pgm_read_byte(map_test+tile_y*MAP_WIDTH+tile_x);
tile_num += (tile_num >= TILES_ANIMATED_START && tile_num <= TILES_ANIMATED_6End)*millis()/ANIMATION_FREQUENCY%2;
draw_sprite(tiles_pointer+tile_num*TILE_HEIGHT, x*TILE_WIDTH-camera_x%TILE_WIDTH, y*TILE_HEIGHT-camera_y%TILE_HEIGHT);
}
}
}
}
void draw_player(int x, int y, byte direction, byte animation){
gb.display.setColor(WHITE, BLACK);
gb.display.drawBitmap(x, y, player_masks_pointer[direction*3+animation]);
draw_sprite(player_charset_pointer+(direction*24+animation*8), x, y);
}
void draw_sprite(const byte data[], char x, char y){ // routine by Sorunome
uint8_t* buf = (((y+8)&0xF8)>>1) * 21 + x + gb.display.getBuffer();
asm volatile(
"mov R20,%[y]\n\t"
"ldi R17,7\n\t"
"add R20,R17\n\t"
"brmi End\n\t"
"cpi %[y],48\n\t"
"brpl End\n\t"
"inc R20\n\t"
"ldi R16,8\n\t"
"andi R20,7\n\t"
"cpi R20,0\n\t"
"breq LoopAligned\n"
"LoopStart:\n\t"
"tst %[x]\n\t"
"brmi LoopSkip\n\t"
"cpi %[x],84\n\t"
"brcc LoopSkip\n\t"
"ld R17,Z\n\t"
"eor R18,R18\n\t"
"mov R19,R20\n\t"
"clc\n\t"
"LoopShift:\n\t" // carry is still reset from the cpi instruction or from the dec
"rol R17\n\t"
"rol R18\n\t"
"dec R19\n\t"
"brne LoopShift\n\t"
"tst %[y]\n\t"
"brmi LoopSkipPart\n\t"
"ld R19,X\n\t"
"eor R19,R17\n\t"
"st X,R19\n\t"
"LoopSkipPart:\n\t"
"cpi %[y],40\n\t"
"brpl LoopSkip\n\t"
"ld R19,Y\n\t"
"eor R19,R18\n\t"
"st Y,R19\n\t"
"LoopSkip:\n\t"
"eor R18,R18\n\t"
"ldi R19,1\n\t"
"add R26,R19\n\t" // INC DOESN'T CHANGE CARRY!
"adc R27,R18\n\t"
"add R28,R19\n\t"
"adc R29,R18\n\t"
"add R30,R19\n\t"
"adc R31,R18\n\t"
"inc %[x]\n\t"
"dec R16\n\t"
"brne LoopStart\n\t"
"rjmp End\n"
"LoopAligned:\n\t"
"tst %[x]\n\t"
"brmi LoopAlignSkip\n\t"
"cpi %[x],84\n\t"
"brcc LoopAlignSkip\n\t"
"ld R17,Z\n\t"
"ld R18,X\n\t"
"eor R18,R17\n\t"
"st X,R18\n\t"
"LoopAlignSkip:\n\t"
"ldi R18,1\n\t"
"add R26,R18\n\t"
"adc R27,R20\n\t"
"add R30,R18\n\t"
"adc R31,R20\n\t"
"inc %[x]\n\t"
"dec R16\n\t"
"brne LoopAligned\n"
"End:\n\t"
::"x" (buf - 84),"y" (buf),"z" (data),[y] "r" (y),[x] "r" (x):"r16","r17","r18","r19","r20");
}
Return to Software Development
Users browsing this forum: No registered users and 2 guests