Jump to content
IGNORED

Performing math on CALL CHAR hex strings in TI Basic?


notwhoyouthink

Recommended Posts

I want to point out that i am talking strictly about doing this in Basic, not Extended Basic, RXB, Forth or whatever, and no using Minimem for its added features either.

Using the method that senior_falcon came up with for sprite usage under normal Basic, the sprites location, color, and character used are all handled through a CALL CHAR hex string (which actually effects 2 sprites at a time).

I will not go into details of how it all works here, but basically, i need some way of taking for instance, the string 5760A10F5770A50F and modifying certain characters of that string (which, technically, is two strings ran together, one string per sprite. 8 ASCII characters / 4 two-digit hex values per sprite.), which will in turn effect the on-screen sprites.

For instance, i can move the sprites from their current location to a new one by changing 5760A10F5770A50F to 5770A10F5780A50F.

If i were dealing with hex numbers and not strings i could, for instance take the hex numbers 5760A10F for sprite 1 & 5770A50F for sprite 2, then add hex 100000 to each to get hex 5770A10F & hex 5780A50F, and run the 2 numbers together as a string "5770A10F5780A50F".

 

I guess what i really need is something similar to STR$ and VAL that operate in hex mode instead of decimal to use as sub-routines.

Then i could take my CALL CHAR string and convert it into a value, add/subtract a certain amount from it, then convert the result back into a string that i pass back to CALL CHAR.

But i have no idea how to implement that (or even know if it is possible) under TI Basic.

... Is any of this making any sense to anyone, or am i just falling off of the deep end?

Edited by notwhoyouthink
Link to comment
Share on other sites

I used to use POS() to convert single-digit hex to decimal and SEG$() to convert back. You will need to divide up your sprite CHAR definitions to deal with them individually rather than how you propose to work with an entire string.

DECIMAL=POS("0123456789ABCDEF",HEX$,1)-1

HEX$=SEG$("0123456789ABCDEF",DECIMAL+1,1)



You could use this method to convert multiple digits one-at-a-time by multiplying or dividing by the positional value: 0, 16, 256, 4096, etc. The -1 and +1 are to account for POS() and SEG$() starting at position 1 rather than 0.

10 REM  CONVERT TWO-DIGIT HEXADECIMAL TO DECIMAL
15 INPUT "TWO-DIGIT HEX NUMBER: ":HEX$
16 REM  NO ERROR CHECKING ON HEX$
20 DECIMAL=0
30 FOR P=0 TO 1
40 DIGIT=POS("0123456789ABCDEF",SEG$(HEX$,2-P,1),1)-1
50 DECIMAL=DECIMAL+DIGIT*(16^P)
60 NEXT P
70 PRINT :HEX$;" IS";DECIMAL;"IN DECIMAL.":::
80 GOTO 10


10 REM  CONVERT DECIMAL BETWEEN 0 AND 255 TO HEXADECIMAL
15 INPUT "DECIMAL NUMBER (0-255): ":DECIMAL
16 IF (DECIMAL<0)+(DECIMAL>255)THEN 15
20 DIGIT1=INT(DECIMAL/16)
30 DIGIT2=DECIMAL-(DIGIT1*16)
40 HEX$=SEG$("0123456789ABCDEF",DIGIT1+1,1)&SEG$("0123456789ABCDEF",DIGIT2+1,1)
50 PRINT :DECIMAL;"IN HEXADECIMAL IS ";HEX$:::
60 GOTO 15



You could also use a string to replace the "0123456789ABCDEF" literals. In my experience this is a slow and expensive process in TI BASIC. I never developed anything beyond this but I suspect there is a better method.

  • Like 1
Link to comment
Share on other sites

While fixing a bug in my quick-n-dirty above, I also expanded it to convert ANY length hexadecimal number to decimal.

 

 

