dsgmLib/source/DSGM_background.c
2015-04-19 12:58:11 +01:00

322 lines
7.8 KiB
C

#include "DSGM.h"
inline void DSGM_UnlockBackgroundPalette(u8 screen) {
switch(screen) {
case DSGM_TOP:
vramSetBankE(VRAM_E_LCD);
break;
case DSGM_BOTTOM:
vramSetBankH(VRAM_H_LCD);
break;
}
}
inline void DSGM_LockBackgroundPalette(u8 screen) {
switch(screen) {
case DSGM_TOP:
vramSetBankE(VRAM_E_BG_EXT_PALETTE);
break;
case DSGM_BOTTOM:
vramSetBankH(VRAM_H_SUB_BG_EXT_PALETTE);
break;
}
}
inline unsigned short *DSGM_GetBackgroundPalette(u8 screen, int layerNumber) {
return (screen == DSGM_TOP ? VRAM_E_EXT_PALETTE : VRAM_H_EXT_PALETTE)[layerNumber][0];
}
inline void DSGM_SetScreenColor(u8 screen, u16 color) {
switch(screen) {
case DSGM_TOP:
BG_PALETTE[0] = color;
break;
case DSGM_BOTTOM:
BG_PALETTE_SUB[0] = color;
break;
}
}
inline bool DSGM_BackgroundIsNitroFull(DSGM_Background *background) {
return !background->tiles;
}
void DSGM_LoadBackgroundFull(DSGM_Layer *layer) {
BgType type = (layer->background->type == DSGM_LARGE_BACKGROUND) ? BgType_Text8bpp : layer->background->type;
BgSize size = (layer->background->type == DSGM_LARGE_BACKGROUND) ? BgSize_T_512x512 : layer->background->size;
switch(layer->screen) {
case DSGM_TOP:
layer->vramId = bgInit(layer->layerNumber, type, size, layer->mapBase, layer->tileBase);
break;
case DSGM_BOTTOM:
layer->vramId = bgInitSub(layer->layerNumber, type, size, layer->mapBase, layer->tileBase);
break;
}
bgHide(layer->vramId);
if(DSGM_BackgroundIsNitroFull(layer->background)) {
DSGM_LoadBackgroundNitroFull(layer);
}
else {
DSGM_LoadBackgroundRAMFull(layer);
}
if(layer->background->type == DSGM_LARGE_BACKGROUND) {
DSGM_LargeBackgroundCopyScreen(layer);
}
//DSGM_ScrollBackgroundFull(layer);
swiWaitForVBlank();
bgUpdate();
bgShow(layer->vramId);
}
void DSGM_LoadBackgroundNitroFull(DSGM_Layer *layer) {
void *map;
size_t mapLength = DSGM_GetFileLength(layer->background->nitroMapFilename);
if(layer->background->type == DSGM_LARGE_BACKGROUND) {
DSGM_Debug("Allocating %d bytes for large background map\n", mapLength);
layer->largeBackgroundMap = malloc(mapLength);
DSGM_Debug("Gave %p\n", layer->largeBackgroundMap);
map = layer->largeBackgroundMap;
}
else {
map = bgGetMapPtr(layer->vramId);
}
layer->background->tilesCount = DSGM_ReadFileManual(bgGetGfxPtr(layer->vramId), 0, DSGM_AUTO_LENGTH, layer->background->nitroTilesFilename) / 64;
if(layer->background->nitroMapFilename) DSGM_ReadFileManual(map, 0, DSGM_AUTO_LENGTH, layer->background->nitroMapFilename);
DSGM_UnlockBackgroundPalette(layer->screen);
switch(layer->screen) {
case DSGM_TOP:
DSGM_ReadFileManual(&VRAM_E_EXT_PALETTE[layer->layerNumber][0], 0, DSGM_AUTO_LENGTH, layer->background->nitroPaletteFilename);
break;
case DSGM_BOTTOM:
DSGM_ReadFileManual(&VRAM_H_EXT_PALETTE[layer->layerNumber][0], 0, DSGM_AUTO_LENGTH, layer->background->nitroPaletteFilename);
break;
}
DSGM_LockBackgroundPalette(layer->screen);
}
void DSGM_LoadBackgroundRAMFull(DSGM_Layer *layer) {
void *map;
size_t mapLength = *layer->background->mapLength;
if(layer->background->type == DSGM_LARGE_BACKGROUND) {
DSGM_Debug("Allocating %d bytes for large background map\n", mapLength);
layer->largeBackgroundMap = malloc(mapLength);
DSGM_Debug("Gave %p\n", layer->largeBackgroundMap);
map = layer->largeBackgroundMap;
}
else {
map = bgGetMapPtr(layer->vramId);
}
dmaCopy(layer->background->tiles, bgGetGfxPtr(layer->vramId), *layer->background->tilesLength);
layer->background->tilesCount = (*layer->background->tilesLength) / 64;
if(layer->background->map != NULL) dmaCopy(layer->background->map, map, *layer->background->mapLength);
DSGM_UnlockBackgroundPalette(layer->screen);
switch(layer->screen) {
case DSGM_TOP:
dmaCopy(layer->background->palette, &VRAM_E_EXT_PALETTE[layer->layerNumber][0], *layer->background->paletteLength);
break;
case DSGM_BOTTOM:
dmaCopy(layer->background->palette, &VRAM_H_EXT_PALETTE[layer->layerNumber][0], *layer->background->paletteLength);
break;
}
DSGM_LockBackgroundPalette(layer->screen);
}
void DSGM_ScrollBackgroundFull(DSGM_View *view, DSGM_Layer *layer) {
if(layer != NULL/* && background != DSGM_DEFAULT_FONT*/) {
if(layer->background != NULL) {
bgSetScroll(layer->vramId, layer->x + (layer->attachedToView ? view->x : 0), layer->y + (layer->attachedToView ? view->y : 0));
}
}
}
inline unsigned int DSGM_GetLayerPriorityFull(DSGM_Layer *layer) {
return (unsigned int)bgGetPriority(layer->vramId);
}
inline void DSGM_SetLayerPriorityFull(DSGM_Layer *layer, unsigned int priority) {
bgSetPriority(layer->vramId, priority);
}
inline BgSize DSGM_GetBGSize(u8 screen, int layerNumber) {
return bgState[layerNumber + ((screen == DSGM_BOTTOM) * 4)].size;
}
int DSGM_GetBGWidth(u8 screen, int layerNumber) {
switch(DSGM_GetBGSize(screen, layerNumber)) {
case BgSize_R_128x128:
case BgSize_ER_128x128:
case BgSize_B8_128x128:
case BgSize_B16_128x128:
return 128;
break;
case BgSize_T_256x256:
case BgSize_T_256x512:
case BgSize_R_256x256:
case BgSize_ER_256x256:
case BgSize_B8_256x256:
case BgSize_B16_256x256:
return 256;
break;
case BgSize_T_512x256:
case BgSize_T_512x512:
case BgSize_R_512x512:
case BgSize_ER_512x512:
case BgSize_B8_512x512:
case BgSize_B8_512x256:
case BgSize_B8_512x1024:
case BgSize_B16_512x512:
case BgSize_B16_512x256:
return 512;
break;
case BgSize_R_1024x1024:
case BgSize_ER_1024x1024:
case BgSize_B8_1024x512:
return 1024;
break;
default:
break;
}
return 256;
}
int DSGM_GetBGHeight(u8 screen, int layerNumber) {
switch(DSGM_GetBGSize(screen, layerNumber)) {
case BgSize_R_128x128:
case BgSize_ER_128x128:
case BgSize_B8_128x128:
case BgSize_B16_128x128:
return 128;
break;
case BgSize_T_256x256:
case BgSize_T_512x256:
case BgSize_R_256x256:
case BgSize_ER_256x256:
case BgSize_B8_256x256:
case BgSize_B8_512x256:
case BgSize_B16_256x256:
case BgSize_B16_512x256:
return 256;
break;
case BgSize_T_256x512:
case BgSize_T_512x512:
case BgSize_R_512x512:
case BgSize_ER_512x512:
case BgSize_B8_512x512:
case BgSize_B8_1024x512:
case BgSize_B16_512x512:
return 512;
break;
case BgSize_R_1024x1024:
case BgSize_ER_1024x1024:
case BgSize_B8_512x1024:
return 1024;
break;
default:
break;
}
return 256;
}
inline u16 DSGM_GetTileFull(DSGM_Layer *layer, int x, int y) {
u16 *map;
if(layer->background->type == DSGM_LARGE_BACKGROUND) {
map = layer->largeBackgroundMap;
}
else {
map = bgGetMapPtr(layer->vramId);
}
// todo: optimise with div and modulus rather than loop
while(y > 31) {
y -= 32;
x += 64;
}
while(x > 31) {
x -= 32;
y += 32;
}
// DSGM_GetBGWidth(layer->screen, layer->layerNumber)
return map[y * 32 + x];
}
inline void DSGM_SetTileFull(DSGM_Layer *layer, int x, int y, u16 tile) {
u16 *map;
if(layer->background->type == DSGM_LARGE_BACKGROUND) {
map = layer->largeBackgroundMap;
}
else {
map = bgGetMapPtr(layer->vramId);
}
while(y > 31) {
y -= 32;
x += 64;
}
while(x > 31) {
x -= 32;
y += 32;
}
map[y * 32 + x] = tile;
}
inline void DSGM_SetTileForceVRAM(DSGM_Layer *layer, int x, int y, u16 tile) {
u16 *map = bgGetMapPtr(layer->vramId);
if(layer->background->type == DSGM_LARGE_BACKGROUND) {
x %= 512 / 8;
y %= 512 / 8;
}
while(y > 31) {
y -= 32;
x += 64;
}
while(x > 31) {
x -= 32;
y += 32;
}
map[y * DSGM_GetBGWidth(layer->screen, layer->layerNumber) / 16 + x] = tile;
}
inline void DSGM_SetRotationCenterFull(DSGM_Layer *layer, int x, int y) {
bgSetCenter(layer->vramId, x, y);
}
inline void DSGM_RotateBackgroundFull(DSGM_Layer *layer, int angle) {
bgSetRotate(layer->vramId, angle);
}
inline void DSGM_ScaleBackgroundFull(DSGM_Layer *layer, int x, int y) {
bgSetScale(layer->vramId, x, y);
}