Jump to content
IGNORED

Programming Questions


Fushek

Recommended Posts

Howdy! I'm working on a game (very slowly as life is busy and I'm not a programmer by nature) but I'm trying to work through two issues that I'm hoping someone can assist me with.

 

Basically, the game is designed to be an Choose Your Own Adventure / RPG with a turn-based combat system. Right now, just trying to get the intro screen and basic game mechanics with a basic fight scene. I've attached my code and a ROM below to show what I have so far, which isn't much :P.

 

My two issues:

 

1) In drawing the Intro Screen (using the Print for each Bitmap card), it stops "printing" them after I hit around the 18th bitmap even though I've used:

 

DEFINE DEF00,25,IntroScreen

 

2) Can you use a variable as the destination for a GOTO statement? As my game will be "page" driven, I want to be able to define a variable as the next "page number" to go to after a battle. In other words, define PAGE = 130 and tell the system GOTO PAGE (except page is the variable of 130 rather than "PAGE").

 

I'm sure that the code is ugly and that there is a TON of things that can be more efficient. Just trying to have fun and end up with some kind of completed project!

 

Any advice is appreciated!

 

post-31049-0-11778200-1444335583_thumb.png post-31049-0-42022000-1444335590_thumb.png

WizWar.rom WizWar.bas

 

  • Like 3
Link to comment
Share on other sites

1) In drawing the Intro Screen (using the Print for each Bitmap card), it stops "printing" them after I hit around the 18th bitmap even though I've used:

 

DEFINE DEF00,25,IntroScreen

You can DEFINE 18 GRAM cards per wait without music and 16 with. So you'll need to break it up into 2 lots of defines separated by a "wait".

 

2) Can you use a variable as the destination for a GOTO statement? As my game will be "page" driven, I want to be able to define a variable as the next "page number" to go to after a battle. In other words, define PAGE = 130 and tell the system GOTO PAGE (except page is the variable of 130 rather than "PAGE").

Kinda. You have

 

ON expr GOTO [label1],[label2],[label3]

 

and

 

ON expr GOSUB [label1],,[label2]

 

So if expr is 0 "label1" wall will be gone to/called, if expr is 1 then "label2" will be gone to/called.

  • Like 1
Link to comment
Share on other sites

You needed a wait and an additional label before rem 16

I used Introscreen2. And load 16 cards at a time.

DEFINE DEF00,16,IntroScreen
wait
DEFINE DEF16,9,IntroScreen2

WAIT

The STIC will ignore command from the CPU when it is drawing the graphic portion of the screen, if I'm right. 'wait' waits for the screen to finish drawing and then starts accepting more data.

  • Like 1
Link to comment
Share on other sites

You can DEFINE 18 GRAM cards per wait without music and 16 with. So you'll need to break it up into 2 lots of defines separated by a "wait".

 

 

Kinda. You have

 

ON expr GOTO [label1],[label2],[label3]

 

and

 

ON expr GOSUB [label1],,[label2]

 

So if expr is 0 "label1" wall will be gone to/called, if expr is 1 then "label2" will be gone to/called.

 

You guys are awesome and quick! I'll try those tonight.

 

Is there a limit to the number of labels that you can define in the On expr GOTO?

  • Like 4
Link to comment
Share on other sites

You guys are awesome and quick! I'll try those tonight.

Glad to help.

 

Is there a limit to the number of labels that you can define in the On expr GOTO?

Looking at the assembly language generated for that expression it creates what is known as a jump table. Thats just a table of ROM addresses for procedures or goto destination labels and some code that indexes into it using expr. So. in regards to code generation the answer is "no" with the caveat that you don't exceed the current ROM segment. However, IntyBASIC might have internal line parsing buffer limits, so nanochess will need to chime in about the maximum line length limit (if any).

Edited by GroovyBee
Link to comment
Share on other sites

Glad to help.

 

 

