Weber's Rants (tutorials)

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Weber's Rants (tutorials)

Post by Jubatian »

Huh, sorry being a bit late!

Maybe instead of that ".", you could add some read only flag which you could set in the editor once you don't want to edit a quest any more. What was a bit more annoying than the dot is that it replaced the first character, guess that was just being lazy on your part (Guess there wasn't anything to stop you from writing ".ORIGINAL_QUEST" except for the tediousness of using the SNES controller for typing it up, didn't have a hex editor handy?).
User avatar
D3thAdd3r
Posts: 3221
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Weber's Rants (tutorials)

Post by D3thAdd3r »

I added the '.' in a hex editor to make them editable and left it. Takes far too long to type out a couple words of course :lol:

I disabled all of that stuff for now, and I kind of like it. I guess I am leaning towards putting more power to the user and have no safety mechanisms has to fight. Easy enough to re-download the original data file if(would have to be purposeful really) the user decided to really mess up the stock episodes.

Got quite a bit done on the editor. You can jump in and test the screen you are editing, then jump back to the editor quickly. This is a huge improvement actually, I made a new quite long and rather challenging episode before I got that feature done, but I think it will provide quite a bit of replay value as I cannot beat it every time. Enough play testing to know you can complete every screen without being hit(except where it is purposely used as a jump boost mechanic), but doing it reliably requires very good timing. With the game being so simple, it is difficult to get excited enough to make a third episode. There is only so much you can do with the small amount of objects and tiles; better to work on that kind of stuff for an original scrolling platformer later on. Fixing up the demo recording(record a demo to the SD for the episode you create, which will cycle through the "attract mode"), and then it's done.
User avatar
D3thAdd3r
Posts: 3221
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Weber's Rants (tutorials)

Post by D3thAdd3r »

Little update, and I hope I have time today to finish the new demo code. Small things about the editor are polished, the editor is simply done now. Gameplay has of course been done for a while, and the new longer/challenging episode is also done. It should be noted the gameplay itself has many small details that are different from original, and I feel they are self evident improvements to smoothness. The only thing left, that I care about, is demo recording. I had this game "ported" within hours playing like the original just too small+no sound. All the upscaling of 30hz->60hz, 8x8->16x16, and bells and whistles, I don't know, am I over 100 hours of developing a port now?!? Need to save this from the void, as my interest is gone. I have scrapped a couple big games because I couldn't get it to where I wanted it, this is the very hardest point of development actually finishing, and it drives me nuts if things aren't just so. So I am thinking out loud, my apologies for how often you will notice me do this if you frequent the forums!

The previous versions have demo playback but only for the original episode, now I want the attract mode to be more interesting by showing multiple episodes and demos. This means the user can enter demo recording in the editor now, but it required a much more complex demo recording process. Previously I just dumped demo data to the EEPROM and manually copied it to progmem, which means you can't have user recorded demos without recompiling the whole game. Now I found the Achilles Heel to doing this to SD instead, because there is a small lag between exiting and entering a screen since it has to read the room data(happens so fast there is no lag), but then move to a different location and read a whole other sector for the demo data. The lag is not too bad, but if I allow longer demos that can cross a sector, it gets worse and looks like an ugly glitch between rooms. For aesthetics, demos can only be about 5/8 the length of the one in previous versions to fit in 1 sector. I know in the future, you can basically only do 1 sector read and still look lag free.

Anyways I hope it gets done this weekend and I can put this one to bed. This just sounds like Alter Ego demos, but it is much more difficult. At least I can re-use the code in future games, where AE code I found no re-use for because I specifically avoided this feature due to difficulty and code space :roll:
User avatar
Artcfox
Posts: 1382
Joined: Thu Jun 04, 2015 5:35 pm
Contact:

Re: Weber's Rants (tutorials)

Post by Artcfox »

That's pretty awesome! I really enjoyed playing a previous WIP version, though I haven't tried any levels past the first. It took me a few days of playing just to beat the first level.
User avatar
D3thAdd3r
Posts: 3221
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Weber's Rants (tutorials)

Post by D3thAdd3r »

I can't think of a name for a thread related to this, so I will dump it here. Essentially I am in a situation I have been in multiple times before, where I cannot achieve what is optimal;but this time I hope to do something about it. I think the fix is quite easy, it's just more what is the right way to do it so it could be a coherent makefile flag.

