home *** CD-ROM | disk | FTP | other *** search
- /*
- * $Id: $
- */
-
- /*
- * Mesa 3-D graphics library
- * Version: 3.1
- * Copyright (C) 1995 Brian Paul (brianp@ssec.wisc.edu)
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library 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
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #include <math.h>
- #include <stddef.h>
-
- #define NO_CONTEXT_AVAILABLE
- #include <AOS/amigamesa.h>
- #include <graphics/view.h>
-
- #include "palettes/palettes.c" /* pre-defined palettes */
- #include "palettes/error.c" /* match-error tables */
- #include "palettes/remap.c" /* remap-tables */
- #include "palettes/clamps.c" /* clamping-tables */
-
- #define MATCH_ERROR
- #define REAL_HPCR
- //#undef ASM_CODE
- #undef MATCH_6BITS
- #undef REVISIT_PALETTE
- #undef REVISIT_YCrCb
-
- /*****************************************************************************/
- /* modelling */
- /*****************************************************************************/
-
- /* allocate all pens for a given max-number of colors into a given list */
- static BOOL AllocColors(struct ColorEntry *Cols, GLshort Number, struct Screen *Screen)
- {
- register LONG pen;
- register BOOL fail = GL_TRUE;
- register struct ColorMap *ColorMap = Screen->ViewPort.ColorMap;
- ULONG ColTab[3];
- GLshort fill = Number;
- #ifdef REVISIT_PALETTE
- ULONG ColorTable[256][3];
- GLshort j = Number, k = 256;
- #endif
-
- do {
- GLshort newNumber = remap[Number];
-
- if ((pen = ObtainBestPen(ColorMap, c8toc32(Cols[newNumber].orgEntry.r),
- c8toc32(Cols[newNumber].orgEntry.g),
- c8toc32(Cols[newNumber].orgEntry.b),
- OBP_Precision, PRECISION_EXACT, TAG_DONE)) == -1)
- fail = GL_FALSE;
- else {
- Cols[newNumber].PenNo = pen;
- GetRGB32(ColorMap, pen, 1, ColTab);
- Cols[newNumber].mapEntry.r = ColTab[0] >> 24;
- Cols[newNumber].mapEntry.g = ColTab[1] >> 24;
- Cols[newNumber].mapEntry.b = ColTab[2] >> 24;
- }
- } while (--Number >= 0); /* Number is the max-value, not including! */
-
- #ifdef REVISIT_PALETTE
- GetRGB32(ColorMap, 0, 256, ColorTable[0]);
-
- while (--k >= 0) {
- GLshort newNumber = remap[k];
- register GLshort i = j;
-
- #ifndef REVISIT_YCrCb
- register GLshort match = 0x7FFF, max = 0;
-
- for (pen = 0; i >= 0; i--) {
- register GLshort thismatch, thismax;
-
- #ifdef MATCH_ERROR
- register GLshort sum;
-
- if ((thismatch = (GLshort)((ColorTable[i][0] >> 24)) - (GLshort)Cols[newNumber].orgEntry.r) < 0)
- thismatch = -thismatch;
- thismax = thismatch;
- if ((sum = (GLshort)((ColorTable[i][1] >> 24)) - (GLshort)Cols[newNumber].orgEntry.g) < 0)
- sum = -sum;
- if (sum > thismax)
- thismax = sum;
- thismatch += sum;
- if ((sum = (GLshort)((ColorTable[i][2] >> 24)) - (GLshort)Cols[newNumber].orgEntry.b) < 0)
- sum = -sum;
- if (!(thismatch += sum)) {
- pen = i;
- break;
- }
- if (sum > thismax)
- thismax = sum;
- #else
- register GLshort sum;
-
- sum = error111[(GLshort)((ColorTable[i][0] >> 24)) - (((GLshort)Cols[newNumber].orgEntry.r) * 4) + 0];
- thismatch = sum;
- thismax = sum;
- sum = error111[(GLshort)((ColorTable[i][1] >> 24)) - (((GLshort)Cols[newNumber].orgEntry.g) * 4) + 1];
- thismatch += sum;
- if (sum > thismax)
- thismax = sum;
- sum = error111[(GLshort)((ColorTable[i][2] >> 24)) - (((GLshort)Cols[newNumber].orgEntry.b) * 4) + 2];
- if (!(thismatch += sum)) {
- pen = i;
- break;
- }
- if (sum > thismax)
- thismax = sum;
- #endif
- #else
- /* maybe the best match is to match in YCrCb- not in RGB-space */
- register GLint match = 1000000000, max = 0;
- double Y, Cr, Cb;
-
- #define toY(R, G, B) ( 0.29900 * R + 0.58700 * G + 0.11400 * B)
- #define toCr(R, G, B) (-0.16874 * R - 0.33126 * G + 0.50000 * B)
- #define toCb(R, G, B) ( 0.50000 * R - 0.41869 * G - 0.08131 * B)
-
- Y = toY(Cols[newNumber].orgEntry.r, Cols[newNumber].orgEntry.g, Cols[newNumber].orgEntry.b);
- Cr = toCr(Cols[newNumber].orgEntry.r, Cols[newNumber].orgEntry.g, Cols[newNumber].orgEntry.b);
- Cb = toCb(Cols[newNumber].orgEntry.r, Cols[newNumber].orgEntry.g, Cols[newNumber].orgEntry.b);
-
- for (pen = 0; i >= 0; i--) {
- register double sum;
- register double thismatch, thismax;
-
- if ((thismatch = toY((ColorTable[i][0] >> 24), (ColorTable[i][1] >> 24), (ColorTable[i][2] >> 24)) - Y) < 0)
- thismatch = -thismatch;
- thismax = thismatch;
-
- if ((sum = toCr((ColorTable[i][0] >> 24), (ColorTable[i][1] >> 24), (ColorTable[i][2] >> 24)) - Cr) < 0)
- sum = -sum;
- if (sum > thismax)
- thismax = sum;
- thismatch += sum;
-
- if ((sum = toCb((ColorTable[i][0] >> 24), (ColorTable[i][1] >> 24), (ColorTable[i][2] >> 24)) - Cb) < 0)
- sum = -sum;
- if (!(thismatch += sum)) {
- pen = i;
- break;
- }
- if (sum > thismax)
- thismax = sum;
- #endif
-
- /* this is the key for good pen-matching! :^) */
- if (match < (GLint)thismatch)
- continue;
- if (match == (GLint)thismatch) {
- if (max < (GLint)thismax)
- continue;
- /* what to do now? match is equal, max is equal */
- if (max == (GLint)thismax) {
- }
- }
-
- match = (GLint)thismatch;
- max = (GLint)thismax;
- pen = i;
- }
-
- if (pen != Cols[newNumber].PenNo) {
- DEBUGOUT(0, " original: 0x%06x -> old: 0x%06x (%4d/%4d/%4d), new: 0x%06x (%4d/%4d/%4d) -> old: 0x%x, new: 0x%x\n",
- *((ULONG *)&Cols[newNumber].orgEntry) >> 8,
- *((ULONG *)&Cols[newNumber].mapEntry) >> 8,
- Cols[newNumber].mapEntry.r - Cols[newNumber].orgEntry.r,
- Cols[newNumber].mapEntry.g - Cols[newNumber].orgEntry.g,
- Cols[newNumber].mapEntry.b - Cols[newNumber].orgEntry.b,
- ((ColorTable[pen][0] >> 8) & 0x00FF0000) |
- ((ColorTable[pen][1] >> 16) & 0x0000FF00) |
- ((ColorTable[pen][2] >> 24) & 0x000000FF),
- (ColorTable[pen][0] >> 24) - Cols[newNumber].orgEntry.r,
- (ColorTable[pen][1] >> 24) - Cols[newNumber].orgEntry.g,
- (ColorTable[pen][2] >> 24) - Cols[newNumber].orgEntry.b,
- Cols[newNumber].PenNo, pen);
- #if 0
- /* lock new key without changing it's value and release old pen */
- ObtainPen(Screen->ViewPort.ColorMap, pen, 0, 0, 0, PENF_NO_SETCOLOR);
- ReleasePen(Screen->ViewPort.ColorMap, Cols[newNumber].PenNo);
- #endif
- Cols[newNumber].PenNo = pen;
- }
- }
- #endif
-
- /* this is for PenNo-clamping of grey-levels beyond 64 */
- if (fill < 255) {
- do {
- Cols[++fill].PenNo = Cols[fill].PenNo;
- } while (fill <= 255);
- }
-
- return (BOOL) fail;
- };
-
- /* free all pens for all PaletteModes */
- static void FreeColors(struct ColorEntry *Cols, GLshort Number, struct Screen *Screen)
- {
- while (--Number >= 0)
- ReleasePen(Screen->ViewPort.ColorMap, Cols[Number].PenNo);
- };
-
- /*****************************************************************************/
- /* encoding */
- /*****************************************************************************/
-
- /* match a pen to a RGB */
- static inline ULONG Match(register unsigned char R __asm__("d0"),
- register unsigned char G __asm__("d1"),
- register unsigned char B __asm__("d2"),
- register amigaMesaContext amesa __asm__("a0")) {
- register ULONG pen = 0;
-
- /* pen-caching doesn't make sense for dithers, as the
- * random character of the dither-matrice are allmost
- * never the same for neighbourhood-pixels (spans/arrays)
- * only for random jumping pixels (random + random = linear)
- * but that's highly unlikly
- * you can take a look at the cache-performance and verify
- * this statement
- */
- if (TstF(amesa->flags, PALETTE_CACHE)) {
- #define cachedPen pen
- /* use G as LUT 'cause it has the middle energy */
- if ((cachedPen = *((ULONG *) & amesa->penCache[G]))) {
- cachedPen >>= 8;
- if ((unsigned char)cachedPen == (unsigned char)B) {
- cachedPen >>= 8;
- if ((unsigned char)cachedPen == (unsigned char)R) {
- cachedPen >>= 8;
- return cachedPen;
- }
- }
- }
- cachedPen = ((((R << 8) | B) << 8) | CACHED);
- *((ULONG *) & amesa->penCache[G]) = cachedPen;
- }
-
- {
- register GLshort i = amesa->PaletteCols;
- register struct ColorEntry *entries = amesa->Palette + i;
- #ifdef MATCH_ERROR
- register GLshort *errors = (GLshort *)amesa->MatchErrors;
- #endif
-
- /* infinite bad start-match */
- register GLshort match = 0x7FFF;
-
- /* pal332-mask:
- *
- * 0x00 = 0b000 00000
- * 0x20 = 0b001 00000
- * 0x40 = 0b010 00000
- * 0x80 = 0b100 00000
- * 0xA0 = 0b101 00000
- * 0xC0 = 0b110 00000
- * 0xE0 = 0b111 00000
- * -------------------
- * 0xE0 = 0b111 00000
- *
- * if (!(R & (~0xE0)))
- * entries -= 256 - (((R >> 5) + 1) * 32);
- * entries += (R >> 5) * 32;
- * if (!(G & (~0xE0)))
- * entries -= 32 - (((G >> 5) + 1) * 4);
- * entries += (G >> 5) * 4;
- * if (!(B & (~0xC0)))
- * entries -= 4 - (((B >> 6) + 1) * 1);
- * entries += (B >> 5) * 1;
- *
- * pal189-mask:
- *
- * 0x00 = 0b0000 0000
- * 0x1F = 0b0001 1111
- * 0x3F = 0b0011 1111
- * 0x5F = 0b0101 1111
- * 0x7F = 0b1000 1111
- * 0x9F = 0b1001 1111
- * 0xBF = 0b1011 1111
- * 0xDF = 0b1101 1111
- * 0xFF = 0b1111 1111
- * -------------------
- * 0xF0 = 0b1111 ????
- *
- * if (!(R & (~0xFF)))
- * entries += ?;
- *
- * palgrey-mask:
- *
- * 0x00 = 0b000000 00
- * 0x04 = 0b000001 00
- * 0x08 = 0b000010 00
- * 0x0C = 0b000011 00
- * .... = ........ 00
- * 0xFC = 0b111111 00
- * -------------------
- * 0xFC = 0b111111 00
- *
- * if (!(R & (~0xFC)))
- * entries -= 64 - (((R >> 2) + 1) * 1);
- * if (!(G & (~0xFC)))
- * entries -= 16 - (((G >> 2) + 1) * 1);
- * if (!(B & (~0xFC)))
- * entries -= 4 - (((B >> 2) + 1) * 1);
- */
-
- /* find match */
- for (; i >= 0; i--, entries--) {
- register GLshort thismatch;
-
- #ifdef MATCH_ERROR
- if (!(thismatch = errors[(((GLshort)entries->mapEntry.r - (GLshort)R) * 4) + 0] +
- errors[(((GLshort)entries->mapEntry.g - (GLshort)G) * 4) + 1] +
- errors[(((GLshort)entries->mapEntry.b - (GLshort)B) * 4) + 2])) {
- pen = i;
- break;
- }
- #else
- register GLshort sum;
-
- if ((thismatch = (GLshort)(entries->mapEntry.r) - (GLshort)R) < 0)
- thismatch = -thismatch;
- if ((sum = (GLshort)(entries->mapEntry.g) - (GLshort)G) < 0)
- sum = -sum;
- thismatch += sum;
- if ((sum = (GLshort)(entries->mapEntry.b) - (GLshort)B) < 0)
- sum = -sum;
- if (!(thismatch += sum)) {
- pen = i;
- break;
- }
- #endif
-
- if (match > thismatch) {
- match = thismatch;
- pen = i;
- }
- }
- }
-
- pen = (ULONG) (amesa->Palette[pen].PenNo);
- if (amesa->flags & PALETTE_CACHE)
- amesa->penCache[G].PenCch = (unsigned char)(pen);
-
- return pen;
- };
-
- /*****************************************************************************/
-
- ULONG GetPen(register unsigned char R __asm__("d0"),
- register unsigned char G __asm__("d1"),
- register unsigned char B __asm__("d2"),
- register amigaMesaContext amesa __asm__("a0")) {
- /* quick original HPCR-match, looks very dark
- * is not so good without dithering, in the
- * XMesa they talk about a special colormap
- * but I havn't found it
- */
- #ifdef REAL_HPCR
- if (IS_HPCR(amesa->trueColor)) {
- #ifndef ASM_CODE
- return amesa->Palette[c24toc8(((GLshort *)amesa->MatchErrors)[(R * 4) + 0],
- ((GLshort *)amesa->MatchErrors)[(G * 4) + 1],
- ((GLshort *)amesa->MatchErrors)[(B * 4) + 2])].PenNo;
- #else
- __asm__("
- .equ erroffs,%5
- .equ paloffs,%4
- .equ amesa,%3
- .equ err,a1
- .equ mask,d3
- .equ r,%0
- .equ g,%1
- .equ b,%2
-
- move%.l amesa@(erroffs),err | amesa->MatchErrors
- moveq #0xFFFFFFE0,mask
- move%.w err@(0,r:w:8),r | amesa->MatchErrors[R][0]
- and%.w mask,r | amesa->MatchErrors[R][0] & 0xE0
- move%.w err@(2,g:w:8),g | amesa->MatchErrors[G][1]
- and%.w mask,g | amesa->MatchErrors[G][1] & 0xE0
- move%.w err@(4,b:w:8),b | amesa->MatchErrors[B][2]
- and%.w mask,b | amesa->MatchErrors[B][2] & 0xE0
- lsr%.w #3,g | (amesa->MatchErrors[G][1] & 0xE0) >> 3
- lsr%.w #6,b | (amesa->MatchErrors[B][2] & 0xE0) >> 6
- or%.w g,r
- or%.w b,r
- move%.b amesa@(paloffs+9,r:w:8),r"
- : "=d" (R)
- : "d" (R)
- , "d" (G)
- , "d" (B)
- , "a" (amesa)
- , "i" (117) /* offsetof(amesa, Palette) doesn't work here ATTENTION if it changes */
- , "i" (2158) /* offsetof(amesa, MatchErrors) doesn't work here ATTENTION if it changes */
- : "d3", "a1", "cc");
- return R;
- #endif
- }
- #endif
-
- /* every grey-value we can compute does really exists
- * in the grey-map so the following transformation is
- * allways the same result as if we try to match
- * (the match was done in AllocCMap)
- * take a look at "palettes/quickgrey.c" why I choose
- * this approximated (and on the first view) totally
- * wrong function
- * the function does produce levels beyond 64 (69,...)
- * but for grey we must clamp negative values so we can
- * put the value for palette[64].PenNo into the higher
- * (unused) PenNos
- */
- if (IS_GREY(amesa->trueColor)) {
- #ifndef ASM_CODE
- return amesa->Palette[((R << 5) + (G << 6) + (G << 5) + (G << 1) + (B << 3) + B) >> 9].PenNo; /* aprox. to shifts */
- #else
- __asm__("
- .equ paloffs,%4
- .equ amesa,%3
- .equ r,%0
- .equ g,%1
- .equ b,%2
-
- lsl%.w #5,r | (r << 5)
- add%.w b,r | b + (r << 5)
- lsl%.w #3,b | (b << 3)
- add%.w b,r | (b << 3) + b + (r << 5)
- add%.w g,g | (g << 1)
- add%.w g,r | (g << 1) + (b << 3) + b + (r << 5)
- lsl%.w #4,g | (g << 5)
- add%.w g,r | (g << 5) + (g << 1) + (b << 3) + b + (r << 5)
- add%.w g,g | (g << 6)
- add%.w g,r | (g << 6) + (g << 5) + (g << 1) + (b << 3) + b + (r << 5)
- lsr%.w #8,r | ((g << 6) + (g << 5) + (g << 1) + (b << 3) + b + (r << 5)) >> 9
- lsr%.w #1,r
- move%.b amesa@(paloffs+9,r:w:8),r"
- : "=d" (R)
- : "d" (R)
- , "d" (G)
- , "d" (B)
- , "a" (amesa)
- , "i" (117) /* offsetof(amesa, Palette) doesn't work here ATTENTION if it changes */
- : "cc");
- return R;
- #endif
- }
-
- /* on most graphics-cards there are only 6bits per palette-entry
- * so the error produced by this shouldn't be too high but make the
- * matching faster (hopefull, not tested yet)
- */
- #ifdef MATCH_6BITS
- R &= 0xFC;
- G &= 0xFC;
- B &= 0xFC;
- #endif
-
- return Match(R, G, B, amesa);
- };
-
- /*****************************************************************************/
-
- /* red, green and blue have different modification-values
- * max red is -15/16
- * max green is -15/16
- * max blue is -30/32
- * max alpha is 0 )alpga exists only for alignment reasons)
- *
- * generation:
- * r = ?
- * g = -r + 1;
- * b =
- */
- static const GLshort DMatrix[16][2][4] = {
- { { 16,-11, 6, 0}, {-15, 12, -4, 0} },
- { { -4, 15,-18, 0}, { 5,-14, 20, 0} },
- { { 1, -7, 26, 0}, { 0, 8,-24, 0} },
- { {-11, 3, 14, 0}, { 12, -2, 16, 0} },
- { { 14, -8, 2, 0}, {-13, 9, 0, 0} },
- { { -6, 14,-22, 0}, { 7,-13, 24, 0} },
- { { 3, -4, 30, 0}, { -2, 5,-28, 0} },
- { { -9, 2,-10, 0}, { 10, -1, 12, 0} },
- { { 15,-10, 8, 0}, {-14, 11, -6, 0} },
- { { -5, 16,-16, 0}, { 6,-15, 18, 0} },
- { { 2, -6, 28, 0}, { -1, 7,-26, 0} },
- { {-10, 4,-12, 0}, { 11, -3, 14, 0} },
- { { 13, -9, 4, 0}, {-12, 10, -2, 0} },
- { { -7, 13,-20, 0}, { 8,-12, 22, 0} },
- { { 4, -5, 32, 0}, { -3, 6,-30, 0} },
- { { -8, 1, 8, 0}, { 9, 0, 10, 0} },
- };
-
- #define DITHER_APPROX(r, g, b, x, y) { \
- x &= 0xF; \
- y &= 0x1; \
- \
- r = clampFF[(GLshort)r + DMatrix[x][y][0] + 32]; \
- g = clampFF[(GLshort)g + DMatrix[x][y][1] + 32]; \
- b = clampFF[(GLshort)b + DMatrix[x][y][2] + 32]; \
- }
-
- ULONG GetPenDithered(register unsigned char R __asm__("d0"),
- register unsigned char G __asm__("d1"),
- register unsigned char B __asm__("d2"),
- register amigaMesaContext amesa __asm__("a0"),
- register unsigned char X __asm__("d3"), /* as the ditherkernel doesn't exceed 2^8 */
- register unsigned char Y __asm__("d4")) { /* we can safe shrink the ccordinates to uc */
- /* quick original HPCR-match, looks very dark
- * but is fast and looks considerable better
- * than shifting or matching, in the
- * XMesa they talk about a special colormap
- * but I havn't found it
- */
- #ifdef REAL_HPCR
- if (IS_HPCR(amesa->trueColor)) {
- #ifndef ASM_CODE
- X &= 0xF;
- Y &= 0x1;
- return amesa->Palette[c24toc8(((GLshort *)amesa->MatchErrors)[(R * 4) + 0] + DMatrix[X][Y][0],
- ((GLshort *)amesa->MatchErrors)[(G * 4) + 1] + DMatrix[X][Y][1],
- ((GLshort *)amesa->MatchErrors)[(B * 4) + 2] + DMatrix[X][Y][2])].PenNo;
- #else
- __asm__("
- .equ y,%8
- .equ x,%7
- .equ mat,%6
- .equ erroffs,%5
- .equ paloffs,%4
- .equ amesa,%3
- .equ err,a1
- .equ mask,d3
- .equ r,%0
- .equ g,%1
- .equ b,%2
-
- and%.w #0x000F,x | X & 0xF
- and%.w #0x0001,y | Y & 0x1
- add%.w x,x
- or%.w y,x
- move%.l amesa@(erroffs),err | amesa->MatchErrors
- moveq #0xFFFFFFE0,mask
- move%.w err@(0,r:w:8),r | amesa->MatchErrors[R][0]
- add%.w mat@(0,x:w:8),r | DMatrix[X][Y][0]
- and%.w mask,r | amesa->MatchErrors[R][0] & 0xE0
- move%.w err@(2,g:w:8),g | amesa->MatchErrors[G][1]
- add%.w mat@(1,x:w:8),g | DMatrix[X][Y][1]
- and%.w mask,g | amesa->MatchErrors[G][1] & 0xE0
- move%.w err@(4,b:w:8),b | amesa->MatchErrors[B][2]
- add%.w mat@(2,x:w:8),b | DMatrix[X][Y][2]
- and%.w mask,b | amesa->MatchErrors[B][2] & 0xE0
- lsr%.w #3,g | (amesa->MatchErrors[G][1] & 0xE0) >> 3
- lsr%.w #6,b | (amesa->MatchErrors[B][2] & 0xE0)>> 6
- or%.w g,r
- or%.w b,r
- move%.b amesa@(paloffs+9,r:w:8),r"
- : "=d" (R)
- : "d" (R)
- , "d" (G)
- , "d" (B)
- , "a" (amesa)
- , "i" (117) /* offsetof(amesa, Palette) doesn't work here ATTENTION if it changes */
- , "i" (2158) /* offsetof(amesa, MatchErrors) doesn't work here ATTENTION if it changes */
- , "a" (DMatrix)
- , "d" (X)
- , "d" (Y)
- : "a1", "cc");
- return R;
- #endif
- }
- #endif
-
- /* apply the HPCR-dither-kernel as if it is a
- * ordered dither-matrix, gives good results
- */
- DITHER_APPROX(R, G, B, X, Y);
-
- /* every grey-value we can compute does really exists
- * in the grey-map so the following transformation is
- * allways the same result as if we try to match
- * (the match was done in AllocCMap)
- * take a look at "palettes/quickgrey.c" why I choose
- * this approximated (and on the first view) totally
- * wrong function
- * the function does produce levels beyond 64 (69,...)
- * but for grey we must clamp negative values so we can
- * put the value for palette[64].PenNo into the higher
- * (unused) PenNos
- */
- if (IS_GREY(amesa->trueColor)) {
- #ifndef ASM_CODE
- return amesa->Palette[((R << 5) + (G << 6) + (G << 5) + (G << 1) + (B << 3) + B) >> 9].PenNo; /* aprox. to shifts */
- #else
- __asm__("
- .equ paloffs,%4
- .equ amesa,%3
- .equ pal,%3
- .equ r,%0
- .equ g,%1
- .equ b,%2
-
- lsl%.w #5,r | (r << 5)
- add%.w b,r | b + (r << 5)
- lsl%.w #3,b | (b << 3)
- add%.w b,r | (b << 3) + b + (r << 5)
- add%.w g,g | (g << 1)
- add%.w g,r | (g << 1) + (b << 3) + b + (r << 5)
- lsl%.w #4,g | (g << 5)
- add%.w g,r | (g << 5) + (g << 1) + (b << 3) + b + (r << 5)
- add%.w g,g | (g << 6)
- add%.w g,r | (g << 6) + (g << 5) + (g << 1) + (b << 3) + b + (r << 5)
- lsr%.w #8,r | ((g << 6) + (g << 5) + (g << 1) + (b << 3) + b + (r << 5)) >> 9
- lsr%.w #1,r
- move%.b amesa@(paloffs+9,r:w:8),r"
- : "=d" (R)
- : "d" (R)
- , "d" (G)
- , "d" (B)
- , "a" (amesa)
- , "i" (117) /* offsetof(amesa, Palette) doesn't work here ATTENTION if it changes */
- : "cc");
- return R;
- #endif
- }
-
- /* on most graphics-cards there are only 6bits per palette-entry
- * so the error produced by this shouldn't be too high but make the
- * matching faster (hopefull, not tested yet)
- */
- #ifdef MATCH_6BITS
- R &= 0xFC;
- G &= 0xFC;
- B &= 0xFC;
- #endif
-
- return Match(R, G, B, amesa);
- };
-
- /*****************************************************************************/
- /* preparing */
- /*****************************************************************************/
-
- /* calls AllocColors depend of the PaletteMode */
- void AllocCMap(amigaMesaContext amesa, struct Screen *Scr)
- {
- DEBUGOUT(1, "AllocCMap(0x%08x, 0x%08x)\n", amesa, Scr);
-
- /* clear pen-cache */
- if (TstF(amesa->flags, PALETTE_CACHE))
- bzero(amesa->penCache, sizeof(amesa->penCache));
-
- /* clear and refill palette */
- if (IS_WEIGHTED(amesa->trueColor)) {
- amesa->PaletteCols = palNumCols - 1;
- amesa->MatchErrors = &error111[ERROR_RANGE / 2][0];
-
- CopyMem(Palette, amesa->Palette, palNumCols * sizeof(struct ColorEntry));
- }
- else if (IS_GREY(amesa->trueColor)) {
- amesa->PaletteCols = palNumColsGrey - 1;
- amesa->MatchErrors = &errorRGB[ERROR_RANGE / 2][0];
-
- CopyMem(PaletteGrey, amesa->Palette, palNumColsGrey * sizeof(struct ColorEntry));
- }
- else if (IS_HPCR(amesa->trueColor)) {
- amesa->PaletteCols = palNumColsHPCR - 1;
- #ifdef REAL_HPCR
- amesa->MatchErrors = &errorHPCR[ERROR_RANGE / 2][0];
- #else
- amesa->MatchErrors = &error111[ERROR_RANGE / 2][0];
- #endif
-
- #ifdef REAL_HPCR
- CopyMem(Palette332, amesa->Palette, palNumCols * sizeof(struct ColorEntry));
- #else
- CopyMem(PaletteHPCR, amesa->Palette, palNumCols * sizeof(struct ColorEntry));
- #endif
- }
- else {
- amesa->PaletteCols = palNumCols332 - 1;
- amesa->MatchErrors = &error565[ERROR_RANGE / 2][0];
-
- CopyMem(Palette332, amesa->Palette, palNumCols332 * sizeof(struct ColorEntry));
- }
-
- AllocColors(amesa->Palette, amesa->PaletteCols, Scr);
- #ifdef AOS_WARP3D
- if (amesa->TDdriver) {
- W3D_Color *TDpalette = &amesa->TDdriver->Palette;
- struct ColorEntry *palette = amesa->Palette;
- short int i = 256;
-
- while (--i >= 0) {
- TDpalette->r = (W3D_Float)palette->orgEntry.r;
- TDpalette->g = (W3D_Float)palette->orgEntry.g;
- TDpalette->b = (W3D_Float)palette->orgEntry.b;
- TDpalette->a = (W3D_Float) 0.0;
- TDpalette++;
- palette++;
- }
- }
- #endif
- };
-
- /* calls FreeColors depend of the PaletteMode */
- void FreeCMap(amigaMesaContext amesa, struct Screen *Scr)
- {
- DEBUGOUT(1, "FreeCMap(0x%08x, 0x%08x)\n", amesa, Scr);
-
- FreeColors(amesa->Palette, amesa->PaletteCols + 1, Scr);
- };
-
- void RethinkCMap(amigaMesaContext amesa)
- {
- GLshort index = 256;
- GLuint *ItoP, *PtoI;
-
- DEBUGOUT(1, "RethinkCMap(0x%08x)\n", amesa);
-
- ItoP = amesa->ItoP;
- PtoI = amesa->PtoI;
-
- while (--index >= 0) {
- GLubyte r, g, b, pen;
-
- r = (GetRGBPLocal(index) >> 24) & 0xFF;
- g = (GetRGBPLocal(index) >> 16) & 0xFF;
- b = (GetRGBPLocal(index) >> 8) & 0xFF;
- pen = PLG_RGBA(amesa, r, g, b); /* no dither (index-mode), no shift (gives better quality) */
-
- /* the format of index is RGBP, red|green|blue|pen */
- GetRGBPLocal(index) = (GetRGBPLocal(index) & 0xFFFFFF00) | pen;
- /* the index recovers from index = PtoI[pen] */
- GetIndexLocal(pen) = (GetIndexLocal(pen) & 0xFFFFFF00) | index;
- }
- }
-
- /* converts one PaletteMode to another on the run */
- void ConvertCMap(amigaMesaContext amesa, palMode newColor, struct Screen *Scr)
- {
- DEBUGOUT(1, "ConvertCMap(0x%08x, 0x%x, 0x%08x)\n", amesa, newColor, Scr);
-
- if (amesa->trueColor != newColor) {
- amesa->trueColor = newColor;
-
- if (amesa->depth <= 8) {
- FreeCMap(amesa, Scr);
- AllocCMap(amesa, Scr);
- RethinkCMap(amesa);
- }
- }
- };
-