From 83f7223a50a692d74c51d43d894c65201a08f6f0 Mon Sep 17 00:00:00 2001 From: gewlitys Date: Fri, 27 Sep 2002 02:05:58 +0000 Subject: [PATCH] Implemented SetGraphicStrength git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@86 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/sc2code/libs/graphics/gfx_common.c | 11 + sc2/src/sc2code/libs/graphics/gfx_common.h | 4 + sc2/src/sc2code/libs/graphics/sdl/3do_blt.c | 12 + sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c | 16 +- sc2/src/sc2code/libs/graphics/sdl/dcqueue.c | 3 + sc2/src/sc2code/libs/graphics/sdl/pure.c | 2 + .../sc2code/libs/graphics/sdl/sdl_common.c | 254 +++++++++++++++++- .../sc2code/libs/graphics/sdl/sdl_common.h | 3 + sc2/src/sc2code/sis.c | 19 +- 9 files changed, 297 insertions(+), 27 deletions(-) diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.c b/sc2/src/sc2code/libs/graphics/gfx_common.c index 20412f08c..2d58cf741 100644 --- a/sc2/src/sc2code/libs/graphics/gfx_common.c +++ b/sc2/src/sc2code/libs/graphics/gfx_common.c @@ -32,3 +32,14 @@ int ScreenWidthActual; int ScreenHeightActual; int GraphicsDriver; int TFB_DEBUG_HALT; +int BlendNumerator = 4; +int BlendDenominator = 4; + + +void +SetGraphicStrength (int numerator, int denominator) +{ + //fprintf (stderr, "SetGraphicsStrength %d %d\n",numerator, denominator); + BlendNumerator = numerator; + BlendDenominator = denominator; +} diff --git a/sc2/src/sc2code/libs/graphics/gfx_common.h b/sc2/src/sc2code/libs/graphics/gfx_common.h index e356ca946..9bb9f47d7 100644 --- a/sc2/src/sc2code/libs/graphics/gfx_common.h +++ b/sc2/src/sc2code/libs/graphics/gfx_common.h @@ -106,6 +106,8 @@ typedef struct tfb_drawcommand int b; TFB_Palette Palette[256]; BOOLEAN UsePalette; + int BlendNumerator; + int BlendDenominator; } TFB_DrawCommand; // Queue Stuff @@ -243,6 +245,8 @@ extern int ScreenHeight; extern int ScreenWidthActual; extern int ScreenHeightActual; extern int GraphicsDriver; +extern int BlendNumerator; +extern int BlendDenominator; int Starcon2Main (void *); diff --git a/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c b/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c index 0aaf93967..209cdd2f7 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_blt.c @@ -162,6 +162,9 @@ blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) } } + DrawCommand.BlendNumerator = BlendNumerator; + DrawCommand.BlendDenominator = BlendDenominator; + TFB_EnqueueDrawCommand(&DrawCommand); } else @@ -234,6 +237,9 @@ fillrect_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) DrawCommand.image = 0; DrawCommand.UsePalette = FALSE; + DrawCommand.BlendNumerator = BlendNumerator; + DrawCommand.BlendDenominator = BlendDenominator; + TFB_EnqueueDrawCommand(&DrawCommand); } else @@ -297,6 +303,9 @@ line_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr) DC.image = 0; DC.UsePalette = FALSE; + DC.BlendNumerator = BlendNumerator; + DC.BlendDenominator = BlendDenominator; + TFB_EnqueueDrawCommand(&DC); } else @@ -327,6 +336,9 @@ read_screen (PRECT lpRect, FRAMEPTR DstFramePtr) DC.image = (TFB_ImageStruct *) ((BYTE *) DstFramePtr + DstFramePtr->DataOffs); + DC.BlendNumerator = BlendNumerator; + DC.BlendDenominator = BlendDenominator; + 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 60d139fb2..184b9b2b6 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_funcs.c @@ -79,26 +79,20 @@ FlushGraphics (void) continuity_break = 1; } +// Status: Ignored (only used in fmv.c) void SetGraphicUseOtherExtra (int other) //Could this possibly be more cryptic?!? :) { //fprintf(stderr, "SetGraphicUseOtherExtra %d\n", other); } +// Status: Ignored (only used in solarsys.c) void SetGraphicGrabOther (int grab_other) { //fprintf(stderr, "SetGraphicGrabOther %d\n", grab_other); } -// Status: Unimplemented -void -SetGraphicStrength (int numerator, int denominator) - // I just hope numerator always = denominator... -{ - //fprintf (stderr, "SetGraphicsStrength, %d %d\n",numerator, denominator); -} - static int transition_task_func (void *data) { @@ -198,6 +192,9 @@ DrawFromExtraScreen (PRECT r) //No scaling? DC.h = r->extent.height; DC.image = 0; + DC.BlendNumerator = BlendNumerator; + DC.BlendDenominator = BlendDenominator; + TFB_EnqueueDrawCommand (&DC); } @@ -225,6 +222,9 @@ LoadIntoExtraScreen (PRECT r) DC.h = r->extent.height; DC.image = 0; + DC.BlendNumerator = BlendNumerator; + DC.BlendDenominator = BlendDenominator; + TFB_EnqueueDrawCommand (&DC); } diff --git a/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c b/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c index 6e59a32fb..e73c23e00 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c +++ b/sc2/src/sc2code/libs/graphics/sdl/dcqueue.c @@ -234,6 +234,9 @@ TFB_EnqueueDrawCommand (TFB_DrawCommand* DrawCommand) DC.image = 0; DC.UsePalette = FALSE; + DC.BlendNumerator = BlendNumerator; + DC.BlendDenominator = BlendDenominator; + TFB_EnqueueDrawCommand(&DC); } } diff --git a/sc2/src/sc2code/libs/graphics/sdl/pure.c b/sc2/src/sc2code/libs/graphics/sdl/pure.c index 394bf60b4..ee869b9af 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/pure.c +++ b/sc2/src/sc2code/libs/graphics/sdl/pure.c @@ -230,6 +230,8 @@ TFB_Pure_SwapBuffers () } case 3: { + // FIXME: this one might have endian issues + Uint32 pixval_32; for (y = 0; y < 240; ++y) { diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index 40c93f5e9..8ffe01c4f 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -44,6 +44,12 @@ TFB_InitGraphics (int driver, int flags, int width, int height, int bpp) { int result; + if (bpp != 15 && bpp != 16 && bpp != 24 && bpp != 32) + { + fprintf(stderr, "Fatal error: bpp of %d not supported\n", bpp); + exit(-1); + } + if (driver == TFB_GFXDRIVER_SDL_OPENGL) { #ifdef HAVE_OPENGL @@ -276,6 +282,244 @@ TFB_DisplayFormatAlpha (SDL_Surface *surface) return SDL_DisplayFormatAlpha (surface); } +void TFB_BlitSurface (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, + SDL_Rect *dstrect, int blend_numer, int blend_denom) +{ + BOOLEAN has_colorkey; + int x, y, x1, y1, x2, y2, dst_x2, dst_y2, colorkey, nr, ng, nb; + int srcx, srcy, w, h; + Uint8 sr, sg, sb, dr, dg, db; + Uint32 src_pixval, dst_pixval; + GetPixelFn src_getpix, dst_getpix; + PutPixelFn putpix; + SDL_Rect fulldst; + + if (blend_numer == blend_denom) + { + // normal blit: dst = src + + //fprintf(stderr, "normal blit\n"); + SDL_BlitSurface (src, srcrect, dst, dstrect); + return; + } + + // NOTE: following clipping code is copied from SDL-1.2.4 sources + + // If the destination rectangle is NULL, use the entire dest surface + if (dstrect == NULL) + { + fulldst.x = fulldst.y = 0; + dstrect = &fulldst; + } + + // clip the source rectangle to the source surface + if (srcrect) + { + int maxw, maxh; + + srcx = srcrect->x; + w = srcrect->w; + if(srcx < 0) + { + w += srcx; + dstrect->x -= srcx; + srcx = 0; + } + maxw = src->w - srcx; + if(maxw < w) + w = maxw; + + srcy = srcrect->y; + h = srcrect->h; + if(srcy < 0) + { + h += srcy; + dstrect->y -= srcy; + srcy = 0; + } + maxh = src->h - srcy; + if(maxh < h) + h = maxh; + + } + else + { + srcx = srcy = 0; + w = src->w; + h = src->h; + } + + // clip the destination rectangle against the clip rectangle + { + SDL_Rect *clip = &dst->clip_rect; + int dx, dy; + + dx = clip->x - dstrect->x; + if(dx > 0) + { + w -= dx; + dstrect->x += dx; + srcx += dx; + } + dx = dstrect->x + w - clip->x - clip->w; + if(dx > 0) + w -= dx; + + dy = clip->y - dstrect->y; + if(dy > 0) + { + h -= dy; + dstrect->y += dy; + srcy += dy; + } + dy = dstrect->y + h - clip->y - clip->h; + if(dy > 0) + h -= dy; + } + + dstrect->w = w; + dstrect->h = h; + + if (w <= 0 || h <= 0) + return; + + x1 = srcx; + y1 = srcy; + x2 = srcx + w; + y2 = srcy + h; + + if (src->flags & SDL_SRCCOLORKEY) + { + has_colorkey = TRUE; + colorkey = src->format->colorkey; + } + else + { + has_colorkey = FALSE; + } + + src_getpix = getpixel_for (src); + dst_getpix = getpixel_for (dst); + putpix = putpixel_for (dst); + + SDL_LockSurface (src); + SDL_LockSurface (dst); + + if (blend_denom < 0) + { + // additive blit: dst = src + dst + + //fprintf(stderr, "additive blit %d %d, src %d %d %d %d dst %d %d, srcbpp %d\n",blend_numer, blend_denom, x1, y1, x2, y2, dstrect->x, dstrect->y, src->format->BitsPerPixel); + + for (y = y1; y < y2; ++y) + { + dst_y2 = dstrect->y + (y - y1); + for (x = x1; x < x2; ++x) + { + dst_x2 = dstrect->x + (x - x1); + src_pixval = src_getpix (src, x, y); + + if (has_colorkey && src_pixval == colorkey) + continue; + + dst_pixval = dst_getpix (dst, dst_x2, dst_y2); + + SDL_GetRGB (src_pixval, src->format, &sr, &sg, &sb); + SDL_GetRGB (dst_pixval, dst->format, &dr, &dg, &db); + + nr = sr + dr; + ng = sg + dg; + nb = sb + db; + + if (nr > 255) + nr = 255; + if (ng > 255) + ng = 255; + if (nb > 255) + nb = 255; + + putpix (dst, dst_x2, dst_y2, SDL_MapRGB (dst->format, nr, ng, nb)); + } + } + } + else if (blend_numer < 0) + { + // subtractive blit: dst = src - dst + + //fprintf(stderr, "subtractive blit %d %d, src %d %d %d %d dst %d %d, srcbpp %d\n",blend_numer, blend_denom, x1, y1, x2, y2, dstrect->x, dstrect->y, src->format->BitsPerPixel); + + for (y = y1; y < y2; ++y) + { + dst_y2 = dstrect->y + (y - y1); + for (x = x1; x < x2; ++x) + { + dst_x2 = dstrect->x + (x - x1); + src_pixval = src_getpix (src, x, y); + + if (has_colorkey && src_pixval == colorkey) + continue; + + dst_pixval = dst_getpix (dst, dst_x2, dst_y2); + + SDL_GetRGB (src_pixval, src->format, &sr, &sg, &sb); + SDL_GetRGB (dst_pixval, dst->format, &dr, &dg, &db); + + nr = sr - dr; + ng = sg - dg; + nb = sb - db; + + if (nr < 0) + nr = 0; + if (ng < 0) + ng = 0; + if (nb < 0) + nb = 0; + + putpix (dst, dst_x2, dst_y2, SDL_MapRGB (dst->format, nr, ng, nb)); + } + } + } + else + { + // modulated blit: dst = src * (blend_numer / blend_denom) + + float f = blend_numer / (float)blend_denom; + + //fprintf(stderr, "modulated blit %d %d, f %f, src %d %d %d %d dst %d %d, srcbpp %d\n",blend_numer, blend_denom, f, x1, y1, x2, y2, dstrect->x, dstrect->y, src->format->BitsPerPixel); + + for (y = y1; y < y2; ++y) + { + dst_y2 = dstrect->y + (y - y1); + for (x = x1; x < x2; ++x) + { + dst_x2 = dstrect->x + (x - x1); + src_pixval = src_getpix (src, x, y); + + if (has_colorkey && src_pixval == colorkey) + continue; + + SDL_GetRGB (src_pixval, src->format, &sr, &sg, &sb); + + nr = (int)(sr * f); + ng = (int)(sg * f); + nb = (int)(sb * f); + + if (nr > 255) + nr = 255; + if (ng > 255) + ng = 255; + if (nb > 255) + nb = 255; + + putpix (dst, dst_x2, dst_y2, SDL_MapRGB (dst->format, nr, ng, nb)); + } + } + } + + SDL_UnlockSurface (dst); + SDL_UnlockSurface (src); +} + void TFB_ComputeFPS () { @@ -434,7 +678,7 @@ TFB_FlushGraphics () // Only call from main thread!! } } - SDL_BlitSurface(surf, NULL, SDL_Screen, &targetRect); + TFB_BlitSurface(surf, NULL, SDL_Screen, &targetRect, DC.BlendNumerator, DC.BlendDenominator); break; } @@ -516,13 +760,13 @@ TFB_FlushGraphics () // Only call from main thread!! if (DC_image == 0) { - SDL_BlitSurface(SDL_Screen, &src, ExtraScreen, &dest); + TFB_BlitSurface(SDL_Screen, &src, ExtraScreen, &dest, DC.BlendNumerator, DC.BlendDenominator); } else { dest.x = 0; dest.y = 0; - SDL_BlitSurface(SDL_Screen, &src, DC_image->NormalImg, &dest); + TFB_BlitSurface(SDL_Screen, &src, DC_image->NormalImg, &dest, DC.BlendNumerator, DC.BlendDenominator); } break; } @@ -533,7 +777,9 @@ TFB_FlushGraphics () // Only call from main thread!! src.y = dest.y = DC.y; src.w = DC.w; src.h = DC.h; - SDL_BlitSurface(ExtraScreen, &src, SDL_Screen, &dest); + + TFB_BlitSurface(ExtraScreen, &src, SDL_Screen, &dest, DC.BlendNumerator, DC.BlendDenominator); + break; } case TFB_DRAWCOMMANDTYPE_DELETEIMAGE: diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h index e943c7ab1..370d143e6 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h @@ -59,5 +59,8 @@ void TFB_FreeImage (TFB_Image *img); void TFB_SwapBuffers (); SDL_Surface* TFB_DisplayFormatAlpha (SDL_Surface *surface); +void TFB_BlitSurface (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, + SDL_Rect *dstrect, int blend_numer, int blend_denom); + #endif diff --git a/sc2/src/sc2code/sis.c b/sc2/src/sc2code/sis.c index b269d6611..f8902ce55 100644 --- a/sc2/src/sc2code/sis.c +++ b/sc2/src/sc2code/sis.c @@ -934,14 +934,11 @@ int flash_rect_func(void *data) #define NORMAL_F_STRENGTH 0 DWORD TimeIn; SIZE strength, fstrength, incr; - /* Added by Michael: simple on-off flash right now */ - BOOLEAN flash_on; Task task = (Task)data; fstrength = NORMAL_F_STRENGTH; incr = 1; strength = NORMAL_STRENGTH; - flash_on = 0; TimeIn = GetTimeCounter (); while (!Task_ReadState(task, TASK_EXIT)) { @@ -968,13 +965,8 @@ int flash_rect_func(void *data) fstrength = MIN_F_STRENGTH + 1; incr = 1; } - - flash_on = !flash_on; - DrawFromExtraScreen (&flash_rect); - - // if (fstrength != NORMAL_F_STRENGTH) - if (flash_on) + if (fstrength != NORMAL_F_STRENGTH) { STAMP s; @@ -991,6 +983,8 @@ int flash_rect_func(void *data) else SetGraphicStrength (8, -8); // add to (partial mask) } + + DrawFromExtraScreen (&flash_rect); } else { @@ -1011,12 +1005,7 @@ int flash_rect_func(void *data) } SetContext (OldContext); ClearSemaphore (GraphicsSem); - // 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." - // SleepThreadUntil (TimeIn + (ONE_SECOND / 16)); - SleepThreadUntil (TimeIn + (ONE_SECOND / 4)); + SleepThreadUntil (TimeIn + (ONE_SECOND / 16)); TimeIn = GetTimeCounter (); }