Cool BASIC tricks and tips!

16781012

Comments

  • edited August 2011
    Crisis wrote: »
    This aint a TRICK, is it? This is NEW SOFTWARE ...

    Hi Crisis,

    I thought about this long and hard before I posted in the tricks section. There were a couple of reasons for this:

    1) If someone looks at the source it contains many clever (not taking the credit here as I got them from others :-)) tricks in one place. I would have found this very useful a few months back. For example:

    * Using VAL "number" to reduce memory use
    * Using single variables rather than an array - faster
    * How to print on line 22/23
    * POKEing ATTR_P to set PAPER, INK rather than PAPER, INK - faster
    * Breaking out conditions on IF statements to improve performance
    * Using LAST_K rather than INKEY$ - faster
    * Coding conditions on LET statements
    * Using AT/TAB to create blocks of colour
    * Placing frequently used routines nearer the top of the program

    2) A replacement for INPUT feels like a "trick" to me as it is a subroutine and not a program.

    However, I understand your point and in no way was offence or distress intended.

    If a Moderator wishes to move the posting then I have no problem with that.

    Many thanks

    Paddy
  • edited August 2011
    Hi Crisis,

    (..)
    However, I understand your point and in no way was offence or distress intended.

    If a Moderator wishes to move the posting then I have no problem with that.

    Many thanks

    Paddy

    Hi Paddy,
    I am not offended by your efforts and i hope you dont feel alike reversed. maybe i feel a little distressed becouse in this tread it self there are already quiet a few remarks with 'keep this one dedicated'. You explain you even extra thought about it. Thats a good thing. I dont intend to be the policeman around, its just that threads very easily grow out off proportion in al kind off wild discssions and directions. I was part of it myself :-) AND have been replaced severall times ...If there were more moderators, then some off the 250+ 'tips&tricks' posts would indeed be moved to other threads. leaving maybe 200+ serious 'sticky' posts.
    But we should not try to stop evolution do we??
    btw If you take out some REMS its only a short routine indeed.
    my old website http://home.hccnet.nl/c.born/ has changed to http://www.cborn.nl/zxfiles/ so just click it and select a file
  • edited August 2011
    * Using VAL "number" to reduce memory use

    Lately many people have been recommending this trick to save memory, but I can't remember anybody ever mentioning the impact in performance.

    Using VAL "number" means the Spectrum has to convert a sequence of digits into its numeric representation in runtime, instead of calculating it in advance and already storing the converted value right after the digits. This is the reason this trick saves memory, but also the reason it's much slower.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited August 2011
    Lately many people have been recommending this trick to save memory, but I can't remember anybody ever mentioning the impact in performance.

    Using VAL "number" means the Spectrum has to convert a sequence of digits into its numeric representation in runtime, instead of calculating it in advance and already storing the converted value right after the digits. This is the reason this trick saves memory, but also the reason it's much slower.

    Yes, there is a performance hit. You have to decide if it is worth it. It can be, if it makes your program fit a 16K Spectrum when it otherwise wouldn't.

    There is a quicker and even more memory-efficient way for numbers between 32 and 255 - use CODE "char" where char is the character which has the code equal to the number wanted. Of course, that is, I'll say "difficult", in 128/+3 BASIC but no real problem in 48.

    NOT PI for 0, SGN PI for 1, INT PI for 3 are also often used.
  • edited August 2011
    emleymoor wrote: »
    NOT PI for 0, SGN PI for 1, INT PI for 3 are also often used.

    Actually BIN for 0 is shorter :)

    And there's also COS PIN for -1.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited August 2011
    Lately many people have been recommending this trick to save memory, but I can't remember anybody ever mentioning the impact in performance.
    (..)

    It has been mentioned severall times defenitely. i think even in this thread it self. thats one off the cloudy things , you know.
    These discussions it self might be beter placed beside the tips&tricks, like a sticky "discusion about tips&tricks".
    Perhaps one sticky trhead is just not enough and maybe we need a block with a sticky with only the technical trick and then loads off discusion threads were you just refer to the sticky-tech.
    meaning beside 'SinclairBasic' a real BLOCK 'basic tips&tricks'
    That would lighten things up (were is that sunny icon)
    my old website http://home.hccnet.nl/c.born/ has changed to http://www.cborn.nl/zxfiles/ so just click it and select a file
  • edited August 2011
    Actually BIN for 0 is shorter :)

    This one doesn't actually work as the ROM still inserts chr$ 14 and five zeros after the 'BIN' token.

    Another oddity is that BIN 00000000000000000000000000000000000000000000000000000000000001000000010101010 works :-)

    Although it requires 16 bit numbers it only starts counting after the first '1'.
    (or uses the initial zero if no digits follow as you stated).
  • edited August 2011
    Geoff wrote: »
    This one doesn't actually work as the ROM still inserts chr$ 14 and five zeros after the 'BIN' token.

    Ops, you are right!

    Sorry, my mistake. It never occurred to me that the ROM could be interpreting it this way :(
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited August 2011
    Did some comparisons using BAsin's Profiler of the following code:
    100 CLS 
    110 LET a=0
    120 LET a=a+32
    130 PRINT a
    140 LET a=0
    150 LET a=a+VAL "32"
    160 PRINT a
    170 LET a=0
    180 LET a=a+CODE " "
    190 PRINT a
    
    Line 120 takes 10396 Ts to execute.
    Line 150 takes 38867 Ts to execute.
    Line 180 takes 13141 Ts to execute.

    So if you want maximum speed then use a literal number. If memory conservation is your aim the try to use CODE and only VAL as the last resort.

    Hope this helps.

    Paddy
  • edited September 2011
    Are there any tricks to speeding up a 'move a character around screen' routine? Right now I'm reading the existing character and disallowing movement with anything that isn't a " " space character. It's pretty flickery and slow.

    This is my current method for the 'W' up button, with 500 being the collision detection code and re-drawing code.
    IF INKEY$ = "w" THEN PRINT AT y,x; " ": LET y = y-1: GO SUB 500
    
  • edited September 2011
    Dock wrote: »
    Are there any tricks to speeding up a 'move a character around screen' routine? Right now I'm reading the existing character and disallowing movement with anything that isn't a " " space character. It's pretty flickery and slow.

    This is my current method for the 'W' up button, with 500 being the collision detection code and re-drawing code.
    IF INKEY$ = "w" THEN PRINT AT y,x; " ": LET y = y-1: GO SUB 500
    

    You are erasing the character, then performing lots of tasks before printing the character again. This is the reason for flickering.

    Change your program to work like this:
    IF INKEY$="w" THEN LET x2=x: LET y2=y-1: GO SUB 500: PRINT AT y,x; " "; AT y2,x2;"o"
    

    If you need examples, take a look at the source code of my BASIC games such as SOKO-BAN, Pongo, JOGOS BASICOS vol. 1 and others. None of them are either flickery or slow.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited September 2011
    Hi all.
    I've just realized that i found a way to find the address of the content of a string variable

    DEF FN x(x$)=PEEK (4+PEEK 23563+256*PEEK 23564)+256*PEEK (5+PEEK 23563+256*PEEK 23564)

    useful to call brief assembler routine stored within a string variable or whatever... like in another post.

    _ Matteo
  • edited September 2011
    You are erasing the character, then performing lots of tasks before printing the character again. This is the reason for flickering.

    Change your program to work like this:
    IF INKEY$="w" THEN LET x2=x: LET y2=y-1: GO SUB 500: PRINT AT y,x; " "; AT y2,x2;"o"
    

    If you need examples, take a look at the source code of my BASIC games such as SOKO-BAN, Pongo, JOGOS BASICOS vol. 1 and others. None of them are either flickery or slow.

    Wow, that makes a big difference! Thanks for the tip!
    Pongo is a little bit slow, but yes - this method is certainly an improvement. :)
  • edited September 2011
    Dock wrote: »
    Wow, that makes a big difference! Thanks for the tip!

    You are welcome!

    Dock wrote: »
    Pongo is a little bit slow, but yes - this method is certainly an improvement. :)

    On second thought, Pongo was probably a bad example. All characters are larger than usual (not very efficient in BASIC) and the program is not optimized since it was just a proof-of-concept, not a released game. You better skip this one :)
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited September 2011
    This reminds me a technique I developed to mimic the way Game & Watch handhelds work. Some years ago, I wrote a BASIC version of the game "Fire":

    bomberos_en_accion.jpg

    For it, I started with the above picture, scaled, converted to B&W and saved as a SCR which I loaded into Art Studio.

    fireman_art_studio.jpg

    The screen features all the sprites present in the game, in each position they have to be. I took care of avoiding two sprites to share the same character cell. After applying colour, this was the result:

    fireman_color.jpg

    The final version, the one that is loaded to be used in the game has all the sprite area covered with an attribute value with the same ink and paper. To switch on a sprite, I only had to poke to the right addresses in the attribute memory to change the ink and reveal the sprite(s). This is faster than do a PRINT to erase a sprite, then another PRINT to show the updated one. And better yet: even with a fairly dense game loop as this game has, there's no noticeable flicker :)

    fireman_ingame.jpg

    For menus, title screen, etc, I can even write text on some unused rows, or paint big texts using colourfull blocks covering all the sprite area. Just take care of using the same value for ink and paper to not reveal the sprite bitmap behind.

    fireman_start.jpg

    The game has an entry at the WOS archive. Of course it's not protected in any way, so you can read the BASIC code:
    http://www.worldofspectrum.org/infoseekid.cgi?id=0015756

    PS: I even managed to translate it into C and compiled it for the Spectrum using the SDCC compiler. The resulting code was so fast that I had to insert delay loops into the game loop to make it run at a decent speed. I talked about it at the Speccy.org spanish forum (ZIP with the game and source code included). http://www.speccy.org/foro/viewtopic.php?f=6&t=436
  • edited September 2011
    This reminds me a technique I developed to mimic the way Game & Watch handhelds work.

    Nice!

    I used a similar method in the 80's to implement Tetris so I could make each block appear or disappear just manipulating attributes, but your implementation was more sophisticated. Good work!
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited September 2011
    I didn't know of this little hand-held conversion of yours, Miguel. Very nice and carefully done - just a little pity that the 2008 compiled version does not feature the "invisible" victims, but that's nitpicking after all :)
  • edited September 2011
    Hi, I like it. Its more difficult then it looks, especially when you lose one, the bounce rhythm is disturbed.

    If you make the backside off the redcross-van one pixel Longer to the left, the final black line will fall on a green background, the little white corners off the van will get smaller as well, and finally the left black stripe on the red-cross might get red as well... :-D
    BTW i think i like the original smoke better.
    BTW-2: Some times there are 2 jumps at one place, from high and low at once,creating colored ones, is that mend like that? those must be the "invisible" victims ?

    btw-3 :
    which emulator/ZX clone is this picture from?
    fireman_color.jpg
    my old website http://home.hccnet.nl/c.born/ has changed to http://www.cborn.nl/zxfiles/ so just click it and select a file
  • edited September 2011
    Crisis wrote: »
    btw-3 :
    which emulator/ZX clone is this picture from?
    fireman_color.jpg

    No ZX Spectrum. It's the PC coloured image just before translating to a Spectrum layout.
  • edited September 2011
    Crisis wrote: »
    If you make the backside off the redcross-van one pixel Longer to the left..
    BTW i think i like the original smoke better.

    Graphics is definetly not my thing :) The white thing at the top of the building is supossed to be a giant paper-made aeroplane that had just crashed into the building.
    Crisis wrote: »
    BTW-2: Some times there are 2 jumps at one place, from high and low at once,creating colored ones, is that mend like that? those must be the "invisible" victims ?

    Yes. I added that "feature" of invisible victims to add some challenging to the game, as I couldn't get it to be faster (and hence, more difficult). The story is that the building is some kind of biological experiment center that caught fire. At that moment, the first floor labs guys were experimenting with some radioactive thingy, and the heat made the containers to explode and the substance infected all the people of that floor.

    The compiled version is fast enought to be challenging on its own, and the port was meant to be an example of how to use C for coding a game for the ZX Spectrum (the source code of the C version is included), so I decided to not to include the "first floor radioactive guys".
  • edited September 2011
    The compiled version is fast enought to be challenging on its own, and the port was meant to be an example of how to use C for coding a game for the ZX Spectrum (the source code of the C version is included), so I decided to not to include the "first floor radioactive guys".

    Why don't you add the C version and its source code to the current WoS entry?
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited September 2011
    Why don't you add the C version and its source code to the current WoS entry?

    Can I? In fact, I didn't add the original BASIC version to WOS. I thought that only some people can modify the WOS database...
    I've just seen that someone did already add the compiled C version. On the other hand, I cannot see any "Modify entry" button or something like that to add files to the entry.
  • edited September 2011
    Can I? In fact, I didn't add the original BASIC version to WOS. I thought that only some people can modify the WOS database...

    Correct, but you can use this form to upload additional content and ask them to do it (pending their approval).

    I've just seen that someone did already add the compiled C version.

    If "FiremanV2008" is the C version, then it seems the source code is still missing...
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited November 2012
    The different issue's of ZX Spectrum will give different Key input while checking IN xxxxx value's. Without any key press the IN value will be 191 or 255 because of the difference in bit 6.
           IN:    Reads keys (bit 0 to bit 4 inclusive)
           0xfefe  SHIFT, Z, X, C, V            0xeffe  0, 9, 8, 7, 6
           0xfdfe  A, S, D, F, G                0xdffe  P, O, I, U, Y
           0xfbfe  Q, W, E, R, T                0xbffe  ENTER, L, K, J, H
           0xf7fe  1, 2, 3, 4, 5                0x7ffe  SPACE, SYM SHFT, M, N, B
    
    my solution for issue difference is the do a key check which needs a "no key pressed" garantie. Now store the result as calculation base.
    You can only RUN a program with a RUN command followed by the ENTER key. The change that a Being Loaded program will check other keys then SPACE/BREAK is really very rare, perhaps Technician Ted but i dont know if there is some key response in the running Ted's

    So
    7000 let ii= IN 63468
    7010 IF IN 65022=ii-2 then print  "s";
    7020 GOTO 7010
    
    
    RUN 7000
    
    ii should be 191 or 255

    Key s is now IN 65022 = ii-2 giving 189 or 253
    my old website http://home.hccnet.nl/c.born/ has changed to http://www.cborn.nl/zxfiles/ so just click it and select a file
  • edited November 2012
    There are quite a few issues here...
    Crisis wrote: »
    7000 let ii= IN 63468
    
    This instruction is reading from port $EC instead of $FE. It may not work properly in computers with other devices attached.

    Regardless of this, here's a better idea: use IN 65534 instead, which AFAIK will read from port $FE but ignore all pressed keys. This is what you really want, right?
    Crisis wrote: »
    7010 IF IN 65022=ii-2 then print "s";
    
    It's better to use IN 65022+2=ii instead of IN 65022=ii-2 since addition executes faster than subtraction.

    However my main concern is, this method is not very reliable anyway, because bit 6 may change value in the same computer under certain circumstances. Take a look here.
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited November 2012
    Crisis wrote: »
    The different issue's of ZX Spectrum will give different Key input while checking IN xxxxx value's. Without any key press the IN value will be 191 or 255 because of the difference in bit 6.
           IN:    Reads keys (bit 0 to bit 4 inclusive)
           0xfefe  SHIFT, Z, X, C, V            0xeffe  0, 9, 8, 7, 6
           0xfdfe  A, S, D, F, G                0xdffe  P, O, I, U, Y
           0xfbfe  Q, W, E, R, T                0xbffe  ENTER, L, K, J, H
           0xf7fe  1, 2, 3, 4, 5                0x7ffe  SPACE, SYM SHFT, M, N, B
    
    my solution for issue difference is the do a key check which needs a "no key pressed" garantie. Now store the result as calculation base.
    You can only RUN a program with a RUN command followed by the ENTER key. The change that a Being Loaded program will check other keys then SPACE/BREAK is really very rare, perhaps Technician Ted but i dont know if there is some key response in the running Ted's

    So
    7000 let ii= IN 63468
    7010 IF IN 65022=ii-2 then print  "s";
    7020 GOTO 7010
    
    
    RUN 7000
    
    ii should be 191 or 255

    Key s is now IN 65022 = ii-2 giving 189 or 253

    i didn't read the whole thread (and maybe it is not needed), but why not to use this:
    7000 LET ii=IN 65022: LET ii=ii-32*INT(ii/32)
    7010 IF ii=29 THEN PRINT "s";
    7020 GO TO 7000
    
  • edited November 2012
    ub880d wrote: »
    i didn't read the whole thread (and maybe it is not needed), but why not to use this:
    7000 LET ii=IN 65022: LET ii=ii-32*INT(ii/32)
    7010 IF ii=29 THEN PRINT "s";
    7020 GO TO 7000
    
    Efficiency. Multiplication and division takes a lot of time.

    However it wouldn't be too bad as follows:
    7000 LET ii=IN 65022: IF ii<192 THEN LET ii=ii+64
    7010 IF ii=253 THEN PRINT "s";
    7020 GO TO 7000
    
    Or slightly better:
    7000 LET ii=IN 65022
    7010 IF ii+(64 AND ii<192)=253 THEN PRINT "s";
    7020 GO TO 7000
    
    Creator of ZXDB, BIFROST/NIRVANA, ZX7/RCS, etc. I don't frequent this forum anymore, please look for me elsewhere.
  • edited November 2012
    7000 let ii= IN 63468 is a typo error> 63486, I didn't consider peripherals.
    A tape still running easily can cause a bit 6 being set in #fe by noise
    , that's true.
    remains: a time consuming calculation like yours.
    Adding is faster ? so we keep adding ;~)

    my old website http://home.hccnet.nl/c.born/ has changed to http://www.cborn.nl/zxfiles/ so just click it and select a file
  • edited November 2012
    Efficiency. Multiplication and division takes a lot of time.

    aha. then you could use this:
    7000 LET ii=IN 65022
    7010 IF ii=253 OR ii=189 THEN PRINT "s";
    7020 GO TO 7000
    
Sign In or Register to comment.