Compare commits

..

14 Commits

Author SHA1 Message Date
John Bintz c9f1a55ebd Need genam too 2024-09-26 17:43:53 -04:00
John Bintz 457145f964 Ruby 2024-09-26 17:38:17 -04:00
John Bintz 98c05795fc More cleanup 2024-09-26 17:36:22 -04:00
John Bintz 623e51d164 More cleanups 2024-09-26 17:34:58 -04:00
John Bintz f2f699d2c9 Remove some files 2024-09-26 17:33:32 -04:00
John Bintz 38bf0dd0b2 prepping for release 2024-09-26 17:32:04 -04:00
John Bintz 9e8939089d reword 2024-09-22 08:21:25 -04:00
John Bintz e19f59246e how i'll make it fast eventually 2024-09-22 08:20:58 -04:00
John Bintz d1421929d8 Update README 2024-09-22 08:13:38 -04:00
John Bintz 7ba0c167cb finish up video stuff 2024-09-22 08:12:37 -04:00
John Bintz bd47027b4a OK this is CPU bound, much precalculating required 2024-09-22 07:36:27 -04:00
John Bintz f3913286eb binary 2024-09-22 07:32:44 -04:00
John Bintz 6b86be00d4 More performance stuff
Still can't get 50fps on an A500 but this is good enough for now.
2024-09-22 07:32:13 -04:00
John Bintz bd035eaea1 Move blitter commoon stuff to blitter header 2024-09-22 06:52:22 -04:00
28 changed files with 700 additions and 1903 deletions

BIN
32x50 Executable file

Binary file not shown.

90
32x50_bun.c Normal file
View File

@ -0,0 +1,90 @@
/**
* What do we need
* * [ ] screen setup
*/
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <clib/graphics_protos.h>
#include "system/system.h"
#include "system/copper.h"
#include "system/blitter.h"
#include "screen.h"
extern struct Custom far custom;
extern struct CIA far ciaa;
uint16_t custom_color = (uint16_t)offsetof(Custom, color);
uint16_t custom_sprite = (uint16_t)offsetof(Custom, sprpt);
uint16_t custom_sprite_control = (uint16_t)offsetof(Custom, spr);
extern unsigned char chip coolbun[];
int main(void) {
struct ScreenDefinition screenDefinition;
struct ActiveScreenBufferDetails activeScreenBufferDetails;
uint16_t *copperlist, *currentCopperlist;
void *copperlistBitplanePointers[8][2];
int i, plane;
allocateDoubleBufferedScreenMemory(
&screenDefinition,
&activeScreenBufferDetails,
320,
256,
2
);
copperlist = prepareNewCopperlist(300);
currentCopperlist = addDisplayToCopperlist(
copperlist,
&screenDefinition,
&activeScreenBufferDetails,
&copperlistBitplanePointers
);
COPPERLIST_MOVE(currentCopperlist, custom_color, 0x3a6);
COPPERLIST_MOVE(currentCopperlist, custom_color + 2, 0x000);
COPPERLIST_MOVE(currentCopperlist, custom_color + 4, 0xfff);
currentCopperlist = setUpEmptySpritesInCopperlist(currentCopperlist);
endCopperlist(currentCopperlist);
takeOverSystem();
setCopperlist(copperlist);
setUpDisplay((uint32_t)screenDefinition.bitplanes);
// Render a bun at 32x50
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, 0);
custom.bltcon1 = BLTCON1(BLITTER_ASCENDING, 0);
custom.bltapt = coolbun + (plane * 4 * 32);
custom.bltdpt = activeScreenBufferDetails.planes[plane] + (50 * 320 / 8) + 32 / 8;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltamod = 0;
custom.bltdmod = 40 - 4;
custom.bltsize = 2 + (32 << 6);
WaitBlit();
}
while (1) {
if ((ciaa.ciapra >> 6) != 3) break;
}
giveBackSystem();
freeCopperlist(copperlist);
teardownScreen(&screenDefinition);
}

BIN
33x50 Executable file

Binary file not shown.

127
33x50_bun.c Normal file
View File

