home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 1: Collection A
/
17Bit_Collection_A.iso
/
files
/
1063.dms
/
1063.adf
/
DFC
/
dfc5.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-07-25
|
11KB
|
396 lines
#include "DFC5.h"
#define ESC 0x1B
#define RETURN 0x0D
/*
* Mask for EnableGadgets
*/
#define ALLMASK 0x1FFFF
#define COPYMASK 0x03D00
#define AGAINMASK 0x03D00
#define FORMATMASK 0x03700
#define ALLMSGS 0x3F
static char Key2Gadget[39] = { DF0S, DF1S, DF2S, DF3S, DF0D, DF1D, DF2D, DF3D, -1, -1, -1, -1, -1, -1, -1, -1, -1, AUTO, BUFFER, -1, DATE, -1, FORMAT, GO, -1, -1, -1, -1, -1, -1, FFS, -1, -1, -1, REPEAT, STOP, TALK, -1, VERIFY };
static char NoBufferMsg[] = "Sorry, I need a buffer.";
static char NoDiskMsg[] = "Can't open disk.";
static char NoDestMsg[] = "Sorry, I need a destination.";
static char NoSourceMsg[] = "Sorry, I need a source.";
static char NoDiskPresentMsg[] = "No disk in unit x.";
static char WriteProtectedMsg[] = "Disk in unit x is write protected.";
static char GfxName[] = "graphics.library";
extern struct MsgPort *MainPort;
static struct Window *Window;
static char *FormatBuffer, MsgLocked[6],
Source = -1, Dest, ActualSource, ActualDest,
Verify=1, Buffer, BufferUsed, BufferTrack,
Date=1, UseFFS, Fuga, Copying, Formatting,
Passes = 1, CurrentPass, CurrentStartTrack,
CurrentEndTrack, Track, TracksPerPass = 80;
/*
* This routine sends an internal message with given parameters and locks it.
*/
void SendAndLockMsg(int Unit, int Action, int n) {
SendMsg(Unit, Action, n);
MsgLocked[Unit] = 1;
}
/*
* The same, but the message is simply re-sent (for retrying errors).
*/
void ReSendAndLockMsg(struct IMsg *Message) {
SendAndLockMsg(Message->im_ID, Message->im_Action, Message->im_n);
}
/*
* Check if units in the Mask have locked msgs.
*/
int NoLockedMsgs(int Mask) {
register int i;
for(i=0; i<6; i++) if (MsgLocked[i] && (DEST(i) & Mask)) return(FALSE);
return(TRUE);
}
/*
* Here we stop any operation. If we weren't copying, and the buffer is on,
* we wipe the progress bar and reset the pass counter.
*/
void Stop(void) {
if (Copying) {
if (Copying == 'G' && Buffer)
if (--CurrentPass<0) CurrentPass = Passes-1;
Copying = 0;
Track = CurrentEndTrack-1;
Beep(2400);
}
else {
CurrentPass = Passes-1;
if (Buffer) WipeProgress(Window, 0);
}
}
/*
* Here we check if some fatal error was encountered.
*/
int FatalErrors(struct IMsg *Message) {
if (Message->im_RC == NO_DISK) {
NoDiskPresentMsg[16] = 48+Message->im_ID;
Acknowledge(NoDiskPresentMsg);
return(1);
}
if (Message->im_RC == WRITE_PROTECTED) {
WriteProtectedMsg[13] = 48+Message->im_ID;
Acknowledge(WriteProtectedMsg);
return(1);
}
return(0);
}
/*
* The big thing!
* Apart from the open-all-stuff/close-all-stuff parts, this is simply a
* preposterously huge event loop.
*/
void _main(void) {
register int i;
register char *b;
register struct Gadget *G;
struct IMsg *Message;
struct IntuiMessage *Msg;
int Op, Class, Code;
if ((GfxBase = (void *)OpenLibrary(GfxName,36))==NULL) {
if ((GfxBase = (void *)OpenLibrary(GfxName,33))==NULL) goto GameOver;
ReverseBorderColors();
}
if (!SetUpPorts() ||
(IntuitionBase = (void *)OpenLibrary("intuition.library",33))==NULL ||
(Window = SetUpWindow())==NULL)
goto GameOver;
SetUpAudio();
FOREVER {
do {
Msg = (void *)GetMsg(Window->UserPort);
Message = (void *)GetMsg(MainPort);
if (Msg) {
Code = Msg->Code ;
Class = Msg->Class;
G = (struct Gadget *)(Msg->IAddress);
ReplyMsg((void *)Msg) ;
switch(Class) {
case CLOSEWINDOW: Fuga = 1;
break;
case GADGETUP:
case GADGETDOWN:
case VANILLAKEY:
if (Class == VANILLAKEY) {
Op = toupper(Code);
if (Op>='0' && Op<='V' && Key2Gadget[Op]>=0) G = GAddr(Key2Gadget[Op-48]);
else G = NULL;
}
else Op = G->GadgetID;
switch(Op) {
case RETURN:
Op = Buffer ? 'R' : 'G';
case 'F':
case 'R':
case 'G': if (Copying || !NoLockedMsgs(ALLMSGS) || (Op == 'F' && !(FormatBuffer = AllocMem(TRACKSIZE, MEMF_PUBLIC)))) break;
if (Op == 'G' && Source<0) {
Acknowledge(NoSourceMsg);
break;
}
if (((Op == 'G' && INDEST(Source)) || Op == 'R') && !Buffer) {
Acknowledge(NoBufferMsg);
break;
}
if ((Op == 'R' || Op == 'F' || (Op == 'G' && !Buffer)) && !Dest) {
Acknowledge(NoDestMsg);
break;
}
ActualDest = Dest;
switch(Copying = Op) {
case 'G':
EnableGadgets(Window, COPYMASK);
ActualSource = Source;
if (Buffer) ActualDest = DEST(4);
if (++CurrentPass == Passes) CurrentPass = 0;
break;
case 'R':
EnableGadgets(Window, AGAINMASK);
ActualSource = 4;
break;
case 'F':
EnableGadgets(Window, FORMATMASK);
ActualSource = 5;
break;
}
if (Formatting = (Copying == 'F')) {
CurrentStartTrack = 79;
CurrentEndTrack = 0;
}
else {
CurrentStartTrack = 79-CurrentPass*TracksPerPass;
CurrentEndTrack = max(0, CurrentStartTrack-TracksPerPass+1);
}
Track = CurrentStartTrack;
WipeProgress(Window, 79-CurrentStartTrack);
for(i=0; i<5; i++) if (INACTUALDEST(i) || i == ActualSource) SendAndLockMsg(i, INIT, i == ActualSource && Date && !Formatting && CurrentPass == 0 ? -1 : CurrentStartTrack);
BufferUsed = DEST(ActualSource);
break;
case 'S': Stop();
break;
case ESC:
case 'Q': Fuga = 1;
break;
case 'B':
case 'V':
case 'D':
case 'A':
case 'N':
case 'T': if (!G) break;
if (Class == VANILLAKEY) ToggleGadget(Window, G);
i = ((G->Flags & SELECTED) != 0);
switch(Op) {
case 'V': Verify = i;
break;
case 'D': Date = i;
break;
case 'A': break;
case 'N': UseFFS = i;
break;
case 'T': if (i) {
if (!OpenVoice()) SelectGadget(Window, G, FALSE);
}
else CloseVoice();
break;
case 'B': if (i) {
if (Passes = OpenDiskTask(4)) {
Buffer = 1;
}
else {
SelectGadget(Window, G, FALSE);
Acknowledge("Not enough memory.");
}
}
else {
CloseDiskTask(4);
Buffer = 0;
}
if (!Buffer) {
Passes = 1;
}
TracksPerPass = 80/Passes+(Passes==3);
CurrentPass = Passes-1;
break;
}
break;
case '0':
case '1':
case '2':
case '3': Op -= '0';
if (!G) break;
if (Class == VANILLAKEY) ToggleGadget(Window, G);
if ((i = (G->Flags & SELECTED)) && OpenDiskTask(Op)) {
if (Source == Op) break;
if (Source>=0) {
SelectGadget(Window, GAddr(DF0S)+Source, FALSE);
if (!INDEST(Source)) CloseDiskTask(Source);
}
Source = Op;
}
else {
SelectGadget(Window, G, FALSE);
if (i) Acknowledge(NoDiskMsg);
if (!INDEST(Op)) CloseDiskTask(Op);
if (Op == Source) Source = -1;
}
break;
case '4':
case '5':
case '6':
case '7': Op -= '4';
if (!G) break;
if (Class == VANILLAKEY) ToggleGadget(Window, G);
if ((i = (G->Flags & SELECTED)) && OpenDiskTask(Op)) Dest |= DEST(Op);
else {
Dest &= ~DEST(Op);
SelectGadget(Window, G, FALSE);
if (i) Acknowledge(NoDiskMsg);
if (Op != Source) CloseDiskTask(Op);
}
break;
}
break;
}
}
if (Message) {
MsgLocked[Message->im_ID] = 0;
switch(Message->im_Action) {
case INIT: if (Message->im_ID == ActualSource && Message->im_RC == NOT_DOS) Acknowledge("This is not a DOS disk.");
break;
case READ_TRACK:
if (Copying && Message->im_RC == READ_ERROR && ProblemsWithUnit("Read", Message->im_ID, Message->im_n)) {
ReSendAndLockMsg(Message);
break;
}
if (FatalErrors(Message)) Stop();
b = Message->im_p;
BufferTrack = Message->im_n;
BufferUsed = ActualDest;
if (Formatting && Message->im_n>=0) MakeFormatData(Message->im_n, b = FormatBuffer, UseFFS);
break;
case WRITE_TRACK:
case WRITE_AND_VERIFY_TRACK:
if (Copying &&
((Message->im_RC == WRITE_ERROR && ProblemsWithUnit("Write", Message->im_ID, Message->im_n)) ||
(Message->im_RC == VERIFY_ERROR && ProblemsWithUnit("Verify", Message->im_ID, Message->im_n)))) {
ReSendAndLockMsg(Message);
break;
}
if (FatalErrors(Message)) Stop();
break;
case STOP_MOTOR: if (Message->im_ID == ActualSource) {
BufferUsed = ActualDest;
BufferTrack = CurrentEndTrack-1;
}
else if (NoLockedMsgs(ActualDest)) {
EnableGadgets(Window, ALLMASK);
UpdateProgress(Window);
if (FormatBuffer) {
FreeMem(FormatBuffer, TRACKSIZE);
FormatBuffer = NULL;
}
Copying = 0;
}
break;
}
if (NoLockedMsgs(ActualDest))
for(i=0; i<5; i++)
if (DEST(i) & BufferUsed & ActualDest) {
BufferUsed &= ~DEST(i);
if ((Date || Formatting) && BufferTrack==40) UpdateRootBlock(b);
CopyBuffer(b, i, BufferTrack % TracksPerPass);
SendAndLockMsg(i, (Copying && BufferTrack>=CurrentEndTrack) ? (Verify ? WRITE_AND_VERIFY_TRACK : WRITE_TRACK) : STOP_MOTOR, BufferTrack);
}
if (!BufferUsed) {
if (Copying && BufferTrack>=CurrentEndTrack) DrawProgress(Window, 79-BufferTrack, Buffer && Copying == 'G' ? 1 : 3);
BufferUsed = DEST(ActualSource);
if (BufferTrack == CurrentEndTrack+4) Beep(3000);
if (Copying && BufferTrack == CurrentEndTrack-1) {
Beep(4000);
if (!Buffer || Formatting) Say("Operation completed.");
else Say("Pass completed.");
}
}
if (!MsgLocked[ActualSource] && (BufferUsed & DEST(ActualSource)) && Track >= CurrentEndTrack-1) {
SendAndLockMsg(ActualSource, (Copying && Track>=CurrentEndTrack) ? READ_TRACK : STOP_MOTOR, Track--);
}
}
} while(Msg || Message);
if (Fuga && NoLockedMsgs(ALLMSGS)) break;
Wait(1 << Window->UserPort->mp_SigBit | 1 << MainPort->mp_SigBit);
}
GameOver:
if (Window) CloseWindow(Window);
if (IntuitionBase) CloseLibrary((void *)IntuitionBase);
if (GfxBase) CloseLibrary((void *)GfxBase);
for(i=0; i<5; i++) CloseDiskTask(i);
CloseAudio();
CloseVoice();
ClosePorts();
}