Author Topic: Converting from Prgm to App  (Read 2789 times)

0 Members and 1 Guest are viewing this topic.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Converting from Prgm to App
« on: March 23, 2023, 10:28:52 pm »
Way way late, but thanks to both E37 and Zeda I was able to implement a working A* Algorithm in my game. The source for the project is on Github here: https://github.com/kiloments/axe-rl
I've been pretty inconsistent in working on it, but recently I started back up again. I've reached the point where I need to make the program into an app. I thought it would be as simple as change from compiling to No Shell to Compiling as an Application, but once I did it looked like the my appvars were somehow being corrupted. When I moved around the map random tiles would get changed when I left an area and came back to it. The attached gif illustrates what I mean.

You can also see a little confused slime walking outside the map. This is because the DistMap appvar I'm using to calculate the AI is somehow also being corrupted. It's initially spawned in the room that gets corrupted then wanders its way out ignoring collision. I even compiled an older working version to verify and it seems to confirm. Everything works as a program and not as an App. I would like any help in beginning to convert this project into an app. And any other advice/optimizations you may have. Thanks!

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Converting from Prgm to App
« Reply #1 on: March 24, 2023, 03:56:29 pm »
I don't see any overflow protection for A* pathfinding although I could have missed it in the complex logic. Right now you create appvFLOOR before appvDISTMAP. Try creating appvDISTMAP first (Just invert the order of the two GetCalc lines in main) If you are overflowing, that should change the overflow behavior. If you aren't then nothing should change. I noticed you used sign{ in quite a few places. I don't know what that is supposed to be, my best guess is the signed{} command. If it is nib{} then that would be the source of your problems. But, based on how you are using it, it looks like signed{} which is fine. The line 'Fill(^^oTargetX,400,0)' seems a little strange but it should be safe. I don't have any other suggestions, I took a hard look at it for over an hour and didn't see any red flags. Do you reset ram after every time you quit normally?

Also that is some beautifully optimized tile drawing code.
« Last Edit: March 25, 2023, 10:26:28 am by E37 »
I'm still around... kind of.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: Converting from Prgm to App
« Reply #2 on: March 25, 2023, 09:41:08 pm »
Thanks for taking the time to look it over and reply. I tried inverting it and the issue still persisted. I'm not sure what the problem could be. Can you try compiling and running it when you get a chance? If possible, uncomment the first AddMob so that you can also test the AI to see how it behaves on your calc. I open a new Wabbit when I compile and test, so the RAM is always clear. Here's a screenshot showing what's happening with both the tilemap and the AI.

I don't know how to proceed with trying to fix it.

Also I can't take full credit for the tile code. It's mostly Runer's from his GRAYPKMN source that I modified and repurposed for monochrome. Took a while to read and understand haha. I'm also considering possibly using Fullrene or Crabcake if converting to an app is somehow impossible. I'll keep trying to debug this. Also if you're willing to help me learn and optimize my code maybe we can work together sometime. Thanks again.

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Converting from Prgm to App
« Reply #3 on: March 27, 2023, 08:00:50 pm »
I'll take a look. I'm kinda busy at the moment so it may be a couple days until I find an hour or two to sit down and hunt through it. If you just want to have over 8811 bytes of executable code, fullrene is probably a better choice over an app (just because it compiles faster) Since the inversion didn't change anything, I think compiling as an app just brings an already existing problem to the surface. None of your code does anything that would matter if it was compiled as app.

You shouldn't try optimizing until you get your code working or have a real need for it. Also, you don't have very much code in total. Are you really running into the execution limit? You are limited to 8811 bytes of code, not data. Your data can go above that limit. I guess I will see when I actually sit down and compile it ;)
I'm still around... kind of.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: Converting from Prgm to App
« Reply #4 on: March 27, 2023, 09:39:57 pm »
I think I am going to do a full and final rewrite of this project. I'm encountering issues that I do not understand and quite frankly it has been very frustrating. I feel so helpless not knowing why my code behaves the way it does. Things that used to work no longer do with little to no modification. And I don't know if it's because of mistakes I made as a programmer or something I don't know about the language/calculator. I really really wanted to create a good game but it feels like I've been fighting the language at each step.

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Converting from Prgm to App
« Reply #5 on: April 03, 2023, 08:58:19 am »
@Ki1o Sorry I took so long, I forgot.
I sent your code to my calc and gave it a look. The code in its original state worked fine as a program and an app. As a program, it leaves garbage all over the homescreen on quit. Adding a 'ClrHome' in Exit will fix that. The total compiled program is only 8k bytes total. Since probably 1k of that is data, you still have some space to play with before you hit the execution limit.

