Jump to content
IGNORED

[IntyBASIC] More advanced tutorials - suggestions


GroovyBee

Recommended Posts

In terms of optimization (at the risk of pre-optimization), I wonder if it is better from a storage or game-speed perspective to play an effect using 50 words from a DATA statement, or to have an n-line procedure that calculates the tones and plays them.

 

 

General statement here: it's almost always going to be faster to read some pre-computed amount from a DATA statement, and use that for "whatever". Reading a value from ROM is faster than almost every other type of instruction. It also lends itself well to simpler code in general. I find that I can make incredibly simple routines do very complex things, just by iterating through an array in ROM. Sound, graphics, text, physics engines (yes, I've done a small gravity engine using a lookup table): you name it, it'll likely be faster.

 

Storage-wise it's obviously a trade-off, but unless you're making the biggest Intellivision game of all time there's nothing to worry about. It's unbelievable how wasteful you can be and still have oodles of space to spare.

Link to comment
Share on other sites

It's unbelievable how wasteful you can be and still have oodles of space to spare.

As someone who has indeed wasted huge amounts of space in the pursuit of technical simplicity, I cannot agree more.

 

The blatant disregard of storage efficiency for graphics and animations data in Christmas Carol is shameful.

 

However, all that time not spent devising clever ways to compress or de-duplicate graphics data was spent creating some of the most fluid and expressive animation sequences in an 8-bit vintage console. So it was a fair compromise. ;)

 

dZ.

  • Like 2
Link to comment
Share on other sites

  • 4 months later...

:dunce: Have there been any new tutorials lately????

 

I am way too dumb to figure out anything new on my own.

Did you see this one? http://atariage.com/forums/topic/249273-intybasicgame-sample/

I posted that in February.

It is a bit example how to compile using window's run box. Also somewhat ok sample of Tilestudio stuff working with Intycolor. And methods how to use Array Slot SystemTM for objects. Using 4 sprites to make 1 object.

Link to comment
Share on other sites

Did you see this one? http://atariage.com/forums/topic/249273-intybasicgame-sample/

I posted that in February.

It is a bit example how to compile using window's run box. Also somewhat ok sample of Tilestudio stuff working with Intycolor. And methods how to use Array Slot SystemTM for objects. Using 4 sprites to make 1 object.

Yes. I looked it over when it was posted and I have visited it several times since. It is very good.

Link to comment
Share on other sites

Yes. I looked it over when it was posted and I have visited it several times since. It is very good.

Any specific topic/tutorial you want covered?

 

Only new thing I can share now is the highscore code I got working.

CompareHSice:procedure
#MCard=sc(0)*1000+sc(1)*100+sc(2)*10+sc(3)
bombrate=sc(4)*10+sc(5)
'I'm using a 6 byte array to hold the digits, so I need to collapse them and put them
'into 1 8-bit "temporary" variable to hold the lower 2 digits of the score ____00
'Another in 1 16-bit "temporary" variable to hold the upper 4 digits of the score 0000__

' 3 cases to determine whether the current score is higher than the highscore

if bombrate>hsice and #hsice=0 then gosub UpdateHSice:goto HSiceHere 

'This checks if 16-bit hsice is 0 and check if the current variable is higher than 
'8-bit variable score.  

if #MCard=#hsice then if bombrate>hsice then gosub UpdateHSice:goto HSiceHere 

'This checks if the 16-bit score is equal to each other.
'If they are equal, then it compares the 8-bit variable

if #MCard>#hsice then gosub UpdateHSice:goto HSiceHere

'This final check compare the 2 16-bit variables


HSiceHere:
'label and the 'goto HSiceHere' in the 3 cases can be omitted I believe.  Just to be safe.

return
end

UpdateHSice:procedure
#hsice = #MCard
hsice = bombrate
'Updates the variable
return
end

