diff --git a/sc2/src/msvc++/Starcon2.dsp b/sc2/src/msvc++/Starcon2.dsp index 5ef5d40ca..79733a9b0 100644 --- a/sc2/src/msvc++/Starcon2.dsp +++ b/sc2/src/msvc++/Starcon2.dsp @@ -223,6 +223,14 @@ SOURCE=..\sc2code\libs\graphics\gfx_common.c SOURCE=..\sc2code\libs\graphics\gfx_common.h # End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\cmap.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\cmap.h +# End Source File # Begin Group "sdl" # PROP Default_Filter "" diff --git a/sc2/src/sc2code/comm.c b/sc2/src/sc2code/comm.c index 0cd545554..fafc55f4b 100644 --- a/sc2/src/sc2code/comm.c +++ b/sc2/src/sc2code/comm.c @@ -387,9 +387,8 @@ int xform_PLUT_task(void* blah) CurTime = GetTimeCounter (); do { -#define NUMBER_OF_PLUTVALS 32 -#define NUMBER_OF_PLUT_UINT32s (NUMBER_OF_PLUTVALS >> 1) -#define PLUT_BYTE_SIZE (sizeof (DWORD) * NUMBER_OF_PLUT_UINT32s) +//#define NUMBER_OF_PLUTVALS 32 +//#define NUMBER_OF_PLUT_UINT32s (NUMBER_OF_PLUTVALS >> 1) BYTE i; DWORD StartTime; DWORD *pCurCMap; diff --git a/sc2/src/sc2code/libs/graphics/Makefile.am b/sc2/src/sc2code/libs/graphics/Makefile.am index 786ef6dcc..273a36018 100644 --- a/sc2/src/sc2code/libs/graphics/Makefile.am +++ b/sc2/src/sc2code/libs/graphics/Makefile.am @@ -16,11 +16,13 @@ noinst_LTLIBRARIES = libgraphics.la libgraphics_la_SOURCES = clipline.c context.c drawable.c filegfx.c font.c \ frame.c intersec.c line.c loaddisp.c makepoly.c map.c \ - pixmap.c poly.c rect.c resgfx.c stamp.c boxint.c gfx_common.c + pixmap.c poly.c rect.c resgfx.c stamp.c boxint.c gfx_common.c \ + cmap.c libgraphics_la_LIBADD = sdl/libsdl.la #libgraphics_la_LDFLAGS = @SMPEG_LIBS@ -noinst_HEADERS = context.h display.h drawable.h font.h gfxintrn.h gfx_common.h +noinst_HEADERS = context.h display.h drawable.h font.h gfxintrn.h \ + gfx_common.h cmap.h diff --git a/sc2/src/sc2code/libs/graphics/cmap.c b/sc2/src/sc2code/libs/graphics/cmap.c new file mode 100644 index 000000000..eecbf99ad --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/cmap.c @@ -0,0 +1,312 @@ +//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 "gfx_common.h" + + +static struct +{ + COLORMAPPTR CMapPtr; + SIZE Ticks; + union + { + COUNT NumCycles; + TASK XFormTask; + } tc; +} TaskControl; + + +DWORD* _varPLUTs; +static unsigned int varPLUTsize = VARPLUTS_SIZE; +UBYTE _batch_flags; + + +UBYTE *current_colormap; +int current_colormap_size; + + +// Status: Implemented +BOOLEAN +BatchColorMap (COLORMAPPTR ColorMapPtr) +{ + return (SetColorMap (ColorMapPtr)); +} + +// Status: Partially implemented +BOOLEAN +SetColorMap (COLORMAPPTR map) +{ + int start, end, bytes; + UBYTE *colors = (UBYTE*)map; + UBYTE *vp; + + if (!map) + return TRUE; + + start = *colors++; + end = *colors++; + if (start > end) + return TRUE; + + bytes = (end - start + 1) * PLUT_BYTE_SIZE; + + if (!_varPLUTs) + { + if (!(_varPLUTs = (unsigned int*) HMalloc (bytes))) + return TRUE; + varPLUTsize = bytes; + } + + vp = (UBYTE*)_varPLUTs + (start * PLUT_BYTE_SIZE); + + memcpy (vp, colors, bytes); + + current_colormap = vp; + current_colormap_size = bytes; + + //printf("SetColorMap(): vp %x map %x bytes %d\n",vp, map, bytes); + return TRUE; +} + +void +_threedo_set_colors (UBYTE *colors, unsigned int indices) +{ + int i, start, end; + //unsigned int *ce; + + start = (int)LOBYTE (indices); + end = (int)HIBYTE (indices); + + //ce = colorEntries; + for (i = start; i <= end; i++) + { + UBYTE r, g, b; + + r = (*colors << 2) | (*colors >> 4); + ++colors; + g = (*colors << 2) | (*colors >> 4); + ++colors; + b = (*colors << 2) | (*colors >> 4); + ++colors; + + //*ce++ = MakeCLUTColorEntry (i, r, g, b); + } + + //ceCt = end - start + 1; + + //_threedo_add_task (TASK_SET_CLUT); + //_batch_flags |= CYCLE_PENDING; +} + +static int +color_cycle (void *foo) +{ + UWORD color_beg, color_len, color_indices; + COUNT Cycles, CycleCount; + DWORD TimeIn, SleepTicks; + COLORMAPPTR BegMapPtr, CurMapPtr; + + Cycles = CycleCount = TaskControl.tc.NumCycles; + BegMapPtr = TaskControl.CMapPtr; + SleepTicks = TaskControl.Ticks; + + color_indices = MAKE_WORD (BegMapPtr[0], BegMapPtr[1]); + color_beg = *BegMapPtr++ * 3; + color_len = (*BegMapPtr++ + 1) * 3 - color_beg; + CurMapPtr = BegMapPtr; + + TaskControl.CMapPtr = 0; + TimeIn = GetTimeCounter (); + for (;;) + { + //_threedo_set_colors (CurMapPtr, color_indices); + + if (--Cycles) + CurMapPtr += color_len + sizeof (BYTE) * 2; + else + { + Cycles = CycleCount; + CurMapPtr = BegMapPtr; + } + + TimeIn = SleepTask (TimeIn + SleepTicks); + + if (TaskControl.CMapPtr) + { + TaskControl.CMapPtr = (COLORMAPPTR)0; + for (;;) + TaskSwitch (); + } + } +} + +CYCLE_REF +CycleColorMap (COLORMAPPTR ColorMapPtr, COUNT Cycles, SIZE TimeInterval) +{ + if (ColorMapPtr && Cycles && ColorMapPtr[0] <= ColorMapPtr[1]) + { + TASK T; + + while (TaskControl.CMapPtr) + { + TaskSwitch (); + } + + TaskControl.CMapPtr = ColorMapPtr; + TaskControl.tc.NumCycles = Cycles; + if ((TaskControl.Ticks = TimeInterval) <= 0) + TaskControl.Ticks = 1; + + if (T = AddTask (color_cycle, 0)) + { + _batch_flags |= ENABLE_CYCLE; + do + TaskSwitch (); + while (TaskControl.CMapPtr); + } + TaskControl.CMapPtr = 0; + + return ((CYCLE_REF)T); + } + + return (0); +} + +void +StopCycleColorMap (CYCLE_REF CycleRef) +{ + TASK T; + + if (T = (TASK)CycleRef) + { + TaskControl.CMapPtr = (COLORMAPPTR)1; + while (TaskControl.CMapPtr) + TaskSwitch (); + + _batch_flags &= ~ENABLE_CYCLE; + DeleteTask (T); + } +} + +#define NO_INTENSITY 0x00 +#define NORMAL_INTENSITY 0xff +#define FULL_INTENSITY (0xff * 32) + +static int cur = NORMAL_INTENSITY, end, XForming; + +static +int xform_clut_task (void *foo) +{ + TASK T; + SIZE TDelta, TTotal; + DWORD CurTime; + + XForming = TRUE; + while ((T = TaskControl.tc.XFormTask) == 0) + TaskSwitch (); + TTotal = TaskControl.Ticks; + TaskControl.tc.XFormTask = 0; + + { + CurTime = GetTimeCounter (); + do + { + DWORD StartTime; + + StartTime = CurTime; + CurTime = SleepTask (CurTime + 2); + if (!XForming || (TDelta = (SIZE)(CurTime - StartTime)) > TTotal) + TDelta = TTotal; + + cur += (end - cur) * TDelta / TTotal; + //_threedo_change_clut (cur); + } while (TTotal -= TDelta); + } + + XForming = FALSE; + DeleteTask (T); + + return 0; +} + +//Status: Partially implemented +DWORD +XFormColorMap (COLORMAPPTR ColorMapPtr, SIZE TimeInterval) +{ + BYTE what; + DWORD TimeOut; + + //printf ("Partially implemented function activated: XFormColorMap()\n"); + + + FlushColorXForms (); + + if (ColorMapPtr == (COLORMAPPTR)0) + return (0); + + switch (what = *ColorMapPtr) + { + case FadeAllToBlack: + case FadeSomeToBlack: + end = NO_INTENSITY; + break; + case FadeAllToColor: + case FadeSomeToColor: + end = NORMAL_INTENSITY; + break; + case FadeAllToWhite: + case FadeSomeToWhite: + end = FULL_INTENSITY; + break; + default: + return (GetTimeCounter ()); + } + + //if (what == FadeAllToBlack || what == FadeAllToWhite || what == FadeAllToColor) + //_threedo_enable_fade (); + + if ((TaskControl.Ticks = TimeInterval) <= 0 + || (TaskControl.tc.XFormTask = AddTask (xform_clut_task, 1024)) == 0) + { + //_threedo_change_clut (end); + TimeOut = GetTimeCounter (); + } + else + { + do + TaskSwitch (); + while (TaskControl.tc.XFormTask); + + TimeOut = GetTimeCounter () + TimeInterval + 1; + } + + return (TimeOut); +} + +//Status: Implemented +void +FlushColorXForms() +{ + if (XForming) + { + XForming = FALSE; + TaskSwitch (); + } + + //printf ("Partially implemented function activated: FlushColorXForms()\n"); +} diff --git a/sc2/src/sc2code/libs/graphics/cmap.h b/sc2/src/sc2code/libs/graphics/cmap.h new file mode 100644 index 000000000..e5c9cfc07 --- /dev/null +++ b/sc2/src/sc2code/libs/graphics/cmap.h @@ -0,0 +1,53 @@ +//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 CMAP_H +#define CMAP_H + +#define NUMBER_OF_VARPLUTS 256 +#define NUMBER_OF_PLUTVALS 32 +#define NUMBER_OF_PLUT_UINT32s (NUMBER_OF_PLUTVALS >> 1) +#define PLUT_BYTE_SIZE (sizeof (unsigned int) * NUMBER_OF_PLUT_UINT32s) +#define NUMBER_OF_CLUTVALS 32 +#define VARPLUTS_SIZE (NUMBER_OF_VARPLUTS * NUMBER_OF_PLUT_UINT32s * sizeof (unsigned int)) +#define GET_VAR_PLUT(i) (_varPLUTs + (i) * NUMBER_OF_PLUT_UINT32s) + +#define BUILD_FRAME (1 << 0) +#define FIND_PAGE (1 << 1) +#define FIRST_BATCH (1 << 2) +#define GRAB_OTHER (1 << 3) +#define COLOR_CYCLE (1 << 4) +#define CYCLE_PENDING (1 << 5) +#define ENABLE_CYCLE (1 << 6) + +/*enum +{ + FadeAllToWhite = 250, + FadeSomeToWhite, + FadeAllToBlack, + FadeAllToColor, + FadeSomeToBlack, + FadeSomeToColor +};*/ + +extern UBYTE _batch_flags; + +extern UBYTE *current_colormap; +extern int current_colormap_size; + +#endif diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.c b/sc2/src/sc2code/libs/graphics/gfx_common.c index 9c48cb800..20412f08c 100644 --- a/sc2/src/sc2code/libs/graphics/gfx_common.c +++ b/sc2/src/sc2code/libs/graphics/gfx_common.c @@ -20,10 +20,6 @@ #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[]) @@ -35,5 +31,4 @@ int ScreenHeight; int ScreenWidthActual; int ScreenHeightActual; int GraphicsDriver; - int TFB_DEBUG_HALT; diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.h b/sc2/src/sc2code/libs/graphics/gfx_common.h index d203a6bd0..2437ed61b 100644 --- a/sc2/src/sc2code/libs/graphics/gfx_common.h +++ b/sc2/src/sc2code/libs/graphics/gfx_common.h @@ -19,10 +19,6 @@ #ifndef GFX_COMMON_H #define GFX_COMMON_H -#ifdef WIN32 -#pragma warning (disable:4244) /* Disable bogus conversion warnings. */ -#endif - #include #include #include @@ -31,6 +27,7 @@ #include "libs/gfxlib.h" #include "libs/vidlib.h" #include "libs/misc.h" +#include "cmap.h" #define TFB_WINDOW_CAPTION "The Ur-Quan Masters" @@ -45,6 +42,8 @@ enum #define TFB_GFXFLAGS_FULLSCREEN (1<<0) #define TFB_GFXFLAGS_BILINEAR_FILTERING (1<<1) #define TFB_GFXFLAGS_SHOWFPS (1<<2) +#define TFB_GFXFLAGS_TVEFFECT (1<<3) + int TFB_InitGraphics (int driver, int flags, int width, int height, int bpp); int TFB_CreateGamePlayThread (); @@ -87,6 +86,14 @@ enum TFB_DRAWCOMMANDTYPE_DELETEIMAGE, }; +typedef struct tfb_palette +{ + UBYTE r; + UBYTE g; + UBYTE b; + UBYTE unused; +} TFB_Palette; + typedef struct tfb_drawcommand { int Type; @@ -94,11 +101,12 @@ typedef struct tfb_drawcommand int y; int w; int h; - TFB_ImageStruct *image; // only used for image draw type - int r; // RGB only used for rect draw types + TFB_ImageStruct *image; + int r; int g; int b; - int Qualifier; + TFB_Palette Palette[256]; + BOOLEAN UsePalette; } TFB_DrawCommand; // Queue Stuff diff --git a/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c b/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c index 817975e04..41f8d8a02 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c @@ -39,8 +39,7 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) img = (TFB_Image *) ((BYTE *) SrcFramePtr + SrcFramePtr->DataOffs); - if (SDL_mutexP(img->mutex)) - printf("blt(): couldn't lock img->mutex\n"); + SDL_mutexP (img->mutex); if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE) { @@ -54,8 +53,8 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) GetFrameHotX (_CurFramePtr); DrawCommand->y = pClipRect->corner.y - GetFrameHotY (_CurFramePtr); - DrawCommand->w = img->SurfaceSDL->clip_rect.w; - DrawCommand->h = img->SurfaceSDL->clip_rect.h; + DrawCommand->w = img->NormalImg->clip_rect.w; + DrawCommand->h = img->NormalImg->clip_rect.h; if (gscale != 0 && gscale != 256) { @@ -81,29 +80,37 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) // NOTE: Planet surfaces maybe causes memory leaks, // I haven't currently seen DELETEIMAGE executed to them at all. - // Also, we might want to change the way they are implemented, as - // currently the scaled img is like 1936x600x32bit so it takes - // much memory and is perhaps too slow to process on slower systems. - // -Mika SDL_Surface *new_surf; img->scale = gscale; - new_surf = zoomSurface (img->DrawableImg, gscale / 256.0f, + new_surf = zoomSurface (img->NormalImg, gscale / 256.0f, gscale / 256.0f, SMOOTHING_OFF); if (new_surf) { - img->ScaledImg = TFB_DisplayFormatAlpha (new_surf); - - if (img->ScaledImg) + if (new_surf->format->BytesPerPixel > 1) { - SDL_FreeSurface(new_surf); + img->ScaledImg = TFB_DisplayFormatAlpha (new_surf); + if (img->ScaledImg) + { + SDL_FreeSurface(new_surf); + } + else + { + printf("blt(): TFB_DisplayFormatAlpha failed\n"); + img->ScaledImg = new_surf; + } } else { - printf("blt(): TFB_DisplayFormatAlpha failed\n"); img->ScaledImg = new_surf; + SDL_SetColors (img->ScaledImg, img->Palette, 0, 256); + if (img->NormalImg->flags & SDL_SRCCOLORKEY) + { + SDL_SetColorKey (img->ScaledImg, SDL_SRCCOLORKEY, + img->NormalImg->format->colorkey); + } } } else @@ -117,17 +124,65 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) if (GetPrimType (PrimPtr) == STAMPFILL_PRIM) { + int i; DWORD c32k; c32k = GetPrimColor (PrimPtr) >> 8; // shift out color index DrawCommand->r = (c32k >> (10 - (8 - 5))) & 0xF8; DrawCommand->g = (c32k >> (5 - (8 - 5))) & 0xF8; - DrawCommand->b = (c32k << (8 - 5)); + DrawCommand->b = (c32k << (8 - 5)) & 0xF8; + + for (i = 0; i < 256; ++i) + { + DrawCommand->Palette[i].r = DrawCommand->r; + DrawCommand->Palette[i].g = DrawCommand->g; + DrawCommand->Palette[i].b = DrawCommand->b; + } + + DrawCommand->UsePalette = TRUE; + } + else + { + DrawCommand->UsePalette = FALSE; + + // NOTE: following code for colormaps is experimental + if (img->NormalImg->format->BytesPerPixel == 1) + { + if (current_colormap && current_colormap_size <= 512) + { + int i, n; + SDL_Color *imgpal; + SDL_Color cmap_rgb[256]; + + n = TFB_ColorMapToRGB (cmap_rgb); + + //printf("draw cmap %x, size %d, n %d, imgw %d imgh %d\n",current_colormap, current_colormap_size, n, img->NormalImg->w, img->NormalImg->h); + + imgpal = img->NormalImg->format->palette->colors; + for (i = 0; i < 256; ++i) + { + DrawCommand->Palette[i].r = imgpal[i].r; + DrawCommand->Palette[i].g = imgpal[i].g; + DrawCommand->Palette[i].b = imgpal[i].b; + } + + for (i = 0; i < n; ++i) + { + DrawCommand->Palette[252 - i].r = cmap_rgb[n - i - 1].r; + DrawCommand->Palette[252 - i].g = cmap_rgb[n - i - 1].g; + DrawCommand->Palette[252 - i].b = cmap_rgb[n - i - 1].b; + } + + DrawCommand->UsePalette = TRUE; + } + } } - DrawCommand->Qualifier = (TYPE_GET (GetFrameParentDrawable ( + current_colormap = 0; + + /*DrawCommand->Qualifier = (TYPE_GET (GetFrameParentDrawable ( SrcFramePtr)->FlagsAndIndex) >> FTYPE_SHIFT) & - MAPPED_TO_DISPLAY; + MAPPED_TO_DISPLAY;*/ TFB_EnqueueDrawCommand(DrawCommand); } @@ -139,13 +194,12 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) dst_img = ((TFB_Image *) ((BYTE *) _CurFramePtr + _CurFramePtr->DataOffs)); - if (SDL_mutexP(dst_img->mutex)) - printf("blt(): couldn't lock dst_img->mutex\n"); + SDL_mutexP (dst_img->mutex); - SDL_SrcRect.x = (short) img->SurfaceSDL->clip_rect.x; - SDL_SrcRect.y = (short) img->SurfaceSDL->clip_rect.y; - SDL_SrcRect.w = (short) img->SurfaceSDL->clip_rect.w; - SDL_SrcRect.h = (short) img->SurfaceSDL->clip_rect.h; + SDL_SrcRect.x = (short) img->NormalImg->clip_rect.x; + SDL_SrcRect.y = (short) img->NormalImg->clip_rect.y; + SDL_SrcRect.w = (short) img->NormalImg->clip_rect.w; + SDL_SrcRect.h = (short) img->NormalImg->clip_rect.h; SDL_DstRect.x = (short) pClipRect->corner.x - GetFrameHotX (_CurFramePtr) + SDL_SrcRect.x; @@ -153,32 +207,28 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) GetFrameHotY (_CurFramePtr) + SDL_SrcRect.y; SDL_BlitSurface ( - img->SurfaceSDL, // src - &SDL_SrcRect, // src rect - dst_img->SurfaceSDL, - &SDL_DstRect // dst rect + img->NormalImg, + &SDL_SrcRect, + dst_img->NormalImg, + &SDL_DstRect ); - - dst_img->dirty = TRUE; - if (SDL_mutexV(dst_img->mutex)) - printf("blt(): couldn't unlock dst_img->mutex\n"); + SDL_mutexV (dst_img->mutex); } - if (SDL_mutexV(img->mutex)) - printf("blt(): couldn't unlock img->mutex\n"); + SDL_mutexV (img->mutex); } static void fillrect_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) { - BYTE r, g, b; + int r, g, b; DWORD c32k; c32k = GetPrimColor (PrimPtr) >> 8; //shift out color index r = (c32k >> (10 - (8 - 5))) & 0xF8; g = (c32k >> (5 - (8 - 5))) & 0xF8; - b = (c32k << (8 - 5)); + b = (c32k << (8 - 5)) & 0xF8; if (TYPE_GET (_CurFramePtr->TypeIndexAndFlags) == SCREEN_DRAWABLE) { @@ -207,6 +257,7 @@ fillrect_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) } DrawCommand->image = 0; + DrawCommand->UsePalette = FALSE; TFB_EnqueueDrawCommand(DrawCommand); } @@ -219,8 +270,7 @@ fillrect_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) img = ((TFB_Image *) ((BYTE *) _CurFramePtr + _CurFramePtr->DataOffs)); - if (SDL_mutexP(img->mutex)) - printf("fillrect_blt(): couldn't lock img->mutex\n"); + SDL_mutexP (img->mutex); SDLRect.x = (short) (pClipRect->corner.x - GetFrameHotX (_CurFramePtr)); @@ -229,12 +279,9 @@ fillrect_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) SDLRect.w = (short) pClipRect->extent.width; SDLRect.h = (short) pClipRect->extent.height; - SDL_FillRect (img->SurfaceSDL, &SDLRect, SDL_MapRGB (img->SurfaceSDL->format, r, g, b)); + SDL_FillRect (img->NormalImg, &SDLRect, SDL_MapRGB (img->NormalImg->format, r, g, b)); - img->dirty = TRUE; - - if (SDL_mutexV(img->mutex)) - printf("fillrect_blt(): couldn't unlock img->mutex\n"); + SDL_mutexV (img->mutex); } } @@ -247,14 +294,14 @@ cmap_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) static void line_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) { - float x1,y1,x2,y2; - BYTE r, g, b; + int x1,y1,x2,y2; + int r, g, b; DWORD c32k; c32k = GetPrimColor (PrimPtr) >> 8; // shift out color index r = (c32k >> (10 - (8 - 5))) & 0xF8; g = (c32k >> (5 - (8 - 5))) & 0xF8; - b = (c32k << (8 - 5)); + b = (c32k << (8 - 5)) & 0xF8; x1=PrimPtr->Object.Line.first.x - GetFrameHotX (_CurFramePtr); y1=PrimPtr->Object.Line.first.y - GetFrameHotY (_CurFramePtr); @@ -274,6 +321,7 @@ line_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) DC.g = g; DC.b = b; DC.image = 0; + DC.UsePalette = FALSE; TFB_EnqueueDrawCommand(&DC); } diff --git a/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c b/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c index 72aa454f3..a18213d51 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c @@ -19,7 +19,6 @@ #ifdef GFXMODULE_SDL #include "sdl_common.h" -#include "rotozoom.h" //Status: Not entirely unimplemented! @@ -80,56 +79,15 @@ SetGraphicGrabOther (int grab_other) void SetGraphicStrength (int numerator, int denominator) // I just hope numerator always = denominator... -{ -// printf("Unimplemented function activated: SetGrahicsStrength()\n"); -} - -// Status: Unimplemented -BOOLEAN -BatchColorMap (COLORMAPPTR ColorMapPtr) - // Batch... I wonder what that verb means in this context? - // SvdB: I don't think it is a verb. -{ - BOOLEAN ret; - -// printf("Unimplemented function activated: BatchColorMap()\n"); - ret = TRUE; - return (ret); -} - -//Status: Unimplemented -BOOLEAN -SetColorMap (COLORMAPPTR map) - //There's also a macro for thing in appglue.h... Hmm... -{ - BOOLEAN ret; - - //printf("Unimplemented function activated: SetColorMap()\n"); - ret = TRUE; - return (ret); -} - -//Status: Unimplemented -DWORD -XFormColorMap (COLORMAPPTR colormap, SIZE time) - // Not sure what the time's supposed to mean... -{ - // printf ("Unimplemented function activated: XFormColorMap()\n"); - return (GetTimeCounter () + time); -} - -//Status: Unimplemented -void -FlushColorXForms() //Not entirely sure what's done here. CLUT stuff? -{ -// printf ("Unimplemented function activated: FlushColorXForms()\n"); +{ + //printf("Unimplemented function activated: SetGrahicsStrength(), %d %d\n",numerator,denominator); } //Status: Unimplemented void ScreenTransition (int TransType, PRECT pRect) //TransType==3 { - //printf ("Unimplemented function activated: ScreenTransition()\n"); + //printf ("Unimplemented function activated: ScreenTransition()\n"); } void diff --git a/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c b/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c index 3ad45933c..30e5d24dc 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c @@ -24,6 +24,7 @@ #include #include "sdl_common.h" +#include "primitives.h" // following stuff was in libs/graphics/getbody.c before modularization @@ -31,7 +32,7 @@ extern char *_cur_resfile_name; static void -process_image (FRAMEPTR FramePtr, SDL_Surface *img[], int cel_ct) +process_image (FRAMEPTR FramePtr, SDL_Surface *img[], int cel_ct, BOOLEAN is_font) { int hx, hy, h; @@ -41,7 +42,59 @@ process_image (FRAMEPTR FramePtr, SDL_Surface *img[], int cel_ct) hx = hy = 0; SDL_LockSurface (img[cel_ct]); - if (img[cel_ct]->w >= 3 && (h = img[cel_ct]->h)) + + if (is_font) + { + // convert 32-bit png font to indexed + + int x,y; + Uint8 r,g,b,a; + Uint32 p; + SDL_Color colors[256]; + + SDL_Surface *new_surf; + GetPixelFn getpix; + PutPixelFn putpix; + + new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, img[cel_ct]->w, img[cel_ct]->h, + 8, 0, 0, 0, 0); + + getpix = getpixel_for (img[cel_ct]); + putpix = putpixel_for (new_surf); + + for (y = 0; y < img[cel_ct]->h; ++y) + { + for (x = 0; x < img[cel_ct]->w; ++x) + { + p = getpix (img[cel_ct], x, y); + SDL_GetRGBA (p, img[cel_ct]->format, &r, &g, &b, &a); + + if (a) + putpix (new_surf, x, y, 1); + else + putpix (new_surf, x, y, 0); + } + } + + colors[0].r = colors[0].g = colors[0].b = 0; + for (x = 1; x < 256; ++x) + { + colors[x].r = 255; + colors[x].g = 255; + colors[x].b = 255; + } + + SDL_SetColors (new_surf, colors, 0, 256); + SDL_SetColorKey (new_surf, SDL_SRCCOLORKEY, 0); + + SDL_UnlockSurface (img[cel_ct]); + SDL_FreeSurface (img[cel_ct]); + + img[cel_ct] = new_surf; + + SDL_LockSurface (img[cel_ct]); + } + else if (img[cel_ct]->w >= 3 && (h = img[cel_ct]->h)) { if (img[cel_ct]->format->palette) { @@ -57,17 +110,7 @@ process_image (FRAMEPTR FramePtr, SDL_Surface *img[], int cel_ct) *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 - ) - ); + SDL_SetColorKey(img[cel_ct], SDL_SRCCOLORKEY, Cknockout); do { w = img[cel_ct]->w - (p - pixel); @@ -149,24 +192,30 @@ process_image (FRAMEPTR FramePtr, SDL_Surface *img[], int cel_ct) { } } + SDL_UnlockSurface (img[cel_ct]); -hx -= img[cel_ct]->clip_rect.x; -hy -= img[cel_ct]->clip_rect.y; + 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; + img[cel_ct] = ((TFB_Image *)((BYTE *)FramePtr + FramePtr->DataOffs))->NormalImg; + + 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", + 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 @@ -206,6 +255,10 @@ _GetCelData (FILE *fp, DWORD length) cel_ct = 0; while (fgets (CurrentLine, sizeof (CurrentLine), fp) && cel_ct < MAX_CELS) { + /*char fnamestr[1000]; + sscanf(CurrentLine, "%s", fnamestr); + printf("imgload %s\n",fnamestr);*/ + if ( sscanf(CurrentLine, "%s", &filename[n]) == 1 @@ -218,6 +271,8 @@ _GetCelData (FILE *fp, DWORD length) else if (img[cel_ct]) printf("_GetCelData: Bad file!\n"), SDL_FreeSurface (img[cel_ct]); + + if ((int)ftell (fp) - (int)opos >= (int)length) break; @@ -250,7 +305,7 @@ printf("_GetCelData: Bad file!\n"), FramePtr = &DrawablePtr->Frame[cel_ct]; while (--FramePtr, cel_ct--) - process_image (FramePtr, img, cel_ct); + process_image (FramePtr, img, cel_ct, FALSE); UnlockDrawable (Drawable); } @@ -368,10 +423,26 @@ _GetFontData (FILE *fp, DWORD length) { if (img[cel_ct]) { - process_image (FramePtr, img, cel_ct); - SetFrameBounds (FramePtr, GetFrameWidth (FramePtr) + 1, GetFrameHeight (FramePtr)); + process_image (FramePtr, img, cel_ct, TRUE); + SetFrameBounds (FramePtr, GetFrameWidth (FramePtr) + 1, GetFrameHeight (FramePtr) + 1); + if (img[0]) - SetFrameHotSpot (FramePtr, MAKE_HOT_SPOT (0, img[0]->clip_rect.h)); + { + // This tunes the font positioning to be about what it should + // TODO: prolly needs a little tweaking still + + int tune_amount = 0; + + if (img[0]->clip_rect.h == 8) + tune_amount = -1; + else if (img[0]->clip_rect.h == 9) + tune_amount = -2; + else if (img[0]->clip_rect.h > 9) + tune_amount = -3; + + SetFrameHotSpot (FramePtr, MAKE_HOT_SPOT (0, img[0]->clip_rect.h + tune_amount)); + } + if (GetFrameHeight (FramePtr) > FontPtr->Leading) FontPtr->Leading = GetFrameHeight (FramePtr); } @@ -450,20 +521,24 @@ _request_drawable (COUNT NumFrames, DRAWABLE_TYPE DrawableType, 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; + imgw = width; + imgh = height; + + // commented out these when removing support for pre-scaling -Mika + // 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, + SDL_SWSURFACE, imgw, imgh, - 24, + 32, 0x00FF0000, 0x0000FF00, 0x000000FF, diff --git a/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c b/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c index e35934cd6..82915b6f6 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c +++ b/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c @@ -136,6 +136,7 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand) : TFB_DRAWCOMMANDTYPE_SCISSORDISABLE; DC->image = 0; + DC->UsePalette = FALSE; TFB_EnqueueDrawCommand(DC); } diff --git a/sc2/src/sc2code/libs/graphics/sdl/opengl.c b/sc2/src/sc2code/libs/graphics/sdl/opengl.c index 531781fa1..ccbc77c51 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/opengl.c +++ b/sc2/src/sc2code/libs/graphics/sdl/opengl.c @@ -22,10 +22,9 @@ static SDL_Surface *format_conv_surf; -static int ScreenWidthOpenGL; -static int ScreenHeightOpenGL; static int ScreenFilterMode; static unsigned int DisplayTexture; +static BOOLEAN tveffect; int @@ -53,11 +52,8 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp) ScreenWidth = 320; ScreenHeight = 240; - ScreenWidthActual = ScreenWidth; - ScreenHeightActual = ScreenHeight; - - ScreenWidthOpenGL = width; - ScreenHeightOpenGL = height; + ScreenWidthActual = width; + ScreenHeightActual = height; switch(bpp) { case 8: @@ -96,13 +92,13 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp) if (flags & TFB_GFXFLAGS_FULLSCREEN) videomode_flags |= SDL_FULLSCREEN; - SDL_Video = SDL_SetVideoMode (ScreenWidthOpenGL, ScreenHeightOpenGL, + SDL_Video = SDL_SetVideoMode (ScreenWidthActual, ScreenHeightActual, bpp, videomode_flags); if (SDL_Video == NULL) { printf ("Couldn't set OpenGL %ix%ix%i video mode: %s\n", - ScreenWidthOpenGL, ScreenHeightOpenGL, bpp, + ScreenWidthActual, ScreenHeightActual, bpp, SDL_GetError ()); exit(-1); } @@ -116,7 +112,7 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp) glGetString(GL_VERSION)); } - SDL_Screen = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidthActual, ScreenHeightActual, 32, + SDL_Screen = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth, ScreenHeight, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000); if (SDL_Screen == NULL) @@ -126,7 +122,7 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp) exit(-1); } - ExtraScreen = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidthActual, ScreenHeightActual, 32, + ExtraScreen = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth, ScreenHeight, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000); if (ExtraScreen == NULL) @@ -151,7 +147,12 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp) else ScreenFilterMode = GL_NEAREST; - glViewport (0, 0, ScreenWidthOpenGL, ScreenHeightOpenGL); + if (flags & TFB_GFXFLAGS_TVEFFECT) + tveffect = TRUE; + else + tveffect = FALSE; + + glViewport (0, 0, ScreenWidthActual, ScreenHeightActual); glClearColor (0,0,0,0); glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); SDL_GL_SwapBuffers (); @@ -169,12 +170,33 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp) return 0; } +void +TFB_GL_TVEffect() +{ + int y; + + glDisable(GL_TEXTURE_2D); + glEnable(GL_BLEND); + glBlendFunc(GL_DST_COLOR, GL_ONE); + glColor3f(0.5, 0.5, 0.5); + + for (y = 0; y < ScreenHeightActual; y += 2) + { + glBegin(GL_LINES); + glVertex2i(0, y); + glVertex2i(ScreenWidthActual, y); + glEnd(); + } + + glDisable(GL_BLEND); +} + void TFB_GL_SwapBuffers () { glMatrixMode(GL_PROJECTION); glLoadIdentity(); - glOrtho (0,ScreenWidthOpenGL,ScreenHeightOpenGL, 0, -1, 1); + glOrtho (0,ScreenWidthActual,ScreenHeightActual, 0, -1, 1); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); @@ -198,16 +220,19 @@ TFB_GL_SwapBuffers () glVertex2i(0, 0); glTexCoord2f(ScreenWidth / 512.0f, 0); - glVertex2i(ScreenWidthOpenGL, 0); + glVertex2i(ScreenWidthActual, 0); glTexCoord2f(ScreenWidth / 512.0f, ScreenHeight / 256.0f); - glVertex2i(ScreenWidthOpenGL, ScreenHeightOpenGL); + glVertex2i(ScreenWidthActual, ScreenHeightActual); glTexCoord2f(0, ScreenHeight / 256.0f); - glVertex2i(0, ScreenHeightOpenGL); + glVertex2i(0, ScreenHeightActual); glEnd(); + if (tveffect) + TFB_GL_TVEffect(); + SDL_GL_SwapBuffers(); } diff --git a/sc2/src/sc2code/libs/graphics/sdl/primitives.c b/sc2/src/sc2code/libs/graphics/sdl/primitives.c index a0a0e0347..aa3605d60 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/primitives.c +++ b/sc2/src/sc2code/libs/graphics/sdl/primitives.c @@ -192,4 +192,36 @@ void line(int x1, int y1, int x2, int y2, Uint32 color, PutPixelFn plot, SDL_Sur } } +// replaces all non-alpha pixels by color +void replace_color (Uint32 color, SDL_Surface *surface) +{ + int x,y,w,h; + Uint32 p; + Uint8 r,g,b,a; + GetPixelFn getpix; + PutPixelFn putpix; + + getpix = getpixel_for (surface); + putpix = putpixel_for (surface); + + SDL_LockSurface(surface); + + w = surface->w; + h = surface->h; + + for (y=0;yformat, &r, &g, &b, &a); + + if (a) + putpix (surface,x,y,color); + } + } + + SDL_UnlockSurface(surface); +} + #endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/primitives.h b/sc2/src/sc2code/libs/graphics/sdl/primitives.h index 992916a12..943bc267c 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/primitives.h +++ b/sc2/src/sc2code/libs/graphics/sdl/primitives.h @@ -30,4 +30,6 @@ PutPixelFn putpixel_for(SDL_Surface *surface); void line(int x1, int y1, int x2, int y2, Uint32 color, PutPixelFn plot, SDL_Surface *surface); +void replace_color (Uint32 color, SDL_Surface *surface); + #endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/pure.c b/sc2/src/sc2code/libs/graphics/sdl/pure.c index d13a5b67b..85da3bd35 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/pure.c +++ b/sc2/src/sc2code/libs/graphics/sdl/pure.c @@ -52,10 +52,24 @@ TFB_Pure_InitGraphics (int driver, int flags, int width, int height, int bpp) ScreenWidth = 320; ScreenHeight = 240; - ScreenWidthActual = width; - ScreenHeightActual = height; - videomode_flags = SDL_HWSURFACE | SDL_ANYFORMAT; + if (width == 320 && height == 240) + { + videomode_flags = SDL_HWSURFACE; + ScreenWidthActual = 320; + ScreenHeightActual = 240; + } + else + { + videomode_flags = SDL_SWSURFACE; // cannot be HWSURFACE because of our scaling routine + ScreenWidthActual = 640; + ScreenHeightActual = 480; + + if (width != 640 || height != 480) + printf("Screen resolution of %dx%d not supported under pure SDL, using 640x480\n", width, height); + } + + videomode_flags |= SDL_ANYFORMAT; if (flags & TFB_GFXFLAGS_FULLSCREEN) videomode_flags |= SDL_FULLSCREEN; @@ -77,7 +91,7 @@ TFB_Pure_InitGraphics (int driver, int flags, int width, int height, int bpp) } - test_extra = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidthActual, ScreenHeightActual, 32, + test_extra = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth, ScreenHeight, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000); if (test_extra == NULL) @@ -90,7 +104,7 @@ TFB_Pure_InitGraphics (int driver, int flags, int width, int height, int bpp) SDL_Screen = SDL_DisplayFormat(test_extra); SDL_FreeSurface(test_extra); - test_extra = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidthActual, ScreenHeightActual, 32, + test_extra = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth, ScreenHeight, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000); if (test_extra == NULL) @@ -103,14 +117,161 @@ TFB_Pure_InitGraphics (int driver, int flags, int width, int height, int bpp) ExtraScreen = SDL_DisplayFormat(test_extra); SDL_FreeSurface(test_extra); + if (SDL_Video->format->BytesPerPixel != SDL_Screen->format->BytesPerPixel) + { + printf("Fatal error: SDL_Video and SDL_Screen bpp doesn't match (%d vs. %d)\n", + SDL_Video->format->BytesPerPixel,SDL_Screen->format->BytesPerPixel); + exit(-1); + } + return 0; } void TFB_Pure_SwapBuffers () { - SDL_BlitSurface(SDL_Screen, NULL, SDL_Video, NULL); - SDL_UpdateRect(SDL_Video, 0, 0, 0, 0); + if (ScreenWidth == 320 && ScreenHeight == 240 && + ScreenWidthActual == 640 && ScreenHeightActual == 480) + { + // scales SDL_Screen to SDL_Video (640x480) + + int x, y; + Uint8 *src_p, *src_p2, *dst_p; + + SDL_LockSurface (SDL_Video); + SDL_LockSurface (SDL_Screen); + + src_p = SDL_Screen->pixels; + dst_p = SDL_Video->pixels; + + switch (SDL_Screen->format->BytesPerPixel) + { + case 1: + { + Uint8 pixval_8; + for (y = 0; y < 240; ++y) + { + src_p2 = src_p; + for (x = 0; x < 320; ++x) + { + pixval_8 = *src_p++; + + *dst_p++ = pixval_8; + *dst_p++ = pixval_8; + } + src_p = src_p2; + for (x = 0; x < 320; ++x) + { + pixval_8 = *src_p++; + + *dst_p++ = pixval_8; + *dst_p++ = pixval_8; + } + } + break; + } + case 2: + { + Uint16 pixval_16; + for (y = 0; y < 240; ++y) + { + src_p2 = src_p; + for (x = 0; x < 320; ++x) + { + pixval_16 = *(Uint16*)src_p++; + src_p++; + + *(Uint16*)dst_p++ = pixval_16; + dst_p++; + *(Uint16*)dst_p++ = pixval_16; + dst_p++; + } + src_p = src_p2; + for (x = 0; x < 320; ++x) + { + pixval_16 = *(Uint16*)src_p++; + src_p++; + + *(Uint16*)dst_p++ = pixval_16; + dst_p++; + *(Uint16*)dst_p++ = pixval_16; + dst_p++; + } + } + break; + } + case 3: + { + Uint32 pixval_32; + for (y = 0; y < 240; ++y) + { + src_p2 = src_p; + for (x = 0; x < 320; ++x) + { + pixval_32 = *(Uint32*)src_p; + src_p += 3; + + *(Uint32*)dst_p = pixval_32; + dst_p += 3; + *(Uint32*)dst_p = pixval_32; + dst_p += 3; + } + src_p = src_p2; + for (x = 0; x < 320; ++x) + { + pixval_32 = *(Uint32*)src_p; + src_p += 3; + + *(Uint32*)dst_p = pixval_32; + dst_p += 3; + *(Uint32*)dst_p = pixval_32; + dst_p += 3; + } + } + break; + } + case 4: + { + Uint32 pixval_32; + for (y = 0; y < 240; ++y) + { + src_p2 = src_p; + for (x = 0; x < 320; ++x) + { + pixval_32 = *(Uint32*)src_p; + src_p += 4; + + *(Uint32*)dst_p = pixval_32; + dst_p += 4; + *(Uint32*)dst_p = pixval_32; + dst_p += 4; + } + src_p = src_p2; + for (x = 0; x < 320; ++x) + { + pixval_32 = *(Uint32*)src_p; + src_p += 4; + + *(Uint32*)dst_p = pixval_32; + dst_p += 4; + *(Uint32*)dst_p = pixval_32; + dst_p += 4; + } + } + break; + } + } + + SDL_UnlockSurface (SDL_Screen); + SDL_UnlockSurface (SDL_Video); + } + else + { + // resolution is 320x240 so we can blit directly + SDL_BlitSurface (SDL_Screen, NULL, SDL_Video, NULL); + } + + SDL_UpdateRect (SDL_Video, 0, 0, 0, 0); } #endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/rotozoom.c b/sc2/src/sc2code/libs/graphics/sdl/rotozoom.c index a0c3db8b2..161166eb0 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/rotozoom.c +++ b/sc2/src/sc2code/libs/graphics/sdl/rotozoom.c @@ -11,10 +11,6 @@ #ifdef GFXMODULE_SDL -#ifdef WIN32 -#pragma warning (disable:4018) -#endif - #include #include #include "rotozoom.h" diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index 69de93a90..363f896d1 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -130,20 +130,66 @@ TFB_Image* TFB_LoadImage (SDL_Surface *img) { TFB_Image *myImage; - SDL_Surface *new_surf; - float x_scale = (float)ScreenWidthActual / ScreenWidth; - float y_scale = (float)ScreenHeightActual / ScreenHeight; - myImage = (TFB_Image*) HMalloc (sizeof (TFB_Image)); myImage->mutex = SDL_CreateMutex(); - myImage->dirty = FALSE; myImage->ScaledImg = NULL; + myImage->Palette = NULL; - if (img->format->BytesPerPixel < 4) { - // Because image doesn't have alpha channel, blit it to new surface, using - // transparent color (if SDL_SetColorKey was called before this) + if (img->format->BytesPerPixel == 1) + { + int x,y; + Uint8 *src_p,*dst_p; + SDL_Surface *full_surf; + SDL_Rect SDL_DstRect; + full_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, img->clip_rect.w, img->clip_rect.h, + 8, 0, 0, 0, 0); + + SDL_DstRect.x = SDL_DstRect.y = 0; + + SDL_LockSurface(img); + SDL_LockSurface(full_surf); + + src_p = (Uint8*)img->pixels; + dst_p = (Uint8*)full_surf->pixels; + + for (y = img->clip_rect.y; y < img->clip_rect.y + img->clip_rect.h; ++y) + { + for (x = img->clip_rect.x; x < img->clip_rect.x + img->clip_rect.w; ++x) + { + dst_p[(y - img->clip_rect.y) * full_surf->pitch + (x - img->clip_rect.x)]= + src_p[y * img->pitch + x]; + } + } + + full_surf->clip_rect.x = full_surf->clip_rect.y = 0; + full_surf->clip_rect.w = img->clip_rect.w; + full_surf->clip_rect.h = img->clip_rect.h; + + myImage->Palette = (SDL_Color*) HMalloc (sizeof (SDL_Color) * 256); + + for (x = 0; x < 256; ++x) + { + myImage->Palette[x].r = img->format->palette->colors[x].r; + myImage->Palette[x].g = img->format->palette->colors[x].g; + myImage->Palette[x].b = img->format->palette->colors[x].b; + } + + SDL_SetColors (full_surf, myImage->Palette, 0, 256); + + if (img->flags & SDL_SRCCOLORKEY) + { + SDL_SetColorKey (full_surf, SDL_SRCCOLORKEY, img->format->colorkey); + } + + SDL_UnlockSurface(full_surf); + SDL_UnlockSurface(img); + + SDL_FreeSurface (img); + img = full_surf; + } + else if (img->format->BytesPerPixel == 2 || img->format->BytesPerPixel == 3) { SDL_Surface *full_surf; SDL_Rect SDL_DstRect; @@ -156,30 +202,29 @@ TFB_LoadImage (SDL_Surface *img) full_surf->clip_rect.x = full_surf->clip_rect.y = 0; full_surf->clip_rect.w = img->clip_rect.w; - full_surf->clip_rect.h = img->clip_rect.h; - + full_surf->clip_rect.h = img->clip_rect.h; + SDL_FreeSurface (img); img = full_surf; } - - if ((x_scale==1.0f && y_scale==1.0f) || (img->w==0 && img->h==0)) - { - new_surf = img; - } - else - { - // Note: SMOOTHING_OFF and SMOOTHING_ON controls bilinear filtering - new_surf = zoomSurface (img, x_scale, y_scale, SMOOTHING_OFF); - } - // Now convert to the native display format - - myImage->DrawableImg = TFB_DisplayFormatAlpha (new_surf); - if (new_surf != img) - SDL_FreeSurface(new_surf); - - myImage->SurfaceSDL = TFB_DisplayFormatAlpha (img); - SDL_FreeSurface(img); + if (img->format->BytesPerPixel > 1) + { + myImage->NormalImg = TFB_DisplayFormatAlpha (img); + if (myImage->NormalImg) + { + SDL_FreeSurface(img); + } + else + { + printf("TFB_LoadImage(): TFB_DisplayFormatAlpha failed\n"); + myImage->NormalImg = img; + } + } + else + { + myImage->NormalImg = img; + } return(myImage); } @@ -198,23 +243,34 @@ TFB_FreeImage (TFB_Image *img) } } -void -TFB_UpdateDrawableImage (TFB_Image *img) +int TFB_ColorMapToRGB (SDL_Color *cmap_rgb) { - SDL_Surface *new_surf; + int i, n; + UBYTE *colors; + Uint32 c32k; - float x_scale = (float)ScreenWidthActual / ScreenWidth; - float y_scale = (float)ScreenHeightActual / ScreenHeight; - - SDL_LockSurface (img->SurfaceSDL); - new_surf = zoomSurface (img->SurfaceSDL, x_scale, y_scale, SMOOTHING_OFF); - SDL_UnlockSurface (img->SurfaceSDL); + colors = current_colormap; + n = current_colormap_size / 2; + if (n > 256) + n = 256; - // Now convert to the native display format + for (i = 0; i < n; ++i) + { + // FIXME: this has a rather nasty problem currently.. sometimes, + // green component's most significant bit is missing completely, + // for unknown reason, which leads to color corruption - SDL_FreeSurface (img->DrawableImg); - img->DrawableImg = TFB_DisplayFormatAlpha (new_surf); - SDL_FreeSurface (new_surf); + c32k = (*(Uint32*)colors) >> 8; + colors += 2; + + cmap_rgb[i].r = (c32k & 0x7c00) >> 7; + cmap_rgb[i].g = (c32k & 0x3e0 ) >> 2; + cmap_rgb[i].b = (c32k & 0x1f ) << 3; + + //printf("cmap %d: r %d g %d b %d, c32 %x\n", i, cmap_rgb[i].r, cmap_rgb[i].g, cmap_rgb[i].b, c32k); + } + + return n; } void @@ -309,83 +365,96 @@ TFB_FlushGraphics () // Only call from main thread!! DC_image = (TFB_Image*) DC->image; if (DC_image) - if (SDL_mutexP(DC_image->mutex)) - printf("TFB_FlushGraphics(): couldn't lock DC_image->mutex\n"); + SDL_mutexP (DC_image->mutex); switch (DC->Type) { case TFB_DRAWCOMMANDTYPE_IMAGE: - if (DC_image==0) - { - printf ("Error!!! Bad Image!\n"); - } - else { SDL_Rect targetRect; + SDL_Surface *surf; - targetRect.x = DC->x * ScreenWidthActual / ScreenWidth; - targetRect.y = DC->y * ScreenHeightActual / ScreenHeight; - - if (DC->Qualifier != MAPPED_TO_DISPLAY) + if (DC_image == 0) { - if ((DC->w != DC_image->SurfaceSDL->w || DC->h != DC_image->SurfaceSDL->h) && - DC_image->ScaledImg) + printf ("TFB_FlushGraphics(): error, DC_image == 0\n"); + break; + } + + targetRect.x = DC->x; + targetRect.y = DC->y; + + if ((DC->w != DC_image->NormalImg->w || DC->h != DC_image->NormalImg->h) && + DC_image->ScaledImg) + surf = DC_image->ScaledImg; + else + surf = DC_image->NormalImg; + + if (surf->format->BytesPerPixel == 1) + { + if (DC->UsePalette) { - SDL_BlitSurface(DC_image->ScaledImg, NULL, SDL_Screen, &targetRect); + SDL_SetColors (surf, (SDL_Color*)DC->Palette, 0, 256); } else { - if (DC_image->dirty) - { - TFB_UpdateDrawableImage (DC_image); - DC_image->dirty = FALSE; - } - - SDL_BlitSurface(DC_image->DrawableImg, NULL, SDL_Screen, &targetRect); + SDL_SetColors (surf, DC_image->Palette, 0, 256); } } - else - { - SDL_BlitSurface(DC_image->SurfaceSDL, NULL, SDL_Screen, &targetRect); - } + + SDL_BlitSurface(surf, NULL, SDL_Screen, &targetRect); + + break; } - break; case TFB_DRAWCOMMANDTYPE_LINE: { - int x_scale = ScreenWidthActual / ScreenWidth; - int y_scale = ScreenHeightActual / ScreenHeight; + SDL_Rect r; int x1, y1, x2, y2; Uint32 color; PutPixelFn screen_plot; - int xi, yi; screen_plot = putpixel_for (SDL_Screen); - - x1 = DC->x * x_scale; - x2 = DC->w * x_scale; - y1 = DC->y * y_scale; - y2 = DC->h * y_scale; color = SDL_MapRGB (SDL_Screen->format, DC->r, DC->g, DC->b); + + x1 = DC->x; + x2 = DC->w; + y1 = DC->y; + y2 = DC->h; + SDL_GetClipRect(SDL_Screen, &r); + + if (x1 < r.x) + x1 = r.x; + else if (x1 > r.x + r.w) + x1 = r.x + r.w; + + if (x2 < r.x) + x2 = r.x; + else if (x2 > r.x + r.w) + x2 = r.x + r.w; + + if (y1 < r.y) + y1 = r.y; + else if (y1 > r.y + r.h) + y1 = r.y + r.h; + + if (y2 < r.y) + y2 = r.y; + else if (y2 > r.y + r.h) + y2 = r.y + r.h; + SDL_LockSurface (SDL_Screen); - for (xi = 0; xi < x_scale; xi++) - { - for (yi = 0; yi < y_scale; yi++) - { - line (x1 + xi, y1 + yi, x2 + xi, y2 + yi, - color, screen_plot, SDL_Screen); - } - } + line (x1, y1, x2, y2, color, screen_plot, SDL_Screen); SDL_UnlockSurface (SDL_Screen); + break; } case TFB_DRAWCOMMANDTYPE_RECTANGLE: { SDL_Rect r; - r.x = DC->x * ScreenWidthActual / ScreenWidth; - r.y = DC->y * ScreenHeightActual / ScreenHeight; - r.w = DC->w * ScreenWidthActual / ScreenWidth; - r.h = DC->h * ScreenHeightActual / ScreenHeight; + r.x = DC->x; + r.y = DC->y; + r.w = DC->w; + r.h = DC->h; SDL_FillRect(SDL_Screen, &r, SDL_MapRGB(SDL_Screen->format, DC->r, DC->g, DC->b)); break; @@ -393,10 +462,10 @@ TFB_FlushGraphics () // Only call from main thread!! case TFB_DRAWCOMMANDTYPE_SCISSORENABLE: { SDL_Rect r; - r.x = DC->x * ScreenWidthActual / ScreenWidth; - r.y = DC->y * ScreenHeightActual / ScreenHeight; - r.w = DC->w * ScreenWidthActual / ScreenWidth; - r.h = DC->h * ScreenHeightActual / ScreenHeight; + r.x = DC->x; + r.y = DC->y; + r.w = DC->w; + r.h = DC->h; SDL_SetClipRect(SDL_Screen, &r); break; @@ -407,10 +476,10 @@ TFB_FlushGraphics () // Only call from main thread!! case TFB_DRAWCOMMANDTYPE_COPYBACKBUFFERTOOTHERBUFFER: { SDL_Rect src, dest; - src.x = dest.x = DC->x * ScreenWidthActual / ScreenWidth; - src.y = dest.y = DC->y * ScreenHeightActual / ScreenHeight; - src.w = DC->w * ScreenWidthActual / ScreenWidth; - src.h = DC->h * ScreenHeightActual / ScreenHeight; + src.x = dest.x = DC->x; + src.y = dest.y = DC->y; + src.w = DC->w; + src.h = DC->h; if (DC_image == 0) { @@ -420,32 +489,32 @@ TFB_FlushGraphics () // Only call from main thread!! { dest.x = 0; dest.y = 0; - SDL_BlitSurface(SDL_Screen, &src, DC_image->SurfaceSDL, &dest); - DC_image->dirty = TRUE; + SDL_BlitSurface(SDL_Screen, &src, DC_image->NormalImg, &dest); } break; } case TFB_DRAWCOMMANDTYPE_COPYFROMOTHERBUFFER: { SDL_Rect src, dest; - src.x = dest.x = DC->x * ScreenWidthActual / ScreenWidth; - src.y = dest.y = DC->y * ScreenHeightActual / ScreenHeight; - src.w = DC->w * ScreenWidthActual / ScreenWidth; - src.h = DC->h * ScreenHeightActual / ScreenHeight; + src.x = dest.x = DC->x; + src.y = dest.y = DC->y; + src.w = DC->w; + src.h = DC->h; SDL_BlitSurface(ExtraScreen, &src, SDL_Screen, &dest); break; } case TFB_DRAWCOMMANDTYPE_DELETEIMAGE: - SDL_FreeSurface (DC_image->SurfaceSDL); - SDL_FreeSurface (DC_image->DrawableImg); + SDL_FreeSurface (DC_image->NormalImg); if (DC_image->ScaledImg) { //printf("DELETEIMAGE to ScaledImg %x, size %d %d\n",DC_image->ScaledImg,DC_image->ScaledImg->w,DC_image->ScaledImg->h); SDL_FreeSurface (DC_image->ScaledImg); } - if (SDL_mutexV(DC_image->mutex)) - printf("TFB_FlushGraphics(): couldn't unlock DC_image->mutex (DELETEIMAGE)\n"); + if (DC_image->Palette) + HFree (DC_image->Palette); + + SDL_mutexV (DC_image->mutex); SDL_DestroyMutex (DC_image->mutex); HFree (DC_image); @@ -454,8 +523,7 @@ TFB_FlushGraphics () // Only call from main thread!! } if (DC_image) - if (SDL_mutexV(DC_image->mutex)) - printf("TFB_FlushGraphics(): couldn't unlock DC_image->mutex\n"); + SDL_mutexV (DC_image->mutex); TFB_DeallocateDrawCommand (DC); } diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h index 9b2842662..c7f21b863 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h @@ -41,20 +41,19 @@ void LoadDisplay (PDISPLAY_INTERFACE *pDisplay); // TFB_ImageStruct will be casted to this and vice versa, so sizes must be equal typedef struct tfb_image { - SDL_Surface *SurfaceSDL; - SDL_Surface *DrawableImg; + SDL_Surface *NormalImg; SDL_Surface *ScaledImg; - int scale; // used with ScaledImg - BOOLEAN dirty; // true if DrawableImg needs to be created again + SDL_Color *Palette; + int scale; SDL_mutex *mutex; UBYTE pad[sizeof(TFB_ImageStruct)-sizeof(SDL_Surface*)-sizeof(SDL_Surface*)- - sizeof(SDL_Surface*)-sizeof(int)-sizeof(BOOLEAN)-sizeof(SDL_mutex*)]; + sizeof(SDL_Color*)-sizeof(int)-sizeof(SDL_mutex*)]; } TFB_Image; TFB_Image *TFB_LoadImage (SDL_Surface *img); void TFB_FreeImage (TFB_Image *img); -void TFB_UpdateDrawableImage (TFB_Image *img); +int TFB_ColorMapToRGB (SDL_Color *cmap_rgb); void TFB_SwapBuffers (); SDL_Surface* TFB_DisplayFormatAlpha (SDL_Surface *surface); diff --git a/sc2/src/sc2code/planets/plangen.c b/sc2/src/sc2code/planets/plangen.c index b5dc7cfab..4f6bece2b 100644 --- a/sc2/src/sc2code/planets/plangen.c +++ b/sc2/src/sc2code/planets/plangen.c @@ -125,7 +125,11 @@ RenderTopography (BOOLEAN Reconstruct) d = xlat_tab[d] - cbase[0]; ctab = (cbase + 2) + d * 3; - SetPrimColor (pBatch, BUILD_COLOR (MAKE_RGB15 (ctab[0] >> 3, ctab[1] >> 3, ctab[2] >> 3), d)); + + // fixed planet surfaces being too dark + // ctab shifts were previously >> 3 .. -Mika + SetPrimColor (pBatch, BUILD_COLOR (MAKE_RGB15 (ctab[0] >> 1, ctab[1] >> 1, ctab[2] >> 1), d)); + } if (--i) continue; diff --git a/sc2/src/sc2code/restart.c b/sc2/src/sc2code/restart.c index 404f21b9f..33529d866 100644 --- a/sc2/src/sc2code/restart.c +++ b/sc2/src/sc2code/restart.c @@ -116,14 +116,14 @@ else if (InputState & DEVICE_EXIT) return (FALSE); BYTE NewState; NewState = pMS->CurState; - if (GetInputXComponent (InputState) < 0 - || GetInputYComponent (InputState) < 0) + if (GetInputXComponent (InputState) > 0 + || GetInputYComponent (InputState) > 0) { if (NewState-- == START_NEW_GAME) NewState = PLAY_SUPER_MELEE; } - else if (GetInputXComponent (InputState) > 0 - || GetInputYComponent (InputState) > 0) + else if (GetInputXComponent (InputState) < 0 + || GetInputYComponent (InputState) < 0) { if (NewState++ == PLAY_SUPER_MELEE) NewState = START_NEW_GAME; diff --git a/sc2/src/sc2code/sis.c b/sc2/src/sc2code/sis.c index 7463b68dd..8a09ee7c7 100644 --- a/sc2/src/sc2code/sis.c +++ b/sc2/src/sc2code/sis.c @@ -933,10 +933,13 @@ int flash_rect_func(void *blah) #define NORMAL_F_STRENGTH 0 DWORD TimeIn; SIZE strength, fstrength, incr; + /* Added by Michael: simple on-off flash right now */ + BOOLEAN flash_on; fstrength = NORMAL_F_STRENGTH; incr = 1; strength = NORMAL_STRENGTH; + flash_on = 0; TimeIn = GetTimeCounter (); for (;;) { @@ -947,7 +950,7 @@ int flash_rect_func(void *blah) if (flash_rect.extent.width) { - BatchGraphics (); + BatchGraphics (); SetContextClipRect (&flash_rect); if (flash_frame) { @@ -963,26 +966,29 @@ int flash_rect_func(void *blah) fstrength = MIN_F_STRENGTH + 1; incr = 1; } + + flash_on = !flash_on; - if (fstrength != NORMAL_F_STRENGTH) + DrawFromExtraScreen (&flash_rect); + + // if (fstrength != NORMAL_F_STRENGTH) + if (flash_on) { STAMP s; ClearDrawable (); - SetGraphicStrength (fstrength > 0 ? fstrength : -fstrength, 16); + SetGraphicStrength (fstrength > 0 ? fstrength : -fstrength, 16); s.origin.x = s.origin.y = 0; s.frame = flash_frame; DrawStamp (&s); if (fstrength < 0) - SetGraphicStrength (-8, 8); // add to -(partial mask) + SetGraphicStrength (-8, 8); // add to -(partial mask) else SetGraphicStrength (8, -8); // add to (partial mask) } - - DrawFromExtraScreen (&flash_rect); } else { @@ -999,11 +1005,16 @@ int flash_rect_func(void *blah) SetGraphicStrength (4, 4); - UnbatchGraphics (); + UnbatchGraphics (); } SetContext (OldContext); ClearSemaphore (&GraphicsSem); - TimeIn = SleepTask (TimeIn + (ONE_SECOND / 16)); + // Michael: + // "This is too frequent for a binary flash, so we slow it down. + // eventually once we get better alpha control we can do the fading + // effect again." + // TimeIn = SleepTask (TimeIn + (ONE_SECOND / 16)); + TimeIn = SleepTask (TimeIn + (ONE_SECOND / 4)); } (void) blah; /* Satisfying compiler (unused parameter) */ @@ -1054,7 +1065,9 @@ SetFlashRect (PRECT pRect, FRAME f) flash_rect.corner.y &= ~1; if (flash_task == 0) + { flash_task = AddTask (flash_rect_func, 2048); + } } flash_frame = f;