Family BASIC scrolling backgrounds

Started by zmaster18, August 20, 2015, 01:47:15 pm

Previous topic - Next topic

UglyJoe

August 23, 2015, 12:13:37 pm #15 Last Edit: August 23, 2015, 12:22:22 pm by UglyJoe
I figured out a really hacky way of filling the whole nametable with stars.  It's hilariously bad, but it gets the job done.  All it does is spam the PPU write register with the "star" tile in a loop.  It ends up being semi-random since I can't control the timing, but I threw some modulo logic in there to try and keep the stars from clustering together.

I'll probably have to get back into ASM stuff in order to do it properly, given the precise timing needed to write data to the PPU. 

Anyway, here's the updated code listing:


5 CLS
10 FOR I=0 TO 300
15 IF I MOD 3 = 0 THEN PAUSE 1
20 POKE &H2007, &HCD
30 NEXT
150 A=0
200 REM PAUSE 1
250 POKE &H2005,0
300 POKE &H2005,A
500 A=A+1
600 IF A>239 THEN A=0
650 GOTO 200


UPDATE: tried this on real hardware (v2.1a) and it spams the screen with random characters instead of the "star" character.  I guess Nestopia is not as accurate as I thought.  Nintendulator seems to match the real hardware better.

zmaster18

August 23, 2015, 12:41:32 pm #16 Last Edit: August 23, 2015, 06:41:18 pm by zmaster18
I just tried it in V3 and I also got a screen of random characters as well as some pallet changes. While the characters were being drawn, the screen was shaking.

Post Merge: August 23, 2015, 06:41:18 pm

Here's an example of horizontal scrolling using 2 screens: https://www.youtube.com/watch?v=PFCYHfTKvqI  at 34:23 (I must say, this game has good presentation. There is music during gameplay and ending story!)

P


zmaster18

August 24, 2015, 07:18:39 am #18 Last Edit: August 24, 2015, 09:10:51 am by zmaster18
At the very end of the game, where there is story being displayed. It's actually at 35:40 in the video.

Post Merge: August 24, 2015, 09:09:48 am

I know how this technique was done in V3. In order for one screen to scroll horizontally to the next screen, you need to first create 2 screens of background graphics:


SCREEN 0
PRINT"THIS IS SCREEN 0"
SCREEN 1
PRINT"THIS IS SCREEN 1"


Then type SCREEN 0 to go back to the first screen.

Next, use the code to write the x value to &H2005:


10 A=0
20 PAUSE 1
30 POKE &H2005,A
40 POKE &H2005,0
50 A=A+1
60 IF A>255 THEN SCREEN 1
70 GOTO 20


This is pretty cool. You can use this for transitioning from a title screen to game screen or use this technique to have a 2 screen playing field for your gameplay. What a handy technique!!  :o

UglyJoe

