cool-bun-demo/system/blitter.c

124 lines
3.2 KiB
C
Raw Normal View History

2024-05-02 16:52:06 +00:00
#include <stdlib.h>
#include <hardware/custom.h>
#include "blitter.h"
#include "system.h"
2024-05-27 18:58:13 +00:00
#include "../types.h"
2024-05-02 16:52:06 +00:00
extern struct Custom far custom;
/**
* @param setup Data about the line's draw properties are injected into this struct.
*/
void blit_calculateLineBlit(
struct BlitDrawLineSetup *setup,
uint16_t sx,
uint16_t sy,
uint16_t ex,
uint16_t ey
) {
uint16_t i;
setup->sx = sx;
setup->dx = ex - sx;
setup->dy = ey - sy;
if (setup->dx == 0 && setup->dy == 0) return;
setup->sud = abs(setup->dy) < abs(setup->dx);
if (!setup->sud) { i = setup->dx; setup->dx = setup->dy; setup->dy = i; }
setup->sul = setup->dy < 0;
setup->dy = abs(setup->dy);
setup->aul = setup->dx < 0;
setup->dx = abs(setup->dx);
setup->accumulator = 4 * setup->dy - 2 * setup->dx;
setup->sign = setup->accumulator < 0;
}
void blit_drawSingleLine(
struct BlitAreaDetails *blitAreaDetails,
struct BlitDrawLineSetup *setup
) {
custom.bltadat = 0x8000;
custom.bltbdat = setup->linePattern;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltamod = 4 * (setup->dy - setup->dx);
custom.bltbmod = 4 * setup->dy;
custom.bltcmod = blitAreaDetails->drawAreaWidth / 8;
custom.bltdmod = blitAreaDetails->drawAreaWidth / 8;
custom.bltapt = setup->accumulator;
custom.bltcpt = setup->target;
custom.bltdpt = setup->target;
custom.bltcon0 = ((setup->sx % 16) << 12) + (11 << 8) + 0xca;
custom.bltcon1 = 1 + (setup->aul << 2) + (setup->sul << 3) + (setup->sud << 4) + (setup->sign << 6);
custom.bltsize = 0x02 + ((setup->dx + 1) << 6);
}
void blit_drawLine(
struct BlitAreaDetails *blitAreaDetails,
struct BlitDrawLineSetup *setup,
uint16_t sx,
uint16_t sy,
uint16_t ex,
uint16_t ey,
uint8_t color
) {
int i;
blit_calculateLineBlit(setup, sx, sy, ex, ey);
setup->target = blitAreaDetails->target + WORD_ALIGNED_BYTE_POSITION(blitAreaDetails->drawAreaWidth, sx, sy);
for (i = 0; i < blitAreaDetails->contiguousBitplanes; ++i) {
setup->linePattern = ((color & 1) == 1) ? 0xffff : 0;
blit_drawSingleLine(blitAreaDetails, setup);
setup->target += blitAreaDetails->nextBitplaneAdvance;
color >>= 1;
WaitBlit();
}
}
void blit_fillPolygon(
struct ScreenSetup *screenSetup,
uint16_t sx,
uint16_t sy,
uint16_t ex,
uint16_t ey,
uint8_t color
) {
// use a standard copy blit
// set bltadat to 0xffff
// set bltdpt to the top left corner of the zone
// width is dx / 8
// height is dy
// enable descending mode
// enable inclusive fill for now
uint16_t dx = ex - sx;
uint16_t dy = ey - sy;
unsigned char *source = screenSetup->memoryStart + ((((ey * screenSetup->width + ex) >> 3) - 2) & 0xfffe);
unsigned char *target = screenSetup->memoryStart + (((((ey + 100) * screenSetup->width + ex) >> 3) - 2) & 0xfffe);
custom.bltcon0 = (1 << 11) + (1 << 8) + 0xF0; // we don't want to copy anything so we only enable target
custom.bltcon1 = (1 << 1) + (1 << 3);
custom.bltapt = source;
custom.bltdpt = target;
custom.bltamod = ((screenSetup->width - dx) >> 3) + 1;
custom.bltdmod = ((screenSetup->width - dx) >> 3) + 1;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = (dx / 16) + (dy << 6);
}