Newcomer to NES programming

A place for your artistic side. Discuss techniques and tools for pixel art on the NES, GBC, or similar platforms.

Moderator: Moderators

tepples
Posts: 22708
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Newcomer to NES programming

Post by tepples »

Or break up the highlights with a bit of dithering.

But make sure to try the dithering on hardware, in Nestopia, or in blargg's snes_ntsc preview tool* because the NTSC PPU's composite output does funny things with some dithering patterns. Which operating system does your PC use?


* Despite the name, "snes_ntsc" is also what you want to use to scrutinize NES graphics for possible artifacts because the NES PPU and Super NES S-PPU2 produce pretty much the same artifacts.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Newcomer to NES programming

Post by lidnariq »

I have to agree with tokumaru- simply removing all the details might make it more playable, but removes a lot of the shine and sparkle that made it interesting.

Anyway, running the original scene through nes_ntsc shows the difference between tiles and water to be much more obvious:
no_changes_needed.jpg
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: Newcomer to NES programming

Post by Drag »

Image
Here's another where the water's intact, but with my other suggestions still in place. I've enlarged the floor bricks up one and right one to close the black gaps so the floor is bluer to contrast with the blacker water.

Though yeah, with a different NES palette, the graphics seem less contrasty, so maybe the palette was the problem all along.

Edit:
Image
One last version, with the green highlight added back in.
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Newcomer to NES programming

Post by tokumaru »

The bricks on the floor HAVE to be thick, otherwise it gets hard to tell that they are surrounded by water. In your first edit it actually kinda looks like the water is above the floor, making it look like some kind of wall instead. The original shadows and highlights do a great job at representing the relative depth of the whole scene, I honestly wouldn't remove any of it. A few palette tweaks might indeed help with the contrast though.
Drag
Posts: 1615
Joined: Mon Sep 27, 2004 2:57 pm
Contact:

Re: Newcomer to NES programming

Post by Drag »

lidnariq wrote:I have to agree with tokumaru- simply removing all the details might make it more playable, but removes a lot of the shine and sparkle that made it interesting.
That was my mistake, when I started having second thoughts about wiping out the details in the water, I should've stopped.
Anyway, running the original scene through nes_ntsc shows the difference between tiles and water to be much more obvious:
no_changes_needed.jpg
It looks like the palette's a little different here. Changing the colors of the floor and of the water definitely helps though.
tokumaru wrote:The bricks on the floor HAVE to be thick, otherwise it gets hard to tell that they are surrounded by water. In your first edit it actually kinda looks like the water is above the floor, making it look like some kind of wall instead. The original shadows and highlights do a great job at representing the relative depth of the whole scene, I honestly wouldn't remove any of it. A few palette tweaks might indeed help with the contrast though.
My first suggestion is garbage, please disregard it. My next two suggestions show that the pattern can be reduced but still have detail. The water's texture is very turbulent, and the floor texture is only slightly less turbulent. By smoothing the floor texture out, the scene becomes easier to read. That's not to say that every single detail has to be destroyed, but some do need to be toned down, especially if all these high-contrast details are filling the screen. If the entire background pops out, it's going to be very difficult to place any kind of emphasis on anything else, short of making it blink or shake or something.

Anyway, those are my suggestions; a palette tweaking will help, maybe seeing some more scenes will convince me that that's all that needs to be done, but as of right now, I'm not entirely convinced.
Sik
Posts: 1589
Joined: Thu Aug 12, 2010 3:43 am

Re: Newcomer to NES programming

Post by Sik »

Honestly I still prefer the original. Maybe the palettes could be tweaked, but otherwise yeah, I wouldn't change the graphics.

Also I can't be the only one bothered by the brick pattern interruption at the corners at the top, right?
User avatar
Alp
Posts: 223
Joined: Mon Oct 06, 2014 12:37 am

Re: Newcomer to NES programming

Post by Alp »

After 10 hours of studying opcodes, and banging my head into a wall. I have successfully read from memory, and rendered out 2 8x16 sprites! :O

...Now if only I could make the 2nd sprite follow the first! :?

Apparently, the sprite indexes require being incremented in units of 4, or it'll overwrite another sprite?
I figured this out, through trial and error. There doesn't seem to any mention of it, anywhere, though.

Image

Also, all the talk of Zelda 1 in this thread, made me wonder what a true Zelda-clone would look like.
So I mocked this up, to NES specifications. CHR included. Not sure what to do with these, yet.
EDIT: Switched the image, I indexed something incorrectly. :oops:

Image

I'll try some palette edits, and see if I can reduce the issues, are apparently having with the tiles.
Sik wrote:Also I can't be the only one bothered by the brick pattern interruption at the corners at the top, right?
Oh yes. That is a problem I am aware of.
You see, I keep all of my work on a single canvas, including old versions of tiles, and I shifted the bricks on the wall when I was adding doors, to center them. When I scrapped them, and tiled over the mock-ups, I didn't notice the tile-shearing until later. My bad.
Attachments
knightgame.chr
(8 KiB) Downloaded 204 times
Last edited by Alp on Sat May 21, 2016 2:33 pm, edited 1 time in total.
User avatar
thefox
Posts: 3134
Joined: Mon Jan 03, 2005 10:36 am
Location: 🇫🇮
Contact:

Re: Newcomer to NES programming

Post by thefox »

Alp wrote:Apparently, the sprite indexes require being incremented in units of 4, or it'll overwrite another sprite?
I figured this out, through trial and error. There doesn't seem to any mention of it, anywhere, though.
Sprite index would be in range 0..63, covering the 64 sprites that are available. OAM index is in range 0..255, covering the 256 bytes of OAM. That means 4 bytes (X, Y, tile, attributes) are used for each sprite in OAM.
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: fo.aspekt.fi
User avatar
tokumaru
Posts: 12427
Joined: Sat Feb 12, 2005 9:43 pm
Location: Rio de Janeiro - Brazil

Re: Newcomer to NES programming

Post by tokumaru »

Alp wrote:...Now if only I could make the 2nd sprite follow the first! :?
Are you familiar with the MVC programming pattern? The basic idea is to separate the model and the view of your game world as much as possible. This means that pressing right on the controller shouldn't directly cause the X coordinate byte of an object's OAM entry to increase. Such hardcoded programming would make your code difficult to maintain, because everything is so stuck together that you can't make changes without affecting a huge part of the engine.

The model is the state of the game world, it's how the game is represented in memory. Things like level maps (including collision data) and objects (including position, speed, health, etc.) are part of the model. The view is just a graphical representation of that model, so that us humans can see what's happening in there, but the MODEL SHOULD BE ABLE TO EXIST AND FUNCTION WITHOUT A VIEW. Another interesting side effect of this design is that you can have several views of the same game world. This is what allows games like Doom or Duke Nukem 3D to be played in 3D mode or map mode. It's the same game world, only displayed differently. In Duke Nukem 3D there were also security cameras that would display other parts of the level, which is another type of view the game uses. None of this would be possible if the enemies were trying to draw themselves directly to your screen.

The NES is a machine with very limited resources though, so full separation isn't always possible. But sprites are certainly one of the things that should be abstracted from the main engine. Most games have a meta-sprite rendering routine. A meta-sprite is a list of sprites that represent one animation frame of a single object. So if your player uses 2 sprites at any given animation frame, each of his meta-sprite definitions will have 2 entries. Now, the main difference between these entries and the regular OAM entries, is that the coordinates of meta-sprites are relative to the object they represent, not absolute to the screen. There are many ways to optimize the space used by meta-sprites (automatic pattern increment - so that only the first index has to be defined, automatic coordinate increment of grid-arranged sprites, etc.), but for simplicity and full freedom each meta-sprite entry can be 4 bytes, just like normal OAM entries.

So, you have the player object as part of the model in RAM, and it has a single set of coordinates that specify where in the current room it is. When you call the mata-sprite rendering routine, it will loop through the entries of the selected meta-sprite and add the relative sprite coordinates to the object's coordinates in order to generate the final OAM entries that will be sent to the PPU later. This may sound a bit complicated, and it is at first, but once you have this routine ready, you'll never have to worry about manually updating 8 different sprites every time a big character moves... just call the meta-sprite routine and you're done!

