⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 old screen.cpp

📁 SNES game emulator. C and asm files.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		dobglinedraw (3, on, 1);
		dobglinedraw (2, on, 1);
		if (on&0x10) dospritelinedraw (1);
		dobglinedraw (1, on, 0);
		dobglinedraw (0, on, 0);
		if (on&0x10) dospritelinedraw (2);
		dobglinedraw (1, on, 1);
		dobglinedraw (0, on, 1);
		if (on&0x10) dospritelinedraw (3);
	}
}

void rendersnesscreen ()
{
	if (debugmode) {
		drawdebug (debugscreen);
	} else {
		doframedraw ();
	}
}

void updatetilemap64_16x16 (byte *tilemap, struct cachetilemap *ctmap, int tcharbase, boolean secondrow)
{	// version for 16x16 tile maps.
	int x, tnum, prio;

	if (secondrow) // only difference between 1st & 2nd row is +2 chars...
		tcharbase += (16 << curbg->tcharshift);
	for (x = 32; x > 0; x--) {
		tnum = tcharbase + ((*(word*)tilemap & 0x3FF) << curbg->tcharshift);
		prio = (tilemap[1] >> 5) & 1;
		ctmap[prio].tile = getcachetile (tnum, curbg->cdepth, tilemap[1] >> 6);
		ctmap[prio].empty = cempty [tilemap[1]>>7][tnum];
		ctmap[prio].solid = csolid [tilemap[1]>>7][tnum];
		ctmap[prio].pal_or = curbg->cgoffs | ((tilemap[1] & 0x1C) << (curbg->cdepth<<1));
		tnum += 1 << curbg->tcharshift;
		ctmap[prio+2].tile = getcachetile (tnum, curbg->cdepth, tilemap[1] >> 6);
		ctmap[prio+2].empty = cempty [tilemap[1]>>7][tnum];
		ctmap[prio+2].solid = csolid [tilemap[1]>>7][tnum];
		ctmap[prio+2].pal_or = curbg->cgoffs | ((tilemap[1] & 0x1C) << (curbg->cdepth<<1));
		prio = !prio;
		ctmap[prio].tile = NULL;
		ctmap[prio].empty = 0xFF;
		ctmap[prio].solid = ctmap[prio].pal_or = ctmap[prio].dummy = 0;
		ctmap[prio+2].tile = NULL;
		ctmap[prio+2].empty = 0xFF;
		ctmap[prio+2].solid = ctmap[prio].pal_or = ctmap[prio].dummy = 0;
		tilemap += 2;
		ctmap += 4;
	}
}

void updatetilemap32 (byte *tilemap, struct cachetilemap *ctmap, int tcharbase)
{
	int x, tnum, prio;

	for (x = 32; x > 0; x--) {
		tnum = tcharbase + ((*(word*)tilemap & 0x3FF) << curbg->tcharshift);
		prio = (tilemap[1] >> 5) & 1;
		ctmap[prio].tile = getcachetile (tnum, curbg->cdepth, tilemap[1] >> 6);
		ctmap[prio].empty = cempty [tilemap[1]>>7][tnum];
		ctmap[prio].solid = csolid [tilemap[1]>>7][tnum];
		ctmap[prio].pal_or = curbg->cgoffs | ((tilemap[1] & 0x1C) << (curbg->cdepth << 1));
		prio = !prio;
		ctmap[prio].tile = NULL;
		ctmap[prio].empty = 0xFF;
		ctmap[prio].solid = ctmap[prio].pal_or = ctmap[prio].dummy = 0;
		tilemap += 2;
		ctmap += 2;
	}
}

void updatetilemaprow (int row)
{	// uses curbg
	byte *tilemap = curbg->tilemap;
	struct cachetilemap *ctilemap = (struct cachetilemap *) ctmap[curbg->bgnum-1][row];

	if (row >= (32<<curbg->tile16x16)) {
		row -= (32<<curbg->tile16x16);
		tilemap += ((32*32*2) << curbg->width64);
	}
	if (!curbg->tile16x16) { // 8x8 tiles
		updatetilemap32 (tilemap + (row << 6), ctilemap, curbg->tcharbase);
		if (curbg->width64) { // 64 wide
			updatetilemap32 (tilemap + 32*32*2 + (row << 6), ctilemap + 32*2, curbg->tcharbase);
		} else {
			memcpy (ctilemap + 32*2, ctilemap, sizeof(cachetilemap)*32*2);
		}
		memcpy (ctilemap + 64*2, ctilemap, sizeof(cachetilemap)*64*2);
	} else { // 16x16 tiles
		updatetilemap64_16x16 (tilemap + ((row >> 1) << 6), ctilemap, curbg->tcharbase, row & 1);
		if (curbg->width64) { // 64 16x16 tiles wide
			updatetilemap64_16x16 (tilemap + 32*32*2 + ((row >> 1) << 6), ctilemap + 64*2, curbg->tcharbase, row & 1);
		} else {
			memcpy (ctilemap + 64*2, ctilemap, sizeof(cachetilemap)*64*2);
		}
	}
}

