My goal is to make the sans boss fight at half the resolution of the original game at 30 FPS. It's all written in EZ80 asm.

So far I have the box collisions and the red soul done. The other sprites on the screen are just static for now.

GitHub Repo
This is a fun idea, and importantly I think it's very achievable! People often start very ambitious projects (at least one person has said that want to make a complete Undertale clone) and fail to deliver anything, but this seems like it can capture the feel of its inspiration while not being too hard to implement.

Pity it's not feasible to add audio though, since Undertale's music is a big value-add.
If I keep working on this, I probably could get it finished in 1-3 months is my guess. I only picked this because I felt I could do it.

Quote:
Pity it's not feasible to add audio though, since Undertale's music is a big value-add.


Unless I want to learn how to use the experimental USB drivers and even then it probably would be very slow. Audio sadly is impossible.
I mean, you can always just play megalovania on your pc or something.
I could, but what fun is in that?
ThePinkHacker wrote:
I could, but what fun is in that?
Words to live by. Best of luck with this!


The gaster blasters are gonna take up some space.



Also, I can now rotate sprites. I'm opting for build-time rotations instead of run-time. This will save a lot on performance.
The gaster blasters which have 6 frames and 20 rotations end up being 376,560 bytes. I can fit that into 6 files that are just under 64 kb each.


Current status:


What's left:

  • Dialog boxes
  • UI
  • Health
  • Attacks


Added:

  • Multi-font support (the hud and comic have been added so far).
  • Karma (every second, takes away health).
  • Health.
  • Character name (could be any string).


Next:

I've been wanting to tackle attacks for a while now. I think it's time. Since the game can now keep track of time, I can start work on adding time based attacks.

This would work by having an attack and step selected. The game will run the step of the attack each frame. So for example, it would spawn some bones, then the next frame move. The game would repeat the move until it reaches the next step which could be to despawn the bones and end the attack.


I can now play a single attack. I setup a simple one that just moves a the bones around. Now I need to get multiple attacks working.

Another thing I got working this week was collisions. They do twice as much damage as a side affect of the game running at 60FPS. If someone knows a way to easily get this down to 30FPS while still being able to run code during the blanking interval, that would be really handy.
This is looking quite impressive already! It looks very fluid as well, good job on that.

This might be a very stupid idea (and I reserve the right to edit my post later to save my reputation if it is), but one way to do that could possibly be by using a flag? Every frame, you flip the bit, and then only when the bit is set (or reset), you run the extra code. So then you can end up with one thing running half of 60 fps (30) and one thing running always at 60 still.
TIny_Hacker wrote:
This might be a very stupid idea (and I reserve the right to edit my post later to save my reputation if it is), but one way to do that could possibly be by using a flag? Every frame, you flip the bit, and then only when the bit is set (or reset), you run the extra code. So then you can end up with one thing running half of 60 fps (30) and one thing running always at 60 still.


It's not a stupid idea firstly. This would work if not for some caveats.

I'm using the swap function built into the ce-toolchain. This means I have a screen and a render buffer. Each frame, it toggles between the two functions.

While the swap function does trigger the v-sync, it doesn't happen at that time. It uses a bit of self-modifying code to make it where the next render function syncs with the screen. So the timing might look something like:


  • Start of frame
  • Swap buffers
  • Game logic (runs in the blanking interval)
  • First drawing function (v-sync)
  • Rendering
  • End of frame


The problem is that I can only do one v-sync without some very unstable SMC. I haven't even gotten that to work reliably.

If I made my own v-sync routine, then this would be relatively simple to implement what you are referring to. But, I don't really understand too much about the LCD controller (maybe I should read the docs a bit more).

This would come at the down side of only being able to run game logic during one of the blanking intervals, but the game can already run at 60 FPS anyways. This won't be a problem most likely. The v-sync would block the code from running until two syncs have occurred.

If someone can help explain how to manually wait for the v-sync through the LCD controller, I would like to go that route. I hope I haven't completely misunderstood something and am causing a headache for no reason.

Edit

So I looked into the LCD Controller more. I whipped up some code to manually do a vsync. I don't have my computer with me right now, so I don't know if this works. Is this how that register works?


Code:
vsync:
    ld hl, LCDIMSC

    .loop:
        bit vcomp, (hl)
        jp z, .loop
     
    res vcomp, (hl)
    ret
I tried so hard to manually wait, but it just didn't want to work. So I resorted to a very cursed method.


  • Clear screen causing a wait.
  • Change current buffer to screen.
  • Swap buffer.
  • Wait on next draw routine.



Code:
call gfx.ZeroScreen
ld l, 0
push hl
    call gfx.SetDraw
pop hl
call gfx.SwapDraw


It works now );


Frame Rate

After a bit of semi-cursed code later, I got the game to now run at 30 FPS. This matches Undertale's frame rate. As a result of this, the correct amount of damage is applied per second.

Attacks

In the last update, I got attacks working. The game would run through a list of times and functions that would be ran every frame during that time. While this worked to make some simple moving sprites, this is far from what's needed to replicate the game.

There are two important stages of the game loop: update, and draw. The update stage is for all the code that doesn't draw anything to the screen. An example would be updating the player's position. The draw stage is where all the drawing functions are called like sprite rendering.

Right now steps of an attack are only ran during the update stage. After some refactoring, I added a second function inside a step. The first one is called during the update stage, and the second one is called during the draw stage. This not only allows the update code to change with the attacks, but also drawing functions to be dynamic.

Now that the drawing functions can be modified, I'm able to spawn and despawn entities on the screen. As can be seen in the animation above, the bones aren't always rendered to the screen.

The attack system is far from complete. Currently, there is no way to exit an attack and load the next one for later. At the moment, I'm avoiding the issue all together by exiting the game. This issue will be my next focus.

As the attack system is maturing, the possibility of recreating the first attack is looking more likely…
You could save certain data like position or health to a list and then close it and then when it’s opened you just load the data from the list?


Clipped drawing routines now only render within the attack box. This makes it relatively simple to clip any sprite to within the box.

I now can draw bones of any height onto the screen. I should be able to recreate the scrolling wave of bones in the first attack now.
Blast

If I want to finish the first attack, a very important issue to tackle is the GB's blast. A big white rectangle that goes across the entire screen.



This can be achieved with 2 triangles allowing the rectangle to be at any rotation.

SWOOOP

Toby didn't make the GBs just slide in normally. No… he had to make them ease out when approaching the player. This caveat lead to 3 hours of painful programming.



Next, I just have to combine these in order to make functional GB. Well, ignoring collisions…
This looks very cool! I'm glad to see some Undertale stuff making its way into the calc world.
Wow, very impressive! Would it be possible to get a prototype of this to show a friend? I'll use it on CEmu in case it bugs out.
RubiusTwon wrote:
Wow, very impressive! Would it be possible to get a prototype of this to show a friend? I'll use it on CEmu in case it bugs out.


The code is hosted on GitHub. Here is the repo. The latest semi-stable commit is 1fa89be. It requires Rust, Cargo-Make, and FASM-G.

If building the project yourself is unfavorable, then I would be able to make send you a build myself.
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 2
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement