home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format 105
/
af105sub.adf
/
Beyondthedark.LZX
/
BeyondTheDark
/
Developer
/
Source
/
Boxes
/
Boxes.c
next >
Wrap
C/C++ Source or Header
|
1990-09-06
|
17KB
|
928 lines
/*
* 1995; Gary Duncan (gduncan@werple.net.au)
*
* - based on boxes code from DlineArt (released with DMouse)
*
* - this is freeware.
*
*
*/
/*-------------------------------------------------------------*/
/*-------------------------------------------------------------
Functions:-
PenCountMyBlanker (TAGITEM * TagList)
QueryMyBlanker (void)
InitMyBlanker (TAGITEM * TagList)
EndMyBlanker (BOXES * BX)
AnimMyBlanker (BOXES * BX)
MyBlankerLibFree (void)
MyBlankerLibInit (void)
do_box (RASTPORT * rp, XY * start, XY * end, XY * limit)
checkbounce_start (XY * start, XY * limmax, XY * limmin)
checkbounce_end (XY * end, XY * limmax, XY * limmin)
get_rand_point (int min, int max)
get_rand_dir ()
get_rand_scale ()
my_ran (int lim)
time_diff (ULONG e_freq, ECLOCKVAL * e_val1, ECLOCKVAL * e_val2)
open_timer (void)
close_timer (void)
DrawBounds (RASTPORT * rp, XY * tlhc, XY * brhc)
init_array (BOXES * BX)
-------------------------------------------------------------*/
#include <stdlib.h>
#include <stdio.h>
#include <exec/types.h>
#include <ctype.h>
#include <fcntl.h>
#include <string.h>
#include <clib/dos_protos.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/macros.h>
#include <clib/timer_protos.h>
#include <devices/timer.h>
#include <dos/dos.h>
#include <exec/memory.h>
#include <exec/lists.h>
#include <exec/nodes.h>
#include <exec/execbase.h>
#include <graphics/text.h>
#include <graphics/gfxbase.h>
#include <intuition/preferences.h>
#include <intuition/screens.h>
#include <intuition/intuitionbase.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <libraries/iffparse.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <time.h>
#include <utility/tagitem.h>
#include "/BTD.h"
#include "typedefs.h" /* GMD */
/*-------------------------------------------------------------*/
#if 0
#define DPUTSTR(x) DPutStr(x)
void DPutStr (char *p);
#else
#define DPUTSTR(x)
#endif
#define DTAG(o) (BTD_Client+(o))
#define BX_Boxes DTAG(0)
#define BX_Speed DTAG(1)
#define DEF_BOXES 10L
#define MAX_BOXES 20L
#define MINBOUND 10
#define MIN_SPEED 1L
#define MAX_SPEED 10L
typedef struct BTDInfo BTDINFO;
typedef struct BTDDrawInfo BTDDRAWINFO;
typedef struct XY
{
LONG x;
LONG y;
}
XY;
typedef struct DIRECTION
{
XY start;
XY end;
}
DIRECTION;
#define FindTagData(l,t,d) GetTagData((t),(d),(l))
INTUITIONBASE *IntuitionBase;
GFXBASE *GfxBase;
TIMERBASE *TimerBase;
TIMEREQUEST box_timer;
TIMEREQUEST *t_ptr = &box_timer;
ECLOCKVAL e_then, e_now, e_lcolch;
ULONG e_freq;
typedef struct
{
UBYTE r;
UBYTE g;
UBYTE b;
}
MY_RGB;
#define MY_SIX 6
MY_RGB col_ray[MY_SIX] =
{
0, 0, 255,
0, 255, 0,
255, 0, 0,
0, 255, 255,
255, 255, 0,
255, 0, 255
};
int delay[MAX_SPEED] =
{
0,
5,
10,
20,
30,
40,
50,
80,
90,
100
};
struct BTDInteger BoxesIntParams[] =
{
BX_Speed, "Delay", BTDPT_INTEGER, 2L, MIN_SPEED, MAX_SPEED, TRUE,
};
struct BTDNode *BoxesParams[] =
{
&BoxesIntParams[0].BI_Node,
NULL
};
BTDINFO BoxesInfo =
{
BTDI_Revision,
MAKE_ID ('B', 'O', 'X', ' '),
"Boxes Blanker",
"little boxes, full of ticky-tack...",
"Gary Duncan 1997(1.2)",
BoxesParams
};
typedef struct
{
BTDDRAWINFO *BTDDrawInfo;
LONG entry_count;
LONG col_count;
LONG xoffs;
LONG g_Count;
LONG g_scale1;
LONG g_scale2;
LONG speed;
LONG n_boxes;
LONG debug_count;
LONG init_count;
XY tlhc;
XY brhc;
XY p_stt[MAX_BOXES];
XY p_end[MAX_BOXES];
DIRECTION dir;
}
BOXES;
/*
* func prototypes
*/
static USHORT my_ran (int);
static int get_rand_scale (void);
static int get_rand_dir (void);
static int get_rand_point (int min, int max);
static BOOL checkbounce_start (XY * end, XY * limmax, XY * limmin);
static BOOL checkbounce_end (XY * end, XY * limmax, XY * limmin);
static void do_box (BOXES * BX, XY * start, XY * end, XY * limit);
static LONG time_diff (ULONG e_freq, ECLOCKVAL * e_val1, ECLOCKVAL * e_val2);
static BOOL open_timer (void);
static void close_timer (void);
static void DrawBounds (RASTPORT * rp, XY * p1, XY * p2);
static void init_array (BOXES * BX);
void dbg (BOXES * BX, char *ptr);
/* library stuff */
char MyBlankerName[] = "boxes.btd";
char MyBlankerID[] = "Boxes Blanker V" VERSION "." REVISION " for BTD";
/*
* DEBUG stuff (13 Oct 97)
*/
long DBFh;
int gBDI_Left;
int gBDI_Top;
int gBDI_Width;
int gBDI_Height;
/*
*******************************************************************
*/
ULONG
PenCountMyBlanker (TAGITEM * TagList)
{
//
// debug
//
DPUTSTR ("PenCountMyBlanker\n");
return 1;
}
/*
*******************************************************************
*/
BTDINFO *
QueryMyBlanker (void)
{
//
// debug
//
DPUTSTR ("QueryMyBlanker\n");
return &BoxesInfo;
}
/*
*******************************************************************
*/
BOXES *
InitMyBlanker (TAGITEM * TagList)
{
BOXES *BX;
BTDDRAWINFO *BTDDrawInfo;
UWORD pen, col;
ULONG *Error, Dummy, Instance;
//
// debug
//
DPUTSTR ("InitMyBlanker\n");
if ((BTDDrawInfo = (BTDDRAWINFO *)
FindTagData (TagList, BTD_DrawInfo, NULL)) == NULL)
return NULL;
Error = (LONG *) FindTagData (TagList, BTD_Error, (ULONG) & Dummy);
if ((BX = AllocVec (sizeof (BOXES), MEMF_PUBLIC | MEMF_CLEAR)) == NULL)
{
*Error = BTDERR_Memory;
return NULL;
}
BX->BTDDrawInfo = BTDDrawInfo;
Instance = FindTagData (TagList, BTD_Instance, 0L);
BX->speed = FindTagData (TagList, BX_Speed, 0L);
/*
* define the rectangle (shrink a bit)
*/
BX->tlhc.x = BX->BTDDrawInfo->BDI_Left + MINBOUND;
BX->tlhc.y = BX->BTDDrawInfo->BDI_Top + MINBOUND;
BX->brhc.x = BX->BTDDrawInfo->BDI_Width + BX->tlhc.x - 2 * MINBOUND;
BX->brhc.y = BX->BTDDrawInfo->BDI_Height + BX->tlhc.y - 2 * MINBOUND;
/* (DEBUG) */
gBDI_Left = BX->tlhc.x;
gBDI_Top = BX->tlhc.y;
gBDI_Width = BX->brhc.x;
gBDI_Height = BX->brhc.y;
/*
* Init array
*/
init_array (BX);
col = BX->col_count;
pen = BTDDrawInfo->BDI_Pens[0];
BTDDrawInfo->BDI_Red[pen] = col_ray[col].r;
BTDDrawInfo->BDI_Green[pen] = col_ray[col].g;
BTDDrawInfo->BDI_Blue[pen] = col_ray[col].b;
BTDDrawInfo->BDI_Changed[pen] = TRUE;
SetAPen (BTDDrawInfo->BDI_RPort, pen);
/*
* get and save current E-clock value
*/
e_freq = ReadEClock (&e_now);
e_freq = ReadEClock (&e_then);
e_freq = ReadEClock (&e_lcolch);
return BX;
}
/*
*******************************************************************
*/
void
EndMyBlanker (BOXES * BX)
{
//
// debug
//
DPUTSTR ("EndMyBlanker\n");
FreeVec (BX);
}
/*
*******************************************************************
*/
void
AnimMyBlanker (BOXES * BX)
{
int new_offs, erase_offs, loop;
XY *sxy, *exy, t_sxy, t_exy;
int xmax, ymax;
int curr_offs;
UWORD pen;
int col, j;
XY *tlhc = &BX->tlhc;
XY *brhc = &BX->brhc;
RASTPORT *rp = BX->BTDDrawInfo->BDI_RPort;
BTDDRAWINFO *BTDDrawInfo = BX->BTDDrawInfo;
//
// debug
//
if (BX->debug_count++ == 0)
DPUTSTR ("AnimMyBlanker\n");
/*
* get current E-clock value ; return if < delay
*/
e_freq = ReadEClock (&e_now);
if (time_diff (e_freq, &e_then, &e_now) < delay[BX->speed - 1])
{
return;
}
/*
* reset box array after 1000 loops (arbitary)
*/
if ((BX->init_count++ % 1000) == 0)
{
/*
* erase existing boxes
*/
for (j = 0; j < MAX_BOXES; ++j)
{
if (BX->p_stt[j].x != -1)
{
SetAPen (rp, BTD_BgPen);
do_box (BX, &BX->p_stt[j], &BX->p_end[j], brhc);
SetAPen (rp, BTDDrawInfo->BDI_Pens[0]);
}
}
init_array (BX);
}
/*
* draw Bounds (Debug feature - visually check boxes don't overlap)
*/
t_sxy.x = BX->BTDDrawInfo->BDI_Left;
t_sxy.y = BX->BTDDrawInfo->BDI_Top;
t_exy.x = BX->BTDDrawInfo->BDI_Width + t_sxy.x - 1;
t_exy.y = BX->BTDDrawInfo->BDI_Height + t_sxy.y - 1;
//DrawBounds (rp, &t_sxy, &t_exy);
/*
* time to change colour (2 secs) ?
*/
if (time_diff (e_freq, &e_lcolch, &e_now) > 2000)
{
++BX->col_count; /* cycle colours */
e_lcolch = e_now;
}
col = BX->col_count % MY_SIX; /* cycle colours */
pen = BTDDrawInfo->BDI_Pens[0];
BTDDrawInfo->BDI_Red[pen] = col_ray[col].r;
BTDDrawInfo->BDI_Green[pen] = col_ray[col].g;
BTDDrawInfo->BDI_Blue[pen] = col_ray[col].b;
BTDDrawInfo->BDI_Changed[pen] = TRUE;
for (loop = 0; loop < 1; ++loop) /* change loop count later ?? */
{
curr_offs = BX->xoffs;
sxy = &BX->p_stt[curr_offs];
exy = &BX->p_end[curr_offs];
xmax = brhc->x;
ymax = brhc->y;
/*
* draw a box...
*/
SetAPen (rp, pen);
do_box (BX, sxy, exy, brhc);
/*
* start x,y
*/
if (checkbounce_start (sxy, brhc, tlhc))
{
if (sxy->x <= tlhc->x)
{
BX->dir.start.x = 1;
}
else
{
if (sxy->x >= brhc->x)
BX->dir.start.x = -1;
else
BX->dir.start.x = get_rand_dir ();
}
if (sxy->y <= tlhc->y)
{
BX->dir.start.y = 1;
}
else
{
if (sxy->y >= brhc->y)
BX->dir.start.y = -1;
else
BX->dir.start.y = get_rand_dir ();
}
BX->g_scale1 = get_rand_scale ();
}
/*
* end x,y
*/
if (checkbounce_end (exy, brhc, tlhc))
{
if (exy->x <= tlhc->x)
{
BX->dir.end.x = 1;
}
else
{
if (exy->x >= brhc->x)
BX->dir.end.x = -1;
else
BX->dir.end.x = get_rand_dir ();
}
if (exy->y <= tlhc->y)
{
BX->dir.end.y = 1;
}
else
{
if (exy->y >= brhc->y)
BX->dir.end.y = -1;
else
BX->dir.end.y = get_rand_dir ();
}
BX->g_scale2 = get_rand_scale ();
}
if (++BX->xoffs == MAX_BOXES)
BX->xoffs = 0;
erase_offs = new_offs = BX->xoffs;
/*
* Erase the oldest line (if entry valid)
*/
if (BX->p_stt[erase_offs].x != -1)
{
SetAPen (rp, BTD_BgPen);
do_box (BX, &BX->p_stt[erase_offs], &BX->p_end[erase_offs], brhc);
SetAPen (rp, BTDDrawInfo->BDI_Pens[0]);
}
/* Calculate the next point */
BX->p_stt[new_offs].x =
(BX->g_scale1 * BX->dir.start.x) + BX->p_stt[curr_offs].x;
BX->p_stt[new_offs].y =
(BX->g_scale1 * BX->dir.start.y) + BX->p_stt[curr_offs].y;
BX->p_end[new_offs].x =
(BX->g_scale2 * BX->dir.end.x) + BX->p_end[curr_offs].x;
BX->p_end[new_offs].y =
(BX->g_scale2 * BX->dir.end.y) + BX->p_end[curr_offs].y;
}
/*
* get and save current E-clock value
*/
e_freq = ReadEClock (&e_then);
}
/*
*******************************************************************
*/
void
MyBlankerLibFree (void)
{
//
// debug
//
DPUTSTR ("MyBlankerLibFree\n");
CloseLibrary (UtilityBase);
CloseLibrary (&IntuitionBase->LibNode);
CloseLibrary (&GfxBase->LibNode);
close_timer ();
}
/*
*******************************************************************
*/
LONG
MyBlankerLibInit (void)
{
//
// debug
//
DPUTSTR ("MyBlankerLibInit\n");
if (open_timer () == FALSE)
{
return FALSE;
}
if (GfxBase = (GFXBASE *) OpenLibrary ("graphics.library", 37L))
{
if (IntuitionBase = (INTUITIONBASE *) OpenLibrary ("intuition.library", 37L))
{
if (UtilityBase = OpenLibrary ("utility.library", 37L))
return TRUE;
CloseLibrary (&IntuitionBase->LibNode);
}
CloseLibrary (&GfxBase->LibNode);
}
return FALSE;
}
/*
*********************************************************************
*/
static void
do_box (BOXES * BX, XY * start, XY * end, XY * limit)
{
RASTPORT *rp = BX->BTDDrawInfo->BDI_RPort;
int tempx_s = limit->x - start->x;
int tempy_s = limit->y - start->y;
int tempx_e = limit->x - end->x;
int tempy_e = limit->y - end->y;
/*
* DEBUG-start
*/
if (start->x > gBDI_Width)
{
dbg (BX, "X1\n");
return;
}
if (start->y > gBDI_Height)
{
dbg (BX, "Y1\n");
return;
}
if (end->x > gBDI_Width)
{
dbg (BX, "X2\n");
return;
}
if (end->y > gBDI_Height)
{
dbg (BX, "Y1\n");
return;
}
/*
* check x coords
*/
if ((tempx_s < 0) || (tempx_s > gBDI_Width))
{
dbg (BX, "ST1\n");
return;
}
if ((tempx_e < 0) || (tempx_e > gBDI_Width))
{
dbg (BX, "ST2\n");
return;
}
/*
* check y coords
*/
if ((tempx_e < 0) || (tempx_e > gBDI_Height))
{
dbg (BX, "ET1\n");
return;
}
if ((tempy_e < 0) || (tempy_e > gBDI_Height))
{
dbg (BX, "ET2\n");
return;
}
/*
* DEBUG-end
*/
Move (rp, start->x, start->y);
Draw (rp, end->x, end->y);
Draw (rp, tempx_s, tempy_s);
Draw (rp, tempx_e, tempy_e);
Draw (rp, start->x, start->y);
}
/*
*********************************************************************
*/
static BOOL
checkbounce_start (XY * start, XY * limmax, XY * limmin)
{
if ((start->x >= limmax->x) || (start->y >= limmax->y)
|| (start->x <= limmin->x) || (start->y <= limmin->y))
return TRUE;
else
return FALSE;
}
/*
*********************************************************************
*/
static BOOL
checkbounce_end (XY * end, XY * limmax, XY * limmin)
{
if ((end->x >= limmax->x) || (end->y >= limmax->y)
|| (end->x <= limmin->x) || (end->y <= limmin->y))
return TRUE;
else
return FALSE;
}
/*
*********************************************************************
*/
static int
get_rand_point (int min, int max)
{
SHORT temp;
temp = my_ran (max - min);
return (temp + min);
}
/*
*********************************************************************
*/
static int
get_rand_dir ()
{
SHORT num;
num = my_ran (15000);
return (num < 5000) ? -1 : (num > 10000) ? 1 : 0;
}
/*
*********************************************************************
*/
static int
get_rand_scale ()
{
SHORT temp;
temp = my_ran (MINBOUND);
if (temp == 0)
++temp;
return temp;
}
/*
*********************************************************************
*/
static USHORT
my_ran (int lim)
{
USHORT retval = RangeRand (lim);
if (retval == 0)
return 1;
else
return retval;
}
/*
*********************************************************************
*/
/*
* returns number of msecs between first ECLOCK and second ECLOCK
* - second ECLOCK is later.
*
* - not precise, but a hack ; divides (shifts) by 1024 not 1000.
*
*/
static LONG
time_diff (ULONG e_freq, ECLOCKVAL * e_val1, ECLOCKVAL * e_val2)
{
LONG temp, msecs;
if (e_val2->ev_lo > e_val1->ev_lo)
{
temp = e_val2->ev_lo - e_val1->ev_lo;
}
else
{
temp = e_val1->ev_lo - e_val2->ev_lo;
}
/*
* convert to msecs
*/
e_freq = e_freq >> 10; /* roughly , /1024 */
msecs = temp / e_freq;
return msecs;
}
/*
*********************************************************************
*/
static BOOL
open_timer (void)
{
if (OpenDevice (TIMERNAME, UNIT_ECLOCK, (IOREQUEST *) t_ptr, 0L) != 0)
{
return FALSE;
}
TimerBase = (TIMERBASE *) t_ptr->tr_node.io_Device;
return TRUE;
}
/*
*********************************************************************
*/
static void
close_timer (void)
{
if (t_ptr)
{
CloseDevice ((IOREQUEST *) t_ptr);
t_ptr = NULL;
}
}
/*
*********************************************************************
*/
static void
DrawBounds (RASTPORT * rp, XY * tlhc, XY * brhc)
{
Move (rp, tlhc->x, tlhc->y);
Draw (rp, brhc->x - 1, tlhc->y);
Draw (rp, brhc->x - 1, brhc->y - 1);
Draw (rp, tlhc->x, brhc->y - 1);
Draw (rp, tlhc->x, tlhc->y);
}
/*
*********************************************************************
*/
static void
init_array (BOXES * BX)
{
int j;
/*
* Init array with inactive values
*/
for (j = 0; j < MAX_BOXES; ++j)
{
BX->p_stt[j].x = -1;
BX->p_stt[j].y = -1;
}
/*
* Init starting points with random x,y values
*/
BX->xoffs = 0;
BX->p_stt[0].x = get_rand_point (BX->tlhc.x, BX->brhc.x);
BX->p_stt[0].y = get_rand_point (BX->tlhc.y, BX->brhc.y);
BX->p_end[0].x = get_rand_point (BX->tlhc.x, BX->brhc.x);
BX->p_end[0].y = get_rand_point (BX->tlhc.y, BX->brhc.y);
BX->dir.start.x = get_rand_dir ();
BX->dir.start.y = get_rand_dir ();
BX->dir.end.x = get_rand_dir ();
BX->dir.end.y = get_rand_dir ();
BX->g_scale1 = 2;
BX->g_scale2 = 2;
BX->col_count = my_ran (MY_SIX - 1);
}
/*
*********************************************************************
*/
void
dbg (BOXES * BX, char *ptr)
{
/* DEBUG CODE COMES HERE :) */
}