I think that would work with V2.1a if you have a background loaded (via the BG editor).  The saved BG (the one you'd see by typing VIEW) is in the other non-mirrored section of the nametable.

zmaster18

August 25, 2015, 07:53:09 pm #20 Last Edit: August 25, 2015, 08:31:32 pm by zmaster18
Quote from: P on August 20, 2015, 04:05:51 pm
I've seen lots of those NND compilations but I don't remember any of them scrolling. Do you remember which one it is?

I'm not sure how to do it in assembly though. V3 seems to use SCREEN to switch between the two nametables. Syntax is:
SCREEN display,active
where "display" is screen number (0 or 1) used to choose which screen to display and "active" is which screen (0 or 1 again) the cursor is placed on (you can type stuff on the screen you can't see). If you get stuck you can press CTR+D to restore both to screen 0.

But the question is if V3 keeps it's scroll position buffered somewhere in memory so it can be controlled at will. Else it will keep resetting the scroll position to the beginning of either screen 0 or 1 every frame. Also scroll position must be set in a vertical blanking.

I've been playing around with VIEW, SCREEN, and the BGTOOL and it looks like the 3 interact with each other. I accidentally erased my BG screen when using the SCREEN command. It actually overwrites the BG screen with the SCREEN 1 screen. I'm going to keep playing with these commands and I will figure out what's going on here. I will update you guys with my findings.

Edit: The nametable for SCREEN 1 is shared with BGTOOL screen. Damn, I was hoping to use the SCREEN command for something but now I don't think it's possible.
I have a title screen that uses the BGTOOL nametable. I wanted to use SCREEN 1 to draw to while displaying SCREEN 0, then display SCREEN 1 after drawing was complete.

I'm trying to create a method where you can have a screen displayed completely without having to see every individual tile being drawn. I have to find a way!!!!!

P

That's the very the purpose of having two screens as I understands it. So you can draw on the one not displaying and then swapping or scrolling it in when you are done drawing.

SCREEN x,y - Here x controls the scroll position: 0 = &H2000 (screen0), 1 = &H2400 (screen1). While y controls which of the two screens the cursor is on. I think you can use it to to control where LOCATE and such things are drawing, on the screen you are not displaying.

VIEW simply copies the contents of screen1 to screen0 without touching the contents of screen1. So if you just want to swap in the new screen you use VIEW.

zmaster18

I'm in a tough situation... My game's title screen uses the BGTOOL memory because it is the most complicated screen in my game. There is no pattern to how it is made, so I can't use loops to draw it piece by piece. I would have to use a bunch of LOCATEs and PRINTs and even COLORs! I think if I had to draw the title screen with code, it would be at least 500-1000 bytes. I need this title screen because it has all the gameplay options.
So using the BGTOOL for the title screen won't take any program memory space.

Now I can only use one screen to draw my score screen and gameplay screen. My score screen is very simple and just prints a few lines in a repetitive pattern and should only be about 200 bytes. This score screen between levels should also draw pretty fast as well.

My gameplay screen has to be drawn tile by tile. I would have liked to use the 2 screen method to do this, but then I would erase my title screen.

Here's the dilemma:

-Use BGTOOL for title screen, but redraw everything slowly for gameplay
-code title screen, waste program space, but have quick transitions to gameplay screen. But you would actually have to reload the entire program and BG screen from tape just to go back to the title screen.

Actually, the first option sounds much better. Less program space wasted and more playable for the user when going back to the title screen after game over. Drawing the gameplay screen tile by tile isn't too bad. It would probably take about 10 seconds to do it though...

P

So the classic speed vs space problem? If it affects gameplay it sounds better with the speed solution, but you say the user needs to reload it from tape so the first option is much better even if gameplay is a bit slower.

zmaster18

August 26, 2015, 10:56:39 am #24 Last Edit: August 28, 2015, 09:41:58 pm by zmaster18
Quote from: P on August 26, 2015, 10:24:40 am
So the classic speed vs space problem? If it affects gameplay it sounds better with the speed solution, but you say the user needs to reload it from tape so the first option is much better even if gameplay is a bit slower.

Once the level is drawn, it won't affect speed during the gameplay. The user is just going to have to watch the level load piece by piece. It's actually not too big of an issue. It was really more of a presentation/design issue.

My game will use DATA statements to load meta-tiles into the game screen. One number in the data statement will represent a meta-tile of 4 characters in a 2x2 block. Each row will be 12 meta-tiles, or 24 characters wide. The value of the piece of data will tell the level-loading function what type of meta tile it is as well as the color. Once the full game screen is drawn, the in-gameplay functions will use the SCR$ to determine what the properties of the tiles are.

My levels are going to be 12 x 9 meta tiles. Each DATA statement will look like this:

1000 DATA1,2,3,4,5,6,7,8,9,A,B,C
1001 DATA1,2,3,4,5,6,7,8,9,A,B,C
etc...
each DATA line is only 28 bytes with this integer-based method. I can also have the data type to be a string and have it like this:

1000 DATA"123456789ABC"

With this method, I would use the string functions to pick out 1 character at a time. This method eliminates the commas and is only 19bytes.
Each piece of data could be hex (&H0 to &HF) or I could use the alphabet and then get the ASCII value for each letter(A=65,B=66,C=67). With hex, I can have 16 different types of meta tiles. With the alphabet, as well as katakana, I can have so much more types of meta tiles.

So my level would be 12 meta tiles wide by 9 meta tiles long. I want 9 levels. (19x9)x9=1539bytes for all my level DATA. The rest of my memory is for gameplay functions, printing,data for other stuff in the game, and music/sound effects. I'm confident that I will have enough memory to make this game!  :redcart:

Post Merge: August 28, 2015, 09:41:58 pm

Here's an example of a text screen on top of a scrolling space background:

https://www.youtube.com/watch?v=XrBDmuy9QMA   at 1:41:30

zmaster18

After looking at the V3 manual, I noticed that BGGET and BGPUT will allow you to use screen 0 and screen 1 as well as have your BGTOOL screen to be saved in memory. Now you can have your title screen made with BGTOOL and then do your gameplay screens drawn with the 2 screen method for smooth transitions between game screens.

After you are done displaying your title screen, use BGGET to get the title screen from VRAM and put it in program RAM. Now you can use SCREEN 0 and SCREEN 1 to do drawing.

When you want to return to the title screen, use BGPUT to get your BG screen from program RAM into the VRAM. So now you have 3 screens you can work with.

P

Yeah as long as BGPUT and BGGET can be included in a program it should work I think. Some commands intended to be used in direct mode, refuses to work if they are used in a program.

zmaster18

I just tired it and confirmed that BGGET and BGPUT can be used in program mode. BGPUT actually doubles as a VIEW command when it is run. The BG screen will automatically be dispalyed after running the BGPUT.

P

Are you sure about that? I switched to BG-screen1 using SCREEN, typed "MARIO" and some random stuff, switched back (CTR+D) and saved it to program memory with BGGET. Then I switched to BG-screen1 again, cleared it and typed "LUIGI". Then I used BGPUT which changed BG-screen1 back to MARIO but nothing happened to BG-screen0 until I entered VIEW.