dslinux/user/pixil/packages/flash/flash/Lib Makefile adpcm.cc adpcm.h bitmap.cc bitmap.h button.cc button.h character.cc character.h cxform.cc cxform.h displaylist.cc displaylist.h flash.cc flash.h font.cc font.h graphic.cc graphic.h graphic16.cc graphic16.h graphic24.cc graphic24.h graphic32.cc graphic32.h graphic_generic.cc matrix.cc matrix.h movie.cc movie.h mp3.cc mp3.h program.cc program.h rect.h script.cc script.h shape.cc shape.h sound.cc sound.h sprite.cc sprite.h sqrt.cc sqrt.h swf.h text.cc text.h
amadeus
dslinux_amadeus at user.in-berlin.de
Tue Oct 3 13:26:12 CEST 2006
Update of /cvsroot/dslinux/dslinux/user/pixil/packages/flash/flash/Lib
In directory antilope:/tmp/cvs-serv11916/packages/flash/flash/Lib
Added Files:
Makefile adpcm.cc adpcm.h bitmap.cc bitmap.h button.cc
button.h character.cc character.h cxform.cc cxform.h
displaylist.cc displaylist.h flash.cc flash.h font.cc font.h
graphic.cc graphic.h graphic16.cc graphic16.h graphic24.cc
graphic24.h graphic32.cc graphic32.h graphic_generic.cc
matrix.cc matrix.h movie.cc movie.h mp3.cc mp3.h program.cc
program.h rect.h script.cc script.h shape.cc shape.h sound.cc
sound.h sprite.cc sprite.h sqrt.cc sqrt.h swf.h text.cc text.h
Log Message:
adding pristine copy of pixil to HEAD so I can branch from it
--- NEW FILE: flash.h ---
/*///////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////// */
#ifndef _FLASH_H_
#define _FLASH_H_
#define PLUGIN_NAME "Shockwave Flash"
#define FLASH_VERSION_STRING "Version 0.4.10"
/* Flags to pass to FlashExec */
#define FLASH_WAKEUP 0x01
#define FLASH_EVENT 0x02
#define FLASH_CMD 0x04
/* Mask to extract commands */
#define FLASH_CMD_MASK 0xf0
/* Commands */
#define FLASH_STOP 0x10 /* Pause the movie */
#define FLASH_CONT 0x20 /* Continue the movie after pause */
#define FLASH_REWIND 0x30 /* Rewind the movie and pause */
#define FLASH_STEP 0x40 /* Frame by frame operation */
/* return codes of FlashExec */
#define FLASH_STATUS_WAKEUP 0x01 /* FlashExec must be called again after a given time */
struct FlashInfo {
long frameRate;
long frameCount;
long frameWidth;
long frameHeight;
long version;
};
/* Player settings */
#define PLAYER_LOOP (1<<0)
#define PLAYER_QUALITY (1<<1)
#define PLAYER_MENU (1<<2)
/* Parser status */
#define FLASH_PARSE_ERROR 0
#define FLASH_PARSE_START 1
#define FLASH_PARSE_NEED_DATA 2
#define FLASH_PARSE_EOM 4
#define FLASH_PARSE_WAKEUP 8
#define FLASH_PARSE_OOM 16 /* Out Of Memory */
typedef void *FlashHandle;
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
#endif
enum FlashEventType {
FeNone,
FeMouseMove,
FeButtonPress,
FeButtonRelease,
FeRefresh,
FeKeyPress,
/* internal events */
FeKeyRelease
};
enum FlashKey {
FeKeyUp = 1,
FeKeyDown,
FeKeyLeft,
FeKeyRight,
FeKeyEnter,
FeKeyNext
};
typedef struct FlashEvent {
enum FlashEventType type;
int x,y; /* Mouse coordinates,
relative to upper-left window corner */
enum FlashKey key;
} FlashEvent;
typedef struct FlashDisplay {
void *pixels;
int bpl; /* bytes per line */
int width;
int height;
int depth;
int bpp;
int flash_refresh;
/* Clipping region */
int clip_x, clip_y;
int clip_width, clip_height;
} FlashDisplay;
extern FlashHandle FlashNew();
extern void FlashGetInfo(FlashHandle fh, struct FlashInfo *fi);
extern long FlashGraphicInit(FlashHandle fh, FlashDisplay *fd);
extern void FlashSoundInit(FlashHandle fh, char *device);
extern int FlashParse(FlashHandle fh, int level, char *data, long size);
extern long FlashExec(FlashHandle fh, long flag, FlashEvent *fe, struct timeval *wakeDate);
extern void FlashClose(FlashHandle fh);
extern void FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *);
extern void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData);
extern void FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData);
extern void FlashZoom(FlashHandle fh, int zoom);
extern void FlashOffset(FlashHandle fh, int x, int y);
extern void FlashSettings(FlashHandle fh, long settings);
#if defined(__cplusplus) || defined(c_plusplus)
};
#endif
#endif /* _FLASH_H_ */
--- NEW FILE: graphic16.h ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
class GraphicDevice16: public GraphicDevice {
private:
long GraphicDevice16::allocColor(Color color);
public:
GraphicDevice16(FlashDisplay *fd);
void clearCanvas();
void fillLineAA(FillStyleDef *f, long y, long start, long end);
void fillLine(FillStyleDef *f, long y, long start, long end);
void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
void fillLineLG(Gradient *grad, long y, long start, long end);
void fillLineRG(Gradient *grad, long y, long start, long end);
void drawLine(long x1, long y1, long x2, long y2, long width);
};
--- NEW FILE: graphic.cc ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: graphic.cc,v 1.1 2006-10-03 11:26:09 dslinux_amadeus Exp $";
#endif
#define PRINT 0
// Public
GraphicDevice::GraphicDevice(FlashDisplay *fd)
{
flashDisplay = fd;
bgInitialized = 0;
// Reset flash refresh flag
flashDisplay->flash_refresh = 0;
/* 16 bits, RGB565 */
redMask = 0xF800;
greenMask = 0x07E0;
blueMask = 0x001F;
/* should be the actual window size */
targetWidth = fd->width;
targetHeight = fd->height;
bpl = fd->bpl;
#if PRINT
printf("Target Width = %d\n", targetWidth);
printf("Target Height = %d\n", targetHeight);
#endif
zoom = FRAC;
movieWidth = targetWidth;
movieHeight = targetHeight;
viewPort.xmin = 0;
viewPort.xmax = targetWidth-1;
viewPort.ymin = 0;
viewPort.ymax = targetHeight-1;
canvasBuffer = (unsigned char *) fd->pixels;
adjust = new Matrix;
foregroundColor.red = 0;
foregroundColor.green = 0;
foregroundColor.blue = 0;
foregroundColor.alpha = ALPHA_OPAQUE;
backgroundColor.red = 0;
backgroundColor.green = 0;
backgroundColor.blue = 0;
backgroundColor.alpha = ALPHA_OPAQUE;
showMore = 0;
setClipping(0); // Reset
setClipping(1);
/* polygon rasterizer : handle memory errors ! */
height = targetHeight;
segs = (Segment **)malloc(height * sizeof(Segment *));
memset(segs, 0, height * sizeof(Segment *));
ymin = height;
ymax = -1;
seg_pool = (Segment *)malloc(NB_SEGMENT_MAX * sizeof(Segment));
seg_pool_cur = seg_pool;
}
GraphicDevice::~GraphicDevice()
{
free(segs);
free(seg_pool);
if (adjust) {
delete adjust;
}
}
Color *
GraphicDevice::getColormap(Color *old, long n, Cxform *cxform)
{
Color *newCmp;
newCmp = new Color[n];
if (newCmp == NULL) return NULL;
if (cxform) {
for(long i = 0; i < n; i++)
{
newCmp[i] = cxform->getColor(old[i]);
newCmp[i].pixel = allocColor(newCmp[i]);
}
} else {
for(long i = 0; i < n; i++)
{
newCmp[i] = old[i];
newCmp[i].pixel = allocColor(old[i]);
}
}
return newCmp;
}
long
GraphicDevice::getHeight()
{
return targetHeight;
}
long
GraphicDevice::getWidth()
{
return targetWidth;
}
Color
GraphicDevice::getForegroundColor()
{
return foregroundColor;
}
void
GraphicDevice::setForegroundColor(Color color)
{
foregroundColor = color;
}
Color
GraphicDevice::getBackgroundColor()
{
return backgroundColor;
}
int
GraphicDevice::setBackgroundColor(Color color)
{
if (bgInitialized == 0) {
backgroundColor = color;
clearCanvas();
bgInitialized = 1;
return 1;
}
return 0;
}
void
GraphicDevice::setMovieDimension(long width, long height)
{
float xAdjust, yAdjust;
movieWidth = width;
movieHeight = height;
xAdjust = (float)targetWidth*zoom/(float)width;
yAdjust = (float)targetHeight*zoom/(float)height;
if (xAdjust < yAdjust) {
adjust->a = xAdjust;
adjust->d = xAdjust;
adjust->ty = ((targetHeight*zoom) - (long)(height * xAdjust))/2;
viewPort.ymin = adjust->ty/zoom;
viewPort.ymax = targetHeight-viewPort.ymin-1;
} else {
adjust->a = yAdjust;
adjust->d = yAdjust;
adjust->tx = ((targetWidth*zoom) - (long)(width * yAdjust))/2;
viewPort.xmin = adjust->tx/zoom;
viewPort.xmax = targetWidth-viewPort.xmin-1;
}
if (viewPort.xmin < 0) viewPort.xmin = 0;
if (viewPort.ymin < 0) viewPort.ymin = 0;
if (viewPort.xmax >= targetWidth) viewPort.xmax = targetWidth-1;
if (viewPort.ymax >= targetHeight) viewPort.ymax = targetHeight-1;
}
void
GraphicDevice::setMovieZoom(int z)
{
z *= FRAC;
if (z <= 0 || z > 100) return;
zoom = z;
setMovieDimension(movieWidth,movieHeight);
}
void
GraphicDevice::setMovieOffset(long x, long y)
{
adjust->tx = -zoom*x;
adjust->ty = -zoom*y;
}
long
GraphicDevice::clip(long &y, long &start, long &end)
{
long xmin,xend;
if (y < clip_rect.ymin ||
y >= clip_rect.ymax) return 1;
if (end <= start)
return 1;
xmin = clip_rect.xmin * FRAC;
xend = clip_rect.xmax * FRAC;
if (end <= xmin || start >= xend) return 1;
if (start < xmin) start = xmin;
if (end > xend) end = xend;
return 0;
}
void
GraphicDevice::drawBox(long x1, long y1, long x2, long y2)
{
int i;
for(i=0;i<FRAC*2;i++) {
drawLine(x1+i, y1+i, x2-i, y1+i, 0);
drawLine(x1+i, y2-i, x2-i, y2-i, 0);
drawLine(x1+i, y1+i+1, x1+i, y2-i-1, 0);
drawLine(x2-i, y1+i+1, x2-i, y2-i-1, 0);
}
}
/* polygon rasteriser */
inline Segment *
GraphicDevice::allocSeg()
{
Segment *seg;
if ( (seg_pool_cur - seg_pool) >= NB_SEGMENT_MAX )
return NULL;
seg = seg_pool_cur++;
return seg;
}
/* add a segment to the current path */
void
GraphicDevice::addSegment(long x1, long y1, long x2, long y2,
FillStyleDef *f0,
FillStyleDef *f1,
int aa)
{
Segment *seg,**segs;
long dX, X, Y, ymin, ymax, tmp;
FillStyleDef *ff;
if ( y1 == y2 ) {
return;
}
if (y1 < y2) {
ymin = y1;
ymax = y2;
ff = f0;
f0 = f1;
f1 = ff;
} else {
ymin = y2;
ymax = y1;
tmp = x1;
x1 = x2;
x2 = tmp;
}
if (ymax>>FRAC_BITS < clip_rect.ymin) {
return;
}
if (ymin>>FRAC_BITS > clip_rect.ymax) {
return;
}
X = x1 << SEGFRAC;
dX = ((x2 - x1)<<SEGFRAC)/(ymax-ymin);
if (ymin < 0) {
X += dX * (-ymin);
ymin = 0;
}
Y = (ymin + (FRAC-1)) & ~(FRAC-1);
if (Y > ymax) {
//printf("Elimine @ y = %d ymin = %d, ymax = %d\n", Y, ymin, seg->ymax);
return;
}
X += dX * (Y-ymin);
Y >>= FRAC_BITS;
if (Y >= clip_rect.ymax) {
return;
}
seg = allocSeg();
if (seg == NULL) {
return;
}
seg->next = 0;
seg->nextValid = 0;
seg->aa = aa;
seg->ymax = ymax;
seg->x1 = x1;
seg->x2 = x2;
seg->X = X;
seg->dX = dX;
seg->fs[0] = f0;
seg->fs[1] = f1;
if (Y < this->ymin) this->ymin = Y;
ymax = (seg->ymax + FRAC - 1) >> FRAC_BITS;
if (ymax >= this->height) ymax = this->height-1;
if (ymax > this->ymax) this->ymax = ymax;
segs = this->segs;
if (segs[Y] == 0) {
segs[Y] = seg;
} else {
Segment *s,*prev;
prev = 0;
for(s = segs[Y]; s; prev = s, s = s->next) {
if (s->X > seg->X) {
if (prev) {
prev->next = seg;
seg->next = s;
} else {
seg->next = segs[Y];
segs[Y] = seg;
}
break;
}
}
if (s == 0) {
prev->next = seg;
seg->next = s;
}
}
}
inline Segment *
GraphicDevice::progressSegments(Segment * curSegs, long y)
{
Segment *seg,*prev;
// Update current segments
seg = curSegs;
prev = 0;
while(seg)
{
if ((y*FRAC) > seg->ymax) {
// Remove this segment, no more valid
if (prev) {
prev->nextValid = seg->nextValid;
} else {
curSegs = seg->nextValid;
}
seg = seg->nextValid;
} else {
seg->X += seg->dX * FRAC;
prev = seg;
seg = seg->nextValid;
}
}
return curSegs;
}
inline Segment *
GraphicDevice::newSegments(Segment *curSegs, Segment *newSegs)
{
Segment *s,*seg,*prev;
s = curSegs;
prev = 0;
// Check for new segments
for (seg = newSegs; seg; seg=seg->next)
{
// Place it at the correct position according to X
if (curSegs == 0) {
curSegs = seg;
seg->nextValid = 0;
} else {
for(; s; prev = s, s = s->nextValid)
{
if ( s->X > seg->X ||
( (s->X == seg->X) &&
( (seg->x1 == s->x1 && seg->dX < s->dX) ||
(seg->x2 == s->x2 && seg->dX > s->dX)
))) {
// Insert before s
if (prev) {
seg->nextValid = s;
prev->nextValid = seg;
} else {
seg->nextValid = curSegs;
curSegs = seg;
}
break;
}
}
// Append at the end
if (s == 0) {
prev->nextValid = seg;
seg->nextValid = 0;
}
}
s = seg;
}
return curSegs;
}
#if 0
static void
printSeg(Segment *seg)
{
/*
printf("Seg %08x : X = %5d, Ft = %d, Cl = %2x/%2x/%2x, Cr = %2x/%2x/%2x, x1=%5d, x2=%5d, ymin=%5d, ymax=%5d\n", seg,
seg->X>>SEGFRAC,
seg->right ? seg->right->type: -1,
seg->left ? seg->left->color.red : -1,
seg->left ? seg->left->color.green : -1,
seg->left ? seg->left->color.blue : -1,
seg->right ? seg->right->color.red : -1,
seg->right ? seg->right->color.green : -1,
seg->right ? seg->right->color.blue : -1,
seg->x1, seg->x2, seg->ymin, seg->ymax);
*/
}
#endif
inline void
GraphicDevice::renderScanLine(long y, Segment *curSegs)
{
Segment *seg;
long width;
int fi = 1;
FillStyleDef *f;
width = targetWidth * FRAC;
if (curSegs && curSegs->fs[0] && curSegs->fs[1] == 0) {
fi = 0;
}
for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid)
{
if (seg->nextValid->X <0) continue;
if ((seg->X>>SEGFRAC) > width) break;
f = seg->fs[fi];
if (f) {
switch (f->type) {
case f_Solid:
if (seg->aa) {
fillLineAA(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
} else {
fillLine(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
}
break;
case f_TiledBitmap:
case f_clippedBitmap:
fillLineBitmap(f, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
break;
case f_LinearGradient:
fillLineLG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
break;
case f_RadialGradient:
fillLineRG(&f->gradient, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
break;
case f_None:
break;
}
}
}
}
/* draw the current path */
void
GraphicDevice::drawPolygon(void)
{
long y;
Segment *curSegs,*seg;
// no segments ?
if (this->ymax == -1)
return;
// Foreach scanline
curSegs = 0;
for(y=this->ymin; y <= this->ymax; y++) {
// Make X values progess and remove unuseful segments
curSegs = progressSegments(curSegs, y);
// Add the new segment starting at the y position.
curSegs = newSegments(curSegs, this->segs[y]);
// Render the scanline
if (this->scan_line_func == NULL) {
renderScanLine(y, curSegs);
} else {
for(seg = curSegs; seg && seg->nextValid; seg = seg->nextValid) {
if (seg->nextValid->X >= seg->X) {
scan_line_func(this->scan_line_func_id, y, seg->X>>SEGFRAC, seg->nextValid->X>>SEGFRAC);
}
}
}
}
/* free the segments */
memset(this->segs + this->ymin, 0,
(this->ymax - this->ymin + 1) * sizeof(Segment *));
this->ymax = -1;
this->ymin = this->height;
this->seg_pool_cur = this->seg_pool;
}
void
GraphicDevice::updateClippingRegion(Rect *rect)
{
if (!clipping) return;
transformBoundingBox(&clip_rect, adjust, rect, 1);
clip_rect.xmin >>= FRAC_BITS;
clip_rect.xmax >>= FRAC_BITS;
clip_rect.ymin >>= FRAC_BITS;
clip_rect.ymax >>= FRAC_BITS;
clip_rect.xmin-=2;
clip_rect.ymin-=2;
clip_rect.xmax+=2;
clip_rect.ymax+=2;
if (clip_rect.xmin < viewPort.xmin) clip_rect.xmin = viewPort.xmin;
if (clip_rect.xmax < viewPort.xmin) clip_rect.xmax = viewPort.xmin;
if (clip_rect.ymin < viewPort.ymin) clip_rect.ymin = viewPort.ymin;
if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin;
if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax;
if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax;
if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax;
if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax;
}
void
GraphicDevice::setClipping(int value)
{
clipping = value;
if (clipping == 0) {
// Reset region
clip_rect.xmin = viewPort.xmin;
clip_rect.xmax = viewPort.xmax;
clip_rect.ymin = viewPort.ymin;
clip_rect.ymax = viewPort.ymax;
}
}
// Virtual
void
GraphicDevice::clearCanvas()
{
}
long
GraphicDevice::allocColor(Color color)
{
return 0;
}
void
GraphicDevice::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
{
}
void
GraphicDevice::fillLineLG(Gradient *grad, long y, long start, long end)
{
}
void
GraphicDevice::fillLineRG(Gradient *grad, long y, long start, long end)
{
}
void
GraphicDevice::fillLine(FillStyleDef *f, long y, long start, long end)
{
}
void
GraphicDevice::fillLineAA(FillStyleDef *f, long y, long start, long end)
{
}
void
GraphicDevice::drawLine(long x1, long y1, long x2, long y2, long width)
{
}
--- NEW FILE: script.h ---
#ifndef _SCRIPT_H_
#define _SCRIPT_H_
// SWF file parser.
//
//////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////
// Input script object definition.
//////////////////////////////////////////////////////////////////////
// An input script object. This object represents a script created from
// an external file that is meant to be inserted into an output script.
struct CInputScript : public Dict
{
int level;
struct CInputScript *next;
Program *program; // Current parsed program
// Memory fences
int outOfMemory;
//Flash info
long frameRate;
long frameCount;
Rect frameRect;
// Pointer to file contents buffer.
U8 *m_fileBuf;
// File state information.
U32 m_filePos;
U32 m_fileSize;
U32 m_actualSize;
U32 m_fileStart;
U16 m_fileVersion;
int needHeader;
// Bit Handling
S32 m_bitPos;
U32 m_bitBuf;
// Tag parsing information.
U32 m_tagStart;
U32 m_tagEnd;
U32 m_tagLen;
// Parsing information.
S32 m_nFillBits;
S32 m_nLineBits;
S32 m_nGlyphBits;
S32 m_nAdvanceBits;
// Set to true if we wish to dump all contents long form
U32 m_dumpAll;
// if set to true will dump image guts (i.e. jpeg, zlib, etc. data)
U32 m_dumpGuts;
// Handle to output file.
FILE *m_outputFile;
// Constructor/destructor.
CInputScript(int level = 0);
~CInputScript();
// Tag scanning methods.
U16 GetTag(void);
U8 GetByte(void);
U16 GetWord(void);
U32 GetDWord(void);
void GetRect(Rect *r);
void GetMatrix(Matrix *matrix);
void GetCxform(Cxform *cxform, BOOL hasAlpha);
char *GetString(void);
// Routines for reading arbitrary sized bit fields from the stream.
// Always call start bits before gettings bits and do not intermix
// these calls with GetByte, etc...
void InitBits();
S32 GetSBits(S32 n);
U32 GetBits(S32 n);
// Tag subcomponent parsing methods
void ParseFillStyle(long getAlpha = 0);
void ParseLineStyle(long getAlpha = 0);
int ParseShapeRecord(long getAlpha = 0);
ButtonRecord * ParseButtonRecord(long getCxform = 0);
ActionRecord * ParseActionRecord();
TextRecord * ParseTextRecord(int hasAlpha = 0);
void ParseShapeData(int getAlpha, int getStyles);
// Parsing methods.
void ParseEnd(); // 00: stagEnd
void ParseShowFrame(U32 frame, U32 offset); // 01: stagShowFrame
void ParseDefineShape(int level); // 02: stagDefineShape
void ParseFreeCharacter(); // 03: stagFreeCharacter
void ParsePlaceObject(); // 04: stagPlaceObject
void ParseRemoveObject(); // 05: stagRemoveObject
void ParseDefineBits(); // 06: stagDefineBits
void ParseDefineButton(); //x 07: stagDefineButton
void ParseJPEGTables(); // 08: stagJPEGTables
void ParseSetBackgroundColor(); // 09: stagSetBackgroundColor
void ParseDefineFont(); //x 10: stagDefineFont
void ParseDefineText(int hasAplha); //x 11: stagDefineText 33: stagDefineText2
void ParseDoAction(); // 12: stagDoAction
void ParseDefineFontInfo(); //x 13: stagDefineFontInfo
void ParseDefineSound(); // 14: stagDefineSound
void ParseStartSound(); // 15: stagStartSound
void ParseStopSound(); // 16: stagStopSound
void ParseDefineButtonSound(); // 17: stagDefineButtonSound
void ParseSoundStreamHead(); // 18: stagSoundStreamHead
void ParseSoundStreamBlock(); // 19: stagSoundStreamBlock
void ParseDefineBitsLossless(int level); // 20: stagDefineBitsLossless 36: stagDefineBitsLossless2
void ParseDefineBitsJPEG2(); // 21: stagDefineBitsJPEG2
void ParseDefineButtonCxform(); // 23: stagDefineButtonCxform
void ParseProtect(); // 24: stagProtect
void ParsePlaceObject2(); // 26: stagPlaceObject2
void ParseRemoveObject2(); // 28: stagRemoveObject2
void ParseDefineButton2(); //x 34: stagDefineButton2
void ParseDefineBitsJPEG3(); // 35: stagDefineBitsJPEG3
void ParseDefineMouseTarget(); // 38: stagDefineMouseTarget
void ParseDefineSprite(); //x 39: stagDefineSprite
void ParseNameCharacter(); // 40: stagNameCharacter
void ParseFrameLabel(); // 43: stagFrameLabel
void ParseSoundStreamHead2(); // 45: stagSoundStreamHead2
void ParseDefineMorphShape(); //x 46: stagDefineMorphShape
void ParseDefineFont2(); //x 48: stagDefineFont2
void ParseUnknown(long,long);
void ParseTags(int *);
int ParseData(FlashMovie *movie, char * data, long size);
void S_DumpImageGuts();
#ifdef DUMP
long save(char *filenam);
#endif
};
#endif /* _SCRIPT_H_ */
--- NEW FILE: graphic32.h ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
class GraphicDevice32: public GraphicDevice {
private:
long GraphicDevice32::allocColor(Color color);
public:
GraphicDevice32(FlashDisplay *fd);
void clearCanvas();
void fillLineAA(FillStyleDef *f, long y, long start, long end);
void fillLine(FillStyleDef *f, long y, long start, long end);
void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
void fillLineLG(Gradient *grad, long y, long start, long end);
void fillLineRG(Gradient *grad, long y, long start, long end);
void drawLine(long x1, long y1, long x2, long y2, long width);
};
--- NEW FILE: text.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: text.cc,v 1.1 2006-10-03 11:26:10 dslinux_amadeus Exp $";
#endif
Text::Text(long id) : Character(TextType, id)
{
textRecords = 0;
}
Text::~Text()
{
TextRecord *cur,*del;
for(cur = textRecords; cur;)
{
del = cur;
cur = cur->next;
delete del;
}
}
void
Text::setTextBoundary(Rect rect)
{
boundary = rect;
}
void
Text::setTextMatrix(Matrix m)
{
textMatrix = m;
}
void
Text::addTextRecord(TextRecord *tr)
{
SwfFont *font = 0;
long n;
tr->next = 0;
if (textRecords == 0) {
textRecords = tr;
font = tr->font;
} else {
TextRecord *current;
long fontHeight = 0;
for(current = textRecords; current->next; current = current->next) {
if (current->flags & textHasFont) {
font = current->font;
fontHeight = current->fontHeight;
}
}
current->next = tr;
if (current->flags & textHasFont) {
font = current->font;
fontHeight = current->fontHeight;
}
if (tr->flags & textHasFont) {
font = tr->font;
} else {
tr->font = font;
tr->fontHeight = fontHeight;
}
}
if (tr->nbGlyphs) {
for(n=0; n < tr->nbGlyphs; n++) {
tr->glyphs[n].code = font->getGlyphCode(tr->glyphs[n].index);
}
}
}
int
Text::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
{
return doText(gd, matrix, cxform, ShapeDraw, NULL, NULL);
}
void
Text::getRegion(GraphicDevice *gd, Matrix *matrix,
void *id, ScanLineFunc scan_line_func)
{
doText(gd, matrix, 0, ShapeGetRegion, id, scan_line_func);
}
void
Text::getBoundingBox(Rect *bb, DisplayListEntry *e)
{
*bb = boundary;
}
TextRecord *
Text::getTextRecords()
{
return textRecords;
}
int
Text::doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action,
void *id, ScanLineFunc scan_line_func)
{
TextRecord *tr;
long x,y; // Current position
SwfFont *font = 0; // Current font
long fontHeight;
Matrix tmat,fmat;
long g;
x = y = 0;
fontHeight = 0;
// Compute final text matrix
tmat = (*matrix) * textMatrix;
for(tr = textRecords; tr; tr = tr ->next)
{
if (tr->flags & isTextControl) {
if (tr->flags & textHasXOffset) {
x = tr->xOffset;
}
if (tr->flags & textHasYOffset) {
y = tr->yOffset;
}
if (tr->flags & textHasColor) {
if (action == ShapeDraw) {
if (cxform) {
gd->setForegroundColor(cxform->getColor(tr->color));
} else {
gd->setForegroundColor(tr->color);
}
}
}
}
font = tr->font;
fontHeight = tr->fontHeight;
// Update font matrix
fmat.a = fontHeight/1000.0;
fmat.d = fontHeight/1000.0;
assert(font != 0);
for (g = 0; g < tr->nbGlyphs; g++)
{
Shape *shape;
Matrix cmat;
shape = font->getGlyph( tr->glyphs[g].index );
#ifdef PRINT
printf("%c", font->getGlyphCode(tr->glyphs[g].index));
#endif
// Update font matrix
fmat.tx = x;
fmat.ty = y;
// Compute Character matrix
cmat = tmat * fmat;
if (action == ShapeDraw) {
shape->execute(gd, &cmat, cxform);
} else {
shape->getRegion(gd, &cmat, id, scan_line_func);
}
// Advance
x += tr->glyphs[g].xAdvance;
}
#ifdef PRINT
printf("\n");
#endif
}
if (gd->showMore) {
tmat = (*gd->adjust) * (*matrix);
long x1,x2,y1,y2;
x1 = boundary.xmin;
y1 = boundary.ymin;
x2 = boundary.xmax;
y2 = boundary.ymax;
gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),FRAC);
gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),FRAC);
gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),FRAC);
gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),FRAC);
}
return 0;
}
////////// TextRecord Methods
TextRecord::TextRecord() {
flags = (TextFlags)0;
font = 0;
fontHeight = 0;
nbGlyphs = 0;
glyphs = 0;
xOffset = 0;
yOffset = 0;
}
TextRecord::~TextRecord() {
if (nbGlyphs) delete glyphs;
}
char *
TextRecord::getText() {
static char text[256];
long g;
for(g=0; g < nbGlyphs; g++) {
text[g] = glyphs[g].code;
}
text[g] = 0;
return text;
}
--- NEW FILE: shape.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
[...1167 lines suppressed...]
break;
case f_LinearGradient:
case f_RadialGradient:
if (f->gradient.ramp) {
delete f->gradient.ramp;
}
break;
case f_TiledBitmap:
case f_clippedBitmap:
if (f->bitmap) {
if (f->cmap && f->cmap != f->bitmap->colormap) delete f->cmap;
if (f->alpha_table) free(f->alpha_table);
}
break;
case f_None:
break;
}
}
}
--- NEW FILE: rect.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _RECT_H_
#define _RECT_H_
struct Rect
{
long xmin;
long xmax;
long ymin;
long ymax;
long getWidth() {
return xmax-xmin;
};
long getHeight() {
return ymax-ymin;
};
void print() {
printf("Xmin = %d Xmax = %d Ymin = %d Ymax = %d\n",
(int)xmin,(int)xmax,(int)ymin,(int)ymax);
};
void reset() {
xmin = LONG_MAX;
ymin = LONG_MAX;
xmax = LONG_MIN;
ymax = LONG_MIN;
};
#ifdef DUMP
void dump(BitStream *bs);
#endif
};
#endif /* _RECT_H_ */
--- NEW FILE: character.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: character.cc,v 1.1 2006-10-03 11:26:08 dslinux_amadeus Exp $";
#endif
///// Character member definitions
Character::Character(ObjectType objectType, long tagid)
{
type = objectType;
tagId = tagid;
name = NULL;
}
Character::~Character()
{
delete name;
}
int
Character::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
{
printf("Cannot be executed\n");
return 0;
}
ActionRecord *
Character::eventHandler(GraphicDevice *gd, FlashEvent *ev)
{
fprintf(stderr,"Unable to handle event !!!\n");
return 0;
}
int
Character::isButton()
{
return 0;
}
int
Character::isSprite(void)
{
return 0;
}
char *
Character::getName()
{
return name;
}
void
Character::getBoundingBox(Rect *bb, DisplayListEntry *e)
{
//fprintf(stderr,"Unable to handle getBoundingBox !!!\n");
bb->xmin = LONG_MAX;
bb->ymin = LONG_MAX;
bb->ymax = LONG_MIN;
bb->ymax = LONG_MIN;
return;
}
void
Character::getRegion(GraphicDevice *gd, Matrix *matrix,
void *id, ScanLineFunc scan_line_func)
{
fprintf(stderr,"Unable to handle getRegion !!!\n");
return;
}
long
Character::getTagId()
{
return tagId;
}
void
Character::reset()
{
}
ObjectType
Character::getType()
{
return type;
}
char *
Character::getTypeString()
{
switch (type) {
case BitmapType:
return "Bitmap";
case FontType:
return "Font";
case ButtonType:
return "Button";
case SpriteType:
return "Sprite";
case ShapeType:
return "Shape";
case SoundType:
return "Sound";
case TextType:
return "Text";
default:
return "Unknown";
}
}
void
Character::setName(char* string)
{
name = strdup(string);
}
///// Dict methods definitions
Dict::Dict()
{
head = 0;
}
Dict::~Dict()
{
struct sCharCell *cell,*del;
for(cell = head; cell;)
{
del = cell;
cell = cell->next;
delete del->elt;
delete del;
}
}
void
Dict::addCharacter(Character *character)
{
struct sCharCell *cell;
cell = new sCharCell;
if (cell == NULL) {
delete character;
return;
}
cell->elt = character;
cell->next = head;
head = cell;
}
Character *
Dict::getCharacter(long id)
{
struct sCharCell *cell;
for(cell = head; cell; cell = cell->next)
{
if (id == cell->elt->getTagId()) return cell->elt;
}
return 0;
}
void
Dict::dictRewind()
{
currentCell = head;
}
Character *
Dict::dictNextCharacter()
{
if (currentCell) {
struct sCharCell *cell;
cell = currentCell;
currentCell = currentCell->next;
return cell->elt;
} else {
return 0;
}
}
void
Dict::nameCharacter(long id, char *string)
{
struct sCharCell *cell;
for(cell = head; cell; cell = cell->next)
{
if (cell->elt->getTagId() == id) {
cell->elt->setName(string);
break;
}
}
}
#ifdef DUMP
void
Dict::dictSetUnsaved()
{
struct sCharCell *cell;
for(cell = head; cell; cell = cell->next)
{
cell->elt->saved = 0;
}
}
#endif
--- NEW FILE: movie.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _MOVIE_H_
#define _MOVIE_H_
#include "swf.h"
struct FlashMovie {
/* true if a button has been moved */
int buttons_updated;
/* current keyboard focus */
DisplayListEntry *cur_focus;
/* mouse state */
long mouse_active;
long mouse_x;
long mouse_y;
int button_pressed;
Button *lost_over;
/* a button can return to a given state after some time */
FlashEvent scheduledEvent;
struct timeval scheduledTime;
int refresh;
CInputScript *main;
long msPerFrame;
GraphicDevice *gd;
SoundMixer *sm;
void (*getUrl)(char *,char *, void *);
void *getUrlClientData;
void (*getSwf)(char *url, int level, void *clientData);
void *getSwfClientData;
void (*cursorOnOff)(int , void *);
void *cursorOnOffClientData;
FlashMovie();
~FlashMovie();
int processMovie(GraphicDevice *gd, SoundMixer *sm);
int handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event);
void renderMovie();
void renderFocus();
};
#endif /* _MOVIE_H_ */
--- NEW FILE: swf.h ---
#ifndef _SWF_H_
#define _SWF_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <assert.h>
#include <limits.h>
#ifdef DUMP
#include "bitstream.h"
#endif
#include "flash.h"
extern int debug;
// Global Types
typedef unsigned long U32, *P_U32, **PP_U32;
typedef signed long S32, *P_S32, **PP_S32;
typedef unsigned short U16, *P_U16, **PP_U16;
typedef signed short S16, *P_S16, **PP_S16;
typedef unsigned char U8, *P_U8, **PP_U8;
typedef signed char S8, *P_S8, **PP_S8;
typedef signed long SFIXED, *P_SFIXED;
typedef signed long SCOORD, *P_SCOORD;
typedef unsigned long BOOL;
#define ZOOM(v,f) ((v)/(f))
#include "matrix.h"
#include "cxform.h"
#include "rect.h"
#include <sys/time.h>
#define ST struct timeval t1,t2;
#define START gettimeofday(&t1,0)
#define STOP(msg) gettimeofday(&t2,0); printf("%s Delta = %d ms\n", msg, (t2.tv_sec-t1.tv_sec)*1000+(t2.tv_usec-t1.tv_usec)/1000); fflush(stdout);
// Start Sound Flags
enum {
soundHasInPoint = 0x01,
soundHasOutPoint = 0x02,
soundHasLoops = 0x04,
soundHasEnvelope = 0x08
// the upper 4 bits are reserved for synchronization flags
};
// Flags for Sound Format
enum SoundFlags {
soundIsStereo = 0x01,
soundIs16bit = 0x02,
soundFormatMask = 0xf0,
soundFormatRaw = 0x00,
soundFormatADPCMCompressed = 0x10,
soundFormatMP3Compressed = 0x20
};
// Flags for defining Button States
enum ButtonState {
stateHitTest = 0x08,
stateDown = 0x04,
stateOver = 0x02,
stateUp = 0x01
};
// Actions
enum Action {
// Internal actions
ActionRefresh = 0x00,
ActionPlaySound = 0x01,
// Normal actions
ActionGotoFrame = 0x81,
ActionGetURL = 0x83,
ActionNextFrame = 0x04,
ActionPrevFrame = 0x05,
ActionPlay = 0x06,
ActionStop = 0x07,
ActionToggleQuality = 0x08,
ActionStopSounds = 0x09,
ActionWaitForFrame = 0x8a,
ActionSetTarget = 0x8b,
ActionGoToLabel = 0x8c
};
class Sound;
struct ActionRecord {
Action action;
// GotoFrame & WaitForFrame
long frameIndex;
// GetURL
char *url;
char *target;
// GotoLabel
char *frameLabel;
// WaitForFrame
long skipCount;
// Sound
Sound *sound;
struct ActionRecord *next;
ActionRecord() {
frameLabel = 0;
url = 0;
target = 0;
sound = 0;
};
~ActionRecord() {
if (frameLabel) free(frameLabel);
if (url) free(url);
if (target) free(target);
};
};
enum FontFlags {
fontUnicode = 0x20,
fontShiftJIS = 0x10,
fontANSI = 0x08,
fontItalic = 0x04,
fontBold = 0x02,
fontWideCodes = 0x01
};
enum TextFlags {
isTextControl = 0x80,
textIsLarge = 0x70,
textHasFont = 0x08,
textHasColor = 0x04,
textHasYOffset= 0x02,
textHasXOffset= 0x01
};
#ifndef NULL
#define NULL 0
#endif
// Tag values that represent actions or data in a Flash script.
enum
{
stagEnd = 0,
stagShowFrame = 1,
stagDefineShape = 2,
stagFreeCharacter = 3,
stagPlaceObject = 4,
stagRemoveObject = 5,
stagDefineBits = 6,
stagDefineButton = 7,
stagJPEGTables = 8,
stagSetBackgroundColor = 9,
stagDefineFont = 10,
stagDefineText = 11,
stagDoAction = 12,
stagDefineFontInfo = 13,
stagDefineSound = 14, // Event sound tags.
stagStartSound = 15,
stagStopSound = 16,
stagDefineButtonSound = 17,
stagSoundStreamHead = 18,
stagSoundStreamBlock = 19,
stagDefineBitsLossless = 20, // A bitmap using lossless zlib compression.
stagDefineBitsJPEG2 = 21, // A bitmap using an internal JPEG compression table.
stagDefineShape2 = 22,
stagDefineButtonCxform = 23,
stagProtect = 24, // This file should not be importable for editing.
// These are the new tags for Flash 3.
stagPlaceObject2 = 26, // The new style place w/ alpha color transform and name.
stagRemoveObject2 = 28, // A more compact remove object that omits the character tag (just depth).
stagDefineShape3 = 32, // A shape V3 includes alpha values.
stagDefineText2 = 33, // A text V2 includes alpha values.
stagDefineButton2 = 34, // A button V2 includes color transform, alpha and multiple actions
stagDefineBitsJPEG3 = 35, // A JPEG bitmap with alpha info.
stagDefineBitsLossless2 = 36, // A lossless bitmap with alpha info.
stagDefineSprite = 39, // Define a sequence of tags that describe the behavior of a sprite.
stagNameCharacter = 40, // Name a character definition, character id and a string, (used for buttons, bitmaps, sprites and sounds).
stagFrameLabel = 43, // A string label for the current frame.
stagSoundStreamHead2 = 45, // For lossless streaming sound, should not have needed this...
stagDefineMorphShape = 46, // A morph shape definition
stagDefineFont2 = 48,
notEnoughData = 0xffff // Special code
};
#ifndef false
#define false 0
#endif
#ifndef true
#define true 1
#endif
extern int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb;
typedef void (*ScanLineFunc)(void *id, long y, long start, long end);
class Bitmap;
struct FlashMovie;
extern "C" {
#include "jpeglib.h"
};
extern "C" {
#include "zlib.h"
};
#include "graphic.h"
#include "character.h"
#include "bitmap.h"
#include "shape.h"
#include "displaylist.h"
#include "sound.h"
#include "button.h"
#include "font.h"
#include "text.h"
#include "adpcm.h"
#include "mp3.h"
#include "program.h"
#include "sprite.h"
#include "script.h"
#include "movie.h"
#endif /* _SWF_H_ */
--- NEW FILE: sqrt.cc ---
unsigned char SQRT[] = {
0,1,1,1,2,2,2,2,2,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,
5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,
6,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
8,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,
9,9,9,9,10,10,10,10,10,10,10,10,10,10,10,10,
10,10,10,10,10,10,10,10,10,11,11,11,11,11,11,11,
11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,
12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,12,
12,12,12,12,12,12,12,12,12,13,13,13,13,13,13,13,
13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,13,
13,13,13,13,14,14,14,14,14,14,14,14,14,14,14,14,
14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,14,
14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,
16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
[...4060 lines suppressed...]
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
};
--- NEW FILE: sqrt.h ---
--- NEW FILE: adpcm.cc ---
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: adpcm.cc,v 1.1 2006-10-03 11:26:08 dslinux_amadeus Exp $";
#endif
// This file has been rearranged from the code posted
// on news:forums.macromedia.com by Jonathan Gay.
// Courtesy of Macromedia
//
// ADPCM tables
//
static const int indexTable2[2] = {
-1, 2,
};
// Is this ok?
static const int indexTable3[4] = {
-1, -1, 2, 4,
};
static const int indexTable4[8] = {
-1, -1, -1, -1, 2, 4, 6, 8,
};
static const int indexTable5[16] = {
-1, -1, -1, -1, -1, -1, -1, -1, 1, 2, 4, 6, 8, 10, 13, 16,
};
static const int* indexTables[] = {
indexTable2,
indexTable3,
indexTable4,
indexTable5
};
static const int stepsizeTable[89] = {
7, 8, 9, 10, 11, 12, 13, 14, 16, 17,
19, 21, 23, 25, 28, 31, 34, 37, 41, 45,
50, 55, 60, 66, 73, 80, 88, 97, 107, 118,
130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066,
2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899,
15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767
};
long
Adpcm::GetBits(int n)
{
if ( bitPos < n ) FillBuffer();
assert(bitPos >= n);
long v = ((unsigned long)bitBuf << (32-bitPos)) >> (32-n);
bitPos -= n;
return v;
}
long
Adpcm::GetSBits(int n)
{
if ( bitPos < n ) FillBuffer();
assert(bitPos >= n);
long v = ((long)bitBuf << (32-bitPos)) >> (32-n);
bitPos -= n;
return v;
}
//
// The Decompressor
//
// Constructor
Adpcm::Adpcm(unsigned char *buffer, long isStereo)
{
stereo = isStereo;
src = buffer;
nBits = 0; // flag that it is not inited
nSamples = 0;
bitPos = 0;
bitBuf = 0;
}
void
Adpcm::FillBuffer()
{
while ( bitPos <= 24 /*&& srcSize > 0*/ ) {
bitBuf = (bitBuf<<8) | *src++;
bitPos += 8;
}
}
void
Adpcm::Decompress(short *dst, long n)
{
if ( nBits == 0 ) {
// Get the compression header
nBits = (int)GetBits(2)+2;
}
const int* indexTable = indexTables[nBits-2];
int k0 = 1 << (nBits-2);
int signmask = 1 << (nBits-1);
if ( !stereo ) {
// Optimize for mono
long vp = valpred[0]; // maybe these can get into registers...
int ind = index[0];
long ns = nSamples;
while ( n-- > 0 ) {
ns++;
if ( (ns & 0xFFF) == 1 ) {
// Get a new block header
*dst++ = (short)(vp = GetSBits(16));
ind = (int)GetBits(6); // The first sample in a block does not have a delta
} else {
// Process a delta value
int delta = (int)GetBits(nBits);
// Compute difference and new predicted value
// Computes 'vpdiff = (delta+0.5)*step/4'
int step = stepsizeTable[ind];
long vpdiff = 0;
int k = k0;
do {
if ( delta & k )
vpdiff += step;
step >>= 1;
k >>= 1;
} while ( k );
vpdiff += step; // add 0.5
if ( delta & signmask ) // the sign bit
vp -= vpdiff;
else
vp += vpdiff;
// Find new index value
ind += indexTable[delta&(~signmask)];
if ( ind < 0 )
ind = 0;
else if ( ind > 88 )
ind = 88;
// clamp output value
if ( vp != (short)vp )
vp = vp < 0 ? -32768 : 32767;
/* Step 7 - Output value */
*dst++ = (short)vp;
}
}
valpred[0] = vp;
index[0] = ind;
nSamples = ns;
} else {
int sn = stereo ? 2 : 1;
// Stereo
while ( n-- > 0 ) {
nSamples++;
if ( (nSamples & 0xFFF) == 1 ) {
// Get a new block header
for ( int i = 0; i < sn; i++ ) {
*dst++ = (short)(valpred[i] = GetSBits(16));
// The first sample in a block does not have a delta
index[i] = (int)GetBits(6);
}
} else {
// Process a delta value
for ( int i = 0; i < sn; i++ ) {
int delta = (int)GetBits(nBits);
// Compute difference and new predicted value
// Computes 'vpdiff = (delta+0.5)*step/4'
int step = stepsizeTable[index[i]];
long vpdiff = 0;
int k = k0;
do {
if ( delta & k ) vpdiff += step;
step >>= 1;
k >>= 1;
} while ( k );
vpdiff += step; // add 0.5
if ( delta & signmask ) // the sign bit
valpred[i] -= vpdiff;
else
valpred[i] += vpdiff;
// Find new index value
index[i] += indexTable[delta&(~signmask)];
if ( index[i] < 0 )
index[i] = 0;
else if ( index[i] > 88 )
index[i] = 88;
// clamp output value
if ( valpred[i] != (short)valpred[i] )
valpred[i] = valpred[i] < 0 ? -32768 : 32767;
/* Step 7 - Output value */
*dst++ = (short)valpred[i];
}
}
}
}
}
--- NEW FILE: character.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _CHARACTER_H_
#define _CHARACTER_H_
enum ObjectType {
ShapeType,
TextType,
FontType,
SoundType,
BitmapType,
SpriteType,
ButtonType
};
class DisplayListEntry;
// Character definition
class Character {
long tagId;
ObjectType type;
char *name;
public:
Character(ObjectType type, long tagId);
virtual ~Character();
virtual int execute(GraphicDevice *, Matrix *, Cxform *); // Display, play or whatever
virtual int isButton(void); // True if Character is a button
virtual int isSprite(void);
virtual ActionRecord *eventHandler(GraphicDevice *, FlashEvent *);
virtual void getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func);
virtual void reset(); // Reset internal state of object
virtual void getBoundingBox(Rect *bb, DisplayListEntry *de);
#ifdef DUMP
virtual void dump(BitStream *main);
int saved;
#endif
long getTagId(); // Return tagId
ObjectType getType();
char *getTypeString();
char *getName();
void setName(char *);
};
struct sCharCell {
Character *elt;
struct sCharCell *next;
};
class Dict {
struct sCharCell *head;
struct sCharCell *currentCell; // Iteration variable for dictNextCharacter
public:
Dict();
~Dict();
void addCharacter(Character *character);
void nameCharacter(long id, char *string);
Character *getCharacter(long id);
void dictRewind();
Character *dictNextCharacter();
#ifdef DUMP
void dictSetUnsaved();
#endif
};
#endif /* _CHARACTER_H_ */
--- NEW FILE: adpcm.h ---
#ifndef _ADPCM_H_
#define _ADPCM_H_
class Adpcm {
// Destination format - note we always decompress to 16 bit
long stereo;
int nBits; // number of bits in each sample
long valpred[2]; // Current state
int index[2];
long nSamples; // number of samples decompressed so far
// Parsing Info
unsigned char *src;
long bitBuf; // this should always contain at least 24 bits of data
int bitPos;
void FillBuffer();
long GetBits(int n);
long GetSBits(int n);
public:
Adpcm(unsigned char *buffer, long isStereo);
void Decompress(short * dst, long n); // return number of good samples
#ifdef DUMP
void dump(BitStream *bs);
void Compress(short *pcm, long n, int bits);
#endif
};
#endif /* _ADPCM_H_ */
--- NEW FILE: flash.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#include "graphic16.h"
#include "graphic24.h"
#include "graphic32.h"
#ifdef RCSID
static char *rcsid = "$Id: flash.cc,v 1.1 2006-10-03 11:26:09 dslinux_amadeus Exp $";
#endif
// Interface with standard C
extern "C" {
FlashHandle
FlashNew()
{
FlashMovie *fh;
fh = new FlashMovie;
fh->main = new CInputScript;
return (FlashHandle)fh;
}
int
FlashParse(FlashHandle flashHandle, int level, char *data, long size)
{
FlashMovie *fh;
CInputScript *script;
int status = FLASH_PARSE_ERROR;
fh = (FlashMovie *)flashHandle;
for(script = fh->main; script != NULL; script = script->next) {
if (script->level == level) {
status = script->ParseData(fh, data, size);
if (status & FLASH_PARSE_START) {
fh->msPerFrame = 1000/fh->main->frameRate;
script->program->rewindMovie();
}
break;
}
}
return status;
}
void
FlashGetInfo(FlashHandle flashHandle, struct FlashInfo *fi)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fi->version = fh->main->m_fileVersion;
fi->frameRate = fh->main->frameRate;
fi->frameCount = fh->main->frameCount;
fi->frameWidth = fh->main->frameRect.xmax - fh->main->frameRect.xmin;
fi->frameHeight = fh->main->frameRect.ymax - fh->main->frameRect.ymin;
}
long FlashGraphicInit(FlashHandle flashHandle, FlashDisplay *fd)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
switch (fd->bpp) {
case 4:
fh->gd = new GraphicDevice32(fd);
break;
case 3:
fh->gd = new GraphicDevice24(fd);
break;
case 2:
fh->gd = new GraphicDevice16(fd);
break;
default:
fprintf(stderr, "Unsupported depth\n");
}
fh->gd->setMovieDimension(fh->main->frameRect.xmax - fh->main->frameRect.xmin,
fh->main->frameRect.ymax - fh->main->frameRect.ymin);
return 1; // Ok
}
void
FlashSoundInit(FlashHandle flashHandle, char *device)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fh->sm = new SoundMixer(device);
}
void
FlashZoom(FlashHandle flashHandle, int zoom)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fh->gd->setMovieZoom(zoom);
}
void
FlashOffset(FlashHandle flashHandle, int x, int y)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fh->gd->setMovieOffset(x,y);
}
long
FlashExec(FlashHandle flashHandle, long flag,
FlashEvent *fe, struct timeval *wakeDate)
{
FlashMovie *fh;
long wakeUp = 0;
fh = (FlashMovie *)flashHandle;
if (fh->main == NULL) return 0; // Not ready
if (fh->main->program == NULL) return 0; // Not ready
if (fh->main->program->nbFrames == 0) return 0; // Still not ready
if (fh->gd == 0) return 0;
switch (flag & FLASH_CMD_MASK) {
case FLASH_STOP:
fh->main->program->pauseMovie();
wakeUp = 0;
break;
case FLASH_CONT:
fh->main->program->continueMovie();
wakeUp = FLASH_STATUS_WAKEUP;
break;
case FLASH_REWIND:
fh->main->program->rewindMovie();
wakeUp = 0;
break;
case FLASH_STEP:
fh->main->program->nextStepMovie();
wakeUp = 0;
break;
}
if (flag & FLASH_WAKEUP) {
// Compute next wakeup time
gettimeofday(wakeDate,0);
wakeDate->tv_usec += fh->msPerFrame*1000;
if (wakeDate->tv_usec > 1000000) {
wakeDate->tv_usec -= 1000000;
wakeDate->tv_sec++;
}
// Play frame
wakeUp = fh->processMovie(fh->gd, fh->sm);
}
if (checkFlashTimer(&fh->scheduledTime)) {
if (fh->handleEvent(fh->gd, fh->sm, &fh->scheduledEvent)) {
wakeUp = 1;
}
setFlashTimer(&fh->scheduledTime, -1);
}
if (flag & FLASH_EVENT) {
wakeUp = fh->handleEvent(fh->gd, fh->sm, fe);
if (wakeUp) {
/* Wake up at once, except for mouse move (40 ms after) */
gettimeofday(wakeDate,0);
if (fe->type == FeMouseMove) {
wakeDate->tv_usec += 40*1000;
if (wakeDate->tv_usec > 1000000) {
wakeDate->tv_usec -= 1000000;
wakeDate->tv_sec++;
}
}
}
}
return wakeUp || (fh->scheduledTime.tv_sec != -1);
}
void FlashSetGetSwfMethod(FlashHandle flashHandle, void (*getSwf)(char *url, int level, void *clientData), void *clientData)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fh->getSwf = getSwf;
fh->getSwfClientData = clientData;
}
void
FlashSetCursorOnOffMethod(FlashHandle flashHandle, void (*cursorOnOff)(int , void *), void *clientData)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fh->cursorOnOff = cursorOnOff;
fh->cursorOnOffClientData = clientData;
}
void
FlashSetGetUrlMethod(FlashHandle flashHandle, void (*getUrl)(char *, char *, void *), void *clientData)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fh->getUrl = getUrl;
fh->getUrlClientData = clientData;
}
void
FlashClose(FlashHandle flashHandle)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
delete fh;
}
void
FlashSettings(FlashHandle flashHandle, long settings)
{
FlashMovie *fh;
fh = (FlashMovie *)flashHandle;
fh->main->program->modifySettings( settings );
}
int shape_size,shape_nb,shaperecord_size,shaperecord_nb,style_size,style_nb;
void flash_dump(void)
{
printf("flash: shape_size=%d (nb=%d)\n",shape_size,shape_nb);
printf("flash: shaperecord_size=%d (nb=%d)\n",shaperecord_size,shaperecord_nb);
printf("flash: style_size=%d (nb=%d)\n",style_size,style_nb);
}
}; /* end of extern C */
--- NEW FILE: mp3.h ---
#ifndef _MP3_H_
#define _MP3_H_
class Mp3 {
unsigned char *src;
int pos;
int len;
public:
Mp3(unsigned char *buffer, int len, long flags);
void Decompress(short * dst, long n); // return number of good samples
};
#endif /* _MP3_H_ */
--- NEW FILE: shape.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _SHAPE_H_
#define _SHAPE_H_
struct LineStyleDef {
long width;
Color color;
FillStyleDef fillstyle;
};
enum ShapeRecordType {
shapeNonEdge,
shapeCurve,
shapeLine
};
enum ShapeFlags {
flagsMoveTo = 0x01,
flagsFill0 = 0x02,
flagsFill1 = 0x04,
flagsLine = 0x08,
flagsNewStyles = 0x10,
flagsEndShape = 0x80
};
struct ShapeRecord {
ShapeRecordType type;
// Non Edge
ShapeFlags flags;
long x,y; // Moveto
long fillStyle0;
long fillStyle1;
long lineStyle;
FillStyleDef *newFillStyles; // Array
long nbNewFillStyles;
LineStyleDef *newLineStyles; // Array
long nbNewLineStyles;
// Curve Edge
long ctrlX, ctrlY;
long anchorX, anchorY;
// Straight Line
long dX,dY;
struct ShapeRecord *next;
ShapeRecord() {
shaperecord_size += sizeof(ShapeRecord);
shaperecord_nb++;
}
};
enum ShapeAction {
ShapeDraw,
ShapeGetRegion
};
struct LineSegment {
long x1,y1,x2,y2;
char first;
LineStyleDef *l;
struct LineSegment *next;
};
struct Path {
long lastX,lastY;
int nb_edges;
int nb_segments;
};
struct StyleList {
FillStyleDef *newFillStyles; // Array
long nbNewFillStyles;
LineStyleDef *newLineStyles; // Array
long nbNewLineStyles;
StyleList *next;
};
/* fast bit parser */
struct BitParser {
// Bit Handling
S32 m_bitPos;
U32 m_bitBuf;
U8 *ptr;
};
class Shape;
/* state of the shape parser */
struct ShapeParser {
Dict *dict; /* XXX: should be put elsewhere */
BitParser bit_parser;
S32 m_nFillBits;
S32 m_nLineBits;
StyleList *style_list;
Matrix *matrix;
Path curPath;
int reverse;
/* line rasteriser */
LineSegment *first_line,*last_line;
GraphicDevice *gd;
Cxform *cxform;
Shape *shape;
FillStyleDef *f0;
FillStyleDef *f1;
LineStyleDef *l;
};
class Shape : public Character {
public:
int defLevel; // 1,2 or 3
Rect boundary;
FillStyleDef defaultFillStyle;
LineStyleDef defaultLineStyle;
Matrix lastMat;
/* parsing for the rendering stage (saves a lot of memory &
may not reduce significantly the size). These variables
should be in another structure (no state need to be
maintained between two renderings) */
int getAlpha, getStyles;
unsigned char *file_ptr;
Dict *dict; /* XXX: should be put elsewhere */
protected:
void drawLines(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, long, long);
void buildSegmentList(Segment **segs, int height, long &n, Matrix *matrix, int update, int reverse);
Segment *progressSegments(Segment *, long);
Segment *newSegments(Segment *, Segment *);
public:
Shape(long id = 0 , int level = 1);
~Shape();
void setBoundingBox(Rect rect);
int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
void getRegion(GraphicDevice *gd, Matrix *matrix,
void *id, ScanLineFunc scan_line_func);
void getBoundingBox(Rect *bb, DisplayListEntry *);
#ifdef DUMP
void dump(BitStream *bs);
void dumpShapeRecords(BitStream *bs, int alpha);
void dumpFillStyles(BitStream *bs, FillStyleDef *defs, long n, int alpha);
void dumpLineStyles(BitStream *bs, LineStyleDef *defs, long n, int alpha);
void checkBitmaps(BitStream *bs);
#endif
};
#endif /* _SHAPE_H_ */
--- NEW FILE: matrix.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _MATRIX_H_
#define _MATRIX_H_
struct Matrix {
float a,b,c,d;
long tx,ty;
public:
Matrix operator*(Matrix);
Matrix invert();
Matrix();
#ifdef DUMP
void dump(BitStream *bs);
#endif
inline
long Matrix::getX(long x, long y)
{
return (long) (x*a+y*b+tx);
};
inline
long Matrix::getY(long x, long y)
{
return (long) (x*c+y*d+ty);
};
};
#endif /* _MATRIX_H_ */
--- NEW FILE: font.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _SWFFONT_H_
#define _SWFFONT_H_
class SwfFont : public Character {
Shape *glyphs; // Array
long nbGlyphs;
char *name;
FontFlags flags;
long *lookUpTable; // Array
// Font2
long ascent;
long descent;
long leading;
public:
SwfFont(long id);
~SwfFont();
void setFontShapeTable(Shape *shapes, long n);
void setFontName(char *str);
void setFontLookUpTable(long *lut);
void setFontFlags(FontFlags f);
long getGlyphCode(long index);
long getNbGlyphs();
Shape *getGlyph(long index);
char *getName();
FontFlags getFlags();
#ifdef DUMP
void dump(BitStream *bs);
void dumpFontInfo(BitStream *bs);
#endif
};
#endif /* _SWFFONT_H_ */
--- NEW FILE: button.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: button.cc,v 1.1 2006-10-03 11:26:08 dslinux_amadeus Exp $";
#endif
#define PRINT 0
// Contructor
Button::Button(long id, int level) : Character(ButtonType, id)
{
defLevel = level;
actionRecords = 0;
buttonRecords = 0;
conditionList = 0;
reset();
isMenu = 0;
sound[0] = sound[1] = sound[2] = sound[3] = 0;
}
// Destructor
Button::~Button()
{
if (actionRecords) {
ActionRecord *ar,*del;
for(ar = actionRecords; ar;) {
del = ar;
ar = ar->next;
delete del;
}
}
if (buttonRecords) {
ButtonRecord *br,*del;
for(br = buttonRecords; br;) {
del = br;
br = br->next;
if (del->cxform)
delete del->cxform;
delete del;
}
}
if (conditionList) {
Condition *cond,*del;
for(cond = conditionList; cond;) {
ActionRecord *ar,*d;
for(ar = cond->actions; ar;) {
d = ar;
ar = ar->next;
delete d;
}
del = cond;
cond = cond->next;
delete del;
}
}
}
ButtonRecord *
Button::getButtonRecords()
{
return buttonRecords;
}
ActionRecord *
Button::getActionRecords()
{
return actionRecords;
}
Sound **
Button::getSounds()
{
return sound;
}
Condition *
Button::getConditionList()
{
return conditionList;
}
void
Button::setButtonSound(Sound *s, int state)
{
if (state >=0 && state < 4) {
sound[state] = s;
}
}
void
Button::setButtonMenu(int menu)
{
isMenu = menu;
}
void
Button::addButtonRecord( ButtonRecord *br )
{
#if 0
/* SURTOUT PAS !!! */
ButtonRecord **l;
/* sort by layer */
l=&buttonRecords;
while (*l != NULL && (*l)->layer < br->layer) l = &(*l)->next;
br->next = *l;
*l = br;
#else
br->next = 0;
if (buttonRecords == 0) {
buttonRecords = br;
} else {
ButtonRecord *current;
for(current = buttonRecords; current->next; current = current->next);
current->next = br;
}
#endif
}
void
Button::addCondition( long transition )
{
Condition *condition;
condition = new Condition;
if (condition == NULL) return;
condition->transition = transition;
condition->next = conditionList;
// Move current actionRecords to this condition
condition->actions = actionRecords;
actionRecords = 0;
conditionList = condition;
}
void
Button::addActionRecord( ActionRecord *ar )
{
ar->next = 0;
if (actionRecords == 0) {
actionRecords = ar;
} else {
ActionRecord *current;
for(current = actionRecords; current->next; current = current->next);
current->next = ar;
}
}
void
Button::getRegion(GraphicDevice *gd, Matrix *matrix, void *id, ScanLineFunc scan_line_func)
{
ButtonRecord *br;
for (br = buttonRecords; br; br = br->next)
{
if ((br->state & stateHitTest) && br->character /* Temporaire */) {
Matrix mat;
mat = (*matrix) * br->buttonMatrix;
br->character->getRegion(gd, &mat, id, scan_line_func);
}
}
}
int
Button::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ButtonState renderState)
{
ButtonRecord *br;
int sprite = 0;
Cxform *cxf = 0;
#if PRINT==2
printf("Rendering Button %d for State(s) ", getTagId());
#endif
for (br = buttonRecords; br; br = br->next)
{
if ((br->state & renderState) && br->character != NULL) {
Matrix mat;
#if PRINT==2
printf("%d ", br->state);
#endif
mat = (*matrix) * br->buttonMatrix;
if (cxform) {
cxf = cxform;
} else if (br->cxform) {
cxf = br->cxform;
}
if (br->character->execute(gd, &mat, cxf)) {
sprite = 1;
}
}
}
#if PRINT==2
printf("\n");
#endif
return sprite;
}
ActionRecord *
Button::getActionFromTransition(ButtonState cur, ButtonState old)
{
Condition *cond;
long mask;
if (old == cur) return NULL;
/* transitions */
mask = 0;
if (old == stateUp && cur == stateOver)
mask |= 0x001;
else if (old == stateOver && cur == stateUp)
mask |= 0x002;
else if (old == stateOver && cur == stateDown)
mask |= 0x004;
else if (old == stateDown && cur == stateOver)
mask |= 0x008;
if (!isMenu) {
/* push button transitions (XXX: not quite correct) */
if (old == stateDown && cur == stateUp)
mask = 0x010;
else if (old == stateUp && cur == stateDown)
mask = 0x020;
/* XXX: what is transition 0x040 ?? */
} else {
/* menu button transitions (XXX: not quite correct) */
if (old == stateUp && cur == stateDown)
mask = 0x080;
else if (old == stateDown && cur == stateUp)
mask = 0x100;
}
for (cond = conditionList; cond; cond = cond->next) {
if (cond->transition & mask) {
return cond->actions;
}
}
return 0;
}
void
Button::getBoundingBox(Rect *bbox, DisplayListEntry *e)
{
ButtonRecord *br;
bbox->reset();
for (br = buttonRecords; br; br = br->next)
{
if (br->state & e->renderState) {
if (br->character) {
Rect bb;
bb.reset();
br->character->getBoundingBox(&bb,e);
transformBoundingBox(bbox, &br->buttonMatrix, &bb, 0);
}
}
}
}
/* Get current render character, actually it should be a list of characters
so a DisplayList after all */
Character *
Button::getRenderCharacter(ButtonState state)
{
ButtonRecord *br;
for (br = buttonRecords; br; br = br->next)
{
if (br->state & state) {
return br->character;
}
}
return 0;
}
void
Button::updateButtonState(DisplayListEntry *e)
{
ButtonRecord *br;
e->buttonCharacter = 0;
for (br = buttonRecords; br; br = br->next)
{
if (br->state & e->renderState) {
e->buttonCharacter = br->character;
e->buttonMatrix = br->buttonMatrix;
return;
}
}
}
--- NEW FILE: cxform.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id";
#endif
long
Cxform::getRed(long v) {
long val;
val = (long)(ra*v+rb);
if (val > 255) val = 255;
else if (val < 0) val = 0;
return val;
}
long
Cxform::getGreen(long v) {
long val;
val = (long)(ga*v+gb);
if (val > 255) val = 255;
else if (val < 0) val = 0;
return val;
}
long
Cxform::getBlue(long v) {
long val;
val = (long)(ba*v+bb);
if (val > 255) val = 255;
else if (val < 0) val = 0;
return val;
}
long
Cxform::getAlpha(long v) {
long val;
val = (long)(aa*v+ab);
if (val > 255) val = 255;
else if (val < 0) val = 0;
return val;
}
Color
Cxform::getColor(Color color) {
Color newColor;
newColor.red = getRed(color.red);
newColor.green = getGreen(color.green);
newColor.blue = getBlue(color.blue);
newColor.alpha = getAlpha(color.alpha);
return newColor;
}
--- NEW FILE: graphic24.cc ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#include "graphic24.h"
extern unsigned char SQRT[];
#define FULL_AA
#define PRINT 0
typedef unsigned char TYPE;
#define BPP 3
GraphicDevice24::GraphicDevice24(FlashDisplay *fd) : GraphicDevice(fd)
{
}
long
GraphicDevice24::allocColor(Color color)
{
return 0;
}
void
GraphicDevice24::clearCanvas()
{
TYPE *point,*p;
long h, w,n;
if (!bgInitialized) return;
point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin*BPP;
w = clip_rect.xmax - clip_rect.xmin;
h = clip_rect.ymax - clip_rect.ymin;
while (h--) {
p = point;
n = w;
while (n--) {
*p++ = backgroundColor.blue;
*p++ = backgroundColor.green;
*p++ = backgroundColor.red;
}
point = (TYPE *)((char *)point + bpl);
}
flashDisplay->flash_refresh = 1;
flashDisplay->clip_x = clip_rect.xmin;
flashDisplay->clip_y = clip_rect.ymin;
flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
}
/* alpha = 0 : select c1, alpha = 255 select c2 */
static inline void mix_alpha(TYPE *c1, Color c2, int alpha)
{
*c1 = (((c2.blue- (*c1))*alpha + (*c1) * 256) >> 8);
c1++;
*c1 = (((c2.green- (*c1))*alpha + (*c1) * 256) >> 8);
c1++;
*c1 = (((c2.red- (*c1))*alpha + (*c1) * 256) >> 8);
}
void
GraphicDevice24::fillLineAA(FillStyleDef *f, long y, long start, long end)
{
register long n;
TYPE *line;
TYPE *point;
Color pixel;
unsigned int alpha, start_alpha,end_alpha;
if (clip(y,start,end)) return;
line = (TYPE *)(canvasBuffer + bpl*y);
alpha = f->color.alpha;
pixel = f->color;
if (alpha == ALPHA_OPAQUE) {
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start >>= FRAC_BITS;
end >>= FRAC_BITS;
point = &line[start*BPP];
if (start == end) {
mix_alpha(point, pixel, start_alpha + end_alpha - 255);
} else {
n = end-start;
if (start_alpha < 255) {
mix_alpha(point, pixel, start_alpha);
point += BPP;
n--;
}
while (n > 0) {
*point++ = pixel.blue;
*point++ = pixel.green;
*point++ = pixel.red;
n--;
}
if (end_alpha > 0) {
mix_alpha(point, pixel, end_alpha);
}
}
} else {
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start >>= FRAC_BITS;
end >>= FRAC_BITS;
point = &line[start*BPP];
if (start == end) {
mix_alpha(point, pixel, ((start_alpha + end_alpha - 255) * alpha) >> 8);
} else {
n = end-start;
if (start_alpha < 255) {
mix_alpha(point, pixel, (start_alpha * alpha) >> 8);
point+=BPP;
n--;
}
while (n > 0) {
mix_alpha(point, pixel, alpha);
point+=BPP;
n--;
}
if (end_alpha > 0) {
mix_alpha(point, pixel, (end_alpha * alpha) >> 8);
}
}
}
}
void
GraphicDevice24::fillLine(FillStyleDef *f, long y, long start, long end)
{
register long n;
TYPE *line,*point;
Color pixel;
unsigned int alpha;
if (clip(y,start,end)) return;
start >>= FRAC_BITS;
end >>= FRAC_BITS;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start*BPP];
n = end-start;
alpha = f->color.alpha;
pixel = f->color;
if (alpha == ALPHA_OPAQUE) {
while (n--) {
*point++ = pixel.blue;
*point++ = pixel.green;
*point++ = pixel.red;
}
} else {
while (n--) {
mix_alpha(point, pixel, alpha);
point+=BPP;
}
}
}
void
GraphicDevice24::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
{
int n;
long x1,y1,dx,dy;
Matrix *m = &f->bitmap_matrix;
Bitmap *b = f->bitmap;
unsigned char *pixels;
TYPE *p;
Color *cmap;
long pixbpl;
Color pixel;
int offset;
unsigned char *alpha_table;
/* safety test) */
if (!b) return;
if (clip(y,start,end)) return;
start /= FRAC;
end /= FRAC;
n = end - start;
p = (TYPE *) (canvasBuffer + bpl*y + start*BPP);
x1 = (long) (m->a * start + m->b * y + m->tx);
y1 = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
pixels = b->pixels;
pixbpl = b->bpl;
cmap = f->cmap;
if (b->alpha_buf == NULL) {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]];
*p++ = pixel.blue;
*p++ = pixel.green;
*p++ = pixel.red;
} else {
p+=BPP;
}
x1 += dx;
y1 += dy;
n--;
}
} else if (f->alpha_table) {
alpha_table = f->alpha_table;
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
mix_alpha(p, cmap[pixels[offset]], alpha_table[b->alpha_buf[offset]]);
}
p+=BPP;
x1 += dx;
y1 += dy;
n--;
}
} else {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
mix_alpha(p, cmap[pixels[offset]], b->alpha_buf[offset]);
}
p+=BPP;
x1 += dx;
y1 += dy;
n--;
}
}
}
void
GraphicDevice24::fillLineLG(Gradient *grad, long y, long start, long end)
{
long dr,r,v,r2;
register long n;
TYPE *line;
TYPE *point;
Color *cp,*ramp;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
r = (long) (m->a * start + m->b * y + m->tx);
dr = (long) (m->a);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start*BPP];
r2 = r + n * dr;
if ( ((r | r2) & ~255) == 0 ) {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
mix_alpha(point, ramp[v], start_alpha);
point+=BPP;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
*point++ = ramp[v].blue;
*point++ = ramp[v].green;
*point++ = ramp[v].red;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
mix_alpha(point, ramp[v], end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
cp = &ramp[v];
mix_alpha(point, *cp, cp->alpha);
point+=BPP;
r += dr;
}
}
} else {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
mix_alpha(point, ramp[v], start_alpha);
point+=BPP;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point++ = ramp[v].blue;
*point++ = ramp[v].green;
*point++ = ramp[v].red;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
mix_alpha(point, ramp[v], end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
cp = &ramp[v];
mix_alpha(point, *cp, cp->alpha);
point+=BPP;
r += dr;
}
}
}
}
void
GraphicDevice24::fillLineRG(Gradient *grad, long y, long start, long end)
{
long X,dx,r,Y,dy;
long dist2;
register long n;
Color *cp,*ramp;
TYPE *line;
TYPE *point;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
X = (long) (m->a * start + m->b * y + m->tx);
Y = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start*BPP];
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start == end) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
mix_alpha(point, ramp[r], start_alpha + end_alpha - 255);
} else {
if (start_alpha < 255) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
mix_alpha(point, ramp[r], start_alpha);
point+=BPP;
X += dx;
Y += dy;
n--;
}
#endif /* FULL_AA */
while (n>0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point++ = ramp[r].blue;
*point++ = ramp[r].green;
*point++ = ramp[r].red;
X += dx;
Y += dy;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
mix_alpha(point, ramp[r], end_alpha);
}
}
#endif /* FULL_AA */
} else {
while (n--) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
cp = &ramp[r];
mix_alpha(point, *cp, cp->alpha);
point+=BPP;
X += dx;
Y += dy;
}
}
}
void
GraphicDevice24::drawLine(long x1, long y1, long x2, long y2, long width)
{
int n,adr,dx,dy,sx;
Color color;
register int a;
register TYPE *pp;
int alpha;
x1 = (x1) >> FRAC_BITS;
y1 = (y1) >> FRAC_BITS;
x2 = (x2) >> FRAC_BITS;
y2 = (y2) >> FRAC_BITS;
if (y1 > y2 || (y1 == y2 && x1 > x2)) {
long tmp;
tmp=x1;
x1=x2;
x2=tmp;
tmp=y1;
y1=y2;
y2=tmp;
}
if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
if (x1 == x2 && y1 == y2) return; // Bad !!!
if (y1 < clip_rect.ymin && y1 != y2) {
x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
y1 = clip_rect.ymin;
}
if (y2 > clip_rect.ymax && y1 != y2) {
x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
y2 = clip_rect.ymax;
}
if (x1 < x2) {
if (x1 < clip_rect.xmin && x1 != x2) {
y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
x1 = clip_rect.xmin;
}
if (x2 > clip_rect.xmax && x1 != x2) {
y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
x2 = clip_rect.xmax;
}
}
if (x1 > x2) {
if (x2 < clip_rect.xmin && x2 != x1) {
y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
x2 = clip_rect.xmin;
}
if (x1 > clip_rect.xmax && x2 != x1) {
y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
x1 = clip_rect.xmax;
}
}
// Check again
if (x1 == x2 && y1 == y2) return;
if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
sx=bpl >> 1;
adr=(y1 * sx + x1);
pp = (TYPE *)canvasBuffer + adr;
dx = x2 - x1;
dy = y2 - y1;
color = foregroundColor;
alpha = foregroundColor.alpha;
if (alpha == ALPHA_OPAQUE) {
#define PUTPIXEL() \
{ \
*pp++=color.red; \
*pp++=color.green; \
*pp++=color.blue; \
}
#define DRAWLINE(dx,dy,inc_1,inc_2) \
n=dx;\
a=2*dy-dx;\
dy=2*dy;\
dx=2*dx-dy;\
do {\
PUTPIXEL();\
if (a>0) { pp+=(inc_1); a-=dx; }\
else { pp+=(inc_2); a+=dy; }\
} while (--n >= 0);
/* fin macro */
if (dx == 0 && dy == 0) {
PUTPIXEL();
} else if (dx > 0) {
if (dx >= dy) {
DRAWLINE(dx, dy, sx + 1, 1);
} else {
DRAWLINE(dy, dx, sx + 1, sx);
}
} else {
dx = -dx;
if (dx >= dy) {
DRAWLINE(dx, dy, sx - 1, -1);
} else {
DRAWLINE(dy, dx, sx - 1, sx);
}
}
#undef DRAWLINE
#undef PUTPIXEL
} else {
#define PUTPIXEL() \
{ \
mix_alpha(pp,color,alpha); \
}
#define DRAWLINE(dx,dy,inc_1,inc_2) \
n=dx;\
a=2*dy-dx;\
dy=2*dy;\
dx=2*dx-dy;\
do {\
PUTPIXEL();\
if (a>0) { pp+=(inc_1*BPP); a-=dx; }\
else { pp+=(inc_2*BPP); a+=dy; }\
} while (--n >= 0);
/* fin macro */
if (dx == 0 && dy == 0) {
PUTPIXEL();
} else if (dx > 0) {
if (dx >= dy) {
DRAWLINE(dx, dy, sx + 1, 1);
} else {
DRAWLINE(dy, dx, sx + 1, sx);
}
} else {
dx = -dx;
if (dx >= dy) {
DRAWLINE(dx, dy, sx - 1, -1);
} else {
DRAWLINE(dy, dx, sx - 1, sx);
}
}
#undef DRAWLINE
#undef PUTPIXEL
}
}
--- NEW FILE: matrix.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "matrix.h"
#ifdef RCSID
static char *rcsid = "$Id: matrix.cc,v 1.1 2006-10-03 11:26:09 dslinux_amadeus Exp $";
#endif
Matrix::Matrix()
{
a = 1.0;
d = 1.0;
b = c = 0.0;
tx = ty = 0;
}
Matrix Matrix::operator*(Matrix m)
{
Matrix mat;
mat.a = this->a * m.a + this->b * m.c;
mat.b = this->a * m.b + this->b * m.d;
mat.c = this->c * m.a + this->d * m.c;
mat.d = this->c * m.b + this->d * m.d;
mat.tx = this->getX(m.tx,m.ty);
mat.ty = this->getY(m.tx,m.ty);
return mat;
}
Matrix Matrix::invert()
{
Matrix mat;
float det;
det = a*d-b*c;
mat.a = d/det;
mat.b = -b/det;
mat.c = -c/det;
mat.d = a/det;
mat.tx = - (long)(mat.a * tx + mat.b * ty);
mat.ty = - (long)(mat.c * tx + mat.d * ty);
return mat;
}
--- NEW FILE: Makefile ---
CC= gcc
CXX= g++
OPTIMIZE=-g -O3
# Comment out the following line if you use egcs :
CXXFLAGS=$(OPTIMIZE) $(ALLCFLAGS) $(CXXFLAGS_$(CC)) -UNDEBUG
CXXFLAGS_gcc= -Wall -fno-rtti -fno-exceptions
ifeq ($(RGB555),Y)
CXXFLAGS += -DRGB555=1
endif
CCC= $(CXX)
CCFLAGS= $(CXXFLAGS)
INCLUDES= adpcm.h cxform.h graphic.h script.h sqrt.h\
bitmap.h displaylist.h matrix.h shape.h swf.h\
button.h flash.h program.h sound.h text.h\
character.h font.h rect.h sprite.h movie.h\
mp3.h
SWFOBJS=\
flash.o \
character.o \
shape.o \
button.o \
program.o \
bitmap.o \
displaylist.o \
font.o \
graphic.o \
text.o \
matrix.o \
script.o \
sound.o \
sprite.o \
movie.o \
cxform.o \
adpcm.o \
mp3.o \
sqrt.o \
graphic16.o \
graphic24.o \
graphic32.o
# bitstream.o
# dump.o
all: libflash.a
libflash.a: $(SWFOBJS)
ar rcs $@ $(SWFOBJS)
$(SWFOBJS): $(INCLUDES)
clean:
rm -f $(SWFOBJS) *~ libflash.a
.PHONY: plugin jpeg all
--- NEW FILE: font.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: font.cc,v 1.1 2006-10-03 11:26:09 dslinux_amadeus Exp $";
#endif
SwfFont::SwfFont(long id) : Character(FontType, id)
{
glyphs = 0;
nbGlyphs = 0;
name = NULL;
setFontName("Unknown");
flags = (FontFlags)0;
lookUpTable = 0;
}
SwfFont::~SwfFont()
{
if (lookUpTable) {
delete lookUpTable;
}
delete name;
delete [] glyphs;
}
void
SwfFont::setFontFlags(FontFlags f)
{
flags = f;
}
char *
SwfFont::getName()
{
return name;
}
FontFlags
SwfFont::getFlags()
{
return flags;
}
long
SwfFont::getNbGlyphs()
{
return nbGlyphs;
}
Shape *
SwfFont::getGlyph(long index)
{
if (index >= nbGlyphs) return 0;
return &glyphs[index];
}
long
SwfFont::getGlyphCode(long index)
{
if (lookUpTable == 0 || index >= nbGlyphs) return 0;
return lookUpTable[index];
}
void
SwfFont::setFontName(char *str)
{
delete name;
name = new char[strlen(str)+1];
strcpy(name,str);
}
void
SwfFont::setFontLookUpTable(long *lut)
{
lookUpTable = lut;
}
void
SwfFont::setFontShapeTable(Shape *shapes, long n)
{
glyphs = shapes;
nbGlyphs = n;
}
--- NEW FILE: sound.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#if SUN_SOUND
#include <sys/audioio.h>
#endif
#if OSS_SOUND
#ifdef __NetBSD__
#include <soundcard.h>
#else
#include <sys/soundcard.h>
#endif
#endif
#ifdef RCSID
static char *rcsid = "$Id: sound.cc,v 1.1 2006-10-03 11:26:10 dslinux_amadeus Exp $";
#endif
#define PRINT 0
/* There are some defined missing in NetBSD's audioio.h */
#if SUN_SOUND
#ifndef AUDIO_CHANNELS_STEREO
#define AUDIO_CHANNELS_STEREO 2
#endif
#ifndef AUDIO_PRECISION_16
#define AUDIO_PRECISION_16 16
#endif
#endif
//////////// SOUND
Sound::Sound(long id) : Character(SoundType, id)
{
samples = 0;
stereo = 0;
soundRate = 0;
sampleSize = 1;
}
Sound::~Sound()
{
if (samples) {
delete samples;
}
}
void
Sound::setSoundFlags(long f) {
switch (GET_SOUND_RATE_CODE(f)) {
case 0:
soundRate = 5500;
break;
case 1:
soundRate = 11000;
break;
case 2:
soundRate = 22000;
break;
case 3:
soundRate = 44000;
break;
}
if (f & soundIs16bit) {
sampleSize = 2;
}
if (f & soundIsStereo) {
stereo = 1;
}
#if PRINT
printf("-----\nFlags = %2x\n", f);
printf("Rate = %d kHz ", soundRate);
printf("SampleSize = %d byte(s) ", sampleSize);
if (f & soundIsStereo) {
printf("Stereo ");
} else {
printf("Mono ");
}
switch (f & soundFormatMaske) {
case soundFormatADPCMCompressed:
printf("ADPCM\n");
break;
case soundFormatMP3Compressed:
printf("MP3\n");
break;
case soundFormatRaw:
printf("Raw\n");
break;
default:
printf("unknown sound format %x\n", f);
break;
}
#endif
}
char *
Sound::setNbSamples(long n) {
long size;
nbSamples = n;
size = nbSamples * (stereo ? 2 : 1) * sampleSize;
samples = new char[ size ];
memset((char *)samples,0, size);
return samples;
}
long
Sound::getRate() {
return soundRate;
}
long
Sound::getChannel() {
return stereo ? 2 : 1;
}
long
Sound::getNbSamples() {
return nbSamples;
}
long
Sound::getSampleSize() {
return sampleSize;
}
char *
Sound::getSamples() {
return samples;
}
//////////// SOUND MIXER
long SoundMixer::dsp = -1; // Init of descriptor
long SoundMixer::blockSize = 0; // Driver sound buffer size
long SoundMixer::nbInst = 0; // Nb SoundMixer instances
long SoundMixer::sampleSize = 0;
long SoundMixer::stereo = 0;
long SoundMixer::soundRate = 0;
char *SoundMixer::buffer = 0;
SoundMixer::SoundMixer(char *device)
{
#ifndef NOSOUND
int status;
list = 0; // No sound to play
if (nbInst++) {
// Device is already open
return;
}
dsp = open(device,O_WRONLY);
if (dsp < 0) {
perror("open dsp");
return;
}
#if SUN_SOUND
audio_info_t audio_info;
// Init audio_info to "harmless" values
AUDIO_INITINFO(&audio_info);
// Set sound rate in Hertz, Stereo, 16-bit PCM
audio_info.play.sample_rate = 11000;
audio_info.play.channels = AUDIO_CHANNELS_STEREO;
audio_info.play.precision = AUDIO_PRECISION_16;
audio_info.play.encoding = AUDIO_ENCODING_LINEAR;
// Configure the audio device
status = ioctl(dsp, AUDIO_SETINFO, &audio_info);
if (status < 0) perror("ioctl AUDIO_SETINFO");
sampleSize = audio_info.play.precision / 8;
stereo = audio_info.play.channels >= AUDIO_CHANNELS_STEREO;
soundRate = audio_info.play.sample_rate;
blockSize = audio_info.play.buffer_size;
if (blockSize < 1024)
blockSize = 32768;
#else /* !SUN_SOUND */
#if OSS_SOUND
// Reset device
status = ioctl(dsp, SNDCTL_DSP_RESET, 0);
if (status < 0) perror("ioctl SNDCTL_DSP_RESET");
// Set sample size
long fmt = AFMT_S16_LE;
sampleSize = 2;
status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt);
if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT");
if (status) {
fmt = AFMT_U8;
sampleSize = 1;
status = ioctl(dsp, SNDCTL_DSP_SETFMT, &fmt);
if (status < 0) perror("ioctl SNDCTL_DSP_SETFMT");
}
// Set stereo channel
stereo = 1;
status = ioctl(dsp, SNDCTL_DSP_STEREO, &stereo);
if (status) {
stereo = 0;
}
// Set sound rate in Hertz
soundRate = 11000;
status = ioctl(dsp, SNDCTL_DSP_SPEED, &soundRate);
if (status < 0) perror("ioctl SNDCTL_DSP_SPEED");
// Get device buffer size
status = ioctl(dsp, SNDCTL_DSP_GETBLKSIZE, &blockSize);
if (status < 0) perror("ioctl SNDCTL_DSP_GETBLKSIZE");
if (blockSize < 1024) {
blockSize = 32768;
}
#endif /* OSS_SOUND */
#endif /* SUN_SOUND */
blockSize *= 2;
buffer = (char *)malloc(blockSize);
if (buffer == 0) {
close(dsp);
dsp = -1;
}
#if PRINT
#if OSS_SOUND
int caps;
ioctl(dsp,SNDCTL_DSP_GETCAPS, &caps);
printf("Audio capabilities = %x\n", caps);
#endif
printf("Sound Rate = %d\n", soundRate);
printf("Stereo = %d\n", stereo);
printf("Sample Size = %d\n", sampleSize);
printf("Buffer Size = %d\n", blockSize);
#endif /* PRINT */
#endif /* NOSOUND */
}
SoundMixer::~SoundMixer()
{
if (--nbInst == 0) {
if (dsp > 0) {
close(dsp);
free(buffer);
}
}
}
void
SoundMixer::stopSounds()
{
#ifndef NOSOUND
SoundList *sl,*del;
for(sl = list; sl; ) {
del = sl;
sl = sl->next;
delete del;
}
list = 0;
#endif
}
void
SoundMixer::startSound(Sound *sound)
{
#ifndef NOSOUND
SoundList *sl;
if (sound) {
// Add sound in list
sl = new SoundList;
sl->rate = sound->getRate();
sl->stereo = (sound->getChannel() == 2);
sl->sampleSize = sound->getSampleSize();
sl->current = sound->getSamples();
sl->remaining = sound->getSampleSize()*sound->getNbSamples()*sound->getChannel();
sl->next = NULL;
// Append new sound at end of list
if (list != NULL) {
SoundList *last = list;
while (last->next != NULL)
last = last->next;
last->next = sl;
} else {
list = sl;
}
}
#endif
}
long
SoundMixer::playSounds()
{
#ifndef NOSOUND
long nbBytes, n;
SoundList *sl;
int status;
// Init failed
if (dsp < 0) return 0;
// No sound to play
if (list == 0) return 0;
#if SUN_SOUND
fd_set wrset;
struct timeval timeout;
FD_ZERO(&wrset);
FD_SET(dsp, &wrset);
timeout.tv_sec = 0;
timeout.tv_usec = 0;
status = select(dsp+1, NULL, &wrset, NULL, &timeout);
// Cannot output sound data without blocking
// But there are still sounds to play. We must wait.
if (status != 1 || !FD_ISSET(dsp, &wrset)) return 1;
#endif
#if OSS_SOUND
audio_buf_info bufInfo;
// Get free DMA buffer space
status = ioctl(dsp, SNDCTL_DSP_GETOSPACE, &bufInfo);
// Free space is not large enough to output data without blocking
// But there are still sounds to play. We must wait.
if (bufInfo.bytes < blockSize) return 1;
#endif
nbBytes = 0;
// Fill buffer with silence.
memset((void*)buffer, 0, blockSize);
sl = list;
while (sl && nbBytes < blockSize) {
// Ask sound to fill the buffer
// according to device capabilities
n = fillSoundBuffer(sl, buffer + nbBytes, blockSize - nbBytes);
// Remember amount of data written
nbBytes += n;
// No more samples for this sound
if (sl->remaining == 0) {
list = sl->next;
delete sl;
sl = list;
}
}
if (nbBytes) {
// At last ! Play It !
if (write(dsp,buffer,nbBytes) != nbBytes)
perror("write sound data");
#if OSS_SOUND
status = ioctl(dsp, SNDCTL_DSP_POST, 0);
#endif
}
return nbBytes;
#else
return 0;
#endif
}
long
SoundMixer::fillSoundBuffer(SoundList *sl, char *buff, long buffSize)
{
long sampleLeft, sampleRight;
long skipOut, skipOutInit;
long skipIn, skipInInit;
long freqRatio;
long totalOut = 0;
sampleLeft = sampleRight = 0;
skipOutInit = skipInInit = 0;
freqRatio = sl->rate / soundRate;
if (freqRatio) {
skipOutInit = freqRatio - 1;
skipInInit = 0;
}
freqRatio = soundRate / sl->rate;
if (freqRatio) {
skipInInit = freqRatio - 1;
skipOutInit = 0;
}
skipOut = skipOutInit;
skipIn = skipInInit;
while (buffSize && sl->remaining) {
if (skipIn-- == 0) {
// Get sampleLeft
if (sl->sampleSize == 2) {
sampleLeft = (long)(*(short *)(sl->current));
if (sampleSize == 1) {
sampleLeft = (sampleLeft >> 8) &0xff;
}
} else {
sampleLeft = (long)*(sl->current);
if (sampleSize == 2) {
sampleLeft <<= 8;
}
}
sl->current += sl->sampleSize;
sl->remaining -= sl->sampleSize;
if (sl->stereo) {
// Get sampleRight
if (sl->sampleSize == 2) {
sampleRight = (long)(*(short *)(sl->current));
if (sampleSize == 1) {
sampleRight = (sampleRight >> 8) &0xff;
}
} else {
sampleRight = (long)*(sl->current);
if (sampleSize == 2) {
sampleRight <<= 8;
}
}
sl->current += sl->sampleSize;
sl->remaining -= sl->sampleSize;
} else {
sampleRight = sampleLeft;
}
skipIn = skipInInit;
}
if (skipOut-- == 0) {
// Output
if (stereo) {
if (sampleSize == 2) {
*((short *)buff) += sampleLeft/2;
buffSize -= sampleSize;
buff += sampleSize;
*((short *)buff) += sampleRight/2;
buffSize -= sampleSize;
buff += sampleSize;
} else {
*((char *)buff) += sampleLeft/2;
buffSize -= sampleSize;
buff += sampleSize;
*((char *)buff) += sampleRight/2;
buffSize -= sampleSize;
buff += sampleSize;
}
totalOut += 2*sampleSize;
} else {
if (sampleSize == 2) {
*((short *)buff) += (sampleLeft+sampleRight)>>2;
buffSize -= sampleSize;
buff += sampleSize;
} else {
*((char *)buff) += (sampleLeft+sampleRight)>>2;
buffSize -= sampleSize;
buff += sampleSize;
}
totalOut += sampleSize;
}
skipOut = skipOutInit;
}
}
return totalOut;
}
--- NEW FILE: graphic24.h ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
class GraphicDevice24: public GraphicDevice {
private:
long GraphicDevice24::allocColor(Color color);
public:
GraphicDevice24(FlashDisplay *fd);
void clearCanvas();
void fillLineAA(FillStyleDef *f, long y, long start, long end);
void fillLine(FillStyleDef *f, long y, long start, long end);
void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
void fillLineLG(Gradient *grad, long y, long start, long end);
void fillLineRG(Gradient *grad, long y, long start, long end);
void drawLine(long x1, long y1, long x2, long y2, long width);
};
--- NEW FILE: mp3.cc ---
#include "swf.h"
#include <unistd.h>
#include <fcntl.h>
#ifdef RCSID
static char *rcsid = "$Id: mp3.cc,v 1.1 2006-10-03 11:26:09 dslinux_amadeus Exp $";
#endif
//
// MP3 tables
//
static int vertab[4]={2,3,1,0};
static int freqtab[4]={44100,48000,32000};
static int ratetab[2][3][16]=
{
{
{ 0, 32, 64, 96,128,160,192,224,256,288,320,352,384,416,448, 0},
{ 0, 32, 48, 56, 64, 80, 96,112,128,160,192,224,256,320,384, 0},
{ 0, 32, 40, 48, 56, 64, 80, 96,112,128,160,192,224,256,320, 0},
},
{
{ 0, 32, 48, 56, 64, 80, 96,112,128,144,160,176,192,224,256, 0},
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160, 0},
{ 0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96,112,128,144,160, 0},
},
};
//
// The Decompressor
//
// Constructor
Mp3::Mp3(unsigned char *buffer, int len, long flags)
{
this->src = buffer;
this->pos = 0;
this->len = len;
int fd = open("/tmp/data.mp3", O_WRONLY|O_CREAT|O_TRUNC, 0666);
if (fd >= 0) {
if (write(fd, buffer, len) != len)
perror("write mp3 data");
close(fd);
} else {
perror("/tmp/data.mp3");
}
}
void
Mp3::Decompress(short *dst, long n)
{
int iFrameCount = 0;
pos = 0;
for (;;) {
// Get the MP3 frame header
U8 hdr[4];
for (int i=0; i<4; i++)
hdr[i] = src[pos++];
// Decode the MP3 frame header
int ver = vertab[((hdr[1] >> 3) & 3)];
int layer = 3 - ((hdr[1] >> 1) & 3);
int pad = (hdr[2] >>1 ) & 1;
int stereo = ((hdr[3] >> 6) & 3) != 3;
int freq = 0;
int rate = 0;
if (hdr[0] != 0xFF || hdr[1] < 0xE0 || ver==3 || layer != 2) {
// bad MP3 header
printf("\t\tBAD MP3 FRAME HEADER\n");
break;
} else {
freq = freqtab[(hdr[2] >>2 ) & 3] >> ver;
rate = ratetab[ver ? 1 : 0][layer][(hdr[2] >> 4) & 15] * 1000;
if (!freq || !rate) {
// bad MP3 header
printf("\t\tBAD MP3 FRAME HEADER\n");
break;
}
}
// Get the size of a decoded MP3 frame
int iDecodedFrameSize = (576 * (stereo + 1));
if (!ver)
iDecodedFrameSize *= 2;
// Get the size of this encoded MP3 frame
int iEncodedFrameSize = ((ver ? 72 : 144) * rate) / freq + pad - 4;
char* ppszMpegVer[4] = {"1","2","2.5","3?"};
printf("Frame%d: MPEG%s Layer%d %dHz %s %dbps size:Encoded:%d Decoded:%d\n",
iFrameCount, ppszMpegVer[ver], layer+1,
freq, stereo ? "stereo" : "mono", rate,
iEncodedFrameSize, iDecodedFrameSize);
// Decode the MP3 frame
//DecodeMp3Frame(&m_fileBuf[m_filePos], iEncodedFrameSize, iDecodedFrameSize);
// Move to the next frame
iFrameCount++;
if (pos + iEncodedFrameSize >= len)
break;
pos += iEncodedFrameSize;
}
}
--- NEW FILE: sprite.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _SPRITE_H_
#define _SPRITE_H_
class Sprite : public Character {
public:
Program *program;
Sprite(FlashMovie *movie, long id, long frameCount);
~Sprite();
Program *getProgram();
int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
int hasEventHandler();
void reset();
ActionRecord *eventHandler(GraphicDevice *, FlashEvent *);
int isSprite(void);
void getBoundingBox(Rect *bb, DisplayListEntry *de);
};
#endif /* _SPRITE_H_ */
--- NEW FILE: bitmap.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: bitmap.cc,v 1.1 2006-10-03 11:26:08 dslinux_amadeus Exp $";
#endif
static unsigned char *inputData;
// Class variables
int Bitmap::haveTables = 0;
struct jpeg_decompress_struct Bitmap::jpegObject;
struct jpeg_source_mgr Bitmap::jpegSourceManager;
MyErrorHandler Bitmap::jpegErrorMgr;
Bitmap::Bitmap(long id, int level) : Character(BitmapType, id )
{
pixels = NULL;
alpha_buf = NULL;
colormap = NULL;
nbColors = 0;
defLevel = level;
}
Bitmap::~Bitmap()
{
if (pixels) {
delete[] pixels;
}
if (alpha_buf) {
delete[] alpha_buf;
}
if (colormap)
{
delete colormap;
}
if (haveTables) {
jpeg_destroy_decompress(&jpegObject);
haveTables = 0;
}
}
static void errorExit(j_common_ptr info)
{
(*info->err->output_message) (info);
longjmp(((MyErrorHandler *)info->err)->setjmp_buffer, 1);
}
// Methods for Source data manager
static void initSource(struct jpeg_decompress_struct *cInfo)
{
cInfo->src->bytes_in_buffer = 0;
}
static boolean fillInputBuffer(struct jpeg_decompress_struct *cInfo)
{
cInfo->src->next_input_byte = inputData;
cInfo->src->bytes_in_buffer = 1;
inputData++;
return 1;
}
static void skipInputData(struct jpeg_decompress_struct *cInfo, long count)
{
cInfo->src->bytes_in_buffer = 0;
inputData += count;
}
static boolean resyncToRestart(struct jpeg_decompress_struct *cInfo, int desired)
{
return jpeg_resync_to_restart(cInfo, desired);
}
static void termSource(struct jpeg_decompress_struct *cInfo)
{
}
long Bitmap::getWidth()
{
return width;
}
long Bitmap::getHeight()
{
return height;
}
Color *
Bitmap::getColormap(long *n) {
if (n) *n = nbColors;
return colormap;
}
unsigned char *
Bitmap::getPixels()
{
return pixels;
}
// Read Tables and Compressed data to produce an image
static int
buildJpegAlpha(Bitmap *b, unsigned char *buffer)
{
z_stream stream;
int status;
unsigned char *data;
data = new unsigned char[b->width*b->height];
if (data == NULL)
return -1;
stream.next_in = buffer;
stream.avail_in = 1;
stream.next_out = data;
stream.avail_out = b->width*b->height;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
status = inflateInit(&stream);
while (1) {
status = inflate(&stream, Z_SYNC_FLUSH) ;
if (status == Z_STREAM_END) {
break;
}
if (status != Z_OK) {
printf("Zlib data error : %s\n", stream.msg);
delete data;
return -1;
}
stream.avail_in = 1;
}
inflateEnd(&stream);
b->alpha_buf = data;
return 0;
}
int
Bitmap::buildFromJpegInterchangeData(unsigned char *stream, int read_alpha, long offset)
{
struct jpeg_decompress_struct cInfo;
struct jpeg_source_mgr mySrcMgr;
MyErrorHandler errorMgr;
JSAMPROW buffer[1];
unsigned char *ptrPix;
int stride;
long n;
#if PRINT&1
printf("flash: loading jpeg (interchange)\n");
#endif
// Kludge to correct some corrupted files
if (stream[1] == 0xd9 && stream[3] == 0xd8) {
stream[3] = 0xd9;
stream[1] = 0xd8;
}
// Setup error handler
cInfo.err = jpeg_std_error(&errorMgr.pub);
errorMgr.pub.error_exit = errorExit;
if (setjmp(errorMgr.setjmp_buffer)) {
// JPEG data Error
jpeg_destroy_decompress(&cInfo);
if (pixels) {
delete[] pixels;
pixels = NULL;
}
return -1;
}
// Set current stream pointer to stream
inputData = stream;
// Here it's Ok
jpeg_create_decompress(&cInfo);
// Setup source manager structure
mySrcMgr.init_source = initSource;
mySrcMgr.fill_input_buffer = fillInputBuffer;
mySrcMgr.skip_input_data = skipInputData;
mySrcMgr.resync_to_restart = resyncToRestart;
mySrcMgr.term_source = termSource;
// Set default source manager
cInfo.src = &mySrcMgr;
jpeg_read_header(&cInfo, FALSE);
jpeg_read_header(&cInfo, TRUE);
cInfo.quantize_colors = TRUE; // Create colormapped image
jpeg_start_decompress(&cInfo);
// Set objet dimensions
height = cInfo.output_height;
width = cInfo.output_width;
bpl = width;
pixels = new unsigned char [height*width];
if (pixels == NULL) {
jpeg_finish_decompress(&cInfo);
jpeg_destroy_decompress(&cInfo);
return -1;
}
ptrPix = pixels;
stride = cInfo.output_width * cInfo.output_components;
buffer[0] = (JSAMPROW)malloc(stride);
while (cInfo.output_scanline < cInfo.output_height) {
jpeg_read_scanlines(&cInfo, buffer, 1);
memcpy(ptrPix,buffer[0],stride);
ptrPix+= stride;
}
free(buffer[0]);
colormap = new Color[cInfo.actual_number_of_colors];
if (colormap == NULL) {
delete pixels;
jpeg_finish_decompress(&cInfo);
jpeg_destroy_decompress(&cInfo);
return -1;
}
nbColors = cInfo.actual_number_of_colors;
for(n=0; n < nbColors; n++)
{
colormap[n].red = cInfo.colormap[0][n];
colormap[n].green = cInfo.colormap[1][n];
colormap[n].blue = cInfo.colormap[2][n];
}
jpeg_finish_decompress(&cInfo);
jpeg_destroy_decompress(&cInfo);
if (read_alpha) {
if (buildJpegAlpha(this, stream + offset) < 0) {
return -1;
}
}
return 0;
}
// Read JPEG image using pre-loaded Tables
int
Bitmap::buildFromJpegAbbreviatedData(unsigned char *stream)
{
JSAMPROW buffer[1];
unsigned char *ptrPix;
int stride;
long n;
int status;
#if PRINT&1
printf("flash: loading jpeg (abbreviated)\n");
#endif
// Set current stream pointer to stream
inputData = stream;
// Error handler
if (setjmp(jpegErrorMgr.setjmp_buffer)) {
// JPEG data Error
//jpeg_destroy_decompress(&jpegObject);
if (pixels) {
delete[] pixels;
pixels = NULL;
}
return -1;
}
// Here it's ok
jpeg_read_header(&jpegObject, TRUE);
jpegObject.quantize_colors = TRUE; // Create colormapped image
jpeg_start_decompress(&jpegObject);
// Set objet dimensions
height = jpegObject.output_height;
width = jpegObject.output_width;
bpl = width;
pixels = new unsigned char [height*width];
if (pixels == NULL) {
jpeg_finish_decompress(&jpegObject);
return -1;
}
ptrPix = pixels;
stride = jpegObject.output_width * jpegObject.output_components;
buffer[0] = (JSAMPROW)malloc(stride);
while (jpegObject.output_scanline < jpegObject.output_height) {
status = jpeg_read_scanlines(&jpegObject, buffer, 1);
memcpy(ptrPix,buffer[0],stride);
ptrPix+= stride;
}
free(buffer[0]);
colormap = new Color[jpegObject.actual_number_of_colors];
if (colormap == NULL) {
jpeg_finish_decompress(&jpegObject);
delete pixels;
return -1;
}
nbColors = jpegObject.actual_number_of_colors;
for(n=0; n < nbColors; n++)
{
colormap[n].red = jpegObject.colormap[0][n];
colormap[n].green = jpegObject.colormap[1][n];
colormap[n].blue = jpegObject.colormap[2][n];
}
status = jpeg_finish_decompress(&jpegObject);
return 0;
}
// Just init JPEG object and read JPEG Tables
int
Bitmap::readJpegTables(unsigned char *stream)
{
if (haveTables) {
//Error, it has already been initialized
return -1;
}
// Setup error handler
jpegObject.err = jpeg_std_error(&jpegErrorMgr.pub);
jpegErrorMgr.pub.error_exit = errorExit;
if (setjmp(jpegErrorMgr.setjmp_buffer)) {
// JPEG data Error
jpeg_destroy_decompress(&jpegObject);
return -1;
}
// Set current stream pointer to stream
inputData = stream;
// Here it's Ok
jpeg_create_decompress(&jpegObject);
// Setup source manager structure
jpegSourceManager.init_source = initSource;
jpegSourceManager.fill_input_buffer = fillInputBuffer;
jpegSourceManager.skip_input_data = skipInputData;
jpegSourceManager.resync_to_restart = resyncToRestart;
jpegSourceManager.term_source = termSource;
// Set default source manager
jpegObject.src = &jpegSourceManager;
jpeg_read_header(&jpegObject, FALSE);
haveTables = 1;
return 0;
}
int
Bitmap::buildFromZlibData(unsigned char *buffer, int width, int height, int format, int tableSize, int tableHasAlpha)
{
z_stream stream;
int status;
unsigned char *data;
int elementSize;
#if PRINT&1
printf("flash: loading with zlib\n");
#endif
this->width = width;
this->height = height;
this->bpl = width;
if (tableHasAlpha) {
elementSize = 4; // Cmap is RGBA
} else {
elementSize = 3; // Cmap is RGB
}
stream.next_in = buffer;
stream.avail_in = 1;
stream.zalloc = Z_NULL;
stream.zfree = Z_NULL;
tableSize++;
// Uncompress Color Table
if (format == 3) {
unsigned char *colorTable;
long n;
// Ajust width for 32 bit padding
width = (width+3)/4*4;
this->width = width;
this->bpl = width;
depth = 1;
colorTable = new unsigned char[tableSize*elementSize];
if (colorTable == NULL) {
return -1;
}
stream.next_out = colorTable;
stream.avail_out = tableSize*elementSize;
inflateInit(&stream);
while (1) {
status = inflate(&stream, Z_SYNC_FLUSH);
if (status == Z_STREAM_END) {
break;
}
if (status != Z_OK) {
printf("Zlib cmap error : %s\n", stream.msg);
return -1;
}
stream.avail_in = 1;
// Colormap if full
if (stream.avail_out == 0) {
break;
}
}
nbColors = tableSize;
colormap = new Color[nbColors];
if (colormap == NULL) {
delete colorTable;
return -1;
}
for(n=0; n < nbColors; n++) {
colormap[n].red = colorTable[n*elementSize+0];
colormap[n].green = colorTable[n*elementSize+1];
colormap[n].blue = colorTable[n*elementSize+2];
if (tableHasAlpha) {
colormap[n].alpha = colorTable[n*elementSize+3];
}
}
delete colorTable;
} else if (format == 4) {
depth = 2;
width = (width+1)/2*2;
this->bpl = width;
} else if (format == 5) {
depth = 4;
}
data = new unsigned char[depth*width*height];
if (data == NULL) {
if (colormap) delete colormap;
return -1;
}
stream.next_out = data;
stream.avail_out = depth*width*height;
if (format != 3) {
status = inflateInit(&stream);
}
while (1) {
status = inflate(&stream, Z_SYNC_FLUSH) ;
if (status == Z_STREAM_END) {
break;
}
if (status != Z_OK) {
printf("Zlib data error : %s\n", stream.msg);
delete data;
return -1;
}
stream.avail_in = 1;
}
inflateEnd(&stream);
pixels = new unsigned char [height*width];
if (pixels == NULL) {
if (colormap) delete colormap;
delete data;
return -1;
}
if (format != 3) {
int n,c;
unsigned char r,g,b,a;
unsigned char *ptr;
r = g = b = a = 0; /* to supress warnings */
nbColors = 0;
colormap = new Color[256];
if (colormap == NULL) {
delete data;
delete pixels;
return -1;
}
memset(colormap, 0, 256 * sizeof(Color));
ptr = pixels;
for(n=0; n < width*height*depth; n+=depth,ptr++) {
switch (format) {
case 4:
a = 1;
r = (data[n] & 0x78)<<1;
g = ((data[n] & 0x03)<<6) | (data[n+1] & 0xc0)>>2;
b = (data[n+1] & 0x1e)<<3;
break;
case 5:
a = data[n];
// Reduce color dynamic range
r = data[n+1]&0xe0;
g = data[n+2]&0xe0;
b = data[n+3]&0xe0;
break;
}
for(c=0; c < nbColors; c++) {
if (r == colormap[c].red
&& g == colormap[c].green
&& b == colormap[c].blue) {
*ptr = c;
break;
}
}
if (c == nbColors) {
if (nbColors == 256) continue;
nbColors++;
if (nbColors == 256) {
//printf("Colormap entries exhausted. After %d scanned pixels\n", n/4);
}
colormap[c].alpha = a;
colormap[c].red = r;
colormap[c].green = g;
colormap[c].blue = b;
*ptr = c;
}
}
} else {
memcpy(pixels, data, width*height);
if (tableHasAlpha) {
int n;
unsigned char *ptr, *alpha;
alpha_buf = (unsigned char *)malloc(width*height);
ptr = data;
alpha = alpha_buf;
for(n=0; n < width*height; n++, ptr++, alpha++) {
*alpha = colormap[*ptr].alpha;
}
}
}
delete data;
return 0;
}
--- NEW FILE: button.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _BUTTON_H_
#define _BUTTON_H_
struct ButtonRecord {
ButtonState state;
Character *character;
long layer;
Matrix buttonMatrix;
Cxform *cxform;
struct ButtonRecord *next;
};
struct Condition {
long transition;
ActionRecord *actions;
Condition *next;
};
class Button : public Character {
public:
long defLevel;
ButtonRecord *buttonRecords;
ActionRecord *actionRecords;
Condition *conditionList;
long isMenu;
Sound *sound[4];
Button(long id, int level = 1);
~Button();
void addActionRecord( ActionRecord *ar );
void addButtonRecord( ButtonRecord *br );
void addCondition( long transition );
int execute(GraphicDevice *gd, Matrix *matrix,
Cxform *cxform, ButtonState renderState);
ActionRecord *getActionFromTransition(ButtonState currentState,
ButtonState old);
void getRegion(GraphicDevice *gd, Matrix *matrix,
void *id, ScanLineFunc scan_line_func);
ButtonRecord *getButtonRecords();
void setButtonSound(Sound *, int);
void setButtonMenu(int);
ActionRecord *getActionRecords();
Condition *getConditionList();
Sound **getSounds();
void getBoundingBox(Rect *bb, DisplayListEntry *);
void updateButtonState(DisplayListEntry *);
Character *getRenderCharacter(ButtonState state);
// Builtin
int isButton() {
return 1;
};
#ifdef DUMP
void dump(BitStream *);
void dumpButtonRecords(BitStream *, int putCxform = 0);
void dumpButtonConditions(BitStream *);
#endif
};
#endif /* _BUTTON_H_ */
--- NEW FILE: displaylist.cc ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: displaylist.cc,v 1.1 2006-10-03 11:26:08 dslinux_amadeus Exp $";
#endif
#define PRINT 0
void deleteButton(FlashMovie *movie, DisplayListEntry *e)
{
/* save the focus */
if (movie->mouse_active == 0 && e->renderState == stateOver) {
movie->lost_over = (Button *)e->character;
movie->cur_focus = NULL;
}
if (e == movie->cur_focus) {
movie->cur_focus = NULL;
}
}
void addButton(FlashMovie *movie, DisplayListEntry *e)
{
if (movie->mouse_active == 0 &&
movie->cur_focus == NULL &&
movie->lost_over == (Button *)e->character) {
/* restore the lost focus */
e->renderState = stateOver;
e->oldState = stateOver;
((Button *)e->character)->updateButtonState(e);
movie->lost_over = NULL;
movie->cur_focus = e;
}
}
DisplayList::DisplayList(FlashMovie *movie)
{
list = NULL;
this->movie = movie;
bbox.reset();
isSprite = 0;
}
DisplayList::~DisplayList()
{
clearList();
}
void
DisplayList::clearList()
{
DisplayListEntry *del, *e;
for(e = list; e;)
{
updateBoundingBox(e);
if (e->character->isButton()) {
deleteButton(movie,e);
}
del = e;
e = e->next;
delete del;
}
list = 0;
}
DisplayListEntry *
DisplayList::getList()
{
return list;
}
static void bbox(Rect *rect, Matrix *m, long x1, long y1)
{
long x,y;
x = m->getX(x1,y1);
y = m->getY(x1,y1);
if (x < rect->xmin) rect->xmin = x;
if (x > rect->xmax) rect->xmax = x;
if (y < rect->ymin) rect->ymin = y;
if (y > rect->ymax) rect->ymax = y;
}
// Update bb to include boundary, optional reset of bb
void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset)
{
if (reset) {
bb->reset();
}
if (boundary->xmin != LONG_MAX) {
bbox(bb, matrix, boundary->xmin, boundary->ymin);
bbox(bb, matrix, boundary->xmax, boundary->ymin);
bbox(bb, matrix, boundary->xmin, boundary->ymax);
bbox(bb, matrix, boundary->xmax, boundary->ymax);
}
}
void
DisplayList::placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix, Cxform *cxform, char *name)
{
DisplayListEntry *n,*e,*prev;
n = new DisplayListEntry;
if (n == NULL) return;
n->depth = depth;
n->matrix = matrix;
n->cxform = cxform;
n->character = character;
n->instanceName = name;
n->owner = this;
#if 0
printf("Dl %lx: placeObject: depth=%d character=%d cxform=%p\n",
this, n->depth,n->character ? n->character->getTagId() : 0, cxform);
#endif
if (character == 0 || matrix == 0 || cxform == 0) {
for (e = list; e; prev = e, e = e->next) {
if (e->depth == n->depth) {
if (character == 0) {
n->character = e->character;
}
if (matrix == 0) {
n->matrix = e->matrix;
}
if (cxform == 0) {
n->cxform = e->cxform;
}
break;
}
}
}
if (n->character == 0) {
// Not found !!! Should not happen
// printf("PlaceObject cannot find character at depth %ld\n", n->depth);
delete n;
return;
}
prev = 0;
for (e = list; e; prev = e, e = e->next)
{
if (e->depth == n->depth) {
if (e->character->isButton()) {
deleteButton(movie, e);
}
// Do update, object has moved or been resized
updateBoundingBox(e);
// Replace object
e->depth = n->depth;
e->matrix = n->matrix;
e->cxform = n->cxform;
e->character = n->character;
/* if it is a button, we must update its state */
if (e->character->isButton()) {
movie->buttons_updated = 1;
addButton(movie, e);
}
updateBoundingBox(e);
delete n;
return;
}
if (e->depth > n->depth) break;
}
/* new object */
/* button instantiation */
if (n->character->isButton()) {
n->renderState = stateUp;
n->oldState = stateUp;
((Button *)n->character)->updateButtonState(n);
addButton(movie,n);
}
updateBoundingBox(n);
if (prev == 0) {
// Object comes at first place
n->next = list;
list = n;
} else {
// Insert object
n->next = prev->next;
prev->next = n;
}
}
Character *
DisplayList::removeObject(GraphicDevice *gd,Character *character, long depth)
{
DisplayListEntry *e,*prev;
// List should not be empty
if (list == 0) return 0;
#if 0
printf("removeObject: depth=%d character=%d\n",
depth,character ? character->getTagId() : 0);
#endif
prev = 0;
for (e = list; e; prev = e, e = e->next) {
if (e->depth == depth) {
if (prev) {
prev->next = e->next;
} else {
list = e->next;
}
if (character == 0) {
character = e->character;
}
if (e->character->isButton()) {
deleteButton(movie, e);
}
if (e->character->isSprite()) {
((Sprite*)e->character)->reset();
}
updateBoundingBox(e);
delete e;
return character;
}
}
return 0; // Should not happen
}
void
DisplayList::updateBoundingBox(DisplayListEntry *e)
{
Rect rect;
//rect.reset();
e->character->getBoundingBox(&rect,e);
transformBoundingBox(&this->bbox, e->matrix, &rect, 0);
}
int
DisplayList::updateSprites()
{
Sprite *sprite;
DisplayListEntry *e;
int refresh = 0;
for (e = this->list; e != NULL; e = e->next) {
if (e->character->isButton() && e->buttonCharacter) {
if (e->buttonCharacter->isSprite()) {
Matrix mat;
sprite = (Sprite *)e->buttonCharacter;
refresh |= sprite->program->dl->updateSprites();
refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
mat = (*e->matrix) * e->buttonMatrix;
transformBoundingBox(&this->bbox, &mat,
&(sprite->program->dl->bbox),
0);
}
}
if (e->character->isSprite()) {
sprite = (Sprite *)e->character;
refresh |= sprite->program->dl->updateSprites();
refresh |= sprite->program->nestedMovie(this->movie->gd,this->movie->sm, e->matrix, e->cxform);
transformBoundingBox(&this->bbox, e->matrix,
&(sprite->program->dl->bbox),
0);
}
}
return refresh;
}
/* Function can return either 0,1 or 2
0: Nothing match, continue
1: Something matches, but continue searching
2: Something matches, but stop searching
*/
static int exploreButtons1(Program *prg, void *opaque,
ExploreButtonFunc func)
{
DisplayListEntry *e;
int ret, ret2 = 0;
for(e=prg->dl->list; e != NULL; e = e->next) {
if (e->character == NULL) continue;
if (e->character->isButton()) {
ret = func(opaque,prg,e);
if (ret == 2) return ret; // Func asks to return at once !!!
if (ret) ret2 = 1;
}
if (e->character->isSprite()) {
ret = exploreButtons1(((Sprite *)e->character)->program,
opaque,func);
if (ret == 2) return ret; // Func asks to return at once !!!
if (ret) ret2 = 1;
}
}
return ret2;
}
int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func)
{
CInputScript *script;
int ret;
script = movie->main;
while (script != NULL) {
if (script->program) {
ret = exploreButtons1(script->program, opaque, func);
if (ret) return ret;
}
script = script->next;
}
return 0;
}
typedef struct {
long x,y;
int hit;
DisplayListEntry *bhit;
} HitTable;
static void button_hit_func(void *id, long y, long start, long end)
{
HitTable *h = (HitTable *) id;
if ( y == h->y && (h->x >= start && h->x < end) )
h->hit = 1;
}
typedef struct {
FlashMovie *movie;
DisplayListEntry *bhit;
} ButtonHit;
static int button_hit(void *opaque, Program *prg, DisplayListEntry *e)
{
ButtonHit *h = (ButtonHit *) opaque;
HitTable hit_table;
FlashMovie *movie = h->movie;
Rect bb,boundary;
Matrix mat;
ButtonState save;
hit_table.x = movie->mouse_x;
hit_table.y = movie->mouse_y / FRAC;
hit_table.hit = 0;
// Compute the bounding box in screen coordinates
save = e->renderState;
e->renderState = stateHitTest;
e->character->getBoundingBox(&boundary,e);
e->renderState = save;
mat = (*movie->gd->adjust) * e->renderMatrix;
transformBoundingBox(&bb, &mat, &boundary, 1);
// Check if mouse is within bb
if (movie->mouse_x < bb.xmin) return 0;
if (movie->mouse_x > bb.xmax) return 0;
if (movie->mouse_y < bb.ymin) return 0;
if (movie->mouse_y > bb.ymax) return 0;
e->character->getRegion(movie->gd, &e->renderMatrix,
&hit_table, button_hit_func);
if (hit_table.hit) {
h->bhit = e;
return 1;
} else {
return 0;
}
}
static int button_reset(void *opaque, Program *prg, DisplayListEntry *e)
{
if (e->renderState != stateUp) {
e->owner->updateBoundingBox(e);
e->oldState = e->renderState;
e->renderState = stateUp;
((Button *)e->character)->updateButtonState(e);
e->owner->updateBoundingBox(e);
}
return 0;
}
/* update the button states according to the current mouse state & return the list of actions */
void
DisplayList::updateButtons(FlashMovie *movie)
{
DisplayListEntry *bhit;
ButtonHit h;
if (movie->mouse_active) {
h.bhit = NULL;
h.movie = movie;
exploreButtons(movie, &h, button_hit);
bhit = h.bhit;
/* set every button to not hit */
exploreButtons(movie, NULL, button_reset);
if (bhit) {
ButtonState state;
if (movie->button_pressed) {
state = stateDown;
} else {
state = stateOver;
}
if (state != bhit->renderState) {
bhit->owner->updateBoundingBox(bhit);
bhit->renderState = state;
((Button *)bhit->character)->updateButtonState(bhit);
bhit->owner->updateBoundingBox(bhit);
movie->cur_focus = bhit;
if (movie->cursorOnOff)
movie->cursorOnOff(1,movie->cursorOnOffClientData);
}
} else {
if (movie->cursorOnOff)
movie->cursorOnOff(0,movie->cursorOnOffClientData);
}
}
}
typedef struct {
ActionRecord *action; // Action to do
Program *prg; // Context program
} ButtonAction;
static int button_action(void *opaque, Program *prg, DisplayListEntry *e)
{
ButtonAction *h = (ButtonAction *)opaque;
static ActionRecord actionRefresh;
static ActionRecord soundFx;
Button *b;
ActionRecord **paction;
int n;
actionRefresh.action = ActionRefresh;
actionRefresh.next = 0;
soundFx.action = ActionPlaySound;
soundFx.next = &actionRefresh;
b = (Button *)e->character;
if (e->oldState != e->renderState) {
paction = &actionRefresh.next;
if (b->conditionList) {
*paction = b->getActionFromTransition(e->renderState, e->oldState);
} else if (e->renderState == stateDown) {
/* if the button is pressed and
no condition list is defined*/
*paction = b->actionRecords;
}
switch(e->renderState) {
case stateUp:
n = 0;
break;
case stateOver:
n = 1;
break;
default:
/* case stateDown: */
n = 2;
break;
}
if (b->sound[n]) {
soundFx.sound = b->sound[n];
h->action = &soundFx;
} else {
h->action = &actionRefresh;
}
e->oldState = e->renderState;
h->prg = prg;
return 2;
}
h->action = 0; // Nothing to do about this
return 0;
}
int computeActions(FlashMovie *movie, Program **prg, ActionRecord **ar)
{
ButtonAction h;
h.action = NULL;
exploreButtons(movie, &h, button_action);
if (h.action) {
*prg = h.prg;
*ar = h.action;
return 1;
}
return 0;
}
#define FOCUS_ZOOM 1.5
/* in pixels */
#define FOCUS_SIZE_MIN 50
#define FOCUS_TRANSLATE 15
int
DisplayList::render(GraphicDevice *gd, Matrix *render_matrix, Cxform *cxform)
{
DisplayListEntry *e,*cur_focus;
int sprite = 0;
long n = 0;
Cxform cxf,*cxf1;
Rect bb,boundary;
cur_focus = NULL;
/*
if (isSprite == 0) {
if (this->bbox.xmin == LONG_MAX) return 0;
gd->updateClippingRegion(&this->bbox, render_matrix);
gd->clearCanvas();
}
*/
for (e = list; e; e = e->next)
{
#if PRINT
printf("Character %3d @ %3d\n", e->character ? e->character->getTagId() : 0, e->depth);
#endif
if (e->character) {
Matrix mat;
if (render_matrix) {
mat = *render_matrix;
}
if (e->matrix) {
mat = mat * (*e->matrix);
}
/* fast clipping */
// If object boundaries are outside current clip region give up with rendering
e->character->getBoundingBox(&boundary,e);
if (boundary.xmin != LONG_MAX) {
Matrix tmat;
tmat = (*gd->adjust) * mat;
transformBoundingBox(&bb, &tmat, &boundary, 1);
bb.xmin = bb.xmin >> FRAC_BITS;
bb.ymin = bb.ymin >> FRAC_BITS;
bb.xmax = (bb.xmax + FRAC - 1) >> FRAC_BITS;
bb.ymax = (bb.ymax + FRAC - 1) >> FRAC_BITS;
if (bb.xmin >= gd->clip_rect.xmax ||
bb.xmax <= gd->clip_rect.xmin ||
bb.ymin >= gd->clip_rect.ymax ||
bb.ymax <= gd->clip_rect.ymin) {
continue;
}
}
if (cxform == NULL) {
cxf1 = e->cxform;
}
else if (e->cxform == NULL) {
cxf1 = cxform;
}
else {
cxf1 = &cxf;
cxf.ra = cxform->ra * e->cxform->ra;
cxf.ga = cxform->ga * e->cxform->ga;
cxf.ba = cxform->ba * e->cxform->ba;
cxf.aa = cxform->aa * e->cxform->aa;
cxf.rb = (long)(cxform->ra * e->cxform->rb + cxform->rb);
cxf.gb = (long)(cxform->ga * e->cxform->gb + cxform->gb);
cxf.bb = (long)(cxform->ba * e->cxform->bb + cxform->bb);
cxf.ab = (long)(cxform->aa * e->cxform->ab + cxform->ab);
}
if (e->character->isButton()) {
Button *b = (Button *) e->character;
e->renderMatrix = mat;
if (e->renderState != stateUp && movie->mouse_active == 0) {
cur_focus = e;
((Button *)e->character)->updateButtonState(e);
}
if (b->execute(gd, &mat, cxf1, e->renderState)) {
sprite = 1;
}
} else {
if (e->character->execute(gd, &mat, cxf1)) {
sprite = 1;
}
}
n++;
}
}
#if 0
{
/* display the bounding box (debug) */
Matrix tmat;
long x1,x2,y1,y2;
Color white;
white.red = 255;
white.green = white.blue = 0;
gd->setForegroundColor(white);
if (render_matrix) {
tmat = (*gd->adjust) * (*render_matrix);
} else {
tmat = *gd->adjust;
}
x1 = bbox.xmin;
y1 = bbox.ymin;
x2 = bbox.xmax;
y2 = bbox.ymax;
gd->drawLine(tmat.getX(x1,y1),tmat.getY(x1,y1),tmat.getX(x2,y1),tmat.getY(x2,y1),10*FRAC);
gd->drawLine(tmat.getX(x2,y1),tmat.getY(x2,y1),tmat.getX(x2,y2),tmat.getY(x2,y2),10*FRAC);
gd->drawLine(tmat.getX(x2,y2),tmat.getY(x2,y2),tmat.getX(x1,y2),tmat.getY(x1,y2),10*FRAC);
gd->drawLine(tmat.getX(x1,y2),tmat.getY(x1,y2),tmat.getX(x1,y1),tmat.getY(x1,y1),10*FRAC);
bbox.print();
}
#endif
// Reset clipping zone
bbox.reset();
return sprite;
}
void
DisplayList::getBoundary(Rect *bb)
{
DisplayListEntry *e;
Rect boundary;
bb->reset();
for (e = list; e; e = e->next)
{
if (e->character) {
e->character->getBoundingBox(&boundary,e);
transformBoundingBox(bb, e->matrix, &boundary, 0);
}
}
}
extern "C" {
void dump_buttons(FlashHandle flashHandle)
{
#if 0
Rect rect;
DisplayListEntry *e;
FlashMovie *movie;
movie = (FlashMovie *)flashHandle;
for (e = movie->first_button; e; e = e->next_button) {
computeBBox(movie,&rect,e);
printf("button: id=%d pos=%d %d %d %d\n",
e->character->getTagId(),
rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
#endif
}
}
--- NEW FILE: graphic16.cc ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#include "graphic16.h"
extern unsigned char SQRT[];
#define FULL_AA
#define PRINT 0
typedef unsigned short TYPE;
#if RGB555
#define RED_MASK 0x7800
#define GREEN_MASK 0x03E0
#define BLUE_MASK 0x001F
#else
#define RED_MASK 0xF800
#define GREEN_MASK 0x07E0
#define BLUE_MASK 0x001F
#endif
GraphicDevice16::GraphicDevice16(FlashDisplay *fd) : GraphicDevice(fd)
{
}
long
GraphicDevice16::allocColor(Color color)
{
#if RGB555
return (color.red >> 3)<<10 | (color.green>>3)<<5 | (color.blue>>3);
#else
return (color.red >> 3)<<11 | (color.green>>2)<<5 | (color.blue>>3);
#endif
}
void
GraphicDevice16::clearCanvas()
{
TYPE pixel;
TYPE *point,*p;
long h, w,n;
if (!bgInitialized) return;
pixel = allocColor(backgroundColor);
point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
w = clip_rect.xmax - clip_rect.xmin;
h = clip_rect.ymax - clip_rect.ymin;
while (h--) {
p = point;
n = w;
while (n--) {
*p++ = pixel;
}
point = (TYPE *)((char *)point + bpl);
}
flashDisplay->flash_refresh = 1;
flashDisplay->clip_x = clip_rect.xmin;
flashDisplay->clip_y = clip_rect.ymin;
flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
}
/* alpha = 0 : select c1, alpha = 255 select c2 */
static inline unsigned long
mix_alpha(unsigned long c1,
unsigned long c2, int alpha)
{
long r1,r2,r;
long g1,g2,g;
long b1,b2,b;
r1 = c1 & RED_MASK;
r2 = c2 & RED_MASK;
r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;
g1 = c1 & GREEN_MASK;
g2 = c2 & GREEN_MASK;
g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;
b1 = c1 & BLUE_MASK;
b2 = c2 & BLUE_MASK;
b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;
return (r|g|b);
}
void
GraphicDevice16::fillLineAA(FillStyleDef *f, long y, long start, long end)
{
register long n;
TYPE *line;
TYPE *point,pixel;
unsigned int alpha, start_alpha,end_alpha;
if (clip(y,start,end)) return;
line = (TYPE *)(canvasBuffer + bpl*y);
alpha = f->color.alpha;
pixel = f->color.pixel;
if (alpha == ALPHA_OPAQUE) {
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start >>= FRAC_BITS;
end >>= FRAC_BITS;
point = &line[start];
if (start == end) {
*point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
} else {
n = end-start;
if (start_alpha < 255) {
*point = mix_alpha(*point, pixel, start_alpha);
point++;
n--;
}
while (n > 0) {
*point = pixel;
point++;
n--;
}
if (end_alpha > 0) {
*point = mix_alpha(*point, pixel, end_alpha);
}
}
} else {
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start >>= FRAC_BITS;
end >>= FRAC_BITS;
point = &line[start];
if (start == end) {
*point = mix_alpha(*point, pixel,
((start_alpha + end_alpha - 255) * alpha) >> 8);
} else {
n = end-start;
if (start_alpha < 255) {
*point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
point++;
n--;
}
while (n > 0) {
*point = mix_alpha(*point, pixel, alpha);
point++;
n--;
}
if (end_alpha > 0) {
*point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
}
}
}
}
void
GraphicDevice16::fillLine(FillStyleDef *f, long y, long start, long end)
{
register long n;
TYPE *line,*point;
TYPE pixel;
unsigned int alpha;
if (clip(y,start,end)) return;
start >>= FRAC_BITS;
end >>= FRAC_BITS;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
n = end-start;
pixel = f->color.pixel;
alpha = f->color.alpha;
if (alpha == ALPHA_OPAQUE) {
while (n--) {
*point = pixel;
point++;
}
} else {
while (n--) {
*point = mix_alpha(*point, pixel, alpha);
point++;
}
}
}
void
GraphicDevice16::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
{
int n;
long x1,y1,dx,dy;
Matrix *m = &f->bitmap_matrix;
Bitmap *b = f->bitmap;
unsigned char *pixels;
TYPE *p;
Color *cmap;
long pixbpl;
TYPE pixel;
int offset;
unsigned char *alpha_table;
/* safety test) */
if (!b) return;
if (clip(y,start,end)) return;
start /= FRAC;
end /= FRAC;
n = end - start;
p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * 2);
/* the coordinates in the image are normalized to 16 bits */
x1 = (long) (m->a * start + m->b * y + m->tx);
y1 = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
pixels = b->pixels;
pixbpl = b->bpl;
cmap = f->cmap;
if (b->alpha_buf == NULL) {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
*p = pixel;
}
x1 += dx;
y1 += dy;
p++;
n--;
}
} else if (f->alpha_table) {
alpha_table = f->alpha_table;
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
pixel = cmap[pixels[offset]].pixel;
*p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
}
x1 += dx;
y1 += dy;
p++;
n--;
}
} else {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
pixel = cmap[pixels[offset]].pixel;
*p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
}
x1 += dx;
y1 += dy;
p++;
n--;
}
}
}
void
GraphicDevice16::fillLineLG(Gradient *grad, long y, long start, long end)
{
long dr,r,v,r2;
register long n;
TYPE *line;
TYPE *point;
Color *cp,*ramp;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
r = (long) (m->a * start + m->b * y + m->tx);
dr = (long) (m->a);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
r2 = r + n * dr;
if ( ((r | r2) & ~255) == 0 ) {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
point++;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
*point = (TYPE)ramp[v].pixel;
point++;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
cp = &ramp[v];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
r += dr;
}
}
} else {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
point++;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = (TYPE)ramp[v].pixel;
point++;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
cp = &ramp[v];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
r += dr;
}
}
}
}
void
GraphicDevice16::fillLineRG(Gradient *grad, long y, long start, long end)
{
long X,dx,r,Y,dy;
long dist2;
register long n;
Color *cp,*ramp;
TYPE *line;
TYPE *point;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
X = (long) (m->a * start + m->b * y + m->tx);
Y = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start == end) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r = SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
} else {
if (start_alpha < 255) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r = SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
point++;
X += dx;
Y += dy;
n--;
}
#endif /* FULL_AA */
while (n>0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = (TYPE)ramp[r].pixel;
point++;
X += dx;
Y += dy;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
}
}
#endif /* FULL_AA */
} else {
while (n--) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
cp = &ramp[r];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
X += dx;
Y += dy;
}
}
}
void
GraphicDevice16::drawLine(long x1, long y1, long x2, long y2, long width)
{
int n,adr,dx,dy,sx,color;
register int a;
register TYPE *pp;
int alpha;
x1 = (x1) >> FRAC_BITS;
y1 = (y1) >> FRAC_BITS;
x2 = (x2) >> FRAC_BITS;
y2 = (y2) >> FRAC_BITS;
if (y1 > y2 || (y1 == y2 && x1 > x2)) {
long tmp;
tmp=x1;
x1=x2;
x2=tmp;
tmp=y1;
y1=y2;
y2=tmp;
}
if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
if (x1 == x2 && y1 == y2) return; // Bad !!!
if (y1 < clip_rect.ymin && y1 != y2) {
x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
y1 = clip_rect.ymin;
}
if (y2 > clip_rect.ymax && y1 != y2) {
x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
y2 = clip_rect.ymax;
}
if (x1 < x2) {
if (x1 < clip_rect.xmin && x1 != x2) {
y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
x1 = clip_rect.xmin;
}
if (x2 > clip_rect.xmax && x1 != x2) {
y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
x2 = clip_rect.xmax;
}
}
if (x1 > x2) {
if (x2 < clip_rect.xmin && x2 != x1) {
y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
x2 = clip_rect.xmin;
}
if (x1 > clip_rect.xmax && x2 != x1) {
y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
x1 = clip_rect.xmax;
}
}
// Check again
if (x1 == x2 && y1 == y2) return;
if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
sx=bpl >> 1;
adr=(y1 * sx + x1);
pp = (TYPE *)canvasBuffer + adr;
dx = x2 - x1;
dy = y2 - y1;
color = allocColor(foregroundColor);
alpha = foregroundColor.alpha;
if (alpha == ALPHA_OPAQUE) {
#define PUTPIXEL() \
{ \
*pp=color; \
}
#define DRAWLINE(dx,dy,inc_1,inc_2) \
n=dx;\
a=2*dy-dx;\
dy=2*dy;\
dx=2*dx-dy;\
do {\
PUTPIXEL();\
if (a>0) { pp+=(inc_1); a-=dx; }\
else { pp+=(inc_2); a+=dy; }\
} while (--n >= 0);
/* fin macro */
if (dx == 0 && dy == 0) {
PUTPIXEL();
} else if (dx > 0) {
if (dx >= dy) {
DRAWLINE(dx, dy, sx + 1, 1);
} else {
DRAWLINE(dy, dx, sx + 1, sx);
}
} else {
dx = -dx;
if (dx >= dy) {
DRAWLINE(dx, dy, sx - 1, -1);
} else {
DRAWLINE(dy, dx, sx - 1, sx);
}
}
#undef DRAWLINE
#undef PUTPIXEL
} else {
#define PUTPIXEL() \
{ \
*pp=mix_alpha(*pp,color,alpha); \
}
#define DRAWLINE(dx,dy,inc_1,inc_2) \
n=dx;\
a=2*dy-dx;\
dy=2*dy;\
dx=2*dx-dy;\
do {\
PUTPIXEL();\
if (a>0) { pp+=(inc_1); a-=dx; }\
else { pp+=(inc_2); a+=dy; }\
} while (--n >= 0);
/* fin macro */
if (dx == 0 && dy == 0) {
PUTPIXEL();
} else if (dx > 0) {
if (dx >= dy) {
DRAWLINE(dx, dy, sx + 1, 1);
} else {
DRAWLINE(dy, dx, sx + 1, sx);
}
} else {
dx = -dx;
if (dx >= dy) {
DRAWLINE(dx, dy, sx - 1, -1);
} else {
DRAWLINE(dy, dx, sx - 1, sx);
}
}
#undef DRAWLINE
#undef PUTPIXEL
}
}
--- NEW FILE: script.cc ---
#include "swf.h"
////////////////////////////////////////////////////////////
// This file is derived from the 'buggy' SWF parser provided
// by Macromedia.
//
// Modifications : Olivier Debon <odebon at club-internet.fr>
//
#ifdef RCSID
static char *rcsid = "$Id: script.cc,v 1.1 2006-10-03 11:26:10 dslinux_amadeus Exp $";
#endif
#ifndef NDEBUG
#define printf(fmt, args...)
#endif
//////////////////////////////////////////////////////////////////////
// Inline input script object methods.
[...1978 lines suppressed...]
frameRate = GetWord() >> 8;
frameCount = GetWord();
program = new Program(movie, frameCount);
if (program == NULL || program->totalFrames == 0) {
return FLASH_PARSE_ERROR;
}
status |= FLASH_PARSE_START;
}
ParseTags(&status);
return status;
}
--- NEW FILE: graphic.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _GRAPHIC_H_
#define _GRAPHIC_H_
#define ALPHA_OPAQUE 255
enum FillType {
f_Solid = 0x00,
f_LinearGradient = 0x10,
f_RadialGradient = 0x12,
f_TiledBitmap = 0x40,
f_clippedBitmap = 0x41,
f_None = 0x80
};
struct Gradient {
int nbGradients;
unsigned char ratio[8];
Color color[8];
// For rendering
Color *ramp;
Matrix imat;
int has_alpha;
};
struct FillStyleDef {
FillType type; // See enum FillType
// Solid
Color color;
// Gradient
Gradient gradient;
// Bitmap
Bitmap *bitmap;
Matrix bitmap_matrix;
Color *cmap;
unsigned char *alpha_table;
// Gradient or Bitmap
Matrix matrix;
FillStyleDef() {
style_size += sizeof(FillStyleDef);
style_nb++;
}
};
struct Segment {
long x1,x2;
long ymax;
FillStyleDef *fs[2]; // 0 is left 1 is right
int aa;
long dX;
long X;
struct Segment *next;
struct Segment *nextValid;
};
/* fractional bits (we don't use twips here... too expensive) */
#define FRAC_BITS 5
#define FRAC (1 << FRAC_BITS)
#define NB_SEGMENT_MAX (2048*4)
#define SEGFRAC 8
class GraphicDevice {
int targetWidth;
int targetHeight;
Rect viewPort;
int movieWidth;
int movieHeight;
int zoom;
unsigned long redMask;
unsigned long greenMask;
unsigned long blueMask;
int clipping;
public:
FlashDisplay *flashDisplay;
int bgInitialized;
Color backgroundColor;
Color foregroundColor;
public:
void *scan_line_func_id;
ScanLineFunc scan_line_func;
Rect clip_rect;
private:
Segment **segs;
int ymin,ymax;
int height;
Segment *seg_pool;
Segment *seg_pool_cur;
Segment * allocSeg();
Segment * progressSegments(Segment * curSegs, long y);
Segment * newSegments(Segment *curSegs, Segment *newSegs);
void renderScanLine(long y, Segment *curSegs);
protected:
long clip(long &y, long &start, long &end);
public:
Matrix *adjust; // Matrix to fit window (shrink or expand)
long showMore; // Used for debugging
// For Direct Graphics
unsigned char *canvasBuffer; // A pointer to canvas'memory
long bpl; // Bytes per line
long bpp; // Bytes per pixel
long pad; // Scanline pad in byte
GraphicDevice(FlashDisplay *fd);
virtual ~GraphicDevice();
int setBackgroundColor(Color);
void setForegroundColor(Color);
Color getBackgroundColor();
Color getForegroundColor();
void setMovieDimension(long width, long height);
void setMovieZoom(int zoom);
void setMovieOffset(long x, long y);
long getWidth();
long getHeight();
Color *getColormap(Color *old, long n, Cxform *cxform);
void drawBox(long x1, long y1, long x2, long y2);
void addSegment(long x1, long y1, long x2, long y2,
FillStyleDef *f0,
FillStyleDef *f1,
int aa);
void drawPolygon(void);
void updateClippingRegion(Rect *);
void setClipping(int);
// Virtual functions
virtual void clearCanvas();
virtual long allocColor(Color color);
virtual void fillLineBitmap(FillStyleDef *f, long y, long start, long end);
virtual void fillLineLG(Gradient *grad, long y, long start, long end);
virtual void fillLineRG(Gradient *grad, long y, long start, long end);
virtual void fillLine(FillStyleDef *f, long y, long start, long end);
virtual void fillLineAA(FillStyleDef *f, long y, long start, long end);
virtual void drawLine(long x1, long y1, long x2, long y2, long width);
};
#endif /* _GRAPHIC_H_ */
--- NEW FILE: sprite.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#ifdef RCSID
static char *rcsid = "$Id: sprite.cc,v 1.1 2006-10-03 11:26:10 dslinux_amadeus Exp $";
#endif
Sprite::Sprite(FlashMovie *movie, long id, long frameCount) : Character(SpriteType, id)
{
program = new Program(movie, frameCount);
if (program == NULL) return;
if (program->totalFrames == 0) {
delete program;
program = NULL;
return;
}
program->dl->isSprite = 1;
}
Sprite::~Sprite()
{
delete program;
}
void
Sprite::reset()
{
program->rewindMovie();
}
int
Sprite::isSprite(void)
{
return 1;
}
Program *
Sprite::getProgram()
{
return program;
}
int
Sprite::execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform)
{
return program->dl->render(gd,matrix,cxform);
}
ActionRecord *
Sprite::eventHandler(GraphicDevice *gd, FlashEvent *event)
{
#if 0
DisplayList *dl;
ActionRecord *actions;
dl = program->getDisplayList();
actions = dl->processEvent(gd, event);
if (actions) {
program->doAction(actions,0);
}
return actions;
#endif
return NULL;
}
void
Sprite::getBoundingBox(Rect *bb, DisplayListEntry *e)
{
program->dl->getBoundary(bb);
}
--- NEW FILE: displaylist.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _DISPLAYLIST_H_
#define _DISPLAYLIST_H_
class Character;
class Program;
struct DisplayList;
// Display List management
struct DisplayListEntry {
Character *character;
long depth;
Matrix *matrix;
Cxform *cxform;
char *instanceName;
/* button state */
ButtonState renderState;
ButtonState oldState;
Character *buttonCharacter;
Matrix buttonMatrix;
Matrix renderMatrix; /* last render matrix */
DisplayListEntry *next;
DisplayList *owner; // Parent
};
struct DisplayList {
DisplayListEntry *list;
FlashMovie *movie;
Rect bbox; // Delta clipping region
int isSprite;
public:
DisplayList(FlashMovie *movie);
~DisplayList();
DisplayListEntry *getList();
void clearList();
void placeObject(GraphicDevice *gd,Character *character, long depth, Matrix *matrix = 0, Cxform *cxform = 0, char *name = 0);
Character *removeObject(GraphicDevice *gd, Character *character, long depth);
int render(GraphicDevice *gd, Matrix *m = 0, Cxform *cxform = 0);
void updateBoundingBox(DisplayListEntry *);
void updateButtons (FlashMovie *);
void getBoundary(Rect *bb); // Returns boundary of current displayed objects
int updateSprites(); // Update sprites in the display list
};
typedef void (*DisplayListFunc)(DisplayListEntry *e, void *opaque);
void updateButtons(FlashMovie *m);
int computeActions(FlashMovie *m, Program **prog, ActionRecord **ar);
void renderFocus(FlashMovie *movie);
typedef int (*ExploreButtonFunc)(void *opaque, Program *prg, DisplayListEntry *e);
int exploreButtons(FlashMovie *movie, void *opaque, ExploreButtonFunc func);
void updateBoundingBox(DisplayListEntry *e);
void transformBoundingBox(Rect *bb, Matrix *matrix, Rect *boundary, int reset);
void updateButtonState(DisplayListEntry *e, ButtonState state);
#endif /* _DISPLAYLIST_H_ */
--- NEW FILE: sound.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _SOUND_H_
#define _SOUND_H_
#define GET_SOUND_RATE_CODE(f) (((f)&0x0c)>>2)
class Sound : public Character {
long soundRate; // In hz
long stereo; // True if stereo sound
long sampleSize; // 1 or 2 bytes
char *samples; // Array of samples
long nbSamples;
public:
Sound(long id);
~Sound();
void setSoundFlags(long f);
char *setNbSamples(long n);
long getRate();
long getChannel();
long getNbSamples();
long getSampleSize();
char *getSamples();
};
struct SoundList {
long rate;
long stereo;
long sampleSize;
long nbSamples;
long remaining;
char *current;
SoundList *next;
};
class SoundMixer {
SoundList *list;
// Class variables
static long dsp; // Descriptor for /dev/dsp
static char * buffer; // DMA buffer
static long blockSize;
static long nbInst; // Number of instances
// Sound Device Capabilities
static long soundRate; // In hz
static long stereo; // True if stereo sound
static long sampleSize; // 1 or 2 bytes
public:
SoundMixer(char*);
~SoundMixer();
void startSound(Sound *sound); // Register a sound to be played
void stopSounds(); // Stop every current sounds in the instance
long playSounds(); // Actually play sounds of all instances
long fillSoundBuffer(SoundList *, char *buffer, long bufferSize); // Fill sound buffer
};
#endif /* _SOUND_H_ */
--- NEW FILE: cxform.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _CXFORM_H_
#define _CXFORM_H_
struct Color {
unsigned char red,green,blue,alpha;
long pixel;
};
struct Cxform
{
float aa; long ab; // a is multiply factor, b is addition factor
float ra; long rb;
float ga; long gb;
float ba; long bb;
long getRed(long v);
long getGreen(long v);
long getBlue(long v);
long getAlpha(long v);
Color getColor(Color color);
#ifdef DUMP
void dump(BitStream *bs, int alpha = 0);
#endif
};
#endif /* _CXFORM_H_ */
--- NEW FILE: graphic_generic.cc ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
[...1241 lines suppressed...]
if (clip_rect.ymax < viewPort.ymin) clip_rect.ymax = viewPort.ymin;
if (clip_rect.xmax > viewPort.xmax) clip_rect.xmax = viewPort.xmax;
if (clip_rect.ymax > viewPort.ymax) clip_rect.ymax = viewPort.ymax;
if (clip_rect.xmin > viewPort.xmax) clip_rect.xmin = viewPort.xmax;
if (clip_rect.ymin > viewPort.ymax) clip_rect.ymin = viewPort.ymax;
}
void
GraphicDevice::setClipping(int value)
{
clipping = value;
if (clipping == 0) {
// Reset region
clip_rect.xmin = viewPort.xmin;
clip_rect.xmax = viewPort.xmax;
clip_rect.ymin = viewPort.ymin;
clip_rect.ymax = viewPort.ymax;
}
}
--- NEW FILE: graphic32.cc ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#include "graphic32.h"
extern unsigned char SQRT[];
#define FULL_AA
#define PRINT 0
typedef unsigned long TYPE;
GraphicDevice32::GraphicDevice32(FlashDisplay *fd) : GraphicDevice(fd)
{
}
long
GraphicDevice32::allocColor(Color color)
{
return (color.red)<<16 | (color.green)<<8 | (color.blue);
}
void
GraphicDevice32::clearCanvas()
{
TYPE pixel;
TYPE *point,*p;
long h, w,n;
if (!bgInitialized) return;
pixel = allocColor(backgroundColor);
point = (TYPE *)(canvasBuffer + clip_rect.ymin * bpl) + clip_rect.xmin;
w = clip_rect.xmax - clip_rect.xmin;
h = clip_rect.ymax - clip_rect.ymin;
while (h--) {
p = point;
n = w;
while (n--) {
*p++ = pixel;
}
point = (TYPE *)((char *)point + bpl);
}
flashDisplay->flash_refresh = 1;
flashDisplay->clip_x = clip_rect.xmin;
flashDisplay->clip_y = clip_rect.ymin;
flashDisplay->clip_width = clip_rect.xmax-clip_rect.xmin;
flashDisplay->clip_height = clip_rect.ymax-clip_rect.ymin;
}
#define RED_MASK 0xFF0000
#define GREEN_MASK 0x00FF00
#define BLUE_MASK 0x0000FF
/* alpha = 0 : select c1, alpha = 255 select c2 */
static inline unsigned long
mix_alpha(unsigned long c1, unsigned long c2, int alpha)
{
long r1,r2,r;
long g1,g2,g;
long b1,b2,b;
r1 = c1 & RED_MASK;
r2 = c2 & RED_MASK;
r = (((r2-r1)*alpha + r1 * 256) >> 8) & RED_MASK;
g1 = c1 & GREEN_MASK;
g2 = c2 & GREEN_MASK;
g = (((g2-g1)*alpha + g1 * 256) >> 8) & GREEN_MASK;
b1 = c1 & BLUE_MASK;
b2 = c2 & BLUE_MASK;
b = (((b2-b1)*alpha + b1 * 256) >> 8) & BLUE_MASK;
return (r|g|b);
}
void
GraphicDevice32::fillLineAA(FillStyleDef *f, long y, long start, long end)
{
register long n;
TYPE *line;
TYPE *point,pixel;
unsigned int alpha, start_alpha,end_alpha;
if (clip(y,start,end)) return;
line = (TYPE *)(canvasBuffer + bpl*y);
alpha = f->color.alpha;
pixel = f->color.pixel;
if (alpha == ALPHA_OPAQUE) {
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start >>= FRAC_BITS;
end >>= FRAC_BITS;
point = &line[start];
if (start == end) {
*point = mix_alpha(*point, pixel, start_alpha + end_alpha - 255);
} else {
n = end-start;
if (start_alpha < 255) {
*point = mix_alpha(*point, pixel, start_alpha);
point++;
n--;
}
while (n > 0) {
*point = pixel;
point++;
n--;
}
if (end_alpha > 0) {
*point = mix_alpha(*point, pixel, end_alpha);
}
}
} else {
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start >>= FRAC_BITS;
end >>= FRAC_BITS;
point = &line[start];
if (start == end) {
*point = mix_alpha(*point, pixel,
((start_alpha + end_alpha - 255) * alpha) >> 8);
} else {
n = end-start;
if (start_alpha < 255) {
*point = mix_alpha(*point, pixel, (start_alpha * alpha) >> 8);
point++;
n--;
}
while (n > 0) {
*point = mix_alpha(*point, pixel, alpha);
point++;
n--;
}
if (end_alpha > 0) {
*point = mix_alpha(*point, pixel, (end_alpha * alpha) >> 8);
}
}
}
}
void
GraphicDevice32::fillLine(FillStyleDef *f, long y, long start, long end)
{
register long n;
TYPE *line,*point;
TYPE pixel;
unsigned int alpha;
if (clip(y,start,end)) return;
start >>= FRAC_BITS;
end >>= FRAC_BITS;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
n = end-start;
pixel = f->color.pixel;
alpha = f->color.alpha;
if (alpha == ALPHA_OPAQUE) {
while (n--) {
*point = pixel;
point++;
}
} else {
while (n--) {
*point = mix_alpha(*point, pixel, alpha);
point++;
}
}
}
void
GraphicDevice32::fillLineBitmap(FillStyleDef *f, long y, long start, long end)
{
int n;
long x1,y1,dx,dy;
Matrix *m = &f->bitmap_matrix;
Bitmap *b = f->bitmap;
unsigned char *pixels;
TYPE *p;
Color *cmap;
long pixbpl;
TYPE pixel;
int offset;
unsigned char *alpha_table;
/* safety test) */
if (!b) return;
if (clip(y,start,end)) return;
start /= FRAC;
end /= FRAC;
n = end - start;
p = (TYPE *) (this->canvasBuffer + this->bpl*y + start * sizeof(TYPE));
/* the coordinates in the image are normalized to 16 bits */
x1 = (long) (m->a * start + m->b * y + m->tx);
y1 = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
pixels = b->pixels;
pixbpl = b->bpl;
cmap = f->cmap;
if (b->alpha_buf == NULL) {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
pixel = cmap[pixels[(y1 >> 16) * pixbpl + (x1 >> 16)]].pixel;
*p = pixel;
}
x1 += dx;
y1 += dy;
p++;
n--;
}
} else if (f->alpha_table) {
alpha_table = f->alpha_table;
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
pixel = cmap[pixels[offset]].pixel;
*p = mix_alpha(*p, pixel, alpha_table[b->alpha_buf[offset]]);
}
x1 += dx;
y1 += dy;
p++;
n--;
}
} else {
while (n) {
if (x1 >= 0 && y1 >= 0 &&
(x1 >> 16) < b->width && (y1 >> 16) < b->height) {
offset = (y1 >> 16) * pixbpl + (x1 >> 16);
pixel = cmap[pixels[offset]].pixel;
*p = mix_alpha(*p, pixel, b->alpha_buf[offset]);
}
x1 += dx;
y1 += dy;
p++;
n--;
}
}
}
void
GraphicDevice32::fillLineLG(Gradient *grad, long y, long start, long end)
{
long dr,r,v,r2;
register long n;
TYPE *line;
TYPE *point;
Color *cp,*ramp;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
r = (long) (m->a * start + m->b * y + m->tx);
dr = (long) (m->a);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
r2 = r + n * dr;
if ( ((r | r2) & ~255) == 0 ) {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
point++;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
*point = (TYPE)ramp[v].pixel;
point++;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
cp = &ramp[v];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
r += dr;
}
}
} else {
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start_alpha < 255) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, start_alpha);
point++;
r += dr;
n--;
}
#endif /* FULL_AA */
while (n>0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = (TYPE)ramp[v].pixel;
point++;
r += dr;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
*point = mix_alpha(*point, (TYPE)ramp[v].pixel, end_alpha);
}
#endif /* FULL_AA */
} else {
while (n--) {
v = r>>16;
if (v < 0) v = 0;
else if (v > 255) v = 255;
cp = &ramp[v];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
r += dr;
}
}
}
}
void
GraphicDevice32::fillLineRG(Gradient *grad, long y, long start, long end)
{
long X,dx,r,Y,dy;
long dist2;
register long n;
Color *cp,*ramp;
TYPE *line;
TYPE *point;
Matrix *m = &grad->imat;
unsigned int start_alpha,end_alpha;
if (clip(y,start,end)) return;
start_alpha = 255 - ((start & (FRAC-1)) << (8-FRAC_BITS));
end_alpha = (end & (FRAC-1)) << (8-FRAC_BITS);
start /= FRAC;
end /= FRAC;
n = end-start;
X = (long) (m->a * start + m->b * y + m->tx);
Y = (long) (m->c * start + m->d * y + m->ty);
dx = (long) (m->a);
dy = (long) (m->c);
ramp = grad->ramp;
line = (TYPE *)(canvasBuffer + bpl*y);
point = &line[start];
if (!grad->has_alpha) {
#ifdef FULL_AA
if (start == end) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r = SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha + end_alpha - 255);
} else {
if (start_alpha < 255) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r = SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, start_alpha);
point++;
X += dx;
Y += dy;
n--;
}
#endif /* FULL_AA */
while (n>0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = (TYPE)ramp[r].pixel;
point++;
X += dx;
Y += dy;
n--;
}
#ifdef FULL_AA
if (end_alpha > 0) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
*point = mix_alpha(*point, (TYPE)ramp[r].pixel, end_alpha);
}
}
#endif /* FULL_AA */
} else {
while (n--) {
dist2 = ((X>>16)*(X>>16))+((Y>>16)*(Y>>16));
if ((unsigned long)dist2 >= 65536) {
r = 255;
} else {
r= SQRT[dist2];
}
cp = &ramp[r];
*point = mix_alpha(*point, cp->pixel, cp->alpha);
point++;
X += dx;
Y += dy;
}
}
}
void
GraphicDevice32::drawLine(long x1, long y1, long x2, long y2, long width)
{
int n,adr,dx,dy,sx,color;
register int a;
register TYPE *pp;
int alpha;
x1 = (x1) >> FRAC_BITS;
y1 = (y1) >> FRAC_BITS;
x2 = (x2) >> FRAC_BITS;
y2 = (y2) >> FRAC_BITS;
if (y1 > y2 || (y1 == y2 && x1 > x2)) {
long tmp;
tmp=x1;
x1=x2;
x2=tmp;
tmp=y1;
y1=y2;
y2=tmp;
}
if (y1 == y2 && (y1 < clip_rect.ymin || y1 > clip_rect.ymax)) return;
if (x1 == x2 && (x1 < clip_rect.xmin || x1 > clip_rect.xmax)) return;
if (x1 == x2 && y1 == y2) return; // Bad !!!
if (y1 < clip_rect.ymin && y1 != y2) {
x1 += (x2-x1)*(clip_rect.ymin-y1)/(y2-y1);
y1 = clip_rect.ymin;
}
if (y2 > clip_rect.ymax && y1 != y2) {
x2 -= (x2-x1)*(y2-clip_rect.ymax)/(y2-y1);
y2 = clip_rect.ymax;
}
if (x1 < x2) {
if (x1 < clip_rect.xmin && x1 != x2) {
y1 += (y2-y1)*(clip_rect.xmin-x1)/(x2-x1);
x1 = clip_rect.xmin;
}
if (x2 > clip_rect.xmax && x1 != x2) {
y2 -= (y2-y1)*(x2-clip_rect.xmax)/(x2-x1);
x2 = clip_rect.xmax;
}
}
if (x1 > x2) {
if (x2 < clip_rect.xmin && x2 != x1) {
y2 -= (y2-y1)*(clip_rect.xmin-x2)/(x1-x2);
x2 = clip_rect.xmin;
}
if (x1 > clip_rect.xmax && x2 != x1) {
y1 += (y2-y1)*(x1-clip_rect.xmax)/(x1-x2);
x1 = clip_rect.xmax;
}
}
// Check again
if (x1 == x2 && y1 == y2) return;
if (x1 < clip_rect.xmin || x2 < clip_rect.xmin) return;
if (y1 < clip_rect.ymin || y2 < clip_rect.ymin) return;
if (x1 > clip_rect.xmax || x2 > clip_rect.xmax) return;
if (y1 > clip_rect.ymax || y2 > clip_rect.ymax) return;
sx=bpl >> 1;
adr=(y1 * sx + x1);
pp = (TYPE *)canvasBuffer + adr;
dx = x2 - x1;
dy = y2 - y1;
color = allocColor(foregroundColor);
alpha = foregroundColor.alpha;
if (alpha == ALPHA_OPAQUE) {
#define PUTPIXEL() \
{ \
*pp=color; \
}
#define DRAWLINE(dx,dy,inc_1,inc_2) \
n=dx;\
a=2*dy-dx;\
dy=2*dy;\
dx=2*dx-dy;\
do {\
PUTPIXEL();\
if (a>0) { pp+=(inc_1); a-=dx; }\
else { pp+=(inc_2); a+=dy; }\
} while (--n >= 0);
/* fin macro */
if (dx == 0 && dy == 0) {
PUTPIXEL();
} else if (dx > 0) {
if (dx >= dy) {
DRAWLINE(dx, dy, sx + 1, 1);
} else {
DRAWLINE(dy, dx, sx + 1, sx);
}
} else {
dx = -dx;
if (dx >= dy) {
DRAWLINE(dx, dy, sx - 1, -1);
} else {
DRAWLINE(dy, dx, sx - 1, sx);
}
}
#undef DRAWLINE
#undef PUTPIXEL
} else {
#define PUTPIXEL() \
{ \
*pp=mix_alpha(*pp,color,alpha); \
}
#define DRAWLINE(dx,dy,inc_1,inc_2) \
n=dx;\
a=2*dy-dx;\
dy=2*dy;\
dx=2*dx-dy;\
do {\
PUTPIXEL();\
if (a>0) { pp+=(inc_1); a-=dx; }\
else { pp+=(inc_2); a+=dy; }\
} while (--n >= 0);
/* fin macro */
if (dx == 0 && dy == 0) {
PUTPIXEL();
} else if (dx > 0) {
if (dx >= dy) {
DRAWLINE(dx, dy, sx + 1, 1);
} else {
DRAWLINE(dy, dx, sx + 1, sx);
}
} else {
dx = -dx;
if (dx >= dy) {
DRAWLINE(dx, dy, sx - 1, -1);
} else {
DRAWLINE(dy, dx, sx - 1, sx);
}
}
#undef DRAWLINE
#undef PUTPIXEL
}
}
--- NEW FILE: text.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _TEXT_H_
#define _TEXT_H_
struct Glyph {
long index;
long xAdvance;
long code; // Ascii code
};
struct TextRecord {
// Normal text record
Glyph *glyphs;
long nbGlyphs;
// Control text record
TextFlags flags;
SwfFont *font;
long fontHeight;
Color color;
long xOffset;
long yOffset;
TextRecord *next;
TextRecord();
~TextRecord();
char *getText();
};
class Text : public Character {
Rect boundary;
Matrix textMatrix;
TextRecord *textRecords; // List
public:
Text(long id);
~Text();
void setTextBoundary(Rect rect);
void setTextMatrix(Matrix m);
void addTextRecord(TextRecord *tr);
int execute(GraphicDevice *gd, Matrix *matrix, Cxform *cxform);
void getRegion(GraphicDevice *gd, Matrix *matrix,
void *id, ScanLineFunc scan_line_func);
int doText(GraphicDevice *gd, Matrix *matrix, Cxform *cxform, ShapeAction action,
void *id, ScanLineFunc scan_line_func);
void getBoundingBox(Rect *bb, DisplayListEntry *e);
TextRecord *getTextRecords();
#ifdef DUMP
void dump(BitStream *bs);
#endif
};
#endif /* _TEXT_H_ */
--- NEW FILE: program.cc ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "swf.h"
#define NOTHING 0x0
#define WAKEUP 0x1
#define GOTO 0x2
#define REFRESH 0x4
#ifdef RCSID
static char *rcsid = "$Id: program.cc,v 1.1 2006-10-03 11:26:10 dslinux_amadeus Exp $";
#endif
#define PRINT 0
int debug = 0;
Program::Program(FlashMovie *movie, long n)
{
long f;
this->movie = movie;
totalFrames = 0;
dl = new DisplayList(movie);
if (dl == NULL) return;
frames = new Frame[n];
if (frames == NULL) {
delete dl;
return;
}
nbFrames = 0;
totalFrames = n;
currentFrame = 0;
loadingFrame = 0;
movieWait = 1;
nextFrame = currentFrame;
for(f = 0; f < n; f++)
{
frames[f].controls = 0;
frames[f].label = NULL;
}
movieStatus = MoviePlay;
settings = 0;
}
Program::~Program()
{
int i;
Control *ctrl, *ctrl1;
delete dl;
if (frames != NULL) {
for(i=0;i<nbFrames;i++) {
ctrl = frames[i].controls;
if (frames[i].label) free(frames[i].label);
while (ctrl != NULL) {
ctrl1 = ctrl->next;
ctrl->next = NULL;
delete ctrl;
ctrl = ctrl1;
}
}
delete[] frames;
}
}
void
Program::validateLoadingFrame()
{
nbFrames = loadingFrame;
loadingFrame++;
movieWait = 0;
}
Frame *
Program::getFrames()
{
return frames;
}
long
Program::getNbFrames()
{
return nbFrames;
}
DisplayList *
Program::getDisplayList()
{
return dl;
}
long
Program::getCurrentFrame()
{
return currentFrame;
}
void
Program::setCurrentFrame(long n)
{
currentFrame = n;
nextFrame = n;
//refresh = 1;
}
void
Program::gotoFrame(GraphicDevice *gd, long frame)
{
long f;
//printf("GotoFrame %d (Current = %d)\n", frame, currentFrame);
dl->clearList();
for(f=0; f <= frame; f++) {
runFrame(gd, 0, f, 0);
}
}
long
Program::runFrame(GraphicDevice *gd, SoundMixer *sm, long f, long action)
{
Control *ctrl;
Character *character;
Matrix *matrix;
Cxform *cxform;
long status = NOTHING;
long update = 0;
char *name;
#if PRINT&1
if (action) printf("Prog %x (dl=%x): Frame N° %d/%d\n", this, this->dl, f, nbFrames-1);
#endif
movie->buttons_updated = 0;
for(ctrl = frames[f].controls; ctrl; ctrl = ctrl->next)
{
switch (ctrl->type)
{
case ctrlPlaceObject:
case ctrlPlaceObject2:
character = 0;
matrix = 0;
cxform = 0;
name = "";
if (ctrl->flags & placeHasCharacter) {
character = ctrl->character;
}
if (ctrl->flags & placeHasMatrix) {
matrix = &ctrl->matrix;
}
if (ctrl->flags & placeHasColorXform) {
cxform = &ctrl->cxform;
}
if (ctrl->flags & placeHasName) {
name = ctrl->name;
}
if (!ctrl->clipDepth) { // Ignore
dl->placeObject(gd,character, ctrl->depth, matrix, cxform, name);
update = 1;
}
break;
case ctrlRemoveObject:
character = ctrl->character;
if (!character) break; // Should not happen
dl->removeObject(gd, character, ctrl->depth);
if (action) {
character->reset();
update = 1;
}
break;
case ctrlRemoveObject2:
character = dl->removeObject(gd,NULL, ctrl->depth);
if (character && action) {
character->reset();
update = 1;
}
break;
// Actions
case ctrlDoAction:
if (action) {
status = doAction(gd, ctrl->actionRecords, sm);
}
break;
case ctrlStartSound:
if (action && sm) {
sm->startSound( (Sound *)ctrl->character );
}
break;
case ctrlStopSound:
if (action && sm) {
sm->stopSounds();
}
break;
case ctrlBackgroundColor:
if (action) {
if (gd->setBackgroundColor(ctrl->color)) {
dl->bbox.xmin = -32768;
dl->bbox.ymin = -32768;
dl->bbox.xmax = 32768;
dl->bbox.ymax = 32768;
}
}
break;
}
}
if (movie->buttons_updated) {
dl->updateButtons(movie);
}
if (status & GOTO) {
if (nextFrame < nbFrames) {
gotoFrame(gd,nextFrame);
if (nextFrame != f)
if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
update = 1;
}
}
#if PRINT&1
if (action) printf("Frame N° %d ready\n", f);
#endif
return update;
}
long
Program::nestedMovie(GraphicDevice *gd, SoundMixer *sm, Matrix *mat, Cxform *cxform)
{
if (movieStatus == MoviePlay) {
// Movie Beeing Played
advanceFrame();
if (currentFrame == 0) {
dl->clearList();
}
runFrame(gd, sm, currentFrame);
if (nbFrames == 1) {
pauseMovie();
}
}
return (movieStatus == MoviePlay);
}
long
Program::processMovie(GraphicDevice *gd, SoundMixer *sm)
{
int wakeUp = 0;
#if PRINT&1
printf("Prog %x (dl=%x): Current = %d Next = %d Wait = %d Status = %d\n", this, this->dl, currentFrame, nextFrame, movieWait, movieStatus);
#endif
if (movieStatus == MoviePlay && movieWait == 0) {
// Movie Beeing Played
advanceFrame();
if (currentFrame == 0) {
dl->clearList();
}
wakeUp |= runFrame(gd, sm, currentFrame);
wakeUp |= dl->updateSprites();
if (nextFrame == nbFrames) {
if (nbFrames != totalFrames) {
movieWait = 1;
} else if ((settings & PLAYER_LOOP) == 0) {
pauseMovie();
}
}
} else {
wakeUp |= dl->updateSprites();
}
if (wakeUp) {
render = 1;
}
return (wakeUp || movieStatus == MoviePlay);
}
/* timer (ms) -1 = delete timer */
void setFlashTimer(struct timeval *tv, int time_ms)
{
if (time_ms == -1) {
tv->tv_sec = -1;
} else {
gettimeofday(tv,0);
tv->tv_usec += time_ms*1000;
while (tv->tv_usec > 1000000) {
tv->tv_usec -= 1000000;
tv->tv_sec++;
}
}
}
int checkFlashTimer(struct timeval *tv)
{
struct timeval now;
if (tv->tv_sec == -1) return 0;
gettimeofday(&now,0);
return (now.tv_sec > tv->tv_sec ||
(now.tv_sec == tv->tv_sec && now.tv_usec >= tv->tv_usec));
}
/* bbox */
typedef struct {
long x1,y1,x2,y2;
} ButtonBoundingBox;
static void button_bbox_func(void *id, long y, long start, long end)
{
ButtonBoundingBox *h = (ButtonBoundingBox *) id;
if (y < h->y1) h->y1 = y;
if (y > h->y2) h->y2 = y;
if (start < h->x1) h->x1 = start;
if (end > h->x2) h->x2 = end;
}
void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e)
{
ButtonBoundingBox bb;
bb.x1 = LONG_MAX;
bb.y1 = LONG_MAX;
bb.x2 = LONG_MIN;
bb.y2 = LONG_MIN;
e->character->getRegion(movie->gd,&e->renderMatrix,&bb,button_bbox_func);
rect->xmin = bb.x1 / FRAC;
rect->xmax = bb.x2 / FRAC;
rect->ymin = bb.y1;
rect->ymax = bb.y2;
}
void transform_coords(long *x_ptr,long *y_ptr, long cx, long cy, long dx, long dy)
{
long x,y,x1,y1;
x = *x_ptr;
y = *y_ptr;
x -= cx;
y -= cy;
if (dx < 0) {
/* left */
x1 = - x;
y1 = y;
} else if (dy < 0) {
/* up */
y1 = x;
x1 = -y;
} else if (dy > 0) {
/* down */
y1 = x;
x1 = y;
} else {
/* right */
x1 = x;
y1 = y;
}
*x_ptr = x1;
*y_ptr = y1;
}
typedef struct {
FlashMovie *movie;
DisplayListEntry *emin,*cur_focus;
long dmin;
long w,cx,cy,dx,dy;
} ButtonFocus;
static int button_focus(void *opaque, Program *prg, DisplayListEntry *e)
{
ButtonFocus *h=(ButtonFocus *)opaque;
Rect rect;
long d,x,y;
if (e != h->cur_focus) {
computeBBox(h->movie,&rect,e);
x = (rect.xmin + rect.xmax) / 2;
y = (rect.ymin + rect.ymax) / 2;
/* transform the coords so that the angular sector is directed to the right */
transform_coords(&x,&y,h->cx,h->cy,h->dx,h->dy);
/* inside it ? */
if ( x >= 0 &&
(y - x - h->w) <= 0 &&
(y + x + h->w) >= 0) {
d = x*x + y*y;
if (d < h->dmin) {
h->dmin = d;
h->emin = e;
}
}
}
return 0;
}
DisplayListEntry *moveFocus(FlashMovie *movie, long dx, long dy,
DisplayListEntry *cur_focus)
{
Rect cur_rect;
ButtonFocus h;
h.movie = movie;
h.dx = dx;
h.dy = dy;
computeBBox(movie,&cur_rect,cur_focus);
/* center */
h.cx = (cur_rect.xmin + cur_rect.xmax) / 2;
h.cy = (cur_rect.ymin + cur_rect.ymax) / 2;
/* width/2 of the 45 degrees angular sector */
if (dy != 0) {
/* for vertical displacement, we have a larger width */
h.w = (cur_rect.xmax - cur_rect.xmin) / 2;
} else {
/* zero width for horizontal displacement */
h.w = 0;
}
/* now we select the nearest button in the angular sector */
h.dmin = LONG_MAX;
h.emin = NULL;
h.cur_focus = cur_focus;
exploreButtons(movie, &h, button_focus);
return h.emin;
}
static int button_newfocus(void *opaque, Program *prg, DisplayListEntry *e)
{
* (DisplayListEntry **)opaque = e;
return 2;
}
static int button_nextfocus(void *opaque, Program *prg, DisplayListEntry *e)
{
static int found = 0;
DisplayListEntry **focus;
focus = (DisplayListEntry **)opaque;
if (found) {
*focus = e;
found = 0;
return 2;
}
if (e == *focus) {
found = 1;
}
return 0;
}
/* XXX: should not be here (one level upper) */
long
Program::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *fe)
{
ActionRecord *action;
Program *prog;
long status = 0;
DisplayListEntry *cur_focus, *new_focus;
long dx,dy;
int refresh;
refresh = 0;
switch(fe->type) {
case FeKeyRelease:
if (movie->mouse_active == 0) {
if (movie->cur_focus) {
movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
movie->cur_focus->renderState = stateOver;
movie->cur_focus->owner->updateBoundingBox(movie->cur_focus);
}
}
break;
case FeKeyPress:
movie->mouse_active = 0;
/* find the button which has the focus */
cur_focus = movie->cur_focus;
if (fe->key == FeKeyEnter) {
/* selection */
if (cur_focus) {
/* select the button */
cur_focus->owner->updateBoundingBox(cur_focus);
cur_focus->renderState = stateDown;
((Button *)cur_focus->character)->updateButtonState(cur_focus);
cur_focus->owner->updateBoundingBox(cur_focus);
movie->scheduledEvent.type = FeKeyRelease;
movie->scheduledEvent.key = FeKeyEnter;
setFlashTimer(&movie->scheduledTime, 250); /* 250 ms down */
}
} else {
/* displacement */
if (cur_focus == NULL) {
/* no current focus : set one */
exploreButtons(movie, &cur_focus, button_newfocus);
if (cur_focus) {
cur_focus->renderState = stateOver;
((Button *)cur_focus->character)->updateButtonState(cur_focus);
cur_focus->owner->updateBoundingBox(cur_focus);
}
movie->cur_focus = cur_focus;
} else {
/* move the focus (test) */
switch(fe->key) {
case FeKeyNext:
/* Next available */
cur_focus->owner->updateBoundingBox(cur_focus);
cur_focus->renderState = stateUp;
((Button *)cur_focus->character)->updateButtonState(cur_focus);
cur_focus->owner->updateBoundingBox(cur_focus);
exploreButtons(movie, &cur_focus, button_nextfocus);
if (cur_focus) {
cur_focus->renderState = stateOver;
((Button *)cur_focus->character)->updateButtonState(cur_focus);
cur_focus->owner->updateBoundingBox(cur_focus);
}
movie->cur_focus = cur_focus;
dx = 0;
dy = 0;
break;
case FeKeyUp:
dx = 0;
dy = -1;
break;
case FeKeyDown:
dx = 0;
dy = 1;
break;
case FeKeyLeft:
dx = -1;
dy = 0;
break;
case FeKeyRight:
dx = 1;
dy = 0;
break;
default:
/* should not happen */
dx = 0;
dy = 0;
break;
}
if (dx != 0 || dy != 0) {
new_focus = moveFocus(movie, dx, dy, cur_focus);
if (new_focus) {
cur_focus->owner->updateBoundingBox(cur_focus);
cur_focus->renderState = stateUp;
((Button *)cur_focus->character)->updateButtonState(cur_focus);
cur_focus->owner->updateBoundingBox(cur_focus);
if (computeActions(movie, &prog, &action)) {
status |= prog->doAction(gd, action, sm);
}
new_focus->renderState = stateOver;
((Button *)new_focus->character)->updateButtonState(new_focus);
movie->cur_focus = new_focus;
new_focus->owner->updateBoundingBox(new_focus);
} else {
return 0;
}
}
}
if (movie->cur_focus == NULL) return 0;
}
break;
case FeMouseMove:
movie->mouse_active = 1;
movie->mouse_x = fe->x * FRAC;
movie->mouse_y = fe->y * FRAC;
dl->updateButtons(movie);
break;
case FeButtonPress:
movie->mouse_active = 1;
movie->button_pressed = 1;
dl->updateButtons(movie);
break;
case FeButtonRelease:
movie->mouse_active = 1;
movie->button_pressed = 0;
dl->updateButtons(movie);
break;
default:
return 0;
}
if (computeActions(movie, &prog, &action)) {
status |= prog->doAction(gd, action, sm);
}
if (status & REFRESH) {
status |= WAKEUP;
refresh = 1;
}
if (status & GOTO) {
if (nextFrame < nbFrames) {
gotoFrame(gd, nextFrame);
if (movieStatus == MoviePaused) runFrame(gd,sm,nextFrame);
refresh = 1;
}
}
if (refresh) {
dl->updateSprites();
render = 1;
}
return (refresh || movieStatus == MoviePlay);
}
long
Program::doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *sm)
{
long status = NOTHING;
long f;
char *target = "";
long skip = 0;
while(action)
{
if (skip) skip--;
else
switch (action->action)
{
case ActionPlaySound:
#if PRINT&2
printf("Prog %x : PlaySound\n", this);
#endif
if (sm) {
sm->startSound(action->sound);
}
status |= WAKEUP;
break;
case ActionRefresh:
#if PRINT&2
printf("Prog %x : Refresh\n", this);
#endif
status |= REFRESH;
break;
case ActionGotoFrame:
#if PRINT&2
printf("Prog %x : GotoFrame %d\n", this, action->frameIndex);
#endif
if (target[0] == 0) {
if (action->frameIndex < nbFrames) {
currentFrame = action->frameIndex;
pauseMovie();
status |= WAKEUP|GOTO;
}
}
break;
case ActionGetURL:
#if PRINT&2
printf("Prog %x : GetURL %s target = %s\n", this, action->url, action->target);
#endif
{
int len,level;
len = strlen(action->target);
if (len > 6 && memcmp(action->target,"_level", 6) == 0) {
level = atoi(action->target + 6);
loadNewSwf(movie, action->url, level);
} else {
if (movie->getUrl) {
movie->getUrl(action->url, action->target, movie->getUrlClientData);
}
}
}
break;
case ActionNextFrame:
nextFrame = currentFrame+1;
movieStatus = MoviePlay;
status |= WAKEUP;
break;
case ActionPrevFrame:
nextFrame = currentFrame-1;
status |= WAKEUP|GOTO;
break;
case ActionPlay:
#if PRINT&2
printf("Prog %x : Play\n", this);
#endif
if (target[0] == 0) {
movieStatus = MoviePlay;
if ((status & GOTO) == 0) {
if (currentFrame == nextFrame) advanceFrame();
}
status |= WAKEUP;
}
break;
case ActionStop:
#if PRINT&2
printf("Prog %x : Stop\n", this);
#endif
if (target[0] == 0) {
movieStatus = MoviePaused;
nextFrame = currentFrame;
}
break;
case ActionToggleQuality:
break;
case ActionStopSounds:
if (sm) {
sm->stopSounds();
}
break;
case ActionWaitForFrame:
if (action->frameIndex >= nbFrames) {
skip = action->skipCount;
}
break;
case ActionSetTarget:
#if PRINT&2
printf("Prog %x : SetTarget '%s'\n", this, action->target);
#endif
target = action->target;
break;
case ActionGoToLabel:
#if PRINT&2
printf("Prog %x : GotoFrame '%s'\n", this, action->frameLabel);
#endif
f = searchFrame(gd, action->frameLabel, target);
if (f >= 0) {
currentFrame = f;
pauseMovie();
status |= WAKEUP|GOTO;
} else {
status |= REFRESH;
}
break;
}
action = action->next;
}
return status;
}
void
Program::setCurrentFrameLabel(char *label)
{
frames[loadingFrame].label = label;
}
void
Program::rewindMovie()
{
currentFrame = 0;
nextFrame = 0;
}
void
Program::pauseMovie()
{
movieStatus = MoviePaused;
nextFrame = currentFrame;
}
void
Program::continueMovie()
{
movieStatus = MoviePlay;
}
void
Program::nextStepMovie()
{
if (movieStatus == MoviePaused) {
advanceFrame();
}
}
void
Program::advanceFrame()
{
currentFrame = nextFrame;
nextFrame = currentFrame+1;
if (currentFrame == nbFrames) {
currentFrame = 0;
nextFrame = 0;
movieStatus = MoviePlay;
}
}
void
Program::addControlInCurrentFrame(Control *ctrl)
{
Control *c;
ctrl->next = 0;
if (frames[loadingFrame].controls == 0) {
frames[loadingFrame].controls = ctrl;
} else {
for(c = frames[loadingFrame].controls; c->next; c = c->next);
c->next = ctrl;
}
}
void
Program::modifySettings(long flags)
{
settings = flags;
}
long
Program::searchFrame(GraphicDevice *gd, char *label, char *target)
{
long f;
DisplayListEntry *e;
Program *prg;
// Current movie
if (target[0] == 0) {
for(f=0; f < nbFrames; f++)
{
if (frames[f].label && !strcmp(label,frames[f].label)) {
return f;
}
}
}
// Kludge !!!
for (e = dl->list; e; e = e->next) {
if (e->character->isSprite()) {
prg = ((Sprite *)e->character)->program;
f = prg->searchFrame(gd,label,"");
if (f >= 0 && f < prg->nbFrames) {
prg->dl->updateBoundingBox(e);
prg->gotoFrame(gd, f);
prg->nextFrame = f;
prg->dl->updateBoundingBox(e);
return -1;
}
}
}
return -1;
}
void loadNewSwf(FlashMovie *movie, char *url, int level)
{
CInputScript *s,*prev,**l;
if (movie->getSwf == NULL) return;
for(s = movie->main, prev = 0; s != NULL; prev = s, s = s->next) {
if (s->level == level) {
// Mark movie to be deleted
s->level = -1;
break;
}
}
//printf("Unload movie @ %d\n", level);
if (*url == 0) return; // Just UnloadMovie
s = new CInputScript(level);
if (s == NULL) return;
/* insert it in the right order */
l = &movie->main;
while (*l != NULL && (*l)->level < level) l = &(*l)->next;
s->next = *l;
*l = s;
// Notify the external loader of a new movie to load
movie->getSwf(url, level, movie->getSwfClientData);
}
--- NEW FILE: program.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _PROGRAM_H_
#define _PROGRAM_H_
enum ControlType {
ctrlPlaceObject,
ctrlPlaceObject2,
ctrlRemoveObject,
ctrlRemoveObject2,
ctrlDoAction,
ctrlStartSound,
ctrlStopSound,
ctrlBackgroundColor
};
enum PlaceFlags {
placeIsMove = 0x01,
placeHasCharacter = 0x02,
placeHasMatrix = 0x04,
placeHasColorXform = 0x08,
placeHasRatio = 0x10,
placeHasName = 0x20,
placeHasClip = 0x40
};
struct Control {
ControlType type;
// Place, Remove, Sound
Character *character;
long depth;
// Place 1&2
PlaceFlags flags;
Matrix matrix;
Cxform cxform;
long ratio;
long clipDepth;
char *name;
// BackgroundColor
Color color;
// DoAction
ActionRecord *actionRecords;
struct Control *next;
// Methods
void addActionRecord( ActionRecord *ar)
{
ar->next = 0;
if (actionRecords == 0) {
actionRecords = ar;
} else {
ActionRecord *current;
for(current = actionRecords; current->next; current = current->next);
current->next = ar;
}
};
Control()
{
actionRecords = 0;
cxform.aa = 1.0; cxform.ab = 0;
cxform.ra = 1.0; cxform.rb = 0;
cxform.ga = 1.0; cxform.gb = 0;
cxform.ba = 1.0; cxform.bb = 0;
ratio = 0;
clipDepth = 0;
name = 0;
};
~Control()
{
ActionRecord *ar,*del;
for(ar = actionRecords; ar;)
{
del = ar;
ar = ar->next;
delete del;
}
if (name) {
free(name);
}
};
};
struct Frame {
char *label;
Control *controls; // Controls for this frame
};
enum MovieStatus {
MoviePaused,
MoviePlay
};
struct FlashMovie;
struct Program {
DisplayList *dl;
Frame *frames; // Array
long nbFrames; // Number of valid frames
long currentFrame;
long loadingFrame;
long totalFrames; // Total expected number of frames
long nextFrame;
int movieWait; // If true freeze movie until next loaded frame
MovieStatus movieStatus;
Sound *currentSound;
long settings;
FlashMovie *movie;
long render; // True if needed to be rendered
Program(FlashMovie *movie,long n);
~Program();
void rewindMovie();
void pauseMovie();
void continueMovie();
void nextStepMovie();
void gotoFrame(GraphicDevice *gd, long f);
long processMovie(GraphicDevice *, SoundMixer *);
long nestedMovie(GraphicDevice *, SoundMixer *, Matrix *, Cxform *);
long runFrame(GraphicDevice *, SoundMixer *, long f, long action=1);
long handleEvent(GraphicDevice *, SoundMixer *, FlashEvent *);
long doAction(GraphicDevice *gd, ActionRecord *action, SoundMixer *);
void setCurrentFrameLabel(char *label);
void advanceFrame();
void addControlInCurrentFrame(Control *ctrl);
void setGetUrlMethod( void (*)(char *, char *, void *), void *);
void modifySettings(long flags);
long searchFrame(GraphicDevice *gd, char *, char *);
void validateLoadingFrame();
long getCurrentFrame();
void setCurrentFrame(long);
Frame *getFrames();
long getNbFrames();
DisplayList *getDisplayList();
#ifdef DUMP
void dump(BitStream *bs);
static void dumpActions(BitStream *bs, ActionRecord *actions);
#endif
};
DisplayListEntry *findFocus(DisplayList *dl);
void setFlashTimer(struct timeval *tv, int time_ms);
int checkFlashTimer(struct timeval *tv);
void loadNewSwf(FlashMovie *movie, char *url, int level);
void computeBBox(FlashMovie *movie, Rect *rect, DisplayListEntry *e);
long processMovie(FlashMovie *movie);
#endif /* _PROGRAM_H_ */
--- NEW FILE: movie.cc ---
////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998,1999 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
// Author : Olivier Debon <odebon at club-internet.fr>
//
#include "movie.h"
FlashMovie::FlashMovie()
{
gd = NULL;
sm = NULL;
getSwf = NULL;
getUrl = NULL;
cursorOnOff = NULL;
buttons_updated = 0;
scheduledTime.tv_sec = -1;
cur_focus = NULL;
lost_over = NULL;
msPerFrame = 0;
/* mouse handling */
mouse_active = 0;
mouse_x = -1;
mouse_y = -1;
button_pressed = 0;
refresh = 1;
}
FlashMovie::~FlashMovie()
{
CInputScript *n;
while (main != NULL) {
n = main->next;
delete main;
main = n;
}
if (gd) delete gd;
if (sm) delete sm;
}
int
FlashMovie::processMovie(GraphicDevice *gd, SoundMixer *sm)
{
CInputScript *script;
int wakeUp = 0;
if (sm && sm->playSounds()) {
wakeUp = 1;
}
for (script = this->main; script != NULL; script = script->next) {
if (script->program == NULL) continue;
if (script->program->nbFrames == 0) continue;
if (script->program->processMovie(gd,sm)) {
wakeUp = 1;
}
}
renderMovie();
return wakeUp;
}
int
FlashMovie::handleEvent(GraphicDevice *gd, SoundMixer *sm, FlashEvent *event)
{
int wakeUp = 0;
if (sm && sm->playSounds()) {
wakeUp = 1;
}
if (this->main == 0) return 0;
if (this->main->program == 0) return 0;
if (this->main->program->handleEvent(gd, sm, event)) {
wakeUp = 1;
}
renderMovie();
return wakeUp;
}
/* current focus bigger and translated if needed */
void
FlashMovie::renderFocus()
{
Rect rect,boundary;
Matrix mat;
if (mouse_active || !cur_focus) return;
/* rect is the bbox in screen coordinates */
// Compute the bounding box in screen coordinates
cur_focus->character->getBoundingBox(&boundary,cur_focus);
mat = (*gd->adjust) * cur_focus->renderMatrix;
transformBoundingBox(&rect, &mat, &boundary, 1);
gd->drawBox(rect.xmin, rect.ymin, rect.xmax, rect.ymax);
}
void
FlashMovie::renderMovie()
{
CInputScript *script,*prev,*next;
Rect clipping;
Matrix identity;
clipping.reset();
// First pass to update the clipping region
for (script = this->main; script != NULL; script = script->next) {
if (script->level == -1) {
clipping.xmin = -32768;
clipping.ymin = -32768;
clipping.xmax = 32767;
clipping.ymax = 32767;
continue;
}
if (script->program == NULL) continue;
if (script->program->dl->bbox.xmin == LONG_MAX) continue;
transformBoundingBox(&clipping, &identity, &script->program->dl->bbox, 0);
script->program->render = 0;
}
if (clipping.xmin == LONG_MAX) return;
// Update the clipping region
gd->updateClippingRegion(&clipping);
gd->clearCanvas();
// Second pass to render the movie
for (script = this->main; script != NULL; script = script->next) {
if (script->level == -1) continue;
if (script->program == NULL) continue;
script->program->dl->render(gd);
}
renderFocus();
// Final pass to delete some movies
script = this->main;
prev = 0;
while (script != NULL) {
if (script->level == -1) {
next = script->next;
if (prev == 0) {
this->main = next;
} else {
prev->next = next;
}
delete script;
script = next;
} else {
prev = script;
script = script->next;
}
}
}
--- NEW FILE: bitmap.h ---
/////////////////////////////////////////////////////////////
// Flash Plugin and Player
// Copyright (C) 1998 Olivier Debon
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
///////////////////////////////////////////////////////////////
#ifndef _BITMAP_H_
#define _BITMAP_H_
struct MyErrorHandler {
struct jpeg_error_mgr pub;
jmp_buf setjmp_buffer;
};
class Bitmap : public Character {
public:
long width;
long height;
long bpl;
long depth;
unsigned char *pixels; // Array of Pixels
Color *colormap; // Array of color definitions
long nbColors;
unsigned char *alpha_buf; // Array of alpha values (no alpha if NULL)
int defLevel;
// Class Variables
static int haveTables;
static struct jpeg_decompress_struct jpegObject;
static struct jpeg_source_mgr jpegSourceManager;
static MyErrorHandler jpegErrorMgr;
public:
Bitmap(long id, int level = 1);
~Bitmap();
// JPEG handling methods
int buildFromJpegInterchangeData(unsigned char *stream, int alpha, long offset); // Complete
int buildFromJpegAbbreviatedData(unsigned char *stream); // Abbreviated
// Class Method
static int readJpegTables(unsigned char *stream); // Tables Only
// ZLIB handling methods
int buildFromZlibData(unsigned char *buffer,
int width, int height,
int format, int tableSize, int tableHasAlpha);
long getWidth();
long getHeight();
Color *getColormap(long *n);
unsigned char *getPixels();
};
#endif /* _BITMAP_H_ */
More information about the dslinux-commit
mailing list