10 REM  CONVERT HEXADECIMAL NUMBER TO DECIMAL
15 INPUT "HEXADECIMAL NUMBER: ":HEX$
16 REM  NO ERROR CHECKING ON HEX$
20 DECIMAL=0
30 FOR P=0 TO LEN(HEX$)-1
40 DIGIT=POS("0123456789ABCDEF",SEG$(HEX$,LEN(HEX$)-P,1),1)-1
50 DECIMAL=DECIMAL+DIGIT*(16^P)
60 NEXT P
70 PRINT :HEX$;" IS";DECIMAL;"IN DECIMAL.":::
80 GOTO 10
  • Like 2
Link to comment
Share on other sites

Lastly, here is one to convert any positive decimal whole number up to 4294967295 (hex FFFFFFFF) to a hexadecimal number.

 

 

10 REM  CONVERT DECIMAL BETWEEN 0 AND 4294967295 TO HEXADECIMAL        
20 INPUT "DECIMAL NUMBER: ":DECIMAL
30 IF (DECIMAL<0)+(DECIMAL>4294967295)THEN 20
40 PRINT :DECIMAL;"IN HEXADECIMAL ";
50 FOR P=0 TO 7
60 IF INT(DECIMAL/(16^P))=0 THEN 80
70 NEXT P
80 HEX$=""
90 FOR R=P+(P>0)TO 0 STEP -1
100 S=16^R
110 DIGIT=INT(DECIMAL/S)
120 HEX$=HEX$&SEG$("0123456789ABCDEF",DIGIT+1,1)
130 DECIMAL=DECIMAL-(DIGIT*S)
140 NEXT R
150 PRINT "IS ";HEX$:::
160 GOTO 10
  • Like 1
Link to comment
Share on other sites

I would avoid trying to create a subroutine or (far worse) function to do this kind of work.

 

BASIC is going to be slow regardless and the best way to keep it moving fast is to hardcode as much as possible.

But you can't hardcode something like player input.

I was hoping to maybe get a user-controllable sprite moving around the screen.

Player presses E, sprite moves up, and up, and up, until the E key is released.

Etc...

I hardcoded that parsec sprite demo, and thats pretty much all its good for in that state, a animation.

But with a way to better modify the string, i could possibly get the sprite to react to input, a little more like a actual game.

Edited by notwhoyouthink
Link to comment
Share on other sites

I used to use POS() to convert single-digit hex to decimal and SEG$() to convert back. You will need to divide up your sprite CHAR definitions to deal with them individually rather than how you propose to work with an entire string.

 

 

DECIMAL=POS("0123456789ABCDEF",HEX$,1)-1

HEX$=SEG$("0123456789ABCDEF",DECIMAL+1,1)

 

 

You could use this method to convert multiple digits one-at-a-time by multiplying or dividing by the positional value: 0, 16, 256, 4096, etc. The -1 and +1 are to account for POS() and SEG$() starting at position 1 rather than 0.

 

 

10 REM  CONVERT TWO-DIGIT HEXADECIMAL TO DECIMAL
15 INPUT "TWO-DIGIT HEX NUMBER: ":HEX$
16 REM  NO ERROR CHECKING ON HEX$
20 DECIMAL=0
30 FOR P=0 TO 1
40 DIGIT=POS("0123456789ABCDEF",SEG$(HEX$,2-P,1),1)-1
50 DECIMAL=DECIMAL+DIGIT*(16^P)
60 NEXT P
70 PRINT :HEX$;" IS";DECIMAL;"IN DECIMAL.":::
80 GOTO 10


10 REM  CONVERT DECIMAL BETWEEN 0 AND 255 TO HEXADECIMAL
15 INPUT "DECIMAL NUMBER (0-255): ":DECIMAL
16 IF (DECIMAL<0)+(DECIMAL>255)THEN 15
20 DIGIT1=INT(DECIMAL/16)
30 DIGIT2=DECIMAL-(DIGIT1*16)
40 HEX$=SEG$("0123456789ABCDEF",DIGIT1+1,1)&SEG$("0123456789ABCDEF",DIGIT2+1,1)
50 PRINT :DECIMAL;"IN HEXADECIMAL IS ";HEX$:::
60 GOTO 15

 

 

