Log In  

Hello. As you know I've been recently experimenting with the new #INCLUDE command.

I have now recently found that if you use PRINTH it APPENDS text to a file, it does not overwrite it. If there is some way to overwrite the data, then this program could be run more than just a few times.

BUT IT DOES WORK.

You can indeed load a text file as data for PICO-8. Modify it. Save it back. Then re-run the program to see all the changes recorded without having to save anything to SRAM or 256-byte storage.

One problem I ran into is that #INCLUDE can also not be used in a comparison. For instance, this:

IF 1==0 THEN
#INCLUDE DOESNOTEXIST
END

Will crash because it ignores any commands around it and WILL INCLUDE that data if it exists and crash if not.

Here is the program. It does work a few times. Can you make it so it's perfect and can be run over and over again ?

-- test load and save text file
-- by dw817

cls()
game_name=""
game_x={} game_y={} game_r={}
game_c={}

#include gamedata.p8l

repeat
cls()
print("name="..game_name)

for i=0,15 do
  circ(game_x[i],game_y[i],game_r[i],game_c[i])
end

color(6)
print("",0,90)
print"left for new name"
print"right to clear name"
print"up to clear circles"
print"down to create new circles"
print"press 🅾️ to save"

flip()

if btnp(⬅️) then
  game_name=""
  for i=1,3 do
    r=flr(rnd(17))+1
    game_name=game_name..sub("bdfghjklmnprstvwy",r,r)
    r=flr(rnd(5))+1
    game_name=game_name..sub("aeiou",r,r)
  end--next i
elseif btnp(➡️) then
  game_name=""
elseif btnp(⬆️) then
  for i=0,15 do
    game_x={} game_y={}
    game_r={} game_c={}
  end
elseif btnp(⬇️) then
  for i=0,15 do
    game_x[i]=flr(rnd(128))
    game_y[i]=flr(rnd(128))
    game_r[i]=flr(rnd(16))+16
    game_c[i]=flr(rnd(15))+1
  end
elseif btnp(🅾️) then
  t=""
  t='game_name="'..game_name..'" '
  for i=1,4 do
    t=t.."game_"..sub("xyrc",i,i).."={"
    for j=0,15 do
      if (i==1) v=game_x[j]
      if (i==2) v=game_y[j]
      if (i==3) v=game_r[j]
      if (i==4) v=game_c[j]
      if v!=nil then
        t=t..v
        if j<15 then
          t=t..","
        else
          t=t.."}"
        end
      end
    end--next j
    t=t.." "
  end--next i
  printh(t,"gamedata")
  sfx(0)
end

until forever

NOTE, you WILL need to initially create a blank text file called, "gamedata.p8l" where you normally store your carts (notice that is an L on the end).

Then you must SAVE this program, any name, but must be in the same directory you just saved that data file in.

After this though it will work, about 3 times, then crash.

There needs to be some way of overwriting the "gamedata.p8l" instead of just appending data to it.

Once perfected this will be a remarkable and incredible way of loading and saving data bypassing the SRAM completely, and likely a lot more data could be loaded and saved this way, and a lot less coding to be involved since it's just source-code inclusion, modification, and saving. True self-modifying code.

But at this point I am truly stuck and not sure how to continue ...

P#67633 2019-09-13 20:40 ( Edited 2019-09-13 20:52)

... to true ??

ZEP has already accounted for this ?

Testing ...

Superb ! Okay, scratch that. If you use:

printh(text,filename,1)

Then it will OVERWRITE the filename, not append. That's where the "1" comes in. Alright ! So ... going back to the PROOF program.

It works, so long as I don't use LF (character 10) to make divisions. Let me edit the resulting data in NOTEPAD++ to see what it saved.

Ah ha ! Ah ha ... ahh ... that's terrible.

So let's recap, we have a new command called INCLUDE which adds source-code to a project.

Now, if you save that off with PRINTH() EVEN IF you use character 10, it will automatically put character 13 in front.

What does this mean ? You guessed it, you CANNOT import that back later.

Solution ? Well geez, I was hoping to have nicely formatted data. Just take out character 10 and have all your data in one-long run-on sentence.

But it DOES work if you keep out CRs and LFS !

COMPLETE !

Cart #zunakesere-0 | 2019-09-14 | Code ▽ | Embed ▽ | No License