@ -0,0 +1,127 @@
/**
* What do we need
* * [ ] screen setup
*/
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <clib/graphics_protos.h>
#include "system/system.h"
#include "system/copper.h"
#include "system/blitter.h"
#include "screen.h"
extern struct Custom far custom;
extern struct CIA far ciaa;
uint16_t custom_color = (uint16_t)offsetof(Custom, color);
uint16_t custom_sprite = (uint16_t)offsetof(Custom, sprpt);
uint16_t custom_sprite_control = (uint16_t)offsetof(Custom, spr);
extern unsigned char chip coolbun[];
int main(void) {
struct ScreenDefinition screenDefinition;
struct ActiveScreenBufferDetails activeScreenBufferDetails;
uint16_t *copperlist, *currentCopperlist;
void *copperlistBitplanePointers[8][2];
int i, plane, x, y, dirX, dirY, shift, byteX;
allocateDoubleBufferedScreenMemory(
&screenDefinition,
&activeScreenBufferDetails,
320,
256,
2
);
copperlist = prepareNewCopperlist(300);
currentCopperlist = addDisplayToCopperlist(
copperlist,
&screenDefinition,
&activeScreenBufferDetails,
&copperlistBitplanePointers
);
COPPERLIST_MOVE(currentCopperlist, custom_color, 0x3a6);
COPPERLIST_MOVE(currentCopperlist, custom_color + 2, 0x000);
COPPERLIST_MOVE(currentCopperlist, custom_color + 4, 0xfff);
currentCopperlist = setUpEmptySpritesInCopperlist(currentCopperlist);
endCopperlist(currentCopperlist);
takeOverSystem();
setCopperlist(copperlist);
setUpDisplay((uint32_t)screenDefinition.bitplanes);
// Render a bun at 32x50
x = 32;
y = 50;
dirX = 1;
dirY = 1;
while (1) {
WaitTOF();
swapCurrentScreenBuffer(&screenDefinition, &activeScreenBufferDetails);
shift = x & 15;
byteX = (x >> 4 * 2);
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift);
custom.bltcon1 = BLTCON1(BLITTER_ASCENDING, 0);
custom.bltapt = coolbun + (plane * 4 * 32);
custom.bltdpt = activeScreenBufferDetails.planes[plane] + (y * 320 / 8) + byteX;
custom.bltafwm = 0xffff;
if (shift == 0) {
custom.bltalwm = 0xffff;;
} else {
custom.bltalwm = 0x0000;
}
custom.bltamod = shift ? -2 : 0;
custom.bltdmod = 40 - (shift ? 6 : 4);
custom.bltsize = (shift ? 3 : 2) + (32 << 6);
WaitBlit();
}
x += dirX;
if (x == 320 - 32) {
x -= 1;
dirX = -dirX;
}
if (x < 0) {
x = 0;
dirX = -dirX;
}
y += dirY;
if (y == 256 - 32) {
y -= 1;
dirY = -dirY;
}
if (y > 0) {
y = 0;
dirY -= dirY;
}
if ((ciaa.ciapra >> 6) != 3) break;
}
giveBackSystem();
freeCopperlist(copperlist);
teardownScreen(&screenDefinition);
}

View File

@ -1 +0,0 @@
* [ ] Move bun calculation to separate file for CuTest and vamos

50
README.md Normal file
View File

