Jump to content

Bones-69

Members
  • Posts

    253
  • Joined

  • Last visited

Posts posted by Bones-69

  1. Tusi / unhuman, thanks for the time invested. I have started a few projects (games) in the past and always either lost interest or got side tracked with life. I am keen to get this one done and have already invested a lot into it, so again – Thanks for the input.

    5110 IF M<>1 THEN 5120 :: MN=1 :: MX=5 :: D=13 :: CX=46 :: GOTO 5200
    

    Tursi, yes the alternative ELSE format is to remain compatible with the XB compiler which only likes THEN statements which GOTO line numbers. I found it a bit awkward at the beginning but now I am actually starting to prefer this way of ‘elsing’. J

     

     

    I agree the interaction between M & T is strange, if not a somewhat cumbersome. My plan was to have additional enemies which would enter the game from the right side of the screen. The processing of these would simply continue on within the same FOR/NEXT loop (not yet written). As I wanted to process each complete caterpillar a chunk at a time this seemed like a good way to achieve both. As things progress further I will re-consider if anything is gained by changing this. I can think of several ways to improve this. Not sure if speed will be impacted, but I agree it could be a lot prettier.

    5560 …….. C=EAV(MN)
    

    .That is a leftover from some previous fooling around – good catch!

    GT=(EY(T)-1)*32+XT-192
    

    Yes, the -192 is simply to offset the first 6 rows of the screen which are not part of the grid, and save the memory that G(1-192) would otherwise reserve and never use.

     

     

    The G & E pairing is supposed to work like this;

    -Players bullet encounters a G() value that indicates that something has been hit. I could have used GCHAR to identify a screen character, but would then have to search all enemies and check coordinates to see which enemy has actually been hit. With this approach I can identify instantly which E(enemy) needs to be destroyed/processed.

    -Now I know why E having a value <>0 is important, but I can’t for the life of me remember why I decided that it should otherwise hold the grid position. It now seems unnecessary. Having taken some time out I have lost the thought process….. Agree that I can give the added effort to define this value the flick. Woohoo – That’s a saving! J

     

    In regards to some of your other points Tursi, when things started to slow down I removed some code for testing which I always intended to add back in. I had come up with some ideas which might explain some of the strange ways of defining the head direction and the way the variables are treated and displayed.

     

    Currently my character map looks like the photo in the attachment.

     

    I have defined a series of arrays represented by AS(#, counter 1-12). When a caterpillar/enemy is defined it is given a # value. Basically the counter pulls out values such as “0,0,0,0,0,0,0,0,0,0,0,0,” or “8,8,8,8,8,8,8,8,8,8,8,8” or “0,8,16,0,8,16,0,8,16,0,8,16” as the counter moves from 1 to 12. The value retrieved is the amount that the displayed ASCII code will be offset

    CALL HCHAR(EY(T),EX(T),EC(T)+ECO(T)+AS(A,B)).
    

    This approach allows me to individually animate each different “Enemy” and each different segment. Ie, each enemy can have its own colour, can flash all colours, can flash some colours, can be a head facing in any direction, or a body part that might or might not change colour… and yet I only ever have to deal with two characters. 178 is always a head, and 182 is always a body - regardless what it is displayed on the screen.

     

    The same counter was to be used for all non-sprite graphics. For example;. When an enemy was destroyed, EC(##) would change to a value of 160, and then using the same counter I could increase the displayed char value each cycle by increasing the counter. This would have the effect of changing the displayed value from 160, 168 , 176…. Etc moving it through character definitions and character sets.

     

    My plan was to use these counters for displaying/animating everything and my character set was designed to use the values returned with as the counter incremented. By determining the value of AS(#,..) when each enemy was first created, I could determine exactly how every character behaved. I felt it worked extremely well and the time it took to control the counter would be offset when other special things had to happen. When I removed the counters the caterpillar march speed increased by around 10%. I was a little disappointed to find it took this much resources to maintain. I still want to go with this concept but I think I am forced to rethink just how liberally I use this function.

     

    Line 5730 is a leftover. It currently should never be reached and will be deleted.

     

    The whole 5850 / 5890 thing is to fall into line with my Character Set. <16 is always going to be a boundary character. If over >15 it will be something else that requires more processing. It must be confusing trying to make sense of stuff like this when I submitted unfinished code.

     

    Thanks Tursi. Great stuff and good suggestions which I will take fully onboard!

     

     

    Unhuman,

     

    Appreciate the input. I agree that some of the areas you highlighted could be improved. As per earlier comments, I was very pleased with the speed until it came to redrawing/calculating the caterpillar position- This seemed to be the source of the significant slowdown as this is when things took a huge speed hit. However, by milking even minute amounts it will certainly help. I especially like avoiding the math as you put it and didn’t realise there was potential for saving in this regard. This being the case there is possibly several other areas that I could do similar. I need to test it with the compiler and see just how the performance is affected. Thank you!

     

    Again – Thanks guys! JTusi / unhuman, thanks for the time invested.

    post-26079-0-89773300-1514864611.jpg

    • Like 3
  2. Thanks for the feedback guys and apologies for the tardiness of this reply. Crazy time of year and all..... Below is my code for the caterpillar movement which seems to behind much of the slowdown. Everything was working rosy until the lines between 5800 - 6970 were added (these are the lines which update the caterpillar movement).

     

    Some key explanations;

     

    -Line 5500 begins loop (variable T) for processing caterpillar movement. Plan was for maximum of three caterpillars in later levels. M=1 is caterpillar 1 (5 segments). M=7 is caterpillar 2 (5 segments). M=13 is caterpillar 3 (10 segments). Values of M higher than 24 will be later used for other processing updates. Each "T loop" processes Caterpillar 1, Caterpillar 2, or Caterpillar 3. In the last Youtube clip only Caterpillar 1 is active.

     

    -Lines 5570 - 5580 control caterpillar emerging from an egg once egg has hatched. No collision checking is ever required here so it is simply allowed to emerge onto the screen a single character at a time. All working fine here.

     

    -Line 5800 identifies that caterpillar has fully emerged from egg (value is not 999 or 998), and passes control to caterpillar movement processing. This is where I feel things slow down too much....

     

    -Lines 5810 - 5840 calculates next potential screen position of caterpillar segment.

     

    -Lines 5850-5920 checks if game boundary reached, checks for in-game character collisions, checks if move is legal and updates all variables if move is to be allowed (in-game collision checking sent to 5930 is not yet written).

     

    -Line 6900 ends T loop. By this stage the next screen position of all caterpillar segments is known and all variables have been written

     

    -Line 6910 to 6950 draws the caterpillar to the new screen position as determined by lines 5810 - 6900.

     

    -Line 6960 updates EXO(##) & EYO(##) to reflect the current value of EX(##) & EY(##).

     

    -Line 8000 increments value of M which will then process next caterpillar / or enemy if value over 24 (yet to be written).

     

     

    I guess some variable explanations are required;

     

    E(##) represents if enemy is active. If not active (such as might have already been destroyed), the value is zero. If active, value is equal to screen grid position calculated by (Y-1)*32+X-192 and is used for collision checking.

     

    EX(##) is enemy X HCHAR coordinate.

     

    EXO(##) is previous enemy X coordinate before any screen position processing. Once enemy new screen position is updated, this historic position is blanked with the background character, EXO(##) is then updated to EX(##) value.

     

    EY(##) is enemy Y HCHAR coordinate. .

     

    EYO(##) is previous enemy Y coordinate before any screen position processing. Once enemy new screen position is updated, this historic position is blanked with the background character. EYO(##) is then updated to EY(##) value.

     

    EC(##) is the ASCII code of enemy.

     

    ECO(##) is added to displayed ASCII value in HCHAR statement. It offsets the value of the displayed CHAR to set the direction the caterpillar is looking ie-left, right, down (if the char in question is a caterpillar head).

     

    EDX(##) represents the direction of travel for each char. Value of 2 = travelling left. Value of 1=travelling right. Potentially any caterpillar segment can be separated from rest of body and travel its own course.

     

    G(###) holds the integer value of E(##) or the ascii code if part of the game border (ie- The T and/or M value in the program). This is so it can be quickly determined which enemy (if any) is located in any given screen position.

     

    * Note that by "Enemy", I refer to each component (segment) of caterpillar.

     

    * It appears as though some double processing is going on when looking at lines 6910 - 6970. I found it more practical to first calculate all the moves of the caterpillar segments, and then write them to the screen in a second pass. Previous attempts to update each caterpillar to the screen as the location was first defined caused issues with the caterpillar following the leading character. I feel time absorbed by the second loop is negligible as no double processing is happening here.

     

    * I needed to allow control of individual caterpillar segments in the event that any part of the caterpillar is shot and separated from the rest of the body. At the same time if intact, I need all parts to "follow the leader" or be snakelike. Hence the requirements for each caterpillar component to have its own range of complete variable definitions.

     

    * There are a few leftovers such as line 5930 which were used for error checking along the way, 6920 & 6930 which are used for some animation which I have temporarily removed in an attempt to add speed, plus some other odd looking things that I have placed in limbo but left in the original program listing. Just ignore these, I haven't yet committed to completely removing.

     

    Not asking for anyone to rewrite anything, but it was requested that I offer the code for examination so here it is. :)

    5000 FOR M=1 TO 24
    5010 !
    5110 IF M<>1 THEN 5120 :: MN=1 :: MX=5 :: D=13 :: CX=46 :: GOTO 5200 !PROCESS CAT1
    5120 IF M<>7 THEN 5130 :: MN=7 :: MX=11 :: D=13 :: CX=46 :: GOTO 5250 !PROCESS CAT2
    5130 IF M<>13 THEN 5140 :: MN=13 :: MX=22 :: D=8 :: CX=41 :: GOTO 5300 !PROCESS CAT3
    5140 GOTO 7000
    5200 IF E(1)+E(2)+(3)+E(4)+E(5)<>0 THEN 5500 ! PROCESS CAT1
    5210 M=7 :: GOTO 5120 ! CAT1 NOT ACTIVE
    5250 IF E(7)+E(+E(9)+E(10)+E(11)<>0 THEN 5500 ! PROCESS CAT2
    5260 M=13 :: GOTO 5130 ! CAT2 NOT ACTIVE
    5300 IF E(13)+E(14)+E(15)+E(16)+E(17)+E(18)+E(19)+E(20)+E(21)+E(22)<>0 THEN 5500 ! PROCESS CAT3
    5310 M=23 :: GOTO 8000 ! CAT 3 NOT ACTIVE
    5500 FOR T=MN TO MX
    5510 IF E(MN)=998 THEN 5560
    5520 IF E(MN)=999 THEN 5600
    5550 GOTO 5800 ! ALREADY EMERGED
    5559 ! INITIATE EMERGE
    5560 A=MX-MN+1 :: C=EAV(MN)
    5570 FOR I=1 TO A :: B=T+I-1 :: EY(B)=8 :: EX(B)=D+I :: C=(EY(B)-1)*32+EX(B)-192 :: G(C)=B :: E(B)=C :: EYO(B)=8 :: EXO(B)=EX(B)
    5575 R=EAS(B):: CAT$=CAT$&CHR$(182+AS(R,1)):: NEXT I :: S=EAS(MN):: CAT$=CHR$(178+ECO(MN)+(AS(S,1)))&SEG$(CAT$,1,A-1):: E(MN)=999 :: CAT=0
    5580 M=MX+1 :: GOTO 8000
    5599 ! EMERGE 1 PER CYLE
    5600 A=MX-MN+1 :: CALL SOUND(1,1000,1+I)
    5700 CAT=CAT+1 :: CALL LINK("DISPLY",8,19-CAT,SEG$(CAT$,1,CAT))
    5710 M=MX+1 :: IF CAT<>MX-MN THEN 8000 :: CALL LINK("DISPLY",8,D+1,CAT$):: E(MN)=CX :: CAT$="" :: GOTO 8000
    5720 LN=5720 :: GOTO 5720 !ERROR
    5730 M=MX+1
    5799 ! PROCESS CATERPILLAR MOVE
    5800 ECO(T)=0 :: IF E(T)=0 THEN 6900
    5810 IF EDX(T)=2 THEN 5830 :: XT=EX(T)-1 :: IF EC(T)<>178 THEN 5840 :: ECO(T)=2 :: GOTO 5840
    5830 XT=EX(T)+1 :: IF EC(T)<>178 THEN 5840 :: ECO(T)=1
    5840 GT=(EY(T)-1)*32+XT-192
    5850 IF G(GT)<16 THEN 5890 :: A=E(T):: G(A)=37 :: EX(T)=XT :: G(GT)=EC(T):: E(T)=GT :: GOTO 6900
    5890 IF G(GT)>15 THEN 5930 :: YT=EY(T)+1 :: IF EC(T)<>178 THEN 5900 :: ECO(T)=3
    5900 GT=(YT-1)*32+EX(T)-192 :: A=E(T):: G(A)=37 :: EY(T)=YT :: G(GT)=EC(T):: E(T)=GT
    5910 IF EDX(T)=1 THEN 5920 :: EDX(T)=1 :: GOTO 6900
    5920 EDX(T)=2 :: GOTO 6900
    5930 GOTO 5930 
    6900 NEXT T
    6910 FOR T=MN TO MX :: IF EC(T)=0 THEN 6970
    6920 !EAV(T)=EAV(T)+1 :: IF EAV(T)<>13 THEN 6930 :: EAV(T)=1
    6930 ! A=EAS(T):: B=EAV(T)
    6940 IF EC(T+1)=0 THEN 6950 :: CALL HCHAR(EY(T),EX(T),EC(T)+ECO(T)):: GOTO 6960 ! REMOVED ANIMATION COUNTER (AS#,#)
    6950 CALL HCHAR(EYO(T),EXO(T),37):: CALL HCHAR(EY(T),EX(T),EC(T)+ECO(T)) ! REMOVED ANIMATION COUNTER (AS#,#)
    6960 EYO(T)=EY(T):: EXO(T)=EX(T)
    6970 NEXT T
    6990 M=MX+1 :: GOTO 8000
    7000 GOSUB 26000 ! SIDE GUNNER MOVEMENT
    8000 NEXT M
    8010 !GOSUB 25000
    10000 GOTO 5000
    
    • Like 2
  3. Feeling a little disheartened at the moment. Overall my program is coming along well and it is good to see some of my ideas take shape, but already I feel that even when compiled the old TI doesn't have the speed to deliver. I think perhaps I asked too much or tried to include too many "bells and whistles'. Not sure where to go from here. The following clip shows how slow things are starting to get and there is still significant processing to be added such as player movements, shooting, score updates etc etc. I had hoped to run up to 3 caterpillars on the screen at once which looks now unlikely. Really not sure what to sacrifice in order to keep the speed at a playable level.... Or if I should abandon the concept and put my time into developing some other idea.

     

    • Like 1
  4. Little progress update....

     

    Have written the disc file which stores all the character hex data and a bunch of variables & strings in an attempt to free up as much program space as possible. I think at last count it was around 470 records (without the instruction screens which I will worry about at the end). Looks like I have about 5K of programming space left while running XB256 but I reckon I could recover another 1-2K by flicking all my REM statements which i will do as things progress.

     

    Currently struggling with writing the routine for the "marching slugs". There are quite a lot of variables in play and I am losing track of what is going on. I feel I have probably bitten off more than I can comfortably chew. I'll get there but it is slow going with lots of errors at the moment....

     

    I tend to program in sections and later go back and fill in the pretty detail. Here is a progress video of things to date. I haven't yet attempted to sort the timing but have written in "speed counters" that I will fine tune once things have progressed more. I am hopeful that once lots is going on at once I won't have to slow things down anyway..

     

    • Like 7
  5. Hi Harry - Not sure if I have found a bug or missing something plain obvious. The following gives the correct result when run in XB or XB256;

    100 CALL CLEAR
    110 ACCEPT AT(10,1)VALIDATE("123")SIZE(1):A
    120 PRINT A
    
    However, when compiled, A always returns a value of zero.
    I did some experimenting and once I removed the VALIDATE option I started to get the correct outcome when compiled. I was using the result in the following manner and wondering why I was finding no data! :)
    530 A$="DSK"&STR$(A)&".GSDAT" :: PRINT "LOADING ";A$;
    540 OPEN #1:A$,DISPLAY ,VARIABLE
    550 INPUT #1:A$
    

    Is this a little glitch or have I misunderstood the way to use ACCEPT AT with the compiler?

     

    Thank you!

  6. I haven't played with this feature yet (but will) - thanks.

     

    At the moment I am creating a disk file that contains all the string data for character definition, instruction screens, and some other definitions required in-game. Defining a 256 character set adds challenges that I haven't had to deal with before being an otherwise simple XB guy..... :)

    post-26079-0-55762700-1511298386_thumb.jpg

  7.  

    I am desperately waiting for a port of Gridrunner/Matrix to the TI ... for more than 30 years. (That is, for a standard system, no F18A.)

     

    https://www.ninerpedia.org/wiki/Challenges

    Well.... The only sprites used during game play are for the laser which goes the full height of the game screen (requires 7 vertical sprites), the 5 gunners which run along the outside of the grid, two for the players ship, plus a total of 4 bullets (the bullets won't be in play at same time). I really don't feel any 4 of these sprites will line up in a row very often to cause any issues.... All other enemies are non-sprites. Only the slug dudes above the grid should be a cause for noticeable spite flickering, and only when they are pooping out an egg before it enters the grid. By removing the mountains I could reduce two sprites and do away with the flickering completely.

     

    So while not completely faithful to any original, I think it should be very playable on a standard console without F18.

     

    I had never stumbled across that wiki Challenge site. I reckon if I had I would have tried for a more authentic version. Believe it or not I wanted to write something and just couldn't come up with anything original. I started watching Youtube videos and after finding Gridrunner I got a little inspired. I don't *think* I had ever seen Gridrunner before, although I did once own a C64 so who knows what lies in the subconscious....

    • Like 3
  8. Have been fooling around with a game concept for a few weeks now and thought I would share. Named Gridslugger, it loosely plagiarises a little bit of Centipede, a lot of C64 Gridrunner, plus has a few original ideas thrown in....

     

    I have got as far as sorting out the character map (used 253 of them!), worked out how the enemies will interact, have all the game rules worked out, and designed most of the screens. I am still putting the finishing touches on the variable list and starting to get a little nervous about memory but think I should be OK.

     

    The plan is to start putting it all together over the coming weeks. While not specifically written with the F18A in mind, some of the "prettier" aspects of the graphics will probably suffer from sprite flicker without it - but nothing that should effect game play. I personally don't use real hardware so from my perspective its more about the fun and challenge of writing it rather than making it console perfect. Yes, I am an emulation fan.

     

    I have for years wanted to write a fast paced game but could never wrap my brain around Assembly. In this instance the finished product will be compiled so I am hoping the game moves along at a good speed.

     

     

    post-26079-0-21149400-1510574647_thumb.jpg

    post-26079-0-72867400-1510574669_thumb.jpg

    • Like 24
  9. It seems to be working OK, so here's a version with two new features:

     

    - Export to XB 256

    - Analyze Character Usage tool

     

    The latter enables you to see how often you have used each character on your maps.

     

    Is anyone else having issues installing this version? Am running Windows 10 and it crashes half way through the installation reporting the rather unhelpful error message - "Magellan has stopped working". I am very keen to get the XB256 support....

  10. I have always used a similar approach when trying to milk as much speed as possible. It's quite amazing the differences when you start testing. I am now curious how different coding will translate once compiled with the XB compiler....

  11. Thanks for confirming Harry. I have also been thinking about the problem.

     

    Maybe a possible work around might be instead of having 1 file with 100 records, perhaps having 10 files each with 10 records might be an option. In this instance you could pre-drill down to the individual disc file and then only have to process a modest number of sequential records before arriving at the highest numbered record. Actually, the more I think about this, the more I think this might be a workable option. No doubt it would never execute as fast being able to directly read the required record straight up, but I don't see why it wouldn't work.

     

    Although without being able to Update... Might have to go back to the drawing board! :)

  12. Consider that each Disc Record might contain a string up to 255 character long containing the text location, location description & any other information/variables required. If there are 100 locations in the game, that’s 25K of my stack instantly gone if I attempt to load any of it into RAM. If I can fetch this data as required, process it, then write any changes to the same Disc Record, I go from using 25K stack to only using what I require at that specific time for that specific location.

     

    That’s the whole thought process anyway.

     

    In regards to Forth…. I think this old dog is too old to learn new tricks. J

  13. I think there is some confusion. The problem is having to access the disc records Sequentially to arrive at the required record (the record is already known). So assume you need to read Record 125, usually you could;

     

    INPUT #1, REC 125:A$

    -Process A$ as required

     

     

    But without Random file access you would have to;

     

    FOR I=1 TO 125 :: INPUT #1:A$ :: NEXT I

    -Process A$ as required

  14. To be more specific, as the player moved into a new environment (ie - a map location), I want to be able to temporarily load the details for that location. So for the sake of clarity, lets assume the map grid was 10 x 10. If the player was in location 10, and they went South, the location might become location 20. It would be beneficial to be able to instantly read record 20 without having to first read the next 10 records to then arrive at the required file (perhaps the player moves from location 10 to 50, in which case 40 files would first need to be read/dismissed to arrive at the correct record).

     

    By Random I refer to being able to retrieve the disc records Randomly (eg. REC 10, REC 50, REC 5 etc), rather than Sequential. So I am not actually looking to randomize any data, just not be forced to retrieve the data records Sequentially. The amount of information I am considering would quickly erode the TI stack so I need to be able to load the info that I want, process it, and forget it. I can see myself using the 255 bytes per record so a fair amount of data is being considered. ie- Too much for Stack or Data statements.

     

    As I understand it, to be able to do Random files requires that the Open statement specify FIXED file type & I don't *think* the compiler likes this. I think it wants file types to only be Variable. Just looking for confirmation my understanding here is correct. ie- Variable file types can not be read/written randomly.

  15. After creating the 10 records (lines 110 to 170), I then tested it in XB by running lines 180-210. I was able to confirm all records were correct as they were saved, and that I could recall the records in any order I requested.

    After I ran the compiled version the records were not being fetched correctly. The compiled version seemed to only pick-up the records sequentially (ignored the REC function) and it also skipped every 2nd record.
    No doubt this is the result of me not correctly understanding the TI file system, or not understanding the correct application for using files with the XB compiler. I have read the compiler documentation and if I understand correctly, a VARIABLE file structure can only be read sequentially. Is this where it has all gone wrong for me?
    Basically, I am playing with the idea of an adventure game and aiming to recall text records randomly (if this is possible).
    Thanks!
  16. Wondering if somebody might steer me in the right direction here... For testing purposes I wrote the following program to create a small Disc file (DSK3.TESTF) which created 10 sequential records.

     

     

    100 ! GOTO 180
    110 OPEN #1:"DSK3.TESTF",RELATIVE,DISPLAY ,OUTPUT
    120 PRINT #1,REC 0:"FIRST FILE"
    130 FOR I=1 TO 10 :: PRINT I;" ";
    140 INPUT A$ :: PRINT #1,REC I:A$
    150 NEXT I
    160 CLOSE #1
    170 END
    180 OPEN #1:"DSK3.TESTF",RELATIVE,DISPLAY ,INPUT
    190 INPUT A
    200 INPUT #1,REC A:A$ :: PRINT A$
    210 GOTO 190
    
    • Like 1
×
×
  • Create New...