home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Acorn User 10
/
AU_CD10.iso
/
Updates
/
DigitalCD
/
!DigitalCD
/
Copy
/
PowerBars
/
c
/
Main
< prev
next >
Wrap
Text File
|
1999-12-03
|
10KB
|
468 lines
#include <signal.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "kernel.h"
#include "bool.h"
#include "Event.h"
#include "Exception.h"
#include "Window.h"
#include "Task.h"
#include "DCDswi.h"
#define TASKNAME "PowerBars"
const char* TaskName = TASKNAME;
int block[64];
int LeftPower = 0;
int RightPower = 0;
HWind wleft = -1;
HWind wright = -1;
HWind DCDWindow = -1;
CSize spSize = {32, 128};
CSize spDSize = {32, 128};
CSpriteArea* pSprites = NULL;
void App_Log(const char* pformat, ...)
{
va_list arg;
char filename[] = TASKNAME ":Log";
FILE* file = fopen(filename, "a");
if (file == NULL) file = fopen(filename, "w");
if (file == NULL) return;
va_start(arg, pformat);
vfprintf(file, pformat, arg);
va_end(arg);
fclose(file);
}
void App_LogBinary(void* pdata, int len)
{
char filename[] = TASKNAME ":Log";
FILE* file = fopen(filename, "a");
if (file == NULL) file = fopen(filename, "w");
if (file == NULL) return;
fprintf(file, "Dump of %p\n", pdata);
fwrite(pdata, len, 1, file);
fprintf(file, "End of Dump\n");
fclose(file);
}
typedef void (*Window_Drawer)(const CWindRedraw* pdraw, void* handle);
void Window_Update(HWind w, const CRect* pbox, Window_Drawer pdraw, void* handle)
{
_kernel_swi_regs regs;
CWindRedraw r;
r.w = w;
r.cvt.box = *pbox;
/* Wimp_UpdateWindow */
regs.r[1] = (int) &r;
_kernel_swi(0x0600c9, ®s, ®s);
while (regs.r[0])
{
if (pdraw) pdraw(&r, handle);
/* Wimp_GetRectangle */
regs.r[1] = (int) &r;
_kernel_swi(0x0600ca, ®s, ®s);
}
}
void Window_Redraw(HWind w, Window_Drawer pdraw, void* handle)
{
_kernel_swi_regs regs;
CWindRedraw r;
r.w = w;
/* Wimp_RedrawWindow */
regs.r[1] = (int) &r;
_kernel_swi(0x0600c8, ®s, ®s);
while (regs.r[0])
{
if (pdraw) pdraw(&r, handle);
/* Wimp_GetRectangle */
regs.r[1] = (int) &r;
_kernel_swi(0x0600ca, ®s, ®s);
}
}
CRect Window_GetOutline(HWind id)
{
_kernel_swi_regs regs;
struct
{
HWind w;
CRect pos;
} outline;
/* Wimp_GetWindowOutline */
outline.w = id;
regs.r[1] = (int) &outline;
_kernel_swi(0x0600e0, ®s, ®s);
return outline.pos;
}
void Desktop_SetStdColour(int c)
{
_kernel_swi_regs regs;
regs.r[0] = c;
_kernel_swi(0x600e6, ®s, ®s);
}
void Display_Plot(int code, int x, int y)
{
_kernel_swi_regs regs;
/* OS_Plot */
regs.r[0] = code;
regs.r[1] = x;
regs.r[2] = y;
_kernel_swi(0x020045, ®s, ®s);
}
void BarDrawer(const CWindRedraw* pdraw, void* handle)
{
int power = (int) handle;
int y = pdraw->cvt.box.y0 + (((pdraw->cvt.box.y1 - pdraw->cvt.box.y0)*power) >> 7);
CPoint pt;
CRect rect = {0, 0, 0, 0};
pt.x = pdraw->cvt.box.x0;
pt.y = pdraw->cvt.box.y0;
Desktop_SetStdColour(7);
Display_Plot( 4, pdraw->cvt.box.x0, y);
Display_Plot(101, pdraw->cvt.box.x1, pdraw->cvt.box.y1);
y -= pt.y;
rect.x1 = spSize.cx;
while (y > 0)
{
rect.y1 = (spSize.cy*y)/spDSize.cy;
Desktop_PlotSprite(pSprites, "bar", &pt, &rect);
y -= spDSize.cy;
pt.y += spDSize.cy;
}
}
bool App_ProcessKey(int key)
{
return false;
}
void BarOpenLeft(void)
{
_kernel_swi_regs regs;
CWindOpen open;
CRect box = Window_GetOutline(DCDWindow);
open.w = wleft;
open.cvt.box.y0 = box.y0;
open.cvt.box.y1 = box.y1;
open.cvt.box.x0 = box.x0 - spDSize.cx;
open.cvt.box.x1 = box.x0;
open.cvt.s.cx = 0;
open.cvt.s.cy = 0;
open.behind = DCDWindow;
regs.r[1] = (int) &open;
_kernel_swi(0x600C5, ®s, ®s);
}
void BarOpenRight(void)
{
_kernel_swi_regs regs;
CWindOpen open;
CRect box = Window_GetOutline(DCDWindow);
open.w = wright;
open.cvt.box.y0 = box.y0;
open.cvt.box.y1 = box.y1;
open.cvt.box.x0 = box.x1;
open.cvt.box.x1 = box.x1 + spDSize.cx;
open.cvt.s.cx = 0;
open.cvt.s.cy = 0;
open.behind = DCDWindow;
regs.r[1] = (int) &open;
_kernel_swi(0x600C5, ®s, ®s);
}
#define SND_WIDTH 128
char2 Buffer[SND_WIDTH];
void App_ProcessFrame(void)
{
CRect box = {0, 0, 32, 1024};
int i, size;
char left, right;
/* DCDWindow tracking, send WindowOpen Requests */
/* Read wave */
LeftPower = 0;
RightPower = 0;
size = DCDUtils_GetBuffer(Buffer, Buffer + SND_WIDTH);
for (i = 0; i < size; i++)
{
left = Buffer[i][0];
right = Buffer[i][1];
/* Get abs */
if (left & 0x80) left = -left;
if (right & 0x80) right = - right;
if (LeftPower < left)
LeftPower = left;
if (RightPower < right)
RightPower = right;
}
BarOpenLeft();
BarOpenRight();
Window_Update(wleft, &box, BarDrawer, (void*) LeftPower);
Window_Update(wright, &box, BarDrawer, (void*) RightPower);
}
CWind w = {0,0,0,32,1024,0,0,-1,0,0xff,0,0,0xff,0,0,0,0,0,0,256,1024,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
static int messages[] =
{
0x52780, /* Message_UpdatePlugInsPosition */
0
};
int main(int argc, char* argv[])
{
_kernel_oserror Error_Signal;
_kernel_swi_regs regs;
const _kernel_oserror* err = NULL;
const char* errfile = NULL;
int errline = 0;
int Time =0;
int NewTime = 0;
const char* pDCDTitle;
int count = -1;
int oldcount;
int dummy;
HTask TaskId;
bool bLoop = true;
exception_initialise();
if (argc > 1)
{
DCDUtils_SetPlayer(atoi(argv[1]));
}
else
DCDUtils_SetPlayer(0);
/* Choices_Choices("DigitalCD.Plugins." TASKNAME ".Choices");
*/
/* Wimp_Initialise */
regs.r[0] = 310;
regs.r[1] = 0x4B534154;
regs.r[2] = (int) TaskName;
regs.r[3] = (int) messages;
throw_os(_kernel_swi(0x0600C0, ®s, ®s));
TaskId = regs.r[1];
throw_os(DCDUtils_RegisterPlugIn(TaskId, false));
Task_SetModeInfo();
try
{
if ((pSprites = Sprites_LoadFile("PowerBars:Sprites")) == NULL)
throw_string("Failed to load sprites");
spSize = GetSpriteSize(pSprites, "bar");
spDSize = Desktop_GetSpriteSize(pSprites, "bar");
w.o.o.cvt.box.x1 = spDSize.cx;
w.ex.x1 = spDSize.cx;
/* Wimp_CreateWindow */
regs.r[1] = (int) &w.o.o.cvt;
throw_os(_kernel_swi(0x0600C1, ®s, ®s));
wleft = regs.r[0];
/* Wimp_CreateWindow */
regs.r[1] = (int) &w.o.o.cvt;
throw_os(_kernel_swi(0x0600C1, ®s, ®s));
wright = regs.r[0];
/*
* Main loop
*/
bLoop = true;
do
{
bool bWait = true;
/* XOS_ReadMonotonicTime */
_kernel_swi(0x020042, ®s, ®s);
Time = regs.r[0];
/* Get song info */
oldcount = count;
DCDUtils_GetInfo(&DCDWindow, &count, &dummy, &pDCDTitle);
/* Process frame */
if (count)
App_ProcessFrame();
else
bLoop = false;
/* Wimp_PollIdle */
NewTime = Time + 5;
while (bWait && bLoop)
{
regs.r[0] = 0;
regs.r[1] = (int) █
regs.r[2] = NewTime;
_kernel_swi(0x600E1, ®s, ®s);
switch(regs.r[0])
{
case EEvent_Null:
{
bWait = false;
}
break;
case EEvent_WindowRedraw:
{
if (block[0] == wleft)
Window_Redraw(wleft, BarDrawer, (void*) LeftPower);
else if (block[0] == wright)
Window_Redraw(wright, BarDrawer, (void*) RightPower);
else Window_Redraw(block[0], NULL, NULL);
}
break;
case EEvent_WindowOpen:
{
CWindOpen* popen = (CWindOpen*) █
if (popen->w == wleft)
BarOpenLeft();
else if (popen->w == wright)
BarOpenRight();
else
_kernel_swi(0x600C5, ®s, ®s);
}
break;
case EEvent_WindowClose:
{
_kernel_swi(0x600C6, ®s, ®s);
}
break;
case EEvent_Key:
{
Event_Key* pkey = (Event_Key*) █
if (!App_ProcessKey(pkey->code))
{
pkey->caret.pos.w = DCDWindow;
pkey->caret.pos.i = -1;
/* Wimp_SendMessage */
regs.r[0] = EEvent_Key;
regs.r[1] = (int) pkey;
regs.r[2] = DCDWindow;
regs.r[3] = -1;
_kernel_swi(0x0600e7, ®s, ®s);
}
}
break;
case EEvent_Message:
case EEvent_MessageWantAck:
{
switch(block[4])
{
case EMsg_Quit:
{
bLoop = false;
}
break;
case EMsg_ModeChange:
{
/* Preprocessing */
Task_SetModeInfo();
}
break;
case 0x52780:
{
/* Player may send us it's new position */
BarOpenLeft();
BarOpenRight();
}
break;
}
}
break;
}
}
} while (bLoop);
}
catch
{
const exception* e = exception_current();
switch(e->type)
{
case exception_os:
{
/* Save error as it could be overwritten */
Error_Signal = *e->error.os;
err = &Error_Signal;
errfile = e->file;
errline = e->line;
}
break;
/* case exception_user: err = &Task_Error_NoMem; break;
*/ default:
{
if (e->error.signal_id != SIGINT)
{
err = &Error_Signal;
sprintf(&Error_Signal.errmess[0], "Signal:%d\n\0", e->error.signal_id);
errfile = NULL;
errline = 0;
}
}
}
}
catch_end
DCDUtils_DeregisterPlugIn();
/* Wimp_CloseDown */
regs.r[0] = TaskId;
regs.r[1] = 0x4b534154;
_kernel_swi(0x0600DD, ®s, ®s);
if (err)
{
if (errfile)
App_Log("%s at line %d of file %s\n", err->errmess, errline, errfile);
else
App_Log("%s\n", err->errmess);
printf("%s\n", err->errmess);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}