Looking at the assembly language generated for that expression it creates what is known as a jump table. Thats just a table of ROM addresses for procedures or goto destination labels and some code that indexes into it using expr. So. in regards to code generation the answer is "no" with the caveat that you don't exceed the current ROM segment. However, IntyBASIC might have internal line parsing buffer limits, so nanochess will need to chime in about the maximum line length limit (if any).

 

Indeed there is a limit provided by C++, string::max_size, probably in Windows 32-bit this could be 2 GB ;)

  • Like 2
Link to comment
Share on other sites

 

Indeed there is a limit provided by C++, string::max_size, probably in Windows 32-bit this could be 2 GB ;)

 

Something tells me that unless people start using multi-megabyte labels in their code, you'll reach the Intellivision's ROM capacity in the jump table before you reach the PC's RAM capacity (or the ~2GB 32-bit program capacity) parsing the ON-GOTO / ON-GOSUB.

Edited by intvnut
Link to comment
Share on other sites

You needed a wait and an additional label before rem 16

 

I used Introscreen2. And load 16 cards at a time.

 

DEFINE DEF00,16,IntroScreen

wait

DEFINE DEF16,9,IntroScreen2

 

WAIT

 

The STIC will ignore command from the CPU when it is drawing the graphic portion of the screen, if I'm right. 'wait' waits for the screen to finish drawing and then starts accepting more data.

 

It's a bit more interesting (and technical) than that. I'll try to explain it as plainly as I can, because I find it fascinating how it all works, and maybe you guys will think it is interesting also.

 

The CPU and the STIC (video chip: Standard Television Interface Chip) share a data bus to the video memory (GRAM), and only one can use it at a time; so whenever the STIC is using the bus, the CPU can't.

 

The STIC normally accesses video memory to draw a frame on the television screen, during which it asserts control to the bus. During this time, the STIC converts the video buffer data into a TV signal, which is drawn on the TV by an electron gun moving from top-to-bottom, left-to-right, one scan line at a time. At the end of a full frame, the electron gun moves back to the top in what is called "vertical retrace" or "vertical blanking."

 

During this so-called "VBLANK" period, the STIC relinquishes control of the bus, sends an "interrupt signal" to the CPU which results in it gaining brief access to the video memory and the STIC. This occurs 60 times a second, after each frame is drawn on the screen.

 

The bottom line is that the CPU has no access to GRAM or the STIC registers except during the VBLANK period. The "interrupt signal" does exactly that: interrupts the CPU so that it can do whatever is needed to prepare the next frame. When this happens, the EXEC takes control briefly, saves the current state of the CPU and all its registers, and calls a special routine called an "interrupt service request" or ISR. When it finishes, the ISR just returns to the EXEC routine that called it, which restores the state and lets the CPU go back to where it was originally, as if nothing happened.

 

(Fun fact: The trick of home-brew programming avoiding the EXEC is to write a custom ISR that never calls the EXEC for anything else: the EXEC boots up, reads the cartridge header, calls a short routine to draw the title screen and -- BAM! without it being aware of it, your program sets up its own ISR, and never returns. So long, EXEC!)

 

The beauty of this VBLANK period is that since it occurs regularly every 60th of a second, it serves as the "heartbeat" of the Intellivision, and can be used reliably to keep time and synchronize all aspects of a game. Indeed, every Intellivision game does this.

 

IntyBASIC does a pretty good job at abstracting this all away so that you don't have to worry about it. First, it "buffers" all graphic changes. That is, calling DEFINE or such will store the data in normal RAM and hold it there until the next VBLANK period. Second, it automatically handles the "interrupt signal" by defining its own ISR that updates the screen and all internal variables, graphics, music, and sound effects; 60 times a second.

 

So, you say, that's all good and interesting, but why the "WAIT"? To which I respond, it does exactly what it says on the tin: The WAIT statement waits for the next VBLANK interrupt signal to occur. The end result is that your game runs "in time," synchronized with the internal "frame" counter.

 

For example, a typical program that does the following:

