Jump to content
  • 0
kcowolf

Tilemap on layer 0 shows black screen

Question

Posted (edited)

I'm having an issue trying to draw a tilemap on layer 0.  I load the tilemap (40x30) into banked RAM and then vpoke it into VRAM.  Both layers are 64x32 and 4bpp, and I've confirmed from the emulator logs that the palette, tiles, and tilemap are written to where I expect.

I have a repository in GitHub reproducing this: https://github.com/kcowolf/x16-test. In src/main.c, in my initVera() function I set the Vera registers and initialize both of the layer tilemaps to all zeroes -- the first tile in the tileset is all color index 0.  In initTileMap(), I vpoke my image to one of the layers: if I use setForegroundTile(), the image is drawn as expected, but if I use setBackgroundTile(), all I get is a black screen.  This occurs whether or not layer1 is enabled.

Any help I can get would be much appreciated, as I'm pretty stumped by this.

Edited by kcowolf
Fix link to repository

Share this post


Link to post
Share on other sites

8 answers to this question

Recommended Posts

  • 0

Can't quite tell what you're doing wrong, other than doing the whole process the hard way. You can just load the tilemaps into VRAM directly from the file. I'm not sure of what function you use in the C API, but in assembly it's the same kernal function that you use to load it into RAM, but with different arguments.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0

As Matt mentioned you can use the same `vload_host()` function to load a tilemap binary directly into the tilemap address in VRAM.

I'm seeing something similar to this (alternatively seeing colorful garbage for layer0) when I try to enable layer0 in my chopper demo.  For me both layers are using the same tileset.

  • Like 1

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

Your code works fine for me.
image.thumb.png.35c08b024c57c38fc89e760cc8db7679.pngspacer.pngspacer.pngspacer.pngspacer.png

My guess is you forgot to place PALBG1.BIN, TMBG1.BIN, and TSBG1.BIN in the working directory of your emulator, alongside your .prg.

Edit: I've since noticed a //TODO in your code about layer 1 causing a black screen, but replacing the reference to FOREGROUND_TILE_BASE_ADDR with BACKGROUND_MAP_BASE_ADDR, as seemed to be the original intent, doesn't appear to change the result any. Nor would I expect it to, you're initializing all the tiles to index 0, and per one of your recent submit comments, tile 0 was changed to be entirely color index 0 (which will be transparent). So I think the code is fine, it really was just a case of missing files at runtime.

Edited by StephenHorn
  • Like 2

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

You're correct that the line where I had the TODO needed to be changed to reproduce the issue -- I'd committed it load it to the foreground, where it's working.  I've confirmed the files are present in the working folder when I run the program.

Interesting that it seems to work for you.  Here's what I get if I use BACKGROUND_MAP_BASE_ADDR in the vload_host() call for the tilemap:

Layer0.png.3a49a0d01bbc08a9b4460facb8af7cf5.png

A black screen with the system writing "ready" after finishing the program (I assume the font is messed up because I overwrote it with tile or tilemap data).  Interestingly, if I move the cursor up or down, it jumps up to the line where the "ready" text is located, or what appears to be 4 lines instead of just 1.

Edited by kcowolf

Share this post


Link to post
Share on other sites
  • 0
Posted (edited)

The system writes "Ready" because your program terminates and returns control to the kernal. The kernal, however, is not smart enough to realize that it needs to reset the VERA's settings, so it goes and behaves as if you never changed them.

The only other thing I can think of is that it might be a case of case-sensitivity. I tested on Windows, where the filesystem's made up and the cases don't matter. Especially if you're on my favorite finicky hate-buddy of an operating system (🐧), that would be my next suspect point.

So try changing this:

Quote
#define PALBG1_FILENAME "palbg1.bin"
 
#define TSBG1_FILENAME "tsbg1.bin"
#define TSBG1_TILE_COUNT 444
 

#define TMBG1_FILENAME "tmbg1.bin"

into this:

Quote
#define PALBG1_FILENAME "PALBG1.BIN"
 
#define TSBG1_FILENAME "TSBG1.BIN"
#define TSBG1_TILE_COUNT 444
 

#define TMBG1_FILENAME "TMBG1.BIN"

If that doesn't work, try instead making everything consistently lower-case.

Edit: The reason I'm not sure which way is the better way to go, case-wise, but am suggesting you start by switching your code to upper-case, is because we're also potentially talking about the difference between ASCII and PETSCII mapping. My work in ASM invokes the kernal load/save routines directly, and all my filename strings are always entirely upper-case while referring to files that are entirely in lower-case. You might need to follow suit, with upper-case #defines and lower-case filenames. But I'm not sure! The C interface may translate that on your behalf. Play.

Edited by StephenHorn
  • Like 2

Share this post


Link to post
Share on other sites
  • 0

One thing to consider regarding case sensitivity is that the letters you use for constants have their cases toggled automatically by ca65 (and perhaps with cc65 as well). So, filenames may need to be referenced with inverted cases in the source code. For XCI, I added a character map to let you preserve ASCII strings at compile time, as XCI is ASCII based, not PETSCII.

So, you may need to use all lowercase for filenames in your code and all uppercase in your file system. With the Windows version of the emulator, it lets you get away with case differences that won't fly with the real X16.

  • Like 2

Share this post


Link to post
Share on other sites
  • 0

Good point on the filenames/PETSCII on the X16; I'll keep that in mind.  I'm using the emulator on Windows.  If I uppercase the filenames in GFX.h, it just throws garbage on the screen regardless of which layer I use, so the way I have them (lowercase) seems to be correct.

I'm skeptical of the problem being related to the filenames or the files missing since it works consistently if I draw the tilemap on layer1 and fails consistently if I draw it on layer0.

Share this post


Link to post
Share on other sites
  • 0
On 5/21/2020 at 12:11 AM, kcowolf said:

I'm skeptical of the problem being related to the filenames or the files missing since it works consistently if I draw the tilemap on layer1 and fails consistently if I draw it on layer0.

I tend to agree, as I have my own test code (similar, but using 128x64 map dimensions) which works for layer 0 if it uses the map base that layer 1 would otherwise use (0x00000) but fails for other map base addresses (0x04000, 0x08000, 0x0c000).  After modifying my code to test layer 0 and layer 1 separately I think I've found that layer 1 can handle map bases 0x0000, 0x4000, 0x8000, 0xc000 while layer 0 can only handle map base 0x0000.

If I switch to have layer 0 use map base 0x0000 and layer 1 use map base 0x4000 then both layers work together (block of tiles on the left is written to layer 1, block of tiles on the right is written to layer 0).

Wish we had hardware to try this on 😉; I guess I'd suspect an emulator bug?

tile.gif

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

Please review our Terms of Use