From: <Mee...@us...> - 2009-10-25 01:11:48
|
Revision: 3249 http://sc2.svn.sourceforge.net/sc2/?rev=3249&view=rev Author: Meep-Eep Date: 2009-10-25 01:11:41 +0000 (Sun, 25 Oct 2009) Log Message: ----------- Improvements to flashing code. Overlays work right too, now. Modified Paths: -------------- trunk/sc2/src/uqm/flash.c trunk/sc2/src/uqm/flash.h trunk/sc2/src/uqm/pickmele.c Modified: trunk/sc2/src/uqm/flash.c =================================================================== --- trunk/sc2/src/uqm/flash.c 2009-10-25 01:01:45 UTC (rev 3248) +++ trunk/sc2/src/uqm/flash.c 2009-10-25 01:11:41 UTC (rev 3249) @@ -14,20 +14,28 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -// NOTE: A lot of this code is untested. Only highlite flash areas drawing -// directly to the screen, using a cache are currently in use. +// NOTE: A lot of this code is untested. Only highlite and overlay flash +// areas drawing directly to the screen, using a cache are +// currently in use. // TODO: // - Add Flash_setHighlight() to change the brightness as in // Flash_createHighlight(), for an already created flash area. -// - Add Flash_setOverlay() to change the overlay frame as in -// Flash_createOverlay(), for an already created flash area. +// - Be able to set a minimum and maximum merge factor for overlay and +// transition areas, as the numer/denom with highlights. +// - During a few frames during the sequence, the frame to be displayed +// is equal to a frame which was supplied as a parameter to the flash +// sequence (instead of generated during the sequence). It is not +// necessary to make a copy in this case. Instead, the original can be +// used. I had code to do this, but this doesn't work anymore with the +// addition of startNumer, endNumer, and denom. This code is still +// present, but disabled with BEGIN_AND_END_FRAME_EXCEPTIONS. - #define FLASH_INTERNAL #include "flash.h" #include "setup.h" + // For GraphicsLock. #include "libs/log.h" #include "libs/memlib.h" #include "libs/threadlib.h" @@ -66,6 +74,10 @@ context->original = 0; + context->startNumer = 0; + context->endNumer = 1; + context->denom = 1; + context->fadeInTime = Flash_DEFAULT_FADE_IN_TIME; context->onTime = Flash_DEFAULT_ON_TIME; context->fadeOutTime = Flash_DEFAULT_FADE_OUT_TIME; @@ -88,19 +100,18 @@ return context; } -// 'startNumer / denom' is the brightness in the start state of the flash. -// 'endNumer / denom' is the brightness in the end state of the flash. +// 'startNumer / denom' is the brightness in the start state of the sequence. +// 'endNumer / denom' is the brightness in the end state of the sequence. // These numbers are relative to the brighness of the original image. FlashContext * -Flash_createHighlight (CONTEXT gfxContext, FRAME parent, const RECT *rect, - int startNumer, int endNumer, int denom) +Flash_createHighlight (CONTEXT gfxContext, FRAME parent, const RECT *rect) { FlashContext *context = Flash_create (gfxContext, parent); if (rect == NULL) { - // No rectangle specified. Should be later with Flash_setRect() - // before calling Flash_start(). + // No rectangle specified. It should be specified later with + // Flash_setRect(), before calling Flash_start(). context->rect.corner.x = 0; context->rect.corner.y = 0; context->rect.extent.width = 0; @@ -110,10 +121,6 @@ context->rect = *rect; context->type = FlashType_highlight; - context->u.highlight.startNumer = startNumer; - context->u.highlight.endNumer = endNumer; - context->u.highlight.denom = denom; - return context; } @@ -138,18 +145,28 @@ const POINT *origin, FRAME overlay) { FlashContext *context = Flash_create (gfxContext, parent); - + context->type = FlashType_overlay; - context->u.overlay.frame = overlay; - GetFrameRect (overlay, &context->rect); - context->rect.corner = *origin; + if (origin == NULL || overlay == NULL) { + // No overlay specified. It should be specified later with + // Flash_setOverlay(), before calling Flash_start(). + context->u.overlay.frame = NULL; + context->rect.corner.x = 0; + context->rect.corner.y = 0; + context->rect.extent.width = 0; + context->rect.extent.height = 0; + } else + Flash_setOverlay (context, origin, overlay); return context; } +// Set the current state. 'timeSpentInState' determines how much time should +// be considered to be already spent in this state. void -Flash_setState (FlashContext *context, FlashState state) +Flash_setState (FlashContext *context, FlashState state, + TimeCount timeSpentInState) { TimeCount now; @@ -157,10 +174,12 @@ context->state = state; Flash_fixState (context); - Flash_drawCurrentFrame (context); - context->lastStateTime = now; + context->lastStateTime = now - timeSpentInState; context->lastFrameTime = now; + + if (context->started) + Flash_drawCurrentFrame (context); } void @@ -303,6 +322,43 @@ context->offTime = offTime; } +// Determines how the brightness of the flashing changes. +// For highlights: +// 'startNumer / denom' is the brightness, at the start state of the flash. +// 'endNumer / denom' is the brightness, at the end state of the flash. +// For overlays: +// 'startNumer / denom' is the brightness of the image to overlay, at +// the start state of the flash. +// 'endNumer / denom' is the brightness of the image to overlay, at +// the end state of the flash. +// For transitions: +// 'startNumer / denom' is the brightness of the second image, at +// the start state of the flash; '1 - startNumer / denom' is the +// brightness of the first image at the start state of the flash. +// 'endNumer / denom' is the brightness of the second image, at +// the end state of the flash; '1 - endNumer / denom' is the +// brightness of the first image at the end state of the flash. +// These numbers are relative to the brighness of each original image. +void +Flash_setMergeFactors(FlashContext *context, int startNumer, int endNumer, + int denom) { + if (context->started) + { + Flash_drawFrame (context, context->original); + Flash_clearCache (context); + } + + context->startNumer = startNumer; + context->endNumer = endNumer; + context->denom = denom; + + if (context->started) + { + Flash_grabOriginal (context); + Flash_drawCurrentFrame (context); + } +} + // Set the time between updates of the flash area. void Flash_setFrameTime (FlashContext *context, TimeCount frameTime) { @@ -339,6 +395,7 @@ { COUNT i; +#ifdef BEGIN_AND_END_FRAME_EXCEPTIONS if (context->type == FlashType_transition || context->type == FlashType_overlay) { @@ -352,6 +409,7 @@ // we shouldn't free it. context->cache[context->cacheSize - 1] = (FRAME) 0; } +#endif /* BEGIN_AND_END_FRMAE_EXCEPTIONS */ for (i = 0; i < context->cacheSize; i++) { @@ -366,6 +424,8 @@ void Flash_setRect (FlashContext *context, const RECT *rect) { + assert(context->type == FlashType_highlight); + if (context->started) { Flash_drawFrame (context, context->original); @@ -390,20 +450,49 @@ *rect = context->rect; } +void +Flash_setOverlay (FlashContext *context, const POINT *origin, + FRAME overlay) { + assert(context->type = FlashType_overlay); + + if (context->started) + { + Flash_drawFrame (context, context->original); + Flash_clearCache (context); + } + + context->u.overlay.frame = overlay; + GetFrameRect (overlay, &context->rect); + context->rect.corner.x += origin->x; + context->rect.corner.y += origin->y; + + if (context->started) + { + Flash_grabOriginal (context); + Flash_drawCurrentFrame (context); + } +} + // Call before you update the graphics in the currently flashing area. void Flash_preUpdate (FlashContext *context) { - Flash_drawFrame (context, context->original); - Flash_clearCache (context); + if (context->started) + { + Flash_drawFrame (context, context->original); + Flash_clearCache (context); + } } // Call after you update the graphics in the currently flashing area. void Flash_postUpdate (FlashContext *context) { - Flash_grabOriginal (context); - Flash_drawCurrentFrame (context); + if (context->started) + { + Flash_grabOriginal (context); + Flash_drawCurrentFrame (context); + } } // Pre: context->original has been initialised. @@ -482,16 +571,14 @@ // F1 = context->u.highlight.endNumer / context->u.highlight.denom // P = *numer / *denom // R = P * F1 + (1 - P) * F0 - // = numer * context->u.highlight.endNumer / - // (denom * context->u.highlight.denom) + - // (denom - numer) * u.highlight.startNumer / - // denom * context->u.highlight.denom + // = numer * context->endNumer / (denom * context->denom) + + // (denom - numer) * startNumer / denom * context->denom assert (numer >= 0 && numer <= denom); - *resNumer = numer * context->u.highlight.endNumer + - (denom - numer) * context->u.highlight.startNumer; - *resDenom = denom * context->u.highlight.denom; + *resNumer = numer * context->endNumer + + (denom - numer) * context->startNumer; + *resDenom = denom * context->denom; } static void @@ -499,18 +586,18 @@ int numer, int denom) { RECT orgRect; + int blendedNumer; + int blendedDenom; + orgRect.corner.x = 0; orgRect.corner.y = 0; orgRect.extent = context->rect.extent; + Flash_blendFraction (context, numer, denom, &blendedNumer, &blendedDenom); + switch (context->type) { case FlashType_highlight: { - int blendedNumer; - int blendedDenom; - - Flash_blendFraction (context, numer, denom, &blendedNumer, - &blendedDenom); arith_frame_blit (context->original, &orgRect, dest, destRect, blendedNumer, blendedDenom); break; @@ -528,21 +615,43 @@ final = context->original; arith_frame_blit (first, &orgRect, dest, destRect, - denom - numer, denom); + blendedDenom - blendedNumer, blendedDenom); arith_frame_blit (final, &orgRect, dest, destRect, - numer, -denom); + blendedNumer, -blendedDenom); break; } case FlashType_overlay: + { + int addOrSubtractNumer; + int addOrSubtractDenom; + if (blendedNumer < 0) + { + // Subtractive blit. + blendedNumer = -blendedNumer; + addOrSubtractNumer = -1; + addOrSubtractDenom = 1; + } + else + { + // Additive blit. + addOrSubtractNumer = 1; + addOrSubtractDenom = -1; + } + + // Draw the overlay at partial strength: + arith_frame_blit (context->u.overlay.frame, &orgRect, + dest, destRect, blendedNumer, blendedDenom); + + // Merge the original in at full strength: + // For additive blit: dest = context->original + dest + // For subtractive blit blit: dest = context->original - dest arith_frame_blit (context->original, &orgRect, dest, destRect, - denom, denom); - arith_frame_blit (context->u.overlay.frame, &orgRect, - dest, destRect, numer, -denom); + addOrSubtractNumer, addOrSubtractDenom); break; + } } } - // Prepare an entry in the cache. static inline void Flash_prepareCacheFrame (FlashContext *context, COUNT index) @@ -550,6 +659,7 @@ if (context->cache[index] != (FRAME) 0) return; +#ifdef BEGIN_AND_END_FRAME_EXCEPTIONS if (index == 0 && context->type == FlashType_overlay) context->cache[index] = context->original; else if (index == 0 && context->type == FlashType_transition) @@ -560,6 +670,7 @@ context->cache[index] = context->u.transition.final != (FRAME) 0 ? context->u.transition.final : context->original; else +#endif /* BEGIN_AND_END_FRMAE_EXCEPTIONS */ { context->cache[index] = CaptureDrawable (CreateDrawable (WANT_PIXMAP, context->rect.extent.width, context->rect.extent.height, 1)); @@ -606,6 +717,7 @@ static inline void Flash_drawUncachedFrame (FlashContext *context, int numer, int denom) { +#ifdef BEGIN_AND_END_FRAME_EXCEPTIONS // 'lastFrameIndex' is 0 for the first image, 1 for the final // image, and 2 otherwise. @@ -638,6 +750,7 @@ } context->lastFrameIndex = 2; +#endif /* BEGIN_AND_END_FRMAE_EXCEPTIONS */ if (context->parent == NULL) { Modified: trunk/sc2/src/uqm/flash.h =================================================================== --- trunk/sc2/src/uqm/flash.h 2009-10-25 01:01:45 UTC (rev 3248) +++ trunk/sc2/src/uqm/flash.h 2009-10-25 01:11:41 UTC (rev 3249) @@ -20,8 +20,7 @@ /* * This code can draw three kinds of flashing areas. * - a rectangular highlight area. The brightness of the area oscilates. - * - an overlay; an image is overlayed over an area, with oscilating - * brightness. + * - an overlay; an image is laid over an area, with oscilating brightness. * - a transition/cross-fade between two images. * * NB. The graphics lock should not be held when any of the Flash functions @@ -32,8 +31,11 @@ * * // We create the flash context; it is used to manipulate the flash * // rectangle while it exists. - * FlashContext *fc = Flash_createHighlight (context, (FRAME) 0, rect, - * 2, 3, 2); + * FlashContext *fc = Flash_createHighlight (context, (FRAME) 0, rect); + * + * // Specify how bright the flash is at the beginning and ending of the + * // sequence. + * Flash_setMergeFactors(context, 2, 3, 2); * * // We change the flashing speed from the defaults. * Flash_setSpeed (ONE_SECOND, ONE_SECOND, ONE_SECOND, ONE_SECOND); @@ -116,12 +118,6 @@ union { struct { - int startNumer; - // Numerator for the brightness for the on state. - int endNumer; - // Numerator for the brightness for the off state. - int denom; - // Denominator for the brightness. } highlight; struct { FRAME first; @@ -136,6 +132,13 @@ } overlay; } u; + int startNumer; + // Numerator for the merge factor for the on state. + int endNumer; + // Numerator for the merge factor for the off state. + int denom; + // Denominator for the merge factor. + TimeCount fadeInTime; TimeCount onTime; TimeCount fadeOutTime; @@ -173,13 +176,14 @@ FlashContext *Flash_createHighlight (CONTEXT gfxContext, FRAME parent, - const RECT *rect, int startNumer, int endNumer, int denom); + const RECT *rect); FlashContext *Flash_createTransition (CONTEXT gfxContext, FRAME parent, const POINT *origin, FRAME first, FRAME final); FlashContext *Flash_createOverlay (CONTEXT gfxContext, FRAME parent, const POINT *origin, FRAME overlay); -void Flash_setState (FlashContext *context, FlashState state); +void Flash_setState (FlashContext *context, FlashState state, + TimeCount timeSpentInState); void Flash_start (FlashContext *context); void Flash_terminate (FlashContext *context); void Flash_pause (FlashContext *context); @@ -187,10 +191,14 @@ void Flash_process (FlashContext *context); void Flash_setSpeed (FlashContext *context, TimeCount fadeInTime, TimeCount onTime, TimeCount fadeOutTime, TimeCount offTime); +void Flash_setMergeFactors(FlashContext *context, int startNumer, + int endNumer, int denom); void Flash_setFrameTime (FlashContext *context, TimeCount frameTime); TimeCount Flash_nextTime (FlashContext *context); void Flash_setRect (FlashContext *context, const RECT *rect); void Flash_getRect (FlashContext *context, RECT *rect); +void Flash_setOverlay(FlashContext *context, const POINT *origin, + FRAME overlay); void Flash_preUpdate (FlashContext *context); void Flash_postUpdate (FlashContext *context); void Flash_setCacheSize (FlashContext *context, COUNT size); Modified: trunk/sc2/src/uqm/pickmele.c =================================================================== --- trunk/sc2/src/uqm/pickmele.c 2009-10-25 01:01:45 UTC (rev 3248) +++ trunk/sc2/src/uqm/pickmele.c 2009-10-25 01:11:41 UTC (rev 3249) @@ -582,7 +582,8 @@ #endif gmstate.player[playerI].flashContext = - Flash_createHighlight (ScreenContext, (FRAME) 0, NULL, + Flash_createHighlight (ScreenContext, (FRAME) 0, NULL); + Flash_setMergeFactors (gmstate.player[playerI].flashContext, 2, 3, 2); Flash_setFrameTime (gmstate.player[playerI].flashContext, ONE_SECOND / 16); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |