Jump to content
Sign in to follow this  
jacquesg

How can I speed up an XB program?

Recommended Posts

This is the first time that I have tried to post a new topic. I wrote my comments to Notepad and then the only way I could figure out to send them was to attach the file. I did try copy and paste and it did not seem to work.

 

Jacques

mm110711.txt

Share this post


Link to post
Share on other sites

Here ya go :-

 

===============================================

For a number of years I have been mentoring a young friend about XB programming. I say 'young' because he is about half my age and I am 76.

 

A month or so ago my friend decided to write his first major XB program being a game with lots of action. Although game programming is not at the top of my lists of interests I agreed to help. His game is now nearing completion and although written in XB the speed is decent. This was accomplished by building the game around two loops, a main loop and a jump loop which is called by holding down the FIRE button. The hero in this game captures targets while trying to avoid collision with four enemies that are intent on killing him. Like a cat our hero has more than one life. We have used flags to control when the enemy sprites are active and to deactivate them when the next one is called. All enemy sprites are in motion showing a lot of activity but only one enemy sprite becomes dangerous at a time.

 

As I previously stated the speed of the game is decent but probably can be improved. I have set out below some impressions (which may be incorrect) and some specific questions all related to increasing speed in XB.

 

1 - Pre-Scan

 

Although pre-scan will improve loading time because the program uses a lot of redefined characters, my impression is that it will not do much for improving the running speed of the game.

 

2 - Replacing commonly used numbers with numeric variables

 

My impression is that using @=1, !=2 etc will help improve the speed of the program, especially if used with numbers that appear in the main and jump loops. We have already replaced a calculation of PI/45*5 in the jump loop with a numeric variable.

 

3 - Resequencing the program

 

We would not use RES because this would destroy the block structure that we have attempted to maintain, being lines 10000 and up for sub programs on 1000 boundaries, and 5000 to 9999 for GOSUB routines also on 1000 boundaries. Lines below 5000 contain the main loop.

 

Saving in MERGE format and then reloading the MERGE file before saving should maintain our numbering scheme. Should a resequenced program run faster than one which isn't?

 

4 - Sprites in motion

 

Does having four sprites in continuous motion tend to slow down a program? If so, does it help to set motion to 0,0 when inactive or should they be deleted?

 

Any comments or other tips will be appreciated.

 

Jacques

Share this post


Link to post
Share on other sites

Interesting topic, and I'm sure some more profound answers will popup by the more experienced Extended Basic programmers here on AtariAge.

 

Nonetheless, here's a few thing that I would implement in the game code.

 

1. If you use the PI function or something similar for the jump function, it could make sense to do the precalculations and only store the offset values (x,y) as a series of data statements. Thats what I did for Pitfall, but thats an assembly language game.

2. I seem to remember that storing integer values always takes 8 bytes, so is wasting a lot of memory space. It could be useful to store the values as string variables.

3. I would relocate the non-used sprites off-screen instead of removing them. That way they can easily be relocated without much delay.

4. Sprite collision detection is often an issue in Extended Basic. Instead of using sprite automotion, it could make sense to relocate the sprites manually.

 

I dont know if there is any way to avoid garbage collection to kick-in, causing the game to pause.

 

As said I'm sure there are more better tricks for getting acceptable execution speed.

Share this post


Link to post
Share on other sites

1) prescan only affects the time between typing 'RUN' and the program starting. Arranging the code properly and turning off prescan can make a very large difference in a large program.

 

2) I have not verified this, but the rationale between variables versus digits is that there is an extra step converting the digit into the 8-byte internal number. A quick TI BASIC test suggests no real improvement, which makes sense since a variable also needs to be parsed and looked up. (Using strings for numbers saves memory but costs extra time.) But of course, if you have a calculation, that is done every time it is encountered (since this is not a compiler), so if you can get away with doing it once and saving the result, always do so.

 

3) I've never heard of RES making any difference in speed, and since the program uses a line number table which is always searched, and not any kind of calculation or tree search, it doesn't seem very likely.

 

