static BOOLEAN GetFrameValidRect (PRECT pValidRect, HOT_SPOT *pOldHot) { COORD hx, hy; HOT_SPOT OldHot; OldHot = _CurFramePtr->HotSpot; hx = OldHot.x; hy = OldHot.y; pValidRect->corner.x = hx; pValidRect->corner.y = hy; pValidRect->extent.width = GetFrameWidth (_CurFramePtr); pValidRect->extent.height = GetFrameHeight (_CurFramePtr); if (_pCurContext->ClipRect.extent.width) { if (!BoxIntersect (&_pCurContext->ClipRect, pValidRect, pValidRect)) return (FALSE); hx -= _pCurContext->ClipRect.corner.x; hy -= _pCurContext->ClipRect.corner.y; pValidRect->corner.x += hx; pValidRect->corner.y += hy; _CurFramePtr->HotSpot = MAKE_HOT_SPOT (hx, hy); } *pOldHot = OldHot; return (TRUE); }
static void processFontChar (TFB_Char* CharPtr, TFB_Canvas canvas) { BYTE* newdata; size_t dpitch; TFB_DrawCanvas_GetExtent (canvas, &CharPtr->extent); // Currently, each font char has its own separate data // but that can change to common mem area dpitch = CharPtr->extent.width; newdata = HMalloc (dpitch * CharPtr->extent.height * sizeof (BYTE)); TFB_DrawCanvas_GetFontCharData (canvas, newdata, dpitch); CharPtr->data = newdata; CharPtr->pitch = dpitch; CharPtr->disp.width = CharPtr->extent.width + 1; CharPtr->disp.height = CharPtr->extent.height + 1; // XXX: why the +1? // I brought it into this function from the only calling // function, but I don't know why it was there in the first // place. // XXX: the +1 appears to be for character and line spacing // text_blt just adds the frame width to move to the next char { // This tunes the font positioning to be about what it should // TODO: prolly needs a little tweaking still int tune_amount = 0; if (CharPtr->extent.height == 8) tune_amount = -1; else if (CharPtr->extent.height == 9) tune_amount = -2; else if (CharPtr->extent.height > 9) tune_amount = -3; CharPtr->HotSpot = MAKE_HOT_SPOT (0, CharPtr->extent.height + tune_amount); } }
static void process_image (FRAME FramePtr, TFB_Canvas img[], AniData *ani, int cel_ct) { TFB_Image *tfbimg; int hx, hy; FramePtr->Type = ROM_DRAWABLE; FramePtr->Index = cel_ct; // handle transparency cases if (TFB_DrawCanvas_IsPaletted (img[cel_ct])) { // indexed color image if (ani[cel_ct].transparent_color >= 0) { TFB_DrawCanvas_SetTransparentIndex (img[cel_ct], ani[cel_ct].transparent_color, FALSE); } } else { // special transparency cases for truecolor images if (ani[cel_ct].transparent_color == 0) { // make RGB=0,0,0 transparent Color color = {0, 0, 0, 0}; TFB_DrawCanvas_SetTransparentColor (img[cel_ct], color, FALSE); } } if (ani[cel_ct].transparent_color == -1) { // enforce -1 to mean 'no transparency' TFB_DrawCanvas_SetTransparentIndex (img[cel_ct], -1, FALSE); // set transparent_color == -2 to use PNG tRNS transparency } hx = ani[cel_ct].hotspot_x; hy = ani[cel_ct].hotspot_y; FramePtr->image = TFB_DrawImage_New (img[cel_ct]); tfbimg = FramePtr->image; tfbimg->colormap_index = ani[cel_ct].colormap_index; img[cel_ct] = tfbimg->NormalImg; FramePtr->HotSpot = MAKE_HOT_SPOT (hx, hy); SetFrameBounds (FramePtr, tfbimg->extent.width, tfbimg->extent.height); #ifdef CLIPDEBUG { /* for debugging clipping: draws white (or most matching color from palette) pixels to every corner of the image */ Color color = {0xff, 0xff, 0xff, 0xff}; RECT r = {{0, 0}, {1, 1}}; if (tfbimg->extent.width > 2 && tfbimg->extent.height > 2) { TFB_DrawImage_Rect (&r, color, tfbimg); r.corner.x = tfbimg->extent.width - 1; TFB_DrawImage_Rect (&r, color, tfbimg); r.corner.y = tfbimg->extent.height - 1; TFB_DrawImage_Rect (&r, color, tfbimg); r.corner.x = 0; TFB_DrawImage_Rect (&r, color, tfbimg); } } #endif }
static void process_image (FRAME FramePtr, SDL_Surface *img[], AniData *ani, int cel_ct) { TFB_Image *tfbimg; int hx, hy; FramePtr->Type = ROM_DRAWABLE; FramePtr->Index = cel_ct; // handle transparency cases if (img[cel_ct]->format->palette) { // indexed color image if (ani[cel_ct].transparent_color >= 0) SDL_SetColorKey (img[cel_ct], SDL_SRCCOLORKEY, ani[cel_ct].transparent_color); } else if (img[cel_ct]->format->BitsPerPixel > 8) { // special transparency cases for truecolor images if (ani[cel_ct].transparent_color == 0) // make RGB=0,0,0 transparent SDL_SetColorKey (img[cel_ct], SDL_SRCCOLORKEY, SDL_MapRGBA (img[cel_ct]->format, 0, 0, 0, 0)); } if (ani[cel_ct].transparent_color == -1) { // enforce -1 to mean 'no transparency' SDL_SetColorKey (img[cel_ct], 0, 0); // set transparent_color == -2 to use PNG tRNS transparency } hx = ani[cel_ct].hotspot_x; hy = ani[cel_ct].hotspot_y; FramePtr->image = TFB_DrawImage_New (img[cel_ct]); tfbimg = FramePtr->image; tfbimg->colormap_index = ani[cel_ct].colormap_index; img[cel_ct] = (SDL_Surface *)tfbimg->NormalImg; FramePtr->HotSpot = MAKE_HOT_SPOT (hx, hy); SetFrameBounds (FramePtr, img[cel_ct]->w, img[cel_ct]->h); #ifdef CLIPDEBUG { /* for debugging clipping: draws white (or most matching color from palette) pixels to every corner of the image */ Uint32 color = SDL_MapRGB (img[cel_ct]->format, 255, 255, 255); SDL_Rect r = {0, 0, 1, 1}; if (img[cel_ct]->w > 2 && img[cel_ct]->h > 2) { SDL_FillRect (img[cel_ct], &r, color); r.x = img[cel_ct]->w - 1; SDL_FillRect (img[cel_ct], &r, color); r.y = img[cel_ct]->h - 1; SDL_FillRect (img[cel_ct], &r, color); r.x = 0; SDL_FillRect (img[cel_ct], &r, color); } } #endif }
static void processFontChar (TFB_Char* CharPtr, SDL_Surface *surf) { int x,y; Uint8 r,g,b,a; Uint32 p; SDL_PixelFormat* srcfmt = surf->format; GetPixelFn getpix; BYTE* newdata; Uint32 dpitch; // Currently, each font char has its own separate data // but that can change to common mem area newdata = HMalloc (surf->w * surf->h * sizeof(BYTE)); dpitch = surf->w; SDL_LockSurface (surf); getpix = getpixel_for (surf); // produce an alpha-only image in internal BYTE[] format // from the SDL surface for (y = 0; y < surf->h; ++y) { BYTE* dst = newdata + dpitch * y; for (x = 0; x < surf->w; ++x, ++dst) { p = getpix (surf, x, y); SDL_GetRGBA (p, srcfmt, &r, &g, &b, &a); if (!srcfmt->Amask) { // produce alpha from intensity (Y component) // using a fast approximation // contributions to Y are: R=2, G=4, B=1 a = (((int)r << 1) + ((int)g << 2) + b) / 7; } *dst = a; } } SDL_UnlockSurface (surf); CharPtr->data = newdata; CharPtr->pitch = dpitch; CharPtr->extent.width = surf->w; CharPtr->extent.height = surf->h; CharPtr->disp.width = surf->w + 1; CharPtr->disp.height = surf->h + 1; // XXX: why the +1? // I brought it into this function from the only calling // function, but I don't know why it was there in the first // place. // XXX: the +1 appears to be for character and line spacing // text_blt just adds the frame width to move to the next char { // This tunes the font positioning to be about what it should // TODO: prolly needs a little tweaking still int tune_amount = 0; if (CharPtr->extent.height == 8) tune_amount = -1; else if (CharPtr->extent.height == 9) tune_amount = -2; else if (CharPtr->extent.height > 9) tune_amount = -3; CharPtr->HotSpot = MAKE_HOT_SPOT (0, CharPtr->extent.height + tune_amount); } }
BOOLEAN PauseGame (void) { RECT r; STAMP s; BOOLEAN ClockActive; CONTEXT OldContext; FRAME F; HOT_SPOT OldHot; if (ActivityFrame == 0 || (GLOBAL (CurrentActivity) & (CHECK_ABORT | CHECK_PAUSE)) || (LastActivity & (CHECK_LOAD | CHECK_RESTART))) return (FALSE); GLOBAL (CurrentActivity) |= CHECK_PAUSE; ClockActive = (BOOLEAN)( LOBYTE (GLOBAL (CurrentActivity)) != SUPER_MELEE && GameClockRunning () ); if (ClockActive) SuspendGameClock (); else if (CommData.ConversationPhrases && PlayingTrack ()) PauseTrack (); SetSemaphore (GraphicsSem); OldContext = SetContext (ScreenContext); OldHot = SetFrameHot (Screen, MAKE_HOT_SPOT (0, 0)); GetFrameRect (ActivityFrame, &r); r.corner.x = (SCREEN_WIDTH - r.extent.width) >> 1; r.corner.y = (SCREEN_HEIGHT - r.extent.height) >> 1; s.origin = r.corner; s.frame = ActivityFrame; F = CaptureDrawable (LoadDisplayPixmap (&r, (FRAME)0)); DrawStamp (&s); FlushGraphics (); { BYTE scan; scan = KBDToUNICODE (SK_F1); while (KeyDown (scan)) TaskSwitch (); } FlushInput (); while (KeyHit () != SK_F1) TaskSwitch (); s.frame = F; DrawStamp (&s); DestroyDrawable (ReleaseDrawable (s.frame)); SetFrameHot (Screen, OldHot); SetContext (OldContext); WaitForNoInput (ONE_SECOND / 4); FlushInput (); ClearSemaphore (GraphicsSem); if (ClockActive) ResumeGameClock (); else if (CommData.ConversationPhrases && PlayingTrack ()) ResumeTrack (); TaskSwitch (); GLOBAL (CurrentActivity) &= ~CHECK_PAUSE; return (TRUE); }