added audio and scrolling_tricks

This commit is contained in:
Wei-ju Wu 2016-06-13 08:49:14 -07:00
parent 612e9ffdd8
commit 713cf74d27
28 changed files with 1199 additions and 10 deletions

View File

@ -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

78
devices/audio.c Normal file
View File

@ -0,0 +1,78 @@
/* audio.c
This is a cleaned up version of the example program in Commodore RKM (Devices)
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <exec/libraries.h>
#include <graphics/gfxbase.h>
#include <devices/audio.h>
#include <clib/exec_protos.h>
#include <clib/alib_protos.h>
#include <stdio.h>
#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;
}

View File

@ -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

View File

@ -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);

20
scrolling_tricks/Makefile Normal file
View File

@ -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

View File

@ -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

Binary file not shown.

Binary file not shown.

226
scrolling_tricks/cop.asm Normal file
View File

@ -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

29
scrolling_tricks/cop.h Normal file
View File

@ -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[];

160
scrolling_tricks/hardware.c Normal file
View File

@ -0,0 +1,160 @@
#include <exec/exec.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <devices/input.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#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; }

View File

@ -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);

543
scrolling_tricks/main.c Normal file
View File

@ -0,0 +1,543 @@
#include <exec/exec.h>
#include <dos/dos.h>
#include <intuition/intuition.h>
#include <graphics/gfx.h>
#include <hardware/custom.h>
#include <hardware/dmabits.h>
#include <clib/exec_protos.h>
#include <clib/dos_protos.h>
#include <clib/graphics_protos.h>
#include <clib/intuition_protos.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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;
}

12
scrolling_tricks/map.h Normal file
View File

@ -0,0 +1,12 @@
struct RawMap
{
WORD mapwidth;
WORD mapheight;
WORD maplayers;
WORD blockwidth;
WORD blockheight;
BYTE bytesperblock;
BYTE transparentblock;
UBYTE data[1];
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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")

23
utils/soundconvert.rkt Normal file
View File

@ -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))
)

25
utils/wav2ami.py Executable file
View File

@ -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()