WHILE true
  GOSUB UpdateEnemies
  GOSUB UpdateCollisions
  GOSUB UpdateWorld

  WAIT
WEND

Will make sure that the functions always start after the next VBLANK. So if all routines are short enough to complete before the next interrupt signal, your game will update everything at 60 Hz. By contrast, consider the following:

WHILE true
  GOSUB UpdateEnemies
  GOSUB UpdateCollisions
  WAIT

  GOSUB UpdateWorld
  WAIT
WEND

By splitting the "game engine" loop into two phases, that code causes the game to run at 30 Hz: it updates one part during one frame, and another part during a second, taking two whole frames to update the entire game world.

 

Both are perfectly adequate, depending on your game, and both are equally effective. Sometimes speed is critical, and you want to make sure that your game loop runs as fast as possible and as close to 60 HZ as you can; other times, not so much, so you have the leisure of updating graphics and objects over several frames perhaps for a more intricate game-play mechanic.

 

So that's what WAIT does and how it works. Please feel free to ask questions, ignore this whole topic, or tell me to sod off. :)

 

-dZ.

Edited by DZ-Jay
  • Like 4
Link to comment
Share on other sites

Another fun fact: The interrupt signal is actually a hardware feature of the CPU and not really setup in software. Thus, it is typically called a "hardware interrupt." The CPU is then hard-wired to call a specific chunk of code in the EXEC ROM to handle the interrupt signal. This cannot be altered or avoided without actual physical hardware modifications*. Conversely, the address to the "Interrupt Service Request" (ISR) routine is actually configured in RAM in what is called an "interrupt vector," so any program can change it at will.

 

Thus, while home-brewed programs avoid using the EXEC's more sophisticated game routines, there is no way to avoid the EXEC completely, since every 60th of a second, the hardware interrupt signals, and the EXEC jumps in. The good thing is that, as I mentioned in my previous post, it does nothing more than save the state of the entire machine and call the special ISR. The ISR is expected to just "return to caller," which will prompt the EXEC to finish off the sequence by restoring the previous state and returning the CPU to whatever it was doing before. Returning to caller is not really required, though it is convenient since your program would have to do essentially the same thing.

 

And for those of you with hardcore technical chops, just in case you were wondering: the VBLANK interrupt is the ONLY one that is enabled in the Intellivision CPU, and the only one to which a program has access (via the ISR interrupt vector). This means that there is no way to "chase the beam" like they do in other platforms to multiplex objects during "horizontal retrace."

 

Just be thankful that the original designers were gracious enough to give us access to the interrupt vector in software -- without which there would be no home-brewing as we know it! ;)

 

-dZ.

 

 

* Well, not quite. Although you cannot remove or alter the hardware interrupt, you can actually tell the CPU to ignore it momentarily. This is typically done in long-running initialization routines that may take longer than a frame to set up. However, I don't believe IntyBASIC gives you access to this feature.

Edited by DZ-Jay
Link to comment
Share on other sites

And for those of you with hardcore technical chops, just in case you were wondering: the VBLANK interrupt is the ONLY one that is enabled in the Intellivision CPU, and the only one to which a program has access (via the ISR interrupt vector). This means that there is no way to "chase the beam" like they do in other platforms to multiplex objects during "horizontal retrace."

 

 

Assume that I have not much more than a conceptual understanding, and that I only read the book about it: were there other systems than the VCS where you could "chase the beam"? With the VCS you HAD to... I thought this was abstracted away from programmers on pretty much every other platform.

Link to comment
Share on other sites

Assume that I have not much more than a conceptual understanding, and that I only read the book about it: were there other systems than the VCS where you could "chase the beam"? With the VCS you HAD to... I thought this was abstracted away from programmers on pretty much every other platform.

 

I think Vectrex programming is pretty close, no? And there are definitely some other systems that are capable of timed, mid-scanline changes to the graphics output; the Tandy CoCo is one.

Link to comment
Share on other sites

 

