Post subject: some question of FCEUX source code
Joined: 8/4/2011
Posts: 2
Now i study FCEUX source code, but i do not understand some function and some variable, help me, thanks. the flow function do what? and i don't understand variable "sphitx".
static void RefreshLine(int lastpixel)
{
	static uint32 pshift[2];
	static uint32 atlatch;
	uint32 smorkus=RefreshAddr;

#define RefreshAddr smorkus
	uint32 vofs;
	int X1;

	register uint8 *P=Pline;
	int lasttile=lastpixel>>3;
	int numtiles;

	static int norecurse=0; /* Yeah, recursion would be bad.
							PPU_hook() functions can call
							mirroring/chr bank switching functions,
							which call FCEUPPU_LineUpdate, which call this
							function. */
	if(norecurse) return;

	if(sphitx != 0x100 && !(PPU_status&0x40))
	{
		if((sphitx < (lastpixel-16)) && !(sphitx <lasttile>34) lasttile=34;
	numtiles=lasttile-firsttile;

	if(numtiles<=0) return;

	P=Pline;

	vofs=0;

	vofs=((PPU[0]&0x10)<<8>>12)&7);

	if(!ScreenON && !SpriteON)
	{
		uint32 tem;
		tem=Pal[0]|(Pal[0]<<8)|(Pal[0]<<16)|(Pal[0]<<24>=TOFIXNUM && tofix)
		{
			Fixit1();
			tofix=0;
		}

		if((lastpixel-16)>=0)
		{
			InputScanlineHook(Plinef,spork?sprlinebuf:0,linestartts,lasttile*8-16);
		}
		return;
	}

	//Priority bits, needed for sprite emulation.
	Pal[0]|=64;
	Pal[4]|=64;
	Pal[8]|=64;
	Pal[0xC]|=64;

	//This high-level graphics MMC5 emulation code was written for MMC5 carts in "CL" mode.
	//It's probably not totally correct for carts in "SL" mode.

#define PPUT_MMC5
	if(MMC5Hack && geniestage!=1)
	{
		if(MMC5HackCHRMode==0 && (MMC5HackSPMode&0x80))
		{
			int tochange=MMC5HackSPMode&0x1F;
			tochange-=firsttile;
			for(X1=firsttile;X1<lasttile;X1++)
			{
				if((tochange<0>0 && !(MMC5HackSPMode&0x40)))
				{
#define PPUT_MMC5SP
#include "pputile.inc"
#undef PPUT_MMC5SP
				}
				else
				{
#include "pputile.inc"
				}
				tochange--;
			}
		}
		else if(MMC5HackCHRMode==1 && (MMC5HackSPMode&0x80))
		{
			int tochange=MMC5HackSPMode&0x1F;
			tochange-=firsttile;

#define PPUT_MMC5SP
#define PPUT_MMC5CHR1
			for(X1=firsttile;X1<lasttile;X1++)
			{
#include "pputile.inc"
			}
#undef PPUT_MMC5CHR1
#undef PPUT_MMC5SP
		}
		else if(MMC5HackCHRMode==1)
		{
#define PPUT_MMC5CHR1
			for(X1=firsttile;X1<lasttile;X1++)
			{
#include "pputile.inc"
			}
#undef PPUT_MMC5CHR1
		}
		else
		{
			for(X1=firsttile;X1<lasttile;X1++)
			{
#include "pputile.inc"
			}
		}
	}
#undef PPUT_MMC5
	else if(PPU_hook)
	{
		norecurse=1;
#define PPUT_HOOK
		for(X1=firsttile;X1<lasttile;X1++)
		{
#include "pputile.inc"
		}
#undef PPUT_HOOK
		norecurse=0;
	}
	else
	{
		for(X1=firsttile;X1<lasttile;X1++)
		{
#include "pputile.inc"
		}
	}

#undef vofs
#undef RefreshAddr

	//Reverse changes made before.
	Pal[0]&=63;
	Pal[4]&=63;
	Pal[8]&=63;
	Pal[0xC]&=63;

	RefreshAddr=smorkus;
	if(firsttile<=2 && 2<lasttile && !(PPU[1]&2))
	{
		uint32 tem;
		tem=Pal[0]|(Pal[0]<<8)|(Pal[0]<<16)|(Pal[0]<<24);
		tem|=0x40404040;
		*(uint32 *)Plinef=*(uint32 *)(Plinef+4)=tem;
	}

	if(!ScreenON)
	{
		uint32 tem;
		int tstart,tcount;
		tem=Pal[0]|(Pal[0]<<8)|(Pal[0]<<16)|(Pal[0]<<24);
		tem|=0x40404040;

		tcount=lasttile-firsttile;
		tstart=firsttile-2;
		if(tstart<0>0)
			FCEU_dwmemset(Plinef+tstart*8,tem,tcount*8);
	}

	if(lastpixel>=TOFIXNUM && tofix)
	{
		//puts("Fixed");
		Fixit1();
		tofix=0;
	}

	//CheckSpriteHit(lasttile*8); //lasttile*8); //lastpixel);

	//This only works right because of a hack earlier in this function.
	CheckSpriteHit(lastpixel);

	if((lastpixel-16)>=0)
	{
		InputScanlineHook(Plinef,spork?sprlinebuf:0,linestartts,lasttile*8-16);
	}
	Pline=P;
	firsttile=lasttile;
}
Editor, Active player (296)
Joined: 3/8/2004
Posts: 7469
Location: Arzareth
You should wrap your code in the [cоde][/cоde] tags; otherwise indents get removed and end results becomes very difficult to parse. So I went and read the actual ppu.cpp instead. sphitx is an x coordinate that is used for checking whether this scanline was the one on which sprite 0 gets rendered (sprite 0 hit). The PPU can be queried for this condition. The variable records the value 0x100 if the hit no longer needs to be checked, or otherwise, the x coordinate that was last checked. It's something like this. I'm not the author of that code, so I am only deducing from reading it. I do not find a "flow" in your pasted code, so I cannot answer that question. However, if you want to understand how that function works, it might help for you to study first how the NES PPU works. Suggest this article: http://www.nesdev.com/2C02%20technical%20reference.TXT
Joined: 8/4/2011
Posts: 2
Bisqwit wrote:
You should wrap your code in the [cоde][/cоde] tags; otherwise indents get removed and end results becomes very difficult to parse. So I went and read the actual ppu.cpp instead. sphitx is an index to the sprite array. It is used for checking whether this scanline was the one on which sprite 0 gets rendered. The PPU can be queried for this condition. I do not find a "flow" in your pasted code, so I cannot answer that question. However, if you want to understand how that function works, it might help for you to study first how the NES PPU works. Suggest this article: http://www.nesdev.com/2C02%20technical%20reference.TXT
thanks, Bisqwit. I want to do NES on hardware, use verilog and FPGA. so i need to known the details, now i am going to http://www.nesdev.com/2C02%20technical%20reference.TXT ^_^ "I do not find a "flow" in your pasted code, so I cannot answer that question." sorry, it is "follow" ---
static void RefreshLine(int lastpixel)