Converting NES graphics to C64

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Converting NES graphics to C64
by on (#40284)
A big issue of doing this is that the C64 has a completely different pixel resolution. In fact it allows less pixels (200) in height, but much more (320) in width (as opposed to the NES, which is 240 and 256 respectively).

But since both are meant to be viewed on TVs, the screen is about the same size. The C64 has very large border on all 4 corners, which can explain that there is less scanlines vertically (just like the NES it doesn't interleave 2 fields). However this don't explain why the resolution is higher horizontally. Theorically it should be lower because of the borders.

However, I suspect the C64 to output a hi-res signal like the SNES does in it's mode 5&6 (used by both SNES Seiken Densetsu/Secret of Mana games in their respective menus). This mode allows to use 512 pixels horizontally, and minus the borders it becomes 320. However, that makes the border really big (about 90 pixels on each side). I don't know if it works like that.

Also, if you want to get 4 colors like the NES, you have to sacrifice horizontal resolution to get 2 "bitplanes" instead. This is really annoying, but if the C64 uses hi-res graphics, that means that a tile that use the wide pixel feautre to get more color will actually be the same size of a NES pixel, which would be a good thing. I don't know if that's the case tough.

by on (#40287)
On a given video system, scanlines will always be the same height. As for the width of pixels, it's probably easiest to express those as fractions of the NTSC color subcarrier's period. (One period is 1/3579545 second, or 3/560 of a scanline.) Square pixels in 240p are 7/12 of a period wide, and CCIR 601 pixels are 35/132 period (=39.375*11/13.5) wide. Atari 2600 pixels were a full period wide, NES/SMS/SNES pixels were 2/3, and Genesis pixels were 8/15. Apple II pixels were a full color period wide or half a color period wide, depending on whom you ask, because of its unique "direct subpixel" way of generating colors in high-resolution mode.

I think pixels in C64 multicolor mode are a full period wide, but I have no C64 to test my conjecture on. If this is the case, then sixteen C64 multicolor pixels equal 24 NES pixels across.

by on (#40288)
So systems can adjust horizontal resolution as they'd like ? However, it's werid you get fractionnal number of periods. That's something quite hard to understand. Monochrome monitors simply read luminance between HBlanks so it seems really simple. For color monitors, it's so much a headache.

Quote:
I think pixels in C64 multicolor mode are a full period wide, but I have no C64 to test my conjecture on. If this is the case, then sixteen C64 multicolor pixels equal 24 NES pixels across.

If this is true, it would be a pretty good thing, as I'd just have to stretch the graphics so that 4x4 NES metatiles becomes 3x4 C64 metatiles (but it will use 6x4 "tiles", altough C64 people never uses "tile" word for some reason). The problem is that 40 is not a multiple of 6, so it would be impossible to put an integer number of metatile on the screen and that is terrible. I'd pretty much have to live with my graphics stretched somehow, which sounds annoying.

Also, pixels are always the same size. When using multi-color mode, the graphic unit simply outputs 2 pixels of the same color, coosen among 4 possible colors, instead of 2 pixels of differnet colors, each chosen among only 2 possible colors. There is no such thing as "wider pixels", altough this term has been usued very commonly.

What do you think is the worse ? Re-code a game engine in a different assembly language, but being able to use very similar graphics, control and sound (port NES to Gameboy) or having to do major changes to graphics, sound and input, but being able to re-use a big part of code as it (port NES to C64) ?

by on (#40289)
Bregalad wrote:
So systems can adjust horizontal resolution as they'd like ? However, it's werid you get fractionnal number of periods. That's something quite hard to understand.

NTSC signals don't have discrete pixels; instead, they have signals in various frequency bands. The closest thing to "pixels" in an analog video signal is either A. the Nyquist rate of a component's bandwidth, or B. the number of times a digital signal changes state before being converted to analog.

The NTSC NES PPU divides the color subcarrier into 12 sub-periods.[1] A colored pixel is high for 6 and low for 6 depending on the hue/phase, and the rest of the PPU's logic changes the high level, low level, and phase every eight sub-periods.

Quote:
The problem is that 40 is not a multiple of 6, so it would be impossible to put an integer number of metatile on the screen and that is terrible.

It's not unheard of. Kirby Super Star for Super NES uses 3x3-tile metatiles. Puyo Pop and Luminesweeper for Game Boy actually use 12x12-pixel metatiles, created by overlapping two scrolling layers set 12 pixels apart and then using HDMA to skip the bottom 4 pixels of each metatile.

Quote:
What do you think is the worse ? Re-code a game engine in a different assembly language, but being able to use very similar graphics, control and sound (port NES to Gameboy)

As I understand it, NES vs. Game Boy isn't exactly "very similar graphics, control, and sound". Game Boy allows direct access to VRAM during horizontal blanking; NES does not. NES has attribute tables; Game Boy does not. Game Boy has a reprogrammable wavetable channel; NES does not (though some Famicom mappers do). NES has software envelopes for the pulse and noise channels; Game Boy does not. And guess what: the overall width of C64 multicolor mode is closer to that of Game Boy (160px) than NES (256px), though the height is completely different.

Quote:
or having to do major changes to graphics, sound and input, but being able to re-use a big part of code as it (port NES to C64) ?

Look up model-view-controller separation on Wikipedia. This design pattern will help you keep the game rules consistent across platforms, so you can concentrate on a different front end for each platform. I did this in Lockjaw Tetromino Game, which is written in C with front ends that use the Allegro library on PCs and the GBA 2D hardware on the GBA and DS.

[1] Each of these sub-periods is half a cycle of the 21.5 MHz master clock. The PPU's chroma generator acts like a double-pumped counter.

by on (#40294)
Quote:
As I understand it, NES vs. Game Boy isn't exactly "very similar graphics, control, and sound". Game Boy allows direct access to VRAM during horizontal blanking; NES does not. NES has attribute tables; Game Boy does not. Game Boy has a reprogrammable wavetable channel; NES does not (though some Famicom mappers do). NES has software envelopes for the pulse and noise channels; Game Boy does not.

Sure, but instead of pointing to the differences, you should take in consideration the incredible amount of similarities between the NES and Gameboy. 8x8 tiles, 2BP background and sprite tiles, sprites made of either 8x8 or 8x16, 2 square channels with 3 different duty cycles and 16 volume levels, 1 noise channel and another sound channel that can be lower-pitched, possess a timer and can't be adjusted in volume. Also both sytems have exactly the same buttons.

I didn't mention the limited amount of sprite per scanline, and the ability to get raster effects. It's great the GB can acess VRAM during horizontal blanking, it can only help. BTW the C64 can acess VRAM anytime, which can only help even more (at the expense of CPU speed as read/write cycles are intervealed).

Quote:
And guess what: the overall width of C64 multicolor mode is closer to that of Game Boy (160px) than NES (256px), though the height is completely different.

Yes this is a good thing, and can allow 5 of my 32x32 metatiles to be displayed. However, on the C64 they'd probably look stretched horizontally, but maybe it's not that bad.

Quote:
Look up model-view-controller separation on Wikipedia. This design pattern will help you keep the game rules consistent across platforms, so you can concentrate on a different front end for each platform. I did this in Lockjaw Tetromino Game, which is written in C with front ends that use the Allegro library on PCs and the GBA 2D hardware on the GBA and DS.

Yeah I guess the input and output parts are rather well separed in my game engine. But a programm written in assembly is hard to port no matter what.

by on (#40733)
Bregalad wrote:
BTW the C64 can acess VRAM anytime, which can only help even more (at the expense of CPU speed as read/write cycles are intervealed).

<offtopic>

To be pedantic for those who are unfamiliar, the C64 doesn't have "VRAM", as all graphics data is stored in normal system RAM (the VIC-II can only access one 16KB bank of RAM at a time, however, so I guess one could loosely refer to the current bank of RAM as "VRAM", although it is technically not any such thing). Where the C64 loses out CPU-wise is when the VIC-II fetches new character and color data every 8th scanline (commonly known as "badlines"). However, such fetches actually make some of the more interesting tricks possible, where one can force the VIC-II to read new color data on every scanline by essentially triggering extra badlines. This can be used in either hires or multicolor, but it makes the three leftmost columns of the bitmap unusable.

</offtopic>

by on (#40750)
There are other things to note when converting to the C64. Does the game in question use smooth scrolling? If so you must enable the C64's 38 column mode for horizontal scrolling and the 24 row mode for vertical scrolling (or both for 8 way). The C64 can normally scroll the screen 8 pixels on the X and Y axis. The reduced column and row modes allow the character data to move under the border. Once you have scrolled 8 pixels you have to reset the register back to 0 and redraw the screen matrix with everything shifted 1 char over in the direction of the scroll, all before the raster hits the visible area again. There are other ways of doing this but as far as I know only Mayhem in Monsterland has done this outside of a demo.

Next are the sprites. My NES know-how pales compared to the people here but am I right in guessing the NES can do at least 16x16 (2x2 chars). Sprites on the C64 are 24x21 (3 chars wide, 2 chars+5 pixels deep). Sprite data is usually kept separate from character data on the C64. Sprites can access data occupied by a character set but sprites on the C64 are read differently than the NES (big assumption here). With all the talk I hear about tiles and tables (I lurk here a lot) I guess the NES tiles are stores in a similar fashion to the 64's character sets but the sprites are told what tiles to use for their definitions, correct? (I guess that from messing with Nesticle's tile editor). C64 sprites are stored in a linear fashion in memory like a bitmap and pointing a sprite to character data would usually result in a garbled mess.

Also as C64 can't change the resolution if it's sprites (as in the number of pixels it displays, it can double the size of any sprite in width of height) so if you have a sprite that's only 8x8 pixels then there's going to be a bit of wasted memory (unless you store the sprite data somewhere else in memory and unpack it on the fly, the Metal Warrior games do this).

Other things to note are: Multicolour GFX may have a halved resolution, but scrolling and sprite placement still maintain a 1 pixel granularity. Multicolour sprites all share 2 of their 3 colours but this can be split by raster interrupts. Multicolour character GFX like sprites all share the same 2 colours which again can be split. Multicolour character GFX can only use the first 8 colours of the 64's palette, using the other 8 causes the char to switch back to hires. Allows mixing of multicolour and hires characters on the same screen.

There's plenty more but if I were to type it all I would be quicker just to copy-paste the entire C=Hacking collection.

by on (#40751)
Quote:
To be pedantic for those who are unfamiliar, the C64 doesn't have "VRAM", as all graphics data is stored in normal system RAM (the VIC-II can only access one 16KB bank of RAM at a time, however, so I guess one could loosely refer to the current bank of RAM as "VRAM", although it is technically not any such thing)

Maybe you're right, for me any RAM that is reserved for screen usage becomes VRAM, regardless where it is physically (but maybe this is wrong). So whathever memory you use in the C64 to store characters or maps becomes VRAM for me, but this may be wrong. Also the NES is one of the only machines to feature VROM :wink:

Quote:
However, such fetches actually make some of the more interesting tricks possible, where one can force the VIC-II to read new color data on every scanline by essentially triggering extra badlines. This can be used in either hires or multicolor, but it makes the three leftmost columns of the bitmap unusable.

This sounds interesting. That's probably why as C64 games have (in general, not always) far less good graphics than NES games, some C64 demoes are absolutely outsanding I wonder how that's even possible. However, in a real in-game situation you'd want to have CPU time for the game engine and not to display prettys graphics. Also, since the C64 is about 45% slower than the NES, it should already be pretty difficult to port and get something that doesn't lag too much (altough I haven't tried).

Quote:
There are other things to note when converting to the C64. Does the game in question use smooth scrolling? If so you must enable the C64's 38 column mode for horizontal scrolling and the 24 row mode for vertical scrolling (or both for 8 way). The C64 can normally scroll the screen 8 pixels on the X and Y axis. The reduced column and row modes allow the character data to move under the border. Once you have scrolled 8 pixels you have to reset the register back to 0 and redraw the screen matrix with everything shifted 1 char over in the direction of the scroll, all before the raster hits the visible area again. There are other ways of doing this but as far as I know only Mayhem in Monsterland has done this outside of a demo.

Yes, I've known that (altough it's good to have a confirmation). The game I plan to port to C64 only scrolls between screen, and the NES version does that 4 pixels at a time (however there is no reason that that C64 version would do the same). I could get away by only shifting the tileset, but without using fine-scroll for that so that it simplifies things. Or I could just turn the screen to black and fade it in with the new screen, without any scrolling. It wouldn't look as good but the gameplay wouldn't be affected in any way.

Quote:
Next are the sprites. My NES know-how pales compared to the people here but am I right in guessing the NES can do at least 16x16 (2x2 chars). Sprites on the C64 are 24x21 (3 chars wide, 2 chars+5 pixels deep). Sprite data is usually kept separate from character data on the C64. Sprites can access data occupied by a character set but sprites on the C64 are read differently than the NES (big assumption here). With all the talk I hear about tiles and tables (I lurk here a lot) I guess the NES tiles are stores in a similar fashion to the 64's character sets but the sprites are told what tiles to use for their definitions, correct? (I guess that from messing with Nesticle's tile editor). C64 sprites are stored in a linear fashion in memory like a bitmap and pointing a sprite to character data would usually result in a garbled mess.

Yes, sprites on the C64 are a big headache for me. I haven't dealed with them yet, but you're limited to only 8 and if you want more you'll have to do some code that changes them midframe. On the NES their graphics are stored exactly the same way as they are for the BG and are either 8x8 or 8x16 pixels. However, we typically use metasprites that are groups of such sprites. On the C64, most metasprites would be only 1 or 2 hardware sprites, and if I port my game on the C64 I'll have to find a way to bankswitch sprites midframe to get more than 8, since I have 8 objects + 8 graphics effects + player (and it's weapon) in memory, that would do up to about 24-30 sprites needed on the screen in worst cases. Also, I use a complex sorting routine on the NES so that sprites on the bottom appear on the top on sprites on the top, which takes a lot of time, and would probably be too much for the C64, and would conflict with the sotring for sprite multiplexing, routines I've seen on the net sort them the other way arround, which is quite a headache !!

Quote:
Other things to note are: Multicolour GFX may have a halved resolution, but scrolling and sprite placement still maintain a 1 pixel granularity. Multicolour sprites all share 2 of their 3 colours but this can be split by raster interrupts. Multicolour character GFX like sprites all share the same 2 colours which again can be split. Multicolour character GFX can only use the first 8 colours of the 64's palette, using the other 8 causes the char to switch back to hires. Allows mixing of multicolour and hires characters on the same screen.

Oh that 2 color sharing seems quite a limitation to me. However most sprites are black outlined, and I could change the other bright color to white, so that all sprites would be "black" + specific color + "white" instead of "black" + "normal specific color" + "light specific color" like they are on the NES. Also, I'm pretty sure it's possible to overlay sprites to get more colors. In fact overlay monochrome sprites may get almost better result than having halved resolution multi-colour sprites in some cases.
About the BG I don't know yet how I'll handle this. Having to choose between resolution and color is a terrible choise.

It's great that you guys from the C64 scenes come here to help and chat. I appreciate this very much. Now I still don't know how to test my programms on my real C64 which is lameful.

by on (#40776)
Quote:
I could get away by only shifting the tileset, but without using fine-scroll for that so that it simplifies things. Or I could just turn the screen to black and fade it in with the new screen, without any scrolling. It wouldn't look as good but the gameplay wouldn't be affected in any way.


Perhaps using the Metroid method wouldn't look as bad? Fade out everything but the player and UI and move the player sprite in the direction of the scroll to the other side of the screen and fade back in. Give you a few seconds of CPU time to do fancy stuff. I bet if you packed your map data you would have plenty of time to unpack it between screens letting you squeeze more into 60KB you will have to play with on the C64 (if you turn the Kernal and Basic roms off).

Quote:
It's great that you guys from the C64 scenes come here to help and chat. I appreciate this very much. Now I still don't know how to test my programs on my real C64 which is lameful.


Thanks. If you have a 5 1/4" drive for your 64 then building/buying one of the x1541 cables (xe1541 or xm1541 is recommended) and using "The Star Commander" to transfer your game to disk. If you are lucky enough to have a 3 1/2" drive then there's software that will let a PC write Commodore 3 1/2" disks. (But the name of it escapes me atm). If you don't have a drive then something like the 1541-III or SD2IEC, both allow the use of regular SD cards.

One word of warning. If you are developing in a emulator first then beware of the regular PAL/NTSC issues. All C64 emulators default to PAL and afaik only CCS64 does NTSC with any sort of accuracy. If you can code for both. Its a odd fact that a vast majority of C64 games were made for PAL and it was up to the cracking groups to 'fix' the games for NTSC. That is if they could, some programming tricks are much more difficult to pull off on the NTSC 64 due to the reduced amount of CPU time in the borders.

by on (#40780)
Quote:
Perhaps using the Metroid method wouldn't look as bad? Fade out everything but the player and UI and move the player sprite in the direction of the scroll to the other side of the screen and fade back in. Give you a few seconds of CPU time to do fancy stuff. I bet if you packed your map data you would have plenty of time to unpack it between screens letting you squeeze more into 60KB you will have to play with on the C64 (if you turn the Kernal and Basic roms off).

Oh this method is interesting ! Altough my game doesn't have pipes like Super Metroid does. And my maps are packed with the metatile system which is standard on the NES (but maybe not on the C64). Since I'm limited to 32kb ROM and 2kb RAM on the NES, I proably won't have much issue with the 64kb available on the C64.

Quote:
Thanks. If you have a 5 1/4" drive for your 64 then building/buying one of the x1541 cables (xe1541 or xm1541 is recommended) and using "The Star Commander" to transfer your game to disk.

Already tried that, and while Star Commander reconized my cable, I never got anything working with my 1541, I kept getting timing errors and stuff like that. This method (and software that goes with it) seems more than 15 years old too so it doesn't look like the ideal solution.

Quote:
If you don't have a drive then something like the 1541-III or SD2IEC, both allow the use of regular SD cards.

That would seem to be the only solution. If I ever do some kind of loader that handles precise disk reads dealing with the motor, sectors and stuff I'll never be able to test it :(

The other alternative is to made my software cartridge-based, but I don't know how to build a cartridge, and the only one I have (Simon's Basic) I can't open it. Also it seems cartrides are "officially" limited to 16kb, altough bankswitching can easily bypass that I don't know if any emulator would support it.