diff options
Diffstat (limited to 'fbmngplay')
-rw-r--r-- | fbmngplay/ChangeLog | 33 | ||||
-rw-r--r-- | fbmngplay/Makefile | 69 | ||||
-rw-r--r-- | fbmngplay/README | 30 | ||||
-rw-r--r-- | fbmngplay/console.c | 45 | ||||
-rw-r--r-- | fbmngplay/console.h | 21 | ||||
-rw-r--r-- | fbmngplay/fbmngplay.c | 250 | ||||
-rw-r--r-- | fbmngplay/fbmngplay.h | 45 | ||||
-rw-r--r-- | fbmngplay/messages.c | 43 | ||||
-rw-r--r-- | fbmngplay/messages.h | 19 | ||||
-rw-r--r-- | fbmngplay/mng.c | 421 | ||||
-rw-r--r-- | fbmngplay/mng.h | 38 |
11 files changed, 1014 insertions, 0 deletions
diff --git a/fbmngplay/ChangeLog b/fbmngplay/ChangeLog new file mode 100644 index 0000000..91956f8 --- /dev/null +++ b/fbmngplay/ChangeLog @@ -0,0 +1,33 @@ +******************* Sun Nov 17 02:19:34 CET 2002 ********************* + +* fix fbmngplay to cope with 15bit displays that state they are 16bit + (aty128fb on ppc) + +******************* Tue Sep 3 15:28:20 CEST 2002 ******************** + +* get rid of dynamic positioning code (moved to theme config files + for flexibility. + +******************* Mon Mar 18 14:56:29 CET 2002 ********************* + +* rewrite console detection code. +* fix console chosing code to show pictures on the right console + only, when booting or shutting down the system. +* get rid of obsolete code fragments. + +******************* Wed Sep 19 17:25:19 CEST 2001 ******************** + +* gnore multiple USR1 signals to prevent halt animation to + stop early +* if console is one, and you are not on it, exit. + +******************* Thu Sep 13 15:28:01 CEST 2001 ******************** + +* new option -S to play on start console only. +* new option -c to play animationon any fb console +* split fbmngplay to several files. + +******************* Wed Sep 12 14:51:44 CEST 2001 ******************** + +* new option -p for dynamic positioning of the mng animation in the + upper right corner. diff --git a/fbmngplay/Makefile b/fbmngplay/Makefile new file mode 100644 index 0000000..ccde3dd --- /dev/null +++ b/fbmngplay/Makefile @@ -0,0 +1,69 @@ +# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +ARCH = $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/) +SHELL = /bin/sh +CC = gcc +STRIP = strip + +# Triggering lib64 path from spec file. +ifeq ($(PREFIX)x,x) +PREFIX = $(prefix)/usr +endif +ifeq ($(LIB)x,x) +LIB = lib +endif +LIBDIR = /usr/$(LIB) +bindir = $(PREFIX)/bin + +PROGRAMS = fbmngplay fbmngplay.static +OBJECTS = fbmngplay.o messages.o mng.o console.o + +LDFLAGS = -L$(LIBDIR) +LIBSS = $(LIBDIR)/libmng.a $(LIBDIR)/libz.a $(LIBDIR)/libjpeg.a -lm +LIBSD = -lmng -lz -lm + +CFLAGS = -O2 -Wall +COMPILE = $(CC) $(CFLAGS) +LINKS = $(CC) $(CFLAGS) $(LDFLAGS) -static -o $@ +LINKD = $(CC) $(CFLAGS) $(LDFLAGS) -o $@ + +all: $(PROGRAMS) strip + +.SUFFIXES: +.SUFFIXES: .S .c .o .s + +.s.o: + $(COMPILE) -c $< + +.S.o: + $(COMPILE) -c $< + +mostlyclean: + -rm -f *.o core +clean: mostlyclean + -rm -f fbmngplay fbmngplay.static + +install: + install -m 755 -d $(bindir) + install -m755 fbmngplay.static $(prefix)/bin + install -m755 fbmngplay $(bindir) + +fbmngplay: $(OBJECTS) + @rm -f fbmngplay + $(LINKD) $(LDFLAGS) $(OBJECTS) $(LIBSD) +fbmngplay.static: $(OBJECTS) + @rm -f fbmngplay.static + $(LINKS) $(LDFLAGS) $(OBJECTS) $(LIBSS) + +strip: $(PROGRAMS) + $(STRIP) -s $(PROGRAMS) + +.PHONY: mostlyclean clean fbmngplay fbmngplay.static all strip diff --git a/fbmngplay/README b/fbmngplay/README new file mode 100644 index 0000000..1ffec8f --- /dev/null +++ b/fbmngplay/README @@ -0,0 +1,30 @@ +* fbmngplay * + +a simple fbcon based mng player + +This is a simple example program, using the kernel framebuffer device +to display mng animation decoded by the new libmng implementation. + +This player is based on the SDL version included in the libmng package +from Ralph Giles <giles@ashlu.bc.ca>. The code's fairly rough at this +point, but there was no example player for *nix in the distribution. +Patches welcome, of course. + +On a unix-like system, the build instructions are simple: + +(install and/or build the mng library from libmng.com) +make +make install + +To use the player: + +fbmngplay <filename>.mng <filename>.mng ... + +To stop looping animations, press CTRL C or send a TERM or INT signal. + +See the options with +fbmngplay -h + +--- +Stefan Reinauer, <stepan@suse.de> +$Date$ diff --git a/fbmngplay/console.c b/fbmngplay/console.c new file mode 100644 index 0000000..8bc7991 --- /dev/null +++ b/fbmngplay/console.c @@ -0,0 +1,45 @@ +/* + * fbmngplay - framebuffer console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, part of libmng, written and (C) by + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <errno.h> +#include <linux/kd.h> +#include <linux/vt.h> +#include <sys/ioctl.h> + +#include "console.h" + +int start_console = 0; +int fd; + +int current_console(void) +{ + int result=0; + char twelve=12; + + result = ioctl(fd, TIOCLINUX, &twelve); + + return result; +} + +void init_consoles(void) +{ + fd=open("/dev/tty0", O_RDWR|O_NDELAY); + if (fd<0) { + fprintf(stderr, "Could not open virtual terminal.\n"); + exit (1); + } +} + diff --git a/fbmngplay/console.h b/fbmngplay/console.h new file mode 100644 index 0000000..e9832f2 --- /dev/null +++ b/fbmngplay/console.h @@ -0,0 +1,21 @@ +/* + * fbmngplay - fb console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, part of libmng, written and (C) by + * + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#ifndef __CONSOLES_H +#define __CONSOLES_H + +extern void init_consoles(void); +extern int current_console(void); +extern int start_console; + +#endif diff --git a/fbmngplay/fbmngplay.c b/fbmngplay/fbmngplay.c new file mode 100644 index 0000000..d0dbac2 --- /dev/null +++ b/fbmngplay/fbmngplay.c @@ -0,0 +1,250 @@ +/* + * fbmngplay - fb console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, written and (C) by + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#include <unistd.h> +#include <fcntl.h> +#include <getopt.h> +#include <sys/mman.h> +#include <sys/ioctl.h> +#include <linux/fb.h> +#include <signal.h> + +#include "fbmngplay.h" +#include "messages.h" +#include "console.h" +#include "mng.h" + +volatile int run = 1; +int verbose = 0; +int buffered = 0; +int waitsignal = 0; +int delta = 16; +int sconly=0; + +/* + * Signal handlers + */ + +void sigint_handler(int sig) +{ + if (waitsignal) + return; + run = 2; +} + +void sigterm_handler(int sig) +{ + if (waitsignal) + return; + restore_area(); + run = 0; +} + +void sigusr1_handler(int sig) +{ + signal(SIGUSR1, SIG_IGN); + run = 0; +} + +/* + * Main loop + */ + +int main(int argc, char *argv[]) +{ + int fbdev,c,option_index; + unsigned int alpha; + struct fb_var_screeninfo var; + struct fb_fix_screeninfo fix; + + /* Check which console we're running on */ + init_consoles(); + + /* allocate our stream data structure */ + mng = (mngstuff *) calloc(1, sizeof(*mng)); + if (mng == NULL) { + fprintf(stderr, "could not allocate stream structure.\n"); + exit(0); + } + + alpha = 100; + mng->alpha = 100; + mng->fbx = 15; + mng->fby = 15; + mng->background = NULL; + + while (1) { + static struct option long_options[] = { + {"help", 0, 0, 'h'}, + {"verbose", 0, 0, 'v'}, + {"alpha", 1, 0, 'a'}, + {"buffered", 0, 0, 'b'}, + {"signal", 0, 0, 's'}, + {"delta", 0, 0, 'd'}, + {"version", 0, 0, 'V'}, + {"start-console",0,0,'S'}, + {"console",1,0,'c'}, + {0, 0, 0, 0} + }; + + c = getopt_long(argc, argv, "a:x:y:bh?vsd:VSc:", + long_options, &option_index); + + if (c == -1) + break; + + switch (c) { + case 'a': + alpha = atoi(optarg); + if (alpha > 100) + alpha = 100; + mng->alpha = alpha; + break; + case 'x': + mng->fbx = atoi(optarg); + break; + case 'y': + mng->fby = atoi(optarg); + break; + case 'd': + delta = atoi(optarg); + break; + case '?': + case 'h': + usage(argv[0]); + exit(0); + case 'v': + verbose = 1; + break; + case 's': + waitsignal = 1; + break; + case 'b': + buffered = 1; + break; + case 'V': + version(); + exit(0); + case 'c': + start_console=atoi(optarg)-1; + case 'S': + sconly=1; + break; + default: + break; + } + } +#if 0 + if (!output && optind >= argc) { +#else + if (optind >= argc) { +#endif + printf("Which files do you want to play?\n"); + exit(0); + } + + /* Initialize framebuffer */ + fbdev = open("/dev/fb0", O_RDWR); + if (fbdev < 0) { + fprintf(stderr, "error while opening framebuffer.\n"); + exit(fbdev); + } + + ioctl(fbdev, FBIOGET_VSCREENINFO, &var); + mng->fbwidth = var.xres; + mng->fbheight = var.yres; + mng->fbbpp = var.bits_per_pixel; + + mng->fbredo = var.red.offset; + mng->fbgreeno = var.green.offset; + mng->fbblueo = var.blue.offset; + mng->fbredl = var.red.length; + mng->fbgreenl = var.green.length; + mng->fbbluel = var.blue.length; + + /* Display might have a line length unequal + * the visible line. + */ + ioctl(fbdev, FBIOGET_FSCREENINFO, &fix); + mng->fbrow = fix.line_length; + + mng->display = + mmap(NULL, mng->fbrow * mng->fbheight , + PROT_WRITE | PROT_READ, MAP_SHARED, fbdev, 0); +#if 0 + if (output) + prepare_output(); +#endif + /* arrange to call the shutdown routine before we exit */ + atexit(&cleanup); + + while (optind < argc) { + /* leftover arguements are filenames. */ + mng->filename = argv[optind++]; + + /* set up the mng decoder for our stream */ + mng->mng = mng_initialize(mng, mngalloc, mngfree, MNG_NULL); + if (mng->mng == MNG_NULL) { + fprintf(stderr, "could not initialize libmng.\n"); + exit(1); + } + + /* set the callbacks */ + mng_setcb_errorproc(mng->mng, mngerror); + mng_setcb_openstream(mng->mng, mngopenstream); + mng_setcb_closestream(mng->mng, mngclosestream); + mng_setcb_readdata(mng->mng, mngreadstream); + mng_setcb_gettickcount(mng->mng, mnggetticks); + mng_setcb_settimer(mng->mng, mngsettimer); + mng_setcb_processheader(mng->mng, mngprocessheader); + mng_setcb_getcanvasline(mng->mng, mnggetcanvasline); + mng_setcb_refresh(mng->mng, mngrefresh); + + signal(SIGINT, sigint_handler); + signal(SIGTERM, sigterm_handler); + + mng_readdisplay(mng->mng); + + /* loop though the frames */ + while (mng->delay && run) { + usleep(mng->delay * 1000); + mng->delay = 0; + mng_display_resume(mng->mng); + if (run == 2) { + if (mng->alpha == 0) + run = 0; + mng->alpha -= delta; + if (mng->alpha < 0) + mng->alpha = 0; + } + } + + if (waitsignal && optind < argc) { + signal(SIGUSR1, sigusr1_handler); + run = 1; + while (run) { + sleep(2); + } + } + + memset(mng->copybuffer, 0, + 4 * mng->width * mng->height); + run = 1; + mng->alpha = alpha; + if (optind == argc) { /* last file */ + restore_area(); + } + } + + /* cleanup and quit */ + return mngquit(mng->mng); +} diff --git a/fbmngplay/fbmngplay.h b/fbmngplay/fbmngplay.h new file mode 100644 index 0000000..34d3259 --- /dev/null +++ b/fbmngplay/fbmngplay.h @@ -0,0 +1,45 @@ +/* + * fbmngplay - fb console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, part of libmng, written and (C) by + * + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#ifndef __FBMNGPLAY_H +#define __FBMNGPLAY_H + +#include <libmng.h> + +#define FBMNGPLAY_VERSION "0.5.1" + +/* structure for keeping track of our mng stream inside the callbacks */ +typedef struct { + FILE *file; /* pointer to the file we're decoding */ + char *filename; /* pointer to the file's path/name */ + mng_uint32 delay; /* ticks to wait before resuming decode */ + unsigned char *display; /* pointer to display */ + unsigned char *copybuffer; + unsigned char *background; + mng_handle mng; /* mng handle */ + int width, height; + int fbwidth, fbheight, fbbpp, fbrow; + int fbx, fby; + int fbredo, fbredl, fbgreeno, fbgreenl, fbblueo, fbbluel; + int alpha; +} mngstuff; + +extern volatile int run; +extern int verbose; +extern int buffered; +extern int dynpos; +extern int waitsignal; +extern int delta; +extern int sconly; + +#endif diff --git a/fbmngplay/messages.c b/fbmngplay/messages.c new file mode 100644 index 0000000..6bc2aa4 --- /dev/null +++ b/fbmngplay/messages.c @@ -0,0 +1,43 @@ +/* + * fbmngplay - fb console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, part of libmng, written and (C) by + * + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#include <stdio.h> +#include "fbmngplay.h" +#include "messages.h" + +void usage(char *name) +{ + fprintf(stderr, "\nusage: %s [ -x <val> ] [ -y <val> ] [ -a <val> ] [-b] [-v]" + " [-s] [file.mng [file.mng [...]]]\n", name); + fprintf(stderr, + "\n -x: x coordinate\n" + " -y: y coordinate\n" + " -a, --alpha: default alpha channel 1..100\n" + " -v, --verbose: verbose mode\n" + " -b, --buffered: buffered mode\n" + " -s, --signal: wait for SIGUSR1 between animations\n" + " -p, --position: dynamically select position\n" + " -V, --version: show version and exit\n" + " -?, -h, --help: print this help.\n" + " -S --start-console: only output animation on console it was started on.\n" + " -c: start output animation on specified console.\n\n"); +} + +void version(void) +{ + fprintf(stderr, + "fbmngplay v%s, Copyright (C) 2001-2002 Stefan Reinauer <stepan@suse.de>\n\n" + "fbmngplay comes with ABSOLUTELY NO WARRANTY;\n" + "This is free software, and you are welcome to redistribute it\n" + "under certain conditions; Check the GPL for details.\n", FBMNGPLAY_VERSION); +} diff --git a/fbmngplay/messages.h b/fbmngplay/messages.h new file mode 100644 index 0000000..bc8c95b --- /dev/null +++ b/fbmngplay/messages.h @@ -0,0 +1,19 @@ +/* + * fbmngplay - fb console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, part of libmng, written and (C) by + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#ifndef __MESSAGES_H +#define __MESSAGES_H + +extern void usage(char *name); +extern void version(void); + +#endif diff --git a/fbmngplay/mng.c b/fbmngplay/mng.c new file mode 100644 index 0000000..9728975 --- /dev/null +++ b/fbmngplay/mng.c @@ -0,0 +1,421 @@ +/* + * fbmngplay - fb console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, part of libmng, written and (C) by + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#include <unistd.h> +#include <sys/time.h> + +#include "fbmngplay.h" +#include "console.h" +#include "mng.h" + +mngstuff *mng; +unsigned char *bufferstream; +unsigned long bufferpos = 0, buffersize = 0; + +/* + * callbacks for the mng decoder + */ + +/* memory allocation; data must be zeroed */ +mng_ptr mngalloc(mng_uint32 size) +{ + return (mng_ptr) calloc(1, size); +} + +/* memory deallocation */ +void mngfree(mng_ptr p, mng_uint32 size) +{ + free(p); + return; +} + +mng_bool mngopenstream(mng_handle mng) +{ + mngstuff *mymng; + + /* look up our stream struct */ + mymng = (mngstuff *) mng_get_userdata(mng); + + /* open the file */ + mymng->file = fopen(mymng->filename, "rb"); + if (mymng->file == NULL) { + fprintf(stderr, "unable to open '%s'\n", mymng->filename); + run = 0; + return MNG_FALSE; + } + + if (buffered) { + unsigned long len; + fseek(mymng->file, 0, SEEK_END); + len = ftell(mymng->file); + rewind(mymng->file); + bufferstream = malloc(len); + if (!bufferstream) { + /* Not enough memory for buffers + * -> we go back to unbuffered mode + */ + printf("Reverted to non buffered mode.\n"); + buffered = 0; + return MNG_TRUE; + } + buffersize = len; + fread(bufferstream, 1, len, mymng->file); + bufferpos = 0; + fclose(mymng->file); + mymng->file = NULL; + } + + return MNG_TRUE; +} + +mng_bool mngclosestream(mng_handle mng) +{ + mngstuff *mymng; + + /* look up our stream struct */ + mymng = (mngstuff *) mng_get_userdata(mng); + + /* close the file */ + if (mymng->file) + fclose(mymng->file); + mymng->file = NULL; /* for safety */ + + if (bufferstream) { + free(bufferstream); + bufferstream = 0; + buffersize = 0; + bufferpos = 0; + } + return MNG_TRUE; +} + +/* feed data to the decoder */ +mng_bool mngreadstream(mng_handle mng, mng_ptr buffer, + mng_uint32 size, mng_uint32 * bytesread) +{ + mngstuff *mymng; + + /* look up our stream struct */ + mymng = (mngstuff *) mng_get_userdata(mng); + if (!buffered) { + /* read the requested amount of data from the file */ + *bytesread = fread(buffer, 1, size, mymng->file); + } else { + *bytesread = (buffersize - bufferpos) < + size ? (buffersize - bufferpos) : size; + memcpy(buffer, bufferstream + bufferpos, *bytesread); + bufferpos += (*bytesread); + } + return MNG_TRUE; +} + +mng_bool mnggetbackgroundbuffer(mng_handle mng) +{ + unsigned char *background, *src; + mngstuff *mymng=mng_get_userdata(mng); + mng_uint32 width=mymng->width, height=mymng->height; + int bytes=(mymng->fbbpp >> 3); + + if (mymng->background) + return MNG_TRUE; + + /* If we're not on the right terminal, don't + * initialize background yet. + */ + if (sconly && current_console()!=start_console) + return MNG_FALSE; + + background = (unsigned char *) malloc(width * height * bytes); + if (background == NULL) { + fprintf(stderr, "could not allocate background buffer.\n"); + exit(0); + } + + mymng->background = background; + src = mymng->display + (mymng->fbwidth * mymng->fby + mymng->fbx) * bytes; + + while (height--) { + memcpy(background, src, width * bytes); + background += width * bytes; + src += mymng->fbrow; + } + + return MNG_TRUE; +} + +/* the header's been read. set up the display stuff */ +mng_bool mngprocessheader(mng_handle mng, + mng_uint32 width, mng_uint32 height) +{ + mngstuff *mymng; + unsigned char *copybuffer; + + mymng = (mngstuff *) mng_get_userdata(mng); + mymng->width = width; + mymng->height = height; + + copybuffer = (unsigned char *) malloc(width * height * 4); + if (copybuffer == NULL) { + fprintf(stderr, "could not allocate copy buffer.\n"); + exit(0); + } + mymng->copybuffer = copybuffer; + + /* Try to get background buffer */ + mnggetbackgroundbuffer(mng); + + /* tell the mng decoder about our bit-depth choice */ + /* FIXME: this works on intel. is it correct in general? */ + mng_set_canvasstyle(mng, MNG_CANVAS_BGRA8); + + return MNG_TRUE; +} + +/* return a row pointer for the decoder to fill */ +mng_ptr mnggetcanvasline(mng_handle mng, mng_uint32 line) +{ + mngstuff *mymng; + mng_ptr row; + + /* dereference our structure */ + mymng = (mngstuff *) mng_get_userdata(mng); + + /* we assume any necessary locking has happened + outside, in the frame level code */ + row = mymng->copybuffer + mymng->width * 4 * line; + + return (row); +} + +/* timer */ +mng_uint32 mnggetticks(mng_handle mng) +{ + mng_uint32 ticks; + struct timeval tv; + struct timezone tz; + + gettimeofday(&tv, &tz); + ticks = (tv.tv_sec * 1000) + (tv.tv_usec / 1000); + + return (ticks); +} + +static inline void copyline(unsigned char *dest, unsigned char *src, + unsigned char *background, mngstuff * mymng) +{ + // BGRA8 + unsigned int i = mymng->width; + unsigned int fr, fg, fb, br, bg, bb, r, g, b, a; + unsigned short output, input; + + while (i--) { + fb = *src++; + fg = *src++; + fr = *src++; + + a = *src++; + a = a * mymng->alpha / 100; + switch (mymng->fbbpp) { + case 16: + input = *((unsigned short *) background)++; + + br = (input >> mng->fbredo) << (8-mng->fbredl); + bg = (input >> mng->fbgreeno) << (8-mng->fbgreenl); + bb = (input >> mng->fbblueo) << (8-mng->fbbluel); + br &= 0xf8; + bg &= 0xfc; + bb &= 0xff; +#if 0 + br = (input >> 8) & 0xf8; + bg = (input >> 3) & 0xfc; + bb = input << 3 & 0xff; +#endif + break; + case 24: + bb = *background++; + bg = *background++; + br = *background++; + break; + case 32: + bb = *background++; + bg = *background++; + br = *background++; + background++; + break; + default: + br = 0; + bg = 0; + bb = 0; + printf("depth not supported.\n"); + run = 0; + break; + } + + r = ((fr * a) + (br * (0x100 - a))) >> 8; + g = ((fg * a) + (bg * (0x100 - a))) >> 8; + b = ((fb * a) + (bb * (0x100 - a))) >> 8; + + switch (mymng->fbbpp) { + case 16: + // dumb 24->16 bit conversion. + r >>= (8-mng->fbredl); + g >>= (8-mng->fbgreenl); + b >>= (8-mng->fbbluel); + + output = (r << mng->fbredo) | (g << mng->fbgreeno) | (b << mng->fbblueo); + + *((unsigned short *) dest)++ = output; + break; + case 24: + *dest++ = b; + *dest++ = g; + *dest++ = r; + break; + case 32: + *dest++ = b; + *dest++ = g; + *dest++ = r; + dest++; + break; + default: + break; + } + } +} + +mng_bool mngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, + mng_uint32 w, mng_uint32 h) +{ + mngstuff *mymng=mng_get_userdata(mng); + unsigned char *background; + unsigned char *dest, *src; + int bytes=(mymng->fbbpp >> 3); + + if (sconly && current_console()!=start_console) + return MNG_TRUE; + + /* When we read the header, we might still + * have been on a different console + */ + + if (!(mymng->background)) + mnggetbackgroundbuffer(mng); + + background = mymng->background; + + dest = mymng->display+(mymng->fby*mymng->fbwidth + mymng->fbx)*bytes; + src = mymng->copybuffer; + + /* refresh the screen with the new frame */ + while (h-- > 0) { + copyline(dest, src, background, mymng); + + dest += mymng->fbrow; + background += mymng->width * bytes; + /* 4 bytes per pixel due to RGBA */ + src += 4 * mymng->width; + } + + /* remove traces in alpha transparent pictures. */ + memset(mymng->copybuffer, 0, 4 * mymng->width * mymng->height); + + return MNG_TRUE; +} + +/* interframe delay callback */ +mng_bool mngsettimer(mng_handle mng, mng_uint32 msecs) +{ + mngstuff *mymng; + + /* look up our stream struct */ + mymng = (mngstuff *) mng_get_userdata(mng); + + /* set the timer for when the decoder wants to be woken */ + mymng->delay = msecs; + + return MNG_TRUE; +} + +mng_bool mngerror(mng_handle mng, mng_int32 code, mng_int8 severity, + mng_chunkid chunktype, mng_uint32 chunkseq, + mng_int32 extra1, mng_int32 extra2, mng_pchar text) +{ + mngstuff *mymng; + char chunk[5]; + + /* dereference our data so we can get the filename */ + mymng = (mngstuff *) mng_get_userdata(mng); + /* pull out the chuck type as a string */ + // FIXME: does this assume unsigned char? + chunk[0] = (char) ((chunktype >> 24) & 0xFF); + chunk[1] = (char) ((chunktype >> 16) & 0xFF); + chunk[2] = (char) ((chunktype >> 8) & 0xFF); + chunk[3] = (char) ((chunktype) & 0xFF); + chunk[4] = '\0'; + + /* output the error */ + fprintf(stderr, "error playing '%s' chunk %s (%d):\n", + mymng->filename, chunk, chunkseq); + fprintf(stderr, "%s\n", text); + + return 0; +} + +int mngquit(mng_handle mng) +{ + mngstuff *mymng; + + /* dereference our data so we can free it */ + mymng = (mngstuff *) mng_get_userdata(mng); + + /* cleanup. this will call mymngclosestream */ + mng_cleanup(&mng); + + /* free our data */ + free(mymng); + + exit(0); +} + +void cleanup(void) +{ + mngquit(mng->mng); + exit(0); +} + +void restore_area(void) +{ + int height, width; + unsigned char *dest, *background; + + if (sconly && current_console()!=start_console) + return; + + /* when we didn't manage to get a background until + * now, we don't have anything to restore anyways. + */ + + if (!(mng->background)) + return; + + background = mng->background; + height = mng->height; + width = mng->width; + dest = mng->display + (( mng->fbwidth*mng->fby + mng->fbx) * + (mng->fbbpp>>3)); + + while (height--) { + memcpy(dest, background, width * (mng->fbbpp >> 3)); + background += width * (mng->fbbpp >> 3); + dest += mng->fbrow; + } +} diff --git a/fbmngplay/mng.h b/fbmngplay/mng.h new file mode 100644 index 0000000..bbe8af2 --- /dev/null +++ b/fbmngplay/mng.h @@ -0,0 +1,38 @@ +/* + * fbmngplay - fb console MNG player. + * (c) 2001-2002 by Stefan Reinauer, <stepan@suse.de> + * + * This program is based on mngplay, part of libmng, written and (C) by + * Ralph Giles <giles@ashlu.bc.ca> + * + * This program my be redistributed under the terms of the + * GNU General Public Licence, version 2, or at your preference, + * any later version. + */ + +#ifndef __HOOKS_H +#define __HOOKS_H + +#include "fbmngplay.h" + +extern mngstuff *mng; + +mng_ptr mngalloc(mng_uint32 size); +void mngfree(mng_ptr p, mng_uint32 size); +mng_bool mngopenstream(mng_handle mng); +mng_bool mngclosestream(mng_handle mng); +mng_bool mngreadstream( mng_handle mng, mng_ptr buffer, mng_uint32 size, mng_uint32 * bytesread); +mng_bool mngprocessheader( mng_handle mng, mng_uint32 width, mng_uint32 height); +mng_ptr mnggetcanvasline(mng_handle mng, mng_uint32 line); +mng_uint32 mnggetticks(mng_handle mng); +mng_bool mngrefresh(mng_handle mng, mng_uint32 x, mng_uint32 y, mng_uint32 w, mng_uint32 h); +mng_bool mngsettimer(mng_handle mng, mng_uint32 msecs); +mng_bool mngerror(mng_handle mng, mng_int32 code, mng_int8 severity, + mng_chunkid chunktype, mng_uint32 chunkseq, + mng_int32 extra1, mng_int32 extra2, mng_pchar text); +int mngquit(mng_handle mng); +void cleanup(void); +void restore_area(void); + +#endif + |