4) In all but the earliest versions of Extended BASIC, moving sprites cause a slowdown scaled by the highest sprite number moving (regardless as to whether other, lower numbered sprites are moving). Having a higher sprite move and then stopping it does not always get the performance back, so if you have only a few moving sprites, keep them the lowest numbers. (In the earlier versions, the slowdown was more constant and never reversable).

Share this post


Link to post
Share on other sites

Thank you for the Informative replies, We have implemented

some and are in the process of implementing others. I am

most intrigued by Tursi's comments about sprites.

 

At the present time the game uses 6 sprites, two of which

you might call permanent because they are used from start

to finish of the program. The other four are used in

sequence but are created and set in motion early in the

game and are not deleted or hidden when their turn has been

completed.

 

Before I make extensive changes to the program which of the

following approaches is likely to be faster:

 

Retain the present set-up but DELSPRITE each of the four

other sprites after they have been used.

 

or

 

Use only one other sprite to create, when needed, each of

what is presently sprite #3, #4, #5 and #6.The program

would still use two permanent sprites but would set

different parameters for the only additional sprite as it

was needed.

 

My impression is that the second approach would be faster

because only three sprites are in play at any one time. Am

I overlooking something important in coming to this

conclusion?

 

Jacques

Share this post


Link to post
Share on other sites

I would like to add that you can really crank up the speed of XB by using RAM instead of VDP.

 

 

In this demo I used CALL LOAD to put the values in Lower 8K RAM and then after there use RAM instead of VDP.

You can see the that in this way RAM is 3 or 4 times faster then VDP for Strings or for variables.

RAM does not have a built in DELAY to access ever single byte like VDP does.

GROM also has this delay but is slightly faster then VDP as it does not have the problem of having to go from VDP chip to RAM through the CRU IO chip.

GROM goes from GROM to CRU to RAM . VDP goes from VDP RAM to VDP chip to CRU to RAM. That extra step slows it down more.

 

I think this is correct but some other with more tech knoweldge can explain it. The delay is slight but adds up over time.

Then again in Classic99 GROM is much quicker then VDP.

Share this post


Link to post
Share on other sites

Jaques: You have to consider the cost of managing those sprites (ie: turning them on and off). the difference of 4 moving sprites over 1 moving sprite is probably not very large. The best approach, always, is to benchmark. if you run a loop 1000 times, and time it in seconds, you get the time per loop in milliseconds.

 

10 FOR A=1 TO 1000

20 NEXT A

 

Running that takes about 3 seconds, meaning each loop takes 3 milliseconds. You can add instructions inside to see how long THEY take (just subtract the loop time). You could try this loop with varying numbers of sprites running to see what kind of difference it makes.

 