@ -0,0 +1,50 @@
## Cool Bun Demo
![demo](./demo.gif)
Built for [The Obligatory Amiga Blitter Video](https://makertube.net/w/eV545ku522sRq8CTcxDuFZ).
Uses a bunch of C and Assembler code to drive the blitter, sprites, and copper
to display high color Topaz art overtop of flying cool bun logos.
## Running
Click the mouse to escape any demo.
* `main`: Main demo
* `32x50`, `33x50`, `left_side`, `right_side`: Rendering Cool Bun in various
locations on screen.
* `any_position`: Cool Bun flies around like a DVD player pause screen.
* `keyboard_interrupt`: Tests using `input.device` to access the keyboard.
* `blitter_speed_test`: Get the speed of blitter vs. CPU memory operations
* `bun_test`: Run some unit tests (yes, really!)
This will get 50 fps on an 020, and 25 or lower on an 68EC020 and below.
## Building
### Vamos
You'll want [Vamos](https://github.com/cnvogelg/amitools/blob/master/docs/vamos.md),
and [SAS/C](https://www.amigaclub.be/blog/steffest/2/amiga-c%20compilers)
&amp; [GenAm from DevPac](https://archive.org/details/Devpac_v3.14_1994-12-16_HiSoft)
on Vamos's path:
```
# main
ruby ./image_converter.rb && touch images.s && vamos -- smake
# any others
vamos -- smake <other>
```
The image converter requires Ruby 3.2.4 and RMagick installed.
## Performance
The best way I can think of to make this way faster is for a script in
Ruby or Python to calculate every blitter register for every frame of data
for bun renders and clears, store that in a list of words, and rip through
those lists in Assembler, shotgunning the values directly into the registers
without the C code needing to track bun positions and bun clears. That's a
project for another day.

BIN
agnus.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

BIN
any_position Executable file

Binary file not shown.

144
any_position.c Normal file
View File

@ -0,0 +1,144 @@
/**
* What do we need
* * [ ] screen setup
*/
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <clib/graphics_protos.h>
#include "system/system.h"
#include "system/copper.h"
#include "system/blitter.h"
#include "screen.h"
extern struct Custom far custom;
extern struct CIA far ciaa;
uint16_t custom_color = (uint16_t)offsetof(Custom, color);
uint16_t custom_sprite = (uint16_t)offsetof(Custom, sprpt);
uint16_t custom_sprite_control = (uint16_t)offsetof(Custom, spr);
extern unsigned char chip coolbun[];
int main(void) {
struct ScreenDefinition screenDefinition;
struct ActiveScreenBufferDetails activeScreenBufferDetails;
uint16_t *copperlist, *currentCopperlist;
void *copperlistBitplanePointers[8][2];
int i, plane, x, y, dirX, dirY, shift, byteX, clearY;
allocateDoubleBufferedScreenMemory(
&screenDefinition,
&activeScreenBufferDetails,
320,
256,
2
);
copperlist = prepareNewCopperlist(300);
currentCopperlist = addDisplayToCopperlist(
copperlist,
&screenDefinition,
&activeScreenBufferDetails,
&copperlistBitplanePointers
);
COPPERLIST_MOVE(currentCopperlist, custom_color, 0x3a6);
COPPERLIST_MOVE(currentCopperlist, custom_color + 2, 0x000);
COPPERLIST_MOVE(currentCopperlist, custom_color + 4, 0xfff);
currentCopperlist = setUpEmptySpritesInCopperlist(currentCopperlist);
endCopperlist(currentCopperlist);
takeOverSystem();
setCopperlist(copperlist);
setUpDisplay((uint32_t)screenDefinition.bitplanes);
// Render a bun at 32x50
x = 32;
y = 50;
dirX = 1;
dirY = 1;
while (1) {
WaitTOF();
swapCurrentScreenBuffer(&screenDefinition, &activeScreenBufferDetails);
shift = x & 15;
byteX = ((x >> 4) * 2);
clearY = y - 4;
if (clearY < 0) clearY = 0;
if (clearY + 40 > 255) clearY = 255 - 40;
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = BLTCON0(0xc0, 0, 0, 0, 1, 0);
custom.bltcon1 = 0;
custom.bltadat = 0x0000;
custom.bltdpt = activeScreenBufferDetails.planes[plane] + (clearY * 320 / 8);
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
custom.bltsize = BLTSIZE(20, 40);
custom.bltdmod = 0;
WaitBlit();
}
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift);
custom.bltcon1 = BLTCON1(BLITTER_ASCENDING, 0);
custom.bltapt = coolbun + (plane * 4 * 32);
custom.bltdpt = activeScreenBufferDetails.planes[plane] + (y * 320 / 8) + byteX;
custom.bltafwm = 0xffff;
if (shift == 0) {
custom.bltalwm = 0xffff;;
} else {
custom.bltalwm = 0x0000;
}
custom.bltamod = shift ? -2 : 0;
custom.bltdmod = 40 - (shift ? 6 : 4);
custom.bltsize = (shift ? 3 : 2) + (32 << 6);
WaitBlit();
}
x += dirX;
if (x == 320 - 32) {
x -= 1;
dirX = -dirX;
}
if (x < 0) {
x = 0;
dirX = -dirX;
}
y += dirY;
if (y == 256 - 32) {
y -= 1;
dirY = -dirY;
}
if (y < 0) {
y = 0;
dirY = -dirY;
}
if ((ciaa.ciapra >> 6) != 3) break;
}
giveBackSystem();
freeCopperlist(copperlist);
teardownScreen(&screenDefinition);
}

BIN
basics

Binary file not shown.

172
basics.s
View File