When I uncommented all of your AI code, it consistantly corrupted regardless of whether it was a program or app. I also noticed that the slimes always ignored walls - even before corrupted garbage showed up on screen. I am still digging around but my guess is that bu the time the character walks around that big loop, the slimes move so far out of bounds that they corrupt some area of memory. Regardless of what the cause is, as far as I can tell, it has to do with the mob AI and not compiling as an app.
I'm still around... kind of.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: Converting from Prgm to App
« Reply #6 on: April 03, 2023, 10:20:52 pm »
Thanks for testing! I started to think it may be the AI and you just confirmed it. I am still moving forward with the rewrite because I realized that there were issues with the way I was handling the turn based game loop, so I'm hoping to eliminate any other unexpected behavior with better code. Also I just want to confirm, there should be no issue using custom variables to call function labels right?

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Converting from Prgm to App
« Reply #7 on: April 04, 2023, 07:57:01 am »
Alright, a rewrite often helps eliminate nasty bugs. And there is no difference at all between built in variables and custom ones. Anything you can do with one, you can do with the other.

Since you are rewriting, I have a couple suggestions:


You make two appvars but both are a fixed size. You could combine them into one big appvar. Additionally, you only need to call GetCalc after creating new appvars or resizing existing ones. Once you have created all of them, they won't move.



