void TFB_ReturnColorMap (TFB_ColorMap *map) { LockMutex (maplock); release_colormap (map); UnlockMutex (maplock); }
void UninitColorMaps (void) { int i; TFB_ColorMap *next; for (i = 0; i < MAX_COLORMAPS; ++i) { TFB_ColorMap *map = colormaps[i]; if (!map) continue; release_colormap (map); colormaps[i] = 0; } // free spares for ( ; poolhead; poolhead = next, --poolcount) { next = poolhead->next; delete_colormap (poolhead); } DestroyMutex (fadeLock); // uninit xform control DestroyMutex (XFormControl.Lock); // uninit colormaps DestroyMutex (maplock); }
/* This gives the XFormColorMap task a timeslice to do its thing * Only one thread should ever be allowed to be calling this at any time */ BOOLEAN XFormColorMap_step (void) { BOOLEAN Changed = FALSE; int x; DWORD Now = GetTimeCounter (); LockMutex (XFormControl.Lock); for (x = 0; x <= XFormControl.Highest; ++x) { XFORM_CONTROL *control = &XFormControl.TaskControl[x]; int index = control->CMapIndex; int TicksLeft = control->EndTime - Now; TFB_ColorMap *curmap; if (index < 0) continue; // unused slot LockMutex (maplock); curmap = colormaps[index]; if (!curmap) { UnlockMutex (maplock); log_add (log_Error, "BUG: XFormColorMap_step(): no current map"); finish_colormap_xform (x); continue; } if (TicksLeft > 0) { #define XFORM_SCALE 0x10000 TFB_ColorMap *newmap = NULL; UBYTE *newClr; Color *oldClr; int frac; int i; newmap = clone_colormap (curmap, index); oldClr = control->OldCMap; newClr = (UBYTE*)control->CMapPtr + 2; frac = (int)(control->Ticks - TicksLeft) * XFORM_SCALE / control->Ticks; for (i = 0; i < NUMBER_OF_PLUTVALS; ++i, ++oldClr, newClr += PLUTVAL_BYTE_SIZE) { Color color; color.a = 0xff; color.r = blendChan (oldClr->r, newClr[PLUTVAL_RED], frac, XFORM_SCALE); color.g = blendChan (oldClr->g, newClr[PLUTVAL_GREEN], frac, XFORM_SCALE); color.b = blendChan (oldClr->b, newClr[PLUTVAL_BLUE], frac, XFORM_SCALE); SetNativePaletteColor (newmap->palette, i, color); } colormaps[index] = newmap; release_colormap (curmap); } UnlockMutex (maplock); if (TicksLeft <= 0) { // asked for immediate xform or already done finish_colormap_xform (x); } Changed = TRUE; } UnlockMutex (XFormControl.Lock); return Changed; }
BOOLEAN SetColorMap (COLORMAPPTR map) { int start, end; int total_size; UBYTE *colors = (UBYTE*)map; TFB_ColorMap **mpp; if (!map) return TRUE; start = *colors++; end = *colors++; if (start > end) { log_add (log_Warning, "ERROR: SetColorMap(): " "starting map (%d) not less or eq ending (%d)", start, end); return FALSE; } if (start >= MAX_COLORMAPS) { log_add (log_Warning, "ERROR: SetColorMap(): " "starting map (%d) beyond range (0-%d)", start, (int)MAX_COLORMAPS - 1); return FALSE; } if (end >= MAX_COLORMAPS) { log_add (log_Warning, "SetColorMap(): " "ending map (%d) beyond range (0-%d)\n", end, (int)MAX_COLORMAPS - 1); end = MAX_COLORMAPS - 1; } total_size = end + 1; LockMutex (maplock); if (total_size > mapcount) mapcount = total_size; // parse the supplied PLUTs into our colormaps for (mpp = colormaps + start; start <= end; ++start, ++mpp) { int i; TFB_ColorMap *newmap; TFB_ColorMap *oldmap; oldmap = *mpp; newmap = clone_colormap (oldmap, start); for (i = 0; i < NUMBER_OF_PLUTVALS; ++i, colors += PLUTVAL_BYTE_SIZE) { Color color; color.a = 0xff; color.r = colors[PLUTVAL_RED]; color.g = colors[PLUTVAL_GREEN]; color.b = colors[PLUTVAL_BLUE]; SetNativePaletteColor (newmap->palette, i, color); } *mpp = newmap; release_colormap (oldmap); } UnlockMutex (maplock); return TRUE; }