WIP - Castlevania Demo!

Use this forum to share and discuss Uzebox games and demos.
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Castlevania Demo!

Post by uze6666 »

Cool, I'll get that figured out as soon as I can.
No hurry, I'm also pretty busy on other stuff right now. More I think of it, more it make sense to use an already existing, dedicated CV level tool. I'll dig you code shortly and refactor my code to use the new map format.
It would be very neat to have multiple members working in parallel. Probably difficult to do and organize right now, until data formats are totally decided, but at some point maybe you could put out a "To Do" list so people can start moving. I'm sure some artists would be very useful for graphics refactoring for a new look and lowering ram tile requirements for sprites.
Yeah, can't agree more. Though, getting started in not the real challenge, it's more having it going and finished...we have many programmers, what we need a good project manager. Yep, sometime, they *are* useful! :lol:
User avatar
schepers_cp
Posts: 125
Joined: Tue Feb 04, 2014 9:48 pm
Location: netherlands
Contact:

Re: WIP - Castlevania Demo!

Post by schepers_cp »

i know this is a huge sort of bump, but is there any more progress on castlevania? :)
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: WIP - Castlevania Demo!

Post by uze6666 »

Two years already! What a shame... :oops: Unfortunately no progress, I stopped when I realized I would not have enough ramtiles for a decent amount of sprites. Simon Belmont and his whip already takes most and that didn't leave enough for the enemies. I was supposed to work into some better sprites rotation/flicker approach. Lee, did you have something on that?
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: WIP - Castlevania Demo!

Post by D3thAdd3r »

Yeah this is very tough to do right now. Essentially you have to break ground at every step to handle the stuff no one has ever done yet, which is really all the hurdles that has kept anyone from making a full and complex scrolling game. The sprite requirements here are higher than a Mario type game too..my main thought on that is "...'dat whip!? :shock: "
I believe this can be done and turn out amazing, and I also believe the engine that does so immediately makes a plethora of scrolling games possible. Mario for instance, would probably not be as tight of a squeeze on resources. Partitioned sprites are really a must for any of this I'd say. It's a modest 10-15%+ gain, but we are taking about stuff on the extreme edge of possible at this point; right where most of us enjoy it!

So I did think up a new theory on what the best sprite rotation system would be. Of course it ends up being semi-complicated and cpu intensive but I think it will help considerably. The main concept is that some sprites are more important than others and additionally that some parts of those sprites are more important. Basically each 8x8 sprite can take up to 4 ram tiles, but often times there is just a couple pixels or none actually drawn on the ram tiles where the sprite simply went over the 8pixel boundaries but that part of the sprite is blank. The concept could work a couple different ways, 1 requiring significant overdraw on ram tiles(that is blitting higher priority stuff on top of stuff we had already used that ram tile for), and the other being a multi-pass approach on blitting in ProcessSprites().

The first approach I question whether we would have the cycles available, but basically BlitSprite() returns how many non-clear pixels were drawn on the ram tile just drawn and we keep track of that number(to save stack/ram space, put it in ram_tiles_restore since we will have already restored everything at that point?). When we run out of ram tiles but are still in ProcessSprites trying to draw stuff, we draw it to a reserved ram tile and calculate how many non-clear pixels where drawn. We scan through the list again looking for ram tiles where less pixels where drawn, and if found we simply copy from that reserved over that ram tile. Then at the very least we have maximized the number of actual sprite pixels drawn, and don't have a bunch of mostly empty ram tiles which happens constantly in these games currently. Somewhere at the end we make sure to use that reserve ram tile too :) Might be a more clever way to handle the details but I haven't had time to explore it.

The second approach is a different modification to ProcessSprites(). Where normally we try to handle drawing up to 4 ram tiles for each sprite, we instead will only draw 1 of them on the first pass. We will end up making 4 passes through all the sprites this way. For each sprite in the sprite tile table, store 4 numbers. These number indicate which parts of the sprite are more important. We calculate this imagining that the sprite is evenly crossing 4 ram tiles, this works because we just look and say oh this is the back of simons boot. The least important part is the very back/bottom and it will be commonly drawing just a few pixels. Simon's head of course would have maximum priority for every quadrant because it would be very obvious when that flickers. In cases where only the x axis was off alignment we would add the upper left and lower left together and draw it the first pass, the second pass will fail because there is no lower left quadrant if it's aligned on y. Likewise for the right side to calculate its priority. The reason for that is that a sprite that is aligned on at least 1 axis is much more certain to not be wasting ram tiles on just a couple pixels. Of course the same way for the y axis and yes I know this sounds like a headache in the form of a rather late night poorly edited explanation. I think just a mental experiment by anyone, which is all I have done yet, shows that it will have a noticeable effect though.

A third possibility would be to combine those methods if cycles permit. Partitioning + Advanced Sprite Rotation, I feel comfortable in saying we could have 25-35% more perceived sprite pixels on screen that we are used to seeing given the same amount of ram tiles. I did a write up on some of my thoughts on the subject and went a little overboard. It's in my wiki rants. The actual sprite rotation I don't have the details hammered out on, but I will write it up and test it out when I get a few backlogged Uzebox tasks done. I think with a couple guys teaming up we could really advance scrolling on Uzebox. I volunteer for the work on the sprite rotation, another big issue is can we scroll from the SD card?
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: WIP - Castlevania Demo!

Post by uze6666 »

