This is hgrconv.c in view mode; [Download] [Up]
#ifndef USE_COLOR #define USE_COLOR 1 #endif #include <c.h> #include <string.h> #include "hgrtable.h" #include "hgrconv.h" #if !USE_COLOR void apple_to_next (const unsigned char *a2buf, unsigned char nextbuf[192][72], int first_row, int height) { const unsigned int *row_base = row_to_addr + first_row; unsigned long *nbuf = (unsigned long *) &nextbuf[first_row][0]; const unsigned char *p; short rows_left, n; for (rows_left = height - 1; rows_left != -1; rows_left--) { p = a2buf + *row_base++; for (n = 4; n != -1; n--) { #if 0 /* Coerce compiler into using bitfield instructions. Nonportable. */ /* Oddly enough, the shift-and-mask code below is faster, even * though it's ~twice as many instructions. The bitfield code * performs 8 read-modify-writes as opposed to 4 writes. Must be * the difference. * I'll leave this here cuz it looks cool... */ void *buf = (void *) nbuf; ((struct { int a:14, b:14; } *) buf)->a = one_to_two_bpp[*p++]; ((struct { int a:14, b:14; } *) buf)->b = one_to_two_bpp[*p++]; ((struct { int a:12, b:14; } *) (buf+2))->b = one_to_two_bpp[*p++]; ((struct { int a:10, b:14; } *) (buf+4))->b = one_to_two_bpp[*p++]; ((struct { int a:8, b:14; } *) (buf+6))->b = one_to_two_bpp[*p++]; ((struct { int a:6, b:14; } *) (buf+8))->b = one_to_two_bpp[*p++]; ((struct { int a:4, b:14; } *) (buf+10))->b = one_to_two_bpp[*p++]; ((struct { int a:18, b:14; } *) (buf+10))->b = one_to_two_bpp[*p++]; nbuf = (void *) nbuf + 14; #else unsigned long a, b, c; /* NOTE: This assumes a big-endian CPU! */ a = one_to_two_bpp[*p++] << 18; b = one_to_two_bpp[*p++] << 4; c = one_to_two_bpp[*p++]; *nbuf++ = a | b | (c >> 10); a = one_to_two_bpp[*p++] << 8; b = one_to_two_bpp[*p++]; *nbuf++ = (c << 22) | a | (b >> 6); a = one_to_two_bpp[*p++] << 12; c = one_to_two_bpp[*p++]; *nbuf++ = (b << 26) | a | (c >> 2); a = one_to_two_bpp[*p++]; *((unsigned short *) nbuf)++ = a | (c << 14); #endif } } } #else /* Define the Reg type. */ /* Assumes big endian: */ typedef union { struct { char filler1, filler2; unsigned char hi; unsigned char c; } c; struct { unsigned short filler; unsigned short s; } s; unsigned long l; } Reg; void apple_to_next (const unsigned char *a2buf, unsigned char nextbuf[192][72], int first_row, int height) { const unsigned int *row_base = row_to_addr + first_row; unsigned long *nbuf = (unsigned long *) &nextbuf[first_row][0]; const unsigned char *p; register short rows_left, n; /* NOTE: This assumes a big-endian CPU! */ for (rows_left = height - 1; rows_left >= 0; rows_left--) { Reg a2bits; unsigned long a, b, c; #define NEXT_A2BITS a2bits.s.s &= 0x7F; a2bits.s.s <<= 7; a2bits.c.c = *p++ p = a2buf + *row_base++; /* Left edge - 5 bytes */ /* Create the first long and ship it out. */ a2bits.l = *p++; a = color_one_to_two_bpp_even[a2bits.l] << 24; NEXT_A2BITS; b = color_one_to_two_bpp_odd[a2bits.l] << 10; NEXT_A2BITS; c = color_one_to_two_bpp_even[a2bits.l]; *nbuf++ = a | b | (c >> 4); /* Create the second long and ship it out. */ NEXT_A2BITS; a = color_one_to_two_bpp_odd[a2bits.l] << 14; NEXT_A2BITS; b = color_one_to_two_bpp_even[a2bits.l]; *nbuf++ = (c << 28) | a | b; /* Middle - 32 bytes */ for (n = 1; n >= 0; n--) { NEXT_A2BITS; a = color_one_to_two_bpp_odd[a2bits.l] << 18; NEXT_A2BITS; b = color_one_to_two_bpp_even[a2bits.l] << 4; NEXT_A2BITS; c = color_one_to_two_bpp_odd[a2bits.l]; *nbuf++ = a | b | (c >> 10); NEXT_A2BITS; a = color_one_to_two_bpp_even[a2bits.l] << 8; NEXT_A2BITS; b = color_one_to_two_bpp_odd[a2bits.l]; *nbuf++ = (c << 22) | a | (b >> 6); NEXT_A2BITS; a = color_one_to_two_bpp_even[a2bits.l] << 12; NEXT_A2BITS; c = color_one_to_two_bpp_odd[a2bits.l]; *nbuf++ = (b << 26) | a | (c >> 2); NEXT_A2BITS; a = color_one_to_two_bpp_even[a2bits.l] << 16; NEXT_A2BITS; a |= color_one_to_two_bpp_odd[a2bits.l] << 2; NEXT_A2BITS; b = color_one_to_two_bpp_even[a2bits.l]; *nbuf++ = (c << 30) | a | (b >> 12); NEXT_A2BITS; a = color_one_to_two_bpp_odd[a2bits.l] << 6; NEXT_A2BITS; c = color_one_to_two_bpp_even[a2bits.l]; *nbuf++ = (b << 20) | a | (c >> 8); NEXT_A2BITS; a = color_one_to_two_bpp_odd[a2bits.l] << 10; NEXT_A2BITS; b = color_one_to_two_bpp_even[a2bits.l]; *nbuf++ = (c << 24) | a | (b >> 4); NEXT_A2BITS; a = color_one_to_two_bpp_odd[a2bits.l] << 14; NEXT_A2BITS; c = color_one_to_two_bpp_even[a2bits.l]; *nbuf++ = (b << 28) | a | c; } /* Right edge - three bytes. */ NEXT_A2BITS; a = color_one_to_two_bpp_odd[a2bits.l] << 18; NEXT_A2BITS; b = color_one_to_two_bpp_even[a2bits.l] << 4; NEXT_A2BITS; c = color_one_to_two_bpp_odd[a2bits.l]; *nbuf++ = a | b | (c >> 10); /* Handle trailing stuff. */ a2bits.s.s &= 0x7F; a2bits.s.s <<= 7; *nbuf++ = (c << 22) | (color_one_to_two_bpp_even[a2bits.l] << 8); } } #endif /* Compares 40 bytes, returning TRUE iff they are equal, FALSE otherwise. */ /* Requires p1, p2 refer to long-addressable addresses. */ static inline int equal40bytes (const unsigned char *p1, const unsigned char *p2) { const unsigned long *l1 = (const unsigned long *) p1; const unsigned long *l2 = (const unsigned long *) p2; return ( (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++) && (*l1++ == *l2++)); } /* Finds the areas of the screens that differ in scr1 and scr2. It breaks the * screens into 12 16-row sections. If any two bytes differ in any section, * changed[section number] is set to TRUE, otherwise FALSE. * Returns FALSE iff scr1 and scr2 are identical screens. */ int find_changed_areas (const unsigned char *scr1, const unsigned char *scr2, unsigned char changed[192/16]) { const unsigned int *rta, *rta_base; short base; short i; int diff = FALSE; unsigned char *ch; /* Zero all the changed flags. */ /* FIXME - zero as longs? Is that safe? */ for (i = (192 / 16) - 1, ch = &changed[0]; i >= 0; i--) *ch++ = FALSE; #if 0 /* Try each 16 row section. As soon as we hit a difference, go to next. */ rta_base = row_to_addr + 192 - 16; for (base = 11; base >= 0; rta_base -= 16, base--) for (i = 15, rta = rta_base; i >= 0; rta++, i--) if (!equal40bytes (scr1 + *rta, scr2 + *rta)) { changed[base] = diff = TRUE; break; } #else /* Try each 16 row section. As soon as we hit a difference, go to next. */ rta_base = row_to_addr + 192 - 16; for (base = 11; base >= 0; rta_base -= 16, base--) for (i = 15, rta = rta_base; i >= 0; rta++, i--) if (!equal40bytes (scr1 + *rta, scr2 + *rta)) { changed[base] = diff = TRUE; break; } #endif #if 0 /* Old code. */ /* Try each 16 row section. As soon as we hit a difference, go to next. */ for (base = 192 - 16; base >= 0; base -= 16) for (i = 15, rta = row_to_addr + base; i != -1; rta++, i--) if (cmp40bytes (scr1 + *rta, scr2 + *rta) >= 0) { changed[base / 16] = diff = TRUE; break; } #endif return diff; } static inline void copy40bytes (const unsigned char *src, unsigned char *dst) { const unsigned long *s = (const unsigned long *) src; unsigned long *d = (unsigned long *) dst; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d++ = *s++; *d = *s; } void copy_changed_areas (const unsigned char *src, unsigned char *dst, const unsigned char changed[192/16]) { short i; long base; const unsigned int *rta; const unsigned char *ch = &changed[192/16]; for (base = 192 - 16; base >= 0; base -= 16) if (*--ch) for (i = 15, rta = row_to_addr + base; i >= 0; rta++, i--) #if 0 copy40bytes (src + *rta, dst + *rta); #else /* gcc 2 does Good Things with memcpy. */ memcpy ((long *) (dst + *rta), (long *) (src + *rta), 40); #endif }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.