You have about 2200 cycles per vblank (113⅔ · 20) for everything that needs to be sent to the PPU. Updating sprites (OAM DMA) takes roughly 1/4 of that. CC65 is probably adding some overhead, too.

Almost every game I've looked at has some kind of scheduler for PPU updates. Sometimes they're really minimal (e.g. some flip-screen games just change between "PPU is off, uploading new data" and "game is running")

Yup, looks like that's the problem. The question I have is, is it safe to call set_vram_update(); when the PPU is on?

I need to literally update different areas of the screen, depending on different events, score change, worrior doors opening, teleport happening, etc. If I can't call set_vram_update() while ppu is active, will I need to roll my own little queuing and scheduler code for this?

I think you can call set_vram_update whenever you want, that's just setting a pointer and the actual PPU update is done by neslib's NMI handler (which will run at the next vblank). The problem is just that the NMI handler has no way of safeguarding against or helping to diagnose the "too much data takes too long" case.

I believe all the neslib functions you can't call while rendering is on are labelled as such in the header.

If you need all of those updates to happen in one frame, you could write a custom assembly NMI handler that can get that much data through in a single vblank, but the library's generic one is not efficient enough to do it.

Otherwise you can break up your updates so you only have to do some of it each frame.

The solution is making your vram_update array dynamic, fill it with what you need to change for that frame, and let the NMI handler do its magic. I'm sure you don't need to update everythign every frame, so this just works.

Reserve a big enough update buffer in BSS, such as:

Code:

unsigned char update_buffer [UPDATE_LIST_SIZE*3+1];unsigned char *ul;

Here, UPDATE_LIST_SIZE = 32 works for me (more than enough!). ul is a pointer we'll use to update the buffer.

Ok. I'm already basically doing this, I'll just not try to do it in one big buffer. (I was doing 256 bytes in BSS and just creating update records for every single thing to update, and simply just changing the data...)

It depends on how the tube is calibrated. It's often joked that NTSC stands for Never The Same Color, but it can also mean Never The Same Crop. There's a diagram at "Overscan" on the wiki. For convenience and in case something happens to the wiki:

Danger Zone (outside Action Safe Area)

Action Safe Area, 256x224, (0, 8)-(255, 231)

PocketNES Safe Area, 240x212, (8, 16)-(247, 227)

Title Safe Area, 224x192, (16, 24)-(223, 215)

An LCD will probably show the Action Safe Area almost exactly. The average CRT will show somewhere between the PocketNES Safe Area and the Action Safe Area, but older CRTs or CRTs in poor shape might not show much out of the Title Safe Area or might show some of the Danger Zone.

oh I know the joke, all too well. It's especially poignant on the VCS, because you're literally generating half of the video signal yourself! (I have literally made black and white pixels artifact into color on the VCS on accident.)

I just wanted to see how tight my tolerances are, since I do not have a toaster or a tube anymore.

(and yes, I have the overscan chart for the NES, I'm really bunching up against it. I just want to see how close to the cliff I actually am.)

// Set the addresses for the two rows of tiles that make up the door update_buffer[0]=(player==0?MSB(NTADR_A(1,18))|NT_UPD_HORZ:MSB(NTADR_A(28,18))|NT_UPD_HORZ); update_buffer[1]=(player==0?LSB(NTADR_A(1,18)):LSB(NTADR_A(28,18))); update_buffer[2]=3;

Needed more room in my sprite chr bank, so I used NESST's remove duplicates feature. Fantastic feature indeed..in fact, both YYCHR and NESST are fantastically indispensable tools, hats off to Shiru and YY.

Now status is slowing down a bit, as I slog through entering tables and data for animation and start implementing the frame loop for the main part of the game.

I am currently using a very naive vram update scheduler, interleaving parts of the vram to be updated across four different frames, as it isn't critical that all of these updates happen with hair-pin precision:

I will spread the radar update into 4 sections, so that I can have enough cycles to update the radar screen (really not much to do other than just read the dungeon x and y boxes for the 6 enemy state slots, and set the tile to use accordingly, but there are 10x6 tiles to update, so I have to slice it up a bit)

If I need something better, i'll write it.

I've gone through and implemented almost all of the sprites, save for the wizard, as I am needing to decode the bitplane format used on the Astrocade, to grab the blitter object for the wizard from the ROM, as I have tried to frame grab it, like the other character objects, and as it happens, the blitter object is munged a bit to blur it, making extraction of anything other than the one visible object on the character description page difficult. Worst case, I will just #@($#@ draw it based on the blurry (#@$#@ images.

I've also implemented the animation state tables which will be used to select which metasprites to use for a given state, and have enough to where I can do a naive first pass at filling in the OAM on each frame. I believe the game uses four frames for each animation state, with two of those frames duplicated to create a sort of slight cyclical pause that is visible at slower speeds...it certainly makes it easy to cycle through the frames in the state list, as I just have to AND it off.

I've also implemented the red/blue dungeon palette swap that is needed to differentiate certain states (worluk/wizard visible, or you're now in a Worlord dungeon), as well as the Double Score win color cycling.

Looks like enemy collision detection needs a bit of work (I need to add a bit of fudging to allow the monsters to go into the box, as well as some bias correction, but if you look at the radar output, you'll see the collision code is acting as expected)

Who is online

You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot post attachments in this forum