mirror of
https://github.com/CTurt/dsgmLib.git
synced 2025-06-18 22:55:33 -04:00
142 lines
5.3 KiB
C
142 lines
5.3 KiB
C
#include "DSGM.h"
|
|
|
|
void DSGM_InitDrawableBackground(DSGM_Layer *layer) {
|
|
DSGM_Debug("Drawable background screen %d, layerNumber %d", layer->screen, layer->layerNumber);
|
|
switch(layer->screen) {
|
|
case DSGM_TOP:
|
|
layer->vramId = bgInit(layer->layerNumber, BgType_Bmp16, BgSize_B16_256x256, layer->mapBase, layer->tileBase);
|
|
break;
|
|
|
|
case DSGM_BOTTOM:
|
|
layer->vramId = bgInitSub(layer->layerNumber, BgType_Bmp16, BgSize_B16_256x256, layer->mapBase, layer->tileBase);
|
|
break;
|
|
}
|
|
}
|
|
|
|
inline void DSGM_ClearDrawableBackgroundFull(DSGM_Room *room, u8 screen) {
|
|
// Some dma, swi function might be faster
|
|
memset(bgGetGfxPtr(room->layers[screen][3].vramId), 0, 256 * 192 * sizeof(u16));
|
|
}
|
|
|
|
inline void DSGM_DrawPixelToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, u16 color) {
|
|
bgGetGfxPtr(room->layers[screen][3].vramId)[x + (y << 8)] = color;
|
|
}
|
|
|
|
inline u16 DSGM_GetDrawablePixelFull(DSGM_Room *room, u8 screen, int x, int y) {
|
|
if(x >= 0 && y >= 0 && x < 256 && y < 192) return bgGetGfxPtr(room->layers[screen][3].vramId)[x + (y << 8)];
|
|
else return ARGB16(0, 0, 0, 0);
|
|
}
|
|
|
|
inline void DSGM_DrawRectangleToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, int width, int height, int thickness, u16 color) {
|
|
DSGM_DrawLineToBackgroundFull(room, screen, x, y, x + width, y, thickness, color);
|
|
DSGM_DrawLineToBackgroundFull(room, screen, x + width, y, x + width, y + height, thickness, color);
|
|
DSGM_DrawLineToBackgroundFull(room, screen, x + width, y + height, x, y + height, thickness, color);
|
|
DSGM_DrawLineToBackgroundFull(room, screen, x, y, x, y + height, thickness, color);
|
|
}
|
|
|
|
inline void DSGM_DrawFilledRectangleToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, int width, int height, u16 color) {
|
|
u16 *gfx = bgGetGfxPtr(room->layers[screen][3].vramId);
|
|
|
|
int xi, yi;
|
|
for(xi = x; xi < x + width; xi++) {
|
|
for(yi = y; yi < y + height; yi++) {
|
|
if(xi >= 0 && yi >= 0 && xi < 256 && yi < 192) gfx[xi + (yi << 8)] = color;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Adapted from http://rosettacode.org/wiki/Bitmap/Bresenham%27s_line_algorithm#C
|
|
inline void DSGM_DrawLineToBackgroundFull(DSGM_Room *room, u8 screen, int x1, int y1, int x2, int y2, int thickness, u16 color) {
|
|
int hthickness = thickness / 2;
|
|
|
|
int dx = abs(x2 - x1), sx = x1 < x2 ? 1 : -1;
|
|
int dy = abs(y2 - y1), sy = y1 < y2 ? 1 : -1;
|
|
int err = (dx > dy ? dx : -dy) / 2, e2;
|
|
|
|
while(1) {
|
|
DSGM_DrawFilledRectangleToBackgroundFull(room, screen, x1 - hthickness, y1 - hthickness, thickness, thickness, color);
|
|
if(x1 == x2 && y1 == y2) break;
|
|
|
|
e2 = err;
|
|
if(e2 >-dx) {
|
|
err -= dy;
|
|
x1 += sx;
|
|
}
|
|
if(e2 < dy) {
|
|
err += dx;
|
|
y1 += sy;
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void DSGM_DrawLineAtAngleToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, int angle, int length, int thickness, u16 color) {
|
|
DSGM_DrawLineToBackgroundFull(room, screen, x, y, ((x << 12) + cosLerp(angle) * length) >> 12, ((y << 12) - sinLerp(angle) * length) >> 12, thickness, color);
|
|
}
|
|
|
|
inline void DSGM_DrawCircleToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, int radius, int thickness, u16 color) {
|
|
int angle;
|
|
int steps = thickness * 4096 / radius;
|
|
for(angle = 0; angle < degreesToAngle(360); angle += steps) {
|
|
DSGM_DrawFilledRectangleToBackgroundFull(room, screen, ((x << 12) + cosLerp(angle) * radius) >> 12, ((y << 12) - sinLerp(angle) * radius) >> 12, thickness, thickness, color);
|
|
// circle would be more accurate than rectangle, but would be too slow
|
|
}
|
|
}
|
|
|
|
inline void DSGM_DrawFilledCircleToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, int radius, u16 color) {
|
|
int angle;
|
|
int steps = 8192 / radius;
|
|
for(angle = 0; angle < degreesToAngle(180); angle += steps) {
|
|
int xb = x << 12;
|
|
int yb = y << 12;
|
|
int s = sinLerp(angle) * radius;
|
|
int c = cosLerp(angle) * radius;
|
|
DSGM_DrawLineToBackgroundFull(room, screen, (xb + c) >> 12, (yb - s) >> 12, (xb - c) >> 12, (yb + s) >> 12, 2, color);
|
|
}
|
|
}
|
|
|
|
inline void DSGM_DrawTileToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, DSGM_Background *font, char tile, int size, u16 color) {
|
|
unsigned char *fontGfx = NULL;
|
|
bool freeGfx = false;
|
|
|
|
if(font == DSGM_DEFAULT_FONT) fontGfx = DSGM_DEFAULT_FONT_GFX;
|
|
else {
|
|
//fontGfx = bgGetGfxPtr(font->vramId);
|
|
if(DSGM_BackgroundIsNitroFull(font)) {
|
|
size_t length = DSGM_GetFileLength(font->nitroTilesFilename);
|
|
fontGfx = malloc(length);
|
|
DSGM_ReadFileManual(fontGfx, 0, length, font->nitroTilesFilename);
|
|
freeGfx = true;
|
|
}
|
|
else {
|
|
fontGfx = font->tiles;
|
|
}
|
|
}
|
|
|
|
int pixel;
|
|
|
|
for(pixel = 0; pixel < 32; pixel++) {
|
|
unsigned short word = fontGfx[(tile << 5) + pixel];
|
|
|
|
int px = ((tile & 3) << 3) + ((pixel << 1) & 7);
|
|
int py = ((tile >> 2) << 3) + (pixel >> 2);
|
|
|
|
if((word & 0xF0) >> 4 != 0) DSGM_DrawFilledRectangleToBackgroundFull(room, screen, x + ((px + 1) % 8) * size, y + (py % 8) * size, size, size, color);
|
|
if((word & 0x0F) != 0) DSGM_DrawFilledRectangleToBackgroundFull(room, screen, x + (px % 8) * size, y + (py % 8) * size, size, size, color);
|
|
}
|
|
|
|
if(freeGfx) free(fontGfx);
|
|
}
|
|
|
|
inline void DSGM_DrawTextToBackgroundFull(DSGM_Room *room, u8 screen, int x, int y, DSGM_Background *font, int size, u16 color, const char *format, ...) {
|
|
char text[1024];
|
|
va_list args;
|
|
va_start(args, format);
|
|
vsnprintf(text, 1023, format, args);
|
|
va_end(args);
|
|
|
|
int i, len = strlen(text);
|
|
for(i = 0; i < len; i++) {
|
|
DSGM_DrawTileToBackgroundFull(room, screen, x + i * size * 8, y, font, text[i], size, color);
|
|
}
|
|
}
|