RXB: CRU is not involved in either VDP or GROM accesses -- in fact, the two systems function very similarly. GROM is actually slower than VDP, however, because GROMs are slower devices and add additional wait states to the bus, while the VDP is able to function within the standard 16<->8 bit wait state sequence (in fact it's fast enough to function without that, but we have to wait anyway). Both use 8 bit ports and both require addresses to be written separately of data collection. The difference with VDP is that it's possible to read or write to the chip too quickly, and /it/ loses data. However, on the TI-99/4A, this is actually reasonably difficult to do. Because GROMs hold the bus, they don't have this issue.

Share this post


Link to post
Share on other sites

Tursi

So you are talking GROM only right?

As GRAM devices also have this delay but using a PGRAM or GRAMULATOR and testing speed for writting 8K to VDP or 8K to GRAM the GRAM wins.

When I move 8K of RAM to VDP or 8K of GRAM to RAM the GRAM does it faster. So I assumed the GRAM is faster then VDP.

Why is this? Is it the VDP losing data?

Or could it just be that the GRAM device makes up for the problems with GROM?

 

(It could also be the faster chips in GRAM vs the slower chips in VDP and GROM)

Edited by RXB

Share this post


Link to post
Share on other sites

Ok... this has been bugging me.

 

In the demo, you are using a CALL LOAD to store values beginning at 8192. Unless I'm mistaken, CALL LOAD will take this value and apply it to CPU RAM at the equivalent hex address ">2000". In extended BASIC, the vectors for the various routines, ie, STRASG, NUMREF, KSCAN, VMBW,etc. reside in the lower 8K memory space, followed by utility registers and the code itself.

 

I propose that what you encountered was not an Extended BASIC bug but instead a crash, resulting from overwriting support code vectors, registers, and maybe even the code itself.

Share this post


Link to post
Share on other sites

Ok... this has been bugging me.

 

In the demo, you are using a CALL LOAD to store values beginning at 8192. Unless I'm mistaken, CALL LOAD will take this value and apply it to CPU RAM at the equivalent hex address ">2000". In extended BASIC, the vectors for the various routines, ie, STRASG, NUMREF, KSCAN, VMBW,etc. reside in the lower 8K memory space, followed by utility registers and the code itself.

 

I propose that what you encountered was not an Extended BASIC bug but instead a crash, resulting from overwriting support code vectors, registers, and maybe even the code itself.

 

Sorry that is incorrect. I have the source code of XB in GPL and the problem of why it crashs is that in normal XB the CALL INIT sets the lower 8K up but does a XML MVUP to the ROM of XB ROMS and the following code is the reason for the crash:

 

<0325>			   ********************** CHKIN ******************************
<0326>			   * Check for INIT-FLAG = >AA55
<0327>			   * MOVE ERAM(INITF) to CPU *FAC
<0328> C1EB		  PAGE   EQU  $
<0329> C1EB BF,00,83 CHKIN  DST  FAC,@VAR0		 Destination
   C1EE 4A
<0330> C1EF BF,16,20	    DST  INITF,@VARB	   Source
   C1F2 06
<0331> C1F3 BF,5C,00	    DST  2,@ARG		    2 bytes
   C1F6 02
<0332> C1F7 0F,89		   XML  MVUP			  Move it
<0333> C1F9 D7,4A,AA	    DCEQ >AA55,@FAC	    Syntax error
   C1FC 55
<0334> C1FD 45,33		   BR   ERRSYN

99/4 GPL-ASSEMBLER (Pass 3) correct								   PAGE 0017

 

Now RXB does not allow this code to execute so no syntax error results in RXB.

See the CALL LOAD should not require Assembly support just to POKE a value.

This is why I fixed this in RXB, this is a error that resides in XB and why you get of all things a Syntax Error when in reality there is no Syntax Error.

Think about it, if you are doing a CALL PEEK or a CALL LOAD to Scratch Pad RAM why would you need Assembly support?

Why would you need something you are not using. Now if you need the support it will still be there and you get a Syntax Error if you try to access what is not there.

Thus in RXB you get the correct response per what you are doing. And in Normal XB you get a goofy error.

Share this post


Link to post
Share on other sites

Sorry that is incorrect. I have the source code of XB in GPL and the problem of why it crashs is that in normal XB the CALL INIT sets the lower 8K up but does a XML MVUP to the ROM of XB ROMS and the following code is the reason for the crash:

<0325>			   ********************** CHKIN ******************************
<0326>			   * Check for INIT-FLAG = >AA55

See the CALL LOAD should not require Assembly support just to POKE a value.

This is why I fixed this in RXB, this is a error that resides in XB and why you get of all things a Syntax Error when in reality there is no Syntax Error.

 

Whoa, Nelly!!

 

Your demo cleeeearly shows "90 CALL INIT" in the program that crashes. The post-crash comment infers the CALL LOAD/SPRITE loop executed at least two iterations. Perhaps a short test program is in order:

 

10 CALL INIT
20 A=0
30 PRINT A
40 CALL LOAD(8192+A,123)   !random value
50 A=A+2
60 CALL SPRITE(#1,65,4,1,1)  !line added for posterity
70 GOTO 30

 

Execution will result in "SYNTAX ERROR in line 40" when A=8. The loop made it through four successful iterations. Why?

 

XB writes value "AA55" into memory address 0x2006 during a CALL INIT. This value controls CALL LOAD execution, probably via the same check code you reference in GPL. When A=6, and you write "123" to address 0x2006, XB no longer knows a CALL INIT had been executed. This can be proved by attempting another CALL LOAD following the crash: the result is a SYNTAX ERROR.

 

The crash is not symptomatic of an XB bug; rather, it is a result of writing a value where one should not have been written.

 

Is the XB INITFLAG check a bug? I don't think so. It is simply a programming requirement to be followed, inconvenient though it may be.

  • Like 1

Share this post


Link to post
Share on other sites

Sorry wrong here is the video to show difference: (And the reason for the changes)

 

http://www.youtube.com/watch?v=reKfMJPBMZo

 

 

The reason I did this in RXB is that if you change the Lower8K on purpose with a CALL LOAD then that is what YOU WANTED TO DO so why crash with * SYNTAX ERROR *

 

I take it for granted if you do a CALL LOAD in RXB that this is what you wanted, and if it crashed Assembly section then you already know you did this.

The * SYNTAX ERROR * would not explain what happened or why. It is just a silly error that got by TI and into XB. RXB fixed this bug.

 

THE OTHER REASON IS UNLIKE EVERY OTHER BASIC ON ANY OTHER COMPUTER IT SHOULD ALLOW A CALL LOAD TO ANYWHERE IN MEMORY AS THAT IS JUST LIKE ANY OTHER BASIC.

(Name another BASIC that is so restricted with a POKE or PEEK or LOAD)

Edited by RXB

Share this post


Link to post
Share on other sites

I believe InsaneMultitasker is right. It's not a bug. Certain memory address ranges are "reserved" for different purposes. In this case be it >2000 or >8300 etc.

 

THE OTHER REASON IS UNLIKE EVERY OTHER BASIC ON ANY OTHER COMPUTER IT SHOULD ALLOW A CALL LOAD TO ANYWHERE IN MEMORY AS THAT IS JUST LIKE ANY OTHER BASIC.

 

Richdiculous !!! :P

 

Versions of Basic become unique implementations, and will have differences, bugs and undocumented "features". So will RXB. I've never heard of a "perfect" system. XB is just XB. Live with it.

 

:D

Edited by sometimes99er

Share this post


Link to post
Share on other sites

The fact that you can not use the lower 8K to store things is pretty lame.

Live with it imply's that no changes required so why even ever change anything. That sounds like why do we need cars, horses are fine.

 

Just because a bug is there does not mean I can not fix it.

The fact that RXB CALL LOAD or CALL LINK is flexible and normal XB is not proves that the bug is unfriendly the Video shows this.

 

I have used many other BASICs, Apple, MS, QUICK, and others on systems like Vic20 or Z80 or Radio Shack.

(By the way I wrote a utility that was in the Radio Shack version of BASIC for CALL POKE, it was undocumented but included in the manual)

 

Per page 101 XB Manual: "If the Memory Expansion is not attached, a syntax error is given."

 

Yes no perfect system of XB but I am at least working on the problem.

Edited by RXB

Share this post


Link to post
Share on other sites

The fact that you can not use the lower 8K to store things is pretty lame.

 

I think you can use some of it.

 

There's a "TI Extended Basic Assembly Language Code Programmer's Guide" with this overview on page 5:

 

low1.jpg

 

And this is what I get in XB when I do a CALL INIT:

 

low2.png

 

Just because a bug is there does not mean I can not fix it.

 

Yes, you can change a feature or whatever from what is in XB to what will be in your RXB. You can identify whatever as a bug, and try and fix it. All fine. You may even introduce new bugs. I'll say a bug is a bug, even if it hasn't been identified. But that's just me.

 

Let's say I have a XB program and try and run it in RXB, and an error occurs - only with RXB. Who's to blame ? Really I don't care. You can't change XB, and XB was what I had back in the day, and I'm all fine with having it as it is. No changes for me thanks.

 

The fact that RXB CALL LOAD or CALL LINK is flexible and normal XB is not proves that the bug is unfriendly the Video shows this.

 

There's not much fact about that - not to me. And what is that about friendly and unfriendly bugs ? Who's to say what's what ?

 

I have used many other BASICs, Apple, MS, QUICK, and others on systems like Vic20 or Z80 or Radio Shack.

 

I've used my share of BASICs.

 

(By the way I wrote a utility that was in the Radio Shack version of BASIC for CALL POKE, it was undocumented but included in the manual)

 

I've written many utilities.

 

:)

Share this post


Link to post
Share on other sites

Sorry wrong here is the video to show difference: (And the reason for the changes)

 

The reason I did this in RXB is that if you change the Lower8K on purpose with a CALL LOAD then that is what YOU WANTED TO DO so why crash with * SYNTAX ERROR *

 

I take it for granted if you do a CALL LOAD in RXB that this is what you wanted, and if it crashed Assembly section then you already know you did this.

The * SYNTAX ERROR * would not explain what happened or why. It is just a silly error that got by TI and into XB. RXB fixed this bug.

Both root causes of the SYNTAX error have perfectly valid explanations.

THE OTHER REASON IS UNLIKE EVERY OTHER BASIC ON ANY OTHER COMPUTER IT SHOULD ALLOW A CALL LOAD TO ANYWHERE IN MEMORY AS THAT IS JUST LIKE ANY OTHER BASIC.

(Name another BASIC that is so restricted with a POKE or PEEK or LOAD)

That's silly. Now you are mixing features with bugs.

 

The main point is there are two DIFFERENT causes for the SYNTAX ERRORs you encountered. One is the lack of CALL INIT, the other is program interference with XB itself. I didn't say it crashed the assembly section - please re-read my post.

 

CALL INIT aside, stuffing values into the lower 8K led to misinterpreted consequences, as shown by your two videos. You may use the lower 8K to store any data you wish. But do not blame XB if it cannot operate as expected when you muck about with its internal data needs.

 

This discussion has hijacked Jacques original thread intent - I suggest we move along.

Share this post


Link to post
Share on other sites

Well I am on track as my original post was that you can use CALL LOAD and CALL PEEK which is much faster then using the normal Variables in XB.

The delay in using variables is the Garbage collection routine as it creates variables for temporary use. (XML MVUP in ROM2 can trigger XML COMPCT)

You could possible write a routine to force a Garbage Collection when you want it to but that would require to much Assembly so that just makes it worse.

If you are using Assembly memory with XB POKE and PEEK then you might as well just write in Assembly. That makes these commands unfriendly with XB.

 

The problem is even if XB does not use the lower 8K at all it still crashes the CALL LOAD or CALL LINK or CALL PEEK at >2000 for no good reason.

Proof is it does not matter if you are writing a XB program as simply why would you need it to crash?

Like the XB manual shows a syntax error indicates no 32K on page 101 of XB manual. No other mention is made of this.

Yet you do have one installed and the syntax errors says you do not, so exactly how helpful is that?

I fail to understand how conflicting information should be the standard.

Other then 2 bytes at >2000 has to be >A55A which does not affect anything at all except to crash the CALL routines. You can use all the rest of lower 8K.

A better idea would have been a flag bit instead of wasting 2 bytes for a program flag in the lower 8K. Oddly most of the XB module uses flag bits.

 

I do not know why anyone would assume that RXB has new errors that XB does not have as the GPL Code is almost exactly the same. Besides if you find a error and I will fix it.

I did write RXB with XB GPL Source code so I know how it works. I am not some newby with GPL or XB source code. It is not me mucking around like I am some idiot.

Edited by RXB

Share this post


Link to post
Share on other sites

I am not some newby with GPL or XB source code. It is not me mucking around like I am some idiot.

 

>A55A or was it something else ... it's all very confusing

 

Please don't muck XB, which I happen to love. Okay.

Share this post


Link to post
Share on other sites

Did you know that the correction to XB INIT for CALL LOAD, CALL PEEK and CALL LINK was done by GKXB from Miller Graphics first?

 

They did this way back in 1984 shortly after they introduced the GRAMKRACKER in 1983 so this was the first modified TI XB.

 

The second modified TI XB was Triton XB around the end of 1984.

 

RXB is based on GKXB Source combined with XB source. Yea some people may like XB as buggy as it is.

Share this post


Link to post
Share on other sites

Back on the topic of speeding up XB.

The first version of XB(100) updated all 28 sprites rather they where used or not, the later revised XB(110) corrected this by only updating to the highest sprite number you assigned.

 

use CALL VERSION(A):: PRINT A to find out what version you have. it is a noticeable difference.

 

So always use the lowest sprite numbers you can.

Neat trick you can check the highest sprite number used with this peek -31878 in version XB(100) it always returns 28

 

Random numbers

for a random number 0 to 99

RANDOMIZE :: CALL PEEK(-31880,A)

is twice as fast as

INT(RND*100)

 

For a random number 0 to 255

RANDOMIZE :: CALL PEEK(-31808,A,B)

again about twice as fast and generates 2 different random numbers

 

 

About action game programming,

Everything should be timer based in the main loop.

There are 2 ways to go about this

1) create a variable called tick and increase it on every cycle though the main loop

