extern char BG1_tiles, BG1_tiles_end;
extern char BG1_pal, BG1_pal_end;
extern char BG1_map, BG1_map_end;
extern char BG2_tiles, BG2_tiles_end;
extern char BG2_pal, BG1_pal_end;
extern char BG2_map, BG1_map_end;
extern char BG3_tiles, BG3_tiles_end;
extern char BG3_pal, BG3_pal_end;
extern char BG3_map, BG3_map_end;
extern char character_tiles, character_tiles_end;
extern char character_pal, character_pal_end;
typedef struct
{
u8 oamAddress;
int _x;
int _y;
} character;
typedef struct
{
u8 id;
u16 vram;
u16 scrX;
u16 scrY;
u8 *bgMap;
u8 mapPage;
bool vRamFirstPage;
u16 scrollX;
u16 maxScrollX;
} scroll;
typedef struct
{
u8 *gfxoffset;
u16 adrgfxvram;
u16 size;
} bgpage;
typedef struct
{
bgpage bg1;
bgpage bg2;
u8 refreshBG1;
u8 refreshBG2;
} background;
scroll bgMain;
scroll bgSub;
character player1;
unsigned short pad0;
unsigned char bg_mutex;
background bgInfo;
void updateBG1(u8 *pgfx, u16 adrspr, int size)
{
bg_mutex = 1;
bgInfo.bg1.adrgfxvram = adrspr;
bgInfo.bg1.gfxoffset = pgfx;
bgInfo.bg1.size = size;
bgInfo.refreshBG1 = true;
bg_mutex = 0;
}
void updateBG2(u8 *pgfx, u16 adrspr, int size)
{
bg_mutex = 1;
bgInfo.bg2.adrgfxvram = adrspr;
bgInfo.bg2.gfxoffset = pgfx;
bgInfo.bg2.size = size;
bgInfo.refreshBG2 = true;
bg_mutex = 0;
}
void updatePos(character *p, unsigned short pad)
{
{
p->_y -= 2;
}
{
p->_y += 2;
}
{
p->_x -= 2;
}
{
p->_x += 2;
}
}
void handleScroll(character *p, scroll *s)
{
if (p->_x > 94)
{
if (s->scrX < s->maxScrollX)
{
s->scrX += 1;
p->_x -= 1;
}
if ((s->scrX >= (s->mapPage + 1) * 256))
{
s->mapPage += 1;
s->vRamFirstPage = !s->vRamFirstPage;
u16 vram = s->vram;
if (s->vRamFirstPage == false)
{
vram += 1024;
}
updateBG1(s->bgMap + 2048 * s->mapPage, vram, 2048);
}
}
}
void handleScrollSub(character *p, scroll *s)
{
if (p->_x > 94)
{
if (s->scrX < s->maxScrollX)
{
s->scrX += 2;
}
if ((s->scrX >= (s->mapPage + 1) * 256))
{
s->mapPage += 1;
s->vRamFirstPage = !s->vRamFirstPage;
u16 vram = s->vram;
if (s->vRamFirstPage == false)
{
vram += 1024;
}
updateBG2(s->bgMap + 2048 * s->mapPage, vram, 2048);
}
}
}
void myconsoleVblank()
{
if (bg_mutex == 0)
{
if (bgInfo.refreshBG1 == true)
{
dmaCopyVram(bgInfo.bg1.gfxoffset, bgInfo.bg1.adrgfxvram, bgInfo.bg1.size);
bgInfo.refreshBG1 = false;
}
}
if (bg_mutex == 0)
{
if (bgInfo.refreshBG2 == true)
{
dmaCopyVram(bgInfo.bg2.gfxoffset, bgInfo.bg2.adrgfxvram, bgInfo.bg2.size);
bgInfo.refreshBG2 = false;
}
}
}
int main(void)
{
bgInitTileSet(0, &BG1_tiles, &BG1_pal, 2, (&BG1_tiles_end - &BG1_tiles), 16 * 4, BG_16COLORS, 0x2000);
bgInitTileSet(1, &BG2_tiles, &BG2_pal, 4, (&BG2_tiles_end - &BG2_tiles), 16 * 4, BG_16COLORS, 0x3000);
bgInitTileSet(2, &BG3_tiles, &BG3_pal, 0, (&BG3_tiles_end - &BG3_tiles), 16 * 4, BG_4COLORS, 0x4000);
bg_mutex = 0;
updateBG1(&BG1_map, 0x0000, 2048);
updateBG2(&BG2_map, 0x0000 + 2048, 2048);
setMode(BG_MODE1, BG3_MODE1_PRIORITY_HIGH);
player1._x = 20;
player1._y = 100;
player1.oamAddress = 0;
oamInitGfxSet(&character_tiles, (&character_tiles_end - &character_tiles), &character_pal, (&character_pal_end - &character_pal), 0, 0x6000,
OBJ_SIZE16_L32);
oamSet(player1.oamAddress, player1._x, player1._y, 2, 0, 0, 0, 0);
oamSetEx(player1.oamAddress, OBJ_SMALL, OBJ_SHOW);
bgMain.id = 0;
bgMain.scrX = 255;
bgMain.scrY = 255;
bgMain.vram = 0x0000;
bgMain.vRamFirstPage = true;
bgMain.mapPage = 0;
bgMain.bgMap = &BG1_map;
bgMain.maxScrollX = 768;
bgSub.id = 1;
bgSub.scrX = 255;
bgSub.scrY = 255;
bgSub.vram = 0x0000 + 2048;
bgSub.vRamFirstPage = true;
bgSub.mapPage = 0;
bgSub.bgMap = &BG2_map;
bgSub.maxScrollX = 1024 + 128;
while (1)
{
updatePos(&player1, pad0);
handleScroll(&player1, &bgMain);
handleScrollSub(&player1, &bgSub);
}
return 0;
}
void bgSetMapPtr(u8 bgNumber, u16 address, u8 mapSize)
Change Background Map address.
void bgSetScroll(u8 bgNumber, u16 x, u16 y)
Sets the scroll hardware to the specified location.
void bgInitTileSet(u8 bgNumber, u8 *tileSource, u8 *tilePalette, u8 paletteEntry, u16 tileSize, u16 paletteSize, u16 colorMode, u16 address)
Initializes a Tile Set and Loads the Tile GFX into VRAM.
void consoleInit(void)
Initialize console.
void dmaCopyOAram(u8 *source, u16 address, u16 size)
copies Sprites from source to destination using channel 0 of DMA available channels in half words
void dmaCopyVram(u8 *source, u16 address, u16 size)
copy data from source to destination using channel 0 of DMA available channels in half words
void WaitForVBlank(void)
Wait for vblank interrupt
#define nmiSet(handler)
Add a handler for the given interrupt mask.
Definition: interrupt.h:150
the master include file for snes applications.
#define OBJ_SIZE16_L32
default OAM size 16x16 (SM) and 32x32 (LG) pix for OBJSEL register
Definition: sprite.h:42
void oamSetVisible(u16 id, u8 hide)
Hide or show a sprite.
void oamSetEx(u16 id, u8 size, u8 hide)
Put the correct size and hide or show a sprite.
void oamInitGfxSet(u8 *tileSource, u16 tileSize, u8 *tilePalette, u16 paletteSize, u8 tilePaletteNumber, u16 address, u8 oamsize)
Initializes a sprites Gfx and Loads the GFX into VRAM.
void oamSetXY(u16 id, u16 xspr, u16 yspr)
sets an oam coordinate to the supplied values
u8 oamMemory[128 *4+8 *4]
to address oam table low and high
void oamSet(u16 id, u16 xspr, u16 yspr, u8 priority, u8 hflip, u8 vflip, u16 gfxoffset, u8 paletteoffset)
sets an oam entry to the supplied values
void setScreenOn(void)
Put screen On.
void setMode(u8 mode, u8 size)
Set the SNES hardware to operate in new display mode.