home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
424.lha
/
LoadImage_v1.11
/
Cycling.c
< prev
next >
Wrap
Text File
|
1990-09-26
|
8KB
|
424 lines
/* $Revision Header * Header built automatically - do not edit! *************
*
* (C) Copyright 1990 by MXM
*
* Name .....: Cycling.c
* Created ..: Saturday 23-Sep-90 12:30
* Revision .: 2
*
* Date Author Comment
* ========= ======== ====================
* 11-May-90 Olsen Rework for Aztec 5.0 release
* 23-Sep-89 Olsen Created this file!
*
* $Revision Header *********************************************************
*
* This file contains subroutines handling the colour cycling employed
* by LoadImage.c
*
***************************************************************************/
/* LoadCycleRange needs these macros. */
#define CRNG_NORATE (36) /* Don't cycle this range. */
#define CRNG_ACTIVE (1 << 0) /* This range is active. */
#define CRNG_REVERSE (1 << 1) /* This range is cycling backwards. */
/* The following values are to control the interrupt code. */
#define CY_CYCL (0) /* Keep on cycling. */
#define CY_WAIT (1) /* Don't cycle, wait for startup message. */
/* CycleCode needs this data, InitCycleCode prepares it. */
static struct ViewPort *VPort; /* Where to cycle. */
static struct Interrupt *VBlank; /* The Cycling-interrupt. */
static CRange *Range; /* The cycling-ranges. */
static LONG RangeNum; /* The number of ranges. */
static UWORD ColMap[32]; /* The colourmap. */
static LONG ColNum; /* The number of colours. */
static SHORT TicksPassed[16]; /* Event counter for ranges. */
static UWORD TempCol; /* Temporary colour buffer. */
static UWORD UndoBuffer[32]; /* Original palette buffer. */
static SHORT WeAreWaiting; /* CycleCode is waiting. */
static SHORT Command; /* What is the CycleCode up to do? */
static LONG CodeRun = FALSE; /* Is the CycleCode already running? */
/* CycleCode() :
*
* CycleCode is the 'C' cycling routine. It runs as an
* interrupt server to save task time.
*/
static LONG
CycleCode()
{
SHORT i,j; /* Loop counter. */
int_start();
/* Are we to wait? */
if(Command == CY_WAIT)
{
/* Restore the original palette. */
if(!WeAreWaiting)
LoadRGB4(VPort,UndoBuffer,ColNum);
WeAreWaiting = TRUE;
int_end();
/* Don't continue to cycle. */
return(0);
}
/* We aren't waiting any more. */
if(WeAreWaiting)
{
/* Re-initialize the palette. */
for(i = 0 ; i < ColNum ; i++)
ColMap[i] = UndoBuffer[i];
/* Reset event counters. */
for(i = 0 ; i < RangeNum ; i++)
TicksPassed[i] = 0;
WeAreWaiting = FALSE;
}
/* Now handle the cycle ranges. */
for(i = 0 ; i < RangeNum ; i++)
{
/* Increment event counter. */
TicksPassed[i]++;
/* Is this one up to cycle next? */
if(TicksPassed[i] == Range[i] . rate)
{
/* Reset event counter for this range. */
TicksPassed[i] = 0;
/* Is this range active? */
if(!(Range[i] . active & CRNG_ACTIVE))
continue;
/* Cycling backwards? */
if(Range[i] . active & CRNG_REVERSE)
{
/* Move the colours. */
TempCol = ColMap[Range[i] . low];
for(j = Range[i] . low ; j < Range[i] . high ; j++)
ColMap[j] = ColMap[j + 1];
ColMap[Range[i] . high] = TempCol;
}
else
{
/* This one is cycling forwards. */
TempCol = ColMap[Range[i] . high];
for(j = Range[i] . high ; j > Range[i] . low ; j--)
ColMap[j] = ColMap[j - 1];
ColMap[Range[i] . low] = TempCol;
}
/* Okay, everything has been moved, now
* load the new palette.
*/
LoadRGB4(VPort,ColMap,ColNum);
}
}
int_end();
return(0);
}
/* InitCycleCode(ViewPort,ColMap,ColNum,Range,RangeNum) :
*
* Initializes all data and starts up the interrupt
* server.
*/
LONG
InitCycleCode(struct ViewPort *Cy_ViewPort,UWORD *Cy_ColMap,LONG Cy_ColNum,CRange *Cy_Range,LONG Cy_RangeNum)
{
SHORT i;
/* Check for valid parameters. */
if(!Cy_ViewPort || !Cy_ColMap || !Cy_ColNum || !Cy_Range || !Cy_RangeNum)
return(FALSE);
/* See if we can allocate the Interrupt structure. */
if(!(VBlank = (struct Interrupt *)AllocMem(sizeof(struct Interrupt),MEMF_PUBLIC | MEMF_CLEAR)))
return(FALSE);
/* Copy the data. */
VPort = Cy_ViewPort;
ColNum = Cy_ColNum;
Range = Cy_Range;
RangeNum = Cy_RangeNum;
for(i = 0 ; i < ColNum ; i++)
ColMap[i] = Cy_ColMap[i];
/* Clear event counters. */
for(i = 0 ; i < Cy_RangeNum ; i++)
TicksPassed[i] = 0;
/* Copy the original palette to the undo buffer. */
for(i = 0 ; i < Cy_ColNum ; i++)
UndoBuffer[i] = Cy_ColMap[i];
/* Let the CycleCode wait. */
Command = CY_WAIT;
WeAreWaiting = TRUE;
/* Ta Da! The CycleCode enters the stage!. */
VBlank -> is_Code = CycleCode;
VBlank -> is_Node . ln_Type = NT_INTERRUPT;
VBlank -> is_Node . ln_Name = "Cycling Interrupt";
AddIntServer(INTB_VERTB,VBlank);
CodeRun = TRUE;
return(TRUE);
}
/* ClearCycleCode() :
*
* Forces the CycleCode to hit and quit.
*/
VOID
ClearCycleCode()
{
SHORT i;
/* Is the interrupt already running? */
if(CodeRun && VBlank)
{
/* Tell it to wait. */
WeAreWaiting = TRUE;
Command = CY_WAIT;
/* Remove the server code. */
RemIntServer(INTB_VERTB,VBlank);
FreeMem(VBlank,sizeof(struct Interrupt));
/* Rebuild palette. */
for(i = 0 ; i < ColNum ; i++)
ColMap[i] = UndoBuffer[i];
/* Wait for it to finish. */
WaitTOF();
WaitTOF();
WaitTOF();
/* Close the shop. */
CodeRun = FALSE;
}
}
/* ToggleCycleCode() :
*
* Toggles the activity of the cycling code.
*/
VOID
ToggleCycleCode()
{
static BYTE Mode = FALSE;
Mode ^= TRUE;
if(Mode)
Command = CY_CYCL;
else
Command = CY_WAIT;
WaitTOF();
}
/* IsCycling() :
*
* Returns the present status of the cycling code.
*/
LONG
IsCycling()
{
if(Command == CY_CYCL)
return(TRUE);
if(Command == CY_WAIT)
return(FALSE);
}
/* LoadCycleRange(FileName,Range,MaxRange) :
*
* Searches the IFF-ILBM-file for CRNG or CCRT
* chunks und initializes the colour-ranges.
*/
LONG
LoadCycleRange(char *FileName,CRange *Range,LONG MaxRange)
{
FILE *CycFile;
SHORT i;
/* GraphiCraft private cycling chunk. */
struct
{
WORD direction; /* Which direction? */
UBYTE start; /* First colour. */
UBYTE end; /* Last colour. */
LONG seconds; /* Wait time. */
LONG microseconds; /* Wait time. */
WORD pad; /* Expansion/padding byte. */
} CcrtChunk;
/* Clear all ranges. */
for(i = 0 ; i < MaxRange ; i++)
Range[i] . active = 0;
/* Open the file and try to locate the CRNG chunk. */
if(!(CycFile = fopen(FileName,"r")))
return(FALSE);
if(FindChunk("CRNG",CycFile))
{
/* Read all ranges. */
for(i = 0 ; i < MaxRange ; i++)
{
fread(&Range[i],sizeof(CRange),1,CycFile);
/* Carefully determine if this chunk is
* active.
*/
if(Range[i] . active == CRNG_NORATE || !Range[i] . rate || Range[i] . low == Range[i] . high)
Range[i] . active = 0;
/* Recalculate speed value. */
if(Range[i] . rate > 0)
Range[i] . rate = 16384 / Range[i] . rate;
else
Range[i] . rate = 0;
/* Finished reading the chunks? */
if(!FindChunk("CRNG",CycFile))
{
i++;
break;
}
}
}
else
{
/* Didn't find a CRNG chunk, try to find a
* CCRT chunk.
*/
fseek(CycFile,0,0);
if(FindChunk("CCRT",CycFile))
{
for(i = 0 ; i < MaxRange ; i++)
{
fread(&CcrtChunk,sizeof(CcrtChunk),1,CycFile);
/* We have located a CCRT chunk, now
* make it a CRNG chunk.
*/
Range[i] . low = CcrtChunk . start;
Range[i] . high = CcrtChunk . end;
if(CcrtChunk . direction != 0)
Range[i] . active = CRNG_ACTIVE;
else
Range[i] . active = 0;
if(CcrtChunk . direction > 0)
Range[i] . active |= CRNG_REVERSE;
/* Recalculate speed (by
* Carolyn Scheppner).
*/
Range[i] . rate = 16384 / (CcrtChunk . seconds * 60 + (CcrtChunk . microseconds + 8334) / 16667);
/* See if it is active. */
if(!Range[i] . rate || Range[i] . low == Range[i] . high)
Range[i] . active = 0;
/* Recalculate speed value. */
if(Range[i] . rate > 0)
Range[i] . rate = 16384 / Range[i] . rate;
else
Range[i] . rate = 0;
/* See if there is another chunk. */
if(!FindChunk("CCRT",CycFile))
{
i++;
break;
}
}
}
else
{
/* Seems that we failed. */
fclose(CycFile);
return(FALSE);
}
}
fclose(CycFile);
return(i);
}