2) use the VDP interrupt timer which updates every 60/sec, access with peek -31879

 

Problem with #2 is it takes about 7 secs to reset the integer, range is (0-255)

A 7second timer is long in a game, but this method has its uses.

 

A loop example for #1

10 TIMER1SET=50
20 TIMER2SET=100
30 TIMER3SET=150
REM GAME LOOP
40 TICK=TICK+1
50 IF TICK-TIMER1>TIMER1SET THEN PRINT "TIMER 1":: TIMER1=TICK
60 IF TICK-TIMER2>TIMER2SET THEN PRINT "	   TIMER 2":: TIMER2=TICK
70 IF TICK-TIMER3>TIMER3SET THEN PRINT "			  TIMER 3":: TIMER3=TICK
80 GOTO 40

 

You can check somethings every main loop cycle like sprite collisions for accuracy, somethings dont need to be checked every cycle like animation frames so you do these on a timer.

Figure out what you need to do every cycle or not, You dont need to check input from the player every cycle. The main point is to have sprite collision checked as often as possible. The more often you check the faster they can move.

Share this post


Link to post
Share on other sites

Nice work. As i was pointing out in my first post that a CALL LOAD and CALL PEEK are faster then most XB commands.

Found this in MG Smart Programmer : Mike MCue worked out times of commands using loops for timing in seconds.

