How to compile fceux?

Discuss emulation of the Nintendo Entertainment System and Famicom.

Moderator: Moderators

User avatar
nesrocks
Posts: 437
Joined: Thu Aug 13, 2015 4:40 pm
Location: Rio de Janeiro - Brazil
Contact:

Re: [Solved] How to compile fceux?

Post by nesrocks » Thu Mar 07, 2019 8:15 pm

So... Scroll position cannot be read by looking at some address of CPU or PPU RAM?
Also, your note about when to read the registers, you're talking about $2000 and $2001? I think I'm reading it when the emulator is paused, the same moment any memview file prompt popup is launched. So far with my tests it seems to be working ok, but it could be that it's loading at some random moment and I'm lucky. I'm just using default memview behavior, it seems to be fine.

Moving on:

I'm having a really hard time understanding the code. I've only found two instances of the string "2005" on ppu.cpp.

Code: Select all

ARead[x + 5] = A200x;
BWrite[x + 5] = B2005;
I don't know what to make of this. What is "A200x"?

Also, when programming a game in ca65 I've learned horizontal scroll has two important values: the selected nametable, as defined by the two least significant bits of PPUCTRL register, and a value of 0-255 to be written to $2005 that defines the pixel position of the scroll relative to the selected nametable. Is that equivalent to what I'm looking for in the source code? I ask this because the wiki talks about fine and coarse scroll values, which is confusing me. Source: http://wiki.nesdev.com/w/index.php/PPU_scrolling

Code: Select all

PPU internal registers

v
Current VRAM address (15 bits)
t
Temporary VRAM address (15 bits); can also be thought of as the address of the top left onscreen tile.
x
Fine X scroll (3 bits)

The 15 bit registers t and v are composed this way during rendering:
yyy NN YYYYY XXXXX
||| || ||||| +++++-- coarse X scroll
||| || +++++-------- coarse Y scroll
||| ++-------------- nametable select
+++----------------- fine Y scroll
It took me a long time to understand this. So the PPU has a register called "x". So... I need registers v and x?

ppu.cpp has this function, but I don't understand how it's used

Code: Select all

void ppu_getScroll(int &xpos, int &ypos) {
	if (newppu) {
		ypos = ppur._vt * 8 + ppur._fv + ppur._v * 256;
		xpos = ppur._ht * 8 + ppur.fh + ppur._h * 256;
	} else {
		xpos = ((RefreshAddr & 0x400) >> 2) | ((RefreshAddr & 0x1F) << 3) | XOffset;

		ypos = ((RefreshAddr & 0x3E0) >> 2) | ((RefreshAddr & 0x7000) >> 12);
		if (RefreshAddr & 0x800) ypos += 240;
	}
}
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!

User avatar
rainwarrior
Posts: 7680
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: [Solved] How to compile fceux?

Post by rainwarrior » Thu Mar 07, 2019 8:25 pm

B2005 is defined here

No, scroll isn't just stored in RAM anywhere, it's an internal PPU thing and intimately tied up with the PPU address (written through $2006) as well. That wiki page you linked should explain, hopefully.

User avatar
nesrocks
Posts: 437
Joined: Thu Aug 13, 2015 4:40 pm
Location: Rio de Janeiro - Brazil
Contact:

Re: [Solved] How to compile fceux?

Post by nesrocks » Fri Mar 08, 2019 6:44 am

My C++ knowledge is too limited. It's too abstract to me right now. DECLFW is defined as "void x (uint32 A, uint8 V)" in fceu.h. I have no idea what that means. Shouldn't A be the accumulator, therefore uint8?

Anyway, B2005 only seems to be ever used to initialize PPU, so that doesn't seem to be useful. I tried to retrieve PPUGenLatch and it always came out as 0. I don't know how to access ppu.cpp's "V" from memview.cpp even though I've included ppu.h. I can't include ppu.cpp, it gives a random error elsewhere.

There's this, but I don't know how to access those vars from memview.cpp. I tried searching for how savestate does it, but I couldn't either. I think I'm going to give up for now.

Code: Select all

struct PPUREGS {
	//normal clocked regs. as the game can interfere with these at any time, they need to be savestated
	uint32 fv;	//3
	uint32 v;	//1
	uint32 h;	//1
	uint32 vt;	//5
	uint32 ht;	//5

	//temp unlatched regs (need savestating, can be written to at any time)
	uint32 _fv, _v, _h, _vt, _ht;

	//other regs that need savestating
	uint32 fh;	//3 (horz scroll)
	uint32 s;	//1 ($2000 bit 4: "Background pattern table address (0: $0000; 1: $1000)")
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!

User avatar
rainwarrior
Posts: 7680
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How to compile fceux?

Post by rainwarrior » Fri Mar 08, 2019 6:03 pm

A is for "address" and V is for "value", in that function.

Though I think really you found a better interface already in ppu_getScroll, which already seems designed to convert the current register state into convenient pixel scroll coordinates.

Code: Select all

int x,y;
ppu_getScroll(x, y);
// x add y now equal to scroll positions
Edit: made a typo in the code.
Last edited by rainwarrior on Fri Mar 08, 2019 7:00 pm, edited 1 time in total.

User avatar
nesrocks
Posts: 437
Joined: Thu Aug 13, 2015 4:40 pm
Location: Rio de Janeiro - Brazil
Contact:

Re: How to compile fceux?

Post by nesrocks » Fri Mar 08, 2019 6:50 pm

40 minutes after reading your message, I think I got it. At least looking at the output file binary seems to be producing numbers different than zero. It was giving me an error about const params and pointers I assume (from my error research), though I don't fully understood it. So after trying some things semi blindly, this is what worked:

Code: Select all

int scx = 0;
int scy = 0;
int *scxptr = &scx;
int *scyptr = &scy;
ppu_getScroll( *scxptr, *scyptr);
bar[0x4103] = *scyptr; // this is the binary file address I chose for scroll y
bar[0x4102] = *scxptr; // this is the binary file address I chose for scroll x 
Thanks you very much, importing dumps is getting very robust, at least for games that don't change much graphics mid-frame.
https://twitter.com/bitinkstudios <- Follow me on twitter! Thanks!

User avatar
rainwarrior
Posts: 7680
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: How to compile fceux?

Post by rainwarrior » Fri Mar 08, 2019 7:02 pm

Sorry, I made a typo above. There should not have been an & in front of x and y.

You don't need to make a pointer to a reference and then dereference them like you're doing, you can just use the two ints directly. The & in the function's declaration automatically references them and makes them available for output.

Post Reply