You could also use a string to replace the "0123456789ABCDEF" literals. In my experience this is a slow and expensive process in TI BASIC. I never developed anything beyond this but I suspect there is a better method.

 

 

While fixing a bug in my quick-n-dirty above, I also expanded it to convert ANY length hexadecimal number to decimal.

 

 

10 REM  CONVERT HEXADECIMAL NUMBER TO DECIMAL
15 INPUT "HEXADECIMAL NUMBER: ":HEX$
16 REM  NO ERROR CHECKING ON HEX$
20 DECIMAL=0
30 FOR P=0 TO LEN(HEX$)-1
40 DIGIT=POS("0123456789ABCDEF",SEG$(HEX$,LEN(HEX$)-P,1),1)-1
50 DECIMAL=DECIMAL+DIGIT*(16^P)
60 NEXT P
70 PRINT :HEX$;" IS";DECIMAL;"IN DECIMAL.":::
80 GOTO 10

 

 

Lastly, here is one to convert any positive decimal whole number up to 4294967295 (hex FFFFFFFF) to a hexadecimal number.

 

 

10 REM  CONVERT DECIMAL BETWEEN 0 AND 4294967295 TO HEXADECIMAL        
20 INPUT "DECIMAL NUMBER: ":DECIMAL
30 IF (DECIMAL<0)+(DECIMAL>4294967295)THEN 20
40 PRINT :DECIMAL;"IN HEXADECIMAL ";
50 FOR P=0 TO 7
60 IF INT(DECIMAL/(16^P))=0 THEN 80
70 NEXT P
80 HEX$=""
90 FOR R=P+(P>0)TO 0 STEP -1
100 S=16^R
110 DIGIT=INT(DECIMAL/S)
120 HEX$=HEX$&SEG$("0123456789ABCDEF",DIGIT+1,1)
130 DECIMAL=DECIMAL-(DIGIT*S)
140 NEXT R
150 PRINT "IS ";HEX$:::
160 GOTO 10

Thanks for these. I will play around with these sometime and see if i can get my little parsec demo to have some sort of interactive element. :)

Edited by notwhoyouthink
Link to comment
Share on other sites

This code shows one way to get the motion. This moves both row and column 2 pixels at a time. It's pretty bulky and pretty slow. If there is no vertical motion then there are steps you could omit and that would speed it up. The other problem you are going to run into is the "garbage collection". This is slow in BASIC and will cause pauses in what little action there is.

 

OLD CS1's suggestion might be a faster way to go. "It may be possible to create a table of values which would predict a player position based upon input."

1 VS=2
2 HS=2
9 HEX$="0123456789ABCDEF"
10 S1R=87
20 S1C=96
30 S2R=87
40 S2C=112
50 CALL CHAR(144,"D")
51 CALL CHAR(145,"D")
60 S1R=S1R+VS
70 S1C=S1C+HS
80 S2R=S2R+VS
90 S2C=S2C+HS
100 SR=S1R
110 SC=S1C
120 GOSUB 1000
130 S$=P$&"A10F"
140 SR=S2R
150 SC=S2C
160 GOSUB 1000
170 S$=S$&P$&"A50F"
180 CALL CHAR(144,S$)
190 GOTO 60
1000 RMSN=INT(SR/16)
1010 RLSN=SR-RMSN*16
1020 CMSN=INT(SC/16)
1030 CLSN=SC-CMSN*16
1040 P$=SEG$(HEX$,RMSN+1,1)&SEG$(HEX$,RLSN+1,1)&SEG$(HEX$,CMSN+1,1)&SEG$(HEX$,CLSN+1,1)
1050 RETURN
  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...