@ -1,172 +0,0 @@
XREF _custom
; write this from scratch and get it working
; then plug it into C
FUNC_CNT SET -30
FUNCDEF MACRO
_LVO\1 EQU FUNC_CNT
FUNC_CNT SET FUNC_CNT-6
ENDM
INCDIR "include_i_39:"
INCDIR "extra_lvos_39:"
INCLUDE "exec/exec_lib.i"
INCLUDE "exec/types.i"
INCLUDE "exec/execbase.i"
INCLUDE "exec/libraries.i" # get the CALLLIB macro
INCLUDE "graphics/gfxbase.i"
INCLUDE "graphics_lvo.i"
INCLUDE "hardware/custom.i"
INCLUDE "hardware/dmabits.i"
START:
BSR _takeOverSystem
BSR _giveBackSystem
MOVE.L #0,D0
RTS
OpenGraphicsLibrary MACRO
LEA GraphicsLibrary,A1
MOVEQ #0,D0
CALLLIB _LVOOpenLibrary
MOVE.L D0,GraphicsBase
ENDM
TakeOverView MACRO
MOVE.L GraphicsBase,A6
MOVE.L gb_ActiView(A6),OldView
MOVEQ #0,D0
CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF
ENDM
PreserveOldCopper MACRO
MOVE.L $26(A6),OldCopper1
MOVE.L $32(A6),OldCopper2
ENDM
GetVBRPointer MACRO
BSR getVBR
MOVE.L D0,VBRPtr
ENDM
PreserveOldRegisters MACRO
LEA _custom,A6
MOVE.W adkconr(A6),Oldadkcon
MOVE.W intenar(A6),Oldintena
MOVE.W dmaconr(A6),Olddmacon
ENDM
ClearRegisters MACRO
MOVE.W #$7FFF,D0
BSR waitRaster
MOVE.W D0,intena(A6)
MOVE.W D0,dmacon(A6)
MOVE.W D0,intreq(A6)
ENDM
SetRegisters MACRO
MOVE.W #$C000,intena(A6) ; enable master interrupt
MOVE.W #$3FFF,intena(A6) ; disable every other interrupt
MOVE.W #DMAF_SETCLR|DMAF_COPPER|DMAF_RASTER|DMAF_BLITTER,dmacon(A6)
MOVE.W #DMAF_AUDIO|DMAF_DISK|DMAF_SPRITE,dmacon(A6)
ENDM
_takeOverSystem:
MOVEM.L A6,-(SP)
CLR.W $100
MOVE.L $4,A6
CALLLIB _LVOForbid
OpenGraphicsLibrary
PreserveOldCopper
CALLLIB _LVOOwnBlitter
CALLLIB _LVOWaitBlit
PreserveOldRegisters
SetRegisters
TakeOverView
MOVEM.L (SP)+,A6
RTS
waitRaster:
MOVE.L D0,-(SP)
.loop:
MOVE.L $DFF004,D0
AND.L #$1FF00,D0
CMP.L #303<<8,D0
BNE .loop
MOVE.L (SP)+,D0
RTS
_giveBackSystem:
CLR.W $100
MOVEM.L A6,-(SP)
LEA _custom,A6
MOVE.W #$8000,d0
OR.W D0,Olddmacon
OR.W D0,Oldintena
OR.W D0,Oldadkcon
SUBQ #1,D0
;ClearRegisters
MOVE.L OldCopper1,cop1lc(A6)
MOVE.L OldCopper2,cop2lc(A6)
MOVE.W #1,copjmp1(A6)
MOVE.W Olddmacon,intena(A6)
MOVE.W Olddmacon,dmacon(A6)
MOVE.W Oldadkcon,adkcon(A6)
MOVE.L OldView,A1
MOVE.L GraphicsBase,A6
CALLLIB _LVOLoadView
CALLLIB _LVOWaitTOF
CALLLIB _LVOWaitTOF
MOVE.L $4,A6
MOVE.L GraphicsBase,D0
MOVE.L D0,A1
CALLLIB _LVOCloseLibrary
CALLLIB _LVOPermit
MOVEM.L (SP)+,A6
RTS
getVBR:
MOVE.L A5,-(SP)
MOVEQ #0,D0
MOVE.L $4,A6
BTST #0,AttnFlags+1(A6)
BEQ .is68K
LEA .get010VBR(pc),A5
CALLLIB _LVOSupervisor
.is68K:
MOVE.L (SP)+,A5
RTS
.get010VBR:
dc.l $4E7A0801 ; movec vcr,d0
RTE
CNOP 0,4
GraphicsLibrary dc.b 'graphics.library',0
CNOP 0,4
GraphicsBase dc.l 1
OldView dc.l 1
OldCopper1 dc.l 1
OldCopper2 dc.l 1
VBRPtr dc.l 1
Oldadkcon dc.w 0
Oldintena dc.w 0
Olddmacon dc.w 0

Binary file not shown.

View File

