home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus 1998 #5
/
AmigaPlus_CD-ROM_Nr.5-98.iso
/
pd
/
musik
/
playmf
/
fireworks
/
source
/
fireworks.c
< prev
next >
Wrap
C/C++ Source or Header
|
1998-04-05
|
68KB
|
2,870 lines
/*-------------------------------------------------*/
/* fireworks.c - graphical MIDI note visualisation */
/* ® 1998 by Christian Buchner */
/*-------------------------------------------------*/
#include "fireworks.h"
#include "fireworks_protos.h"
#include "fwmodes.h"
#define PREF_VERSION 1
struct Task *MyTask; /* this task */
BOOL WBMode = FALSE; /* Workbench or not? */
/* for MIDI timestamping */
extern struct EClockVal stampeclock;
/* Globals for Watchdog timer */
/* (from timer.c) */
extern struct Interrupt VertBlank;
extern BOOL Watch;
extern ULONG IdleCount;
/* Function Prototypes */
LONG ShellInterface(void);
LONG WBInterface(struct Process *MyProc);
BOOL WindowLayout(struct Globals *glob, WORD *minw, WORD *minh, WORD *maxw, WORD *maxh);
LONG Fireworks(struct Prefs *pref);
void MainLoop(struct Globals *glob, struct Prefs *pref);
BOOL OpenGUI(struct Globals *glob, struct Prefs *pref);
void TitleWindow(struct Globals *glob, UBYTE *Text, ...);
BOOL SelectScreenMode(struct Globals *glob, struct Prefs *pref, struct ScreenModeRequester **srq);
void CloseGUI(struct Globals *glob, struct Prefs *pref);
void InitPrefs(struct Prefs *pref);
BOOL LoadPrefs(struct Prefs *pref);
BOOL SavePrefs(struct Globals *glob, struct Prefs *pref, UBYTE *EnvName);
void InitGlobals(struct Globals *glob);
void AsyncSelectMIDILink(struct Globals *glob, struct Prefs *pref);
void AsyncSelectScreenMode(struct Globals *glob, struct Prefs *pref);
void AsyncSelectImage(struct Globals *glob, struct Prefs *pref);
void AsyncSelectAndPlay(struct Globals *glob, struct Prefs *pref);
BOOL InitOrUpdateGraphics(struct Globals *glob, struct Prefs *pref);
void FreeGraphics(struct Globals *glob);
struct Screen *GetScreen(struct Globals *glob);
void LoadImage(struct Globals *glob, struct Prefs *pref);
BOOL SelectImage(struct Globals *glob, struct Prefs *pref, struct FileRequester **fr, UBYTE *filebuffer, ULONG MaxSize);
BOOL SelectMIDI(struct Globals *glob, struct Prefs *pref, struct FileRequester **fr, UBYTE *filebuffer, ULONG MaxSize);
void PlayMIDI(struct Globals *glob, struct Prefs *pref);
void StopMIDI(struct Globals *glob, struct Prefs *pref);
/* Palette and Sprite data structures */
ULONG ScreenPalette[] =
{
((2L<<16) | 0),
0x00000000, 0x00000000, 0x00000000,
0xAAAAAAAA, 0xAAAAAAAA, 0xAAAAAAAA,
((0L<<16) | 0)
};
UWORD PenArray[] =
{
1, // DETAILPEN
0, // BLOCKPEN
1, // TEXTPEN
1, // SHINEPEN
1, // SHADOWPEN
1, // FILLPEN
0, // FILLTEXTPEN
0, // BACKGROUNDPEN
1, // HIGHLIGHTTEXTPEN
1, // BARDETAILPEN
0, // BARBLOCKPEN
0, // BARTRIMPEN
};
UBYTE PenColors[NUMPENS][3] =
{
0x00, 0x00, 0x00, /* Black background */
0xff, 0xff, 0xff, /* white sparks/glitter */
255, 64, 64, /* Chan 1 */
255, 137, 64, /* Chan 2 */
255, 207, 64, /* Chan 3 */
230, 255, 64, /* Chan 4 */
159, 255, 64, /* Chan 5 */
86, 255, 64, /* Chan 6 */
64, 255, 112, /* Chan 7 */
64, 255, 185, /* Chan 8 */
64, 255, 255, /* Chan 9 */
64, 185, 255, /* Chan 10 */
64, 112, 255, /* Chan 11 */
86, 64, 255, /* Chan 12 */
159, 64, 255, /* Chan 13 */
230, 64, 255, /* Chan 14 */
255, 64, 207, /* Chan 15 */
255, 64, 137, /* Chan 16 */
};
UWORD chip WaitPointer[] =
{
0x0000, 0x0000,
0x0400, 0x07C0,
0x0000, 0x07C0,
0x0100, 0x0380,
0x0000, 0x07E0,
0x07C0, 0x1FF8,
0x1FF0, 0x3FEC,
0x3FF8, 0x7FDE,
0x3FF8, 0x7FBE,
0x7FFC, 0xFF7F,
0x7EFC, 0xFFFF,
0x7FFC, 0xFFFF,
0x3FF8, 0x7FFE,
0x3FF8, 0x7FFE,
0x1FF0, 0x3FFC,
0x07C0, 0x1FF8,
0x0000, 0x07E0,
0x0000, 0x0000, /* reserved, must be NULL */
};
UWORD chip NoPointer[] =
{
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000,
0x0000, 0x0000, /* reserved, must be NULL */
};
/* Array of random numbers (0 or 1) */
UBYTE randomarray33[256];
/* Some defines */
/* the opposite of noteon() */
#define noteoff(m) ( voicemsg(m,MS_NoteOff) || (voicemsg(m,MS_NoteOn) && (!(m)->mm_Data2)) )
#define offsetof(s, m) (size_t)(&(((s *)0)->m))
#define MIN(a,b) ((a) <= (b) ? (a) : (b))
#define elementsof(a) ((sizeof(a) / sizeof(a[0])))
/* Intuition Menu structures */
enum
{
Menu_Ignore1,
Menu_Link,
Menu_Hooks,
Menu_Save,
Menu_Ignore2,
Menu_About,
Menu_Ignore3,
Menu_Quit,
Menu_Ignore4,
Menu_Kill,
Menu_Load,
Menu_Tile,
Menu_Ignore5,
Menu_Screenmode,
Menu_Fullscreen,
Menu_Titlebar,
Menu_Mouse,
Menu_Ignore6,
Menu_Mode1,
Menu_Mode2,
Menu_Mode3,
Menu_Ignore7,
Menu_Sens1,
Menu_Sens2,
Menu_Sens3,
Menu_Ignore8,
Menu_Double,
Menu_Sparks,
Menu_Ignore9,
Menu_Release,
Menu_Ignore10,
Menu_Play,
Menu_Stop,
Menu_Ignore11,
Menu_Init1,
Menu_Init2,
Menu_Init3,
Menu_Init4,
Menu_Init5,
Menu_Ignore12,
Menu_Timestamp,
Menu_Ignore13,
};
#define M1 (1<<0)
#define M2 (1<<1)
#define M3 (1<<2)
#define S1 (1<<4)
#define S2 (1<<5)
#define S3 (1<<6)
#define I1 (1<<5)
#define I2 (1<<6)
#define I3 (1<<7)
#define I4 (1<<8)
#define I5 (1<<9)
struct NewMenu FWNewMenu[]=
{
/* nm_Type nm_Label nm_CommKey nm_Flags nm_MutualExclude nm_UserData */
NM_TITLE, "Project", NULL, 0, 0, (APTR)Menu_Ignore1,
NM_ITEM, "MIDI Link...", "L", 0, 0, (APTR)Menu_Link,
NM_ITEM, "ASL Hooks", "A", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Hooks,
NM_ITEM, "Save Config", "C", 0, 0, (APTR)Menu_Save,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore2,
NM_ITEM, "About", "?", 0, 0, (APTR)Menu_About,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore3,
NM_ITEM, "Quit", "Q", 0, 0, (APTR)Menu_Quit,
NM_TITLE, "Window", NULL, 0, 0, (APTR)Menu_Ignore4,
NM_ITEM, "Remove Backdrop", "R", 0, 0, (APTR)Menu_Kill,
NM_ITEM, "Load Backdrop...", "B", 0, 0, (APTR)Menu_Load,
NM_ITEM, "Tile Backdrop", "T", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Tile,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore5,
NM_ITEM, "Set Screenmode...","M", 0, 0, (APTR)Menu_Screenmode,
NM_ITEM, "Full Screen", "F", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Fullscreen,
NM_ITEM, "Hide Titlebar", "H", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Titlebar,
NM_ITEM, "Hide Mouseptr", "I", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Mouse,
NM_TITLE, "Rendering", NULL, 0, 0, (APTR)Menu_Ignore6,
NM_ITEM, "Laser Mode", "1", CHECKIT, ( M2|M3), (APTR)Menu_Mode1,
NM_ITEM, "Pixel Mode", "2", CHECKIT, (M1| M3), (APTR)Menu_Mode2,
NM_ITEM, "Fountain Mode", "3", CHECKIT, (M1|M2 ), (APTR)Menu_Mode3,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore7,
NM_ITEM, "Sensitivity Max", "X", CHECKIT, ( S2|S3), (APTR)Menu_Sens1,
NM_ITEM, "Sensitivity Med", "Y", CHECKIT, (S1| S3), (APTR)Menu_Sens2,
NM_ITEM, "Sensitivity Low", "Z", CHECKIT, (S1|S2 ), (APTR)Menu_Sens3,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore8,
NM_ITEM, "Double Strength", "D", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Double,
NM_ITEM, "Sparks", "+", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Sparks,
NM_TITLE, "MIDI", NULL, 0, 0, (APTR)Menu_Ignore9,
NM_ITEM, "Release Notes", "N", 0, 0, (APTR)Menu_Release,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore10,
NM_ITEM, "Play MIDI file...","P", 0, 0, (APTR)Menu_Play,
NM_ITEM, "Stop playing", "S", 0, 0, (APTR)Menu_Stop,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore11,
NM_ITEM, "Normal Init", NULL, CHECKIT, ( I2|I3|I4|I5), (APTR)Menu_Init1,
NM_ITEM, "GM Reset", NULL, CHECKIT, (I1| I3|I4|I5), (APTR)Menu_Init2,
NM_ITEM, "GS Reset", NULL, CHECKIT, (I1|I2| I4|I5), (APTR)Menu_Init3,
NM_ITEM, "XG Reset", NULL, CHECKIT, (I1|I2|I3 |I5), (APTR)Menu_Init4,
NM_ITEM, "MT32 Emu", NULL, CHECKIT, (I1|I2|I3|I4 ), (APTR)Menu_Init5,
NM_ITEM, NM_BARLABEL, NULL, 0, 0, (APTR)Menu_Ignore12,
NM_ITEM, "Timestamping", "E", CHECKIT|MENUTOGGLE, 0, (APTR)Menu_Timestamp,
NM_END, NULL, NULL, 0, 0, (APTR)Menu_Ignore13,
};
/*--------------*/
/* Startup code */
/*--------------*/
LONG __saveds mymain(void)
{
LONG ReturnCode;
struct Process *MyProc;
SysBase = *((struct ExecBase**)(0x4));
MyProc = (struct Process*) FindTask(NULL);
if (!MyProc->pr_CLI)
{
WBMode = TRUE;
ReturnCode = WBInterface(MyProc);
}
else
{
ReturnCode = ShellInterface();
}
return(ReturnCode);
}
/*---------------------*/
/* Workbench Interface */
/*---------------------*/
LONG WBInterface(struct Process *MyProc)
{
struct WBStartup *wbmsg;
LONG ReturnCode = RETURN_ERROR;
WaitPort(&MyProc->pr_MsgPort);
if (wbmsg = (struct WBStartup*)GetMsg(&MyProc->pr_MsgPort))
{
if (OpenLibs())
{
BPTR OldDir;
struct Prefs *pref;
OldDir = CurrentDir(wbmsg->sm_ArgList->wa_Lock);
if (!(pref = AllocVec(sizeof(struct Prefs),MEMF_ANY|MEMF_CLEAR)))
{
Message("No memory for prefs!",NULL);
}
else
{
InitPrefs(pref);
LoadPrefs(pref);
ReturnCode = Fireworks(pref);
FreeVec(pref);
}
CurrentDir(OldDir);
CloseLibs();
}
Forbid();
ReplyMsg((struct Message*)wbmsg);
}
return(ReturnCode);
}
/*-----------------*/
/* Shell Interface */
/*-----------------*/
LONG ShellInterface(void)
{
LONG ReturnCode = RETURN_ERROR;
BPTR lock;
BPTR OldDir;
if (OpenLibs())
{
if (!(lock = Lock("PROGDIR:", SHARED_LOCK)))
{
Message("Unable to locate program directory.",NULL);
}
else
{
/* CLI argument parsing */
struct ArgArray
{
UBYTE *aa_Link;
ULONG *aa_Mode;
ULONG *aa_Sensitivity;
ULONG *aa_WinX;
ULONG *aa_WinY;
ULONG *aa_WinW;
ULONG *aa_WinH;
UBYTE *aa_Image;
ULONG aa_Tile;
ULONG aa_Fullscreen;
ULONG aa_Double;
ULONG aa_Sparks;
ULONG aa_GM;
ULONG aa_GS;
ULONG aa_XG;
ULONG aa_MT32;
ULONG aa_NoHooks;
ULONG aa_NoTS;
} AA;
static UBYTE *Template = "L=LINK/K,M=MODE/K/N,S=SENSITIVITY/K/N,WX=WINX/K/N,WY=WINY/K/N,WW=WINW/K/N,WH=WINH/K/N,I=IMAGE/K,T=TILE/S,FS=FULLSCREEN/S,D=DOUBLE/S,SP=SPARKS/S,GM/S,GS/S,XG/S,MT32/S,NH=NOHOOKS/S,NTS=NOTIMESTAMPING/S";
struct RDArgs *RDArgs;
struct Prefs *pref;
ReturnCode = RETURN_FAIL;
OldDir = CurrentDir(lock);
if (!(pref = AllocVec(sizeof(struct Prefs),MEMF_ANY|MEMF_CLEAR)))
{
Message("No memory for prefs!",NULL);
}
else
{
InitPrefs(pref);
LoadPrefs(pref);
memset(&AA, 0, sizeof(struct ArgArray));
if (RDArgs=ReadArgs(Template, (LONG *)&AA, 0))
{
BOOL fault = FALSE;
UWORD opts;
if (AA.aa_Link)
{
strncpy(pref->Link, AA.aa_Link, sizeof(pref->Link));
pref->Link[sizeof(pref->Link)-1] = 0;
}
if (AA.aa_Mode)
{
LONG mode = (*AA.aa_Mode) - 1;
if (mode >=0 && mode < NUM_FWMODES) pref->FWMode = mode;
else
Message("Mode out of range! There are currently modes 1-%ld available.", NULL, NUM_FWMODES);
fault = TRUE;
}
if (AA.aa_Sensitivity)
{
LONG sens = (*AA.aa_Sensitivity);
switch(sens)
{
case 1: pref->Sensitivity=100; break;
case 2: pref->Sensitivity= 75; break;
case 3: pref->Sensitivity= 50; break;
default:
Message("Sensitivity out of range! Allowed range is 1-3.", NULL);
fault = TRUE;
break;
}
}
if (AA.aa_WinX) pref->WinX= *AA.aa_WinX;
if (AA.aa_WinY) pref->WinY= *AA.aa_WinY;
if (AA.aa_WinW) pref->WinW= *AA.aa_WinW;
if (AA.aa_WinH) pref->WinH= *AA.aa_WinH;
if (AA.aa_Image)
{
strncpy(pref->Image, AA.aa_Image, sizeof(pref->Image));
pref->Image[sizeof(pref->Image)-1] = 0;
}
if (AA.aa_Tile) pref->Flags |= PREFF_TILE;
if (AA.aa_Fullscreen) pref->Flags |= PREFF_FULLSCREEN;
if (AA.aa_Double) pref->Flags |= PREFF_DOUBLE;
if (AA.aa_Sparks) pref->Flags |= PREFF_SPARKS;
if (AA.aa_NoHooks) pref->Flags &= ~(PREFF_ASLHOOKS);
if (AA.aa_NoTS) pref->Flags &= ~(PREFF_TIMESTAMP);
opts = 0;
if (AA.aa_GM ) {opts++; pref->Flags |= PREFF_GM ;};
if (AA.aa_GS ) {opts++; pref->Flags |= PREFF_GS ;};
if (AA.aa_XG ) {opts++; pref->Flags |= PREFF_XG ;};
if (AA.aa_MT32) {opts++; pref->Flags |= PREFF_MT32;};
if (opts>1)
{
Message("Please specify only one of GM, GS, XG and MT32.", NULL);
fault = TRUE;
}
if (!fault)
{
ReturnCode = Fireworks(pref);
}
FreeArgs(RDArgs);
}
else
{
PrintFault(IoErr(),"Fireworks");
}
FreeVec(pref);
}
CurrentDir(OldDir);
UnLock(lock);
}
CloseLibs();
}
return(ReturnCode);
}
/*-----------------------------*/
/* GUI and MIDI initialisation */
/*-----------------------------*/
LONG Fireworks(struct Prefs *pref)
{
LONG ReturnCode = RETURN_FAIL;
struct Globals *glob;
BYTE OldPri;
MyTask = FindTask(NULL);
if (!(glob = AllocVec(sizeof(struct Globals), MEMF_ANY|MEMF_CLEAR)))
{
Message("No memory for globals!",NULL);
}
else
{
InitGlobals(glob);
if (OpenGUI(glob,pref))
{
if (!((glob->NotePool = CreatePool(MEMF_ANY,8192,4096))))
{
Message("No memory for NotePool!",NULL);
}
else
{
if (!(glob->midi = CreateMidi(
MIDI_Name, "Fireworks",
MIDI_TimeStamp, &stampeclock.ev_lo,
MIDI_RecvSignal, SIGBREAKB_CTRL_E,
MIDI_MsgQueue, 2000,
MIDI_ErrFilter, CMEF_All,
TAG_DONE)))
{
Message("Cannot create MIDI port!",NULL);
}
else
{
if (!(glob->link = AddMidiLink(glob->midi, MLTYPE_Receiver,
MLINK_Name, "Fireworks Link",
MLINK_Location, pref->Link,
MLINK_EventMask, CMF_Note|CMF_Mode,
MLINK_Comment, "Fireworks [Input]",
TAG_DONE)))
{
Message("Cannot create link to MIDI interface '%s'",NULL,pref->Link);
}
else
{
TitleWindow(glob, "Fireworks [%s] [idle]", pref->Link);
if (!(glob->treq = OpenTimer()))
{
}
else
{
OldPri = MyTask->tc_Node.ln_Pri;
MainLoop(glob, pref);
WaitAsync(glob);
ReturnCode = RETURN_OK;
SetTaskPri(MyTask, OldPri);
CloseTimer(glob->treq);
glob->treq=NULL;
}
RemoveMidiLink(glob->link);
glob->link = NULL;
}
DeleteMidi(glob->midi);
glob->midi = NULL;
}
DeletePool(glob->NotePool);
glob->NotePool = NULL;
}
CloseGUI(glob, pref);
}
if (glob->ImageFR)
{
FreeAslRequest(glob->ImageFR);
glob->ImageFR = NULL;
}
if (glob->MIDIFR)
{
FreeAslRequest(glob->MIDIFR);
glob->MIDIFR = NULL;
}
if (glob->ScreenModeRQ)
{
FreeAslRequest(glob->ScreenModeRQ);
glob->ScreenModeRQ = NULL;
}
FreeVec(glob);
}
return(ReturnCode);
}
/*--------------------*/
/* Set Prefs defaults */
/*--------------------*/
void InitPrefs(struct Prefs *pref)
{
memset(pref, 0, sizeof(struct Prefs));
strcpy(pref->Header, "Fireworks");
pref->Version = PREF_VERSION;
strcpy(pref->Link,"out.0");
pref->FWMode = ParabolicMode2;
pref->Sensitivity = 100;
pref->Flags = PREFF_BACKDROP | PREFF_ASLHOOKS | PREFF_TIMESTAMP;
pref->WinX = 100;
pref->WinY = 200;
pref->WinW = 256;
pref->WinH = 256;
strcpy(pref->Image,"PROGDIR:Backdrop.Pic");
pref->ScreenMode = -1L;
pref->AutoScroll = FALSE;
}
/*------------*/
/* Load Prefs */
/*------------*/
BOOL LoadPrefs(struct Prefs *pref)
{
BOOL Success = FALSE;
UBYTE *name = "ENV:MIDI/Fireworks.prefs";
BPTR file;
if (file = Open(name, MODE_OLDFILE))
{
if (Read(file, pref, sizeof(struct Prefs)) != -1)
{
if (stricmp(pref->Header, "Fireworks"))
{
Message("'%s' is not a Fireworks preferences file. Using defaults.", NULL, name);
}
else
{
if (pref->Version != PREF_VERSION)
{
Message("'%s' preferences version is not supported. Using defaults.", NULL, name);
}
else
{
Success = TRUE;
}
}
}
if (!Success) InitPrefs(pref);
Close(file);
}
return(Success);
}
/*------------*/
/* Save Prefs */
/*------------*/
BOOL SavePrefs(struct Globals *glob, struct Prefs *pref, UBYTE *EnvName)
{
BOOL Success = FALSE;
BPTR OldDir=NULL;
BPTR EnvLock=NULL;
BPTR MIDILock=NULL;
BPTR FH;
UBYTE *FileName = "Fireworks.prefs";
UBYTE *MIDIName = "MIDI";
pref->WinX = glob->Window->LeftEdge;
pref->WinY = glob->Window->TopEdge;
pref->WinW = glob->ww;
pref->WinH = glob->wh;
if (EnvLock=Lock(EnvName,ACCESS_READ))
{
OldDir=CurrentDir(EnvLock);
if (!(MIDILock=Lock(MIDIName,ACCESS_READ)))
{
MIDILock=CreateDir(MIDIName);
}
if (MIDILock)
{
CurrentDir(MIDILock);
Success=TRUE;
}
}
if (Success)
{
Success=FALSE;
if (FH=Open(FileName,MODE_NEWFILE))
{
if (Write(FH,pref,sizeof(struct Prefs))==sizeof(struct Prefs))
{
Success=TRUE;
}
Close(FH);
}
}
if (OldDir) CurrentDir(OldDir);
if (MIDILock) UnLock(MIDILock);
if (EnvLock) UnLock(EnvLock);
return(Success);
}
/*--------------------*/
/* Initialize globals */
/*--------------------*/
void InitGlobals(struct Globals *glob)
{
UWORD i;
for (i=0; i<NUMPENS; i++) glob->PenArray[i] = -1L;
}
/*-------------------------------*/
/* Open the GUI (Screen, Window) */
/*-------------------------------*/
BOOL OpenGUI(struct Globals *glob, struct Prefs *pref)
{
BOOL Success = FALSE;
struct Screen *wbscr;
WORD minw, minh;
WORD maxw, maxh;
UWORD mode, sens, init;
glob->Screen = NULL;
if (!(glob->AppPort = CreateMsgPort()))
{
Message("Failed to create AppMsg port.", NULL);
}
else
{
if (pref->Flags & PREFF_FULLSCREEN)
{
if (pref->ScreenMode == -1L)
{
if (!SelectScreenMode(glob, pref, &glob->ScreenModeRQ))
{
pref->Flags &= ~(PREFF_FULLSCREEN);
}
}
}
if (pref->Flags & PREFF_FULLSCREEN)
{
if (pref->ScreenMode != -1L)
{
struct Screen *scr;
/* maybe screen couldn't be closed before (visitor window) */
if (glob->OpenedScreen) CloseScreen(glob->OpenedScreen);
if (!(scr = OpenScreenTags(NULL,
SA_DisplayID, pref->ScreenMode,
SA_Width, (ULONG)pref->ScreenWidth,
SA_Height, (ULONG)pref->ScreenHeight,
SA_Depth, (ULONG)pref->ScreenDepth,
SA_Overscan, (ULONG)pref->OverscanType,
SA_AutoScroll, (ULONG)pref->AutoScroll,
SA_SharePens, (ULONG)TRUE,
SA_Interleaved, (ULONG)TRUE,
SA_PubName, "Fireworks",
SA_Colors32, ScreenPalette,
SA_Pens, PenArray,
TAG_DONE )))
{
Message("Unable to open selected screen!",NULL);
}
else
{
glob->Screen = glob->OpenedScreen = scr;
if (glob->LockedScreen)
{
UnlockPubScreen(NULL, glob->LockedScreen);
glob->LockedScreen = NULL;
}
}
}
}
else
{
if (!glob->LockedScreen)
{
glob->LockedScreen = GetScreen(glob);
}
glob->Screen = glob->LockedScreen;
}
if (glob->Screen)
{
if (!(glob->VisualInfo = GetVisualInfo(glob->Screen, TAG_DONE)))
{
Message("No visual info!",NULL);
}
else
{
glob->ww = pref->WinW;
glob->wh = pref->WinH;
if (!(WindowLayout(glob, &minw, &minh, &maxw, &maxh )))
{
Message("Couldn't layout window!",NULL);
}
else
{
if (pref->Flags & PREFF_FULLSCREEN)
{
ULONG height;
ULONG BDrop;
if (pref->Flags & PREFF_HDTITLEBAR)
{
height = pref->ScreenHeight;
BDrop = FALSE;
}
else
{
height = pref->ScreenHeight-(glob->Screen->BarHeight+1);
BDrop = FALSE;
}
glob->Window = OpenWindowTags( NULL,
WA_PubScreen, glob->Screen,
WA_Left, 0,
WA_Top, glob->Screen->BarHeight+1,
WA_Width, pref->ScreenWidth,
WA_Height, height,
WA_Backdrop, BDrop,
WA_Borderless, TRUE,
WA_Activate, TRUE,
WA_IDCMP, IDCMP_MENUPICK|IDCMP_REFRESHWINDOW,
WA_SimpleRefresh, TRUE,
WA_NewLookMenus, TRUE,
TAG_DONE );
}
else
{
glob->Window = OpenWindowTags( NULL,
WA_PubScreen, glob->Screen,
WA_Title, "Fireworks",
WA_Left, pref->WinX,
WA_Top, pref->WinY,
WA_InnerWidth, (ULONG)glob->ww,
WA_InnerHeight, (ULONG)glob->wh,
WA_GimmeZeroZero, TRUE,
WA_DepthGadget, TRUE,
WA_SizeGadget, TRUE,
WA_SizeBBottom, TRUE,
WA_CloseGadget, TRUE,
WA_DragBar, TRUE,
WA_Activate, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW|IDCMP_NEWSIZE|IDCMP_MENUPICK|IDCMP_REFRESHWINDOW,
WA_SimpleRefresh, TRUE,
WA_NewLookMenus, TRUE,
TAG_DONE );
}
if (!glob->Window)
{
Message("Couldn't open window!",NULL);
}
else
{
glob->ProcWindow = ((struct Process*)MyTask)->pr_WindowPtr;
((struct Process*)MyTask)->pr_WindowPtr = glob->Window;
if ( wbscr = LockPubScreen("Workbench") )
{
if (glob->Screen == wbscr)
{
glob->AppWindow = AddAppWindow( 1, NULL, glob->Window, glob->AppPort, TAG_DONE);
}
UnlockPubScreen( NULL, wbscr );
}
glob->ww = glob->Window->Width - glob->Window->BorderLeft-glob->Window->BorderRight ;
glob->wh = glob->Window->Height - glob->Window->BorderTop -glob->Window->BorderBottom;
glob->Window->MinWidth = minw + glob->Window->BorderLeft+glob->Window->BorderRight;
glob->Window->MinHeight = minh + glob->Window->BorderTop +glob->Window->BorderBottom;
glob->Window->MaxWidth = maxw + glob->Window->BorderLeft+glob->Window->BorderRight;
glob->Window->MaxHeight = maxh + glob->Window->BorderTop +glob->Window->BorderBottom;
if (!(InitOrUpdateGraphics(glob,pref)))
{
Message("Failed to initialize graphics!",NULL);
}
else
{
BltBitMapRastPort(glob->PaintBitMap, 0, 0, glob->Window->RPort, 0, 0, glob->ww, glob->wh, 0xc0);
if (pref->Flags & PREFF_BACKDROP)
if (pref->Image) LoadImage(glob,pref);
if (pref->Flags & PREFF_ASLHOOKS)
FWNewMenu[Menu_Hooks].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Hooks].nm_Flags &= (~CHECKED);
if (pref->Flags & PREFF_TILE)
FWNewMenu[Menu_Tile].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Tile].nm_Flags &= (~CHECKED);
if (pref->Flags & PREFF_FULLSCREEN)
FWNewMenu[Menu_Fullscreen].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Fullscreen].nm_Flags &= (~CHECKED);
if (pref->Flags & PREFF_HDTITLEBAR)
FWNewMenu[Menu_Titlebar].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Titlebar].nm_Flags &= (~CHECKED);
if (pref->Flags & PREFF_HDMOUSEPTR)
FWNewMenu[Menu_Mouse].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Mouse].nm_Flags &= (~CHECKED);
if (pref->Flags & PREFF_DOUBLE)
FWNewMenu[Menu_Double].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Double].nm_Flags &= (~CHECKED);
if (pref->Flags & PREFF_SPARKS)
FWNewMenu[Menu_Sparks].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Sparks].nm_Flags &= (~CHECKED);
for (mode = 0; mode < NUM_FWMODES ; mode++)
{
if (pref->FWMode == mode)
FWNewMenu[Menu_Mode1+mode].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Mode1+mode].nm_Flags &= (~CHECKED);
}
for (sens = 1; sens <= 3 ; sens++)
{
if (((sens == 1) && (pref->Sensitivity == 100)) ||
((sens == 2) && (pref->Sensitivity == 75)) ||
((sens == 3) && (pref->Sensitivity == 50)))
FWNewMenu[Menu_Sens1+sens-1].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Sens1+sens-1].nm_Flags &= (~CHECKED);
}
for (init = 0; init <= 4 ; init++)
{
BOOL set = FALSE;
switch(init)
{
case 0:
if (!(pref->Flags&(PREFF_GM|PREFF_GS|PREFF_XG|PREFF_MT32)))
set = TRUE;
break;
case 1:
if (pref->Flags & PREFF_GM)
set = TRUE;
break;
case 2:
if (pref->Flags & PREFF_GS)
set = TRUE;
break;
case 3:
if (pref->Flags & PREFF_XG)
set = TRUE;
break;
case 4:
if (pref->Flags & PREFF_MT32)
set = TRUE;
break;
}
if (set)
FWNewMenu[Menu_Init1+init].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Init1+init].nm_Flags &= ~(CHECKED);
}
if (pref->Flags & PREFF_TIMESTAMP)
FWNewMenu[Menu_Timestamp].nm_Flags |= CHECKED;
else
FWNewMenu[Menu_Timestamp].nm_Flags &= (~CHECKED);
if (!(glob->Menu=(struct Menu *)CreateMenus(FWNewMenu, TAG_DONE)))
{
Message("Failed to create intuition menu.",NULL);
}
else
{
LayoutMenus(glob->Menu, glob->VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE);
SetMenuStrip(glob->Window, glob->Menu);
Success = TRUE;
}
}
}
}
}
}
}
if (!Success) CloseGUI(glob, pref);
return(Success);
}
/*----------------------*/
/* Set the window title */
/*----------------------*/
void TitleWindow(struct Globals *glob, UBYTE *Text, ...)
{
va_list Arg;
va_start(Arg,Text);
VSPrintf(glob->WTitle, Text, Arg);
if (glob->OpenedScreen)
{
SetWindowTitles(glob->Window, (UBYTE*) ~0, glob->WTitle);
}
else
{
SetWindowTitles(glob->Window, glob->WTitle, (UBYTE*) ~0);
}
va_end(Arg);
}
/*---------------------------*/
/* Choose desired screenmode */
/*---------------------------*/
BOOL SelectScreenMode(struct Globals *glob, struct Prefs *pref, struct ScreenModeRequester **srq)
{
BOOL Result = FALSE;
ULONG InitialDisplayID = pref->ScreenMode;
UWORD InitialDisplayDepth = pref->ScreenDepth;
UWORD InitialDisplayWidth = pref->ScreenWidth;
UWORD InitialDisplayHeight = pref->ScreenHeight;
ULONG InitialOverscanType = pref->OverscanType;
BOOL InitialAutoScroll = pref->AutoScroll;
if (InitialDisplayID == -1L)
{
struct DimensionInfo dims;
if ((InitialDisplayID = BestModeID(
BIDTAG_NominalWidth, 320,
BIDTAG_NominalHeight, 240,
BIDTAG_Depth, 8,
TAG_DONE )) == INVALID_ID)
{
InitialDisplayID = LORES_KEY;
}
InitialOverscanType = OSCAN_TEXT;
InitialAutoScroll = TRUE;
if (GetDisplayInfoData(NULL, (UBYTE*)&dims, sizeof(dims), DTAG_DIMS, InitialDisplayID) < sizeof(dims))
{
InitialDisplayDepth = 8;
InitialDisplayWidth = 320;
InitialDisplayHeight = 240;
}
else
{
InitialDisplayDepth = dims.MaxDepth;
InitialDisplayWidth = (dims.TxtOScan.MaxX-dims.TxtOScan.MinX) + 1;
InitialDisplayHeight = (dims.TxtOScan.MaxY-dims.TxtOScan.MinY) + 1;
}
}
if (!(*srq))
{
if (!((*srq) = AllocAslRequestTags(ASL_ScreenModeRequest,
ASLSM_TitleText, "Select screen mode",
TAG_DONE)))
{
Message("Unable to allocate ASL screenmode requester.",NULL);
}
}
if (*srq)
{
Result = AslRequestTags(*srq,
ASLSM_Screen, GetScreen(glob),
ASLSM_DoWidth, TRUE,
ASLSM_DoHeight, TRUE,
ASLSM_DoDepth, TRUE,
ASLSM_DoOverscanType, TRUE,
ASLSM_DoAutoScroll, TRUE,
ASLSM_InitialDisplayID, InitialDisplayID,
ASLSM_InitialDisplayWidth, InitialDisplayWidth,
ASLSM_InitialDisplayHeight, InitialDisplayHeight,
ASLSM_InitialDisplayDepth, InitialDisplayDepth,
ASLSM_InitialOverscanType, InitialOverscanType,
ASLSM_InitialAutoScroll, InitialAutoScroll,
TAG_DONE);
if (Result)
{
pref->ScreenMode=(*srq)->sm_DisplayID;
pref->ScreenWidth=(*srq)->sm_DisplayWidth;
pref->ScreenHeight=(*srq)->sm_DisplayHeight;
pref->ScreenDepth=(*srq)->sm_DisplayDepth;
pref->OverscanType=(*srq)->sm_OverscanType;
pref->AutoScroll=(*srq)->sm_AutoScroll;
}
}
return(Result);
}
/*--------------------------------*/
/* Close the GUI (Screen, Window) */
/*--------------------------------*/
void CloseGUI(struct Globals *glob, struct Prefs *pref)
{
if (glob->Window)
{
if (glob->Menu)
{
ClearMenuStrip(glob->Window);
FreeMenus(glob->Menu);
glob->Menu = NULL;
}
FreeGraphics(glob);
((struct Process*)MyTask)->pr_WindowPtr=glob->ProcWindow;
glob->ProcWindow = NULL;
if (glob->LockedScreen)
{
pref->WinX = glob->Window->LeftEdge;
pref->WinY = glob->Window->TopEdge;
pref->WinW = glob->ww;
pref->WinH = glob->wh;
}
if (glob->AppWindow)
{
RemoveAppWindow(glob->AppWindow);
glob->AppWindow = NULL;
}
CloseWindow(glob->Window);
glob->Window = NULL;
}
if (glob->Screen)
{
if (glob->VisualInfo)
{
FreeVisualInfo(glob->VisualInfo);
glob->VisualInfo = NULL;
}
if (glob->LockedScreen)
{
UnlockPubScreen(NULL, glob->LockedScreen);
glob->LockedScreen = NULL;
}
if (glob->OpenedScreen)
{
if (CloseScreen(glob->OpenedScreen))
glob->OpenedScreen = NULL;
}
glob->Screen = NULL;
}
if (glob->AppPort)
{
struct Message *msg;
while(msg=GetMsg(glob->AppPort)) ReplyMsg(msg);
DeleteMsgPort(glob->AppPort);
glob->AppPort = NULL;
}
}
/*-------------------------*/
/* Set Busy/Normal Pointer */
/*-------------------------*/
void BusyPointer(struct Globals *glob, struct Prefs *pref)
{
SetPointer(glob->Window, WaitPointer, 16, 16, -6, 0);
}
void NormalPointer(struct Globals *glob, struct Prefs *pref)
{
if ((pref->Flags & PREFF_FULLSCREEN) &&
(pref->Flags & PREFF_HDMOUSEPTR))
SetPointer(glob->Window, NoPointer, 16, 16, -6, 0);
else
ClearPointer(glob->Window);
}
/*-----------------------------*/
/* Calculate window dimensions */
/*-----------------------------*/
BOOL WindowLayout(struct Globals *glob, WORD *minw, WORD *minh, WORD *maxw, WORD *maxh)
{
BOOL Success = TRUE;
*minw=64;
*minh=64;
*maxw=1024;
*maxh=1024;
if (glob->ww < *minw) glob->ww = *minw;
if (glob->wh < *minh) glob->wh = *minh;
if (glob->ww > *maxw) glob->ww = *maxw;
if (glob->wh > *maxh) glob->wh = *maxh;
return(Success);
}
/*-----------------*/
/* Main event loop */
/*-----------------*/
UWORD NoteArray[128];
UBYTE ChanUse[16];
void MainLoop(struct Globals *glob, struct Prefs *pref)
{
UWORD Mask = 0xffff;
UWORD i;
BOOL Active;
APTR fwdata;
ULONG signals;
ULONG gotsignals;
struct IntuiMessage *imsg;
ULONG Cl;
UWORD Co;
APTR IA;
ULONG timersig = (1L << glob->treq->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
ULONG appsig = (1L << glob->AppPort->mp_SigBit);
ULONG winsig = (1L << glob->Window->UserPort->mp_SigBit);
BOOL TimerActive;
UBYTE Err;
srand(GetTimeDelta());
for (i=0; i<256; i++)
{
randomarray33[i] = ((rand()%100)<33) ? 1 : 0;
}
Active=TRUE;
glob->GUIRefresh=FALSE;
glob->LinkRefresh=FALSE;
memset(NoteArray,0,sizeof(NoteArray));
memset(ChanUse ,0,sizeof(ChanUse ));
Watch = FALSE;
AddIntServer(INTB_VERTB, &VertBlank);
glob->ww = glob->Window->Width - glob->Window->BorderLeft-glob->Window->BorderRight ;
glob->wh = glob->Window->Height - glob->Window->BorderTop -glob->Window->BorderBottom;
if (!(fwdata = (FWDefinitions[pref->FWMode].InitFireworks)(glob, pref)))
{
Message("Unable to initialize fireworks.", "Oh no");
}
else
{
signals = winsig | appsig | timersig | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_E;
TimerActive = FALSE;
SetTaskPri(MyTask, HIGHPRI);
while(Active)
{
if (glob->GUIRefresh)
{
BOOL SaveWatch = Watch;
Watch = FALSE;
CloseGUI(glob, pref);
if (!OpenGUI(glob, pref))
{
pref->Flags &= (~PREFF_FULLSCREEN);
if (!OpenGUI(glob, pref))
{
Active = FALSE;
break;
}
}
TitleWindow(glob, "Fireworks [%s]%s", pref->Link, TimerActive ? "" : " [idle]");
winsig = (1L << glob->Window->UserPort->mp_SigBit);
signals = winsig | appsig | timersig | SIGBREAKF_CTRL_C | SIGBREAKF_CTRL_E;
if (fwdata) (FWDefinitions[pref->FWMode].RethinkWindow)(fwdata);
glob->GUIRefresh = FALSE;
Watch=SaveWatch;
}
if (glob->LinkRefresh)
{
struct MidiLink *newlink;
if (!(newlink = AddMidiLink(glob->midi, MLTYPE_Receiver,
MLINK_Name, "VU Meter Link",
MLINK_Location, pref->Link,
MLINK_EventMask, CMF_Note|CMF_Mode,
MLINK_Comment, "Fireworks [Input]",
TAG_DONE)))
{
Message("Cannot create link to MIDI interface '%s'",NULL,pref->Link);
}
else
{
RemoveMidiLink( glob->link );
FlushMidi ( glob->midi );
glob->link = newlink;
TitleWindow(glob, "Fireworks [%s]%s", pref->Link, TimerActive ? "" : " [idle]");
memset(NoteArray,0,sizeof(NoteArray));
memset(ChanUse ,0,sizeof(ChanUse ));
if (fwdata) (FWDefinitions[pref->FWMode].FreeNoteData)(fwdata);
}
glob->LinkRefresh = FALSE;
}
gotsignals = Wait(signals);
if (gotsignals & winsig)
{
while(Active && (imsg=(struct IntuiMessage*)GetMsg(glob->Window->UserPort)))
{
Cl=imsg->Class;
Co=imsg->Code;
IA=imsg->IAddress;
ReplyMsg((struct Message*)imsg);
if (Cl==IDCMP_CLOSEWINDOW)
{
if (AskAsync(glob))
{
Active = FALSE;
break;
}
else
AsyncMessage(glob,CloseTask, "Cannot quit yet. Please close all open requesters.","I will");
}
if (Cl==IDCMP_NEWSIZE)
{
BOOL SaveWatch = Watch;
Watch = FALSE;
glob->ww = pref->WinW = glob->Window->Width - glob->Window->BorderLeft-glob->Window->BorderRight ;
glob->wh = pref->WinH = glob->Window->Height - glob->Window->BorderTop -glob->Window->BorderBottom;
if (!(InitOrUpdateGraphics(glob, pref)))
{
Message("Failed to update graphics!",NULL);
}
if (glob->PaintBitMap)
{
BltBitMapRastPort(glob->PaintBitMap, 0, 0, glob->Window->RPort, 0, 0, glob->ww, glob->wh, 0xc0);
}
else EraseRect(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
if (fwdata) (FWDefinitions[pref->FWMode].RethinkWindow)(fwdata);
Watch = SaveWatch;
}
if (Cl==IDCMP_REFRESHWINDOW)
{
BeginRefresh( glob->Window );
if (glob->PaintBitMap)
{
BltBitMapRastPort(glob->PaintBitMap, 0, 0, glob->Window->RPort, 0, 0, glob->ww, glob->wh, 0xc0);
}
else EraseRect(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
EndRefresh( glob->Window, TRUE );
}
if (Cl==IDCMP_MENUPICK)
{
BOOL SaveWatch = Watch;
struct MenuItem *n;
ULONG pick;
Watch = FALSE;
while( (Co != MENUNULL) && Active)
{
n = ItemAddress( glob->Window->MenuStrip, (ULONG)Co );
pick = (ULONG) GTMENUITEM_USERDATA( n );
switch(pick)
{
case Menu_Link:
{
AsyncSelectMIDILink(glob, pref);
}
break;
case Menu_Hooks:
{
if (n->Flags & CHECKED)
pref->Flags |= PREFF_ASLHOOKS;
else
{
pref->Flags &= (~PREFF_ASLHOOKS);
/* Damn, there is no (legal) way */
/* to clear the filter function */
/* of an existing ASL requester */
if (glob->ImageFR)
{
FreeAslRequest(glob->ImageFR);
glob->ImageFR = NULL;
}
if (glob->MIDIFR)
{
FreeAslRequest(glob->MIDIFR);
glob->MIDIFR = NULL;
}
}
}
break;
case Menu_Save:
{
if ((!SavePrefs(glob, pref,"ENVARC:")) ||
(!SavePrefs(glob, pref,"ENV:")))
AsyncMessage(glob,SaveTask, "Failed to save configuration!", NULL);
}
break;
case Menu_About:
{
AsyncMessage(glob,AboutTask, "Fireworks\n© 1998 by Christian Buchner\nflowerp@eikon.e-technik.tu-muenchen.de","Cool");
}
break;
case Menu_Quit:
{
if (AskAsync(glob))
Active = FALSE;
else
AsyncMessage(glob,CloseTask, "Cannot quit yet. Please close all open requesters.","I will");
}
break;
case Menu_Kill:
{
pref->Flags &= (~PREFF_BACKDROP);
if (glob->dto)
{
SetAPen(glob->Window->RPort, glob->PenArray[Backgroundpen]);
RectFill(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
DisposeDTObject(glob->dto);
glob->dto = NULL;
if (!(InitOrUpdateGraphics(glob,pref)))
{
Message("Failed to update graphics!",NULL);
}
if (glob->PaintBitMap)
{
BltBitMapRastPort(glob->PaintBitMap, 0, 0, glob->Window->RPort, 0, 0, glob->ww, glob->wh, 0xc0);
}
else EraseRect(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
}
}
break;
case Menu_Load:
{
AsyncSelectImage(glob, pref);
}
break;
case Menu_Tile:
{
if (n->Flags & CHECKED)
pref->Flags |= PREFF_TILE;
else
pref->Flags &= (~PREFF_TILE);
if (!(InitOrUpdateGraphics(glob,pref)))
{
Message("Failed to update graphics!",NULL);
}
if (glob->PaintBitMap)
{
BltBitMapRastPort(glob->PaintBitMap, 0, 0, glob->Window->RPort, 0, 0, glob->ww, glob->wh, 0xc0);
}
else EraseRect(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
}
break;
case Menu_Screenmode:
{
AsyncSelectScreenMode(glob, pref);
}
break;
case Menu_Fullscreen:
{
if (n->Flags & CHECKED)
{
if (pref->ScreenMode == -1L)
{
n->Flags &= (~CHECKED);
AsyncSelectScreenMode(glob, pref);
}
else
{
pref->Flags |= PREFF_FULLSCREEN;
glob->GUIRefresh = TRUE;
}
}
else
{
glob->GUIRefresh = TRUE;
pref->Flags &= (~PREFF_FULLSCREEN);
}
}
break;
case Menu_Titlebar:
{
if (n->Flags & CHECKED)
{
if (!(pref->Flags & PREFF_HDTITLEBAR))
glob->GUIRefresh = TRUE;
pref->Flags |= PREFF_HDTITLEBAR;
}
else
{
if (pref->Flags & PREFF_HDTITLEBAR)
glob->GUIRefresh = TRUE;
pref->Flags &= ~(PREFF_HDTITLEBAR);
}
}
break;
case Menu_Mouse:
{
if (n->Flags & CHECKED)
{
pref->Flags |= PREFF_HDMOUSEPTR;
NormalPointer(glob, pref);
}
else
{
pref->Flags &= ~(PREFF_HDMOUSEPTR);
NormalPointer(glob, pref);
}
}
break;
case Menu_Mode1:
case Menu_Mode2:
case Menu_Mode3:
{
if (n->Flags & CHECKED)
{
UWORD NewMode = pick - Menu_Mode1;
if (NewMode != pref->FWMode)
{
if (fwdata)
{
(FWDefinitions[pref->FWMode].ExitFireworks)(fwdata);
fwdata = NULL;
}
pref->FWMode = NewMode;
if (!(fwdata = (FWDefinitions[pref->FWMode].InitFireworks)(glob, pref)))
{
Message("Unable to initialize fireworks.", "Oh no");
n->Flags &= (~CHECKED);
}
}
}
}
break;
case Menu_Sens1:
case Menu_Sens2:
case Menu_Sens3:
{
if (n->Flags & CHECKED)
{
UWORD sens = pick - Menu_Sens1 + 1;
switch(sens)
{
case 1: pref->Sensitivity=100; break;
case 2: pref->Sensitivity= 75; break;
case 3: pref->Sensitivity= 50; break;
}
}
}
break;
case Menu_Double:
{
if (n->Flags & CHECKED)
pref->Flags |= PREFF_DOUBLE;
else
pref->Flags &= (~PREFF_DOUBLE);
}
break;
case Menu_Sparks:
{
if (n->Flags & CHECKED)
pref->Flags |= PREFF_SPARKS;
else
pref->Flags &= (~PREFF_SPARKS);
}
break;
case Menu_Release:
{
memset(NoteArray,0,sizeof(NoteArray));
memset(ChanUse ,0,sizeof(ChanUse ));
if (fwdata) (FWDefinitions[pref->FWMode].TimePassed)(fwdata);
if (fwdata) (FWDefinitions[pref->FWMode].ReleaseNotes)(fwdata, 0);
}
break;
case Menu_Play:
{
AsyncSelectAndPlay(glob, pref);
};
break;
case Menu_Stop:
{
StopMIDI(glob,pref);
}
break;
case Menu_Init1:
case Menu_Init2:
case Menu_Init3:
case Menu_Init4:
case Menu_Init5:
{
if (n->Flags & CHECKED)
{
UWORD init = pick - Menu_Init1;
pref->Flags &= (~(PREFF_GM|PREFF_GS|PREFF_XG|PREFF_MT32));
switch(init)
{
case 1: pref->Flags |= PREFF_GM;
break;
case 2: pref->Flags |= PREFF_GS;
break;
case 3: pref->Flags |= PREFF_XG;
break;
case 4: pref->Flags |= PREFF_MT32;
break;
}
}
}
break;
case Menu_Timestamp:
{
if (n->Flags & CHECKED)
pref->Flags |= PREFF_TIMESTAMP;
else
pref->Flags &= (~PREFF_TIMESTAMP);
}
break;
}
Co = n->NextSelect;
}
Watch = SaveWatch;
}
}
}
if (Active && (gotsignals & SIGBREAKF_CTRL_E))
{
MidiMsg msg;
if (fwdata) (FWDefinitions[pref->FWMode].TimePassed)(fwdata);
while (GetMidi(glob->midi,&msg))
{
LONG reltime = 0;
if (pref->Flags & PREFF_TIMESTAMP)
{
reltime = HowOldIsTimestamp(msg.mm_Time);
if (reltime < 0) reltime = 0;
}
if (noteon(&msg))
{
UBYTE chn = msg.mm_Status & MS_ChanBits;
UWORD note = msg.mm_Data1;
UWORD cmsk = 1<<chn;
// if ((Mask & cmsk) && !((NoteArray[note] & Mask)))
// {
// }
if (!(NoteArray[note] & cmsk))
{
/* Channel wird benutzt */
ChanUse[chn]++;
NoteArray[note] |= cmsk;
/* Note angeschlagen */
if (fwdata) (FWDefinitions[pref->FWMode].NoteOn)(fwdata, chn, note, msg.mm_Data2, reltime);
}
}
else
{
if (noteoff(&msg))
{
UBYTE chn = msg.mm_Status & MS_ChanBits;
UWORD note = msg.mm_Data1;
UWORD cmsk = 1<<chn;
if (NoteArray[note] & cmsk)
{
/* Channel wird nicht mehr benutzt */
ChanUse[chn]--;
NoteArray[note] &= (~cmsk);
/* Note losgelassen */
if (fwdata) (FWDefinitions[pref->FWMode].NoteOff)(fwdata, chn, note, reltime);
}
// if ((Mask & cmsk) && (!(NoteArray[note] & Mask)))
// {
// }
}
else
{
if (modemsg(&msg))
{
UBYTE chn = msg.mm_Status & MS_ChanBits;
UBYTE mode = msg.mm_Data1;
UWORD note;
UWORD cmsk = 1<<chn;
if (mode == MM_AllOff)
{
for (note=0;note<128;note++)
{
if (NoteArray[note] & cmsk)
{
/* Channel wird nicht mehr benuzt */
ChanUse[chn]--;
if (fwdata) (FWDefinitions[pref->FWMode].NoteOff)(fwdata, chn, note, reltime);
NoteArray[note] &= (~cmsk);
}
// if ((Mask & cmsk) && (!(NoteArray[note] & Mask)))
// {
// }
}
}
}
}
}
}
if (Err = GetMidiErr(glob->midi))
{
if (Err & CMEF_MsgErr) AsyncMessage(glob,ErrTask, "MIDI Error: MsgErr!",NULL);
if (Err & CMEF_BufferFull) AsyncMessage(glob,ErrTask, "MIDI Error: BufferFull!",NULL);
if (Err & CMEF_SysExFull) AsyncMessage(glob,ErrTask, "MIDI Error: SysExFull!",NULL);
if (Err & CMEF_ParseMem) AsyncMessage(glob,ErrTask, "MIDI Error: ParseMem!",NULL);
if (Err & CMEF_RecvErr) AsyncMessage(glob,ErrTask, "MIDI Error: RecvErr!",NULL);
if (Err & CMEF_RecvOverflow) AsyncMessage(glob,ErrTask, "MIDI Error: RecvOverflow!",NULL);
if (Err & CMEF_SysExTooBig) AsyncMessage(glob,ErrTask, "MIDI Error: SysExTooBig!",NULL);
}
/* (re-)start timer if it isn't running */
if (!TimerActive)
{
/* but only if there is something to display */
if (fwdata) if (!(FWDefinitions[pref->FWMode].IsIdle)(fwdata))
{
glob->treq->tr_node.io_Command = TR_ADDREQUEST;
glob->treq->tr_time.tv_secs = 0;
glob->treq->tr_time.tv_micro = 1000000 / FPS;
SendIO((struct IORequest*)glob->treq);
TimerActive = TRUE;
Watch = TRUE;
TitleWindow(glob, "Fireworks [%s]", pref->Link);
}
}
}
if (Active && (gotsignals & timersig))
{
BOOL idle = TRUE;
IdleCount = 0;
if (fwdata) (FWDefinitions[pref->FWMode].TimePassed)(fwdata);
if (fwdata) idle = (FWDefinitions[pref->FWMode].IsIdle)(fwdata);
if (!idle)
{
glob->treq->tr_node.io_Command = TR_ADDREQUEST;
glob->treq->tr_time.tv_secs = 0;
glob->treq->tr_time.tv_micro = 1000000 / FPS;
SendIO((struct IORequest*)glob->treq);
}
if ((glob->BGBitMap) && (glob->PaintBitMap))
{
BltBitMapRastPort(glob->BGBitMap, 0, 0, &glob->PaintRP, 0, 0, glob->ww, glob->wh, 0xc0);
if (fwdata) (FWDefinitions[pref->FWMode].DrawFireworks)(fwdata, Mask);
BltBitMapRastPort(glob->PaintBitMap, 0, 0, glob->Window->RPort, 0, 0, glob->ww, glob->wh, 0xc0);
}
if (idle)
{
TimerActive = FALSE;
Watch = FALSE;
SetTaskPri(MyTask, HIGHPRI);
TitleWindow(glob, "Fireworks [%s] [idle]", pref->Link);
}
else
{
/* reset task priority if it has
been modified by the watchdog */
if (MyTask->tc_Node.ln_Pri != NORMPRI)
{
SetTaskPri(MyTask, NORMPRI);
}
}
}
if (Active && (gotsignals & appsig))
{
struct AppMessage *appm;
while(appm = (struct AppMessage*)GetMsg(glob->AppPort))
{
if (appm->am_Type == AMTYPE_APPWINDOW)
{
BOOL SaveWatch = Watch;
struct WBArg *arg = appm->am_ArgList;
ULONG i;
Watch = FALSE;
for (i=0 ; i < appm->am_NumArgs ; i++, arg++)
{
BOOL IsPicture = FALSE;
BOOL IsMIDI = FALSE;
BPTR OldDir;
BPTR lock;
OldDir = CurrentDir(arg->wa_Lock);
if (lock = Lock(arg->wa_Name, SHARED_LOCK))
{
struct DataType *dtn;
if (dtn = ObtainDataTypeA (DTST_FILE, (APTR) lock, NULL))
{
if (dtn->dtn_Header->dth_GroupID == GID_PICTURE)
{
if (NameFromLock(lock, pref->Image, sizeof(pref->Image)))
{
IsPicture = TRUE;
}
}
ReleaseDataType (dtn);
}
if (!IsPicture)
{
BPTR dupedlock;
BPTR file;
if (dupedlock = DupLock(lock))
{
if (file = OpenFromLock(dupedlock))
{
UBYTE header[20];
if (Read(file, header, sizeof(header)) == sizeof(header))
{
if ( ((header[0] == 'M') &&
(header[1] == 'T') &&
(header[2] == 'h') &&
(header[3] == 'd'))
||
((header[0] == 'X') &&
(header[1] == 'P') &&
(header[2] == 'K') &&
(header[3] == 'F') &&
(header[16]== 'M') &&
(header[17]== 'T') &&
(header[18]== 'h') &&
(header[19]== 'd')) )
{
if (NameFromLock(lock, pref->MIDIFile, sizeof(pref->MIDIFile)))
{
IsMIDI = TRUE;
}
}
}
Close(file);
} else UnLock(dupedlock);
}
}
UnLock(lock);
}
CurrentDir(OldDir);
if (IsPicture) LoadImage(glob, pref);
else
if (IsMIDI) PlayMIDI(glob, pref);
else
AsyncMessage(glob,DropTask, "Please drop only picture objects or MIDI files\ninto the Fireworks window.","Sorry");
}
Watch = SaveWatch;
}
ReplyMsg((struct Message*)appm);
}
}
if (gotsignals & SIGBREAKF_CTRL_C)
{
if (AskAsync(glob))
{
Active = FALSE;
Watch = FALSE;
}
else
AsyncMessage(glob,CloseTask, "Cannot quit yet. Please close all open requesters.","I will");
}
}
RemIntServer(INTB_VERTB, &VertBlank);
if (TimerActive)
{
AbortIO((struct IORequest*)glob->treq);
WaitIO((struct IORequest*)glob->treq);
}
if (fwdata)
{
(FWDefinitions[pref->FWMode].ExitFireworks)(fwdata);
fwdata = NULL;
}
}
}
/*-----------------------------------*/
/* Asynchronously select a MIDI link */
/*-----------------------------------*/
void SyncSelectMIDILink(struct Globals *glob, struct Prefs *pref, APTR UserData)
{
APTR listreq;
if (!(listreq = AllocListRequest(
LISTREQ_Screen, GetScreen(glob),
LISTREQ_TitleText, "Select input link",
TAG_DONE )))
{
Message("Couldn't allocate a list requester.",NULL);
}
else
{
if (SelectCluster( listreq, pref->Link, sizeof(pref->Link), TAG_DONE ))
{
if (strcmp((glob->link)->ml_Location->mcl_Node.ln_Name,pref->Link))
{
glob->LinkRefresh = TRUE;
Signal(MyTask, SIGBREAKF_CTRL_E); /* wake up main task */
}
}
FreeListRequest(listreq);
}
}
void AsyncSelectMIDILink(struct Globals *glob, struct Prefs *pref)
{
if (!StartAsyncTask(glob, pref, "Fireworks MIDI link selection task", LinkTask, &SyncSelectMIDILink, NULL, 0))
{
SyncSelectMIDILink(glob, pref, NULL);
}
}
/*------------------------------------*/
/* Asynchronously select a screenmode */
/*------------------------------------*/
void SyncSelectScreenMode(struct Globals *glob, struct Prefs *pref, APTR UserData)
{
if (SelectScreenMode(glob, pref, &glob->ScreenModeRQ))
{
pref->Flags |= PREFF_FULLSCREEN;
glob->GUIRefresh = TRUE;
Signal(MyTask, SIGBREAKF_CTRL_E); /* wake up main task */
}
}
void AsyncSelectScreenMode(struct Globals *glob, struct Prefs *pref)
{
if (!StartAsyncTask(glob, pref, "Fireworks ScreenMode selection task", ScreenTask, &SyncSelectScreenMode, NULL, 0))
{
SyncSelectScreenMode(glob, pref, NULL);
}
}
/*---------------------------------------------------*/
/* Asynchronously select an image and notify program */
/*---------------------------------------------------*/
void AsyncSelectImageFunction(struct Globals *glob, struct Prefs *pref, APTR UserData)
{
BOOL Success = FALSE;
UBYTE *filename;
UBYTE *ptr, save;
BPTR dirlock;
ULONG msglen;
struct AppMessage *appm,*got;
struct WBArg *argument;
UBYTE *name;
struct Process *MyProc = (struct Process*)FindTask(NULL);
if (SelectImage(glob, pref, &glob->ImageFR, pref->Image, sizeof(pref->Image)))
{
pref->Flags |= PREFF_BACKDROP;
/* now fake an AppMessage to notify program of image change */
filename = FilePart(pref->Image);
ptr = PathPart(pref->Image);
save = *ptr;
*ptr = 0;
if (dirlock = Lock(pref->Image, SHARED_LOCK))
{
*ptr = save;
msglen = sizeof(struct AppMessage)+sizeof(struct WBArg)+strlen(filename)+1;
if (appm = AllocVec(msglen,MEMF_ANY|MEMF_CLEAR))
{
argument = (struct WBArg*)(appm+1);
name = (UBYTE*)(argument+1);
appm->am_Message.mn_Length = msglen;
appm->am_Message.mn_ReplyPort = &MyProc->pr_MsgPort;
appm->am_Type = AMTYPE_APPWINDOW;
appm->am_NumArgs = 1;
appm->am_ArgList = argument;
argument->wa_Lock = dirlock;
argument->wa_Name = name;
strcpy(name, filename);
PutMsg(glob->AppPort, (struct Message*)appm);
got = NULL;
while (got != appm)
{
WaitPort(&MyProc->pr_MsgPort);
got = (struct AppMessage*)GetMsg(&MyProc->pr_MsgPort);
}
FreeVec(appm);
Success = TRUE;
}
UnLock(dirlock);
}
else *ptr = save;
}
}
void AsyncSelectImage(struct Globals *glob, struct Prefs *pref)
{
if (!(StartAsyncTask(glob, pref, "Fireworks Backdrop selection task", ImageTask, &AsyncSelectImageFunction, NULL, 0)))
{
if (SelectImage(glob, pref, &glob->ImageFR, pref->Image, sizeof(pref->Image)))
{
pref->Flags |= PREFF_BACKDROP;
LoadImage(glob,pref);
}
}
}
/*------------------------------------------*/
/* Asynchronously select & play a MIDI file */
/*------------------------------------------*/
void SelectAndPlay(struct Globals *glob, struct Prefs *pref, APTR UserData)
{
if (SelectMIDI(glob, pref, &glob->MIDIFR, pref->MIDIFile,sizeof(pref->MIDIFile)))
{
PlayMIDI(glob,pref);
}
}
void AsyncSelectAndPlay(struct Globals *glob, struct Prefs *pref)
{
if (!StartAsyncTask(glob, pref, "Fireworks MIDI file selection task", PlayTask, &SelectAndPlay, NULL, 0))
{
SelectAndPlay(glob, pref, NULL);
}
}
/*----------------------------*/
/* Initialize/Update Graphics */
/*----------------------------*/
BOOL InitOrUpdateGraphics(struct Globals *glob, struct Prefs *pref)
{
BOOL Success = FALSE;
if (glob->PaintLayer)
{
DeleteLayer(0, glob->PaintLayer);
glob->PaintLayer = NULL;
}
if (glob->BGBitMap)
{
FreeBitMap(glob->BGBitMap);
glob->BGBitMap = NULL;
}
if (glob->PaintBitMap)
{
FreeBitMap(glob->PaintBitMap);
glob->PaintBitMap = NULL;
}
if (glob->Window)
{
UWORD i;
struct ColorMap *cmap = glob->Window->WScreen->ViewPort.ColorMap;
struct BitMap *friend = glob->Window->RPort->BitMap;
ULONG depth = GetBitMapAttr(friend, BMA_DEPTH);
ULONG flags = GetBitMapAttr(friend, BMA_FLAGS);
struct RastPort BGRP;
BusyPointer(glob, pref);
for (i = 0 ; i < NUMPENS ; i++)
{
if (glob->PenArray[i] == -1L)
{
glob->PenArray[i] = ObtainBestPen(
cmap,
(ULONG)PenColors[i][0]<<24,
(ULONG)PenColors[i][1]<<24,
(ULONG)PenColors[i][2]<<24,
OBP_Precision, PRECISION_IMAGE,
TAG_DONE );
}
}
/* Cybergraphics kludge */
if ( !(flags & BMF_STANDARD) ) flags |= BMF_MINPLANES;
if (glob->BGBitMap = AllocBitMap(glob->ww, glob->wh, depth, flags | BMF_CLEAR, friend))
{
struct BitMap *ImageBM = NULL;
struct BitMapHeader *bmh = NULL;
InitRastPort(&BGRP);
BGRP.BitMap = glob->BGBitMap;
SetAPen(&BGRP, glob->PenArray[Backgroundpen]);
if (glob->dto)
{
GetDTAttrs(glob->dto, PDTA_DestBitMap, &ImageBM,
PDTA_BitMapHeader, &bmh,
TAG_DONE);
}
if ((!ImageBM) || (!bmh))
{
RectFill(&BGRP, 0, 0, (glob->ww)-1, (glob->wh)-1);
}
else
{
UWORD width = bmh->bmh_Width;
UWORD height= bmh->bmh_Height;
if (pref->Flags & PREFF_TILE)
{
UWORD x,y;
UWORD dow, doh;
for (y = 0 ; y < glob->wh ; y += doh)
{
doh = height;
if (y + doh > glob->wh)
doh = glob->wh - y;
for (x = 0 ; x < glob->ww ; x += dow)
{
dow = width;
if (x + dow > glob->ww)
dow = glob->ww - x;
BltBitMap(ImageBM, 0, 0, glob->BGBitMap, x, y, dow, doh, 0xc0, 0xff,NULL);
}
}
}
else
{
struct BitScaleArgs bsa;
bsa.bsa_SrcX = 0;
bsa.bsa_SrcY = 0;
bsa.bsa_SrcWidth = width;
bsa.bsa_SrcHeight = height;
bsa.bsa_XSrcFactor = width;
bsa.bsa_YSrcFactor = height;
bsa.bsa_DestX = 0;
bsa.bsa_DestY = 0;
bsa.bsa_DestWidth = glob->ww;
bsa.bsa_DestHeight = glob->wh;
bsa.bsa_XDestFactor = glob->ww;
bsa.bsa_YDestFactor = glob->wh;
bsa.bsa_SrcBitMap = ImageBM;
bsa.bsa_DestBitMap = glob->BGBitMap;
bsa.bsa_Flags = 0;
bsa.bsa_XDDA = 0;
bsa.bsa_YDDA = 0;
bsa.bsa_Reserved1 = 0;
bsa.bsa_Reserved2 = 0;
BitMapScale(&bsa);
}
}
if ( glob->PaintBitMap = AllocBitMap(glob->ww, glob->wh, depth, flags | BMF_CLEAR, friend))
{
InitRastPort(&glob->PaintRP);
glob->PaintRP.BitMap = glob->PaintBitMap;
if (!(glob->LInfo)) glob->LInfo = NewLayerInfo();
if (glob->LInfo)
{
if (glob->PaintLayer = CreateUpfrontLayer(glob->LInfo, glob->PaintBitMap, 0, 0, (glob->ww)-1, (glob->wh)-1, LAYERSMART, NULL))
{
glob->PaintRP.Layer = glob->PaintLayer;
BltBitMapRastPort(glob->BGBitMap, 0, 0, &glob->PaintRP, 0, 0, glob->ww, glob->wh, 0xc0);
Success = TRUE;
}
}
}
}
NormalPointer(glob,pref);
}
if (!Success)
{
if (glob->PaintLayer)
{
DeleteLayer(0, glob->PaintLayer);
glob->PaintLayer = NULL;
}
if (glob->BGBitMap)
{
FreeBitMap(glob->BGBitMap);
glob->BGBitMap = NULL;
}
if (glob->PaintBitMap)
{
FreeBitMap(glob->PaintBitMap);
glob->PaintBitMap = NULL;
}
}
return(Success);
}
/*-------------------------*/
/* Free allocated Graphics */
/*-------------------------*/
void FreeGraphics(struct Globals *glob)
{
UWORD i;
if (glob->dto)
{
SetAPen(glob->Window->RPort, glob->PenArray[Backgroundpen]);
RectFill(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
DisposeDTObject(glob->dto);
glob->dto = NULL;
}
if (glob->PaintLayer)
{
DeleteLayer(0, glob->PaintLayer);
glob->PaintLayer = NULL;
}
if (glob->LInfo)
{
DisposeLayerInfo(glob->LInfo);
glob->LInfo = NULL;
}
if (glob->BGBitMap)
{
FreeBitMap(glob->BGBitMap);
glob->BGBitMap = NULL;
}
if (glob->PaintBitMap)
{
FreeBitMap(glob->PaintBitMap);
glob->PaintBitMap = NULL;
}
if (glob->Window)
{
struct ColorMap *cmap = glob->Window->WScreen->ViewPort.ColorMap;
for (i = 0 ; i < NUMPENS ; i++)
{
if (glob->PenArray[i] != -1L)
{
ReleasePen( cmap, glob->PenArray[i] );
glob->PenArray[i] = -1L;
}
}
}
}
/*--------------------*/
/* Get current screen */
/*--------------------*/
struct Screen *GetScreen(struct Globals *glob)
{
struct Window *win;
struct Screen *scr = NULL;
if (MyTask)
{
win = ((struct Window*)((struct Process*)MyTask)->pr_WindowPtr);
if (win) scr = win->WScreen;
}
if (!scr)
{
if (glob->LockedScreen)
scr = glob->LockedScreen;
else
scr = glob->LockedScreen = LockPubScreen(NULL);
}
return(scr);
}
/*----------------------------------*/
/* Load image using datatypes (V43) */
/*----------------------------------*/
void LoadImage(struct Globals *glob, struct Prefs *pref)
{
if (glob->dto)
{
SetAPen(glob->Window->RPort, glob->PenArray[Backgroundpen]);
RectFill(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
DisposeDTObject(glob->dto);
glob->dto = NULL;
}
BusyPointer(glob, pref);
if (glob->dto = (Object *) NewDTObject(pref->Image,
DTA_GroupID, GID_PICTURE,
PDTA_DestMode, MODE_V43,
PDTA_Remap, TRUE,
PDTA_Screen, GetScreen(glob),
PDTA_FreeSourceBitMap, TRUE,
TAG_DONE) )
{
SetDTAttrs(glob->dto, NULL, NULL,
PDTA_Remap, TRUE,
PDTA_Screen, GetScreen(glob),
PDTA_FreeSourceBitMap, TRUE,
PDTA_UseFriendBitMap, TRUE,
TAG_DONE );
DoMethod( glob->dto, DTM_PROCLAYOUT, NULL, TRUE );
}
else
{
LONG errnum=IoErr();
UBYTE errstring[80];
if (errnum>=DTERROR_UNKNOWN_DATATYPE)
{
SPrintf(errstring,GetDTString(errnum),pref->Image);
}
else
{
Fault(errnum,NULL,errstring,sizeof(errstring));
}
Message("%s: %s",NULL,pref->Image,errstring);
}
if (!(InitOrUpdateGraphics(glob,pref)))
{
Message("Failed to update graphics!",NULL);
}
if (glob->PaintBitMap)
{
BltBitMapRastPort(glob->PaintBitMap, 0, 0, glob->Window->RPort, 0, 0, glob->ww, glob->wh, 0xc0);
}
else EraseRect(glob->Window->RPort, 0, 0, (glob->ww)-1, (glob->wh)-1);
NormalPointer(glob, pref);
}
/*-------------------------------------------*/
/* Datatypes hook function for ASL requester */
/*-------------------------------------------*/
ULONG __asm __saveds Filter (register __a0 struct Hook *h, register __a2 struct FileRequester *fr, register __a1 struct AnchorPath *ap)
{
struct DataType *dtn;
ULONG use = FALSE;
UBYTE buffer[300];
BPTR lock;
if (ap->ap_Info.fib_DirEntryType > 0)
{
use = TRUE;
}
else
{
strncpy (buffer, fr->fr_Drawer, sizeof (buffer));
AddPart (buffer, ap->ap_Info.fib_FileName, sizeof (buffer));
if (lock = Lock (buffer, ACCESS_READ))
{
if (dtn = ObtainDataTypeA (DTST_FILE, (APTR) lock, NULL))
{
if (dtn->dtn_Header->dth_GroupID == GID_PICTURE)
use = TRUE;
ReleaseDataType (dtn);
}
UnLock (lock);
}
}
return (use);
}
/*--------------------------------------*/
/* Select image to load (ASL requester) */
/*--------------------------------------*/
BOOL SelectImage(struct Globals *glob, struct Prefs *pref, struct FileRequester **fr, UBYTE *filebuffer, ULONG MaxSize)
{
BOOL Selected=FALSE;
UBYTE initialdrawer[200];
UBYTE initialfile [40];
struct Hook filter = {NULL, NULL, NULL, NULL, NULL};
UBYTE save, *ptr;
filter.h_Entry = (HOOKFUNC)Filter;
ptr = PathPart(filebuffer);
save = *ptr; *ptr = 0;
strncpy (initialdrawer,filebuffer,sizeof(initialdrawer));
initialdrawer[sizeof(initialdrawer)-1]=0;
*ptr = save;
strncpy (initialfile, FilePart(filebuffer), sizeof(initialfile));
initialfile[sizeof(initialfile)-1]=0;
if (!(*fr))
{
if(!((*fr) = AllocAslRequestTags (ASL_FileRequest,
ASLFR_TitleText, "Select Picture to load",
ASLFR_PositiveText, "Load",
ASLFR_RejectIcons, TRUE,
ASLFR_DoPatterns, TRUE,
TAG_DONE)))
{
Message("Couldn't allocate asl requester",NULL);
}
}
if (*fr)
{
Selected = AslRequestTags(*fr,
ASLFR_Screen, GetScreen(glob),
ASLFR_InitialDrawer, initialdrawer,
ASLFR_InitialFile, initialfile,
(pref->Flags & PREFF_ASLHOOKS) ? ASLFR_FilterFunc : TAG_IGNORE, &filter,
TAG_DONE);
if (Selected)
{
strncpy (filebuffer, (*fr)->fr_Drawer, MaxSize);
AddPart (filebuffer, (*fr)->fr_File, MaxSize);
}
}
return(Selected);
}
/*--------------------------------------*/
/* MIDI hook function for ASL requester */
/*--------------------------------------*/
ULONG __asm __saveds MIDIFilter (register __a0 struct Hook *h, register __a2 struct FileRequester *fr, register __a1 struct AnchorPath *ap)
{
ULONG use = FALSE;
UBYTE buffer[300];
UBYTE header[20];
BPTR file;
if (ap->ap_Info.fib_DirEntryType >0)
use = TRUE;
else
{
strncpy (buffer, fr->fr_Drawer, sizeof (buffer));
AddPart (buffer, ap->ap_Info.fib_FileName, sizeof (buffer));
if (file = Open (buffer, MODE_OLDFILE))
{
if (Read(file,header,sizeof(header)) == sizeof(header))
{
if ( ((header[0] == 'M') &&
(header[1] == 'T') &&
(header[2] == 'h') &&
(header[3] == 'd'))
||
((header[0] == 'X') &&
(header[1] == 'P') &&
(header[2] == 'K') &&
(header[3] == 'F') &&
(header[16]== 'M') &&
(header[17]== 'T') &&
(header[18]== 'h') &&
(header[19]== 'd')) )
{
use = TRUE;
}
}
Close (file);
}
}
return(use);
}
/*----------------------------*/
/* Select a MIDI file to load */
/*----------------------------*/
BOOL SelectMIDI(struct Globals *glob, struct Prefs *pref, struct FileRequester **fr, UBYTE *filebuffer, ULONG MaxSize)
{
BOOL Selected=FALSE;
UBYTE initialdrawer[200];
UBYTE initialfile [40];
struct Hook filter = {NULL, NULL, NULL, NULL, NULL};
UBYTE save, *ptr;
filter.h_Entry = (HOOKFUNC)MIDIFilter;
ptr = PathPart(filebuffer);
save = *ptr; *ptr = 0;
strncpy (initialdrawer,filebuffer,sizeof(initialdrawer));
initialdrawer[sizeof(initialdrawer)-1]=0;
*ptr = save;
strncpy (initialfile, FilePart(filebuffer), sizeof(initialfile));
initialfile[sizeof(initialfile)-1]=0;
if (!(*fr))
{
if (!((*fr) = AllocAslRequestTags (ASL_FileRequest,
ASLFR_TitleText, "Select MIDI file to play",
ASLFR_PositiveText, "Play",
ASLFR_RejectIcons, TRUE,
ASLFR_DoPatterns, TRUE,
TAG_DONE)))
{
Message("Couldn't allocate asl requester",NULL);
}
}
if (*fr)
{
Selected = AslRequestTags(*fr,
ASLFR_Screen, GetScreen(glob),
ASLFR_InitialDrawer, initialdrawer,
ASLFR_InitialFile, initialfile,
(pref->Flags & PREFF_ASLHOOKS) ? ASLFR_FilterFunc : TAG_IGNORE, &filter,
TAG_DONE);
if (Selected)
{
strncpy (filebuffer, (*fr)->fr_Drawer, MaxSize);
AddPart (filebuffer, (*fr)->fr_File, MaxSize);
}
}
return(Selected);
}
/*-----------------------------------*/
/* Invoke PlayMF to play a MIDI file */
/*-----------------------------------*/
void PlayMIDI(struct Globals *glob, struct Prefs *pref)
{
UBYTE CommandString[300];
UBYTE *init = "";
BPTR lock;
BPTR out;
BOOL CloseOut = FALSE;
if (pref->Flags & PREFF_GM) init = "GM";
if (pref->Flags & PREFF_GS) init = "GS";
if (pref->Flags & PREFF_XG) init = "XG";
if (pref->Flags & PREFF_MT32) init = "MT32";
if (lock = Lock("/PlayMF/PlayMF", SHARED_LOCK ))
{
UnLock(lock);
SPrintf(CommandString,"Run >NIL: /PlayMF/PlayMF \42%s\42 LINK=\42%s\42 %s REPLACE", pref->MIDIFile, pref->Link, init);
}
else
{
SPrintf(CommandString,"Run >NIL: PlayMF \42%s\42 LINK=\42%s\42 %s REPLACE", pref->MIDIFile, pref->Link, init);
}
if ((out = Output()) == NULL)
{
if (out = Open("NIL:", MODE_OLDFILE)) CloseOut = TRUE;
}
if (!Execute( CommandString, NULL, out))
{
AsyncMessage(glob,LaunchTask, "Unable to launch PlayMF.\nPlease make sure it is located somewhere in your search path.","Damn");
}
if (CloseOut) Close(out);
}
/*--------------------------*/
/* Stop PlayMF (if running) */
/*--------------------------*/
void StopMIDI(struct Globals *glob, struct Prefs *pref)
{
APTR lock;
struct MidiCluster *clust;
struct MidiLink *ml;
if (lock = LockCAMD(CD_Linkages))
{
if (clust = FindCluster(pref->Link))
{
for (ml = (struct MidiLink*)clust->mcl_Senders.lh_Head ;
ml->ml_Node.ln_Succ ;
ml = (struct MidiLink*)ml->ml_Node.ln_Succ )
{
if (!stricmp("PlayMF Player", ml->ml_MidiNode->mi_Node.ln_Name))
{
Signal(ml->ml_MidiNode->mi_SigTask, SIGBREAKF_CTRL_C);
break;
}
}
}
UnlockCAMD(lock);
}
}