ABS 6 COS 78

ASC 8 DELSPRITE # 15

ATN 50 DELSPRITE ALL 30

CALL sub 7 DISPLAY AT 59

CHAR 86 DISTANCE # # 33

CHARPAT 62 DISTANCE # XY 35

CHARSET 204 EXP 87

CHR$ 16 GCHAR 21

CLEAR 20 GOSUB 1

COINC # # 34 GOTO 1

COINC # XY 36 HCHAR 21

COINC ALL 15 +6 per RPT #

COLOR # 17 IF THEN ELSE 4

COLOR 18 INT 6

JOYST 27 ! 4

KEY 24 RETURN 1

LEN($) 8 RETURN NEXT 1

LOCATE 22 RETURN # 1

LOAD(1,2) 17 RND 75

LOAD(A,B) 23 RPT$ 30

LOG 117 SCREEN 10

MAGNIFY 11 SEG$ 27

MAX 12 SGN 5

MIN 12 SIN 70

MOTION 25 SOUND 47

PATTERN 17 + 15 per voice

PEEK 19 SPRITE 43

PI 5 SQR 81

POS 22 STR$ 19

POSTION 30 TAN 172

PRINT 100 VAL 21

RANDOMZE 12 VCHAR 25

REM 4 + per RPT #

 

 

