diff --git a/keyboard_interrupt b/keyboard_interrupt new file mode 100755 index 0000000..7cd554f Binary files /dev/null and b/keyboard_interrupt differ diff --git a/keyboard_interrupt.c b/keyboard_interrupt.c new file mode 100644 index 0000000..686fb38 --- /dev/null +++ b/keyboard_interrupt.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include + +static struct MsgPort *keyboardMessagePort = NULL; +static struct IOStdReq *keyboardIO = NULL; +static struct Interrupt keyboardInterrupt; + +extern far ULONG keyboardPressed; + +extern struct InputEvent * __asm stupidKeyboardHandler( + register __a0 struct InputEvent *input, + register __a1 APTR id +); + +void setupKeyboard(void) { + if (keyboardMessagePort = CreatePort(NULL, NULL)) { + if (keyboardIO = (struct IOStdReq *)CreateExtIO( + keyboardMessagePort, + sizeof(struct IOStdReq) + )) { + // OpenDevice returns 0 if successful + if (!OpenDevice( + "input.device", + 0, + (struct IORequest *)keyboardIO, + 0 + )) { + keyboardInterrupt.is_Node.ln_Type = NT_INTERRUPT; + keyboardInterrupt.is_Node.ln_Pri = 100; + keyboardInterrupt.is_Node.ln_Name = (STRPTR)"cool bun"; + keyboardInterrupt.is_Code = (void (*)())&stupidKeyboardHandler; + + keyboardIO->io_Data = (void *)&keyboardInterrupt; + keyboardIO->io_Command = IND_ADDHANDLER; + + DoIO((struct IORequest *)keyboardIO); + } + } + } +} + +void teardownKeyboard(void) { + if (keyboardIO) { + keyboardIO->io_Data = (void *)&keyboardInterrupt; + keyboardIO->io_Command = IND_REMHANDLER; + DoIO((struct IORequest *)keyboardIO); + CloseDevice((struct IORequest *)keyboardIO); + DeleteIORequest((struct IORequest *)keyboardIO); + keyboardIO = NULL; + } + + if (keyboardMessagePort) { + DeleteMsgPort(keyboardMessagePort); + keyboardMessagePort = NULL; + } +} + +int main(void) { + setupKeyboard(); + + while (!keyboardPressed) {} + + teardownKeyboard(); + + return 0; +} diff --git a/main.c b/main.c index 1759cea..0e80fbe 100644 --- a/main.c +++ b/main.c @@ -1,13 +1,23 @@ #include +#include +#include #include #include + #include +#include +#include +#include + +#include #include #include #include +#include + #include #include "system/blitter.h" @@ -84,6 +94,38 @@ void renderTopaz(void) { } } + +void renderMostlyTopaz(void) { + int plane; + + uint16_t bltcon0, 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.bltcon1 = 0; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltapt = MaskBitplane + (30 * TOPAZ_WIDTH_BYTES); + custom.bltbpt = bltbpt + (30 * TOPAZ_WIDTH_BYTES); + custom.bltcpt = 30 * screenDefinition.byteWidth + activeScreenBufferDetails.planes[plane] + 8; + custom.bltdpt = 30 * screenDefinition.byteWidth + activeScreenBufferDetails.planes[plane] + 8; + custom.bltamod = 0; + custom.bltbmod = 0; + custom.bltcmod = bltcmod; + custom.bltdmod = bltcmod; + custom.bltsize = BLTSIZE(TOPAZ_WIDTH_WORDS, 196); + + bltbpt += TOPAZ_WIDTH_BYTES * 256; + + WaitBlit(); + } +} + #define COPPERLIST_SIZE (10000) uint16_t *copperlist; @@ -124,7 +166,6 @@ void buildCopperlist(void) { ); } } else { - printf("Skipping render\n"); currentCopperlist = setUpEmptySpritesInCopperlist(currentCopperlist); } @@ -150,7 +191,7 @@ void buildCopperlist(void) { } } } else { - printf("Skipping render\n"); + //printf("Skipping render\n"); } for (i = 3; i < 8; ++i) { @@ -172,20 +213,86 @@ void buildCopperlist(void) { endCopperlist(currentCopperlist); } +uint16_t renderPartialAreas[BUN_COUNT][5]; + +void calculateTopazRenderPartialAreas( + uint16_t redrawRanges[BUN_COUNT][4] +) { + int topazX; + uint16_t i, width, height, screenX; + + for (i = 0; i < BUN_COUNT; ++i) { + renderPartialAreas[i][0] = 0; + + if (redrawRanges[i][2] - redrawRanges[i][0] < TOPAZ_WIDTH_PIXELS) { + if ( + (redrawRanges[i][2] > 64 && redrawRanges[i][0] < (64 + TOPAZ_WIDTH_PIXELS)) || + (redrawRanges[i][0] < (64 + TOPAZ_WIDTH_PIXELS) && redrawRanges[i][2] > 64) + ) { + width = redrawRanges[i][2] - redrawRanges[i][0] + 16; + height = redrawRanges[i][3] - redrawRanges[i][1]; + topazX = redrawRanges[i][0] - 64; + screenX = redrawRanges[i][0]; + + if (topazX < 0) { + //printf("Too far left, adjusting...\n"); + topazX += 16; + screenX += 16; + width -= 16; + } + + if (topazX + width > 64 + TOPAZ_WIDTH_PIXELS) { + //printf("Too far right, adjusting...\n"); + width -= 16; + } + + renderPartialAreas[i][0] = width; + renderPartialAreas[i][1] = height; + renderPartialAreas[i][2] = topazX; + renderPartialAreas[i][3] = screenX; + renderPartialAreas[i][4] = redrawRanges[i][1]; + } + } + } +} + +void calculateTopazRenderPartialBlitterSettings() { + uint16_t bltapt, bltcpt, bltamod, bltcmod, bltsize; + int i; + + for (i = 0; i < BUN_COUNT; ++i) { + if (renderPartialAreas[i][0] == 0) continue; + bltapt = renderPartialAreas[i][4] * TOPAZ_WIDTH_BYTES + (renderPartialAreas[i][2] >> 4) * 2; + bltcpt = renderPartialAreas[i][4] * screenDefinition.byteWidth + (renderPartialAreas[i][3] >> 4) * 2; + + printf("%d, %d\n", screenDefinition.byteWidth, renderPartialAreas[i][0]); + + bltamod = TOPAZ_WIDTH_BYTES - (renderPartialAreas[i][0] >> 4) * 2; + bltcmod = screenDefinition.byteWidth - (renderPartialAreas[i][0] >> 4) * 2; + + bltsize = BLTSIZE((renderPartialAreas[i][0] >> 4), renderPartialAreas[i][1]); + + renderPartialAreas[i][0] = bltapt; + renderPartialAreas[i][1] = bltcpt; + renderPartialAreas[i][2] = bltamod; + renderPartialAreas[i][3] = bltcmod; + renderPartialAreas[i][4] = bltsize; + } +} + void renderTopazPartials( uint16_t redrawRanges[BUN_COUNT][4] ) { - int plane, i, topazX; + int plane, i, topazX, screenX; uint16_t bltcon0; uint16_t bltamod, bltbmod, bltcmod, bltdmod; uint16_t width, height, bltsize; - uint8_t *bltapt, *bltbpt, *bltcpt, *bltdpt; + uint32_t bltapt, bltbpt, bltcpt, bltdpt; bltcon0 = 0xca + (1 << 8) + (1 << 9) + (1 << 10) + (1 << 11); - bltcmod = screenDefinition.byteWidth; - bltbpt = TopazBitplanes; + WaitTOF(); for (i = 0; i < BUN_COUNT; ++i) { if (redrawRanges[i][2] - redrawRanges[i][0] < TOPAZ_WIDTH_PIXELS) { @@ -193,20 +300,26 @@ void renderTopazPartials( (redrawRanges[i][2] > 64 && redrawRanges[i][0] < (64 + TOPAZ_WIDTH_PIXELS)) || (redrawRanges[i][0] < (64 + TOPAZ_WIDTH_PIXELS) && redrawRanges[i][2] > 64) ) { - width = redrawRanges[i][2] - redrawRanges[i][0]; + width = redrawRanges[i][2] - redrawRanges[i][0] + 16; height = redrawRanges[i][3] - redrawRanges[i][1]; topazX = redrawRanges[i][0] - 64; + screenX = redrawRanges[i][0]; if (topazX < 0) { + //printf("Too far left, adjusting...\n"); topazX += 16; + screenX += 16; + width -= 16; + } + + if (topazX + width > 64 + TOPAZ_WIDTH_PIXELS) { + //printf("Too far right, adjusting...\n"); width -= 16; } - // always round up to the next word - width += 16; bltapt = redrawRanges[i][1] * TOPAZ_WIDTH_BYTES + (topazX >> 4) * 2; bltbpt = bltapt; - bltcpt = redrawRanges[i][1] * screenDefinition.byteWidth + (redrawRanges[i][0] >> 4) * 2; + bltcpt = redrawRanges[i][1] * screenDefinition.byteWidth + (screenX >> 4) * 2; bltdpt = bltcpt; bltamod = TOPAZ_WIDTH_BYTES - (width >> 4) * 2; @@ -215,6 +328,7 @@ void renderTopazPartials( bltdmod = bltcmod; bltsize = BLTSIZE((width >> 4), height); + /* printf( "Coords: %d, %d -> %d, %d\n", @@ -227,10 +341,18 @@ void renderTopazPartials( printf("topazX: %d\n", topazX); printf("width: %d\n", width); + printf("MaskBitplane: %d\n", MaskBitplane); + printf("TopazBitplanes: %d\n", TopazBitplanes); + printf("ActiveScreenBuffer Plane 0: %d\n", activeScreenBufferDetails.planes[0]); + printf("BLTAPT: %d\n", bltapt); + printf("BLTAPT src: %d\n", bltapt + (uint32_t)MaskBitplane); printf("BLTBPT: %d\n", bltbpt); + printf("BLTBPT src: %d\n", bltbpt + (uint32_t)TopazBitplanes); printf("BLTCPT: %d\n", bltcpt); + printf("BLTCPT src: %d\n", bltcpt + (uint32_t)activeScreenBufferDetails.planes[0] + 8); printf("BLTDPT: %d\n", bltdpt); + printf("BLTDPT src: %d\n", bltdpt + (uint32_t)activeScreenBufferDetails.planes[0] + 8); printf("BLTAMOD: %d\n", bltamod); printf("BLTBMOD: %d\n", bltbmod); @@ -238,39 +360,151 @@ void renderTopazPartials( printf("BLTDMOD: %d\n", bltdmod); printf("BLTSIZE: %d, %d\n", (width >> 4), height); +*/ - /* - for (plane = 0; plane < 3; ++plane) { + bltapt += (uint32_t)MaskBitplane; + bltbpt += (uint32_t)TopazBitplanes; + + for (plane = 0; plane < 2; ++plane) { custom.bltcon0 = bltcon0; custom.bltcon1 = 0; custom.bltafwm = 0xffff; custom.bltalwm = 0xffff; - custom.bltapt = MaskBitplane; - custom.bltbpt = bltbpt; - custom.bltcpt = activeScreenBufferDetails.planes[plane] + 8; - custom.bltdpt = activeScreenBufferDetails.planes[plane] + 8; - custom.bltamod = 0; - custom.bltbmod = 0; + custom.bltapt = bltapt; + custom.bltbpt = bltbpt + (plane * TOPAZ_WIDTH_BYTES * 256); + custom.bltcpt = bltcpt + activeScreenBufferDetails.planes[plane]; + custom.bltdpt = bltdpt + activeScreenBufferDetails.planes[plane]; + custom.bltamod = bltamod; + custom.bltbmod = bltbmod; custom.bltcmod = bltcmod; - custom.bltdmod = bltcmod; - custom.bltsize = BLTSIZE(TOPAZ_WIDTH_WORDS, 256); - - bltbpt += TOPAZ_WIDTH_BYTES * 256; + custom.bltdmod = bltdmod; + custom.bltsize = bltsize; WaitBlit(); } - */ + + break; } } } } +static struct MsgPort *keyboardMessagePort = NULL; +static struct IOStdReq *keyboardIO = NULL; +static struct Interrupt keyboardInterrupt; + +extern far ULONG keyboardPressed; + +extern struct InputEvent * __asm stupidKeyboardHandler( + register __a0 struct InputEvent *input, + register __a1 APTR id +); + +void setupKeyboard(void) { + if (keyboardMessagePort = CreatePort(NULL, NULL)) { + if (keyboardIO = (struct IOStdReq *)CreateExtIO( + keyboardMessagePort, + sizeof(struct IOStdReq) + )) { + // OpenDevice returns 0 if successful + if (!OpenDevice( + "input.device", + 0, + (struct IORequest *)keyboardIO, + 0 + )) { + keyboardInterrupt.is_Node.ln_Type = NT_INTERRUPT; + keyboardInterrupt.is_Node.ln_Pri = 100; + keyboardInterrupt.is_Node.ln_Name = (STRPTR)"cool bun"; + keyboardInterrupt.is_Code = (void (*)())&stupidKeyboardHandler; + + keyboardIO->io_Data = (void *)&keyboardInterrupt; + keyboardIO->io_Command = IND_ADDHANDLER; + + DoIO((struct IORequest *)keyboardIO); + } + } + } +} + +void teardownKeyboard(void) { + if (keyboardIO) { + keyboardIO->io_Data = (void *)&keyboardInterrupt; + keyboardIO->io_Command = IND_REMHANDLER; + DoIO((struct IORequest *)keyboardIO); + CloseDevice((struct IORequest *)keyboardIO); + DeleteIORequest((struct IORequest *)keyboardIO); + keyboardIO = NULL; + } + + if (keyboardMessagePort) { + DeleteMsgPort(keyboardMessagePort); + keyboardMessagePort = NULL; + } +} + int main(void) { int i; struct BunRenderer bunRenderer; uint16_t redrawRanges[BUN_COUNT][4]; + /* + + allocateDoubleBufferedScreenMemory( + &screenDefinition, + &activeScreenBufferDetails, + SCREEN_WIDTH, + SCREEN_HEIGHT, + 3 + ); + + setupBunRenderer( + &bunRenderer, + &screenDefinition, + &activeScreenBufferDetails + ); + + calculateNeededRedrawRanges(i, redrawRanges); + calculateTopazRenderPartialAreas(redrawRanges); + + printf("********\n"); + + for (i = 0; i < BUN_COUNT; ++i) { + if (renderPartialAreas[i][0] == 0) continue; + + printf( + "%d, %d, %d, %d, %d\n", + renderPartialAreas[i][0], + renderPartialAreas[i][1], + renderPartialAreas[i][2], + renderPartialAreas[i][3], + renderPartialAreas[i][4] + ); + } + + calculateTopazRenderPartialBlitterSettings(); + + printf("********\n"); + + for (i = 0; i < BUN_COUNT; ++i) { + if (renderPartialAreas[i][0] == 0) continue; + + printf( + "%d, %d, %d, %d, %x\n", + renderPartialAreas[i][0], + renderPartialAreas[i][1], + renderPartialAreas[i][2], + renderPartialAreas[i][3], + renderPartialAreas[i][4] + ); + } + + teardownScreen(&screenDefinition); + + return 0; +*/ + printf("\nCool bun blitter, copper, and sprite demo by John Bintz\n"); printf("\n"); printf("This is my first real go at writing graphics code for the Amiga.\n"); @@ -310,6 +544,7 @@ int main(void) { buildCopperlist(); + /* copperlist debugging for (i = 0; i < 20; ++i) { @@ -322,11 +557,7 @@ int main(void) { ); } */ - - calculateNeededRedrawRanges(0, redrawRanges); - renderTopazPartials(redrawRanges); - - /* + setupKeyboard(); takeOverSystem(); setCopperlist(copperlist); @@ -337,16 +568,31 @@ int main(void) { renderTopaz(); swapCurrentScreenBuffer(&screenDefinition, &activeScreenBufferDetails); + updateDisplayInCopperList( + &screenDefinition, + &activeScreenBufferDetails, + copperlistBitplanePointers + ); + i = 0; + while (1) { + WaitTOF(); - while (0) { swapCurrentScreenBuffer(&screenDefinition, &activeScreenBufferDetails); clearCurrentBuns(&bunRenderer); renderBunFrame(i, &bunRenderer); + /* + calculateNeededRedrawRanges(i, redrawRanges); + renderTopazPartials(redrawRanges); + */ + renderMostlyTopaz(); + + //WaitTOF(); + updateDisplayInCopperList( &screenDefinition, @@ -354,16 +600,21 @@ int main(void) { copperlistBitplanePointers ); - WaitBOF(250); + //WaitBOF(100); + //WaitTOF(); + + if (keyboardPressed) { + i++; + } if ((ciaa.ciapra >> 6) != 3) break; i++; - //i %= FRAMES_FOR_SCREEN; + i %= FRAMES_FOR_SCREEN; } giveBackSystem(); - */ + teardownKeyboard(); teardownScreen(&screenDefinition); diff --git a/screen.c b/screen.c index 1ca9108..74eabcb 100644 --- a/screen.c +++ b/screen.c @@ -69,6 +69,10 @@ void swapCurrentScreenBuffer( struct ScreenDefinition *screenDefinition, struct ActiveScreenBufferDetails *currentScreen ) { - setActiveScreenBuffer(screenDefinition, currentScreen, 1 - currentScreen->currentBuffer); + setActiveScreenBuffer( + screenDefinition, + currentScreen, + 1 - currentScreen->currentBuffer + ); } diff --git a/system/system.s b/system/system.s index 360f676..5bbffe1 100644 --- a/system/system.s +++ b/system/system.s @@ -9,6 +9,9 @@ XDEF _endCopperlist XDEF _myWaitBlit XDEF _WaitBOF + XDEF _stupidKeyboardHandler + + XDEF _keyboardPressed XREF _custom @@ -29,6 +32,8 @@ FUNC_CNT SET FUNC_CNT-6 INCLUDE "hardware/custom.i" INCLUDE "hardware/dmabits.i" INCLUDE "hardware/intbits.i" + INCLUDE "exec/io.i" + INCLUDE "devices/inputevent.i" ; @param 1 Pointer to null terminated name of library ; @param 2 Minimum version of library, 0 for any @@ -73,6 +78,52 @@ ActiveScreenBufferDetails_planes EQU SOFFSET SOFFSET SET SOFFSET+(8*4) LABEL ActiveScreenBufferDetails_SIZEOF +; @see https://amigadev.elowar.com/read/ADCD_2.1/Devices_Manual_guide/node019A.html +; @register A0 struct InputEvent * +; @register A1 extra data about the event +; @output D0 The value of A0 +_stupidKeyboardHandler: + ; @stack [RA,A0,current node] + MOVE.L A0,-(SP) + MOVE.L #0,-(SP) + +_stupidKeyboardHandler_CheckLoop: + CMP.B #IECLASS_RAWKEY,ie_Class(A0) + BNE.S _stupidKeyboardHandler_NextEvent + + MOVE.W ie_Code(A0),D0 + AND.W #IECODE_UP_PREFIX,D0 + SEQ _keyboardPressed + + ; if next_event: + ; do the stack swap thing below + ; else: + ; change the A0 in the stack above it + TST.L (SP) + BNE.S _stupidKeyboardHandler_hasLastEvent + + MOVE.L (A0),4(SP) + BRA.S _stupidKeyboardHandler_NextEvent + +_stupidKeyboardHandler_hasLastEvent: + ; put the next event in the first pointer of the + ; last event + MOVE.L A1,-(SP) + MOVE.L 4(SP),A1 + MOVE.L (A0),(A1) + MOVE.L (SP)+,A1 + +_stupidKeyboardHandler_NextEvent: + ; next event is in first long of struct + MOVE.L (A0),D0 + ; store current node in stack + MOVE.L A0,(SP) + + MOVE.L D0,A0 + BNE.S _stupidKeyboardHandler_CheckLoop + MOVE.L (SP)+,D0 + MOVE.L (SP)+,D0 + RTS M68K_LEVEL3_INTERRUPT_AUTOVECTOR EQU $6C _takeOverSystem: @@ -438,5 +489,8 @@ VBIPtr dc.l 0 CNOP 0,4 GraphicsLibrary GRAPHICSNAME + CNOP 0,4 +_keyboardPressed dc.l 0 + SECTION Sprite,Data_C EmptySprite dc.w 0,0