I think Vectrex programming is pretty close, no? And there are definitely some other systems that are capable of timed, mid-scanline changes to the graphics output; the Tandy CoCo is one.

 

Good point about the Vectrex. From what little I gleaned when I looked into homebrew a few years back.. yeah, it's at least "pretty close". It kinda has to be.

Link to comment
Share on other sites

 

Assume that I have not much more than a conceptual understanding, and that I only read the book about it: were there other systems than the VCS where you could "chase the beam"? With the VCS you HAD to... I thought this was abstracted away from programmers on pretty much every other platform.

The Sinclair ZX81 computer didn't have a true "graphics generator" circuit - instead the designers tricked the Z80 processor into generating the graphics display data stream.

 

As a result, even though the computer was designed to display only character graphics, programmers have rewritten the display code to generate "hires" displays and games.

Link to comment
Share on other sites

The Apple II computer had a minimalist audio circuit. A speaker was wired to the address decoder circuit for the "sound" register. Whenever the "sound register" address was accessed, a click was heard in the speaker. That was it.

 

With this simple setup, programmers wrote code that played multi-part music harmony, and even voice synthesis.

 

What impressed me was that some games played music in the background while the game was playing. Since the Apple II had no software programmable interrupts, the programmer had to design the game program to make sure that no matter what path the code took, the execution time would be the same, so that at the proper intervals the code could hit the sound register. This was the audio version of "chasing the beam".

  • Like 1
Link to comment
Share on other sites

The Apple II computer had a minimalist audio circuit. A speaker was wired to the address decoder circuit for the "sound" register. Whenever the "sound register" address was accessed, a click was heard in the speaker. That was it.

 

With this simple setup, programmers wrote code that played multi-part music harmony, and even voice synthesis.

 

What impressed me was that some games played music in the background while the game was playing. Since the Apple II had no software programmable interrupts, the programmer had to design the game program to make sure that no matter what path the code took, the execution time would be the same, so that at the proper intervals the code could hit the sound register. This was the audio version of "chasing the beam".

 

The CoCo is in a similar boat, with nothing but a DAC to work with for sound. It's capable of great results, but the programmer needs to do all the heavy lifting if you want sound & action at the same time. It sometimes makes me sad that I grew up with the CoCo -- between that and the lack of hardware sprites, it made programming a game seem totally impossible, so I pretty much gave up on it despite multiple attempts, and just stuck to sound programming. :(

 

Oh, well, at least now we have lots of options for every possible platform, including the Intellivision! And yet most of what I do now is, at heart, the exact same stuff I did back then... :)

Link to comment
Share on other sites

 

Assume that I have not much more than a conceptual understanding, and that I only read the book about it: were there other systems than the VCS where you could "chase the beam"? With the VCS you HAD to... I thought this was abstracted away from programmers on pretty much every other platform.

 

On the C64 you could request a raster interrupt on a particular scanline. Likewise on the NES (depending on the mapper chip used). This is how they implemented split-screen effects, such as status bars that stayed still relative to a scrolling background. (And, IIRC the Sega Genesis also used raster interrupts for certain effects.)

 

The closest you get to chasing the beam on the Intellivision is when you have to scroll BACKTAB contents. You change HDLY/VDLY in the interrupt handler, and then to prevent display artifacts, you need to move BACKTAB before the raster refresh gets there.

 

 

The Apple II computer had a minimalist audio circuit. A speaker was wired to the address decoder circuit for the "sound" register. Whenever the "sound register" address was accessed, a click was heard in the speaker. That was it.

 

With this simple setup, programmers wrote code that played multi-part music harmony, and even voice synthesis.

 

I always had so much fun with PEEK(-16336) / LDA $C030. :-) One of my high school hobbies was an attempt to perfect a 3-voice harmony loop; I never quite got it right. But it made some interesting sounds, much to the annoyance of my teachers, I'm sure.

 

 