@ -1,98 +0,0 @@
#include <clib/exec_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <exec/memory.h>
#include <graphics/gfxbase.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <exec/types.h>
extern struct GfxBase *GfxBase;
extern far struct Custom custom;
int main(void) {
UWORD OldDMACON,OldINTENA,OldINTREQ,OldADKCON;
struct View *OldView = ((struct GfxBase *)GfxBase)->ActiView;
ULONG OldCopper = custom.cop1lc;
ULONG OldCopper2 = custom.cop2lc;
UWORD *copperlist = AllocMem(10000, MEMF_CHIP | MEMF_CLEAR);
UWORD *currentCopperlist;
UBYTE *bitplanes = AllocMem(320 * 256, MEMF_CHIP | MEMF_CLEAR);
int i;
LoadView(0);
WaitTOF();
WaitTOF();
OwnBlitter();
WaitBlit();
Forbid();
OldDMACON = custom.dmaconr | 0x8000;
OldINTENA = custom.intenar | 0x8000;
//OldINTREQ = custom.intreqr | 0x8000;
OldADKCON = custom.adkconr | 0x8000;
custom.intreq = 0x7fff;
custom.cmacon = 0x7fff;
custom.cmacon = 0x7fff;
// enable
custom.dmacon = DMAF_SETCLR | DMAF_COPPER | DMAF_RASTER | DMAF_BLITTER;
// disable
custom.dmacon = DMAF_AUDIO | DMAF_DISK | DMAF_SPRITE;
custom.bplcon0 = (1 << 9) + (1 << 12);
custom.bplcon1 = 0;
custom.bplcon2 = 0;
custom.bpl1mod = 0;
custom.bpl2mod = 0;
custom.diwstrt = 0x2c21;
custom.diwstop = 0x2cc1;
custom.ddfstrt = 0x0038;
custom.ddfstop = 0x00d0;
currentCopperlist = copperlist;
*(currentCopperlist++) = 0x0050;
*(currentCopperlist++) = ((ULONG)bitplanes >> 16);
*(currentCopperlist++) = 0x0020;
*(currentCopperlist++) = ((ULONG)bitplanes && 16);
*(currentCopperlist++) = 0xffff;
*(currentCopperlist++) = 0xfffe;
custom.cop1lc = copperlist;
for (i = 0; i < 200; ++i) {
WaitTOF();
}
custom.dmacon = 0x7FFF;
custom.dmacon = OldDMACON;
custom.intena = 0x7FFF;
custom.intena = OldINTENA;
/*
custom.intreq = 0x7FFF;
custom.intreq = OldINTREQ;
*/
custom.adkcon = 0x7FFF;
custom.adkcon = OldADKCON;
custom.cop1lc = OldCopper;
custom.cop2lc = OldCopper1;
LoadView(OldView);
WaitTOF();
WaitTOF();
WaitBlit();
DisownBlitter();
Permit();
FreeMem(copperlist, 10000);
FreeMem(bitplanes, 320 * 256);
}

View File

62
bun.c
View File

