jacquesg Posted November 7, 2011 Share Posted November 7, 2011 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 Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted November 7, 2011 Share Posted November 7, 2011 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 Quote Link to comment Share on other sites More sharing options...
+retroclouds Posted November 7, 2011 Share Posted November 7, 2011 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. Quote Link to comment Share on other sites More sharing options...
Tursi Posted November 8, 2011 Share Posted November 8, 2011 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). Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted November 8, 2011 Share Posted November 8, 2011 I guess when using multiple-statement lines, the program uses the line number table less, which might speed things up a bit. Quote Link to comment Share on other sites More sharing options...
jacquesg Posted November 9, 2011 Author Share Posted November 9, 2011 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 Quote Link to comment Share on other sites More sharing options...
RXB Posted November 9, 2011 Share Posted November 9, 2011 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. Quote Link to comment Share on other sites More sharing options...
Tursi Posted November 10, 2011 Share Posted November 10, 2011 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. Quote Link to comment Share on other sites More sharing options...
RXB Posted November 10, 2011 Share Posted November 10, 2011 (edited) 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 November 10, 2011 by RXB Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted November 10, 2011 Share Posted November 10, 2011 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. Quote Link to comment Share on other sites More sharing options...
RXB Posted November 10, 2011 Share Posted November 10, 2011 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. Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted November 11, 2011 Share Posted November 11, 2011 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. 1 Quote Link to comment Share on other sites More sharing options...
RXB Posted November 11, 2011 Share Posted November 11, 2011 (edited) 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 November 11, 2011 by RXB Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted November 11, 2011 Share Posted November 11, 2011 (edited) 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 !!! 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. Edited November 11, 2011 by sometimes99er Quote Link to comment Share on other sites More sharing options...
RXB Posted November 11, 2011 Share Posted November 11, 2011 (edited) 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 November 11, 2011 by RXB Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted November 11, 2011 Share Posted November 11, 2011 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: And this is what I get in XB when I do a CALL INIT: 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. Quote Link to comment Share on other sites More sharing options...
+InsaneMultitasker Posted November 11, 2011 Share Posted November 11, 2011 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. Quote Link to comment Share on other sites More sharing options...
RXB Posted November 11, 2011 Share Posted November 11, 2011 (edited) 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 November 11, 2011 by RXB Quote Link to comment Share on other sites More sharing options...
sometimes99er Posted November 11, 2011 Share Posted November 11, 2011 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. Quote Link to comment Share on other sites More sharing options...
RXB Posted November 15, 2011 Share Posted November 15, 2011 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. Quote Link to comment Share on other sites More sharing options...
jchase1970 Posted November 15, 2011 Share Posted November 15, 2011 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. Quote Link to comment Share on other sites More sharing options...
RXB Posted November 15, 2011 Share Posted November 15, 2011 (edited) 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 November 15, 2011 by RXB Quote Link to comment Share on other sites More sharing options...
jacquesg Posted November 15, 2011 Author Share Posted November 15, 2011 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 Quote Link to comment Share on other sites More sharing options...
jacquesg Posted November 16, 2011 Author Share Posted November 16, 2011 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? Quote Link to comment Share on other sites More sharing options...
RXB Posted November 16, 2011 Share Posted November 16, 2011 The White FTP http://www.atariage.com/forums/topic/153704-ti-994a-development-resources/ You can find the entire listing in the Miller Graphics SMART PROGRAMMER Magazine. Just ran into it the other day when I saw your post here. He does not say exactly how he did the calculations. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.