cool-bun-demo/main.c

498 lines
14 KiB
C
Raw Normal View History

2024-04-30 02:12:48 +00:00
#include <stdio.h>
#include <clib/exec_protos.h>
#include <clib/graphics_protos.h>
#include <exec/exec.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
2024-05-27 18:58:13 +00:00
#include <graphics/gfx.h>
2024-05-02 16:52:06 +00:00
#include "blitter.h"
#include "copper.h"
#include "screen.h"
#include "types.h"
#include "system.h"
2024-04-30 02:12:48 +00:00
2024-05-02 16:52:06 +00:00
extern struct Custom far custom;
2024-05-27 18:58:13 +00:00
extern unsigned char far coolbun[];
2024-04-30 02:12:48 +00:00
2024-05-02 16:52:06 +00:00
void writeSomethingToScreen(struct ScreenSetup *screenSetup) {
2024-04-30 02:12:48 +00:00
*(screenSetup->memoryStart) = 255;
*(screenSetup->memoryStart + 8) = 0xAA;
*(screenSetup->memoryStart + 16) = 0xF0;
*(screenSetup->memoryStart + SCREEN_WIDTH * SCREEN_HEIGHT / 8 + 4) = 255;
}
2024-05-27 18:58:13 +00:00
// [ ] increase the size of the bun area
// [ ] ensure the area has the correct data
// [ ] fix existing edge writes to work
// [ ] change non-edge write to use only bun area
#define COOL_BUN_WIDTH (32)
#define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8)
#define COOL_BUN_HEIGHT (32)
#define COOL_BUN_PLANES (2)
#define COOL_BUN_PLANE_SIZE (COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT)
#define COOL_BUN_MEMORY_SIZE (COOL_BUN_PLANE_SIZE * COOL_BUN_PLANES)
// this should be large enough to hold one bitplane of the largest object
// you are blitting, plus one additional word on each side
#define SCRATCH_AREA_WIDTH_BYTES (8)
#define SCRATCH_AREA_HEIGHT_ROWS (34)
#define SCRATCH_AREA_MEMORY_SIZE (SCRATCH_AREA_WIDTH_BYTES * SCRATCH_AREA_HEIGHT_ROWS)
volatile short *dbg = (volatile short *)0x100;
unsigned char *coolbunArea;
unsigned char *scratchArea;
struct ScreenSetup screenSetup;
void clearScratchArea() {
custom.bltcon0 = 0xf0 + (1 << 8);
custom.bltcon1 = 0;
custom.bltadat = 0x0000;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltdpt = scratchArea;
custom.bltamod = 0;
custom.bltdmod = 0;
custom.bltsize = (4) + (32 << 6);
WaitBlit();
}
void bun_offRightSide(int plusXValue, int y) {
uint8_t i, plane = 0;
uint8_t shift = plusXValue & 15;
uint8_t wordShift = (plusXValue >> 4);
uint16_t bltalwm;
for (plane = 0; plane < 2; ++plane) {
clearScratchArea();
// step 2: copy bun to scratch area that aligns right edge to word edge
// right shift so it's ascending.
custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12);
custom.bltcon1 = (shift << 12);
custom.bltadat = 0xffff;
custom.bltafwm = 0xffff;
bltalwm = 0xffff;
for (i = 0; i < shift; ++i) {
bltalwm -= (1 << i);
}
custom.bltalwm = bltalwm;
custom.bltbpt = coolbunArea + (plane * COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT);
custom.bltdpt = scratchArea + 2 + (wordShift * 2);
custom.bltamod = 0;
custom.bltbmod = wordShift * 2;
custom.bltdmod = SCRATCH_AREA_WIDTH_BYTES - 4 + (wordShift * 2);
// TODO: [ ] handle a scroll larger than 16px
custom.bltsize = (2 - wordShift) + (32 << 6);
WaitBlit();
// step 3: copy the cropped bun image to the main screen, already left
// aligned and with no fear of wraparound
// since buns are the back layer, we shouldn't need to preserve the
// background, so no c channel needed.
//
// y repeats go here. all buns are x aligned for simplicity.
custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11);
custom.bltcon1 = 0;
custom.bltapt = scratchArea + 2 + (wordShift * 2);
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltdpt = screenSetup.memoryStart + 30 + (wordShift * 2) + (screenSetup.nextBitplaneAdvance * plane) + (screenSetup.width / 8 * y);
custom.bltamod = 4 + (wordShift * 2);
custom.bltdmod = (screenSetup.width / 8) - 4 + (wordShift * 2);
custom.bltsize = (2 - wordShift) + (32 << 6);
WaitBlit();
}
}
void bun_offLeftSide(int minusXValue, int y) {
unsigned char plane;
uint8_t shift = minusXValue & 15;
uint8_t wordShift = (minusXValue >> 4);
uint8_t i;
uint16_t bltalwm;
/**
* This is a three step process, repeated for each bitplane:
*
* * clean out the scratch plane
* * copy the bun graphic shifted left so that the third blit...
* * can pick up just that area and stamp it down.
*/
for (plane = 0; plane < 2; ++plane) {
// step 1: clear the scratch area
// no modifications here!
clearScratchArea();
// step 2: copy the bun image to the scratch area in a way that aligns
// the cutoff point to a word edge. this requires a left shift, so
// it's descending.
custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (shift << 12);
custom.bltcon1 = (1 << 1) + (shift << 12);
custom.bltadat = 0xffff;
custom.bltafwm = 0xffff;
bltalwm = 0xffff;
for (i = 0; i < shift; ++i) {
bltalwm -= (1 << (15 - i));
}
custom.bltalwm = bltalwm;
// TODO: [ ] handle a scroll larger than 16px
custom.bltbpt = coolbunArea + 2 + ((COOL_BUN_HEIGHT - 1) * COOL_BUN_WIDTH_BYTES) + (plane * COOL_BUN_WIDTH_BYTES * COOL_BUN_HEIGHT);
custom.bltdpt = scratchArea + 4 - (wordShift * 2) + ((COOL_BUN_HEIGHT - 1) * SCRATCH_AREA_WIDTH_BYTES);
custom.bltamod = 0;
custom.bltbmod = wordShift * 2;
custom.bltdmod = SCRATCH_AREA_WIDTH_BYTES - 4 + (wordShift * 2);
// TODO: [ ] handle a scroll larger than 16px
custom.bltsize = (2 - wordShift) + (32 << 6);
WaitBlit();
// step 3: copy the cropped bun image to the main screen, already left
// aligned and with no fear of wraparound
// since buns are the back layer, we shouldn't need to preserve the
// background, so no c channel needed.
//
// y repeats go here. all buns are x aligned for simplicity.
custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11);
custom.bltcon1 = 0;
custom.bltapt = scratchArea + 2;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltdpt = screenSetup.memoryStart + (screenSetup.nextBitplaneAdvance * plane) + (screenSetup.width / 8 * y);
custom.bltamod = 4 + (wordShift * 2);
custom.bltdmod = (screenSetup.width / 8) - 4 + (wordShift * 2);
custom.bltsize = (2 - wordShift) + (32 << 6);
WaitBlit();
}
}
void bun_anywhere(int x, int y) {
uint8_t plane;
uint8_t shift = x & 15;
uint8_t needsExtraWord = shift != 0;
for (plane = 0; plane < 2; ++plane) {
// if we extend the bun area by a word, we only need one write
// buns will never interfere with a background so they don't need a mask
// they do need the scratch area though
custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11) + (shift << 12);
custom.bltcon1 = 0;
custom.bltapt = coolbunArea + (COOL_BUN_HEIGHT * COOL_BUN_WIDTH_BYTES * plane);
custom.bltdpt = scratchArea + 2;
// custom.bltdpt = screenSetup.memoryStart;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltamod = 0;
custom.bltdmod = 4 - (needsExtraWord * 2);
custom.bltsize = (2 + needsExtraWord) + (32 << 6);
WaitBlit();
custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11);
custom.bltcon1 = 0;
custom.bltapt = scratchArea + 2;
custom.bltdpt = screenSetup.memoryStart + WORD_ALIGNED_BYTE_POSITION(screenSetup.width, x, y) + (screenSetup.nextBitplaneAdvance * plane);
custom.bltamod = 2;
custom.bltdmod = 40 - 6;
custom.bltsize = (3) + (32 << 6);
WaitBlit();
}
}
2024-04-30 02:12:48 +00:00
int main(void) {
2024-05-02 16:52:06 +00:00
uint16_t *copperlist, *currentCopperlist;
2024-05-27 18:58:13 +00:00
int i, x, y, plane, result;
int blitShiftRight, memoryXOffset, blitWidth;
int bunPosition = -31;
2024-04-30 02:12:48 +00:00
color_t colors[16];
2024-05-27 18:58:13 +00:00
unsigned char *currentCoolBunArea, *currentCoolBun;
2024-05-02 16:52:06 +00:00
2024-05-27 18:58:13 +00:00
coolbunArea = AllocMem(COOL_BUN_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR);
currentCoolBun = coolbun;
2024-05-02 16:52:06 +00:00
2024-05-27 18:58:13 +00:00
scratchArea = AllocMem(SCRATCH_AREA_MEMORY_SIZE, MEMF_CHIP | MEMF_CLEAR);
colors[0] = 0x09b8;
colors[1] = 0x0000;
colors[2] = 0x0fff;
2024-04-30 02:12:48 +00:00
colors[3] = 0x000f;
2024-05-02 16:52:06 +00:00
prepareScreen(&screenSetup, SCREEN_WIDTH, SCREEN_HEIGHT, 4);
allocateScreenMemory(&screenSetup);
2024-05-27 18:58:13 +00:00
currentCoolBunArea = coolbunArea;
2024-05-02 16:52:06 +00:00
2024-05-27 18:58:13 +00:00
for (plane = 0; plane < COOL_BUN_PLANES; ++plane) {
for (y = 0; y < COOL_BUN_HEIGHT; ++y) {
for (x = 0; x < COOL_BUN_WIDTH_BYTES; ++x) {
*(currentCoolBunArea++) = *(currentCoolBun++);
}
}
}
2024-04-30 02:12:48 +00:00
// blitter copy the first bitplane row down to the second
2024-05-02 16:52:06 +00:00
copperlist = prepareNewCopperlist();
2024-04-30 02:12:48 +00:00
2024-05-02 16:52:06 +00:00
takeOverSystem();
setCopperlist(copperlist);
setUpDisplay(&screenSetup);
currentCopperlist = addDisplayToCopperlist(copperlist, &screenSetup);
currentCopperlist = addColorsToCopperlist(currentCopperlist, colors, 16);
endCopperlist(currentCopperlist);
2024-05-27 18:58:13 +00:00
custom.bltcon0 = 0xc0 + (1 << 10) + (1 << 8);
custom.bltcon1 = (8 << 12);
custom.bltadat = 0xffff;
custom.bltafwm = 0x00ff;
custom.bltalwm = 0x0000;
custom.bltbpt = coolbunArea;
custom.bltdpt = screenSetup.memoryStart + (40 * 10 + 36);
custom.bltbmod = -2;
custom.bltdmod = 40 - 6;
custom.bltsize = (3) + (32 << 6);
WaitBlit();
custom.bltcon0 = 0xc0 + (1 << 10) + (1 << 8);
custom.bltcon1 = (15 << 12);
custom.bltadat = 0xffff;
custom.bltafwm = 0x0001;
custom.bltalwm = 0x0000;
custom.bltbpt = coolbunArea;
custom.bltdpt = screenSetup.memoryStart + (40 * 45 + 36);
custom.bltbmod = -2;
custom.bltdmod = 40 - 6;
2024-04-30 02:12:48 +00:00
2024-05-27 18:58:13 +00:00
custom.bltsize = (3) + (32 << 6);
WaitBlit();
custom.bltcon0 = 0xc0 + (1 << 10) + (1 << 8);
custom.bltcon1 = (8 << 12);
custom.bltadat = 0xffff;
custom.bltafwm = 0x00ff;
custom.bltalwm = 0x0000;
custom.bltbpt = coolbunArea;
custom.bltdpt = screenSetup.memoryStart + (40 * 80 + 38);
custom.bltbmod = 0;
custom.bltdmod = 40 - 4;
custom.bltsize = (2) + (32 << 6);
WaitBlit();
2024-04-30 02:12:48 +00:00
/*
2024-05-02 16:52:06 +00:00
2024-05-27 18:58:13 +00:00
for (bunPosition = -31; bunPosition < screenSetup.width + 31; ++bunPosition) {
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = 0xf0 + (1 << 11);
custom.bltcon1 = 0;
custom.bltadat = 0x0000;
custom.bltdpt = screenSetup.memoryStart;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = (20) + (256 << 6);
WaitBlit();
}
if (bunPosition < 0) {
//bun_offLeftSide(abs(bunPosition), 100);
} else if (bunPosition >= screenSetup.width) {
//bun_offRightSide(bunPosition - screenSetup.width - 1, 100);
} else {
bun_anywhere(bunPosition, 100);
}
WaitTOF();
WaitTOF();
}
/*
for (i = 0; i < 32; ++i) {
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = 0xf0 + (1 << 8);
custom.bltcon1 = 0;
custom.bltadat = 0x0000;
custom.bltdpt = screenSetup.memoryStart;
custom.bltafwm = 0x0000;
custom.bltalwm = 0x0000;
custom.bltsize = (20) + (256 << 6);
WaitBlit();
}
bun_offLeftSide(i, 100);
bun_offRightSide(i, 100);
WaitTOF();
WaitTOF();
}
/*
// left shift this over 8 so it's "against the edge"
custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (1 << 11) + (0 << 12);
custom.bltcon1 = (1 << 1) + (0 << 12);
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltapt = coolbunScratchArea + 4 + (32 * 8);
custom.bltbpt = coolbunScratchArea + 4 + (31 * 8);
custom.bltdpt = screenSetup.memoryStart + 2 + (32 * 40);
custom.bltamod = -4;
custom.bltbmod = 4;
custom.bltdmod = 40 - 4;
custom.bltsize = (2) + (32 << 6);
WaitBlit();
/*
// left shift this over 8 so it's "against the edge"
custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (1 << 11) + (abs(x) << 12);
custom.bltcon1 = (1 << 1) + (abs(x) << 12);
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltapt = coolbunScratchArea + 2 + (32 * 8) + 4;
custom.bltbpt = coolbunScratchArea + 2 + 4 + (31 * 8);
custom.bltdpt = screenSetup.memoryStart + 4 + (31 * 40);
custom.bltamod = -6;
custom.bltbmod = 2;
custom.bltdmod = 40 - 6;
custom.bltsize = (1) + (32 << 6);
2024-04-30 02:12:48 +00:00
WaitBlit();
2024-05-27 18:58:13 +00:00
*/
WaitTOF();
2024-04-30 02:12:48 +00:00
2024-05-02 16:52:06 +00:00
/*
2024-05-27 18:58:13 +00:00
for (x = -15; x < 0; ++x) {
custom.bltcon0 = 0xf0 + (1 << 8);
custom.bltcon1 = 0;
custom.bltadat = 0xffff;
result = 0xffff;
for (i = 0; i < abs(x); ++i) {
result -= (1 << (15 - i));
}
custom.bltafwm = result;
2024-04-30 02:12:48 +00:00
2024-05-27 18:58:13 +00:00
custom.bltalwm = 0xffff;
custom.bltdpt = coolbunScratchArea + 2 + (32 * 8);
custom.bltsize = (2) + (1 << 6);
WaitBlit();
// left shift this over 8 so it's "against the edge"
custom.bltcon0 = 0xc0 + (1 << 8) + (1 << 10) + (1 << 11) + (abs(x) << 12);
custom.bltcon1 = (1 << 1) + (abs(x) << 12);
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltapt = coolbunScratchArea + 2 + (32 * 8) + 4;
custom.bltbpt = coolbunScratchArea + 2 + 4 + (31 * 8);
custom.bltdpt = screenSetup.memoryStart + 4 + (31 * 40);
custom.bltamod = -6;
custom.bltbmod = 2;
custom.bltdmod = 40 - 6;
custom.bltsize = (3) + (32 << 6);
WaitBlit();
WaitTOF();
}
2024-04-30 02:12:48 +00:00
2024-05-27 18:58:13 +00:00
/*
for (x = 15; x < 17; ++x) {
for (plane = 0; plane < COOL_BUN_PLANES; ++plane) {
blitShiftRight = x & 15;
memoryXOffset = (x >> 3) & 0xfffe;
blitWidth = (blitShiftRight > 0) ? 6 : 4;
custom.bltcon0 = 0xf0 + (1 << 8) + (1 << 11) + (blitShiftRight << 12);
custom.bltcon1 = 0;
custom.bltapt = coolbunScratchArea + 2 + (COOL_BUN_PLANE_SIZE * plane);
custom.bltdpt = screenSetup.memoryStart + memoryXOffset + screenSetup.nextBitplaneAdvance * plane;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltamod = 8 - blitWidth;
custom.bltdmod = 40 - blitWidth;
custom.bltsize = (blitWidth / 2) + (32 << 6);
WaitBlit();
}
WaitTOF();
}
2024-05-02 16:52:06 +00:00
*/
2024-04-30 02:12:48 +00:00
2024-05-27 18:58:13 +00:00
for (i = 0; i < 100; ++i) {
2024-04-30 02:12:48 +00:00
WaitTOF();
}
2024-05-02 16:52:06 +00:00
giveBackSystem();
2024-04-30 02:12:48 +00:00
2024-05-02 16:52:06 +00:00
freeScreenMemory(&screenSetup);
2024-04-30 02:12:48 +00:00
2024-05-02 16:52:06 +00:00
freeCopperlist(copperlist);
2024-04-30 02:12:48 +00:00
2024-05-27 18:58:13 +00:00
for (y = 0; y < 32; ++y) {
for (x = 0; x < SCRATCH_AREA_WIDTH_BYTES; ++x) {
printf("%d ", scratchArea[y * SCRATCH_AREA_WIDTH_BYTES + x]);
}
printf("\n");
}
2024-04-30 02:12:48 +00:00
2024-05-27 18:58:13 +00:00
printf("%d\n", 16 & 15);
2024-05-02 16:52:06 +00:00
2024-05-27 18:58:13 +00:00
FreeMem(coolbunArea, COOL_BUN_MEMORY_SIZE);
FreeMem(scratchArea, SCRATCH_AREA_MEMORY_SIZE);
2024-05-02 16:52:06 +00:00
2024-04-30 02:12:48 +00:00
return 0;
}