Like I said before, this improves maintainability of your code. For example, if you decide to change the type of OAM cycling (since the NES can only show 8 sprites per scanline, it's common practice to rotate or randomize the OAM positions for all the objects every frame, so that all objects affected will flicker instead of some disappearing), you just have to modify this particular routine. If the sprite code was hardcoded in each object, you would have to revise every single object in the game, with big chances of missing something along the way.

Does that make sense? It may seem a little overwhelming, but the sooner you realize that math is more important than knowing what each opcode and register does, the sooner you'll be on the right track. You can always look up the documentation for opcodes and registers, but the internal workings of your game should always be clear to you.
User avatar
Alp
Posts: 223
Joined: Mon Oct 06, 2014 12:37 am

Re: Newcomer to NES programming

Post by Alp »

tokumaru wrote: Are you familiar with the MVC programming pattern? The basic idea is to separate the model and the view of your game world as much as possible. This means that pressing right on the controller shouldn't directly cause the X coordinate byte of an object's OAM entry to increase. Such hardcoded programming would make your code difficult to maintain, because everything is so stuck together that you can't make changes without affecting a huge part of the engine.
So, what you're talking about, is a "state engine"? I've programmed some of those before.
I'm just trying to figure out some of the basic coding methods for this language, so I can get started on my game. I have such a structure partially planned out.

My previous programming experience is on the C64, and the Gameboy. >.>
(and some DOS work, for a German game design company.)
User avatar
Alp
Posts: 223
Joined: Mon Oct 06, 2014 12:37 am

Re: Newcomer to NES programming

Post by Alp »

Blah... been sick. But I've been reading up on coding in that time. As of last night, I now have nametable data being loaded from a map offset! Metasprites are only partially implemented at the moment.

Image

EDIT: Oh yeah, a question. On an NROM it seems that map tiles cannot be animated? Is this correct?
If so, I can save 8 tiles for something else... >.>
Last edited by Alp on Sat May 21, 2016 2:34 pm, edited 1 time in total.
User avatar
Kasumi
Posts: 1293
Joined: Wed Apr 02, 2008 2:09 pm

Re: Newcomer to NES programming

Post by Kasumi »

Oh yeah, a question. On an NROM it seems that map tiles cannot be animated? Is this correct?
It's not possible to guarantee all tiles with a certain index can be animated regardless of how many times that index is used in the current nametable, no. To animate a tile on NROM, you would need to rewrite all instances of the index you want to change in the nametable with the next frame's index during vblank. So it's possible, but there are only so many nametable writes you can do during vblank. You'd have to plan around it.
User avatar
DragonDePlatino
Posts: 94
Joined: Mon Oct 20, 2014 1:50 pm

Re: Newcomer to NES programming

Post by DragonDePlatino »

Whoa! Nice graphics!

The detail on these tiles are great, and your foreshortening is just incredible! There's lots of personality in every tile and these would make for some incredible graphics on the NES.

With that being said, I'm really not a fan of your sprite palettes. The black on them works well enough on the overworld screens, but a lot of their details are swallowed up on the darker dungeon screens and they're a bit indiscernible with the NTSC filter. Also, I know it's been said many times, but make your tiles asymmetric! One good application of this would be your dungeon walls, which could have separate lighting on both sides to simulate a lightsource coming from the west:

Image

EDIT:

On another note, how do I create my own NTSC-simulated screens? I know there's an nes_ntsc library out there or I could just load up a nametable into an emulator, but both of those methods are really time-consuming. Is there a standalone executable I could use to get some quick, dirty results?
User avatar
rainwarrior
Posts: 8732
Joined: Sun Jan 22, 2012 12:03 pm
Location: Canada
Contact:

Re: Newcomer to NES programming

Post by rainwarrior »

You could use CHR-RAM with NROM to update a small number of CHR tiles each frame (as opposed to nametable animation), but this is not a common choice for NROM, since this requires you to use your very limited PRG space to store all CHR data as well.
lidnariq
Posts: 11432
Joined: Sun Apr 13, 2008 11:12 am

Re: Newcomer to NES programming

Post by lidnariq »

DragonDePlatino wrote:On another note, how do I create my own NTSC-simulated screens? I know there's an nes_ntsc library out there or I could just load up a nametable into an emulator, but both of those methods are really time-consuming. Is there a standalone executable I could use to get some quick, dirty results?
Blargg's nes_ntsc library includes a really simple program called "demo.c" which is what I've been using. Unfortunately, I lack the tools to compile a windows build of it.
Post Reply