@ -13,6 +13,7 @@
#include "screen.h"
#include "bun.h"
#include "system/system.h"
#include "system/blitter.h"
#define COOL_BUN_WIDTH (32)
#define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8)
@ -40,16 +41,8 @@
// linked as raw bytes in assembler
extern unsigned char chip coolbun[];
#define BLTCON0( \
minterm, aChan, bChan, cChan, dChan, shift \
) (minterm + (aChan << 11) + (bChan << 10) + (cChan << 9) + (dChan << 8) + (shift << 12))
#define BLTCON1(descending, shift) ((descending << 1) + (shift << 12))
extern struct Custom far custom;
#define BLITTER_ASCENDING (0)
#define BLITTER_DESCENDING (1)
struct BunClear {
uint16_t memoryStartOffsetBytes;
uint16_t widthWords;
@ -63,6 +56,33 @@ struct BunClear {
uint8_t *coolbunPlaneStarts[3][2];
uint16_t bunRightSide_bltalwmPrecalc[16];
uint16_t bunLeftSide_bltalwmPrecalc[16];
void precalculateBunBLTALWM() {
int shift, j;
uint16_t bltalwm;
for (shift = 0; shift < 16; ++shift) {
// right
bltalwm = 0x0000;
for (j = 0; j < 15 - shift; ++j) {
bltalwm += (1 << (15 - j));
}
bunRightSide_bltalwmPrecalc[shift] = bltalwm;
//left
bltalwm = 0x0000;
for (j = 0; j <= 15 - shift; ++j) {
bltalwm += (1 << j);
}
bunLeftSide_bltalwmPrecalc[shift] = bltalwm;
}
}
void bun_offRightSide(
int plusXValue,
int y,
@ -82,10 +102,14 @@ void bun_offRightSide(
bunClear->widthWords = 2 - wordShift;
bunClear->direction = BLITTER_ASCENDING;
bltalwm = bunRightSide_bltalwmPrecalc[shift];
/*
bltalwm = 0x0000;
for (i = 0; i <= 15 - shift; ++i) {
bltalwm += (1 << (15 - i));
}
*/
bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift);
bltcon1 = BLTCON1(bunClear->direction, shift);
@ -137,10 +161,14 @@ void bun_offLeftSide(
bunClear->widthWords = 2 - wordShift;
bunClear->direction = BLITTER_DESCENDING;
bltalwm = bunLeftSide_bltalwmPrecalc[shift];
/*
bltalwm = 0x0000;
for (i = 0; i <= 15 - shift; ++i) {
bltalwm += (1 << i);
}
*/
bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift);
bltcon1 = BLTCON1(bunClear->direction, shift);
@ -222,6 +250,8 @@ void bun_anywhere(
}
}
#define ENABLE_RENDER_BUN_CHECKING (0)
void renderBun(
int x,
int y,
@ -231,14 +261,17 @@ void renderBun(
) {
/**
* Conditions that will cause the program to crash if met. If your bun
* isn't rendering, it's due to here.
* isn't rendering, it's due to here. Turn off checking once you know
* everything is solid to save some CPU.
*
* TODO: Handle top/bottom off-screen as well.
*/
if (x < -31) return;
if (x > screenDefinition->width + 31) return;
if (y < 1) return;
if (y > screenDefinition->height - COOL_BUN_HEIGHT - 1) return;
if (ENABLE_RENDER_BUN_CHECKING) {
if (x < -31) return;
if (x > screenDefinition->width + 31) return;
if (y < 1) return;
if (y > screenDefinition->height - COOL_BUN_HEIGHT - 1) return;
}
if (x < 0) {
bun_offLeftSide(
@ -355,6 +388,7 @@ void setupBunRenderer(
buildBunAngleAdjustments();
calculateAllBunPositions(screenDefinition);
precalculateBunRenderInfo();
precalculateBunBLTALWM();
}
/**
@ -373,7 +407,7 @@ void clearCurrentBuns(
if (!hasBunClear[bunRenderer->activeScreenBufferDetails->currentBuffer]) return;
bltcon0 = 0xc0 + (1 << 8);
bltcon0 = BLTCON0(0xc0, 0, 0, 0, 1, 0);
for (bun = 0; bun < BUN_COUNT; ++bun) {
currentBunClear = &bunClearForScreen[bunRenderer->activeScreenBufferDetails->currentBuffer][bun];

BIN
demo.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 KiB

BIN
left_side Executable file

Binary file not shown.

90
left_side.c Normal file
View File

@ -0,0 +1,90 @@
/**
* What do we need
* * [ ] screen setup
*/
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <clib/graphics_protos.h>
#include "system/system.h"
#include "system/copper.h"
#include "system/blitter.h"
#include "screen.h"
extern struct Custom far custom;
extern struct CIA far ciaa;
uint16_t custom_color = (uint16_t)offsetof(Custom, color);
uint16_t custom_sprite = (uint16_t)offsetof(Custom, sprpt);
uint16_t custom_sprite_control = (uint16_t)offsetof(Custom, spr);
extern unsigned char chip coolbun[];
int main(void) {
struct ScreenDefinition screenDefinition;
struct ActiveScreenBufferDetails activeScreenBufferDetails;
uint16_t *copperlist, *currentCopperlist;
void *copperlistBitplanePointers[8][2];
int i, plane;
allocateDoubleBufferedScreenMemory(
&screenDefinition,
&activeScreenBufferDetails,
320,
256,
2
);
copperlist = prepareNewCopperlist(300);
currentCopperlist = addDisplayToCopperlist(
copperlist,
&screenDefinition,
&activeScreenBufferDetails,
&copperlistBitplanePointers
);
COPPERLIST_MOVE(currentCopperlist, custom_color, 0x3a6);
COPPERLIST_MOVE(currentCopperlist, custom_color + 2, 0x000);
COPPERLIST_MOVE(currentCopperlist, custom_color + 4, 0xfff);
currentCopperlist = setUpEmptySpritesInCopperlist(currentCopperlist);
endCopperlist(currentCopperlist);
takeOverSystem();
setCopperlist(copperlist);
setUpDisplay((uint32_t)screenDefinition.bitplanes);
// Render a cut off bun at -8x50
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, 8);
custom.bltcon1 = BLTCON1(BLITTER_DESCENDING, 8);
custom.bltapt = coolbun + (plane * 4 * 32) + (31 * 4) + 2;
custom.bltdpt = activeScreenBufferDetails.planes[plane] + ((50 + 31) * 320 / 8) + 2;
custom.bltafwm = 0xffff;
custom.bltalwm = 0x00ff;
custom.bltamod = 0;
custom.bltdmod = 40 - 4;
custom.bltsize = 2 + (32 << 6);
WaitBlit();
}
while (1) {
if ((ciaa.ciapra >> 6) != 3) break;
}
giveBackSystem();
freeCopperlist(copperlist);
teardownScreen(&screenDefinition);
}

BIN
main

Binary file not shown.

31
main.c
View File

@ -29,6 +29,22 @@
#include "types.h"
#include "bun.h"
/**
* This barely gets 50fps on an 020 but I'm leaving it for now.
* The demo is definitely CPU bound.
*
* Potential improvements:
*
* [ ] Precalculate even more of bun.c. This may get 50fps on an A500 if I do this.
* It would require more significant caching of as much stuff as possible.
* The A500 is spending entirely too much time on CPU tasks.
* [ ] Topaz re-rendering is limited to squares or rows that changed in the last frame.
* I tried this once but I need a more precise way of redrawing those areas.
* [ ] Cool bun clears and re-renders happen in the same pass.
* This would likely mean extending the cool bun art to have a blank word on the left,
* and enough blank rows above and below to cover clearing areas above and below.
*/
extern struct Custom far custom;
extern struct CIA far ciaa;
@ -61,20 +77,17 @@ extern uint8_t chip MaskBitplane[];
#define TOPAZ_WIDTH_BYTES (TOPAZ_WIDTH_PIXELS / 8)
#define TOPAZ_WIDTH_WORDS (TOPAZ_WIDTH_PIXELS / 16)
#define BLTSIZE(w, h) (w + (h << 6))
void renderTopaz(void) {
int plane;
uint16_t bltcon0, bltcmod;
uint16_t bltcmod;
uint8_t *bltbpt;
bltcon0 = 0xca + (1 << 8) + (1 << 9) + (1 << 10) + (1 << 11);
bltcmod = screenDefinition.byteWidth - TOPAZ_WIDTH_BYTES;
bltbpt = TopazBitplanes;
for (plane = 0; plane < 3; ++plane) {
custom.bltcon0 = bltcon0;
custom.bltcon0 = BLTCON0(0xca, 1, 1, 1, 1, 0);
custom.bltcon1 = 0;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
@ -99,15 +112,14 @@ void renderTopaz(void) {
void renderMostlyTopaz(void) {
int plane;
uint16_t bltcon0, bltcmod;
uint16_t bltcmod;
uint8_t *bltbpt;
bltcon0 = 0xca + (1 << 8) + (1 << 9) + (1 << 10) + (1 << 11);
bltcmod = screenDefinition.byteWidth - TOPAZ_WIDTH_BYTES;
bltbpt = TopazBitplanes;
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = bltcon0;
custom.bltcon0 = BLTCON0(0xca, 1, 1, 1, 1, 0);
custom.bltcon1 = 0;
custom.bltafwm = 0xffff;
custom.bltalwm = 0xffff;
@ -362,9 +374,10 @@ int main(void) {
if ((ciaa.ciapra >> 6) != 3) break;
i++;
i %= FRAMES_FOR_SCREEN;
if (i > FRAMES_FOR_SCREEN) i = 0;
}
// somthing in here causes an A500 in KS 1.3 to crash
giveBackSystem();
teardownKeyboard();

File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 62 KiB

BIN
right_side Executable file

Binary file not shown.

90
right_side.c Normal file
View File

@ -0,0 +1,90 @@
/**
* What do we need
* * [ ] screen setup
*/
#include <hardware/custom.h>
#include <hardware/cia.h>
#include <clib/graphics_protos.h>
#include "system/system.h"
#include "system/copper.h"
#include "system/blitter.h"
#include "screen.h"
extern struct Custom far custom;
extern struct CIA far ciaa;
uint16_t custom_color = (uint16_t)offsetof(Custom, color);
uint16_t custom_sprite = (uint16_t)offsetof(Custom, sprpt);
uint16_t custom_sprite_control = (uint16_t)offsetof(Custom, spr);
extern unsigned char chip coolbun[];
int main(void) {
struct ScreenDefinition screenDefinition;
struct ActiveScreenBufferDetails activeScreenBufferDetails;
uint16_t *copperlist, *currentCopperlist;
void *copperlistBitplanePointers[8][2];
int i, plane;
allocateDoubleBufferedScreenMemory(
&screenDefinition,
&activeScreenBufferDetails,
320,
256,
2
);
copperlist = prepareNewCopperlist(300);
currentCopperlist = addDisplayToCopperlist(
copperlist,
&screenDefinition,
&activeScreenBufferDetails,
&copperlistBitplanePointers
);
COPPERLIST_MOVE(currentCopperlist, custom_color, 0x3a6);
COPPERLIST_MOVE(currentCopperlist, custom_color + 2, 0x000);
COPPERLIST_MOVE(currentCopperlist, custom_color + 4, 0xfff);
currentCopperlist = setUpEmptySpritesInCopperlist(currentCopperlist);
endCopperlist(currentCopperlist);
takeOverSystem();
setCopperlist(copperlist);
setUpDisplay((uint32_t)screenDefinition.bitplanes);
// Render a cut off bun at -8x50
for (plane = 0; plane < 2; ++plane) {
custom.bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, 8);
custom.bltcon1 = BLTCON1(BLITTER_ASCENDING, 8);
custom.bltapt = coolbun + (plane * 4 * 32);
custom.bltdpt = activeScreenBufferDetails.planes[plane] + (50 * 320 / 8) + (40 - 4);
custom.bltafwm = 0xffff;
custom.bltalwm = 0xff00;
custom.bltamod = 0;
custom.bltdmod = 40 - 4;
custom.bltsize = 2 + (32 << 6);
WaitBlit();
}
while (1) {
if ((ciaa.ciapra >> 6) != 3) break;
}
giveBackSystem();
freeCopperlist(copperlist);
teardownScreen(&screenDefinition);
}

View File

@ -21,6 +21,7 @@ void allocateDoubleBufferedScreenMemory(
uint8_t bitplanes
) {
unsigned char *memory;
int buffer, plane;
screenDefinition->width = width;
screenDefinition->height = height;
@ -38,6 +39,14 @@ void allocateDoubleBufferedScreenMemory(
screenDefinition->nextBitplaneAdvance = screenDefinition->byteWidth * height;
screenDefinition->nextBufferAdvance = screenDefinition->nextBitplaneAdvance * bitplanes;
for (buffer = 0; buffer < 2; ++buffer) {
for (plane = 0; plane < bitplanes; ++plane) {
screenDefinition->bufferPlanes[buffer][plane] = screenDefinition->memoryStart +
buffer * screenDefinition->nextBufferAdvance +
plane * screenDefinition->nextBitplaneAdvance;
}
}
setActiveScreenBuffer(screenDefinition, activeScreenBufferDetails, 0);
}
@ -59,9 +68,7 @@ void setActiveScreenBuffer(
currentScreen->currentBuffer = buffer;
for (plane = 0; plane < screenDefinition->bitplanes; ++plane) {
currentScreen->planes[plane] = screenDefinition->memoryStart +
buffer * screenDefinition->nextBufferAdvance +
plane * screenDefinition->nextBitplaneAdvance;
currentScreen->planes[plane] = screenDefinition->bufferPlanes[buffer][plane];
}
}

View File

@ -17,6 +17,7 @@ struct ScreenDefinition {
uint16_t byteWidth;
uint16_t nextBitplaneAdvance;
uint16_t nextBufferAdvance;
unsigned char *bufferPlanes[2][8];
};
struct ActiveScreenBufferDetails {

View File

@ -1,4 +1,9 @@
MAIN_OBJS = main.o images.o system.lib screen.o bun.o
32_objs = 32x50_bun.o system.lib screen.o images.o
33_objs = 33x50_bun.o system.lib screen.o images.o
left_side_objs = left_side.o system.lib screen.o images.o
right_side_objs = right_side.o system.lib screen.o images.o
any_position = any_position.o system.lib screen.o images.o
all: main
@ -14,6 +19,21 @@ system.lib: system/system.o system/copper.o system/blitter.o system/debug.o
main: $(MAIN_OBJS)
sc link to main math=standard $(MAIN_OBJS)
32x50: $(32_objs)
sc link to 32x50 $(32_objs)
33x50: $(33_objs)
sc link to 33x50 $(33_objs)
left_side: $(left_side_objs)
sc link to left_side $(left_side_objs)
right_side: $(right_side_objs)
sc link to right_side $(right_side_objs)
any_position: $(any_position)
sc link to any_position $(any_position)
test: bun_test.o bun.o
sc link to bun_test identifierlength=32 math=standard bun_test.o bun.o cutest/CuTest.c

View File

@ -1,8 +1,14 @@
#ifndef __BLITTER_H__
#define __BLITTER_H__
#include "types.h"
#include "screen.h"
#define BLTSIZE(w, h) (w + (h << 6))
#define BLTCON0( \
minterm, aChan, bChan, cChan, dChan, shift \
) (minterm + (aChan << 11) + (bChan << 10) + (cChan << 9) + (dChan << 8) + (shift << 12))
#define BLTCON1(descending, shift) ((descending << 1) + (shift << 12))
#define BLITTER_ASCENDING (0)
#define BLITTER_DESCENDING (1)
/*

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB