Ultimate Amiga
Network Boards => AMOS Language Discussion => AMOS Factory => AMOS Professional Forum => Topic started by: xboxisfinished on December 07, 2015, 10:10:45 PM
-
Hello,
I am stuck in one little predicament and I was hoping someone can help me here. I have the following code below:
Open In 1,"1.txt"
While Eof(1)=0
Input#1,A$
Wend
The file 1.txt hold this information:
0,0,0,0,0,0,0,0,0,0 (Line 1)
0,1,1,1,0,0,1,1,1,0 (Line 2)
etc
I want to be able to read the file character by character and store that character in A$ and when I reach the comma file I want to be able to write some code (all inside the while loop mind you) and then resume reading the characters after that comma and so on.
For example right now I have 0,0,0,0,33,0,0 I should be able to read the first character 0 and then if the second character is comma, do code here, then move on to the second character which is 0 and then the one after it is a comma, then do code here, repeat until I reach 33. In 33, it reads the first character 3 then the second character 3 and store that in a string variable A$="33" when it reaches the third character comma then it executes code. It keeps these procedures until it finishes Line 1 and then repeat the same cycle to Line 2 until it reaches end of file.
Right now my problem are two faults.
1) When it reads the file it stores A$ immediately as "0,0,0,0,0,0,0,0,0,0" one string , but does not store the second line, third line...it just stores the first line in the string
2) I keep getting End Of File.
What advice and approach you guys could give me? Also, now they are stored as easy modifiable 1.txt file that you can easily open in a notepad, change the level design, setting and poof. There goes the security and cheating is a breeze. How do I protect people from accessing or modifying or even saving it in this format but encrypted and where it fails to open the file not encrypted?
Thanks in advance.
-
Ooops :(
-
Hi xboxisfinished. This is a common problem in games - how to store the state of a game or playfield, etc.
Forget for a moment the idea of text files. It may seem obvious, but what you're storing is data. So store it as data ;) .
Taking you sample as the example. You're storing sets of numbers. And from the values you're using, it looks like they will all fit into byte values. So store them in a memory bank:
Rem This assumes you data is in a two-dimensional array 10 rows x 10 columns
B_NUM=17 : Rem whatever number you want to know the bank by
B_LEN=10*10 : Rem assuming 10 numbers in 10 lines - adjust to suit
Rem All AMOS arrays are base zero. So 10 x 10 has indexes ranging from 0 thru 9
Dim G_BOARD(9,9)
Reserve As Work B_NUM,B_LEN
Now store your data into the bank using Poke:
B_ADDR=Start(B_NUM)
IX=B_ADDR
For IX_ROW=0 To 9
For IX_COL=0 To 9
Poke IX,G_BOARD(IX_ROW*10+IX_COL)
Inc IX
Next IX_COL
Next IX_ROW
Now you can simply use Bsave to save it to a file:
Rem I've hard coded the file name.
Rem It would be better to make is selectable using Fsel$()
Bsave "GameData.bin",B_ADDR To B_ADDR+B_LEN
To get it back:
Rem First open the file to get its length
Rem You could hard code the length but it's far more flexible to do it this way
Open In 1,"GameData.bin"
B_LEN=Lof(1)
Close 1
Rem Got the length so now reserve the bank
Reserve As Work B_NUM,B_LEN
B_ADDR=Start(B_NUM)
Bload "GameData.bin",B_ADDR to B_ADDR+B_LEN
And to access the data
Rem This is the really simple approach
IX_ADDR=Start(B_NUM)
Do
D=Peek(IX_ADDR)
Rem Do what you want with the data value here
...
Rem Now get the next byte
Inc IX_ADDR
Exit If IX_ADDR=Start(B)+Length(B)
Loop
All the above assumes simple data like a two-dimensional array or similar. If you're dealing with variable length 'lines' of data, you need something to tell you you've reached the end of a 'line'. As long as your data values are less than $80. simply use $80 to mark the end of a 'line'.
Your code to read it out of the bank then looks like this
Open In 1,"GameData.bin"
B_LEN=Lof(1)
Close 1
Rem Got the length so now reserve the bank
Reserve As Work B_NUM,B_LEN
B_ADDR=Start(B_NUM)
Bload "GameData.bin",B_ADDR to B_ADDR+B_LEN
IX_ADDR=B_ADDR
Do
D=Peek(IX_ADDR)
If D=$80
Rem Do whatever you want to do at the end of a 'line' here
...
Rem
End if
Rem Do whatever you want to do with the data element in D here
...
Rem
Inc IX_ADDR
Exit If IX_ADDR>=B_START+BLEN
Loop
If your data elements have values larger than 127, simply use words to store it using Doke and Deek. And don't forget to increment your memory pointer twice! Even longer values can be handled using Loke and Leek (and adding 4 to the memory pointer each time!)
That covers ways you can store it. Now how to encrypt it. The simplest method is to use a fixed value as a key and Exclusive Or it with each byte. To get it back, simply Exclusive Or it again with the same key value.
Rem The simple method of encrypting
D_KEY=$A3
For IX_ADDR=B_START To B_START+B_LEN-1
D_VAL=Peek(IX_ADDR)
D_VAL=D_VAL xor D_KEY
Poke IX_ADDR,D_VAL
Next IX_ADDR
Rem The simple method of decrypting
For IX_ADDR=B_START To B_START+B_LEN-1
D_VAL=Peek(IX_ADDR)
D_VAL=D_VAL xor D_KEY
Poke IX_ADDR,D_VAL
Next IX_ADDR
No. it's not a mistake, the method is fully reversible so the code to decrypt it is identical :) .
But simple encryption like that is easily cracked. So one method is to use an array of keys like this:
Restore KEY_VALUES
Dim KEYS(7)
For I=0 To 7
Read KEYS(I)
Next I
Rem Now cycle through the keys array as you encrypt
IX_KEY=0
For IX_ADDR=B_START To B_START+B_LEN-1
D_VAL=Peek(IX_ADDR)
D_VAL=D_VAL xor KEYS(IX_KEY)
Poke IX_ADDR,D_VAL
Add IX_KEY,1,0 To 7
Next IX_ADDR
KEY_VALUES:
Data $A5,$44,$12,$F5,$30,$67,$88,$39
Decrypting the data is exactly the same code. Just make sure you don't lose the Data line containing the key!!!
There's heaps of ways of encrypting the data. Far too many to go into here. Limited. as Lego says, only by your imagination ;) .
And that's the end of my 'sitting allowance' today and my back's killing me. So good luck and let us know how you get on. And apologies for any typos.
-
Oh WOW!!
Thanks!!!!!! ;D :D
-
I have only question to ask. Where do I get the value of B_start and B_length?
-
Use the start and length functions on the data bank your data is in.
Be sure to put the values into the variables though, otherwise it will slow down the loop.
-
instead of bload / bsave, maybe use wload/wsave (an AMCAF function) and remvoe the need to specify the size of the block
:)
http://www.ultimateamiga.co.uk/HostedProjects/AMOSFactory/AMCAFguide/manual/diskprimary.html#wload
i use similar techniques myself, and tend to edit my data files in a Hex Editor a lot of the time!