From 2da3d5886c441063c6123eb2c10b181b398c57ac Mon Sep 17 00:00:00 2001 From: luminescent Date: Fri, 6 Sep 2002 16:31:27 +0000 Subject: [PATCH] First steps in modularization... git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@16 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/sc2code/libs/graphics/gfx_common.c | 52 + sc2/src/sc2code/libs/graphics/gfx_common.h | 228 +++++ sc2/src/sc2code/libs/graphics/sdl/Makefile.am | 22 + sc2/src/sc2code/libs/graphics/sdl/rotozoom.c | 938 ++++++++++++++++++ sc2/src/sc2code/libs/graphics/sdl/rotozoom.h | 84 ++ .../sc2code/libs/graphics/sdl/sdl_common.c | 547 ++++++++++ .../sc2code/libs/graphics/sdl/sdl_common.h | 50 + sc2/src/sc2code/libs/input/input_common.c | 184 ++++ sc2/src/sc2code/libs/input/sdl/Makefile.am | 14 + sc2/src/sc2code/libs/input/sdl/input.c | 759 ++++++++++++++ sc2/src/sc2code/libs/input/sdl/input.h | 49 + sc2/src/sc2code/libs/misc.h | 47 + sc2/src/sc2code/libs/sound/sdl/Makefile.am | 13 + sc2/src/sc2code/libs/sound/sdl/modfuncs.c | 206 ++++ sc2/src/sc2code/libs/sound/sdl/play.c | 95 ++ sc2/src/sc2code/libs/sound/sdl/sound.c | 187 ++++ sc2/src/sc2code/libs/sound/sdl/trackplayer.c | 199 ++++ sc2/src/sc2code/libs/sound/sound_common.c | 79 ++ sc2/src/sc2code/libs/sound/trackplayer.h | 33 + 19 files changed, 3786 insertions(+) create mode 100644 sc2/src/sc2code/libs/graphics/gfx_common.c create mode 100644 sc2/src/sc2code/libs/graphics/gfx_common.h create mode 100644 sc2/src/sc2code/libs/graphics/sdl/Makefile.am create mode 100644 sc2/src/sc2code/libs/graphics/sdl/rotozoom.c create mode 100644 sc2/src/sc2code/libs/graphics/sdl/rotozoom.h create mode 100644 sc2/src/sc2code/libs/graphics/sdl/sdl_common.c create mode 100644 sc2/src/sc2code/libs/graphics/sdl/sdl_common.h create mode 100644 sc2/src/sc2code/libs/input/input_common.c create mode 100644 sc2/src/sc2code/libs/input/sdl/Makefile.am create mode 100644 sc2/src/sc2code/libs/input/sdl/input.c create mode 100644 sc2/src/sc2code/libs/input/sdl/input.h create mode 100644 sc2/src/sc2code/libs/misc.h create mode 100644 sc2/src/sc2code/libs/sound/sdl/Makefile.am create mode 100644 sc2/src/sc2code/libs/sound/sdl/modfuncs.c create mode 100644 sc2/src/sc2code/libs/sound/sdl/play.c create mode 100644 sc2/src/sc2code/libs/sound/sdl/sound.c create mode 100644 sc2/src/sc2code/libs/sound/sdl/trackplayer.c create mode 100644 sc2/src/sc2code/libs/sound/sound_common.c create mode 100644 sc2/src/sc2code/libs/sound/trackplayer.h diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.c b/sc2/src/sc2code/libs/graphics/gfx_common.c new file mode 100644 index 000000000..62eb492f9 --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/gfx_common.c @@ -0,0 +1,52 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + +/****************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*******************************************/ + + +#include "libs/graphics/gfxintrn.h" +#include "libs/input/inpintrn.h" +#include "libs/graphics/gfx_common.h" + + +#define NUMBER_OF_PLUTVALS 32 +#define NUMBER_OF_PLUT_UINT32s (NUMBER_OF_PLUTVALS >> 1) +#define GET_VAR_PLUT(i) (_varPLUTs + (i) * NUMBER_OF_PLUT_UINT32s) +DWORD* _varPLUTs; //Not a function +PDISPLAY_INTERFACE _pCurDisplay; //Not a function. Probably has to be initialized... + +void (*mask_func_array[]) + (PRECT pClipRect, PRIMITIVEPTR PrimPtr) + = { 0 }; + +int ScreenWidth; +int ScreenHeight; +int ScreenWidthActual; +int ScreenHeightActual; +int ScreenBPPActual; + +int TFB_DEBUG_HALT; + diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.h b/sc2/src/sc2code/libs/graphics/gfx_common.h new file mode 100644 index 000000000..a829bf5f2 --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/gfx_common.h @@ -0,0 +1,228 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + + +/**************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*****************************************/ + + +#ifndef GFX_COMMON_H +#define GFX_COMMON_H + +#include +#include +#include + +#include "starcon.h" +#include "libs/gfxlib.h" +#include "libs/vidlib.h" +#include "libs/misc.h" + + +int Main(int argc, char *argv[]); +int Starcon2Main (void *); + +// Graphics Stuff + +void LoadIntoExtraScreen (PRECT r); +void DrawFromExtraScreen (PRECT r); +void SetGraphicStrength (int numer, int denom); +void SetGraphicGrabOther (int grab_other); +void SetGraphicScale (int scale); +void SetGraphicUseOtherExtra (int other); +void *GetScreenBitmap (); +void ScreenTransition (int transition, PRECT pRect); +void ScreenOrigin (FRAME Display, COORD sx, COORD sy); + +extern float FrameRate; +extern int FrameRateTickBase; + +// Image + Drawing Stuff + +#define TFB_IMAGESTRUCT_SIZE 32 + +// TFB_Image (which is module-specific) will be casted to this and vice versa +typedef struct tfb_imagestruct +{ + UBYTE data[TFB_IMAGESTRUCT_SIZE]; +} TFB_ImageStruct; + +enum +{ + TFB_DRAWCOMMANDTYPE_LINE, + TFB_DRAWCOMMANDTYPE_RECTANGLE, + TFB_DRAWCOMMANDTYPE_IMAGE, + TFB_DRAWCOMMANDTYPE_COPYFROMOTHERBUFFER, + + TFB_DRAWCOMMANDTYPE_SCISSORENABLE, + TFB_DRAWCOMMANDTYPE_SCISSORDISABLE, + TFB_DRAWCOMMANDTYPE_COPYBACKBUFFERTOOTHERBUFFER, + TFB_DRAWCOMMANDTYPE_DELETEIMAGE, +}; + +typedef struct tfb_drawcommand +{ + int Type; + int x; + int y; + int w; + int h; + TFB_ImageStruct *image; // only used for image draw type + int r; // RGB only used for rect draw types + int g; + int b; + int Qualifier; +} TFB_DrawCommand; + +// Queue Stuff + +typedef struct tfb_drawcommandqueue +{ + int Front; + int Back; + int Size; +} TFB_DrawCommandQueue; + +TFB_DrawCommandQueue *TFB_DrawCommandQueue_Create (); + +void TFB_DrawCommandQueue_Push (TFB_DrawCommandQueue* myQueue, + TFB_DrawCommand* Command); + +int TFB_DrawCommandQueue_Pop (TFB_DrawCommandQueue* myQueue, + TFB_DrawCommand* Command); + +void TFB_DeallocateDrawCommand (TFB_DrawCommand* Command); + +extern TFB_DrawCommandQueue *DrawCommandQueue; + +// The TFB_Enqueue* functions are necessary, because only the +// main thread can draw to the window. + +void TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand); +void TFB_FlushGraphics (); // Only call from main thread!! + +// CCB Stuff + +typedef struct +{ + int ccb_Flags; + int ccb_HDX; + int ccb_HDY; + int ccb_HDDX; + int ccb_HDDY; + int ccb_VDX; + int ccb_VDY; + int ccb_PIXC; + void* ccb_SourcePtr; + unsigned int* ccb_PLUTPtr; + int ccb_Width; + int ccb_Height; + int ccb_PRE0; + int ccb_PRE1; + void* ccb_NextPtr; + int ccb_XPos; + int ccb_YPos; +} CCB; + +// Geez, I hope these #defines work out... + +#define CCB_SPABS (1 << 0) +#define CCB_PPABS (1 << 1) +#define CCB_YOXY (1 << 2) +#define CCB_ACW (1 << 3) +#define CCB_ACCW (1 << 4) +#define CCB_LDSIZE (1 << 5) +#define CCB_CCBPRE (1 << 6) +#define CCB_LDPRS (1 << 7) +#define CCB_LDPPMP (1 << 8) +#define CCB_ACE (1 << 9) +#define CCB_LCE (1 << 10) +#define CCB_PLUTPOS (1 << 11) +#define CCB_BGND (1 << 12) +#define CCB_NPABS (1 << 13) +#define CCB_PACKED (1 << 14) +#define CCB_LDPLUT (1 << 15) +#define CCB_LAST (1 << 16) +#define CCB_USEAV (1 << 17) + +#define PPMP_0_SHIFT 0 // ? +#define PPMP_1_SHIFT 1 // ? + +#define PPMPC_MS_PIN (1 << 0) +#define PPMPC_MS_CCB (1 << 1) +#define PPMPC_SF_8 (1 << 2) +#define PPMPC_MF_8 (1 << 3) +#define PPMPC_MF_SHIFT 3 +#define PPMPC_1S_PDC (1 << 4) +#define PPMPC_2S_CFBD (1 << 5) +#define PPMPC_2D_1 (1 << 6) +#define PPMPC_MF_6 (1 << 7) +#define PPMPC_2S_0 (1 << 8) +#define PPMPC_1S_CFBD (1 << 9) +#define PPMPC_MF_2 (1 << 10) +#define PPMPC_SF_2 (1 << 11) +#define PPMPC_2S_PDC (1 << 12) +#define PPMPC_MF_1 (1 << 13) +#define PPMPC_SF_16 (1 << 14) + +#define PRE0_LITERAL (1 << 0) +#define PRE0_VCNT_PREFETCH (1 << 1) +#define PRE0_VCNT_SHIFT 1 +#define PRE0_VCNT_MASK (1 << 1) +#define PRE0_BPP_8 (1 << 2) +#define PRE0_BPP_SHIFT 2 +#define PRE0_BPP_16 (1 << 3) +#define PRE0_BGND (1 << 4) +#define PRE0_LINEAR (1 << 5) +#define PRE0_SKIPX_MASK 0 +#define PRE0_SKIPX_SHIFT 0 +#define PRE0_BPP_1 (1 << 6) +#define PRE1_TLLSB_PDC0 (1 << 7) +#define PRE1_TLHPCNT_PREFETCH (1 << 7) +#define PRE1_TLHPCNT_SHIFT 7 +#define PRE1_TLHPCNT_MASK (1 << 7) +#define PRE1_WOFFSET_PREFETCH (1 << 8) +#define PRE1_WOFFSET10_SHIFT (1 << 9) +#define PRE1_WOFFSET8_SHIFT (1 << 10) + +// Cel Stuff + +void add_cel(CCB* cel); +void add_cels(CCB* first, CCB* last); +void myMapCel(CCB* myCCB, POINT Points[4]); +int _ThreeDO_batch_cels(int unknown); +CCB *ParseCel(CCB*,unsigned int); + +#define CelData void + +// Unknown Stuff + +extern int ScreenWidth; +extern int ScreenHeight; +extern int ScreenWidthActual; +extern int ScreenHeightActual; +extern int ScreenBPPActual; + +#endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/Makefile.am b/sc2/src/sc2code/libs/graphics/sdl/Makefile.am new file mode 100644 index 000000000..e5d80b875 --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/sdl/Makefile.am @@ -0,0 +1,22 @@ + +# Automake template file. +# Written by Mudry , protected by GNU GPL. +# CVS $ Id: $ + +SUBDIRS = opengl pure + +CFLAGS = -Wall + +INCLUDES = @SDL_CFLAGS@ @SMPEG_CFLAGS@ \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/sc2code \ + -I$(top_srcdir)/src/sc2code/libs + +noinst_LTLIBRARIES = libsdl.la + +libsdl_la_SOURCES = sdl_common.c rotozoom.c + +libsdl_la_LIBADD = opengl/libopengl.la pure/libpure.la + +noinst_HEADERS = sdl_common.h rotozoom.h + diff --git a/sc2/src/sc2code/libs/graphics/sdl/rotozoom.c b/sc2/src/sc2code/libs/graphics/sdl/rotozoom.c new file mode 100644 index 000000000..e3405dfa6 --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/sdl/rotozoom.c @@ -0,0 +1,938 @@ +/* + + rotozoom.c - rotozoomer for 32bit or 8bit surfaces + LGPL (c) A. Schiffler + + Note by sc2 developers: + Taken from SDL_gfx library and modified, original code can be downloaded + from http://www.ferzkopp.net/Software/SDL_gfx-2.0/ + +*/ + +#include +#include + +#include "rotozoom.h" + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) + +/* + + 32bit Zoomer with optional anti-aliasing by bilinear interpolation. + + Zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. + +*/ + +int zoomSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int smooth) +{ + int x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy, ex, ey, t1, t2, sstep; + tColorRGBA *c00, *c01, *c10, *c11; + tColorRGBA *sp, *csp, *dp; + int sgap, dgap; + + /* + * Variable setup + */ + if (smooth) { + /* + * For interpolation: assume source dimension is one pixel + */ + /* + * smaller to avoid overflow on right and bottom edge. + */ + sx = (int) (65536.0 * (float) (src->w - 1) / (float) dst->w); + sy = (int) (65536.0 * (float) (src->h - 1) / (float) dst->h); + } else { + sx = (int) (65536.0 * (float) src->w / (float) dst->w); + sy = (int) (65536.0 * (float) src->h / (float) dst->h); + } + + /* + * Allocate memory for row increments + */ + if ((sax = (int *) malloc((dst->w + 1) * sizeof(Uint32))) == NULL) { + return (-1); + } + if ((say = (int *) malloc((dst->h + 1) * sizeof(Uint32))) == NULL) { + free(sax); + return (-1); + } + + /* + * Precalculate row increments + */ + csx = 0; + csax = sax; + for (x = 0; x <= dst->w; x++) { + *csax = csx; + csax++; + csx &= 0xffff; + csx += sx; + } + csy = 0; + csay = say; + for (y = 0; y <= dst->h; y++) { + *csay = csy; + csay++; + csy &= 0xffff; + csy += sy; + } + + /* + * Pointer setup + */ + sp = csp = (tColorRGBA *) src->pixels; + dp = (tColorRGBA *) dst->pixels; + sgap = src->pitch - src->w * 4; + dgap = dst->pitch - dst->w * 4; + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) { + + /* + * Interpolating Zoom + */ + + /* + * Scan destination + */ + csay = say; + for (y = 0; y < dst->h; y++) { + /* + * Setup color source pointers + */ + c00 = csp; + c01 = csp; + c01++; + c10 = (tColorRGBA *) ((Uint8 *) csp + src->pitch); + c11 = c10; + c11++; + csax = sax; + for (x = 0; x < dst->w; x++) { + + /* + * Interpolate colors + */ + ex = (*csax & 0xffff); + ey = (*csay & 0xffff); + t1 = ((((c01->r - c00->r) * ex) >> 16) + c00->r) & 0xff; + t2 = ((((c11->r - c10->r) * ex) >> 16) + c10->r) & 0xff; + dp->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->g - c00->g) * ex) >> 16) + c00->g) & 0xff; + t2 = ((((c11->g - c10->g) * ex) >> 16) + c10->g) & 0xff; + dp->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->b - c00->b) * ex) >> 16) + c00->b) & 0xff; + t2 = ((((c11->b - c10->b) * ex) >> 16) + c10->b) & 0xff; + dp->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01->a - c00->a) * ex) >> 16) + c00->a) & 0xff; + t2 = ((((c11->a - c10->a) * ex) >> 16) + c10->a) & 0xff; + dp->a = (((t2 - t1) * ey) >> 16) + t1; + + /* + * Advance source pointers + */ + csax++; + sstep = (*csax >> 16); + c00 += sstep; + c01 += sstep; + c10 += sstep; + c11 += sstep; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer + */ + csay++; + csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch); + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + + } else { + + /* + * Non-Interpolating Zoom + */ + + csay = say; + for (y = 0; y < dst->h; y++) { + sp = csp; + csax = sax; + for (x = 0; x < dst->w; x++) { + /* + * Draw + */ + *dp = *sp; + /* + * Advance source pointers + */ + csax++; + sp += (*csax >> 16); + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer + */ + csay++; + csp = (tColorRGBA *) ((Uint8 *) csp + (*csay >> 16) * src->pitch); + /* + * Advance destination pointers + */ + dp = (tColorRGBA *) ((Uint8 *) dp + dgap); + } + + } + + /* + * Remove temp arrays + */ + free(sax); + free(say); + + return (0); +} + +/* + + 8bit Zoomer without smoothing. + + Zoomes 8bit palette/Y 'src' surface to 'dst' surface. + +*/ + +int zoomSurfaceY(SDL_Surface * src, SDL_Surface * dst) +{ + Uint32 x, y, sx, sy, *sax, *say, *csax, *csay, csx, csy; + Uint8 *sp, *dp, *csp; + int dgap; + + /* + * Variable setup + */ + sx = (Uint32) (65536.0 * (float) src->w / (float) dst->w); + sy = (Uint32) (65536.0 * (float) src->h / (float) dst->h); + + /* + * Allocate memory for row increments + */ + if ((sax = (Uint32 *) malloc(dst->w * sizeof(Uint32))) == NULL) { + return (-1); + } + if ((say = (Uint32 *) malloc(dst->h * sizeof(Uint32))) == NULL) { + if (sax != NULL) { + free(sax); + } + return (-1); + } + + /* + * Precalculate row increments + */ + csx = 0; + csax = sax; + for (x = 0; x < dst->w; x++) { + csx += sx; + *csax = (csx >> 16); + csx &= 0xffff; + csax++; + } + csy = 0; + csay = say; + for (y = 0; y < dst->h; y++) { + csy += sy; + *csay = (csy >> 16); + csy &= 0xffff; + csay++; + } + + csx = 0; + csax = sax; + for (x = 0; x < dst->w; x++) { + csx += (*csax); + csax++; + } + csy = 0; + csay = say; + for (y = 0; y < dst->h; y++) { + csy += (*csay); + csay++; + } + + /* + * Pointer setup + */ + sp = csp = (Uint8 *) src->pixels; + dp = (Uint8 *) dst->pixels; + dgap = dst->pitch - dst->w; + + /* + * Draw + */ + csay = say; + for (y = 0; y < dst->h; y++) { + csax = sax; + sp = csp; + for (x = 0; x < dst->w; x++) { + /* + * Draw + */ + *dp = *sp; + /* + * Advance source pointers + */ + sp += (*csax); + csax++; + /* + * Advance destination pointer + */ + dp++; + } + /* + * Advance source pointer (for row) + */ + csp += ((*csay) * src->pitch); + csay++; + /* + * Advance destination pointers + */ + dp += dgap; + } + + /* + * Remove temp arrays + */ + free(sax); + free(say); + + return (0); +} + +/* + + 32bit Rotozoomer with optional anti-aliasing by bilinear interpolation. + + Rotates and zoomes 32bit RGBA/ABGR 'src' surface to 'dst' surface. + +*/ + +void transformSurfaceRGBA(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos, int smooth) +{ + int x, y, t1, t2, dx, dy, xd, yd, sdx, sdy, ax, ay, ex, ey, sw, sh; + tColorRGBA c00, c01, c10, c11; + tColorRGBA *pc, *sp, *spb; + int gap; + + /* + * Variable setup + */ + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; + pc = dst->pixels; + gap = dst->pitch - dst->w * 4; + + /* + * Switch between interpolating and non-interpolating code + */ + if (smooth) { + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (sdx >> 16); + dy = (sdy >> 16); + if ((dx >= -1) && (dy >= -1) && (dx < src->w) && (dy < src->h)) { + if ((dx >= 0) && (dy >= 0) && (dx < sw) && (dy < sh)) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + sp += 1; + c01 = *sp; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + sp -= 1; + c10 = *sp; + sp += 1; + c11 = *sp; + } else if ((dx == sw) && (dy == sh)) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if ((dx == -1) && (dy == -1)) { + sp = (tColorRGBA *) (src->pixels); + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if ((dx == -1) && (dy == sh)) { + sp = (tColorRGBA *) (src->pixels); + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if ((dx == sw) && (dy == -1)) { + sp = (tColorRGBA *) (src->pixels); + sp += dx; + c00 = *sp; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } else if (dx == -1) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + c00 = *sp; + c01 = *sp; + c10 = *sp; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + c11 = *sp; + } else if (dy == -1) { + sp = (tColorRGBA *) (src->pixels); + sp += dx; + c00 = *sp; + c01 = *sp; + c10 = *sp; + sp += 1; + c11 = *sp; + } else if (dx == sw) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + c01 = *sp; + sp = (tColorRGBA *) ((Uint8 *) sp + src->pitch); + c10 = *sp; + c11 = *sp; + } else if (dy == sh) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + c00 = *sp; + sp += 1; + c01 = *sp; + c10 = *sp; + c11 = *sp; + } + /* + * Interpolate colors + */ + ex = (sdx & 0xffff); + ey = (sdy & 0xffff); + t1 = ((((c01.r - c00.r) * ex) >> 16) + c00.r) & 0xff; + t2 = ((((c11.r - c10.r) * ex) >> 16) + c10.r) & 0xff; + pc->r = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.g - c00.g) * ex) >> 16) + c00.g) & 0xff; + t2 = ((((c11.g - c10.g) * ex) >> 16) + c10.g) & 0xff; + pc->g = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.b - c00.b) * ex) >> 16) + c00.b) & 0xff; + t2 = ((((c11.b - c10.b) * ex) >> 16) + c10.b) & 0xff; + pc->b = (((t2 - t1) * ey) >> 16) + t1; + t1 = ((((c01.a - c00.a) * ex) >> 16) + c00.a) & 0xff; + t2 = ((((c11.a - c10.a) * ex) >> 16) + c10.a) & 0xff; + pc->a = (((t2 - t1) * ey) >> 16) + t1; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } else { + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (short) (sdx >> 16); + dy = (short) (sdy >> 16); + if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { + sp = (tColorRGBA *) ((Uint8 *) src->pixels + src->pitch * dy); + sp += dx; + *pc = *sp; + } + sdx += icos; + sdy += isin; + pc++; + } + pc = (tColorRGBA *) ((Uint8 *) pc + gap); + } + } +} + +/* + + 8bit Rotozoomer without smoothing + + Rotates and zoomes 8bit palette/Y 'src' surface to 'dst' surface. + +*/ + +void transformSurfaceY(SDL_Surface * src, SDL_Surface * dst, int cx, int cy, int isin, int icos) +{ + int x, y, dx, dy, xd, yd, sdx, sdy, ax, ay, sw, sh; + tColorY *pc, *sp; + int gap; + + /* + * Variable setup + */ + xd = ((src->w - dst->w) << 15); + yd = ((src->h - dst->h) << 15); + ax = (cx << 16) - (icos * cx); + ay = (cy << 16) - (isin * cx); + sw = src->w - 1; + sh = src->h - 1; + pc = dst->pixels; + gap = dst->pitch - dst->w; + /* + * Clear surface to colorkey + */ + memset(pc, (unsigned char) (src->format->colorkey & 0xff), dst->pitch * dst->h); + /* + * Iterate through destination surface + */ + for (y = 0; y < dst->h; y++) { + dy = cy - y; + sdx = (ax + (isin * dy)) + xd; + sdy = (ay - (icos * dy)) + yd; + for (x = 0; x < dst->w; x++) { + dx = (short) (sdx >> 16); + dy = (short) (sdy >> 16); + if ((dx >= 0) && (dy >= 0) && (dx < src->w) && (dy < src->h)) { + sp = (tColorY *) (src->pixels); + sp += (src->pitch * dy + dx); + *pc = *sp; + } + sdx += icos; + sdy += isin; + pc++; + } + pc += gap; + } +} + +/* + + rotozoomSurface() + + Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1 + then the destination 32bit surface is anti-aliased. If the surface is not 8bit + or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + +*/ + +#define VALUE_LIMIT 0.001 + + +/* Local rotozoom-size function with trig result return */ + +void rotozoomSurfaceSizeTrig(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight, + double *canglezoom, double *sanglezoom) +{ + double x, y, cx, cy, sx, sy; + double radangle; + int dstwidthhalf, dstheighthalf; + + /* + * Determine destination width and height by rotating a centered source box + */ + radangle = angle * (M_PI / 180.0); + *sanglezoom = sin(radangle); + *canglezoom = cos(radangle); + *sanglezoom *= zoom; + *canglezoom *= zoom; + x = width / 2; + y = height / 2; + cx = *canglezoom * x; + cy = *canglezoom * y; + sx = *sanglezoom * x; + sy = *sanglezoom * y; + dstwidthhalf = MAX((int) + ceil(MAX(MAX(MAX(fabs(cx + sy), fabs(cx - sy)), fabs(-cx + sy)), fabs(-cx - sy))), 1); + dstheighthalf = MAX((int) + ceil(MAX(MAX(MAX(fabs(sx + cy), fabs(sx - cy)), fabs(-sx + cy)), fabs(-sx - cy))), 1); + *dstwidth = 2 * dstwidthhalf; + *dstheight = 2 * dstheighthalf; +} + + +/* Publically available rotozoom-size function */ + +void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth, int *dstheight) +{ + double dummy_sanglezoom, dummy_canglezoom; + + rotozoomSurfaceSizeTrig(width, height, angle, zoom, dstwidth, dstheight, &dummy_sanglezoom, &dummy_canglezoom); +} + + +/* Publically available rotozoom function */ + +SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth) +{ + SDL_Surface *rz_src; + SDL_Surface *rz_dst; + double zoominv; + double sanglezoom, canglezoom, sanglezoominv, canglezoominv; + int dstwidthhalf, dstwidth, dstheighthalf, dstheight; + double x, y, cx, cy, sx, sy; + int is32bit; + int i, src_converted; + + /* + * Sanity check + */ + if (src == NULL) + return (NULL); + + /* + * Determine if source surface is 32bit or 8bit + */ + is32bit = (src->format->BitsPerPixel == 32); + if ((is32bit) || (src->format->BitsPerPixel == 8)) { + /* + * Use source surface 'as is' + */ + rz_src = src; + src_converted = 0; + } else { + /* + * New source surface is 32bit with a defined RGBA ordering + */ + rz_src = + SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface(src, NULL, rz_src, NULL); + src_converted = 1; + is32bit = 1; + } + + /* + * Sanity check zoom factor + */ + if (zoom < VALUE_LIMIT) { + zoom = VALUE_LIMIT; + } + zoominv = 65536.0 / (zoom * zoom); + + /* + * Check if we have a rotozoom or just a zoom + */ + if (fabs(angle) > VALUE_LIMIT) { + + /* + * Angle!=0: full rotozoom + */ + /* + * ----------------------- + */ + + /* Determine target size */ + rotozoomSurfaceSizeTrig(rz_src->w, rz_src->h, angle, zoom, &dstwidth, &dstheight, &canglezoom, &sanglezoom); + + /* + * Calculate target factors from sin/cos and zoom + */ + sanglezoominv = sanglezoom; + canglezoominv = canglezoom; + sanglezoominv *= zoominv; + canglezoominv *= zoominv; + + /* Calculate half size */ + dstwidthhalf = dstwidth / 2; + dstheighthalf = dstheight / 2; + + /* + * Alloc space to completely contain the rotated surface + */ + rz_dst = NULL; + if (is32bit) { + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } else { + /* + * Target surface is 8bit + */ + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0); + } + + /* + * Lock source surface + */ + SDL_LockSurface(rz_src); + /* + * Check which kind of surface we have + */ + if (is32bit) { + /* + * Call the 32bit transformation routine to do the rotation (using alpha) + */ + transformSurfaceRGBA(rz_src, rz_dst, dstwidthhalf, dstheighthalf, + (int) (sanglezoominv), (int) (canglezoominv), smooth); + /* + * Turn on source-alpha support + */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + } else { + /* + * Copy palette and colorkey info + */ + for (i = 0; i < rz_src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* + * Call the 8bit transformation routine to do the rotation + */ + transformSurfaceY(rz_src, rz_dst, dstwidthhalf, dstheighthalf, + (int) (sanglezoominv), (int) (canglezoominv)); + SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey); + } + /* + * Unlock source surface + */ + SDL_UnlockSurface(rz_src); + + } else { + + /* + * Angle=0: Just a zoom + */ + /* + * -------------------- + */ + + /* + * Calculate target size + */ + zoomSurfaceSize(rz_src->w, rz_src->h, zoom, zoom, &dstwidth, &dstheight); + + /* + * Alloc space to completely contain the zoomed surface + */ + rz_dst = NULL; + if (is32bit) { + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } else { + /* + * Target surface is 8bit + */ + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0); + } + + /* + * Lock source surface + */ + SDL_LockSurface(rz_src); + /* + * Check which kind of surface we have + */ + if (is32bit) { + /* + * Call the 32bit transformation routine to do the zooming (using alpha) + */ + zoomSurfaceRGBA(rz_src, rz_dst, smooth); + /* + * Turn on source-alpha support + */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + } else { + /* + * Copy palette and colorkey info + */ + for (i = 0; i < rz_src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* + * Call the 8bit transformation routine to do the zooming + */ + zoomSurfaceY(rz_src, rz_dst); + SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey); + } + /* + * Unlock source surface + */ + SDL_UnlockSurface(rz_src); + } + + /* + * Cleanup temp surface + */ + if (src_converted) { + SDL_FreeSurface(rz_src); + } + + /* + * Return destination surface + */ + return (rz_dst); +} + +/* + + zoomSurface() + + Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1 + then the destination 32bit surface is anti-aliased. If the surface is not 8bit + or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + +*/ + +#define VALUE_LIMIT 0.001 + +void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight) +{ + /* + * Sanity check zoom factors + */ + if (zoomx < VALUE_LIMIT) { + zoomx = VALUE_LIMIT; + } + if (zoomy < VALUE_LIMIT) { + zoomy = VALUE_LIMIT; + } + + /* + * Calculate target size + */ + *dstwidth = (int) ((double) width * zoomx); + *dstheight = (int) ((double) height * zoomy); + if (*dstwidth < 1) { + *dstwidth = 1; + } + if (*dstheight < 1) { + *dstheight = 1; + } +} + +SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth) +{ + SDL_Surface *rz_src; + SDL_Surface *rz_dst; + int dstwidth, dstheight; + int is32bit; + int i, src_converted; + + /* + * Sanity check + */ + if (src == NULL) + return (NULL); + + /* + * Determine if source surface is 32bit or 8bit + */ + is32bit = (src->format->BitsPerPixel == 32); + if ((is32bit) || (src->format->BitsPerPixel == 8)) { + /* + * Use source surface 'as is' + */ + rz_src = src; + src_converted = 0; + } else { + /* + * New source surface is 32bit with a defined RGBA ordering + */ + rz_src = + SDL_CreateRGBSurface(SDL_SWSURFACE, src->w, src->h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + SDL_BlitSurface(src, NULL, rz_src, NULL); + src_converted = 1; + is32bit = 1; + } + + /* Get size if target */ + zoomSurfaceSize(rz_src->w, rz_src->h, zoomx, zoomy, &dstwidth, &dstheight); + + /* + * Alloc space to completely contain the zoomed surface + */ + rz_dst = NULL; + if (is32bit) { + /* + * Target surface is 32bit with source RGBA/ABGR ordering + */ + rz_dst = + SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 32, + rz_src->format->Rmask, rz_src->format->Gmask, + rz_src->format->Bmask, rz_src->format->Amask); + } else { + /* + * Target surface is 8bit + */ + rz_dst = SDL_CreateRGBSurface(SDL_SWSURFACE, dstwidth, dstheight, 8, 0, 0, 0, 0); + } + + /* + * Lock source surface + */ + SDL_LockSurface(rz_src); + /* + * Check which kind of surface we have + */ + if (is32bit) { + /* + * Call the 32bit transformation routine to do the zooming (using alpha) + */ + zoomSurfaceRGBA(rz_src, rz_dst, smooth); + /* + * Turn on source-alpha support + */ + SDL_SetAlpha(rz_dst, SDL_SRCALPHA, 255); + } else { + /* + * Copy palette and colorkey info + */ + for (i = 0; i < rz_src->format->palette->ncolors; i++) { + rz_dst->format->palette->colors[i] = rz_src->format->palette->colors[i]; + } + rz_dst->format->palette->ncolors = rz_src->format->palette->ncolors; + /* + * Call the 8bit transformation routine to do the zooming + */ + zoomSurfaceY(rz_src, rz_dst); + SDL_SetColorKey(rz_dst, SDL_SRCCOLORKEY | SDL_RLEACCEL, rz_src->format->colorkey); + } + /* + * Unlock source surface + */ + SDL_UnlockSurface(rz_src); + + /* + * Cleanup temp surface + */ + if (src_converted) { + SDL_FreeSurface(rz_src); + } + + /* + * Return destination surface + */ + return (rz_dst); +} diff --git a/sc2/src/sc2code/libs/graphics/sdl/rotozoom.h b/sc2/src/sc2code/libs/graphics/sdl/rotozoom.h new file mode 100644 index 000000000..669835606 --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/sdl/rotozoom.h @@ -0,0 +1,84 @@ +/* + + rotozoom.h - rotozoomer for 32bit or 8bit surfaces + LGPL (c) A. Schiffler + + Note by sc2 developers: + Taken from SDL_gfx library and modified, original code can be downloaded + from http://www.ferzkopp.net/Software/SDL_gfx-2.0/ + +*/ + + +#ifndef ROTOZOOM_H +#define ROTOZOOM_H + +#include +#ifndef M_PI +#define M_PI 3.141592654 +#endif + +#include "SDL.h" + + +/* ---- Defines */ + +#define SMOOTHING_OFF 0 +#define SMOOTHING_ON 1 + +/* ---- Structures */ + +typedef struct tColorRGBA { + Uint8 r; + Uint8 g; + Uint8 b; + Uint8 a; +} tColorRGBA; + +typedef struct tColorY { + Uint8 y; +} tColorY; + + +/* ---- Prototypes */ + +/* + + rotozoomSurface() + + Rotates and zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + 'angle' is the rotation in degrees. 'zoom' a scaling factor. If 'smooth' is 1 + then the destination 32bit surface is anti-aliased. If the surface is not 8bit + or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + +*/ + +SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, + int smooth); + + +/* Returns the size of the target surface for a rotozoomSurface() call */ + +void rotozoomSurfaceSize(int width, int height, double angle, double zoom, + int *dstwidth, int *dstheight); + +/* + + zoomSurface() + + Zoomes a 32bit or 8bit 'src' surface to newly created 'dst' surface. + 'zoomx' and 'zoomy' are scaling factors for width and height. If 'smooth' is 1 + then the destination 32bit surface is anti-aliased. If the surface is not 8bit + or 32bit RGBA/ABGR it will be converted into a 32bit RGBA format on the fly. + +*/ + +SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, + int smooth); + +/* Returns the size of the target surface for a zoomSurface() call */ + +void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, + int *dstwidth, int *dstheight); + +#endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c new file mode 100644 index 000000000..c5e1f3f25 --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -0,0 +1,547 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + + +/**************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*****************************************/ + +#if defined (GFXMODULE_SDL_OPENGL) || defined (GFXMODULE_SDL_PURE) + +#include "sdl_common.h" + +#ifdef WIN32 +#include +#endif +#include + + +//Status: Implemented! +DWORD +GetTimeCounter () //I wonder if it's ms, ticks, or seconds... +{ + DWORD ret; + + ret = (DWORD) (SDL_GetTicks () * ONE_SECOND / 1000.0); + return (ret); +} + +DWORD +SetSemaphore (SEMAPHORE *sem) +{ + SDL_SemWait (*sem); + return (GetTimeCounter ()); +} + +void +ClearSemaphore (SEMAPHORE *sem) +{ + SDL_SemPost (*sem); +} + +TASK +AddTask (TASK_FUNC arg1, COUNT arg2) +{ + return (SDL_CreateThread ((int (*)(void *)) arg1, NULL)); +} + +void +DeleteTask (TASK T) +{ + SDL_KillThread (T); +} + +DWORD +SleepTask (DWORD wake_time) +{ + DWORD t; + + t = GetTimeCounter (); + if (wake_time <= t) + SDL_Delay (0); + else + SDL_Delay ((wake_time - t) * 1000 / ONE_SECOND); + + return (GetTimeCounter ()); +} + + +// following stuff was in getbody.c before modularization + +extern char *_cur_resfile_name; + +static void +process_image (FRAMEPTR FramePtr, SDL_Surface *img[], int cel_ct) +{ + int hx, hy, h; + + TYPE_SET (FramePtr->TypeIndexAndFlags, WANT_PIXMAP << FTYPE_SHIFT); + INDEX_SET (FramePtr->TypeIndexAndFlags, cel_ct); + + hx = hy = 0; + + SDL_LockSurface (img[cel_ct]); + if (img[cel_ct]->w >= 3 && (h = img[cel_ct]->h)) + { + if (img[cel_ct]->format->palette) + { + int w; + BYTE *pixel, *p, Cknockout, Chotx, Choty; + + img[cel_ct]->clip_rect.x = img[cel_ct]->w; + img[cel_ct]->clip_rect.y = img[cel_ct]->h; + img[cel_ct]->clip_rect.w = img[cel_ct]->clip_rect.h = 0; + p = pixel = img[cel_ct]->pixels; + Cknockout = *p++; + Chotx = *p; + *p++ = Cknockout; + Choty = *p; + *p++ = Cknockout; + SDL_SetColorKey + ( + img[cel_ct], SDL_SRCCOLORKEY, + SDL_MapRGB + ( + img[cel_ct]->format, + img[cel_ct]->format->palette->colors[Cknockout].r, + img[cel_ct]->format->palette->colors[Cknockout].g, + img[cel_ct]->format->palette->colors[Cknockout].b + ) + ); + do + { + w = img[cel_ct]->w - (p - pixel); + if (w) + { + int x, y; + BYTE opval; + + opval = Cknockout; + do + { + BYTE pval; + + pval = *p; + if (pval == Chotx) + { + *p = Cknockout; + hx = img[cel_ct]->w - w; + } + if (pval == Choty) + { + *p = Cknockout; + hy = img[cel_ct]->h - h; + } + + pval = *p; + if (pval == Cknockout) + { + if (opval != Cknockout) + { + x = img[cel_ct]->w - w; + if (x > img[cel_ct]->clip_rect.x + img[cel_ct]->clip_rect.w) + img[cel_ct]->clip_rect.w = x - img[cel_ct]->clip_rect.x; + y = img[cel_ct]->h - h; + if (y >= img[cel_ct]->clip_rect.y + img[cel_ct]->clip_rect.h) + img[cel_ct]->clip_rect.h = y - img[cel_ct]->clip_rect.y + 1; + } + } + else + { + if (opval == Cknockout) + { + x = img[cel_ct]->w - w; + if (x < img[cel_ct]->clip_rect.x) + { + if (img[cel_ct]->clip_rect.w == 0) + img[cel_ct]->clip_rect.w = 1; + else + img[cel_ct]->clip_rect.w += img[cel_ct]->clip_rect.x - x; + img[cel_ct]->clip_rect.x = x; + } + y = img[cel_ct]->h - h; + if (y < img[cel_ct]->clip_rect.y) + { + if (img[cel_ct]->clip_rect.h == 0) + img[cel_ct]->clip_rect.h = 1; + else + img[cel_ct]->clip_rect.h += img[cel_ct]->clip_rect.y - y; + img[cel_ct]->clip_rect.y = y; + } + } + } + opval = pval; + } while (++p, --w); + if (opval != Cknockout) + { + x = img[cel_ct]->w - w; + if (x > img[cel_ct]->clip_rect.x + img[cel_ct]->clip_rect.w) + img[cel_ct]->clip_rect.w = x - img[cel_ct]->clip_rect.x; + y = img[cel_ct]->h - h; + if (y >= img[cel_ct]->clip_rect.y + img[cel_ct]->clip_rect.h) + img[cel_ct]->clip_rect.h = y - img[cel_ct]->clip_rect.y + 1; + } + } + p = (pixel += img[cel_ct]->pitch); + } while (--h); + } + else + { + } + } + SDL_UnlockSurface (img[cel_ct]); + +hx -= img[cel_ct]->clip_rect.x; +hy -= img[cel_ct]->clip_rect.y; + FramePtr->DataOffs = (BYTE *)TFB_LoadImage (img[cel_ct]) - (BYTE *)FramePtr; +img[cel_ct] = ((TFB_Image *)((BYTE *)FramePtr + FramePtr->DataOffs))->SurfaceSDL; +hx += img[cel_ct]->clip_rect.x; +hy += img[cel_ct]->clip_rect.y; + SetFrameHotSpot (FramePtr, MAKE_HOT_SPOT (hx, hy)); + SetFrameBounds (FramePtr, img[cel_ct]->clip_rect.w, img[cel_ct]->clip_rect.h); +#if 0 +printf ("\thot[%d, %d], rect[%d, %d, %d, %d]\n", + hx, hy, + img[cel_ct]->clip_rect.x, + img[cel_ct]->clip_rect.y, + img[cel_ct]->clip_rect.w, + img[cel_ct]->clip_rect.h); +#endif +} + +MEM_HANDLE +_GetCelData (FILE *fp, DWORD length) +{ +#ifdef WIN32 + int omode; +#endif + int cel_ct, n; + DWORD opos; + char CurrentLine[1024], filename[1024]; +#define MAX_CELS 256 + SDL_Surface *img[MAX_CELS]; + DRAWABLE Drawable; + + opos = ftell (fp); + + { + char *s1, *s2; + + if (_cur_resfile_name == 0 + || (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0) + && (s2 = strrchr (_cur_resfile_name, '\\')) == 0)) + n = 0; + else + { + if (s2 > s1) + s1 = s2; + n = s1 - _cur_resfile_name + 1; + strncpy (filename, _cur_resfile_name, n); + } + } + +#ifdef WIN32 + omode = _setmode (fileno (fp), O_TEXT); +#endif + cel_ct = 0; + while (fgets (CurrentLine, sizeof (CurrentLine), fp) && cel_ct < MAX_CELS) + { + if + ( + sscanf(CurrentLine, "%s", &filename[n]) == 1 + && (img[cel_ct] = IMG_Load (filename)) + && img[cel_ct]->w > 0 + && img[cel_ct]->h > 0 + && img[cel_ct]->format->BitsPerPixel >= 8 + ) + ++cel_ct; + else if (img[cel_ct]) +printf("_GetCelData: Bad file!\n"), + SDL_FreeSurface (img[cel_ct]); + + if ((int)ftell (fp) - (int)opos >= (int)length) + break; + } +#ifdef WIN32 + _setmode (fileno (fp), omode); +#endif + + Drawable = 0; + if (cel_ct && (Drawable = AllocDrawable (cel_ct, 0))) + { + DRAWABLEPTR DrawablePtr; + + if ((DrawablePtr = LockDrawable (Drawable)) == 0) + { + while (cel_ct--) + SDL_FreeSurface (img[cel_ct]); + + mem_release (Drawable); + Drawable = 0; + } + else + { + FRAMEPTR FramePtr; + + DrawablePtr->hDrawable = GetDrawableHandle (Drawable); + TYPE_SET (DrawablePtr->FlagsAndIndex, + (DRAWABLE_TYPE)ROM_DRAWABLE << FTYPE_SHIFT); + INDEX_SET (DrawablePtr->FlagsAndIndex, cel_ct - 1); + + FramePtr = &DrawablePtr->Frame[cel_ct]; + while (--FramePtr, cel_ct--) + process_image (FramePtr, img, cel_ct); + + UnlockDrawable (Drawable); + } + } + +if (Drawable == 0) + printf ("Couldn't get cel data for '%s'\n", _cur_resfile_name); + return (GetDrawableHandle (Drawable)); +} + +BOOLEAN +_ReleaseCelData (MEM_HANDLE handle) +{ + DRAWABLEPTR DrawablePtr; + + if ((DrawablePtr = LockDrawable (handle)) == 0) + return (FALSE); + + if (TYPE_GET (DrawablePtr->FlagsAndIndex) != SCREEN_DRAWABLE) + { + int cel_ct; + FRAMEPTR FramePtr; + + cel_ct = INDEX_GET (DrawablePtr->FlagsAndIndex); + + FramePtr = &DrawablePtr->Frame[cel_ct]; + while (--FramePtr, cel_ct--) + { + if (FramePtr->DataOffs) + { + TFB_Image *img; + + img = (TFB_Image *)((BYTE *)FramePtr + FramePtr->DataOffs); + FramePtr->DataOffs = 0; + + TFB_FreeImage (img); + } + } + } + + UnlockDrawable (handle); + mem_release (handle); + + return (TRUE); +} + +MEM_HANDLE +_GetFontData (FILE *fp, DWORD length) +{ + DWORD cel_ct; + COUNT num_entries; + FONT_REF FontRef; + DIRENTRY FontDir; + BOOLEAN found_chars; +#define MAX_CELS 256 + SDL_Surface *img[MAX_CELS] = { 0 }; + char pattern[1024]; + + if (_cur_resfile_name == 0) + return (0); + sprintf (pattern, "%s/*.*", _cur_resfile_name); + + found_chars = FALSE; + FontDir = CaptureDirEntryTable (LoadDirEntryTable (pattern, &num_entries)); + while (num_entries--) + { + char *char_name; + + char_name = GetDirEntryAddress (SetAbsDirEntryTableIndex (FontDir, num_entries)); + if (sscanf (char_name, "%u.", (unsigned int) &cel_ct) == 1 + && cel_ct >= FIRST_CHAR + && img[cel_ct -= FIRST_CHAR] == 0 + && sprintf (pattern, "%s/%s", _cur_resfile_name, char_name) + && (img[cel_ct] = IMG_Load (pattern))) + { + if (img[cel_ct]->w > 0 + && img[cel_ct]->h > 0 + && img[cel_ct]->format->BitsPerPixel >= 8) + found_chars = TRUE; + else + { + SDL_FreeSurface (img[cel_ct]); + img[cel_ct] = 0; + } + } + + } + DestroyDirEntryTable (ReleaseDirEntryTable (FontDir)); + + FontRef = 0; + if (found_chars && (FontRef = AllocFont (0))) + { + FONTPTR FontPtr; + + cel_ct = MAX_CELS; // MAX_CHARS; + if ((FontPtr = LockFont (FontRef)) == 0) + { + while (cel_ct--) + { + if (img[cel_ct]) + SDL_FreeSurface (img[cel_ct]); + } + + mem_release (FontRef); + FontRef = 0; + } + else + { + FRAMEPTR FramePtr; + + FontPtr->FontRef = FontRef; + FontPtr->Leading = 0; + FramePtr = &FontPtr->CharDesc[cel_ct]; + while (--FramePtr, cel_ct--) + { + if (img[cel_ct]) + { + process_image (FramePtr, img, cel_ct); + SetFrameBounds (FramePtr, GetFrameWidth (FramePtr) + 1, GetFrameHeight (FramePtr)); + if (img[0]) + SetFrameHotSpot (FramePtr, MAKE_HOT_SPOT (0, img[0]->clip_rect.h)); + if (GetFrameHeight (FramePtr) > FontPtr->Leading) + FontPtr->Leading = GetFrameHeight (FramePtr); + } + } + ++FontPtr->Leading; + + UnlockFont (FontRef); + } + } + (void) fp; /* Satisfying compiler (unused parameter) */ + (void) length; /* Satisfying compiler (unused parameter) */ + return (FontRef); +} + +BOOLEAN +_ReleaseFontData (MEM_HANDLE handle) +{ + FONTPTR FontPtr; + + if ((FontPtr = LockFont (handle)) == 0) + return (FALSE); + + { + int cel_ct; + FRAMEPTR FramePtr; + + cel_ct = MAX_CHARS; + + FramePtr = &FontPtr->CharDesc[cel_ct]; + while (--FramePtr, cel_ct--) + { + if (FramePtr->DataOffs) + { + TFB_Image *img; + + img = (TFB_Image *)((BYTE *)FramePtr + FramePtr->DataOffs); + FramePtr->DataOffs = 0; + + TFB_FreeImage (img); + } + } + } + + UnlockFont (handle); + mem_release (handle); + + return (TRUE); +} + +// _request_drawable was in drawable.c before modularization + +DRAWABLE +_request_drawable (COUNT NumFrames, DRAWABLE_TYPE DrawableType, + CREATE_FLAGS flags, SIZE width, SIZE height) +{ + DRAWABLE Drawable; + + Drawable = AllocDrawableImage ( + NumFrames, DrawableType, flags, width, height + ); + if (Drawable) + { + DRAWABLEPTR DrawablePtr; + + if ((DrawablePtr = LockDrawable (Drawable)) == 0) + { + FreeDrawable (Drawable); + Drawable = 0; + } + else + { + int imgw, imgh; + FRAMEPTR FramePtr; + + DrawablePtr->hDrawable = GetDrawableHandle (Drawable); + TYPE_SET (DrawablePtr->FlagsAndIndex, flags << FTYPE_SHIFT); + INDEX_SET (DrawablePtr->FlagsAndIndex, NumFrames - 1); + + imgw = (flags & MAPPED_TO_DISPLAY) ? width * ScreenWidthActual / ScreenWidth : width; + imgh = (flags & MAPPED_TO_DISPLAY) ? height * ScreenHeightActual / ScreenHeight : height; + FramePtr = &DrawablePtr->Frame[NumFrames - 1]; + while (NumFrames--) + { + TFB_Image *Image; + + + if (DrawableType == RAM_DRAWABLE + && (Image = TFB_LoadImage (SDL_CreateRGBSurface ( + SDL_HWSURFACE, + imgw, + imgh, + 24, + 0x00FF0000, + 0x0000FF00, + 0x000000FF, + 0x00000000 + )))) + FramePtr->DataOffs = (BYTE *)Image - (BYTE *)FramePtr; + + TYPE_SET (FramePtr->TypeIndexAndFlags, DrawableType); + INDEX_SET (FramePtr->TypeIndexAndFlags, NumFrames); + SetFrameBounds (FramePtr, width, height); + --FramePtr; + } + UnlockDrawable (Drawable); + } + } + + return (Drawable); +} + +#endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h new file mode 100644 index 000000000..01c8a487d --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h @@ -0,0 +1,50 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + + +/**************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*****************************************/ + +#ifndef SDL_COMMON_H +#define SDL_COMMON_H + +#include "SDL.h" +#include "SDL_thread.h" +#include "SDL_image.h" +#include "SDL_mixer.h" + +#include "libs/graphics/gfxintrn.h" +#include "libs/input/inpintrn.h" +#include "libs/graphics/gfx_common.h" + +#if defined (GFXMODULE_SDL_OPENGL) +#include "libs/graphics/sdl/opengl/opengl.h" +#elif defined (GFXMODULE_SDL_PURE) +#include "libs/graphics/sdl/pure/pure.h" +#endif + +#include "libs/input/sdl/input.h" + +#endif diff --git a/sc2/src/sc2code/libs/input/input_common.c b/sc2/src/sc2code/libs/input/input_common.c new file mode 100644 index 000000000..2a6fd6ead --- /dev/null +++ b/sc2/src/sc2code/libs/input/input_common.c @@ -0,0 +1,184 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + +#include "inpintrn.h" + +INPUT_DEVICE +CreateSerialKeyboardDevice (void) +{ + INPUT_DEVICE InputDevice; + + if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) + { + INPUT_DESCPTR InputPtr; + + if ((InputPtr = + LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) + { + FreeInputDevice (InputDevice); + InputDevice = (INPUT_DEVICE)NULL_PTR; + } + else + { + SetInputDeviceHandle (InputPtr, InputDevice); + SetInputDeviceInputFunc (InputPtr, _get_serial_keyboard_state); + + UnlockInputDevice (InputDevice); + } + } + + return (InputDevice); +} + +INPUT_DEVICE +CreateJoystickKeyboardDevice (UNICODE lfkey, UNICODE rtkey, UNICODE + topkey, UNICODE botkey, UNICODE but1key, UNICODE but2key, UNICODE + but3key, UNICODE shift1key, UNICODE shift2key) +{ + INPUT_DEVICE InputDevice; + + if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) + { + INPUT_DESCPTR InputPtr; + + if ((InputPtr = + LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) + { + FreeInputDevice (InputDevice); + InputDevice = (INPUT_DEVICE)NULL_PTR; + } + else + { + SetInputDeviceHandle (InputPtr, InputDevice); + SetInputDeviceInputFunc (InputPtr, _get_joystick_keyboard_state); + SetInputDeviceKeyEquivalents (InputPtr, + lfkey, rtkey, topkey, botkey, + but1key, but2key, but3key, + shift1key, shift2key); + + UnlockInputDevice (InputDevice); + } + } + + return (InputDevice); +} + +INPUT_DEVICE +CreateJoystickDevice (COUNT port) +{ + INPUT_DEVICE InputDevice; + + if (!_joystick_port_active (port)) + InputDevice = (INPUT_DEVICE)NULL_PTR; + else if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) + { + INPUT_DESCPTR InputPtr; + + if ((InputPtr = + LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) + { + FreeInputDevice (InputDevice); + InputDevice = (INPUT_DEVICE)NULL_PTR; + } + else + { + SetInputDeviceHandle (InputPtr, InputDevice); + SetInputDeviceInputFunc (InputPtr, _get_joystick_state); + SetInputDeviceJoystickPort (InputPtr, port); + + UnlockInputDevice (InputDevice); + } + } + + return (InputDevice); +} + +INPUT_DEVICE +CreateInternalDevice (INPUT_STATE (*input_func) (INPUT_REF InputRef, + INPUT_STATE InputState)) +{ + INPUT_DEVICE InputDevice; + + if (input_func == NULL_PTR) + InputDevice = (INPUT_DEVICE)NULL_PTR; + else if ((InputDevice = AllocInputDevice ()) != (INPUT_DEVICE)NULL_PTR) + { + INPUT_DESCPTR InputPtr; + + if ((InputPtr = + LockInputDevice (InputDevice)) == (INPUT_DESCPTR)NULL_PTR) + { + FreeInputDevice (InputDevice); + InputDevice = (INPUT_DEVICE)NULL_PTR; + } + else + { + SetInputDeviceHandle (InputPtr, InputDevice); + SetInputDeviceInputFunc (InputPtr, input_func); + + UnlockInputDevice (InputDevice); + } + } + + return (InputDevice); +} + +INPUT_REF +CaptureInputDevice (INPUT_DEVICE InputDevice) +{ + if (InputDevice != (INPUT_DEVICE)NULL_PTR) + return ((INPUT_REF)LockInputDevice (InputDevice)); + + return ((INPUT_REF)NULL_PTR); +} + +INPUT_DEVICE +ReleaseInputDevice (INPUT_REF InputRef) +{ + INPUT_DEVICE InputDevice; + + if (InputRef == (INPUT_REF)NULL_PTR) + InputDevice = (INPUT_DEVICE)NULL_PTR; + else + { + InputDevice = GetInputDeviceHandle (InputRef); + UnlockInputDevice (InputDevice); + } + + return (InputDevice); +} + +BOOLEAN +DestroyInputDevice (INPUT_DEVICE InputDevice) +{ + if (InputDevice != (INPUT_DEVICE)NULL_PTR) + return (FreeInputDevice (InputDevice)); + + return (FALSE); +} + +INPUT_STATE +GetInputState (INPUT_REF InputRef) +{ + if (InputRef == 0) + return (_get_pause_exit_state ()); + else + return ((*GetInputDeviceInputFunc (InputRef)) + (InputRef, _get_pause_exit_state ())); +} + diff --git a/sc2/src/sc2code/libs/input/sdl/Makefile.am b/sc2/src/sc2code/libs/input/sdl/Makefile.am new file mode 100644 index 000000000..98cc1c01a --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/Makefile.am @@ -0,0 +1,14 @@ + +# Automake template file. +# Written by Mudry , protected by GNU GPL. +# CVS $ Id: $ + +INCLUDES = @SDL_CFLAGS@ @SMPEG_CFLAGS@ \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/sc2code \ + -I$(top_srcdir)/src/sc2code/libs + +noinst_LTLIBRARIES = libsdlinput.la +libsdlinput_la_SOURCES = input.c +noinst_HEADERS = input.h + diff --git a/sc2/src/sc2code/libs/input/sdl/input.c b/sc2/src/sc2code/libs/input/sdl/input.c new file mode 100644 index 000000000..6544062c4 --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/input.c @@ -0,0 +1,759 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + + +/**************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*****************************************/ + +#if defined (GFXMODULE_SDL_OPENGL) || defined (GFXMODULE_SDL_PURE) + +#include "libs/graphics/sdl/sdl_common.h" + + +Uint8 KeyboardDown[512]; +#define KBDBUFSIZE (1 << 8) +int kbdhead, kbdtail; +Uint16 kbdbuf[KBDBUFSIZE]; + +UBYTE ControlA; +UBYTE ControlB; +UBYTE ControlC; +UBYTE ControlX; +UBYTE ControlStart; +UBYTE ControlLeftShift; +UBYTE ControlRightShift; + + +static UNICODE PauseKey; +static UNICODE ExitKey; +static UNICODE OtherKey; + +static BOOLEAN (* PauseFunc) (void); + +// Status: Unimplemented +extern BOOLEAN +InitInput (UNICODE Pause, UNICODE Exit, BOOLEAN (*PFunc) (void)) +//Be careful with this one. +{ + PauseKey = Pause; + ExitKey = Exit; + + // Find a unique byte ID not equal to PauseKey, ExitKey, or 0. + OtherKey = 1; + while (OtherKey == PauseKey || OtherKey == ExitKey) + OtherKey++; + + PauseFunc = PFunc; + + return (TRUE); +} + +INPUT_STATE +AnyButtonPress (BOOLEAN DetectSpecial) +{ + int i; + + if (DetectSpecial) + { + if (KeyDown (PauseKey) && PauseFunc && (*PauseFunc) ()) + ; + } + + for (i = 0; i < sizeof (KeyboardDown) / sizeof (KeyboardDown[0]); ++i) + { + if (KeyboardDown[i]) + return (DEVICE_BUTTON1); + } +#if 0 + for (i = 0; i < JOYSTICKS_AVAIL; i++) + if (read_joystick (i)) + return (DEVICE_BUTTON1); +#endif + + return (0); +} + +// Status: Ignored - The keyboard will serve as the joystick, thus a port is always open. +BOOLEAN +_joystick_port_active(COUNT port) //SDL handles this nicely. +{ + printf ("Unimplemented function activated: _joystick_port_active()\n"); + return (0); +} + +INPUT_STATE +_get_pause_exit_state (void) +{ + INPUT_STATE InputState; + + InputState = 0; + if (KeyDown (PauseKey)) + { + if (PauseFunc && (*PauseFunc) ()) + ; + } + else if (KeyDown (ExitKey)) + { + InputState = DEVICE_EXIT; + } +#if 0 + for (i = 0; i < JOYSTICKS_AVAIL; i++) + { + DWORD joy; + + joy = read_joystick (i); + if (joy & ControlStart) // pause + { + if (PauseFunc && (*PauseFunc) ()) +// while (KeyDown (PauseKey)) + ; + } + else if (joy & ControlX) // exit + { +// while (KeyDown (ExitKey)) +// TaskSwitch (); + + InputState = DEVICE_EXIT; + } + } +#endif + + return (InputState); +} + +Uint16 +GetUNICODEKey () +{ + if (kbdtail != kbdhead) + { + Uint16 ch; + + ch = kbdbuf[kbdhead]; + kbdhead = (kbdhead + 1) & (KBDBUFSIZE - 1); + return (ch); + } + + return (0); +} + +// Status: Unimplemented +INPUT_STATE +_get_serial_keyboard_state (INPUT_REF ref, INPUT_STATE InputState) + // I hope these are defined somewhere... +{ + Uint16 key; + extern Uint16 GetUNICODEKey (void); + + if ((key = GetUNICODEKey ()) == '\r') + key = '\n'; + SetInputUNICODE (&InputState, key); + SetInputDevType (&InputState, KEYBOARD_DEVICE); + + return (InputState); +} + +// Status: Unimplemented +INPUT_STATE +_get_joystick_keyboard_state (INPUT_REF InputRef, INPUT_STATE InputState) + // see line above. +{ + SBYTE dx, dy; + BYTEPTR KeyEquivalentPtr; + + KeyEquivalentPtr = GetInputDeviceKeyEquivalentPtr (InputRef); + dx = (SBYTE)(KeyDown (KeyEquivalentPtr[1]) - + KeyDown (KeyEquivalentPtr[0])); + SetInputXComponent (&InputState, dx); + + KeyEquivalentPtr += 2; + dy = (SBYTE)(KeyDown (KeyEquivalentPtr[1]) - + KeyDown (KeyEquivalentPtr[0])); + SetInputYComponent (&InputState, dy); + + KeyEquivalentPtr += 2; + if (KeyDown (*KeyEquivalentPtr++)) + InputState |= DEVICE_BUTTON1; + if (KeyDown (*KeyEquivalentPtr++)) + InputState |= DEVICE_BUTTON2; + if (KeyDown (*KeyEquivalentPtr++)) + InputState |= DEVICE_BUTTON3; + + if (KeyDown (*KeyEquivalentPtr++)) + InputState |= DEVICE_LEFTSHIFT; + if (KeyDown (*KeyEquivalentPtr++)) + InputState |= DEVICE_RIGHTSHIFT; + + if (InputState) + SetInputDevType (&InputState, JOYSTICK_DEVICE); + + return (InputState); +} + +/* +// Status: Implemented +INPUT_STATE +_get_joystick_state (INPUT_REF ref, INPUT_STATE InputState) + // consistant, at least. +{ +// printf ("Half-implemented function activated: _get_joystick_state()\n"); + + if (KeyboardStroke[SDLK_LEFT]) + { + SetInputXComponent (&InputState, -1); +// printf ("LEFT!\n"); + KeyboardStroke[SDLK_LEFT] = FALSE; + } + if (KeyboardStroke[SDLK_RIGHT]) + { + SetInputXComponent (&InputState, 1); +// printf ("RIGHT!\n"); + KeyboardStroke[SDLK_RIGHT] = FALSE; + } + + if (KeyboardStroke[SDLK_UP]) + { + SetInputYComponent (&InputState, -1); +// printf ("UP!\n"); + KeyboardStroke[SDLK_UP] = FALSE; + } + if (KeyboardStroke[SDLK_DOWN]) + { + SetInputYComponent (&InputState, 1); +// printf ("DOWN!\n"); + KeyboardStroke[SDLK_DOWN] = FALSE; + } + + if (KeyboardStroke[ControlA]) + { + InputState |= DEVICE_BUTTON1; +// printf("BUTTON1!\n"); + KeyboardStroke[ControlA]=FALSE; + } + if (KeyboardStroke[ControlB]) + { + InputState |= DEVICE_BUTTON2; +// printf ("BUTTON2!\n"); + KeyboardStroke[ControlB] = FALSE; + } + if (KeyboardStroke[ControlC]) + { + InputState |= DEVICE_BUTTON3; +// printf ("BUTTON3!\n"); + KeyboardStroke[ControlC] = FALSE; + } + if (KeyboardStroke[ControlX]) + { + InputState |= DEVICE_EXIT; +// printf ("BUTTONX!\n"); + KeyboardStroke[ControlX] = FALSE; + } + if (KeyboardStroke[ControlStart]) + { + InputState |= DEVICE_PAUSE; +// printf ("CONTROLSTART!\n"); + KeyboardStroke[ControlStart] = FALSE; + } + if (KeyboardStroke[ControlLeftShift]) + { + InputState |= DEVICE_LEFTSHIFT; +// printf ("LEFTSHIFT!\n"); + KeyboardStroke[ControlLeftShift] = FALSE; + } + if (KeyboardStroke[ControlRightShift]) + { + InputState |= DEVICE_RIGHTSHIFT; +// printf ("RIGHTSHIFT!\n"); + KeyboardStroke[ControlRightShift] = FALSE; + } + + return (InputState); +} +*/ + +INPUT_STATE +_get_joystick_state (INPUT_REF ref, INPUT_STATE InputState) + // consistant, at least. +{ +#if 0 + if (ref == JoystickInput[1] && 0) + { + //printf ("ref\n"); + + return(0); + } + +// printf ("Half-implemented function activated: _get_joystick_state()\n"); + + if (KeyboardDown[SDLK_LEFT]) + { + SetInputXComponent (&InputState, -1); + //printf ("LEFT!\n"); + } + if (KeyboardDown[SDLK_RIGHT]) + { + SetInputXComponent (&InputState, 1); + //printf ("RIGHT!\n"); + } + + if (KeyboardDown[SDLK_UP]) + { + SetInputYComponent (&InputState, -1); + //printf ("UP!\n"); + } + if (KeyboardDown[SDLK_DOWN]) + { + SetInputYComponent (&InputState, 1); + //printf ("DOWN!\n"); + } + + if (KeyboardDown[ControlA]) + { + InputState |= DEVICE_BUTTON1; + //printf ("BUTTON1!\n"); + } + if (KeyboardDown[ControlB]) + { + InputState |= DEVICE_BUTTON2; + //printf ("BUTTON2!\n"); + } + if (KeyboardDown[ControlC]) + { + InputState |= DEVICE_BUTTON3; + //printf ("BUTTON3!\n"); + } + if (KeyboardDown[ControlX]) + { + InputState |= DEVICE_EXIT; + //printf ("BUTTONX!\n"); + } + if (KeyboardDown[ControlStart]) + { + InputState |= DEVICE_PAUSE; + //printf ("CONTROLSTART!\n"); + } + if (KeyboardDown[ControlLeftShift]) + { + InputState |= DEVICE_LEFTSHIFT; + //printf ("LEFTSHIFT!\n"); + } + if (KeyboardDown[ControlRightShift]) + { + InputState |= DEVICE_RIGHTSHIFT; + //printf ("RIGHTSHIFT!\n"); + } +#endif + + return (InputState); +} + + +void +FlushInput () +{ + kbdtail = kbdhead = 0; +} + +void +ProcessKeyboardEvent(const SDL_Event *Event) +{ + if(Event->key.keysym.sym == SDLK_BACKQUOTE) + { + exit(0); + } + else + { + if (Event->type == SDL_KEYDOWN) + { + if ((kbdbuf[kbdtail] = Event->key.keysym.unicode) + || (kbdbuf[kbdtail] = Event->key.keysym.sym) <= 0x7F) + { + kbdtail = (kbdtail + 1) & (KBDBUFSIZE - 1); + if (kbdtail == kbdhead) + kbdhead = (kbdhead + 1) & (KBDBUFSIZE - 1); + } + KeyboardDown[Event->key.keysym.sym]=TRUE; + } + else + { + KeyboardDown[Event->key.keysym.sym]=FALSE; + } + } +} + +void +ProcessJoystickEvent (const SDL_Event* Event) +{ + SDL_Event PseudoEvent; + + return; + + if (Event->type == SDL_JOYAXISMOTION) + { + if (Event->jaxis.axis == 0) + { + //x-axis + + if (Event->jaxis.value <= -5) //Left + { + PseudoEvent.type = SDL_KEYDOWN; + PseudoEvent.key.keysym.sym = SDLK_LEFT; + ProcessKeyboardEvent (&PseudoEvent); + + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_RIGHT; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jaxis.value >= 5) //Right + { + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_LEFT; + ProcessKeyboardEvent (&PseudoEvent); + + PseudoEvent.type = SDL_KEYDOWN; + PseudoEvent.key.keysym.sym = SDLK_RIGHT; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jaxis.value > -5 && Event->jaxis.value < 5) + //Neither Left nor Right + { + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_LEFT; + ProcessKeyboardEvent (&PseudoEvent); + + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_RIGHT; + ProcessKeyboardEvent (&PseudoEvent); + } + } + if (Event->jaxis.axis == 1) + { + //y-axis + + if (Event->jaxis.value <= -5) //Down + { + PseudoEvent.type = SDL_KEYDOWN; + PseudoEvent.key.keysym.sym = SDLK_DOWN; + ProcessKeyboardEvent (&PseudoEvent); + + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_UP; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jaxis.value >= 5) //Up + { + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_DOWN; + ProcessKeyboardEvent (&PseudoEvent); + + PseudoEvent.type = SDL_KEYDOWN; + PseudoEvent.key.keysym.sym = SDLK_UP; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jaxis.value >-5 && Event->jaxis.value < 5) + //Neither Down nor Up + { + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_DOWN; + ProcessKeyboardEvent (&PseudoEvent); + + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = SDLK_UP; + ProcessKeyboardEvent (&PseudoEvent); + } + } + } + if (Event->type == SDL_JOYBUTTONDOWN) + { + printf("Joystick %i down\n", Event->jbutton.button); + + if (Event->jbutton.button % 3 == 0) + { + //Mimic the Primary key + + PseudoEvent.type=SDL_KEYDOWN; + PseudoEvent.key.keysym.sym = ControlA; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jbutton.button % 3 == 1) + { + //Mimic the Secondary key + + PseudoEvent.type = SDL_KEYDOWN; + PseudoEvent.key.keysym.sym = ControlB; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jbutton.button % 3 == 2) + { + //Mimic the Tertiary key + + PseudoEvent.type = SDL_KEYDOWN; + PseudoEvent.key.keysym.sym = ControlC; + ProcessKeyboardEvent (&PseudoEvent); + } + } + if (Event->type == SDL_JOYBUTTONUP) + { + if (Event->jbutton.button % 3 == 0) + { + //Mimic the Primary key + + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = ControlA; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jbutton.button % 3 == 1) + { + //Mimic the Secondary key + + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = ControlB; + ProcessKeyboardEvent (&PseudoEvent); + } + if (Event->jbutton.button % 3 == 2) + { + //Mimic the Tertiary key + + PseudoEvent.type = SDL_KEYUP; + PseudoEvent.key.keysym.sym = ControlC; + ProcessKeyboardEvent (&PseudoEvent); + } + } +} + +//Status: Unimplemented +UNICODE +KBDToUNICODE (UNICODE SK_in) + //This one'll probably require a big table. Arg. +{ + return (SK_in); +} + +//Status: Ignored +BOOLEAN +UninitInput () // Looks like it'll be empty +{ + BOOLEAN ret; + + // printf("Unimplemented function activated: UninitInput()\n"); + ret = TRUE; + return (ret); +} + +// Status: Unimplemented +UNICODE +KeyHit () // Does this clear the top of a queue, or just read it? +{ + int i; + + for (i = 0; i < sizeof (KeyboardDown) / sizeof (KeyboardDown[0]); ++i) + { + if (KeyboardDown[i]) + { + if (i == SDLK_RETURN) + return ('\n'); + else if (i >= 256) + { + switch (i) + { + case SDLK_KP_ENTER: + return ('\n'); + case SDLK_KP4: + case SDLK_LEFT: + return (SK_LF_ARROW); + case SDLK_KP6: + case SDLK_RIGHT: + return (SK_RT_ARROW); + case SDLK_KP8: + case SDLK_UP: + return (SK_UP_ARROW); + case SDLK_KP2: + case SDLK_DOWN: + return (SK_DN_ARROW); + case SDLK_KP7: + case SDLK_HOME: + return (SK_HOME); + case SDLK_KP9: + case SDLK_PAGEUP: + return (SK_PAGE_UP); + case SDLK_KP1: + case SDLK_END: + return (SK_END); + case SDLK_KP3: + case SDLK_PAGEDOWN: + return (SK_PAGE_DOWN); + case SDLK_KP0: + case SDLK_INSERT: + return (SK_INSERT); + case SDLK_KP_PERIOD: + case SDLK_DELETE: + return (SK_DELETE); + case SDLK_KP_PLUS: + return (SK_KEYPAD_PLUS); + case SDLK_KP_MINUS: + return (SK_KEYPAD_MINUS); + case SDLK_LSHIFT: + return (SK_LF_SHIFT); + case SDLK_RSHIFT: + return (SK_RT_SHIFT); + case SDLK_LCTRL: + case SDLK_RCTRL: + return (SK_CTL); + case SDLK_LALT: + case SDLK_RALT: + return (SK_ALT); + case SDLK_F1: + case SDLK_F2: + case SDLK_F3: + case SDLK_F4: + case SDLK_F5: + case SDLK_F6: + case SDLK_F7: + case SDLK_F8: + case SDLK_F9: + case SDLK_F10: + case SDLK_F11: + case SDLK_F12: + return ((UNICODE) ((i - SDLK_F1) + SK_F1)); + } + continue; + } + + return ((UNICODE) i); + } + } + + return (0); +} + +//Status: Unimplemented +int +KeyDown (UNICODE which_scan) + // This might use SK_* stuff, of just plain old chars +{ + int i; + + i = which_scan; + if (i == '\n') + { + if (KeyboardDown[SDLK_KP_ENTER]) + return (1); + i = SDLK_RETURN; + } + else if (i >= 128) + { + switch (i) + { + case SK_LF_ARROW: + if (KeyboardDown[SDLK_KP4]) + return (1); + i = SDLK_LEFT; + break; + case SK_RT_ARROW: + if (KeyboardDown[SDLK_KP6]) + return (1); + i = SDLK_RIGHT; + break; + case SK_UP_ARROW: + if (KeyboardDown[SDLK_KP8]) + return (1); + i = SDLK_UP; + break; + case SK_DN_ARROW: + if (KeyboardDown[SDLK_KP2]) + return (1); + i = SDLK_DOWN; + break; + case SK_HOME: + if (KeyboardDown[SDLK_KP7]) + return (1); + i = SDLK_HOME; + break; + case SK_PAGE_UP: + if (KeyboardDown[SDLK_KP9]) + return (1); + i = SDLK_PAGEUP; + break; + case SK_END: + if (KeyboardDown[SDLK_KP1]) + return (1); + i = SDLK_END; + break; + case SK_PAGE_DOWN: + if (KeyboardDown[SDLK_KP3]) + return (1); + i = SDLK_PAGEDOWN; + break; + case SK_INSERT: + if (KeyboardDown[SDLK_KP0]) + return (1); + i = SDLK_INSERT; + break; + case SK_DELETE: + if (KeyboardDown[SDLK_KP_PERIOD]) + return (1); + i = SDLK_DELETE; + break; + case SK_KEYPAD_PLUS: + i = SDLK_KP_PLUS; + break; + case SK_KEYPAD_MINUS: + i = SDLK_KP_MINUS; + break; + case SK_LF_SHIFT: + i = SDLK_LSHIFT; + break; + case SK_RT_SHIFT: + i = SDLK_RSHIFT; + break; + case SK_CTL: + if (KeyboardDown[SDLK_LCTRL]) + return (1); + i = SDLK_RCTRL; + break; + case SK_ALT: + if (KeyboardDown[SDLK_LALT]) + return (1); + i = SDLK_RALT; + break; + case SK_F1: + case SK_F2: + case SK_F3: + case SK_F4: + case SK_F5: + case SK_F6: + case SK_F7: + case SK_F8: + case SK_F9: + case SK_F10: + case SK_F11: + case SK_F12: + i = (i - SK_F1) + SDLK_F1; + } + } + + return (KeyboardDown[i]); +} + +#endif diff --git a/sc2/src/sc2code/libs/input/sdl/input.h b/sc2/src/sc2code/libs/input/sdl/input.h new file mode 100644 index 000000000..4acf24540 --- /dev/null +++ b/sc2/src/sc2code/libs/input/sdl/input.h @@ -0,0 +1,49 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + + +/**************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*****************************************/ + + +#ifndef INPUT_H +#define INPUT_H + +extern Uint8 KeyboardDown[512]; + +extern UBYTE ControlA; +extern UBYTE ControlB; +extern UBYTE ControlC; +extern UBYTE ControlX; +extern UBYTE ControlStart; +extern UBYTE ControlLeftShift; +extern UBYTE ControlRightShift; + +Uint16 GetUNICODEKey (); +void FlushInput (); +void ProcessKeyboardEvent (const SDL_Event *Event); +void ProcessJoystickEvent (const SDL_Event *Event); + +#endif diff --git a/sc2/src/sc2code/libs/misc.h b/sc2/src/sc2code/libs/misc.h new file mode 100644 index 000000000..a24ed8ff1 --- /dev/null +++ b/sc2/src/sc2code/libs/misc.h @@ -0,0 +1,47 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + +// This file includes some misc things, previously in SDL_wrapper.h +// before modularization. -Mika + +#ifndef MISC_H +#define MISC_H + +#define Stream FILE +#define MEMTYPE_ANY 1 + +extern SEMAPHORE _MemorySem; + +#define SqrtF16 sqrt +#define Atan2F16 atan2 +#define CosF16 cos +#define SinF16 sin + +int CD_get_drive(); // Returns 0 +unsigned int CD_get_volsize(); // Returns 0 + +void OpenMathFolio(); + +extern void *HMalloc (int size); +extern void HFree (void *p); +extern void *HCalloc (int size); +extern void *HRealloc (void *p, int size); + +extern int TFB_DEBUG_HALT; + +#endif diff --git a/sc2/src/sc2code/libs/sound/sdl/Makefile.am b/sc2/src/sc2code/libs/sound/sdl/Makefile.am new file mode 100644 index 000000000..d484033b2 --- /dev/null +++ b/sc2/src/sc2code/libs/sound/sdl/Makefile.am @@ -0,0 +1,13 @@ + +# Automake template file. +# Written by Mudry , protected by GNU GPL. +# CVS $ Id: $ + +INCLUDES = @SDL_CFLAGS@ @SMPEG_CFLAGS@ \ + -I$(top_srcdir)/src \ + -I$(top_srcdir)/src/sc2code \ + -I$(top_srcdir)/src/sc2code/libs + +noinst_LTLIBRARIES = libsdlsound.la +libsdlsound_la_SOURCES = modfuncs.c play.c sound.c trackplayer.c + diff --git a/sc2/src/sc2code/libs/sound/sdl/modfuncs.c b/sc2/src/sc2code/libs/sound/sdl/modfuncs.c new file mode 100644 index 000000000..bbfe70af9 --- /dev/null +++ b/sc2/src/sc2code/libs/sound/sdl/modfuncs.c @@ -0,0 +1,206 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + +#if defined (GFXMODULE_SDL_OPENGL) || defined (GFXMODULE_SDL_PURE) + +#include "libs/strings/strintrn.h" +#include "libs/sound/sndintrn.h" +#ifdef WIN32 +#include +#endif +#include + +#include "libs/graphics/sdl/sdl_common.h" + +MEM_HANDLE +_GetSoundBankData (FILE *fp, DWORD length) +{ +#ifdef WIN32 + int omode; +#endif + int snd_ct, n; + DWORD opos; + char CurrentLine[1024], filename[1024]; +#define MAX_FX 256 + Mix_Chunk *sndfx[MAX_FX]; + STRING_TABLE Snd; + + opos = ftell (fp); + + { + char *s1, *s2; + extern char *_cur_resfile_name; + + if (_cur_resfile_name == 0 + || (((s2 = 0), (s1 = strrchr (_cur_resfile_name, '/')) == 0) + && (s2 = strrchr (_cur_resfile_name, '\\')) == 0)) + n = 0; + else + { + if (s2 > s1) + s1 = s2; + n = s1 - _cur_resfile_name + 1; + strncpy (filename, _cur_resfile_name, n); + } + } + +#ifdef WIN32 + omode = _setmode (fileno (fp), O_TEXT); +#endif + snd_ct = 0; + while (fgets (CurrentLine, sizeof (CurrentLine), fp) && snd_ct < MAX_FX) + { + if + ( + sscanf(CurrentLine, "%s", &filename[n]) == 1 && + (sndfx[snd_ct] = Mix_LoadWAV (filename)) + ) + { + ++snd_ct; + } + else + { + printf("_GetSoundBankData: Bad file!\n"); + } + + if (ftell (fp) - opos >= length) + break; + } +#ifdef WIN32 + _setmode (fileno (fp), omode); +#endif + + Snd = 0; + if (snd_ct && (Snd = AllocStringTable ( + sizeof (STRING_TABLE_DESC) + + (sizeof (DWORD) * snd_ct) + + (sizeof (sndfx[0]) * snd_ct) + ))) + { + STRING_TABLEPTR fxTab; + + LockStringTable (Snd, &fxTab); + if (fxTab == 0) + { + while (snd_ct--) + Mix_FreeChunk (sndfx[snd_ct]); + FreeStringTable (Snd); + Snd = 0; + } + else + { + DWORD *offs, StringOffs; + + fxTab->StringCount = snd_ct; + fxTab->flags = 0; + offs = fxTab->StringOffsets; + StringOffs = sizeof (STRING_TABLE_DESC) + (sizeof (DWORD) * snd_ct); + memcpy ((BYTE *)fxTab + StringOffs, sndfx, sizeof (sndfx[0]) * snd_ct); + do + { + *offs++ = StringOffs; + StringOffs += sizeof (sndfx[0]); + } while (snd_ct--); + UnlockStringTable (Snd); + } + } + + return ((MEM_HANDLE)Snd); +} + +BOOLEAN +_ReleaseSoundBankData (MEM_HANDLE Snd) +{ + STRING_TABLEPTR fxTab; + + LockStringTable (Snd, &fxTab); + if (fxTab) + { + int snd_ct; + Mix_Chunk **sptr; + + snd_ct = fxTab->StringCount; + sptr = (Mix_Chunk **)((BYTE *)fxTab + fxTab->StringOffsets[0]); + while (snd_ct--) + { + Mix_FreeChunk (*sptr); + *sptr++ = 0; + } + UnlockStringTable (Snd); + FreeStringTable (Snd); + + return (TRUE); + } + + return (FALSE); +} + +MEM_HANDLE +_GetMusicData (FILE *fp, DWORD length) +{ + MEM_HANDLE h; + extern char *_cur_resfile_name; + + h = 0; + if (_cur_resfile_name && (h = AllocMusicData (sizeof (void *)))) + { + Mix_Music **pmus; + + LockMusicData (h, &pmus); + if (pmus == 0 || (*pmus = Mix_LoadMUS (_cur_resfile_name)) == 0) + { + UnlockMusicData (h); + mem_release (h); + h = 0; + } + else + { + // + } + UnlockMusicData (h); + } + + (void) fp; /* satisfy compiler (unused parameter) */ + (void) length; /* satisfy compiler (unused parameter) */ + return (h); +} + +BOOLEAN +_ReleaseMusicData (MEM_HANDLE handle) +{ + Mix_Music **pmus; + + LockMusicData (handle, &pmus); + if (pmus == 0) + return (FALSE); + + Mix_FreeMusic (*pmus); + + UnlockMusicData (handle); + mem_release (handle); + + return (TRUE); +} + +BOOLEAN +DestroySound(SOUND_REF target) +{ + return (_ReleaseSoundBankData (target)); +} + +#endif diff --git a/sc2/src/sc2code/libs/sound/sdl/play.c b/sc2/src/sc2code/libs/sound/sdl/play.c new file mode 100644 index 000000000..ad479cb92 --- /dev/null +++ b/sc2/src/sc2code/libs/sound/sdl/play.c @@ -0,0 +1,95 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + +#if defined (GFXMODULE_SDL_OPENGL) || defined (GFXMODULE_SDL_PURE) + +#include "libs/sound/sndintrn.h" +#include "timlib.h" + +#include "libs/graphics/sdl/sdl_common.h" + +static MUSIC_REF curMusicRef; + +void +PLRPlaySong (MUSIC_REF MusicRef, BOOLEAN Continuous, BYTE Priority) +{ + Mix_Music **pmus; + + LockMusicData (MusicRef, &pmus); + if (pmus) + { + PLRStop (curMusicRef); + + curMusicRef = MusicRef; + Mix_PlayMusic (*pmus, Continuous ? -1 : 1); + } + (void) Priority; /* Satisfy compiler because of unused variable */ +} + +void +PLRStop (MUSIC_REF MusicRef) +{ + if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0) + { + Mix_HaltMusic (); + + UnlockMusicData (curMusicRef); + curMusicRef = 0; + } +} + +BOOLEAN +PLRPlaying (MUSIC_REF MusicRef) +{ + if (curMusicRef && (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0)) + { + if (Mix_PlayingMusic ()) + return (TRUE); + PLRStop (curMusicRef); + } + + return (FALSE); +} + +void +PLRPause (MUSIC_REF MusicRef) +{ + if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0) + { +// Mix_FadeOutMusic (1 * 1000); + Mix_PauseMusic (); + } +} + +void +PLRResume (MUSIC_REF MusicRef) +{ + if (MusicRef == curMusicRef || MusicRef == (MUSIC_REF)~0) + { +// Mix_FadeInMusic (1 * 1000); + Mix_ResumeMusic (); + } +} + +BOOLEAN +DestroyMusic (MUSIC_REF MusicRef) +{ + return (FreeMusicData (MusicRef)); +} + +#endif diff --git a/sc2/src/sc2code/libs/sound/sdl/sound.c b/sc2/src/sc2code/libs/sound/sdl/sound.c new file mode 100644 index 000000000..d544847b8 --- /dev/null +++ b/sc2/src/sc2code/libs/sound/sdl/sound.c @@ -0,0 +1,187 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + + +/**************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*****************************************/ + +#if defined (GFXMODULE_SDL_OPENGL) || defined (GFXMODULE_SDL_PURE) + +#include "libs/graphics/sdl/sdl_common.h" + +//Status: Unimplemented +void +StopSound() + // So does this stop ALL sound? How about music? +{ + Mix_HaltChannel (-1); +} + +int _music_volume = (MAX_VOLUME + 1) >> 1; + +// Status: Unimplemented +void +SetMusicVolume(COUNT Volume) //Volume calibration... [0,255]? +{ + Mix_VolumeMusic ((_music_volume = Volume) * SDL_MIX_MAXVOLUME / + MAX_VOLUME); +} + +//Status: Unimplemented +BOOLEAN +SoundPlaying() +{ + return (Mix_Playing (-1) != 0); +} + +int +GetSoundData(char* data) //Returns the data size. +{ + int ret; + + printf("Unimplemented function activated: GetSoundData()\n"); + ret = 0; + return (ret); +} + +// Status: Unimplemented +int +GetSoundInfo(int* length, int* offset) + // Umm... How does it know which sound? +{ + int ret; + + printf ("Unimplemented function activated: GetSoundInfo()\n"); + ret = 0; + return (ret); +} + +// Status: Unimplemented +BOOLEAN +ChannelPlaying(COUNT WhichChannel) + // SDL will have a nice interface for this, I hope. +{ + // printf("Unimplemented function activated: ChannelPlaying()\n"); + return ((BOOLEAN) Mix_Playing (WhichChannel)); +} + +// Status: Unimplemented +void +PlayChannel( + COUNT channel, + PVOID sample, + COUNT sample_length, + COUNT loop_begin, + COUNT loop_length, + unsigned char priority +) // This one's important. +{ + Mix_Chunk* Chunk; + + Chunk=*(Mix_Chunk**)sample; + Mix_PlayChannel ( + channel, //-1 would be easiest + Chunk, + 0 + ); +} + +//Status: Unimplemented +void +StopChannel(COUNT channel, unsigned char Priority) // Easy w/ SDL. +{ + Mix_HaltChannel (channel); +} + +// Status: Maybe Implemented +PBYTE +GetSampleAddress (SOUND sound) + // I might be prototyping this wrong, type-wise. +{ + return ((PBYTE)GetSoundAddress (sound)); +} + +// Status: Unimplemented +COUNT +GetSampleLength (SOUND sound) +{ + COUNT ret; + Mix_Chunk *Chunk; + + Chunk = (Mix_Chunk *) sound; + ret = 0; // Chunk->alen; + +// printf ("Maybe Implemented function activated: GetSampleLength()\n"); + return(ret); +} + +// Status: Unimplemented +void +SetChannelRate (COUNT channel, DWORD rate_hz, unsigned char priority) + // in hz +{ +// printf ("Unimplemented function activated: SetChannelRate()\n"); +} + +// Status: Unimplemented +COUNT +GetSampleRate (SOUND sound) +{ + COUNT ret; + +// printf("Unimplemented function activated: GetSampleRate()\n"); + ret=0; + return(ret); +} + +// Status: Unimplemented +void +SetChannelVolume (COUNT channel, COUNT volume, BYTE priority) + // I wonder what this whole priority business is... + // I can probably ignore it. +{ +// printf ("Unimplemented function activated: SetChannelVolume()\n"); +} + +//Status: Ignored +BOOLEAN +InitSound (int argc, char* argv[]) + // Odd things to pass the InitSound function... +{ + BOOLEAN ret; + +// printf("Unimplemented function activated: InitSound()\n"); + ret = TRUE; + return (ret); +} + +// Status: Unimplemented +void +UninitSound () //Maybe I should call StopSound() first? +{ + //printf("Unimplemented function activated: UninitSound()\n"); +} + +#endif diff --git a/sc2/src/sc2code/libs/sound/sdl/trackplayer.c b/sc2/src/sc2code/libs/sound/sdl/trackplayer.c new file mode 100644 index 000000000..5dfecf3e1 --- /dev/null +++ b/sc2/src/sc2code/libs/sound/sdl/trackplayer.c @@ -0,0 +1,199 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + + + +/**************************************** + + Star Control II: 3DO => SDL Port + + Copyright Toys for Bob, 2002 + + Programmer: Chris Nelson + +*****************************************/ + +#if defined (GFXMODULE_SDL_OPENGL) || defined (GFXMODULE_SDL_PURE) + +#include "libs/graphics/sdl/sdl_common.h" +#include "libs/sound/trackplayer.h" + +#define VOICE_CHANNEL 0 + +extern int do_subtitles (UNICODE *pStr); + +static int tct, tcur, no_voice; +#define MAX_CLIPS 50 +static struct +{ + int text_spliced; + Mix_Chunk *chunk; + UNICODE *text; +} track_clip[MAX_CLIPS]; + +void +JumpTrack (int abort) +{ + Mix_ChannelFinished (0); + + if (track_clip[tcur].chunk) + Mix_HaltChannel (VOICE_CHANNEL); + + no_voice = 1; + do_subtitles ((void *)~0); + + if (abort) + tcur = tct; +} + +static void +advance_track (int channel_finished) +{ + if (channel_finished <= VOICE_CHANNEL) + { + if (channel_finished == VOICE_CHANNEL) + ++tcur; + if (tcur < tct) + { + Mix_PlayChannel (VOICE_CHANNEL, track_clip[tcur].chunk, 0); + do_subtitles (0); + } + else if (channel_finished == VOICE_CHANNEL) + { + --tcur; + no_voice = 1; + } + } +} + +void +ResumeTrack () +{ + if (tcur < tct) + { + if (Mix_Playing /* Mix_Paused */ (VOICE_CHANNEL)) + Mix_Resume (VOICE_CHANNEL); + else if (!no_voice) + { + if (tcur == 0) + Mix_ChannelFinished (advance_track); + advance_track (-1); + } + } +} + +COUNT +PlayingTrack () +{ + if (tcur < tct) + { + if (do_subtitles (track_clip[tcur].text) + || (no_voice && ++tcur < tct && do_subtitles (0))) + return (tcur + 1); + else if (track_clip[tcur].chunk) + return (Mix_Playing (VOICE_CHANNEL) ? (COUNT)(tcur + 1) : 0); + } + + return (0); +} + +void +StopTrack () +{ + Mix_ChannelFinished (0); + Mix_HaltChannel (VOICE_CHANNEL); + + while (tct--) + { + if (track_clip[tct].text_spliced) + { + track_clip[tct].text_spliced = 0; + HFree (track_clip[tct].text); + track_clip[tct].text = 0; + } + if (track_clip[tct].chunk) + { + Mix_FreeChunk (track_clip[tct].chunk); + track_clip[tct].chunk = 0; + } + } + tct = tcur = 0; + no_voice = 0; + do_subtitles (0); +} + +void +SpliceTrack (UNICODE *TrackName, UNICODE *TrackText) +{ + if (TrackText) + { + if (TrackName == 0) + { + if (tct) + { + int slen1, slen2; + UNICODE *oTT; + + oTT = track_clip[tct - 1].text; + slen1 = wstrlen (oTT); + slen2 = wstrlen (TrackText); + if (track_clip[tct - 1].text_spliced) + track_clip[tct - 1].text = HRealloc (oTT, slen1 + slen2 + 1); + else + { + track_clip[tct - 1].text = HMalloc (slen1 + slen2 + 1); + wstrcpy (track_clip[tct - 1].text, oTT); + track_clip[tct - 1].text_spliced = 1; + } + wstrcpy (&track_clip[tct - 1].text[slen1], TrackText); + } + } + else if (tct < MAX_CLIPS) + { + track_clip[tct].text = TrackText; + track_clip[tct].chunk = Mix_LoadWAV (TrackName); + track_clip[tct].text_spliced = 0; + ++tct; + } + } +} + +void +PauseTrack () +{ + if (tcur < tct && track_clip[tcur].chunk) + Mix_Pause (VOICE_CHANNEL); +} + +void +FastReverse () +{ + JumpTrack (0); + no_voice = 0; + tcur = 0; + ResumeTrack (); +} + +void +FastForward () +{ + JumpTrack (0); +// no_voice = 0; +} + +#endif diff --git a/sc2/src/sc2code/libs/sound/sound_common.c b/sc2/src/sc2code/libs/sound/sound_common.c new file mode 100644 index 000000000..2af4df58d --- /dev/null +++ b/sc2/src/sc2code/libs/sound/sound_common.c @@ -0,0 +1,79 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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. + */ + +#include "libs/graphics/gfx_common.h" + +extern int _music_volume; + +static TASK FadeTask; +static SIZE TTotal; +static SIZE volume_end; + +static int +fade_task (void *data) +{ + SIZE TDelta, volume_beg; + DWORD StartTime, CurTime; + + volume_beg = _music_volume; + StartTime = CurTime = GetTimeCounter (); + do + { + CurTime = SleepTask (CurTime + 1); + if ((TDelta = (SIZE) (CurTime - StartTime)) > TTotal) + TDelta = TTotal; + + SetMusicVolume ((COUNT) (volume_beg + (SIZE) + ((long) (volume_end - volume_beg) * TDelta / TTotal))); + } while (TDelta < TTotal); + + FadeTask = 0; + return (1); +} + +DWORD +FadeMusic (BYTE end_vol, SIZE TimeInterval) +{ + DWORD TimeOut; + + if (FadeTask) + { + volume_end = _music_volume; + TTotal = 1; + do + TaskSwitch (); + while (FadeTask); + TaskSwitch (); + } + + if ((TTotal = TimeInterval) <= 0) + TTotal = 1; /* prevent divide by zero and negative fade */ + volume_end = end_vol; + + if (TTotal > 1 && (FadeTask = AddTask (fade_task, 0))) + { + TimeOut = GetTimeCounter () + TTotal + 1; + } + else + { + SetMusicVolume (end_vol); + TimeOut = GetTimeCounter (); + } + + return (TimeOut); +} diff --git a/sc2/src/sc2code/libs/sound/trackplayer.h b/sc2/src/sc2code/libs/sound/trackplayer.h new file mode 100644 index 000000000..42f243060 --- /dev/null +++ b/sc2/src/sc2code/libs/sound/trackplayer.h @@ -0,0 +1,33 @@ +//Copyright Paul Reiche, Fred Ford. 1992-2002 + +/* + * 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 TRACKPLAYER_H +#define TRACKPLAYER_H + +void ResumeTrack(); +void PauseTrack(); +COUNT PlayingTrack(); +void JumpTrack(int abort); +void FastForward(); +void FastReverse(); +void StopTrack(); +void SpliceTrack(UNICODE *filespec, UNICODE *textspec); +int GetSoundData(char *data); +int GetSoundInfo (int *len, int *offs); + +#endif