void blitbgline (int row, int offsy, int col, byte *scrstart, boolean priority)
{	// uses curbg
	struct cachetilemap *ctilemap = &ctmap[curbg->bgnum-1][row][col][priority];
	int x, flagand = (1 << offsy), pixoffsy = (offsy << 3);
	dword dwpal_or;
	byte *pixels;

	for (x = 32; x != 0; scrstart += 8, ctilemap += 2, col++, x--) {
		if (col & 0xFFFFFF80) { // 0 <= Column < 128
			col -= 128;
			ctilemap -= 256; // 128*2
		}
		if (ctilemap->empty & flagand)
			continue;
		else if (ctilemap->solid & flagand) {
			dwpal_or = (ctilemap->pal_or << 24) | (ctilemap->pal_or << 16) | (ctilemap->pal_or << 8) | ctilemap->pal_or;
			((dword*)scrstart)[0] = ctilemap->tile->dwpixel[(offsy << 1)] | dwpal_or;
			((dword*)scrstart)[1] = ctilemap->tile->dwpixel[(offsy << 1) + 1] | dwpal_or;
			continue;
		}
		pixels = &ctilemap->tile->pixel[pixoffsy];
		if (pixels[0]) scrstart[0] = pixels[0] | ctilemap->pal_or;
		if (pixels[1]) scrstart[1] = pixels[1] | ctilemap->pal_or;
		if (pixels[2]) scrstart[2] = pixels[2] | ctilemap->pal_or;
		if (pixels[3]) scrstart[3] = pixels[3] | ctilemap->pal_or;
		if (pixels[4]) scrstart[4] = pixels[4] | ctilemap->pal_or;
		if (pixels[5]) scrstart[5] = pixels[5] | ctilemap->pal_or;
		if (pixels[6]) scrstart[6] = pixels[6] | ctilemap->pal_or;
		if (pixels[7]) scrstart[7] = pixels[7] | ctilemap->pal_or;
	}
}

inline int getobj8x8size (int bits)
{
	switch ((bits & 2) | (*REG2101 & 0xE0)) {
	case 0x00: case 0x20: case 0x40: return 1;
	case 0x02: case 0x60: case 0x80: return 2;
	case 0xA0: case 0x22: case 0x62: return 4;
	case 0x42: case 0x82: case 0xA2: return 8;
	}
	return 1;	// Size unknown
}

void buildspritetable ()
{	// Called at the beginning of every frame
	int obj, bits, tchars, flip, x, y, i, incy;
	byte pal_or;
    int tcharbase = ((*REG2101 & 3) << 10); // Char Address/16
	struct cachetilemap *cursprmap;
	static struct cachetilemap dummymap = { NULL, 0, 0xFF, 0 };

	for (obj = 0; obj < 128; obj++) {
		/*if (spr8x8size[obj] != 0) {
			tchars = tcharbase + ((*((word*)&oam[(obj << 2) + 2]) & 0x1FF) << 1);
			flip = oam [(obj << 2)+3] >> 6;
			for (y = 0; y < spr8x8size[obj]; y++) {
				for (x = 0; x < spr8x8size[obj]; x++) {
					//cursprmap[(y << 3) + x].tile
					getcachetile (tchars + (x << 1), 1, flip);
				}
				tchars += 32;
			}
			continue;
		}*/
		bits = (oam [512 + (obj >> 2)] & (3 << ( (obj & 3) << 1 ) )) >> ( (obj & 3) << 1);
		spr8x8size[obj] = getobj8x8size (bits);
		flip = oam [(obj << 2)+3] >> 6;
		tchars = tcharbase + ((*((word*)&oam[(obj << 2) + 2]) & 0x1FF) << 1);
		pal_or = ((oam[(obj << 2) + 3] & 0xE) << 3) | 0x80;
		cursprmap = (struct cachetilemap *) sprmap[obj];
		if (spr8x8size[obj] == 1) { //8x8=easy
			cursprmap[0].tile = getcachetile (tchars, 1, flip);
			cursprmap[0].pal_or = pal_or;
			cursprmap[0].empty = cempty [flip>>1][tchars];
			cursprmap[0].solid = csolid [flip>>1][tchars];
			cursprmap[1] = cursprmap[2] = cursprmap[3] = cursprmap[4] =\
			cursprmap[5] = cursprmap[6] = cursprmap[7] = dummymap;
			continue;
		}
		if (flip & 2) {
			incy = -1; y = spr8x8size[obj]-1;
		} else {
			incy = 1; y = 0;
		}
		for (; y < spr8x8size[obj] && y >= 0; y += incy) {
			for (x = 0; x < spr8x8size[obj]; x++) {
				if (flip & 1) i = (y << 3) + (spr8x8size[obj]-1-x);
				else i = (y << 3) + x;
				cursprmap[i].tile = getcachetile (tchars + (x << 1), 1, flip);
				cursprmap[i].pal_or = pal_or;
				cursprmap[i].empty = cempty [flip>>1][tchars + (x << 1)];
				cursprmap[i].solid = csolid [flip>>1][tchars + (x << 1)];
			}
			for (; x < 8; x++)
				cursprmap[(y << 3) + x] = dummymap; // should be unneccesary?
			tchars += 32;
		}
	}
}