Hope this helps. Even using a Text copy or using code also messed it up sorry.

Edited by RXB

Share this post


Link to post
Share on other sites

Everyone's suggestions have been very helpful.

 

Here is the main loop of our program.

 

2010 IF FL AND 2 THEN CALL COINC(#1,#3,10,C) :: IF C THEN CALL METEOR(FL) :: GOTO 1030

2020 CALL COLOR(#6,6) :: IF FL AND 4 THEN CALL COINC(#1,#2,8,C) :: IF C THEN CALL DOT(FL,CT) :: IF CT>LG THEN 2910

2030 IF FL AND 8 THEN CALL ALIEN(FL,HIT) :: IF HIT THEN 1030

2040 IF FL AND 16 THEN CALL COINC(#1,#6,8,C) :: IF C THEN CALL PULSAR(FL) :: GOTO 1030

2050 IF FL AND 32 THEN CALL RAY(FL,HIT) :: IF HIT THEN 1030

2060 ANIM=ABS(ANIM-4) :: CALL JOYST(1,X,Y) :: DC=DC+X*4 :: CALL LOCATE(#1,DR,(DC AND 254)+1) :: CALL POSITION(#1,DR,DC)

2070 CALL COLOR(#6,7) :: CALL KEY(1,K,S) :: IF K=18 THEN GOSUB 6000

2080 IF X<>0 THEN CALL PATTERN(#1,ANIM+X*2+108) :: FACE=SGN(X+4) :: DCD=SGN(X) :: GOTO 2010

2090 CALL PATTERN(#1,FACE*16+96) :: GOTO 2010

 

I am not sure if this program will be taken any further but is presented here in case it might help others tackle similar problems. Perhaps others would have approached this differently but that is part of the fun of programming. Here is an overview of the program:

 

The aim is for the man (sprite #1) to capture a target number of LG DOTs (sprite #2) while avoiding four enemies (sprites # 3 to #6). The game ends after the man sustains 5 hits and the METEOR and PULSAR enemies will become inactive after each inflicts 3 HITS. Flags (FL) are used to ensure that only one enemy is active at any one time. CT is a counter in the DOT sub program to track the number of DOTs captured by the man. This counter also triggers when the game moves from one enemy to the next. For example, if CT=5 then the METEOR enemy becomes inactive and the ALIEN enemy is activated. This continues as different levels of CT are reached. The two CALL COLOR statements cause the PULSAR enemy to change colour as the sprite moves across the screen. The ALIEN and RAY sub routines make use of CALL VCHAR in the same way as recently demonstrated by sometimes99er. The man can only move right and left but can also jump right or left when the FIRE key is pressed. The man is immune from hits from ALIEN or RAY while jumping otherwise the poor man does not stand a chance of out running these enemies. Line 1030 tracks the number of hits sustained by the man. I feel that the speed is acceptable considering that it is an XB program. I did experiment with making all the enemies active at the same time but speed is noticeably reduced.

 

My friend had the concept for this game and I was his helper as were many of you because this was the first major XB program that he was attempting to write. I am not much into writing game programs but I have also learned quite a bit from the exercise.

 

 

Jacques

Share this post


Link to post
Share on other sites

Nice work. As i was pointing out in my first post that a CALL LOAD and CALL PEEK are faster then most XB commands.

Found this in MG Smart Programmer : Mike MCue worked out times of commands using loops for timing in seconds.

ABS 6 COS 78

ASC 8 DELSPRITE # 15

ATN 50 DELSPRITE ALL 30

CALL sub 7 DISPLAY AT 59

CHAR 86 DISTANCE # # 33

CHARPAT 62 DISTANCE # XY 35

CHARSET 204 EXP 87

CHR$ 16 GCHAR 21

CLEAR 20 GOSUB 1

COINC # # 34 GOTO 1

COINC # XY 36 HCHAR 21

COINC ALL 15 +6 per RPT #

COLOR # 17 IF THEN ELSE 4

COLOR 18 INT 6

JOYST 27 ! 4

KEY 24 RETURN 1

LEN($) 8 RETURN NEXT 1

LOCATE 22 RETURN # 1

LOAD(1,2) 17 RND 75

LOAD(A,B) 23 RPT$ 30

LOG 117 SCREEN 10

MAGNIFY 11 SEG$ 27

MAX 12 SGN 5

MIN 12 SIN 70

MOTION 25 SOUND 47

PATTERN 17 + 15 per voice

PEEK 19 SPRITE 43

PI 5 SQR 81

POS 22 STR$ 19

POSTION 30 TAN 172

PRINT 100 VAL 21

RANDOMZE 12 VCHAR 25

REM 4 + per RPT #

 

 

Hope this helps. Even using a Text copy or using code also messed it up sorry.

 

The time measurements must be in fractions of seconds. Does anyone know what they are?

 

Also, I am having trouble understanding 'per RPT #' used in three spots. Can someone clarify what is intended?

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
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...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...