Here is a screenshot of my current game WIP:
current.jpg
current.jpg (56.64 KiB) Viewed 6705 times
Now this matches the NES version where the "sky" is black, but I am not doing a straight port of the NES and instead a collage of what I consider all the best features of different ports. Graphically, having the sky blue like the arcade is significantly better. I can easily do this:
possible.jpg
possible.jpg (57.66 KiB) Viewed 6705 times
Now it is obvious how short my screen is when the blue only goes 2 tiles above the ground, which is exactly enough to stay true to the NES version gameplay which has the closest matching screen dimensions(though based on the Atari 7800 6502 source code so far). I cannot make the vram taller because I need the ram, and because I am praying to blit these 72 mode 13 ram tiles with the extra scanline cycles. This would, if fast enough, allow almost no flicker with 8 enemies, fire, falling rocks, etc. I simply cannot throw away those cycles or ram for non-functional area on the screen. This would be the ideal version:
ideal.jpg
ideal.jpg (56.85 KiB) Viewed 6703 times
So basically, there are a lot of games that have a sky above, where it is just blue towards the top(maybe clouds below or such with tiles), and there is no sense in wasting all those cycles for simply a single color on the uppermost ones. So too there could be games with dirt, sand, or otherwise solid colors on the ground where it could give significant gains for cycle bound mode 13. So it would be exceptionally useful if one could specify a color besides black to set the pixel color fed to the AD725 on the scanlines BEFORE actually tiles lines draw, and also the ones after until vsync. I guess, what would the cleanest way to do this be?
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Weber's Rants (tutorials)

Post by Jubatian »

First, just a note, I see you are using a pre-UI version of CUzeBox in its normal "debug" mode. The top of the window is the end of the VSync, not the actual viewable area on a television. Even CUzeBox only displays stuff beginning with scanline 18, 225 lines (so for example Megatris is fully visible, I took that game as the standard for display size, centering and timing). You may switch to game only mode to get a better clue on how large is the actual display surface, but of course that varies wildly between TV sets (especially old CRT ones). The current CUzeBox versions have stuff shifted one scanline down (everything, that is, the sync bars on the sides too to align correctly), just mentioned if you measured anything by screenshots.

Creating vertical borders while still allowing for running main code would demand a different kernel with capability to fire extra interrupts at the appropriate times. With the solutions I used in Flight of a Dragon, possibly using an additional timer (if availabe, would demand emulation if it happens, though) I think such a border would cost maybe around 80 cycles per scanline (the timer has to be fired two times to change the PORTC output, of course both cases with a sync to timer block eliminating jitter). But it would be difficult to be done correctly (also consider that it needs to be aligned with the normal video mode graphics), and that 80 cycles could possibly be used better for adding 2 extra audio channels (inline mixer) for better sound & music.

(In general for hardware design it would have been nice if the sync pin could be driven by the timer's PWM output, although it wouldn't help generating borders)

Currently for a Mode 2 variant plan I am thinking about a different approach: the plan is to integrate the video mode with a "VSync" mixer which instead of VSync I would run in two passes before and after the display, in sync with the timer (and video signal). This would allow for extra vertical borders during the execution of the mixer code for about 12-16 scanlines (considering several channels to mix). Anything else would be quite difficult to accomplish, there isn't many deterministic chunks of code in a game apart from video generation and sound mixing which you could weave in a video synchronized code.
User avatar
D3thAdd3r
Posts: 3221
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Weber's Rants (tutorials)

Post by D3thAdd3r »

Jubatian wrote:(In general for hardware design it would have been nice if the sync pin could be driven by the timer's PWM output, although it wouldn't help generating borders)
I think Alec was considering that years back, but the Fuzebox was already released with the current design so it was locked in.

Yes I am really bad about keeping up and building new versions. On Linux it's a lot easier for me to keep up with builds, as CUzebox has replaced Uzem for my needs. The game itself only needs 26 tiles high, and the NES put out 240 lines which who knows how many were shown on a CRT. First design decision I always make is how short a screen I can get away with until it becomes too much compromise.

I could be wrong I guess, and I probably wouldn't do a hacked mode 13 just for that when it introduces possible extra maintenance. If it costs cycles then it can't work for this. In my mind this wouldn't really cost cycles or ram from the main program because there wold be a compare immediate with the scanline counter, and anything above the first tile line would put a defined color at the end of HSYNC, instead of the normal black on PORTC. Then for those lines above what is rendered it returns control to the user program as normal to get the 1440 cycles free.

I thought this is ok, but I might have to look again what periods there needs to be 0 on PORTC to do HSYNC correctly. I thought it would be less than 8 cycles cost, but I will hash it out and try it on real hardware. I did some experiments a while back with Uzem (not all verified in hardware) that might have given me wrong ideas about what works on a real television. In this case I would give up noise channel since the original game does not use it, and I still mean to fit the UART code in there for this one.
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Weber's Rants (tutorials)

Post by Jubatian »

The problem is that the video timing doesn't work that way: in lines outside the video frame nothing is written to PORTC, it just keeps holding the last value written which is black. The normal timing is roughly as follows (by the original unmodified kernel, Mode 3):
  • TCNT1 = 0: Timer 1 IT triggers.
  • TCNT1 = 104: HSync is driven low by interrupt code.
  • TCNT1 = 240: HSync is driven high by interrupt code.
  • TCNT1 = 400: First pixel is output on PORTC.
  • TCNT1 = 20: Zero is output on PORTC (400 + 1440; timer wraps around at 1820)