What's going on here ?? First off like before this will not run in the BBS. Sorry 'bout that. Only as immediate or EXE.

And you still must create a blank "gamedata.p8l" file to start with where the code is and you still must save this program in the same directory it is located. Other than that, you're ready to rock.

Okay, this is immensely powerful. In the demo you can press RIGHT to randomly create a new name (tests string recall), press DOWN to randomly create 16-new circles (tests numeric array recall).

Press LEFT to clear name or UP to clear the circles.

Now press (O) when you're ready to save.

Saved ? Good. Exit the program and re-run it. NOTICE that all the data you saved is recalled !

Right, now this is quite a bit better than poking all those bytes of memory. Here you can store whopping arrays that may well be beyond 256-bytes or even the 4096 I discovered a year back.

And you have the added advantage that the data is actually source-code that is being added to your code so it's not a string with hex stuff that has to be decoded. It's =ALREADY= decoded.

Now ... I'm just musing for a second. Security. And ... does this mean that when you compile a cart to an EXE it's not REALLY an EXE but the whole blessed PICO-8 OS ?

I mean how else is it going to be able to INCLUDE source-code that changes on the fly ? I understand if it were actually included in the compilation, but no, you MUST have the .P8 file or whatever with you when you run it locally or as an EXE.

... time for a sandwich.

P#67649 2019-09-14 02:13

Next day, next day !

What have I found ? A bit ... First the good news. You can indeed run Pico-8 in immediate mode and both load and save using #INCLUDE and PRINTS().

Now the bad news. It seems like PRINTS() is completely ignored when compiled to an executable. And that could be because of security.

Correction (09-14-19): the PRINTS() file is being saved when you run the executable, however, it is storing it by default HERE:

C:\Users\dw817\AppData\Roaming\pico-8\carts

Which I tried to access, even with %appdata% ...

https://ss64.com/nt/syntax-variables.html

... and PICO-8 does not recognize the ability to call a parent folder. I suppose it could be clumsily done with a batch file in the same directory.

@copy /y %appdata%\pico-8\carts\gamedata.p8l .
@engine.exe
@

Yet it DOES read any included text file even during executable, so ... yes, when you compile to EXE, PICO is apparently not compiling your program at all and just attaching your source-code albeit tokenized to the end of a main executable that will run any PICO code - not just what you wrote.

It's not bad. Some useful tools I'm building that can read and write to the same or different data files work perfectly well in immediate mode.

For more information on #include and a method you can use to write your very own P8 compiler, go HERE:

https://www.lexaloffle.com/bbs/?tid=35350

I suspect ZEP is not going to want this and may in time set it so when you #INCLUDE code, that during compilation the actual code included becomes part of your source.

Meaning when you compile to EXE you will not need to include that external text or data file - and also plug up the security hole in the process.

It would definitely be intriguing to see this activity ONLINE, but the security breach becomes even bigger.

As mentioned for now, I'm quite content to have this ability in immediate mode for my P8 conversion tools.

Comments, questions, or kerosene ? Lemme know !

P#67675 2019-09-14 17:18 ( Edited 2019-09-14 21:27)

Hey dw817 ! I know this is a bit old but I think I might be interested in this- though I'm a true newbie in Pico8 and programming in general - so tell me if I misunderstood the purpose of your research.

Let me explain what I would like to do in my prototype game so you'll understand my needs:
I'd like to store a certain amount of objects with some arguments (string,price,sprite) in an array in order to have a shopping list, where I could access in my game, buy the item (and so remove it from the array, get it in player's inventory). I was thinking using an external text file to store all the items data (let say 50 items), and I thought I could use the #INCLUDE like you present in this topic, am I correct ?
Unfortunately I'm a bit lost in some of your words so I'm not really sure how to proceed, but if someone could just tell me if this is the better solution for my need, I would appreciate.

Thank you and have a great day !

P#86528 2021-01-17 10:10

@dadam what you need is regular #include file - the bug mentionned by dw has been fixed since.

note that including a file is just a way to conveniently arrange your code.
You can get the same result, eg having a lua table describing inventory in main p8 file.

P#86531 2021-01-17 13:48

Thank you @freds72, that's what I thought too, I'll just do this :)

P#86532 2021-01-17 14:06 ( Edited 2021-01-17 14:07)

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-03-28 22:53:51 | 0.084s | Q:25