I tried using my PONG high score routine, but it horribly flawed. :_(

if (lives>12){
check:
if (highscore[4]<digits2[4]){
if(highscore[4]!=digits2[4]){UpdateHS();goto HS;}}
if (highscore[3]<digits2[3]){
if(highscore[3]!=digits2[3]){UpdateHS();goto HS;}}
if (highscore[2]<digits2[2]){
if(highscore[2]!=digits2[2]){UpdateHS();goto HS;}}
if (highscore[1]<digits2[1]){
if(highscore[1]!=digits2[1]){UpdateHS();goto HS;}}
if (highscore[0]<digits2[0]){
UpdateHS();goto HS;}
HS:
game++;lives=0;}

UpdateHS(){
highscore[4]=digits2[4];
highscore[3]=digits2[3];
highscore[2]=digits2[2];
highscore[1]=digits2[1];
highscore[0]=digits2[0];}

Both routine took me all day to figure out. The PONG highscore took a day, and I was more limited in ROM space.

  • Like 1
Link to comment
Share on other sites

Any specific topic/tutorial you want covered?

 

Only new thing I can share now is the highscore code I got working.

CompareHSice:procedure
#MCard=sc(0)*1000+sc(1)*100+sc(2)*10+sc(3)
bombrate=sc(4)*10+sc(5)
'I'm using a 6 byte array to hold the digits, so I need to collapse them and put them
'into 1 8-bit "temporary" variable to hold the lower 2 digits of the score ____00
'Another in 1 16-bit "temporary" variable to hold the upper 4 digits of the score 0000__

' 3 cases to determine whether the current score is higher than the highscore

if bombrate>hsice and #hsice=0 then gosub UpdateHSice:goto HSiceHere 

'This checks if 16-bit hsice is 0 and check if the current variable is higher than 
'8-bit variable score.  

if #MCard=#hsice then if bombrate>hsice then gosub UpdateHSice:goto HSiceHere 

'This checks if the 16-bit score is equal to each other.
'If they are equal, then it compares the 8-bit variable

if #MCard>#hsice then gosub UpdateHSice:goto HSiceHere

'This final check compare the 2 16-bit variables


HSiceHere:
'label and the 'goto HSiceHere' in the 3 cases can be omitted I believe.  Just to be safe.

return
end

UpdateHSice:procedure
#hsice = #MCard
hsice = bombrate
'Updates the variable
return
end

I tried using my PONG high score routine, but it horribly flawed. :_(

if (lives>12){
check:
if (highscore[4]<digits2[4]){
if(highscore[4]!=digits2[4]){UpdateHS();goto HS;}}
if (highscore[3]<digits2[3]){
if(highscore[3]!=digits2[3]){UpdateHS();goto HS;}}
if (highscore[2]<digits2[2]){
if(highscore[2]!=digits2[2]){UpdateHS();goto HS;}}
if (highscore[1]<digits2[1]){
if(highscore[1]!=digits2[1]){UpdateHS();goto HS;}}
if (highscore[0]<digits2[0]){
UpdateHS();goto HS;}
HS:
game++;lives=0;}

UpdateHS(){
highscore[4]=digits2[4];
highscore[3]=digits2[3];
highscore[2]=digits2[2];
highscore[1]=digits2[1];
highscore[0]=digits2[0];}

Both routine took me all day to figure out. The PONG highscore took a day, and I was more limited in ROM space.

 

I follow your IntyBASIC code, but I don't follow your PONG code.

 

For the IntyBASIC code, you could simplify it a little bit:

.

' Current score is stored as 6 bytes in sc(0)..sc(5). sc(0) holds the high digit.
' Temporarily put upper 4 digits of current score into #MCard, and lower 2 digits
' into bombrate. 
CompareHSice:  Procedure
    #MCard = ((sc(0)*10 + sc(1))*10 + sc(2))*10 + sc(3)
    bombrate = sc(4)*10 + sc(5)

    If #MCard > #hsice Or (#MCard = #hsice And bombrate > hsice) Then 
        #hsice = #MCard
        hsice = bombrate
    End If

    Return
End 

.

One nice trick here is that rewriting the computation for #MCard this way makes the multiplication go a bit faster, since each *10 is just 2 shifts, a MOVR and an ADDR.

 

For your PONG code, I don't understand what statements of the form "if (x < y) { if (x != y) { do something } }" accomplish. (Although, you did say your code was flawed.) If x < y, then it's also true that x != y, so it's a bit redundant. I suspect you mistyped something there, or have the x!=y in not-quite-the-right spot. The usual way to do a lexicographic compare is more like this:

.

if (lives > 12)
{
    int i;

    for (i = 4; i >= 0; i--)
        if (highscore[i] != digits2[i])
            break;

    if (i >= 0 && highscore[i] < digits2[i])
        for (i = 4; i >= 0; i--)        
            highscore[i] = digits2[i];

    game++;
    lives = 0;
 }

.

Or if you unroll it completely:

.

if (lives > 12)
{
    if (highscore[4] > digits2[4]) goto done_high;
    if (highscore[4] < digits2[4]) goto new_high;

    if (highscore[3] > digits2[3]) goto done_high;
    if (highscore[3] < digits2[3]) goto new_high;

    if (highscore[2] > digits2[2]) goto done_high;
    if (highscore[2] < digits2[2]) goto new_high;

    if (highscore[1] > digits2[1]) goto done_high;
    if (highscore[1] < digits2[1]) goto new_high;

    if (highscore[0] >= digits2[0]) goto done_high;

new_high:
    highscore[0] = digits2[0];
    highscore[1] = digits2[1];
    highscore[2] = digits2[2];
    highscore[3] = digits2[3];
    highscore[4] = digits2[4];
    highscore[5] = digits2[5];

done_high:
    game++;
    lives = 0;
}


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

That would make a good advanced topic.

 

No worries. I'm just looking for "input" as Johnny 5 would say.

 

 

 

If your wannabe 2 colour "enemy" has restricted motion e.g. moves only left/right or up/down you can reprogram 2 GRAM cards on the fly and put them in BACKTAB and then overlay a sprite on top. If its free roaming then you are better off using 2 sprites.

Link to comment
Share on other sites

  • 2 months later...

 

Here's my informal list of useful "advancy" topics, in no particular order:

  • Sound effects
  • Fixed-point arithmetic
  • Software collision detection (i.e., bounding boxes)
  • Multi-MOB sprites (e.g., colour overlaying, large bosses)
  • GRAM cycling animations at fractional rates
  • Smooth background scrolling
  • Sub-pixel sprite movement
  • Object speed acceleration/deceleration with linear or wave damping
  • Using damping for extra-high-accuracy hand-controller input handling
  • Simple physics simulations:
    • Acceleration due to gravity (e.g., parabolic jumping, ballistics, etc.)
    • DYCP and other demo-y effects
    • Friction & momentum (e.g., slippery surfaces, movement in water, etc.)
    • Moving objects converging on a point

 

 

I know everybody has been busy with projects, and life in general, but, anything new in the tutorial area? In particular I am looking for intyBASIC examples (explanations really) of sub pixel movement. The Fiction and momentum thing is really interesting too. I have been very slack of late working on my own IntyBASIC stuff and the lack of tutorials is now my excuse for being lazy. "I can't work on my game cause I don't know how to do it and the people that know won't show me, WAAA". :sad: :-D

  • Like 5
Link to comment
Share on other sites

Well, what you do need to do is to set up a working game loop. Set up the control scheme that your player can move in 1 pixel in each direction to start this experimentation. Decide what game you want to make and etc.

 

To do friction and acceleration. You'll need a variable called projection-x and projection-y, or projx and projy shorter name.

 

Now in your game loop, your always adding proj variable to your char coordinates.

example:

charx=charx+projx

chary=chary+projy

 

Now your control scheme set up would be...

 

if cont.up then projy=projy-1

if cont.down then projy=projy+1

if cont.left then projx=projx-1

if cont.right then projx=projx+1

 

Compile and test it, you'll see your character moving frictionless space once you press the disc in north, south, west, east. And you can put # in projx and projy variable, #projx, and see your character flying across the screen and getting sick in the process. If you want friction, add

 

if projx<>0 then projx=projx-1

if projy<>0 then projy=projy-1

 

wait, that won't work... hold on, you'll need a timer or something to keep this firing every frame. Create new variable name timeproj

 

if timeproj>=4 then timeproj=0

timeproj=timeproj+1

if timeproj=1 then

if projx<>0 then projx=projx-1

if projy<>0 then projy=projy-1

end if

 

Now you have friction that will fire every third frame if I did that greater than thingy correctly. And sub-pixel movement, I'll have nanochess explain that, I'm feeling lazy. :P

 

I think i had a 2nd variable tracking the y position in Mad Bomber. Let me find that code, hold on to your horses....

 

Ok here it is, sorry for keeping you waiting.

if dropspeed<>0 then 

bombsp(i)=bombsp(i)+bombspeed+bombb(i)
if gravity=1 and gravitytimer=1 then bombb(i)=bombb(i)+1
end if

while bombsp(i)>=200:bomby(i)=bomby(i)-1:bombsp(i)=bombsp(i)+10:wend
while bombsp(i)>=10:bomby(i)=bomby(i)+1:bombsp(i)=bombsp(i)-10:wend

Alternating, in Computer Space and PONG, I added the projection every 2 frame in PONG and Computer Space I think every 4 or 5 frames. Here's the c code for this...

if (frame==4){UpdateShip();}

void UpdateShip() {
projc=projx/16;
projd=projy/16;
shipy=shipy+projd;
shipx=shipx+projc;
}

Translation in IntyBASIC, it would be

 

if timer=4 then

projc=projx/16;
projd=projy/16;
shipy=shipy+projd;
shipx=shipx+projc;

end if

 

Unfortunately, variable frame been taken by IntyBASIC. The game sure slow down a lot when you're doing frame%4 or something :dunce: . frame is a 16-bit variable, so use a 8-bit variable to mod from the power of 2s. OK, hopefully my madness made some sense. Back to lurking this forum aimlessly.

  • Like 2
Link to comment
Share on other sites

  • 1 year later...

I would definitely be interested in a IntyBasic tutorial for Sound Effects. My efforts thus far involve a lot of guesswork and poor results.

 

I tried messing around with PSGtinkerer but did not have much success.

 

Anyone providing some basic instruction in the sound department would be greatly appreciated !!

Link to comment
Share on other sites

I would definitely be interested in a IntyBasic tutorial for Sound Effects. My efforts thus far involve a lot of guesswork and poor results.

 

A while ago in this programming forum I made a sfx demo with source. Later, in Pricess Lydie I used similar code, invoked every 2 frames (25/30Hz), and uses interleaved PAL and NTSC data. To convert AY-3 NTSC frequencies to PAL, multiply by 1.11746826390131

'#SoundAddress=VARPTR Sound_Laugh(0)+NTSC


'==========SOUND PLAYER===================== run it every 2 frames.
SOUNDPLAY2: PROCEDURE
IF #SoundAddress<>0 THEN
#ta=PEEK(#SoundAddress) '--Get data
#SoundAddress=#SoundAddress+2 '--next address.
IF #ta=0 THEN  '-- 0 = end
  #SoundAddress=0 '--clear data address. 0=don't play
  RETURN 
END IF 
IF #ta AND 1 THEN SoundVolume=SoundVolume-1 '-Volume down, if it's an odd value 
  SOUND 2,#ta,SoundVolume
Else
  SOUND 2,1,0
END IF 
END

'Sound data has both PAL and NTSC: DATA PAL,NTSC,PAL, etc. To convert NTSC data to PAL: 1.11746826390131
Sound_Laugh:
DATA $166,$140,$154,$130,$142,$120,$130,$110,$7E,$71,$179,$151,$166,$140,$154,$130,$142,$120,$90,$81,$18A,$161,$177,$150
DATA $166,$140,$154,$130,$A2,$91,$19C,$171,$189,$160,$177,$150,$1AE,$181,$19B,$170,$1C0,$191,$1AD,$180,0,0

I'm not using the noise channel, and I'm also not using the AY-3 envelope generator (that's why I use odd values to decrease volume).
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...