boolean oamposchange;
byte sprhere [256][32];
byte nsprhere [256];

void buildsprlinelist ()
{
	int bits, xpos, ypos, size, obj, y;

	memset (nsprhere, 0, sizeof (nsprhere));
	for (obj = (debugmode ? debug_sprmax : 127); obj >= (debugmode ? debug_sprmin : 0); obj--) {
		bits = (oam [512 + (obj >> 2)] & (3 << ( (obj & 3) << 1 ) )) >> ( (obj & 3) << 1);
		xpos = oam [(obj << 2)] + ((bits & 1) << 8);
		ypos = oam [(obj << 2) + 1];
		size = spr8x8size[obj] << 3;
		if (xpos >= 256 && xpos < 512+7-size)
			continue;
		for (y = ypos; y < ypos+size; y++) {
			if (nsprhere[y & 0xFF] >= 32)
				continue;
			sprhere [y & 0xFF][nsprhere[y & 0xFF]] = obj;
			nsprhere[y & 0xFF]++;
		}
	}
	oamposchange = false;
}

/*void dospritelinedraw (byte priority)
{
	int bits, xpos, ypos, size, row, col, pixoffsy, numtiles, obj;

	if (!(curgs->bgs & 0x10))
		return;
	for (obj = 127; obj >= 0; obj--) {
		if (((oam [(obj << 2) + 3] & 0x30) >> 4) != priority)
			continue;
		bits = (oam [512 + (obj >> 2)] & (3 << ( (obj & 3) << 1 ) )) >> ( (obj & 3) << 1);
		xpos = oam [(obj << 2)] + ((bits & 1) << 8);
		ypos = oam [(obj << 2) + 1];
		size = spr8x8size[obj] << 3;
		if (xpos > 256 && xpos < 512+7-size)
			continue;
		if ((screen_scanline >= ypos+size || screen_scanline < ypos) &&\
			!(ypos+size >= 256 && ((ypos+size)&0xFF) > ypos))
			continue;
		pixoffsy = (screen_scanline - ypos) & 0xFF;
		row = pixoffsy >> 3;
		pixoffsy &= 7;
		numtiles = (256+7-xpos) >> 3;
		if (numtiles > spr8x8size[obj])
			numtiles = spr8x8size[obj];
		col = xpos >= 256 ? (512+7-xpos) >> 3 : 0;
		blitspriteline (&sprmap[obj][row][col], numtiles, pixoffsy, screen + ((xpos+(col<<3))&0xFF));
	}
}*/

void dospritelinedraw (byte priority)
{
	int bits, xpos, ypos, size, row, col, pixoffsy, numtiles, obj, obji;

	if (!(curgs->bgs & 0x10))
		return;
	for (obji = 0; obji < nsprhere[screen_scanline]; obji++) {
		obj = sprhere[screen_scanline][obji];
		if (((oam [(obj << 2) + 3] & 0x30) >> 4) != priority)
			continue;
		bits = (oam [512 + (obj >> 2)] & (3 << ( (obj & 3) << 1 ) )) >> ( (obj & 3) << 1);
		xpos = oam [(obj << 2)] + ((bits & 1) << 8);
		ypos = oam [(obj << 2) + 1];
		size = spr8x8size[obj] << 3;

		pixoffsy = (screen_scanline - ypos) & 0xFF;
		row = pixoffsy >> 3;
		pixoffsy &= 7;
		numtiles = (256+7-xpos) >> 3;
		if (numtiles > spr8x8size[obj])
			numtiles = spr8x8size[obj];
		col = xpos >= 256 ? (512+7-xpos) >> 3 : 0;
		blitspriteline (&sprmap[obj][row][col], numtiles, pixoffsy, screen + ((xpos+(col<<3))&0xFF));
	}
}

void blitspriteline (struct cachetilemap *ctmap, int numtiles, int yoffs, byte *scrstart)
{
	int flagand = (1 << yoffs), pixoffsy = (yoffs << 3);
	byte *pixels;
	dword dwpal_or;

	for (;numtiles > 0; numtiles--, scrstart += 8, ctmap++) {
		if (ctmap->empty & flagand) {
			continue;
		}
		else if (ctmap->solid & flagand) {
			dwpal_or = (ctmap->pal_or << 24) | (ctmap->pal_or << 16) | (ctmap->pal_or << 8) | ctmap->pal_or;
			((dword*)scrstart)[0] = ctmap->tile->dwpixel[(yoffs << 1)] | dwpal_or;
			((dword*)scrstart)[1] = ctmap->tile->dwpixel[(yoffs << 1) + 1] | dwpal_or;
			continue;
		}
		pixels = &ctmap->tile->pixel[pixoffsy];
		if (pixels[0]) scrstart[0] = pixels[0] | ctmap->pal_or;
		if (pixels[1]) scrstart[1] = pixels[1] | ctmap->pal_or;
		if (pixels[2]) scrstart[2] = pixels[2] | ctmap->pal_or;
		if (pixels[3]) scrstart[3] = pixels[3] | ctmap->pal_or;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -