home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Resource Library: Graphics
/
graphics-16000.iso
/
msdos
/
animutil
/
artform
/
playback.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-03
|
15KB
|
642 lines
/********************************************************/
/* */
/* Main function and general user interfaces */
/* */
/********************************************************/
/* include files */
#include <io.h>
#include <dos.h>
#include <conio.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
/********************************************************/
/* Prototypes */
void videoplayback (char *, int, int);
long videoload (char *, long);
long contload (char *, long);
void *loadlist (char *, int);
void _far _interrupt playback ();
void (_far _interrupt *oldfun) (void);
void fastplay (void);
void videomode (void *);
int loadchart (void *, char *);
void videorecall (void *);
void loadcount (unsigned);
char videotest (void);
void textmode (void);
void romprint (char *);
/********************************************************/
/* Constants and macros */
#define MAXVID 200
#define FILEMAX 100
#define MK_FP(seg,ofs) ((void far *) \
(((unsigned long)(seg) << 16) | (unsigned)(ofs)))
#define pokeb(a,b,c) (*((char far*)MK_FP((a),(b))) = (char)(c))
/********************************************************/
/* Data structures */
typedef struct {
int xpos; /* top, left corner of display window */
int ypos;
int xlen; /* size of window */
int ylen;
unsigned base; /* window top, left corner displacement */
unsigned size; /* total number of bytes in frame */
void *data; /* pointer to frame data */
} frame;
typedef struct {
char name[16]; /* video file name */
int maxum; /* number of frames */
long size; /* size in bytes */
frame *photo[MAXVID]; /* pointers to frames */
} video;
typedef struct { /* list file information */
int max;
char name[FILEMAX][10];
int rate[FILEMAX];
int cycle[FILEMAX];
} agenda;
/********************************************************/
/* Main program procedure */
void main (int argc, char *argv[]){
int vest;
int rate;
int cycle;
int index;
int order;
unsigned count;
agenda *list;
rate = 0;
cycle = 0;
romprint ("");
romprint ("-=≡ARTFORM 3D≡=- Animated Graphics Playback");
vest = videotest ();
if (vest != 8){
romprint ("> VGA color video adapter required. Continue ? (Y/N)");
order = getch ();
if (order == 'Y' || order == 'y');
else return;}
romprint ("> Loading video file");
romprint ("> Please wait ...");
if (argc <= 1 || argc >= 5){
romprint ("> Playback <filename> {rate} {count}");
romprint ("> video/list optional optional");
return;}
if (argc == 3 || argc == 4) rate = atoi (argv[2]);
if (argc == 4) cycle = atoi (argv[3]);
list = loadlist (argv[1],rate);
if (list == NULL) videoplayback (argv[1], cycle, rate);
else { do { index = 0;
while (index < list->max && kbhit () == 0){
videoplayback (list->name[index],list->cycle[index],list->rate[index]);
index++;}
if (cycle >= 0) cycle--;
if (cycle == 0) ungetch (27);}
while (kbhit () == 0);
free (list);}
loadcount (0);
textmode ();
return;}
/********************************************************/
/* Test for VGA */
char videotest (){
char vest;
_asm { mov ax,1A00h
int 10h
mov vest,bl}
return (vest);}
/*********************************************************/
/* Mode 0x13 VGA 320 x 200 and 256 color */
void videomode (void *pointer){
_asm { mov ax,1200h /* enable palette init */
mov bl,31h
int 10h
mov ax,13h /* video mode */
int 10h
mov ax,1012h /* load new palette */
mov bx,0
mov cx,256
les dx,pointer
int 10h }
return;}
/********************************************************/
/* Standard text mode */
void textmode (){
_asm { mov ah,0 /* text mode */
mov al,3h
int 10h }}
/********************************************************/
/* load the video file color chart */
int loadchart (void *chart, char *filename){
FILE *load;
int version[8];
load = fopen (filename,"rb");
if (load == NULL) return (0);
else { fread (&version,8,2,load);
fread (chart,768,1,load);
fclose (load);}
return (version[0]);}
/********************************************************/
/* Print message in DOS */
void romprint (char *message){
int n = 0;
char chr;
while (message[n] != 0){
chr = message[n];
_asm { mov ah,0Eh
mov al,chr
mov bh,0
int 10h}
n++;}
_asm { mov ah,0Eh
mov al,10
mov bh,0
int 10h}
_asm { mov ah,0Eh
mov al,13
mov bh,0
int 10h}
return;}
/********************************************************/
/* Set timer/counter for frame rate interrupt */
void loadcount (unsigned word){
int msb,lsb;
lsb = word & 255;
msb = (word >> 8) & 255;
outp (0x43,54);
outp (0x40,lsb);
outp (0x40,msb);
return;}
/********************************************************/
/* Global variables */
int cell;
int frax;
int division;
int cont;
int link;
video *film;
/********************************************************/
/* Test and read list file */
void *loadlist (char *tempfile, int rate){
FILE *load;
int t,len,flag;
char buffer[16];
char listfile[16];
char line[128];
agenda *list;
strcpy (listfile,tempfile);
if (strstr (listfile,".lst") == NULL) strcat (listfile,".lst");
if (access (listfile,0) != 0) return (NULL);
list = malloc (sizeof (agenda));
list->max = 0;
for (len = 0; len < FILEMAX; len++) list->name[len][0] = 0;
load = fopen (listfile,"rt");
while (ferror (load) == 0 && feof (load) == 0 && list->max < FILEMAX){
if (fgets (line,128,load) == NULL) break;
t = 0;
len = 0;
while (isalnum (line[t]) != 0){
list->name[list->max][len] = line[t];
len++;
t++;}
list->name[list->max][len] = 0;
if (line[t] == 32){
len = 0;
t++;
while (isdigit (line[t]) != 0 && len < 16){
buffer[len] = line[t];
len++;
t++;}
buffer[len] = 0;
list->rate[list->max] = atoi (buffer);}
else list->rate[list->max] = rate;
if (line[t] == 32){
len = 0;
t++;
while (isdigit (line[t]) != 0 && len < 16){
buffer[len] = line[t];
len++;
t++;}
buffer[len] = 0;
list->cycle[list->max] = atoi (buffer);}
else list->cycle[list->max] = 1;
list->max++;}
fclose (load);
return (list);}
/********************************************************/
/* Play back video file */
void videoplayback (char *filename, int cycle, int rate){
int n,order,len,base;
int count,pos;
long offset;
unsigned init;
char buffer[16];
char *vgamem = MK_FP (0xA000,0);
void *palette;
division = 2;
if (rate > 0){
if (rate < 10) division = 20 / rate + 1;
init = (unsigned) (1.19e6 / division / rate);}
palette = malloc (768);
film = malloc (sizeof (video));
strcpy (buffer,filename);
if (strstr (buffer,".vdo") == NULL) strcat (buffer,".vdo");
order = loadchart (palette,buffer);
if (order != 2) goto escape;
offset = videoload (buffer,0);
if (offset == 0) cont = 0;
else cont = 1;
videomode (palette);
cell = 0;
order = 25;
if (cycle == 0) cycle--;
while (cycle != 0 && film->maxum > 0 && order == 25){
if (rate == 0){
fastplay ();
order = getch ();
if (order == 0) order = getch ();
while (kbhit () != 0) getch ();
if (order == 27) ungetch (27);
if (cont == 1) for (n=0;n<film->maxum;n++){
free (film->photo[n]->data);
free (film->photo[n]);}
if (order == 25 && offset == 0 && cycle > 0) cycle--;
if (order != 25 || cont == 1 || cycle == 0){
for (n=0;n<film->maxum;n++){
free (film->photo[n]->data);
free (film->photo[n]);}}
if (order == 25 && cont == 1 && cycle != 0)
offset = videoload (buffer,offset);}
else { _disable ();
loadcount (init);
frax = division;
oldfun = _dos_getvect (0x1C);
_dos_setvect (0x1C,playback);
link = cycle;
_enable ();
if (cont == 1 && offset != 0)
offset = contload (buffer,offset);
else while (kbhit () == 0);
_disable ();
cycle = link;
_dos_setvect (0x1C,oldfun);
_enable ();
loadcount (0);
order = getch ();
if (order == 0) order = getch ();
while (kbhit () != 0) getch ();
if (order == 27) ungetch (27);
if (offset == 0 && cycle > 0) cycle--;
if (order != 25 || cycle == 0){
for (n=0;n<film->maxum;n++){
free (film->photo[n]->data);
free (film->photo[n]);}}
if (order != 25) break;
if (cont == 1 && order == 25 && cycle != 0)
offset = videoload (buffer,offset);}}
escape: free (film);
free (palette);}
/********************************************************/
/* Load a video file */
long videoload (char *filename, long offset){
FILE *load;
int num;
int flag;
int xpos;
int ypos;
int xlen;
int ylen;
long base;
long size;
void *data;
film->size = 0;
film->maxum = 0;
load = fopen (filename,"rb");
num = fileno (load);
lseek (num,784,0);
if (offset > 0) lseek (num,offset,1);
do { flag = 0;
if (film->maxum == MAXVID) flag = 2;
else if (eof (num) == 0){
film->photo[film->maxum] = malloc (sizeof (frame));
if (film->photo[film->maxum] == NULL) flag = 2;
else { read (num,&xpos,2);
read (num,&ypos,2);
read (num,&xlen,2);
read (num,&ylen,2);
read (num,&base,4);
read (num,&size,4);
if (size > 0){
data = malloc ((unsigned) size);
if (data == NULL){
flag = 2;
free (film->photo[film->maxum]);}
else { read (num, data, (unsigned) size);
offset = offset + size + 16;
film->photo[film->maxum]->xpos = xpos;
film->photo[film->maxum]->ypos = ypos;
film->photo[film->maxum]->xlen = xlen;
film->photo[film->maxum]->ylen = ylen;
film->photo[film->maxum]->base = (unsigned) base;
film->photo[film->maxum]->size = (unsigned) size;
film->photo[film->maxum]->data = data;
film->size = film->size + size;
film->maxum++;}}}}
else flag = 1;}
while (flag == 0);
fclose (load);
if (flag == 2) return (offset);
return (0);}
/********************************************************/
/* Continuously load a video file */
long contload (char *filename, long offset){
FILE *load;
int num;
int flag;
int xpos;
int ypos;
int xlen;
int ylen;
long base;
long size;
void *data;
load = fopen (filename,"rb");
num = fileno (load);
lseek (num,784,0);
if (offset > 0) lseek (num,offset,1);
do { while (film->maxum == MAXVID);
if (eof (num) == 0){
do film->photo[film->maxum] = malloc (sizeof (frame));
while (film->photo[film->maxum] == NULL);
read (num,&xpos,2);
read (num,&ypos,2);
read (num,&xlen,2);
read (num,&ylen,2);
read (num,&base,4);
read (num,&size,4);
if (size > 0 && eof (num) == 0){
do data = malloc ((unsigned) size);
while (data == NULL);
read (num, data, (unsigned) size);
offset = offset + size + 16;
film->photo[film->maxum]->xpos = xpos;
film->photo[film->maxum]->ypos = ypos;
film->photo[film->maxum]->xlen = xlen;
film->photo[film->maxum]->ylen = ylen;
film->photo[film->maxum]->base = (unsigned) base;
film->photo[film->maxum]->size = (unsigned) size;
film->photo[film->maxum]->data = data;
film->size = film->size + size;
film->maxum++;}}
else { while (kbhit () == 0);
fclose (load);
return (0);}}
while (kbhit () == 0);
fclose (load);
return (offset);}
/********************************************************/
/* Prepare to display a video frame */
void _cdecl _far _interrupt playback (){
int n;
_disable ();
frax--;
if (frax == 0){
if (cont == 1){
if (film->maxum > 0){
videorecall (film->photo[0]);
free (film->photo[0]->data);
free (film->photo[0]);
memcpy (&film->photo[0], &film->photo[1], film->maxum << 2);
film->maxum--;}
else ungetch (25);}
else { videorecall (film->photo[cell]);
cell++;
if (cell == film->maxum){
cell = 0;
if (link > 0) link--;
if (link == 0) ungetch (25);}}
frax = division;}
else if (frax == 1) oldfun ();
_enable ();}
/********************************************************/
/* Display video frames continuously */
void fastplay (){
do { _disable ();
videorecall (film->photo[cell]);
_enable ();
cell++;
if (cell == film->maxum){
cell = 0;
ungetch (25);}}
while (kbhit () == 0);
return;}
/********************************************************/
/* Decompress and display a video frame */
void videorecall (void *link){
frame *photo = link;
void *data = photo->data;
unsigned index = photo->ylen;
unsigned base = photo->base;
if (photo->size == 0) return;
_asm { cld
push ds
push si
push di
lds si,data
mov dx,base
rego: mov bx,[si]
cmp bx,0
jz end
inc si
inc si
mov cx,0A000h
mov es,cx
mov di,dx
mov cx,0
mark: lodsw
mov cl,ah
cmp cl,0
jz single
cmp cl,255
jz blank
jmp skip
single: mov cl,al
sub bx,cx
rep movsb
dec bx
dec bx
jnz mark
jmp end
blank: mov cl,al
add di,cx
dec bx
dec bx
jnz mark
jmp end
skip: rep stosb
dec bx
dec bx
jnz mark
end: add dx,320
dec index
jnz rego
pop di
pop si
pop ds}
return;}
/********************************************************/
/************************************************/
/****************************************/