diff --git a/devices/Makefile b/devices/Makefile index 973fbe8..b937103 100644 --- a/devices/Makefile +++ b/devices/Makefile @@ -1,15 +1,17 @@ -CC=vc +aos68k -CC13=vc +kick13 +CC=vc +kick13 # Note: VBCC comes with linker library replacements, that should be used. # If not, printf() stops working in the expected way, because it is part # of amiga.lib CFLAGS=-c99 -I$(NDK_INC) -all: timer +all: timer audio clean: - rm -f timer + rm -f timer audio timer: timer.c - $(CC13) $(CFLAGS) timer.c -o timer -lamiga + $(CC) $(CFLAGS) $^ -o $@ -lamiga + +audio: audio.c + $(CC) $(CFLAGS) $^ -o $@ -lamiga -lauto diff --git a/devices/audio.c b/devices/audio.c new file mode 100644 index 0000000..48e9fba --- /dev/null +++ b/devices/audio.c @@ -0,0 +1,78 @@ +/* audio.c + This is a cleaned up version of the example program in Commodore RKM (Devices) + */ +#include +#include +#include +#include +#include + +#include +#include +#include + +#define CLOCK_NTSC (3579545) +#define CLOCK_PAL (3546895) +#define SAMPLE_BYTES (2) +#define DURATION_SECS (3) +#define FREQUENCY (440) +#define SAMPLE_CYCLES (1) +#define VOLUME (64) + +extern struct GfxBase *GfxBase; +UBYTE whichannel[] = {1, 2, 4, 8}; + +int main(int argc, char **argv) +{ + struct IOAudio *AudioIO; + struct MsgPort *AudioMP; + struct Message *AudioMSG; + BYTE *waveptr; + ULONG error; + LONG clock; + + clock = (GfxBase->DisplayFlags & PAL) ? CLOCK_PAL : CLOCK_NTSC; + + AudioIO = (struct IOAudio *) AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR); + if (AudioIO) { + puts("IO block created..."); + AudioMP = CreatePort(0, 0); + if (AudioMP) { + puts("Port created..."); + AudioIO->ioa_Request.io_Message.mn_ReplyPort = AudioMP; + AudioIO->ioa_Request.io_Message.mn_Node.ln_Pri = 0; + AudioIO->ioa_Request.io_Command = ADCMD_ALLOCATE; + AudioIO->ioa_Request.io_Flags = ADIOF_NOWAIT; + AudioIO->ioa_AllocKey = 0; + AudioIO->ioa_Data = whichannel; + AudioIO->ioa_Length = sizeof(whichannel); + puts("I/O block initialized for channel allocation..."); + error = OpenDevice(AUDIONAME, 0L, (struct IORequest *) AudioIO, 0L); + if (!error) { + printf("'%s' opened, channel allocated...\n", AUDIONAME); + waveptr = (BYTE *) AllocMem(SAMPLE_BYTES, MEMF_CHIP|MEMF_PUBLIC); + waveptr[0] = 127; + waveptr[1] = -127; + puts("Wave data ready..."); + AudioIO->ioa_Request.io_Message.mn_ReplyPort = AudioMP; + AudioIO->ioa_Request.io_Command = CMD_WRITE; + AudioIO->ioa_Request.io_Flags = ADIOF_PERVOL; + AudioIO->ioa_Data = (BYTE *) waveptr; + AudioIO->ioa_Length = SAMPLE_BYTES; + AudioIO->ioa_Period = clock * SAMPLE_CYCLES / (SAMPLE_BYTES * FREQUENCY); + AudioIO->ioa_Volume = VOLUME; + AudioIO->ioa_Cycles = FREQUENCY * DURATION_SECS / SAMPLE_CYCLES; + puts("I/O block initialized to play tone..."); + puts("Starting tone now..."); + BeginIO((struct IORequest *) AudioIO); + WaitPort(AudioMP); + AudioMSG = GetMsg(AudioMP); + if (waveptr) FreeMem(waveptr, SAMPLE_BYTES); + CloseDevice((struct IORequest *) AudioIO); + } + DeletePort(AudioMP); + } + FreeMem(AudioIO, sizeof(struct IOAudio)); + } + return 0; +} diff --git a/requesters/Makefile b/requesters/Makefile index 3d6870e..dff31c4 100644 --- a/requesters/Makefile +++ b/requesters/Makefile @@ -7,12 +7,17 @@ all: main clean: rm -f *.o main -main: main.o filereq.o dos13.o file_list.o +main: main.o filereq.o dos13.o file_list.o dos_compat.o $(CC) $(CFLAGS) $^ -lamiga -lauto -o $@ -check: file_list_test +check: file_list_test dos_compat_test file_list_test: file_list.c file_list_test.c chibi.c gcc $^ -o $@ ./file_list_test + + +dos_compat_test: dos_compat.c dos_compat_test.c chibi.c + gcc $^ -o $@ + ./dos_compat_test diff --git a/requesters/filereq.c b/requesters/filereq.c index 353824f..2004811 100644 --- a/requesters/filereq.c +++ b/requesters/filereq.c @@ -231,6 +231,9 @@ static struct RastPort filelist_rastport; static UWORD font_baseline, font_height; +#define DIR_BUFFER_SIZE 300 +static char dir_buffer[DIR_BUFFER_SIZE]; + static void close_requester() { if (req_opened) { @@ -477,8 +480,25 @@ static void handle_events() update_string_gadgets(entry); } else if (entry != NULL && is_doubleclick) { printf("double click on: %s\n", entry->name); - if (entry->file_type == FILETYPE_VOLUME || entry->file_type == FILETYPE_DIR) { - reload_file_list(entry->name); + if (entry->file_type == FILETYPE_VOLUME) { + strncpy(dir_buffer, entry->name, DIR_BUFFER_SIZE); + reload_file_list(dir_buffer); + } else if (entry->file_type == FILETYPE_DIR) { + printf("DIR_BUFFER was: '%s'\n", dir_buffer); + int dblen = strlen(dir_buffer); + // We have to implement the DOS functions AddPart()/PathPart()/FilePart() + // ourselves on 1.x, because they only exist after 2.x + // TODO: maybe put path operations in their own module so + // unit testing becomes possible + // append directory separator to path if not a volume + if (dir_buffer[dblen - 1] != ':' && dblen < DIR_BUFFER_SIZE) { + dir_buffer[dblen] = '/'; + dir_buffer[dblen + 1] = '\0'; + dblen++; + } + strncat(dir_buffer, entry->name, DIR_BUFFER_SIZE - dblen); + printf("DIR_BUFFER is NOW: '%s'\n", dir_buffer); + reload_file_list(dir_buffer); } } } @@ -497,6 +517,7 @@ static void handle_events() done = TRUE; break; case REQ_DRIVES_BUTTON_ID: + dir_buffer[0] = '\0'; reload_file_list(NULL); break; case REQ_PARENT_BUTTON_ID: @@ -635,6 +656,7 @@ static void open_request_window(struct Window *window) filelist_rastport.BitMap = &filelist_bitmap; if (req_opened = Request(&requester, req_window)) { + dir_buffer[0] = '\0'; reload_file_list(NULL); handle_events(); free_file_list(current_files); diff --git a/scrolling_tricks/Makefile b/scrolling_tricks/Makefile new file mode 100644 index 0000000..2c7ffad --- /dev/null +++ b/scrolling_tricks/Makefile @@ -0,0 +1,20 @@ +ASM=vasmm68k_mot +ASM_FLAGS = -Fhunk -devpac +.SUFFIXES = .o .asm .c + +CC=vc +kick13 +CFLAGS=-c99 -I$(NDK_INC) -DDEBUG + +all: main + +clean: + rm -f main hardware.o cop.o main.o + +cop.o: cop.asm + $(ASM) $(ASM_FLAGS) -o $@ $< + +.c.o: + $(CC) $(CFLAGS) -c -o $@ $^ + +main: hardware.o cop.o main.o + $(CC) -o $@ $^ -lamiga -lauto diff --git a/scrolling_tricks/README.md b/scrolling_tricks/README.md new file mode 100644 index 0000000..2d69f73 --- /dev/null +++ b/scrolling_tricks/README.md @@ -0,0 +1,6 @@ +# Scrolling Tricks + +This is a project to rework the Aminet Scrolling Tricks into a +version that works on all Amiga OS releases from 1.3 and has +higher reuse. The ScrollingTricks tutorial has tremendous learning +value, but requires at least AmigaOS3.0 to run diff --git a/scrolling_tricks/blocks/demoblocks.raw b/scrolling_tricks/blocks/demoblocks.raw new file mode 100644 index 0000000..6c9c0a1 Binary files /dev/null and b/scrolling_tricks/blocks/demoblocks.raw differ diff --git a/scrolling_tricks/blocks/raceblocks.raw b/scrolling_tricks/blocks/raceblocks.raw new file mode 100644 index 0000000..2c48597 Binary files /dev/null and b/scrolling_tricks/blocks/raceblocks.raw differ diff --git a/scrolling_tricks/cop.asm b/scrolling_tricks/cop.asm new file mode 100644 index 0000000..a1085e7 --- /dev/null +++ b/scrolling_tricks/cop.asm @@ -0,0 +1,226 @@ + + SECTION copperlist,DATA,CHIP + + XDEF _CopperList + XDEF _CopFETCHMODE + XDEF _CopBPLCON0 + XDEF _CopBPLCON1 + XDEF _CopBPLCON3 + XDEF _CopBPLMODA + XDEF _CopBPLMODB + XDEF _CopDIWSTART + XDEF _CopDIWSTOP + XDEF _CopDDFSTART + XDEF _CopDDFSTOP + XDEF _CopPLANE1H + XDEF _CopPLANE1L + XDEF _CopPLANE2H + XDEF _CopPLANE2L + XDEF _CopPLANE3H + XDEF _CopPLANE3L + XDEF _CopPLANE4H + XDEF _CopPLANE4L + XDEF _CopPLANE5H + XDEF _CopPLANE5L + XDEF _CopPLANE6H + XDEF _CopPLANE6L + XDEF _CopPLANE7H + XDEF _CopPLANE7L + XDEF _CopPLANE8H + XDEF _CopPLANE8L + XDEF _CopSKY + +_CopperList: + dc.w $180,0 + +_CopFETCHMODE: + dc.w $1FC,0 + +_CopBPLCON0: + dc.w $100,0 + +_CopBPLCON1: + dc.w $102,0 + +_CopBPLCON3: + dc.w $106,0 + +_CopBPLMODA: + dc.w $108,0 + +_CopBPLMODB: + dc.w $10A,0 + +_CopDIWSTART: + dc.w $8e,0 + +_CopDIWSTOP: + dc.w $90,0 + +_CopDDFSTART: + dc.w $92,0 + +_CopDDFSTOP: + dc.w $94,0 + +_CopPLANE1H: + dc.w $e0,0 + +_CopPLANE1L: + dc.w $e2,0 + +_CopPLANE2H: + dc.w $e4,0 + +_CopPLANE2L: + dc.w $e6,0 + +_CopPLANE3H: + dc.w $e8,0 + +_CopPLANE3L: + dc.w $ea,0 + +_CopPLANE4H: + dc.w $ec,0 + +_CopPLANE4L: + dc.w $ee,0 + +_CopPLANE5H: + dc.w $f0,0 + +_CopPLANE5L: + dc.w $f2,0 + +_CopPLANE6H: + dc.w $f4,0 + +_CopPLANE6L: + dc.w $f6,0 + +_CopPLANE7H: + dc.w $f8,0 + +_CopPLANE7L: + dc.w $fa,0 + +_CopPLANE8H: + dc.w $fc,0 + +_CopPLANE8L: + dc.w $fe,0 + +_CopSKY: + dc.w -1,-2 + dc.w $180,$FFF + + dc.w $390f,-2 + dc.w $180,$EEF + dc.w $3A0f,-2 + dc.w $180,$FFF + dc.w $3B0f,-2 + dc.w $180,$EEF + + dc.w $490f,-2 + dc.w $180,$DDF + dc.w $4a0f,-2 + dc.w $180,$EEF + dc.w $4b0f,-2 + dc.w $180,$DDF + + dc.w $590f,-2 + dc.w $180,$CCF + dc.w $5A0f,-2 + dc.w $180,$DDF + dc.w $5B0f,-2 + dc.w $180,$CCF + + dc.w $690f,-2 + dc.w $180,$BBF + dc.w $6A0f,-2 + dc.w $180,$CCF + dc.w $6B0f,-2 + dc.w $180,$BBF + + dc.w $790f,-2 + dc.w $180,$AAF + dc.w $7A0f,-2 + dc.w $180,$BBF + dc.w $7B0f,-2 + dc.w $180,$AAF + + dc.w $890f,-2 + dc.w $180,$99E + dc.w $8A0f,-2 + dc.w $180,$AAF + dc.w $8B0f,-2 + dc.w $180,$99E + + dc.w $990f,-2 + dc.w $180,$88E + dc.w $9A0f,-2 + dc.w $180,$99E + dc.w $9B0f,-2 + dc.w $180,$88E + + dc.w $A90f,-2 + dc.w $180,$77E + dc.w $AA0f,-2 + dc.w $180,$88E + dc.w $AB0f,-2 + dc.w $180,$77E + + dc.w $B90f,-2 + dc.w $180,$66E + dc.w $BA0f,-2 + dc.w $180,$77E + dc.w $BB0f,-2 + dc.w $180,$66E + + dc.w $C90f,-2 + dc.w $180,$55D + dc.w $CA0f,-2 + dc.w $180,$66E + dc.w $CB0f,-2 + dc.w $180,$55D + + dc.w $D90f,-2 + dc.w $180,$44D + dc.w $DA0f,-2 + dc.w $180,$55D + dc.w $DB0f,-2 + dc.w $180,$44D + + dc.w $E90f,-2 + dc.w $180,$33D + dc.w $EA0f,-2 + dc.w $180,$44D + dc.w $EB0f,-2 + dc.w $180,$33D + + dc.w $F90f,-2 + dc.w $180,$22C + dc.w $FA0f,-2 + dc.w $180,$33D + dc.w $FB0f,-2 + dc.w $180,$22C + + dc.w $FFDF,-2 + dc.w $090F,-2 + dc.w $180,$11C + dc.w $0A0F,-2 + dc.w $180,$22C + dc.w $0B0F,-2 + dc.w $180,$11C + + dc.w $190f,-2 + dc.w $180,$00B + dc.w $1A0f,-2 + dc.w $180,$11C + dc.w $1B0f,-2 + dc.w $180,$00B + + dc.w -1,-2 + END + diff --git a/scrolling_tricks/cop.h b/scrolling_tricks/cop.h new file mode 100644 index 0000000..4b392b7 --- /dev/null +++ b/scrolling_tricks/cop.h @@ -0,0 +1,29 @@ +extern WORD CopperList[]; +extern WORD CopFETCHMODE[]; +extern WORD CopBPLCON0[]; +extern WORD CopBPLCON1[]; +extern WORD CopBPLCON3[]; +extern WORD CopBPLMODA[]; +extern WORD CopBPLMODB[]; +extern WORD CopDIWSTART[]; +extern WORD CopDIWSTOP[]; +extern WORD CopDDFSTART[]; +extern WORD CopDDFSTOP[]; +extern WORD CopPLANE1H[]; +extern WORD CopPLANE1L[]; +extern WORD CopPLANE2H[]; +extern WORD CopPLANE2L[]; +extern WORD CopPLANE3H[]; +extern WORD CopPLANE3L[]; +extern WORD CopPLANE4H[]; +extern WORD CopPLANE4L[]; +extern WORD CopPLANE5H[]; +extern WORD CopPLANE5L[]; +extern WORD CopPLANE6H[]; +extern WORD CopPLANE6L[]; +extern WORD CopPLANE7H[]; +extern WORD CopPLANE7L[]; +extern WORD CopPLANE8H[]; +extern WORD CopPLANE8L[]; +extern WORD CopSKY[]; + diff --git a/scrolling_tricks/hardware.c b/scrolling_tricks/hardware.c new file mode 100644 index 0000000..cc0d6ce --- /dev/null +++ b/scrolling_tricks/hardware.c @@ -0,0 +1,160 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include "hardware.h" + +static UWORD old_dmacon; +static UWORD old_intena; +static UWORD old_adkcon; +static UWORD old_intreq; + +static struct MsgPort *inputmp; +static struct IOStdReq *inputreq; +static struct Interrupt inputhandler; +static BOOL inputdeviceok; + +static struct View *oldview; +static struct Window *old_processwinptr; +static struct Process *thisprocess; + +extern struct IntuitionBase *IntuitionBase; +extern struct GfxBase *GfxBase; + +static LONG NullInputHandler(void) +{ + // kills all input + return 0; +} + +void KillSystem(void) +{ + thisprocess = (struct Process *)FindTask(0); + + // safe actual view and install null view + + oldview = GfxBase->ActiView; + LoadView(0); + WaitTOF(); + WaitTOF(); + + // install NullInputHandler to kill all input events + if ((inputmp = CreateMsgPort())) { + if ((inputreq = CreateIORequest(inputmp,sizeof(*inputreq)))) { + if (OpenDevice("input.device",0,(struct IORequest *)inputreq,0) == 0) { + inputdeviceok = TRUE; + inputhandler.is_Node.ln_Type = NT_INTERRUPT; + inputhandler.is_Node.ln_Pri = 127; + inputhandler.is_Data = 0; + inputhandler.is_Code = (APTR)NullInputHandler; + inputreq->io_Command = IND_ADDHANDLER; + inputreq->io_Data = &inputhandler; + DoIO((struct IORequest *)inputreq); + } + } + } + + // disable requesters for our process + old_processwinptr = thisprocess->pr_WindowPtr; + thisprocess->pr_WindowPtr = (APTR)-1; + + // lock blitter + OwnBlitter(); + WaitBlit(); + + // no multitasking/interrupts + Disable(); + + // save important custom registers + old_dmacon = custom->dmaconr | 0x8000; + old_intena = custom->intenar | 0x8000; + old_adkcon = custom->adkconr | 0x8000; + old_intreq = custom->intreqr | 0x8000; +} + +void ActivateSystem(void) +{ + // reset important custom registers + custom->dmacon = 0x7FFF; + custom->intena = 0x7FFF; + custom->adkcon = 0x7FFF; + custom->intreq = 0x7FFF; + + custom->dmacon = old_dmacon; + custom->intena = old_intena; + custom->adkcon = old_adkcon; + custom->intreq = old_intreq; + + // enable multitasking/interrupts + Enable(); + + // unlock blitter + WaitBlit(); + DisownBlitter(); + + // enable requesters for our process + thisprocess->pr_WindowPtr = old_processwinptr; + + // remove null inputhandler + if (inputdeviceok) + { + inputreq->io_Command = IND_REMHANDLER; + inputreq->io_Data = &inputhandler; + DoIO((struct IORequest *)inputreq); + CloseDevice((struct IORequest *)inputreq); + } + + if (inputreq) DeleteIORequest(inputreq); + if (inputmp) DeleteMsgPort(inputmp); + + // reset old view + LoadView(oldview); + WaitTOF(); + WaitTOF(); +} + +void WaitVBL(void) +{ + UBYTE b; + + b = *(UBYTE *)0xbfe801; + while(*(UBYTE *)0xbfe801 == b) ; +} + +void WaitVBeam(ULONG line) +{ + ULONG vpos; + + line *= 0x100; + + do { + vpos = *(ULONG *)0xdff004; + } while ((vpos & 0x1FF00) != line); +} + +void HardWaitBlit(void) +{ + if (custom->dmaconr & DMAF_BLTDONE) ; + while (custom->dmaconr & DMAF_BLTDONE) ; +} + +void HardWaitLMB(void) +{ + while (((*(UBYTE *)0xbfe001) & 64) != 0) ; + while (((*(UBYTE *)0xbfe001) & 64) == 0) ; +} + +BOOL JoyLeft(void) { return (custom->joy1dat & 512) ? TRUE : FALSE; } +BOOL JoyRight(void) { return (custom->joy1dat & 2) ? TRUE : FALSE; } +BOOL JoyFire(void) { return ((*(UBYTE *)0xbfe001) & 128) ? FALSE : TRUE; } +BOOL LMBDown(void) { return ((*(UBYTE *)0xbfe001) & 64) ? FALSE : TRUE; } diff --git a/scrolling_tricks/hardware.h b/scrolling_tricks/hardware.h new file mode 100644 index 0000000..05a9783 --- /dev/null +++ b/scrolling_tricks/hardware.h @@ -0,0 +1,27 @@ +#ifdef custom +#undef custom +#endif + +#define mycustombase ((struct Custom *)0xdff000) +#define custom mycustombase + +#define BPL0_USEBPLCON3_F 0x1 +#define BPL0_COLOR_F 0x200 +#define BPL0_BPU0_F 0x1000 +#define BPL0_BPU3_F 0x10 +#define BPL0_BPUMASK 0x7000 + +void KillSystem(void); +void ActivateSystem(void); +void WaitVBL(void); +void WaitVBeam(ULONG line); +void HardWaitBlit(void); +void HardWaitLMB(void); + +BOOL JoyLeft(void); +BOOL JoyRight(void); +BOOL JoyUp(void); +BOOL JoyDown(void); +BOOL JoyFire(void); +BOOL LMBDown(void); + diff --git a/scrolling_tricks/main.c b/scrolling_tricks/main.c new file mode 100644 index 0000000..1fe8d8d --- /dev/null +++ b/scrolling_tricks/main.c @@ -0,0 +1,543 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "hardware.h" +#include "cop.h" +#include "map.h" + + +#define ARG_TEMPLATE "SPEED/S,NTSC/S,HOW/S,SKY/S,FMODE/N/K" +#define ARG_SPEED 0 +#define ARG_NTSC 1 +#define ARG_HOW 2 +#define ARG_SKY 3 +#define ARG_FMODE 4 +#define NUM_ARGS 5 + +#define MAPNAME "maps/large.raw" +#define BLOCKSNAME "blocks/demoblocks.raw" + +#define SCREENWIDTH 320 +#define SCREENHEIGHT 256 +#define EXTRAWIDTH 32 +#define SCREENBYTESPERROW (SCREENWIDTH / 8) + +#define BITMAPWIDTH ((SCREENWIDTH + EXTRAWIDTH) * 2) +#define BITMAPBYTESPERROW (BITMAPWIDTH / 8) +#define HALFBITMAPWIDTH (BITMAPWIDTH / 2) +#define BITMAPHEIGHT SCREENHEIGHT + +#define BLOCKSWIDTH 320 +#define BLOCKSHEIGHT 256 +#define BLOCKSDEPTH 4 +#define BLOCKSCOLORS (1L << BLOCKSDEPTH) +#define BLOCKWIDTH 16 +#define BLOCKHEIGHT 16 +#define BLOCKSBYTESPERROW (BLOCKSWIDTH / 8) +#define BLOCKSPERROW (BLOCKSWIDTH / BLOCKWIDTH) + +#define NUMSTEPS BLOCKWIDTH + +#define BITMAPBLOCKSPERROW (BITMAPWIDTH / BLOCKWIDTH) +#define HALFBITMAPBLOCKSPERROW (BITMAPBLOCKSPERROW / 2) +#define BITMAPBLOCKSPERCOL (BITMAPHEIGHT / BLOCKHEIGHT) + +#define BITMAPPLANELINES (BITMAPHEIGHT * BLOCKSDEPTH) +#define BLOCKPLANELINES (BLOCKHEIGHT * BLOCKSDEPTH) + +#define DIWSTART 0x2981 +#define DIWSTOP 0x29C1 + +#define PALSIZE (BLOCKSCOLORS * 2) +#define BLOCKSFILESIZE (BLOCKSWIDTH * BLOCKSHEIGHT * BLOCKSPLANES / 8 + PALSIZE) + +struct Screen *scr; +struct RastPort *ScreenRastPort; +struct BitMap *BlocksBitmap, *ScreenBitmap; +struct RawMap *Map; +UBYTE *frontbuffer,*blocksbuffer; + +WORD mapposx,videoposx; + +LONG mapwidth; +UBYTE *mapdata; + +UWORD colors[BLOCKSCOLORS]; + +LONG Args[NUM_ARGS]; + +BOOL option_ntsc,option_how,option_speed,option_sky; +WORD option_fetchmode; + +BPTR MyHandle; +char s[256]; + +struct FetchInfo +{ + WORD ddfstart; + WORD ddfstop; + WORD modulooffset; + WORD bitmapoffset; + WORD scrollpixels; + +} fetchinfo [] = +{ + {0x30,0xD0,2,0,16}, /* normal */ + {0x28,0xC8,4,16,32}, /* BPL32 */ + {0x28,0xC8,4,16,32}, /* BPAGEM */ + {0x18,0xB8,8,48,64} /* BPL32 + BPAGEM */ +}; + +/********************* MACROS ***********************/ + +#define ROUND2BLOCKWIDTH(x) ((x) & ~(BLOCKWIDTH - 1)) + +/********************* COMPATIBILITY ***********************/ + +/* AllocBitMap() is V39, provide a version here, that works on all AmigaOS versions */ +struct BitMap *MyAllocBitMap(ULONG sizex, ULONG sizey, ULONG depth, ULONG flags, + struct BitMap *friend_bitmap) +{ + return AllocBitMap(sizex, sizey, depth, flags, friend_bitmap); +} + +/* FreeBitMap() is V39, provide a version here that works on all AmigaOS versions */ +void MyFreeBitMap(struct BitMap *bitmap) +{ + FreeBitMap(bitmap); +} + +ULONG is_bitmap_interleaved(struct BitMap *bitmap) +{ + /* GetBitMapAttr() is V39, provide a version here that works on all AmigaOS versions */ + return (GetBitMapAttr(bitmap, BMA_FLAGS) & BMF_INTERLEAVED) == BMF_INTERLEAVED; +} + +/************* SETUP/CLEANUP ROUTINES ***************/ + +static void Cleanup(char *msg) +{ + WORD rc; + + if (msg) { + printf("Error: %s\n",msg); + rc = RETURN_WARN; + } else rc = RETURN_OK; + + if (scr) CloseScreen(scr); + + if (ScreenBitmap) { + WaitBlit(); + MyFreeBitMap(ScreenBitmap); + } + + if (BlocksBitmap) { + WaitBlit(); + MyFreeBitMap(BlocksBitmap); + } + + if (Map) free(Map); + if (MyHandle) Close(MyHandle); + exit(rc); +} + +static void GetArguments(void) +{ + struct RDArgs *MyArgs; + + if (!(MyArgs = ReadArgs(ARG_TEMPLATE,Args,0))) { + Fault(IoErr(),0,s,255); + Cleanup(s); + } + + if (Args[ARG_SPEED]) option_speed = TRUE; + if (Args[ARG_NTSC]) option_ntsc = TRUE; + if (Args[ARG_HOW]) { + option_how = TRUE; + option_speed = FALSE; + } + if (Args[ARG_SKY] && (!option_speed)) { + option_sky = TRUE; + } + if (Args[ARG_FMODE]) { + option_fetchmode = *(LONG *)Args[ARG_FMODE]; + } + FreeArgs(MyArgs); + + if (option_fetchmode < 0 || option_fetchmode > 3) { + Cleanup("Invalid fetch mode. Must be 0 .. 3!"); + } +} + +static void OpenMap(void) +{ + LONG l; + + if (!(MyHandle = Open(MAPNAME,MODE_OLDFILE))) { + Fault(IoErr(),0,s,255); + Cleanup(s); + } + + Seek(MyHandle,0,OFFSET_END); + l = Seek(MyHandle,0,OFFSET_BEGINNING); + + if (!(Map = calloc(l, sizeof(UBYTE)))) { + Cleanup("Out of memory!"); + } + + if (Read(MyHandle,Map,l) != l) { + Fault(IoErr(),0,s,255); + Cleanup(s); + } + Close(MyHandle); + MyHandle = 0; + + mapdata = Map->data; + mapwidth = Map->mapwidth; +} + +static void OpenBlocks(void) +{ + LONG l; + + if (!(BlocksBitmap = MyAllocBitMap(BLOCKSWIDTH, + BLOCKSHEIGHT, + BLOCKSDEPTH, + BMF_STANDARD | BMF_INTERLEAVED, + 0))) { + Cleanup("Can't alloc blocks bitmap!"); + } + + if (!(MyHandle = Open(BLOCKSNAME,MODE_OLDFILE))) { + Fault(IoErr(),0,s,255); + Cleanup(s); + } + + if (Read(MyHandle,colors,PALSIZE) != PALSIZE) { + Fault(IoErr(),0,s,255); + Cleanup(s); + } + + l = BLOCKSWIDTH * BLOCKSHEIGHT * BLOCKSDEPTH / 8; + + if (Read(MyHandle,BlocksBitmap->Planes[0],l) != l) { + Fault(IoErr(),0,s,255); + Cleanup(s); + } + Close(MyHandle);MyHandle = 0; + blocksbuffer = BlocksBitmap->Planes[0]; +} + +// V36: GetDisplayInfoData(), OpenScreenTags(), FindDisplayInfo() +static void OpenDisplay(void) +{ + struct DimensionInfo diminfo; + DisplayInfoHandle dih; + ULONG modeid; + LONG bmflags; + + if (!(ScreenBitmap = MyAllocBitMap(BITMAPWIDTH,BITMAPHEIGHT + 3,BLOCKSDEPTH, + BMF_STANDARD | BMF_INTERLEAVED | BMF_CLEAR,0))) { + Cleanup("Can't alloc screen bitmap!"); + } + frontbuffer = ScreenBitmap->Planes[0]; + frontbuffer += (fetchinfo[option_fetchmode].bitmapoffset / 8); + + if (!(TypeOfMem(ScreenBitmap->Planes[0]) & MEMF_CHIP)) { + Cleanup("Screen bitmap is not in CHIP RAM!?? If you have a gfx card try disabling \"planes to fast\" or similiar options in your RTG system!"); + } + + if (!is_bitmap_interleaved(ScreenBitmap)) { + Cleanup("Screen bitmap is not in interleaved format!??"); + } + + if (option_how) { + modeid = INVALID_ID; + + if ((dih = FindDisplayInfo(VGAPRODUCT_KEY))) { + if (GetDisplayInfoData(dih,(APTR)&diminfo,sizeof(diminfo),DTAG_DIMS,0)) { + if (diminfo.MaxDepth >= BLOCKSDEPTH) modeid = VGAPRODUCT_KEY; + } + } + if (modeid == INVALID_ID) { + if (option_ntsc) modeid = NTSC_MONITOR_ID | HIRESLACE_KEY; + else modeid = PAL_MONITOR_ID | HIRESLACE_KEY; + } + } else { + if (option_ntsc) modeid = NTSC_MONITOR_ID; + else modeid = PAL_MONITOR_ID; + } + + if (!(scr = OpenScreenTags(0,SA_Width,BITMAPWIDTH, + SA_Height,BITMAPHEIGHT + 3, + SA_Depth,BLOCKSDEPTH, + SA_DisplayID,modeid, + SA_BitMap,ScreenBitmap, + option_how ? SA_Overscan : TAG_IGNORE,OSCAN_TEXT, + option_how ? SA_AutoScroll : TAG_IGNORE,TRUE, + SA_Quiet,TRUE, + TAG_DONE))) { + Cleanup("Can't open screen!"); + } + + if (scr->RastPort.BitMap->Planes[0] != ScreenBitmap->Planes[0]) { + Cleanup("Screen was not created with the custom bitmap I supplied!??"); + } + ScreenRastPort = &scr->RastPort; + LoadRGB4(&scr->ViewPort,colors,BLOCKSCOLORS); +} + +static void InitCopperlist(void) +{ + WORD *wp; + LONG l; + + WaitVBL(); + custom->dmacon = 0x7FFF; + custom->beamcon0 = option_ntsc ? 0 : DISPLAYPAL; + CopFETCHMODE[1] = option_fetchmode; + + // bitplane control registers + CopBPLCON0[1] = ((BLOCKSDEPTH * BPL0_BPU0_F) & BPL0_BPUMASK) + + ((BLOCKSDEPTH / 8) * BPL0_BPU3_F) + + BPL0_COLOR_F + + (option_speed ? 0 : BPL0_USEBPLCON3_F); + + CopBPLCON1[1] = 0; + CopBPLCON3[1] = BPLCON3_BRDNBLNK; + + // bitplane modulos + l = BITMAPBYTESPERROW * BLOCKSDEPTH - + SCREENBYTESPERROW - fetchinfo[option_fetchmode].modulooffset; + + CopBPLMODA[1] = l; + CopBPLMODB[1] = l; + + // display window start/stop + CopDIWSTART[1] = DIWSTART; + CopDIWSTOP[1] = DIWSTOP; + + // display data fetch start/stop + CopDDFSTART[1] = fetchinfo[option_fetchmode].ddfstart; + CopDDFSTOP[1] = fetchinfo[option_fetchmode].ddfstop; + + // plane pointers + + wp = CopPLANE1H; + + for (l = 0;l < BLOCKSDEPTH;l++) { + wp[1] = (WORD)(((ULONG)ScreenBitmap->Planes[l]) >> 16); + wp[3] = (WORD)(((ULONG)ScreenBitmap->Planes[l]) & 0xFFFF); + wp += 4; + } + + if (option_sky) { + // activate copper sky + CopSKY[0] = 0x290f; + } + + custom->intena = 0x7FFF; + custom->dmacon = DMAF_SETCLR | DMAF_BLITTER | DMAF_COPPER | DMAF_RASTER | DMAF_MASTER; + custom->cop2lc = (ULONG)CopperList; +} + +/******************* SCROLLING **********************/ + +static void DrawBlock(LONG x,LONG y,LONG mapx,LONG mapy) +{ + UBYTE block; + + // x = in pixels + // y = in "planelines" (1 realline = BLOCKSDEPTH planelines) + x = x / 8; + y = y * BITMAPBYTESPERROW; + + block = mapdata[mapy * mapwidth + mapx]; + + mapx = (block % BLOCKSPERROW) * (BLOCKWIDTH / 8); + mapy = (block / BLOCKSPERROW) * (BLOCKPLANELINES * BLOCKSBYTESPERROW); + + if (option_how) OwnBlitter(); + + HardWaitBlit(); + + custom->bltcon0 = 0x9F0; // use A and D. Op: D = A + custom->bltcon1 = 0; + custom->bltafwm = 0xFFFF; + custom->bltalwm = 0xFFFF; + custom->bltamod = BLOCKSBYTESPERROW - (BLOCKWIDTH / 8); + custom->bltdmod = BITMAPBYTESPERROW - (BLOCKWIDTH / 8); + custom->bltapt = blocksbuffer + mapy + mapx; + custom->bltdpt = frontbuffer + y + x; + custom->bltsize = BLOCKPLANELINES * 64 + (BLOCKWIDTH / 16); + + if (option_how) DisownBlitter(); +} + +static void FillScreen(void) +{ + WORD a,b,x,y; + + for (b = 0;b < BITMAPBLOCKSPERCOL;b++) { + for (a = 0;a < HALFBITMAPBLOCKSPERROW;a++) { + x = a * BLOCKWIDTH; + y = b * BLOCKPLANELINES; + DrawBlock(x,y,a,b); + DrawBlock(x + HALFBITMAPWIDTH,y,a,b); + } + } +} + +static void ScrollLeft(void) +{ + WORD mapx,mapy,x,y; + + if (mapposx < 1) return; + + mapposx--; + videoposx = mapposx % HALFBITMAPWIDTH; + + mapx = mapposx / BLOCKWIDTH; + mapy = mapposx & (NUMSTEPS - 1); + + x = ROUND2BLOCKWIDTH(videoposx); + y = mapy * BLOCKPLANELINES; + + DrawBlock(x,y,mapx,mapy); + DrawBlock(x + HALFBITMAPWIDTH,y,mapx,mapy); +} + +static void ScrollRight(void) +{ + WORD mapx,mapy,x,y; + + if (mapposx >= (mapwidth * BLOCKWIDTH - SCREENWIDTH - BLOCKWIDTH)) return; + + mapx = mapposx / BLOCKWIDTH + HALFBITMAPBLOCKSPERROW; + mapy = mapposx & (NUMSTEPS - 1); + + x = ROUND2BLOCKWIDTH(videoposx); + y = mapy * BLOCKPLANELINES; + + DrawBlock(x,y,mapx,mapy); + DrawBlock(x + HALFBITMAPWIDTH,y,mapx,mapy); + + mapposx++; + videoposx = mapposx % HALFBITMAPWIDTH; +} + +static void CheckJoyScroll(void) +{ + WORD i,count; + + if (JoyFire()) count = 8; else count = 1; + if (JoyLeft()) { + for (i = 0; i < count; i++) ScrollLeft(); + } + + if (JoyRight()) { + for (i = 0; i < count; i++) ScrollRight(); + } +} + +static void UpdateCopperlist(void) +{ + ULONG pl; + WORD xpos,planeaddx,scroll,i; + WORD *wp; + + i = fetchinfo[option_fetchmode].scrollpixels; + + xpos = videoposx + i - 1; + + planeaddx = (xpos / i) * (i / 8); + i = (i - 1) - (xpos & (i - 1)); + + scroll = (i & 15) * 0x11; + if (i & 16) scroll |= (0x400 + 0x4000); + if (i & 32) scroll |= (0x800 + 0x8000); + + // set scroll register in BPLCON1 + CopBPLCON1[1] = scroll; + + // set plane pointers + wp = CopPLANE1H; + + for (i = 0;i < BLOCKSDEPTH;i++) { + pl = ((ULONG)ScreenBitmap->Planes[i]) + planeaddx; + wp[1] = (WORD)(pl >> 16); + wp[3] = (WORD)(pl & 0xFFFF); + wp += 4; + } +} + +static void ShowWhatCopperWouldDo(void) +{ + SetWriteMask(ScreenRastPort,1); + SetAPen(ScreenRastPort,0); + RectFill(ScreenRastPort,0,BITMAPHEIGHT + 1,BITMAPWIDTH - 1,BITMAPHEIGHT + 1); + SetAPen(ScreenRastPort,1); + RectFill(ScreenRastPort,videoposx + BLOCKWIDTH,BITMAPHEIGHT + 1, + videoposx + BLOCKWIDTH + SCREENWIDTH - 1,BITMAPHEIGHT + 1); +} + +static void MainLoop(void) +{ + if (!option_how) { + // activate copperlist + HardWaitBlit(); + WaitVBL(); + custom->copjmp2 = 0; + } + + while (!LMBDown()) { + if (!option_how) { + WaitVBeam(199); + WaitVBeam(200); + } else Delay(1); + + if (option_speed) *(WORD *)0xdff180 = 0xFF0; + + CheckJoyScroll(); + + if (option_speed) *(WORD *)0xdff180 = 0xF00; + if (!option_how) UpdateCopperlist(); + else ShowWhatCopperWouldDo(); + } +} + +/********************* MAIN *************************/ + +int main(int argc, char **argv) +{ + //OpenLibs(); + GetArguments(); + OpenMap(); + OpenBlocks(); + OpenDisplay(); + + if (!option_how) { + Delay(2*50); + KillSystem(); + InitCopperlist(); + } + FillScreen(); + MainLoop(); + + if (!option_how) ActivateSystem(); + Cleanup(0); + return 0; +} diff --git a/scrolling_tricks/map.h b/scrolling_tricks/map.h new file mode 100644 index 0000000..993452a --- /dev/null +++ b/scrolling_tricks/map.h @@ -0,0 +1,12 @@ +struct RawMap +{ + WORD mapwidth; + WORD mapheight; + WORD maplayers; + WORD blockwidth; + WORD blockheight; + BYTE bytesperblock; + BYTE transparentblock; + UBYTE data[1]; +}; + diff --git a/scrolling_tricks/maps/Large.map b/scrolling_tricks/maps/Large.map new file mode 100644 index 0000000..93985f4 Binary files /dev/null and b/scrolling_tricks/maps/Large.map differ diff --git a/scrolling_tricks/maps/Large.map.info b/scrolling_tricks/maps/Large.map.info new file mode 100644 index 0000000..1d19ce6 Binary files /dev/null and b/scrolling_tricks/maps/Large.map.info differ diff --git a/scrolling_tricks/maps/Race.map b/scrolling_tricks/maps/Race.map new file mode 100644 index 0000000..9f2f0ea Binary files /dev/null and b/scrolling_tricks/maps/Race.map differ diff --git a/scrolling_tricks/maps/Race.map.info b/scrolling_tricks/maps/Race.map.info new file mode 100644 index 0000000..30e901e Binary files /dev/null and b/scrolling_tricks/maps/Race.map.info differ diff --git a/scrolling_tricks/maps/Race.raw b/scrolling_tricks/maps/Race.raw new file mode 100644 index 0000000..5c83dfd Binary files /dev/null and b/scrolling_tricks/maps/Race.raw differ diff --git a/scrolling_tricks/maps/Readme b/scrolling_tricks/maps/Readme new file mode 100644 index 0000000..bdc7703 --- /dev/null +++ b/scrolling_tricks/maps/Readme @@ -0,0 +1,11 @@ +The demo programs don't load these PowerCrawler MAP Files but the +corresponding RAW files which are in this directory as well. The +RAW files were created with the RAW-IO Saver included in the +PowerCrawler package. + +---------------------------------------------------------------------------- + +Die Demoprogramme laden nicht diese PowerCrawler MAP Dateien, sondern +die entsprechenden RAW Dateien, die sich ebenfalls in diesem Verzeichnis +befinden. Die RAW Dateien wurden mit dem RAW-IO Saver erzeugt, der Teil +des PowerCrawler Paketes ist. diff --git a/scrolling_tricks/maps/Readme.info b/scrolling_tricks/maps/Readme.info new file mode 100644 index 0000000..d47f14d Binary files /dev/null and b/scrolling_tricks/maps/Readme.info differ diff --git a/scrolling_tricks/maps/Scroller.map b/scrolling_tricks/maps/Scroller.map new file mode 100644 index 0000000..27381c0 Binary files /dev/null and b/scrolling_tricks/maps/Scroller.map differ diff --git a/scrolling_tricks/maps/Scroller.map.info b/scrolling_tricks/maps/Scroller.map.info new file mode 100644 index 0000000..246b719 Binary files /dev/null and b/scrolling_tricks/maps/Scroller.map.info differ diff --git a/scrolling_tricks/maps/Scroller.raw b/scrolling_tricks/maps/Scroller.raw new file mode 100644 index 0000000..d140963 Binary files /dev/null and b/scrolling_tricks/maps/Scroller.raw differ diff --git a/scrolling_tricks/maps/large.raw b/scrolling_tricks/maps/large.raw new file mode 100644 index 0000000..f7fd4fc Binary files /dev/null and b/scrolling_tricks/maps/large.raw differ diff --git a/utils/decode_cloanto_rom.py b/utils/decode_cloanto_rom.py index 97fa6b6..346a835 100755 --- a/utils/decode_cloanto_rom.py +++ b/utils/decode_cloanto_rom.py @@ -41,7 +41,7 @@ if __name__ == '__main__': with open(args.romfile, 'rb') as infile: file_id = infile.read(len(CLOANTO_ID)) if file_id == CLOANTO_ID: - data = infile.read() + data = infile.read() size = len(data) if size not in ROM_SIZES: raise Exception("invalid rom size") diff --git a/utils/soundconvert.rkt b/utils/soundconvert.rkt new file mode 100644 index 0000000..425294b --- /dev/null +++ b/utils/soundconvert.rkt @@ -0,0 +1,23 @@ +#lang racket +(require rsound) +(require rsound/draw) +(require ffi/vector) + +(define (play-sound s n) + (cond [(> n 0) + (play s) + (sleep 0.1) + ;;(play (resample 2 sound)) + (play-sound s (- n 1))])) + +(define (analyze-sound s) + (let ([v (rsound-data s)]) + v)) + + +(let ([sound (rs-read "/home/weiju/Desktop/Laser_Shoot7.wav")]) + ;;(rsound-fft-draw sound) + (play-sound sound 3) + (play-sound sound 3) + ;;(s16vector->list (analyze-sound sound)) + ) diff --git a/utils/wav2ami.py b/utils/wav2ami.py new file mode 100755 index 0000000..b330e85 --- /dev/null +++ b/utils/wav2ami.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python +import argparse +import wave +import struct + +def conv_amplitude(amp_bstr): + """converts 16 bit amplitudes into 8 bit amplitudes""" + return struct.unpack(">H", amp_bstr)[0] >> 8 + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description="wav2ami 1.0") + parser.add_argument('wavfile') + + args = parser.parse_args() + print args.wavfile + infile = wave.open(args.wavfile) + print "# channels: ", infile.getnchannels() + print "sample width: ", infile.getsampwidth() + print "frame rate: ", infile.getframerate() + print "# frames: ", infile.getnframes() + num_frames = infile.getnframes() + data = [conv_amplitude(infile.readframes(1)) for _ in range(num_frames)] + #print data + infile.close()