TIC-80
TIC-80 copied to clipboard
Sync() does not change vbank 1 palette
So, My current project is set up such that some elements draw in vbank 0, and others draw in vbank 1, and different worlds of the game are held in different "content" banks accessed using sync().
However, when I call sync() to go to content bank 1, it does not render using the vbank 1 palette from content bank 1, but rather with the one from content bank 0.
To explain with images, This is the vbank 1 palette from content bank 1;
This is the vbank 1 palette from bank 0;
This is how it renders in-game, using the correct palette indices, but the wrong palette;
I cannot find any information on whether this is intentional behavior or unintentional behavior, although, as a different vbank palette is specified for each content bank in the editor, I would expect that it would change alongside the sprites and map data.
Is this an issue anyone else has run into?
However, when I call sync() to go to content bank 1, it does not render using the vbank 1 palette from content bank 1, but rather with the one from content bank 0.
You'll need to be more specific, calling sync
doesn't render anything...
VBANK0
and VBANK1
should have nothing to do with the 8 banks of cartridge RAM thought.
You can sync cartridge bank 4 or 6 and then draw to EITHER VBANK0
or VBANK1
... they are entirely unrelated to SCREEN banks 0, 1, 2, 3, etc.
it does not render using the vbank 1 palette from content bank 1
I also can't parse this, as there is only a single VBANK1 in all the hardware... so there is only a single VBANK1 palette (not one per "content bank"), etc...
The only open question is how does sync
SCREEN
work with vbank
ing... and my guess would be that it syncs cartridge data into the ACTIVE vbank, though I could be mistaken.
I guess my issue was that, since each content bank allows the definition of a separate vbank1 palette, I assumed that calling sync() would also change the palette to that defined in each content bank. It might be worth reworking this functionality in the future since that does not appear to be how it works (as you said there is only one vbank1 palette).
As this is not currently the functionality, is it possible to change the vbank1 palette using poke? When I was looking into the RAM layout, I am seeing that the addresses are identical to that of vbank0 for palette swaps, and there is no apparent location for vbank1's palette in ram (at least as it is currently documented).
since each content bank allows the definition of a separate vbank1 palette
It does not. Could you point to any specific places on the wiki that lead to this conclusion? (if I can spot it I'd be happy to clean it up)
you said there is only one vbank1 palette
There is only a single VBANK0
and a single VBANK1
. Those existing in _active RAM. sync
copies "ROM" from the cartridge to RAM (or burns RAM to the cartridge "ROM"). I would expect copying a bank into memory would overwrite the active bank - whether it was bank 0 or bank 1. If you confirm that's not the case I would consider that a bug.
is it possible to change the vbank1 palette using poke?
Sure. But you have to swap banks first:
vbank(1)
-- poke whatever here
vbank(0)
and there is no apparent location for vbank1's palette in ram
It's at the same place as vbank1's palette. This is documented on the RAM layout:
https://github.com/nesbox/TIC-80/wiki/RAM#vram
For example:
vbank(1)
sync(screen | palette, 3)
vbank(0)
Should copy the SCREEN
and PALETTE
from cartridge BANK3
into VRAM
(specifically VBANK1
).
Could you point to any specific places on the wiki that lead to this conclusion? (if I can spot it I'd be happy to clean it up)
It's less a place on the wiki that led to that conclusion, but the editor itself. If you look back at the two sprite editor images I shared in the initial post, the palette on both images is set to bank 1, and each is allowed to have a separate palette defined.
(cropped here for ease)
Thanks for pointing out having to bank before poking, I hadn't realized that was the trick to write to vbank 1's palette, and as such got confused when the ram layout specified them as existing at the same addresses.
For example:
vbank(1) sync(screen | palette, 3) vbank(0)
Should copy the
SCREEN
andPALETTE
from cartridgeBANK3
intoVRAM/VBANK1
.
I also can't quite get this to function properly, it refuses to run if I take it exactly as is, though it does work if I do
vbank(1) sync(32 | 128,1) vbank(0)
Figured I'd toss it here in case someone else has the same issue and comes here, I've used issues on here to find solutions in the past.
but the editor itself.
Ah... I see now... because our save file format groups the palettes together... so you're right, you have 16 palettes... spread across 8 banks. Sometimes I forget how different the cartridge format is.
sync(32 | 128,1)
Yeah, I was using the same placeholders the wiki does, you'd need to define those or use constants.
So now the question is what happens when you do:
vbank(0) -- just to start from a normal place
sync(palette, 3)
Are you saying that only updates VBANK0
and not VBANK1
? Are you doing your drawing using vbank(1)
or inside OVR
? You'd need to be using vbank1 to get those colors...
So now the question is what happens when you do:
vbank(0) -- just to start from a normal place sync(palette, 3)
So if I place this into my code before bank switching, it works as you'd expect, it pulls the palette over from cartridge bank 3, only changing vbank 0, which is expected, as we have not called vbank(1) first.
Now, if we do
vbank(1)
sync(palette, 3)
it does change vbank1's palette, but it changes it to the vbank 0 palette specified in cartridge bank 3 instead of the vbank1 palette.
it pulls the palette over from cartridge bank 3, only changing vbank 0, which is expected,
Actually I'm not sure that's expected - or I don't think it's 100% clear what should happen.
When the cartridge "boots" BOTH palettes are synced from cart BANK0
into VBANK0
and VBANK1
... so it seems quite reasonable that this might also happen when you call sync
also.
it does change vbank1's palette, but it changes it to the vbank 0 palette specified in cartridge bank 3 instead o
I'd say that's a bug.
sync(palette, 3)
One other thing that could be fooling you is that you can only call sync
ONCE per frame... if you call it a second time it will do nothing so code liek this will never do anything useful (whatever you think it should/might do):
vbank(0)
sync(palette, 3)
vbank(1)
sync(palette, 3)
The second call to sync
will do nothing at all.
@nesbox It sounds like sync
may not be taking vbank
into account - that the default palette is always getting copied over the "active vbank" palette... I'm thinking we should likely copy BOTH palettes from a bank into vbank0.palette
and vbank1.palette
(same as happens at boot). This would be a potentially breaking change though.
I didn't test this, I'm going solely based on this report.
I realize this issue is a bit old, but could this be solved by adding another bitflag to sync()
for vbank1 palettes?
Again, pretty sure this is a bug - not something we need another flag for - but obviously it's not currently a high priority issue, sorry.
Fair enough. I'm willing to write a PR, I just need to know what approach would be preferred.
I still concor with myself:
I'm thinking we should likely copy BOTH palettes from a specified bank into vbank0.palette and vbank1.palette (same as happens at boot).
IE, just another "magic" feature of the hardware. I feel like we need @nesbox to weigh in those because technically it's a breaking change of anyone relying on the current "broken" behavior.
Since this was fairly recent change though I'm thinking perhaps we can just accept that if we call the current behavior a bug...
added palette syncing for both vbanks simultaneously 9f5744646b5c9c943b9719f7a085f8abb9b52f36
Hello, I believe this issue persists to this day. I am using the Pro version 1.0.2164.
This is what I have in the sprite editor.
Bank 0:
Bank 1:
This is what I have during runtime.
Sync to bank 0, sync(32,0)
:
Sync to bank 1, sync(32,1)
:
Vbank1 should be red.