What impressed me was that some games played music in the background while the game was playing. Since the Apple II had no software programmable interrupts, the programmer had to design the game program to make sure that no matter what path the code took, the execution time would be the same, so that at the proper intervals the code could hit the sound register. This was the audio version of "chasing the beam".

 

Some games used a different strategy for music: They would do a little bit of game work, and then play a little bit of sound. The result wasn't exactly awesome: It sounded like the music was being played through a fan, or something. On the plus side, the pitches stayed 'true' regardless of the game loading. On the minus side, the tempo shifted up and down noticeably with game loading. (The game itself also slowed down and sped up.) Moon Patrol for the Apple ][ demonstrates this rather dramatically. (Skip to about 0:25.)

 

Night Mission Pinball, OTOH, I believe worked more like how you describe. Other games I played often saved sound effects for when graphics weren't being updated.

Edited by intvnut
  • Like 1
Link to comment
Share on other sites

 

On the C64 you could request a raster interrupt on a particular scanline. Likewise on the NES (depending on the mapper chip used). This is how they implemented split-screen effects, such as status bars that stayed still relative to a scrolling background.

 

The closest you get to chasing the beam on the Intellivision is when you have to scroll BACKTAB contents. You change HDLY/VDLY in the interrupt handler, and then to prevent display artifacts, you need to move BACKTAB before the raster refresh gets there.

 

 

 

I always had so much fun with PEEK(-16336) / LDA $C030. :-) One of my high school hobbies was an attempt to perfect a 3-voice harmony loop; I never quite got it right. But it made some interesting sounds, much to the annoyance of my teachers, I'm sure.

 

 

 

Some games used a different strategy for music: They would do a little bit of game work, and then play a little bit of sound. The result wasn't exactly awesome: It sounded like the music was being played through a fan, or something. On the plus side, the pitches stayed 'true' regardless of the game loading. On the minus side, the tempo shifted up and down noticeably with game loading. (The game itself also slowed down and sped up.) Moon Patrol for the Apple ][ demonstrates this rather dramatically. (Skip to about 0:25.)

 

Night Mission Pinball, OTOH, I believe worked more like how you describe. Other games I played often saved sound effects for when graphics weren't being updated.

oh the love i have for the apple ii. I wish back in 94 i didnt sell my apple iie enhanced with color monitor and dual disk drive thing that went under the monitor for $50. At least my pi has everything apple ii to enjoy playing. Wish i could remember the robin hood timesish choose your adventure "point and click" (more like type your direction) game i used to play back in the day.
  • Like 1
Link to comment
Share on other sites

oh the love i have for the apple ii. I wish back in 94 i didnt sell my apple iie enhanced with color monitor and dual disk drive thing that went under the monitor for $50. At least my pi has everything apple ii to enjoy playing. Wish i could remember the robin hood timesish choose your adventure "point and click" (more like type your direction) game i used to play back in the day.

 

You're not thinking of King's Quest, are you?

 

Link to comment
Share on other sites

 

You're not thinking of King's Quest, are you?

 

https://www.youtube.com/watch?v=SwM06NbZ2r0

maybe. I know it drew the screen like that game does. I just dont remember actually moving a character. But its been over 25 years since i played. However i could have sworn i had to type which way to go.
Link to comment
Share on other sites

Maybe Sherwood Forest?

 

http://www.youtube.com/watch?v=p1XmwkY_8-U

thank you so much. That is it. The second i saw the title screen i knew. And i do remember they checkerboarded the colors which was inspiration in my early pixel art days when i was limited in colors i would checkerboard 2 colors to make a new one.
Link to comment
Share on other sites

There are a few Apple ]['ers here and there, sharing the love.

 

oh the love i have for the apple ii. I wish back in 94 i didnt sell my apple iie enhanced with color monitor and dual disk drive thing that went under the monitor for $50. At least my pi has everything apple ii to enjoy playing. Wish i could remember the robin hood timesish choose your adventure "point and click" (more like type your direction) game i used to play back in the day.

  • Like 1
Link to comment
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.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   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.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...