Free RAM areas:
0x966E is 128 bytes of free memory like L5. It normally holds the contents of the homescreen. (So Disp will overwrite data like L5) When you quit, call Fill(0x966E, 128, ' '). That is just filling it with the space character so it appears blank. I use this one a bunch so I am super positive it is very safe.
0x8000 is 256 bytes of free memory. The end of it overlaps with L4-512 (not a problem if you don't use L4-512 as a 756 byte buffer) But even if you do, it is still 165 bytes of memory. You don't need to clear it or anything when you quit. This also means that if you combine 0x8000 and L4, you get a 933 byte long block of memory. Just remember that it will be corrupted on flash operations (which you aren't doing)
0x8E2C is 400 bytes of free memory. Just fill it with 0's when you quit.
0x85E7 is 158 bytes of free memory. I don't think you even need to fill it with 0's when you quit but you might as well to be safe.
L2 can be used as a 768 byte buffer if you fill it with 0's when you quit. (Hint: you can use ClrDraw(L2) instead of Fill(L2, 768, 0). Its faster and smaller (assuming you have used ClrDraw(buffer) somewhere else)
I think that is all the juicy free memory areas. There is quite a bit of smaller ones but they aren't really worth it unless you are really hurting. Omnimaga's free ram page is a very good tool (Ignore anything it says about Axe - it is very outdated) When using it, make sure to double check that you aren't overlapping any of Axe's variables. To do that, you should do 'Print oA>Hex' Repeat for A-theta, r1-r6, Y1-Y10 (Y variables take up 3 bytes each), X1T-Y6T (the parametric variables - yes, those are built in Axe variables!) and L1-L6. Compare the printed addresses to the free ram are you are looking at.




When dealing with the AI of a bunch of different mobs, it is really awkward (and super slow) to keep having to call {CurrentMob + 5}r and the like to access its variables.
Compare these two pieces of code:
Code: (Hard to read) [Select]
0->MobX
2->MobY
4->MobHP

Lbl MobAI .r1 is the pointer to the mob's data
r1->X .save R1 so function calls don't clobber it

.IsWall and similar functions are just made up psuedocode for the example
!If IsWall({X + oMobX}r + 1, {X + oMobY}r) .Simple, but it will get messy quickly
{X + oMobX}r++
End

!If IsWall({X + oMobX}r, {X + oMobY}r + 1)
{X + oMobY}r++
End

!If {X + oMobHP}r
MobDies(X)
End

Return

Versus:
Code: (Easy to read) [Select]
L1+0->MobX .Put your Mob data at a predetermined spot. I usually use 0x966E (described above in the free ram section) but you can put it wherever you want.
L1+2->MobY
L1+4->MobHP

Lbl MobAI .r1 is the pointer to the mob's data
r1->X .save the value of r1
Copy(X, oMobX, SizeOfMob) .Copies the mob's data to a predetermined spot. Fill in SizeOfMob with however big your mobs are, in bytes.

!If IsWall(MobX + 1, MobY) .This is so much easier to read and type than the above example. And it is way faster and uses less space!
MobX++
End

!If IsWall(MobX, MobY + 1)
MobY++
End

!If MobHP
MobDies(oMobX)
End

Copy(oMobX, X, SizeOfMob) .Copy the data back now that we are done
Return







Asm(E5) pushes HL (which is Axe's version of TI-BASIC's Ans) onto the stack and Asm(E1) pops it. That lets you write code like:
Code: [Select]
Lbl XMagic
X:Asm(E5) .Set X as Axe 'Ans' variable and then push it onto the stack

5->X .Modify and use X however you want
Disp X>Dec

Asm(E1)->X .Pop the last entry from the stack and set X to it
Return

This is super useful as it lets you create local variables.
I don't know how familiar you are with assembly and registers, so I'll explain in more detail what that code does. If you understand what 'push hl' and 'pop hl' means, you can ignore all of this.

Code: [Select]
.Like TI-BASIC, Axe has a variable which is the result of the previous calculation. However, Axe's version doesn't have a name.
X+5 .Add 5 to X but don't do anything with the result. The value is stored in HL which is what Axe's 'Ans' is called.
->Y .Store HL to Y. Since the result hasn't changed, we can use HL again
+2->Z .Add 2 to HL and then store HL to Z
X .Sets HL to the value of X
Asm(E5) .Pushes the value of HL onto the stack. You can push and pop whenever you want as long as you know what you are doing
+5 .Adds 5 to HL
SomeFunction() .Call some function that possibly modifies X. At the start of the function, HL will hold X+5. (so the first line of the function could be '->X' for instance)
Asm(E1) .Pops HL from the stack. Now HL holds the same value it did when the most recent Asm(E5) was called
->X .And save that value to X, effectively protecting it from any modifications that might happen in SomeFunction. (Called functions can push and pop if they want too)

.You can push multiple things to the stack at the same time
X:Asm(E5)
Y:Asm(E5)
MyVariable:Asm(E5)

For(x, 0, 5)
Disp X>Dec
End

Asm(E1)->MyVariable .Notice that the order of pops is inverted from the order of pushes
Asm(E1)->Y
Asm(E1)->X

...
There are some restrictions on when you can push and pop from the stack. Well, you can do it at any time, but if you don't know what you are doing, all you will get is a crash
You must make sure that you call pop the same amount of times you call push before you call 'return'. (This is easy, all it means is that you can't call push a bunch at the start of a function and then call Return without popping everything. You don't need to do anything with the popped results if you don't want to)
The stack is used when calling functions. All that means is that you can't push a variable in one function, call another and pop that variable in the function you just called
The stack is also used for single argument For loops. (3 argument for loops don't have this problem - they use a much less efficient method of looping that doesn't use the stack) That means you can't push a variable outside a For(10) loop and pop it inside the loop. (it is still safe to push and pop inside the loop, just make sure your pushes and pops are balanced inside the loop body.
If you just push some variables at the start of a function and pop them at the end, you will always be safe. It also works well inside complex loops.
...


All this is mostly useful for pushing some variables at the start of a function and then popping them at the end so you don't need to worry about clobbering a variable used elsewhere. Its also super fast, a push or pop is almost twice as fast as addition! (*comparing 'push hl' [11cc] and 'pop hl' [10cc] against 'add hl, de' [19cc]) I would recommend spending 15-20 minutes trying out different uses for this before putting it any serious code. Its no fun debugging code you don't fully understand.
I use this so frequently in my code that I wrote a personal axiom that adds commands 'Push' and 'Pop' that just do Asm(E5) and Asm(E1) respectively.
« Last Edit: April 04, 2023, 10:47:17 am by E37 »
I'm still around... kind of.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: Converting from Prgm to App
« Reply #8 on: April 11, 2023, 03:27:05 am »
@E37 As usual, thanks for all the help! I will definitely be making use of this. I figured dereferencing for each variable would be slow but your idea is wayy better. Idk what I was thinking. I was also thinking of creating one big appvar instead of creating multiple appvars with GetCalc() so I'll definitely be doing that. I've run into a weird little bug/issue with Axe that I cannot explain and I was hoping you would be able give me some answers. What I am currently attempting to do in my rewrite at the moment is ensure that only 1 keypress is registered at a time. I'm following a tutorial series and although it's in another language it's pretty easy to convert to Axe. Anyways, my original input code looked like this:
Code: [Select]
Lbl UpdateGame
If getKey(2)
PlayerX--
⁻8→ScrollXOffset
ʟUpdatePlayer→UpdateState
End
If getKey(3)
PlayerX++
8→ScrollXOffset
ʟUpdatePlayer→UpdateState
End
If getKey(4)
PlayerY--
⁻8→ScrollYOffset
ʟUpdatePlayer→UpdateState
End
If getKey(1)
PlayerY++
8→ScrollYOffset
ʟUpdatePlayer→UpdateState
End
If getKey(15)
ʟUpdateQuit→UpdateState
End
Pause 16
Return
Lbl UpdatePlayer
If ScrollXOffset<<0
ScrollLeft()
End
If ScrollXOffset>>0
ScrollRight()
End
If ScrollYOffset<<0
ScrollUp()
End
If ScrollYOffset>>0
ScrollDown()
End
If ScrollXOffset=0 ? ScrollYOffset=0
ʟUpdateGame→UpdateState
End
Return
Lbl UpdateQuit
1→Quit
Return
However this results in diagonal movement when 2 buttons are pressed, which I don't want. So, following the tutorial I tried this code:
Code: [Select]
Lbl UpdateGame
For(I,1,4)
If getKey(I)
PlayerX+sign{I-1+°DirX}→PlayerX
PlayerX+sign{I-1+°DirY}→PlayerY
sign{I-1°DirX}*8→ScrollXOffset
sign{I-1°DirY}*8→ScrollYOffset
ʟUpdatePlayer→UpdateState
End
End
If getKey(15)
ʟUpdateQuit→UpdateState
End
Pause 16
Return
Lbl UpdatePlayer
If ScrollXOffset<<0
ScrollLeft()
End
If ScrollXOffset>>0
ScrollRight()
End
If ScrollYOffset<<0
ScrollUp()
End
If ScrollYOffset>>0
ScrollDown()
End
If ScrollXOffset=0 ? ScrollYOffset=0
ʟUpdateGame→UpdateState
End
Return
Lbl UpdateQuit
1→Quit
Return
This somehow causes the program to quit straight to the homescreen. I tried to figure out the cause of this by commenting out different lines and testing. If I comment out the lines that dealt with either horizontal movement or vertical movement and scrolling, the program executes just fine. However if all 4 lines of code are present it results in an immediate quit to homescreen. This should be impossible since the game screen hasn't even been drawn. It skips any execution of code and seems to instantly quit and I cannot for the life of me understand why. I'm really hoping that you might have some insight. I can provide the entire source so you can test it yourself if you would like.

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Converting from Prgm to App
« Reply #9 on: April 11, 2023, 08:40:43 am »
@Ki1o
You are making this way harder than it needs to be. All you need is an if-else chain like this:
Code: [Select]
If getKey(1)

ElseIf getKey(2)

ElseIf getKey(3)

ElseIf getKey(4)

End

To answer you original question, I don't see anything wrong with your logic. The UpdateState isn't initialized when you code first starts but it isn't initialized in your original code either. Beyond that, I don't know. I don't think I have ever actually used sign{} in serious code so it is possible but very unlikely that there is a bug there. The full source would be useful in troubleshooting because I don't see any problems with what you have. I'm not sure what you are doing with UpdateState in general. Are you are trying to make some kind of state machine? I would avoid that if possible as state machines like that can be way harder to debug than Goto spaghetti. (Source: I do that for a living)
I did notice the line 'PlayerX+sign{I-1+°DirY}→PlayerY' That PlayerX is either a typo or a bug.


A quick code critique:
In both this snippit and the code on GitHub, I noticed that you tend to over complicate logic and rely heavily on indexing into arrays. Both are great ways to spend 80% of your time debugging. Here is how I would write movement code. I have a bit more code than your example but I am doing more checks.
Code: [Select]

1→°KDown+1→°KLeft+1→°KRight+1→°KUp .add some constants for the arrow keys. In my code I define every key like this. Now, I don't have to remember that 2 is left, I just type °KLeft
15→°KClear

Lbl UpdatePlayer

getKey(°KClear) or Quit→Quit .getKey returns either 1 or 0. I use 'or' so as not to set Quit to 0 if it was 1 when we got here. This should be moved to the main loop since it isn't player related code.

If ScrollXOffset
If >>0
ScrollRight()
ScrollXOffset--
.-4??PlayerX++ .If you want to make PlayerX change on the boundary of tiles instead of when movement starts, you can uncomment this and remove the PlayerX++ from the getKey block below
Else
ScrollLeft()
ScrollXOffset++
.+4??PlayerX--
End
Return .Don't let the player push keys during scrolling
ElseIf ScrollYOffset .Doesn't need to be an else-if (because of the Return in the line above) but it doesn't hurt anything and makes the intent clearer
If >>0
ScrollDown()
ScrollYOffset--
.-4??PlayerY++
Else
ScrollUp()
ScrollXOffset++
.+4??PlayerY--
End
Return
End
.If execution makes it here, both ScrollXOffset and ScrollYOffset are 0. The screen isn't moving so it is safe to pick a new direction

.getKey(num) commands are very quick. Don't be afraid to check the same key multiple times if it makes your code cleaner. It *is* possible that the key state changes between checks but unlikely. As long as you keep that in mind, it is totally fine to do.
If getKey(°KDown) ? getKey(°KUp)-1 .getKey(°KUp)-1 is the same as getKey(°KUp)=0. Checking both keys makes the player not move if up and down are both held. It is a preference thing and not needed if you don't like it
If Walkable(PlayerX, PlayerY+1) .Or whatever check you use to see if the player is allowed to walk into a given tile. I check this inside the if-else chain so that the walkable status of a tile doesn't impact what direction the player is moving.
PlayerY++
8→ScrollYOffset
Goto UpdatePlayer .This is optional. Without it, the player will spend one tick standing still for each tile they move, making movement seem slightly jerky on an actual calc
End
ElseIf getKey(°KUp) ? getKey(°KDown)-1
If Walkable(PlayerX, PlayerY-1) .You don't check for collision in your code. I assume that will be added later? If it doesn't apply, just remove the 'If Walkable' statements
PlayerY--
-8→ScrollYOffset
Goto UpdatePlayer
End
ElseIf getKey(°KRight) ? getKey(°KLeft)-1
If Walkable(PlayerX+1, PlayerY)
PlayerX++
8→ScrollXOffset
Goto UpdatePlayer
End
ElseIf getKey(°KLeft) ? getKey(°KRight)-1
If Walkable(PlayerX-1, PlayerY)
PlayerX--
-8→ScrollXOffset
Goto UpdatePlayer
End
End
.I only did a couple minor optimizations in this example since my goal was readable code. There is quite a bit that can be done with this code but that is left as an exercise to the reader.

Return
I'm still around... kind of.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: Converting from Prgm to App
« Reply #10 on: April 11, 2023, 03:07:29 pm »
I am making a state machine for the game, and yeah... I was trying to be... efficient? I was trying to find a way to avoid repeating the same code and I wanted to see if there was a different way instead of using If for each key. I don't know why I also didn't think of simply using If...ElseIf instead. I guess I was fixated on making this specific solution work.
The main game loop itself is pretty simple:
Code: [Select]
Lbl Main
Init()
Game()
Return
Goto MAINEND
Lbl Init
0→Frame→Quit→ScrollXOffset→ScrollYOffset→PlayerX→PlayerY+6*8→MapX→MapY
°TileMap→Map
DrawMap()
ʟUpdateGame→UpdateState
ʟDrawGame→DrawState
Return
Lbl Update
Frame++
(UpdateState)()
Return
Lbl Draw
(DrawState)()
Return
Lbl Game
While 1
Update()
Draw()
EndIf Quit
Return
The idea is that Update and Draw are called every frame which then calls their respective "State" function for that frame. This is opposed to the logic in my code on GitHub where technically, I was doing all of the scrolling within the span of a single game frame. This way, every update and draw call game happens on a per frame basis.
Since I was just working on the movement I haven't added any collision checks yet but I will. I'm also all for code critiques. Honestly, some of my code is a little... weird because I'm also a student so every new CS concept I learn I try to see how it would be done in Axe, resulting in a lot of... pasta

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Converting from Prgm to App
« Reply #11 on: April 11, 2023, 06:43:06 pm »
@Ki1o
State machines are efficient and there is nothing technically wrong with your implementation. They just get complex very quickly and unless very small or very carefully documented are very difficult for your future self to come back and debug. If you can deal with that, there is no reason not to use them.
I wouldn't worry at all about optimization. Heavily optimized Axe code is very difficult to read and that is the last thing you need when you are still learning. Besides, heavy optimization is usually only worth at the most a 20% speedup unless the code is especially inefficient. You will usually get much more significant gains from reorganizing logic - which is easiest if you have clean code.

When I was learning how to program I messed around a lot like you. I have thrown away far more code than I have kept but learned a lot from it - hence the signature below my avatar! Also, re-implementing concepts in Axe is a really good way to understand them. If you can write it in Axe, you can do it any language.

If you are interested, I can send you the source for a real-time strategy game I programmed in Axe. Here is some screenshots. You will need an 84+ SE to hold all the source and the compiled code and I use several custom axioms. It will be quite difficult to follow the flow of execution (although individual features shouldn't be awful)
I'm still around... kind of.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: Converting from Prgm to App
« Reply #12 on: April 11, 2023, 07:07:17 pm »
@E37 Oh man that RTS game is very very nice. I'd love to check out the source. Is the game running at 6MHz? If so how did you squeeze out such performance while handling grayscale? If not, its still very impressive. I'm also curious about the font. Is that your text axiom? Either way I am definitely interested in learning more.

Offline E37

  • LV6 Super Member (Next: 500)
  • ******
  • Posts: 358
  • Rating: +23/-0
  • Trial and error is the best teacher
    • View Profile
Re: Converting from Prgm to App
« Reply #13 on: April 11, 2023, 08:37:49 pm »
@Ki1o

The game runs at 15MHz but that is mostly because of graphics. Without drawing, the game could easily run at 3MHz. If I wrote everything in assembly, I could probably get it in its current state to run at 6MHz but it relies on other hardware features of the TI-84+ so it will never run on an 83. Compiled, it is over 100k of executable code. Does the 83 even have that much flash? I guess I could compile the game as an OS but that is way too much work.

The font is my text axiom. You can do the same thing with the built in Text command but that requires a font hook which requires some Asm work. Axe normally just calls TI-OS's text drawing command which is why mine is so much faster.
I'm still around... kind of.

Offline Ki1o

  • LV4 Regular (Next: 200)
  • ****
  • Posts: 119
  • Rating: +5/-2
  • Doing my best...
    • View Profile
Re: Converting from Prgm to App
« Reply #14 on: April 11, 2023, 10:53:14 pm »
@E37 I really need your help. I think I'm close to approaching my wit's end with Axe as a whole. This may seem sudden, but I am continuously running into issues that I simply cannot explain or find a cause for. At this point it is probably safe to assume that the language is bugged in some way or maybe I'm just bad with it. So I'm hoping that you can help me one last time. I was feeling really optimistic earlier, but it seems I can never make any progress on this project without problems. I'll try to explain what I'm experiencing. Right now, all I have is the simple game loop I posted earlier and the Update code along with the tile map code and a single draw function. I took your advice about the input code and optimized to something that worked and I liked. However, adding any more code to this project now seems to break it. It doesn't draw to the screen, it simply quits and says done. I'm going to attach the source so that maybe you can test it whenever you get a chance. The thing that broke the code is anything that I added dealing with changing direction. Which is very trivial and shouldn't break anything, but it does. So please, please help me make sense of this. What am I doing that is so wrong?