Of course this isn't exactly this way, just to get the idea. Within the video mode the IT is disabled, when the video frame entry is performed, the line on which the entry happens is "wasted" without producting pixels (for example Mode 74 uses this to set up the palette buffer), and only subsequent lines contain actual render.

In a normal HSync interrupt (no video frame, just a plain empty line) the first three steps are necessary, driving the sync happens within the inline mixer code. If the inline mixer contains the minimal 3 wave + 1 noise channels (by the normal kernel) you get some 280 cycles taken away per scanline from approx. TCNT1 = 0 to TCNT1 = 280. If you wanted a border aligning with normal Mode 3 output, you would have to write zero onto PORTC at TCNT1 = 20 (this is impossible even with Flight of a Dragon's syncing method), and the desired border color at TCNT1 = 400 (Either takes away 120 additional cycles or needs a new interrupt).

With the normal kernel so it is totally impossible to get such a border as the location where you needed to clear PORTC is at an "unreachable" location by timing. With Flight of a Dragon's timing you would have something like this:
  • TCNT1 = 0: Timer 1 IT triggers.
  • TCNT1 = 36: HSync is driven low by interrupt code.
  • TCNT1 = 172: HSync is driven high by interrupt code.
  • TCNT1 = 332: First pixel is output on PORTC.
  • TCNT1 = 1772: Zero is output on PORTC.
With this you would be able to reach the location to clear PORTC in a separate interrupt. So to get the border (using a different timer) you would have to generate two interrupts, one for setting PORTC at TCNT1 = 332, and one to clear it at TCNT1 = 1772, and this would be about the fastest solution (taking the aforementioned ~80 cycles).

Cycles may be off by one or two, I just wrote up most by memory and some quick checks in the code, but vaguely the elements are there. Hope it was understandable. Of course if you don't care about getting a nice aligned border (assuming it will be off-screen) you could possibly get away with only blanking PORTC to the duration of the HSync which you can arrange to be within the normal HSync interrupt. But that would even violate NTSC timing (as the blanking has to be wider than the sync pulse), the AD725 might hide it though (it possibly should as it generates the colorburst), but on an EUzeBox it wouldn't work if the TV was picky.
User avatar
D3thAdd3r
Posts: 3221
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: Weber's Rants (tutorials)

Post by D3thAdd3r »

Thank you for the detailed explanation!
Jubatian wrote:the line on which the entry happens is "wasted" without producting pixels (for example Mode 74 uses this to set up the palette buffer), and only subsequent lines contain actual render.
This one has been talked about before, for reading controllers or something else deterministic that might work across nearly all video modes. I always want more build switches, so I really wish one could supply user code with an exact cycle count to include in there. Hell, I wish you could override different parts of the HSYNC period with user code as an option too. The way it is now, to do much of a tweak you basically need to call it a new video mode. I guess you could override some of the default source files or so...I am digressing here...
Jubatian wrote:But that would even violate NTSC timing (as the blanking has to be wider than the sync pulse), the AD725 might hide it though (it possibly should as it generates the colorburst), but on an EUzeBox it wouldn't work if the TV was picky.
Ok so this part is where I assumed some "magic" happened. I do not know how much of HSYNC is done by the AD725 or if it shapes it at all. I doesn't even seem that easy to just hook a scope up and see if it just passes through unmodified timing from the '644. Well, at any ends it might just be too much for such a small detail which would be time better spent on something else.

BTW FoaD...phenomenal, all I will say for now.
User avatar
Jubatian
Posts: 1561
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: Weber's Rants (tutorials)

Post by Jubatian »

Yes, the AD725 quite possibly does some shaping on the thing, but you should always keep EUzeBox in mind, that it produces RGB video directly as-is to a Scart, so you should adhere strictly to the proper timing so it works well everywhere (not to mention that you can get the best quality using EUzeBox due to the direct RGB output if you have anything to accept that).

The user HSync is actually a quite good idea, could be very useful for people willing to write some cycle-counted assembly to get special video arrangement for their games. Even Flight of a Dragon could possibly get away with less RAM usage with such (the sky there requires the Colour 0 replace feature which eats away at the very least so many bytes like how many visible lines you have). With Mode 74 a year ago I rather went for packing it with lots of features using all the HSync I had (in FoaD currently I have 1 cycle (!!) free with the modified 5 channel volume ramping inline mixer I am using), this makes the mode usable from plain C, but at the cost of making it very very complex. Possibly for some throwing all that stuff out and offering an user HSync block instead would work better, so you could build specific codes for your screens.

(Maybe I will try to get such a Mode 74 variant done, although then possibly the current Mode 74 will see no usage, just being too complex to be easily understandable)
Post Reply