I have a lot of catchup up do to on the wiki to fully understand you last post! :oops: I'll read all your articles on partitioned sprites and come back!
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: WIP - Castlevania Demo!

Post by D3thAdd3r »


Maybe not that related to the Uzebox remake, but I found this and it seems pretty awesome! Usually I do not like 2D->3D remakes very much, but this one is really cool if for nothing else than how much lighting adds to a game like this. If not that, then that whip effect...damn satisfying sound!
User avatar
L4rry
Posts: 242
Joined: Sun Dec 28, 2014 7:19 am
Location: Cape Town, South Africa

Re: WIP - Castlevania Demo!

Post by L4rry »

How did I miss this game growing up!?

Got myself a nes mini over the weekend and started playing. Three levels in and I'm hooked.

Looking forward to seeing this materialize on the uzebox someday.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: WIP - Castlevania Demo!

Post by nicksen782 »

It is rather impressive! He even put the screen transition when opening the big doors. And to think, this demo was done in 2012.

I think an issue that is holding some games from the Uzebox is how MapSprite2 and MoveSprite work. When you do a MapSprite2 you have to specify what sprite number you start at. Then, for instance, if your spritemap has a 2x2 tile map then 4 sprite numbers would be taken (and in order.)

All sprites must be contiguous. These two functions are just helper functions. As said before, by Uze, (likely while thinking about this game and the whip) that you will need to create a more specific helper function in some cases. I'm working on another game right now that could use something like this where a tilemap (dynamically created, using vram tile ids) would do what MapSprite2 does but based on the vram id it will detect if the source is a ram tile or not and then set that flag accordingly. In my case, I would make the tilemap array by copying parts of vram. vram ids less that RAM_TILES_COUNT are ram tiles (it can be slightly confusing but if you remember that rule then you are good.) Any vram id >= RAM_TILES_COUNT is a flash tile.

Also, sprites CAN be sourced from RAM. (SPRITE_RAM flag set on the sprite, SPRITE_RAM_ENABLE set in the Makefile). I have actually tested this and it works just fine but it is expensive ram-wise. All tiles in the sprite map would need to come from the same source with MapSprite2. However, it does not appear that the kernel actually requires this when drawing. It just looks at the sprites array, checks the flag and reads from where that tile indicates the source is.

If sprite numbers could be non-contiguous then we could re-use sprites out of order (wherever there is a free spot.) Again, I don't think the kernel really "cares" if a sprite is part of a sprite map. It just draws what is in the sprites array.

So, I'm doing that for a game I'm working on and it is very likely that a similar technique would need to be done with Castlevania. Especially if you want enemies.
User avatar
danboid
Posts: 1937
Joined: Sun Jun 14, 2020 12:14 am

Re: WIP - Castlevania Demo!

Post by danboid »

User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: WIP - Castlevania Demo!

Post by Artcfox »

danboid wrote: Thu Feb 09, 2023 12:58 pm https://youtu.be/cghpNmyrtSk
Interesting, though I've never played Castlevania, so I feel it's mostly lost on me.

Your post did make me read through some of the other comments in this thread, and I realized that a lot of what was discussed about advanced sprite rotation is stuff that I recently implemented in my WIP game engine. I'm not using MapSprite2/MoveSprite, instead I'm using the blitter directly with Lee's idea of partitioned sprites, and my priority system reserves the ram tiles (without wasting time blitting) for the main character up front, and then blits the rest of the objects in a striped manner, so an object taking up 4 ram tiles will get only one of its ram tiles blitted before blitting a single RAM tile from the next object. That reduces the chances that an entire single object will not be drawn in any given frame. And I go one step further. Every time I run out of RAM tiles, I reverse the order of the draw list and then rotate all the objects that got drawn in the middle of the draw list (likely drawn on both even and odd frames) towards the beginning and ends of the draw list, and rotate the stuff that got drawn at each end of the draw list (that was drawn on just an even or odd frame) toward the middle of the draw list so the flickering gets spread evenly across the round-robinly assigned RAM tiles of each non-main character object instead of just being concentrated on all of the RAM tiles of just a few objects that were unfortunate enough to be at the beginning and end of the draw list. With this system, the main character will never flicker, and you get to choose whether it is drawn at the bottom of the Z-order, or at the very top of the Z-order. With all of Jubatian's improvements to Mode 3, you can easily use 32 RAM tiles without running out of CPU time blitting them all, and you still have a decent amount of RAM leftover for a game.

I've already proven to myself that it's possible to stream level data in from the SD card while scrolling with my previous demo, so I'm hoping that once I combine everything into a single game engine (we will likely need kernel support for doing some SD card stuff during HSYNC, even if it's just stupidly clocking out the leftover unneeded bytes in a single sector), that we can push the state of the art for mode 3 with scrolling enough that someone could do a large-scale game like Castlevania.

Does anyone who is really good with ASM stuff want to help me with the clocking out of bytes until the end of the sector from within Mode 3 HSYNC? I think it's doable, since it's not going to be an entire sector, only the leftover padding bytes so we can be ready to queue up another sector read by the next frame. Another option would be to try to cancel the previous sector's read, but from my previous experiments when I tried that it that took longer for the card to become ready again than it did to just blindly clock out the remaining bytes, though I think that's what CunningFellow does in Tornado 2000, so I'm not totally discounting the idea, but I think there are differences between cancelling a single sector read versus cancelling a streaming read.
Post Reply