src/gfx.c
branchcustombridgeheads
changeset 5648 1608018c5ff2
parent 5643 3778051e8095
equal deleted inserted replaced
5647:cbde85c8c878 5648:1608018c5ff2
    22 #endif
    22 #endif
    23 
    23 
    24 Colour _cur_palette[256];
    24 Colour _cur_palette[256];
    25 byte _stringwidth_table[FS_END][224];
    25 byte _stringwidth_table[FS_END][224];
    26 
    26 
    27 static void GfxMainBlitter(const Sprite *sprite, int x, int y, int mode);
    27 typedef enum BlitterModes {
       
    28 	BM_NORMAL,
       
    29 	BM_COLOUR_REMAP,
       
    30 	BM_TRANSPARENT,
       
    31 } BlitterMode;
       
    32 
       
    33 static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode);
    28 
    34 
    29 FontSize _cur_fontsize;
    35 FontSize _cur_fontsize;
    30 static FontSize _last_fontsize;
    36 static FontSize _last_fontsize;
    31 static Pixel _cursor_backup[64 * 64];
    37 static Pixel _cursor_backup[64 * 64];
    32 static Rect _invalid_rect;
    38 static Rect _invalid_rect;
   636 			return x;
   642 			return x;
   637 		}
   643 		}
   638 		if (IsPrintable(c)) {
   644 		if (IsPrintable(c)) {
   639 			if (x >= dpi->left + dpi->width) goto skip_char;
   645 			if (x >= dpi->left + dpi->width) goto skip_char;
   640 			if (x + 26 >= dpi->left) {
   646 			if (x + 26 >= dpi->left) {
   641 				GfxMainBlitter(GetGlyph(size, c), x, y, 1);
   647 				GfxMainBlitter(GetGlyph(size, c), x, y, BM_COLOUR_REMAP);
   642 			}
   648 			}
   643 			x += GetCharacterWidth(size, c);
   649 			x += GetCharacterWidth(size, c);
   644 		} else if (c == '\n') { // newline = {}
   650 		} else if (c == '\n') { // newline = {}
   645 			x = xo;
   651 			x = xo;
   646 			y += GetCharacterHeight(size);
   652 			y += GetCharacterHeight(size);
   673 
   679 
   674 void DrawSprite(uint32 img, int x, int y)
   680 void DrawSprite(uint32 img, int x, int y)
   675 {
   681 {
   676 	if (img & PALETTE_MODIFIER_COLOR) {
   682 	if (img & PALETTE_MODIFIER_COLOR) {
   677 		_color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
   683 		_color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
   678 		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, 1);
   684 		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, BM_COLOUR_REMAP);
   679 	} else if (img & PALETTE_MODIFIER_TRANSPARENT) {
   685 	} else if (img & PALETTE_MODIFIER_TRANSPARENT) {
   680 		_color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
   686 		_color_remap_ptr = GetNonSprite(GB(img, PALETTE_SPRITE_START, PALETTE_SPRITE_WIDTH)) + 1;
   681 		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, 2);
   687 		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, BM_TRANSPARENT);
   682 	} else {
   688 	} else {
   683 		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, 0);
   689 		GfxMainBlitter(GetSprite(img & SPRITE_MASK), x, y, BM_NORMAL);
   684 	}
   690 	}
   685 }
   691 }
   686 
   692 
   687 typedef struct BlitterParams {
   693 typedef struct BlitterParams {
   688 	int start_x, start_y;
   694 	int start_x, start_y;
   689 	const byte *sprite;
   695 	const byte *sprite;
   690 	Pixel *dst;
   696 	Pixel *dst;
   691 	int mode;
   697 	BlitterMode mode;
   692 	int width, height;
   698 	int width, height;
   693 	int width_org;
   699 	int width_org;
   694 	int pitch;
   700 	int pitch;
   695 } BlitterParams;
   701 } BlitterParams;
   696 
   702 
   703 	Pixel *dst;
   709 	Pixel *dst;
   704 	const byte *ctab;
   710 	const byte *ctab;
   705 
   711 
   706 	src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
   712 	src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
   707 	switch (bp->mode) {
   713 	switch (bp->mode) {
   708 		case 1:
   714 		case BM_COLOUR_REMAP:
   709 			do {
   715 			do {
   710 				do {
   716 				do {
   711 					done = src_o[0];
   717 					done = src_o[0];
   712 					num = done & 0x7F;
   718 					num = done & 0x7F;
   713 					skip = src_o[1];
   719 					skip = src_o[1];
   746 
   752 
   747 				bp->dst += bp->pitch;
   753 				bp->dst += bp->pitch;
   748 			} while (--bp->height != 0);
   754 			} while (--bp->height != 0);
   749 			break;
   755 			break;
   750 
   756 
   751 		case 2:
   757 		case BM_TRANSPARENT:
   752 			do {
   758 			do {
   753 				do {
   759 				do {
   754 					done = src_o[0];
   760 					done = src_o[0];
   755 					num = done & 0x7F;
   761 					num = done & 0x7F;
   756 					skip = src_o[1];
   762 					skip = src_o[1];
   839 
   845 
   840 	assert(height > 0);
   846 	assert(height > 0);
   841 	assert(width > 0);
   847 	assert(width > 0);
   842 
   848 
   843 	switch (bp->mode) {
   849 	switch (bp->mode) {
   844 		case 1: {
   850 		case BM_COLOUR_REMAP: {
   845 			const byte *ctab = _color_remap_ptr;
   851 			const byte *ctab = _color_remap_ptr;
   846 
   852 
   847 			do {
   853 			do {
   848 				for (i = 0; i != width; i++) {
   854 				for (i = 0; i != width; i++) {
   849 					byte b = ctab[src[i]];
   855 					byte b = ctab[src[i]];
   854 				dst += bp->pitch;
   860 				dst += bp->pitch;
   855 			} while (--height != 0);
   861 			} while (--height != 0);
   856 			break;
   862 			break;
   857 		}
   863 		}
   858 
   864 
   859 		case 2: {
   865 		case BM_TRANSPARENT: {
   860 			const byte *ctab = _color_remap_ptr;
   866 			const byte *ctab = _color_remap_ptr;
   861 
   867 
   862 			do {
   868 			do {
   863 				for (i = 0; i != width; i++)
   869 				for (i = 0; i != width; i++)
   864 					if (src[i] != 0) dst[i] = ctab[dst[i]];
   870 					if (src[i] != 0) dst[i] = ctab[dst[i]];
   904 	Pixel *dst;
   910 	Pixel *dst;
   905 	const byte *ctab;
   911 	const byte *ctab;
   906 
   912 
   907 	src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
   913 	src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
   908 	switch (bp->mode) {
   914 	switch (bp->mode) {
   909 		case 1:
   915 		case BM_COLOUR_REMAP:
   910 			do {
   916 			do {
   911 				do {
   917 				do {
   912 					done = src_o[0];
   918 					done = src_o[0];
   913 					num = done & 0x7F;
   919 					num = done & 0x7F;
   914 					skip = src_o[1];
   920 					skip = src_o[1];
   954 					src_o += (done & 0x7F) + 2;
   960 					src_o += (done & 0x7F) + 2;
   955 				} while (!(done & 0x80));
   961 				} while (!(done & 0x80));
   956 			} while (--bp->height != 0);
   962 			} while (--bp->height != 0);
   957 			break;
   963 			break;
   958 
   964 
   959 		case 2:
   965 		case BM_TRANSPARENT:
   960 			do {
   966 			do {
   961 				do {
   967 				do {
   962 					done = src_o[0];
   968 					done = src_o[0];
   963 					num = done & 0x7F;
   969 					num = done & 0x7F;
   964 					skip = src_o[1];
   970 					skip = src_o[1];
  1066 
  1072 
  1067 	assert(height > 0);
  1073 	assert(height > 0);
  1068 	assert(width > 0);
  1074 	assert(width > 0);
  1069 
  1075 
  1070 	switch (bp->mode) {
  1076 	switch (bp->mode) {
  1071 		case 1: {
  1077 		case BM_COLOUR_REMAP: {
  1072 			const byte *ctab = _color_remap_ptr;
  1078 			const byte *ctab = _color_remap_ptr;
  1073 
  1079 
  1074 			for (height >>= 1; height != 0; height--) {
  1080 			for (height >>= 1; height != 0; height--) {
  1075 				for (i = 0; i != width >> 1; i++) {
  1081 				for (i = 0; i != width >> 1; i++) {
  1076 					byte b = ctab[src[i * 2]];
  1082 					byte b = ctab[src[i * 2]];
  1081 				dst += bp->pitch;
  1087 				dst += bp->pitch;
  1082 			}
  1088 			}
  1083 			break;
  1089 			break;
  1084 		}
  1090 		}
  1085 
  1091 
  1086 		case 2: {
  1092 		case BM_TRANSPARENT: {
  1087 			const byte *ctab = _color_remap_ptr;
  1093 			const byte *ctab = _color_remap_ptr;
  1088 
  1094 
  1089 			for (height >>= 1; height != 0; height--) {
  1095 			for (height >>= 1; height != 0; height--) {
  1090 				for (i = 0; i != width >> 1; i++)
  1096 				for (i = 0; i != width >> 1; i++)
  1091 					if (src[i * 2] != 0) dst[i] = ctab[dst[i]];
  1097 					if (src[i * 2] != 0) dst[i] = ctab[dst[i]];
  1115 	Pixel *dst;
  1121 	Pixel *dst;
  1116 	const byte *ctab;
  1122 	const byte *ctab;
  1117 
  1123 
  1118 	src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
  1124 	src_o += ReadLE16Aligned(src_o + bp->start_y * 2);
  1119 	switch (bp->mode) {
  1125 	switch (bp->mode) {
  1120 		case 1:
  1126 		case BM_COLOUR_REMAP:
  1121 			for (;;) {
  1127 			for (;;) {
  1122 				do {
  1128 				do {
  1123 					done = src_o[0];
  1129 					done = src_o[0];
  1124 					num = done & 0x7F;
  1130 					num = done & 0x7F;
  1125 					skip = src_o[1];
  1131 					skip = src_o[1];
  1185 				} while (!(done & 0x80));
  1191 				} while (!(done & 0x80));
  1186 				if (--bp->height == 0) return;
  1192 				if (--bp->height == 0) return;
  1187 			}
  1193 			}
  1188 			break;
  1194 			break;
  1189 
  1195 
  1190 		case  2:
  1196 		case BM_TRANSPARENT:
  1191 			for (;;) {
  1197 			for (;;) {
  1192 				do {
  1198 				do {
  1193 					done = src_o[0];
  1199 					done = src_o[0];
  1194 					num = done & 0x7F;
  1200 					num = done & 0x7F;
  1195 					skip = src_o[1];
  1201 					skip = src_o[1];
  1336 
  1342 
  1337 	assert(height > 0);
  1343 	assert(height > 0);
  1338 	assert(width > 0);
  1344 	assert(width > 0);
  1339 
  1345 
  1340 	switch (bp->mode) {
  1346 	switch (bp->mode) {
  1341 		case 1: {
  1347 		case BM_COLOUR_REMAP: {
  1342 			const byte *ctab = _color_remap_ptr;
  1348 			const byte *ctab = _color_remap_ptr;
  1343 
  1349 
  1344 			for (height >>= 2; height != 0; height--) {
  1350 			for (height >>= 2; height != 0; height--) {
  1345 				for (i = 0; i != width >> 2; i++) {
  1351 				for (i = 0; i != width >> 2; i++) {
  1346 					byte b = ctab[src[i * 4]];
  1352 					byte b = ctab[src[i * 4]];
  1351 				dst += bp->pitch;
  1357 				dst += bp->pitch;
  1352 			}
  1358 			}
  1353 			break;
  1359 			break;
  1354 		}
  1360 		}
  1355 
  1361 
  1356 		case 2: {
  1362 		case BM_TRANSPARENT: {
  1357 			const byte *ctab = _color_remap_ptr;
  1363 			const byte *ctab = _color_remap_ptr;
  1358 
  1364 
  1359 			for (height >>= 2; height != 0; height--) {
  1365 			for (height >>= 2; height != 0; height--) {
  1360 				for (i = 0; i != width >> 2; i++)
  1366 				for (i = 0; i != width >> 2; i++)
  1361 					if (src[i * 4] != 0) dst[i] = ctab[dst[i]];
  1367 					if (src[i * 4] != 0) dst[i] = ctab[dst[i]];
  1375 			break;
  1381 			break;
  1376 	}
  1382 	}
  1377 }
  1383 }
  1378 
  1384 
  1379 
  1385 
  1380 static void GfxMainBlitter(const Sprite *sprite, int x, int y, int mode)
  1386 static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode)
  1381 {
  1387 {
  1382 	const DrawPixelInfo *dpi = _cur_dpi;
  1388 	const DrawPixelInfo *dpi = _cur_dpi;
  1383 	int start_x, start_y;
  1389 	int start_x, start_y;
  1384 	BlitterParams bp;
  1390 	BlitterParams bp;
  1385 	int zoom_mask = ~((1 << dpi->zoom) - 1);
  1391 	int zoom_mask = ~((1 << dpi->zoom) - 1);