home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
125.lha
/
PhotonSlide.c
< prev
next >
Wrap
C/C++ Source or Header
|
1986-11-20
|
10KB
|
601 lines
/* Photon SlideShow, by Oren Peli.
Copyright (c) 1988 BazboSoft! and (c) 1988 MicroIllusions. */
/* This program may be freely distributed and used for non-commercial
purposes. Any changed versions of this program must retain the original
copyright notices */
#include <libraries/dos.h>
#include <graphics/gfxbase.h>
#include <stdio.h>
void *OpenLibrary() , *OpenScreen() , *OpenWindow();
struct Window *MyOpenWindow();
LONG Write();
void *FindTask();
void *GetDiskObject() , *FindToolType();
void *Open() , *AllocMem();
#define MAXWIDTH 376
#define MAXHEIGHT 242
#define MAXCOLORS 32
#define MakeID(a , b , c , d) ( (a) << 24L | (b) << 16L | (c) << 8 | (d) )
#define ID_FORM MakeID('F' , 'O' , 'R' , 'M')
#define ID_ILBM MakeID('I' , 'L' , 'B' , 'M')
#define ID_BMHD MakeID('B' , 'M' , 'H' , 'D')
#define ID_CAMG MakeID('C' , 'A' , 'M' , 'G')
#define ID_CMAP MakeID('C' , 'M' , 'A' , 'P')
#define ID_BODY MakeID('B' , 'O' , 'D' , 'Y')
#define cmpByteRun1 1
#define ROUNDODDUP(a) ( ( (a) + 1) & (~1L) )
typedef struct
{
LONG ckID , ckSize;
} Chunk;
typedef struct
{
short w , h , x , y;
char nPlanes , masking , compression , pad1;
short transparentColor;
char xAspect , yAspect;
short pageWidth , pageHeight;
} BitMapHeader;
#define SafeRead(a , b , c) if (Read(a , b , c) == -1L) { Close(a); return(NULL); }
void *IntuitionBase;
struct GfxBase *GfxBase;
BitMapHeader bmhd;
char *bufstart;
Chunk header;
void *ReadILBM(fspec)
REGISTER char *fspec;
{
REGISTER struct NewScreen NewScreen;
REGISTER struct Screen *screen;
REGISTER struct FileHandle *fp;
REGISTER char colormap[MAXCOLORS][3] , *sourcebuf;
REGISTER short colorcount;
LONG id , ViewModes = 0L;
if ( (fp = Open(fspec , MODE_OLDFILE) ) == 0L)
return(NULL);
SafeRead(fp , &header , (LONG) sizeof(header) );
if (header.ckID != ID_FORM)
{
Close(fp);
return(NULL);
}
SafeRead(fp , &id , (LONG) sizeof(id) );
if (id != ID_ILBM)
{
Close(fp);
return(NULL);
}
for (;;)
{
SafeRead(fp , &header , (LONG) sizeof(header) );
if (header.ckID == ID_BODY)
break;
switch(header.ckID)
{
case ID_BMHD: SafeRead(fp , &bmhd , (LONG) sizeof(bmhd) );
break;
case ID_CMAP: SafeRead(fp , &colormap[0] [0] , (LONG) header.ckSize);
colorcount = header.ckSize / 3;
break;
case ID_CAMG: SafeRead(fp , &ViewModes , (LONG) header.ckSize);
break;
default: Seek(fp , ROUNDODDUP(header.ckSize) , OFFSET_CURRENT);
}
}
sourcebuf = bufstart = AllocMem( (LONG) header.ckSize , MEMF_PUBLIC);
if (sourcebuf == 0L)
{
Close(fp);
return(NULL);
}
SafeRead(fp , sourcebuf , (LONG) header.ckSize);
Close(fp);
NewScreen.LeftEdge = 0;
NewScreen.TopEdge = GfxBase->NormalDisplayRows;
NewScreen.Width = bmhd.w;
NewScreen.Height = bmhd.h;
NewScreen.Depth = bmhd.nPlanes;
if (NOT (NewScreen.ViewModes = ViewModes) )
{
if (bmhd.w > MAXWIDTH)
NewScreen.ViewModes |= HIRES;
if (bmhd.h > MAXHEIGHT)
NewScreen.ViewModes |= LACE;
}
if (NewScreen.ViewModes & LACE)
NewScreen.TopEdge *= 2;
NewScreen.Type = CUSTOMSCREEN | SCREENQUIET | SCREENBEHIND;
NewScreen.Font = 0L;
NewScreen.Gadgets = 0L;
if (screen = OpenScreen(&NewScreen) )
{
if (NewScreen.ViewModes & HIRES)
screen->LeftEdge += (640 - screen->Width) / 2;
else
screen->LeftEdge += (320 - screen->Width) / 2;
if (NewScreen.ViewModes & LACE)
screen->ViewPort.DyOffset += (400 - screen->Height) / 2;
else
screen->ViewPort.DyOffset += (200 - screen->Height) / 2;
screen->ViewPort.DxOffset = screen->LeftEdge;
MakeScreen(screen);
RethinkDisplay();
while (colorcount--)
SetRGB4(&screen->ViewPort , (LONG) colorcount , colormap[colorcount][0] >>
4L , colormap[colorcount][1] >> 4L , colormap[colorcount][2] >> 4L);
}
return(screen);
}
Expand(screen , bmhd , sourcebuf)
struct Screen *screen;
BitMapHeader *bmhd;
register char *sourcebuf;
{
register char n , *destbuf;
register short plane , linelen , rowbytes , i;
linelen = bmhd->w / 8;
for (i = 0 ; i < bmhd->h ; i++)
for (plane = 0 ; plane < bmhd->nPlanes ; plane++)
{
destbuf = (char *) (screen->BitMap.Planes[plane]) + linelen * i;
if (bmhd->compression == cmpByteRun1)
{
rowbytes = linelen;
while (rowbytes)
{
n = *sourcebuf++;
if (n >= 0)
{
CopyMem(sourcebuf , destbuf , (LONG) ++n);
rowbytes -= n;
destbuf += n;
sourcebuf += n;
}
else
{
n = -n + 1;
rowbytes -= n;
setmem(destbuf , (WORD) n , (WORD) *sourcebuf++);
destbuf += n;
}
}
}
else
{
CopyMem(sourcebuf , destbuf , (LONG) linelen);
sourcebuf += linelen;
destbuf += linelen;
}
}
}
USHORT dummydata[] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 };
struct Window *
load_pic(name , otherwindow)
REGISTER BYTE *name;
REGISTER struct Window *otherwindow;
{
REGISTER struct Screen *screen;
REGISTER struct Window *window;
REGISTER struct NewWindow nw;
setmem(&nw , sizeof(nw) , 0);
if (NOT (screen = ReadILBM(name) ) )
return(NULL);
nw.IDCMPFlags = VANILLAKEY;
nw.Flags = SIMPLE_REFRESH | BORDERLESS | RMBTRAP | ACTIVATE;
nw.Screen = screen;
nw.Type = CUSTOMSCREEN;
nw.Height = bmhd.h;
nw.Width = bmhd.w;
if (NOT (window = MyOpenWindow(&nw , otherwindow) ) )
{
CloseScreen(screen);
return(NULL);
}
SetPointer(window , dummydata , 2L , 2L , NULL , NULL);
Expand(screen , &bmhd , bufstart);
FreeMem(bufstart , (LONG) header.ckSize);
return(window);
}
static BYTE str_buf[1000];
extern WORD Enable_Abort = 0;
WORD abort = 0;
main(argc , argv)
REGISTER WORD argc;
REGISTER BYTE *argv[];
{
REGISTER WORD i = 0 , cnt = 1;
REGISTER struct Window *win[2];
REGISTER struct Screen *scr[2];
REGISTER FILE *fopen() , *fp;
REGISTER BYTE file_name[500];
REGISTER WORD method , arg1 , arg2 , wait;
scr[0] = scr[1] = NULL;
win[0] = win[1] = NULL;
IntuitionBase = OpenLibrary("intuition.library" , 0L);
GfxBase = OpenLibrary("graphics.library" , 0L);
if (NOT GfxBase || NOT IntuitionBase)
goto end;
puts("\nPhoton SlideShow, by Oren Peli.\n\
Copyright (c) 1988 BazboSoft! and (c) 1988 MicroIllusions.\n");
if (argc == 1)
fp = fopen("script" , "r");
else if (argc == 2)
fp = fopen(argv[1] , "r");
else
{
puts("Bad args.");
goto end;
}
if (NOT fp)
{
puts("Can't open script file ... aborting!");
goto end;
}
forever:
while (fgets(str_buf , 990 , fp) )
{
REGISTER WORD len = strlen(str_buf) - 1;
REGISTER WORD t , p = 0;
for (t = 0 ; t != len ; t++)
if (str_buf[t] == ',')
{
str_buf[t] = '\0';
p++;
}
if (p != 4)
{
puts("Bad script file: wrong number of arguments ... aborting!");
goto end;
}
p = 0;
strncpy(file_name , str_buf , 490);
p += strlen(&str_buf[p]);
p++;
method = atoi(&str_buf[p]);
p += strlen(&str_buf[p]);
p++;
arg1 = atoi(&str_buf[p]);
p += strlen(&str_buf[p]);
p++;
arg2 = atoi(&str_buf[p]);
p += strlen(&str_buf[p]);
p++;
wait = atoi(&str_buf[p]);
i = 1 - i;
if (win[i])
{
chk_abort(win[i]);
CloseWindowSafely(win[i]);
CloseScreen(scr[i]);
win[i] = NULL;
scr[i] = NULL;
}
if (abort)
goto bye;
if (NOT (win[i] = load_pic(file_name , win[1 - i] ) ) )
{
puts("Can't read file or not enough memory ... aborting!");
goto end;
}
scr[i] = win[i]->WScreen;
chk_abort(win[i]);
if (abort)
goto bye;
show_screen(scr[i] , win[i] , method , arg1 , arg2);
if (wait > 0)
{
for (t = 0 ; t <= wait ; t++)
{
if (chk_abort(win[i]) )
break;
if (abort)
goto bye;
Delay(50L);
}
}
if (abort)
goto bye;
}
rewind(fp);
goto forever;
bye:
fclose(fp);
i = 1 - i;
end:
if (win[i])
{
CloseWindowSafely(win[i]);
CloseScreen(scr[i]);
win[i] = NULL;
scr[i] = NULL;
}
i = 1 - i;
if (win[i])
{
CloseWindowSafely(win[i]);
CloseScreen(scr[i]);
win[i] = NULL;
scr[i] = NULL;
}
if (IntuitionBase);
CloseLibrary(IntuitionBase);
if (GfxBase)
CloseLibrary(GfxBase);
exit(0);
}
chk_abort(win)
REGISTER struct Window *win;
{
REGISTER struct IntuiMessage *msg , *GetMsg();
REGISTER WORD code , was_pause = 0 , pausing = 0;
forever:
if (msg = GetMsg(win->UserPort) )
{
code = msg->Code;
ReplyMsg(msg);
if (code == '' || code == 'q' || code == 'Q')
{
abort = 1;
return(was_pause);
}
was_pause = 1;
pausing = NOT pausing;
if (pausing)
WaitPort(win->UserPort);
else
return(was_pause);
}
else
return(was_pause);
goto forever;
}
show_screen(scr , win , method , arg1 , arg2)
REGISTER struct Screen *scr;
REGISTER struct Window *win;
REGISTER WORD method , arg1 , arg2;
{
switch(method)
{
case 1: scrollup(scr , win , arg1);
break;
default:
scrollup(scr , win , -1);
break;
}
}
scrollup(scr , win , jump)
REGISTER struct Screen *scr;
REGISTER struct Window *win;
REGISTER WORD jump;
{
REGISTER WORD i , is_lace = (NOT (NOT (scr->ViewPort.Modes & LACE) ) ) + 1;
REGISTER WORD prev_pri = SetTaskPri(FindTask(NULL) , 9L);
if (jump < 1)
MoveScreen(scr , 0L , -9999L);
ScreenToFront(scr);
while (scr->TopEdge)
{
MoveScreen(scr , 0L , - (LONG) jump * is_lace);
chk_abort(win);
if (abort)
return;
}
SetTaskPri(FindTask(NULL) , (LONG) prev_pri);
}
struct Window *
MyOpenWindow(newwin , otherwin)
REGISTER struct NewWindow *newwin;
REGISTER struct Window *otherwin;
{
REGISTER struct Window *t_win;
if (NOT otherwin)
return(OpenWindow(newwin) );
newwin->IDCMPFlags = NULL;
if (NOT (t_win = OpenWindow(newwin) ) )
return(NULL);
t_win->UserPort = otherwin->UserPort;
ModifyIDCMP(t_win , otherwin->IDCMPFlags);
return(t_win);
}
CloseWindowSafely(p_wind)
REGISTER struct Window *p_wind;
{
REGISTER struct IntuiMessage *msg , *succ;
REGISTER struct Window *window = p_wind;
REGISTER struct MsgPort *mp = (struct MsgPort *) window->UserPort;
Forbid();
msg = (struct IntuiMessage *) mp->mp_MsgList.lh_Head;
while (succ = (struct IntuiMessage *) msg->ExecMessage.mn_Node.ln_Succ)
{
if (msg->IDCMPWindow == window)
{
Remove(msg);
ReplyMsg(msg);
}
msg = succ;
}
window->UserPort = NULL;
ModifyIDCMP(window , NULL);
Permit();
CloseWindow(window);
}