Jump to content

NRV

Members
  • Posts

    444
  • Joined

  • Last visited

  • Days Won

    2

Posts posted by NRV

  1. Nice changes in your version.

    You already have music and sound effects.

    Is kind of funny seeing Bounty Bob destroyed by a laser :)

     

    Your moving platform seems to work well. It would be nice if you can make the movement "per pixel" instead of "per char" (for the player and the platform).

    One way could be having 3 more chars per side (6 in total) with the different offsets for the platform left and right sides.

    Or having 2 special chars per platform, for the left and right borders, and you update the content every frame.

    All this assuming the middle section of the platform doesn't have a visual pattern that also needs to be updated.

    Other option could be using player/missile graphics, but then you need special code to check that collision.

     

    Don't know how you made the player move with the platform, but if I were to implement moving platforms I probably would put the player in a special state, or maybe save the "id" of the platform where the player is walking, and later add any delta movement of that platform also to the player.

     

    Also, probably it would be better if you define now ladders with two chars, the left and right sides, so you can lock the player horizontal position to the center of the ladder.

     

    Having swimming and climbing animations would be great :)

     

    Vertical Blank Setup

     

    In the InitHardware section where I assign the initial FONT address along with the Display List and PM address I included the following setup for a simple VBI.

     

    ldx >#VBIHandler

    ldy <#VBIHandler

    lda #$07

    jsr SETVBI

     

    Then I set the following:

     

    lda #[NMI_DLI + NMI_VBI] ; enable DLI's and VBI's

    sta NMIEN

     

    Then after that any VcountWait 120 statements are commented out as not to interfer with the VBI's

     

    Vertical Blank Routine

     

    VBIHandler

     

    jmp XITVBI

     

    When I run this code the initial screen draws and the player draws but then it freezes. When I hit F8 in the emulator the disassembled code is pointing to a BRK.

    Yep, when I told you that I changed the NMI handler that also means that the OS rom is disabled in my version, so probably your "jsr SETVBI" is going nowhere.

    I think I didn't use the ram under the OS so probably you can switch it back, or never disable it (look for the macro "DisableOperatingSystem").

    But if you only need it to set a VBI you could also call your code where I told you before, inside the bottom DLI (maybe you would need to save the X register also, and restore it later).

     

    Regards.

     

    (Damn.. all this time and I never saw that there was a missing "t" in the title :D)

  2. I haven't looked at your changes, but in my original version I change the NMI handler to point to the only DLI, and the VBI is not enabled.

    You can put your code inside that DLI if your only interest is doing some changes once per frame (like calling RMT's update).

    Is there a xex with your changes in there?

     

    I don't think you want to play digital sound, so forget about wav's for now.

  3. Is that understanding correct?

    And why set 1.79 MhZ/16 bit and then keep the high value of the divisior at 255? More linear results? Or is the CPU simply to slow to set lo/hi of the frequency fas enough?

    I have the same doubt about the setup. Probably Phaeron and Xuel can explain it better.

    I would need to see some graphics to really understand how this technique works x)

     

    Beyond 109, the pulse doesn't occur before the next scan line resets everything again with STIMER. The effect is that you get clipping.

    Yep, I assumed 114 cycles for a scan line, without the 4 cycles for the next STA STIMER (110 different values, range from 0 to 109 for every sample).

    For my 31KHz experiment I used 57-4 = 53 different values.

     

    Can you reupload those pdm stuff with .car extension, so I could test it on Ultimate Cart? Thanks in advance! :)

    Sure. I was waiting for people checking on more hardware, for the correct setup values.

    Right now my previous PCM4+4 examples (ex PDM) only work in Altirra.

    But it seems the values found by Phaeron are good to go (X=3, Y=5).

    So here are the previous PDM examples converted for real hardware and also in .car format:

    pdm_carts_rh.zip

     

    At least in Altirra 3.10 test24 they should sound bad for now (with noise).

     

    The PWM examples in the thread, already have .car files included.

    By the way I generated the .car by saving the .bin from inside Altirra (with "Save Firmware").

     

    Regards.

    • Like 3
  4. Nothing fancy I think..
    I normally start with a 44KHz or 48KHz wav file.
    Sometimes I take a look at it with Audacity and apply a Normalize effect there.
    But in general I use a sox command like this:

    sox --no-dither --norm song.wav --type raw --encoding un --channels 1 --rate 15720 --bits 8 song_ntsc_15k.raw
    or:
    sox --no-dither --norm song.wav --type raw --encoding un --channels 1 --rate 15600 --bits 8 song_pal_15k.raw

    That means no dither, default normalize level (could use also --norm=2, or --norm=3, if you want more volume and don't mind some clipping), generate a raw file without headers, unsigned numbers (0 - 255 in this case), mono, the specific rate for your project (one sample per scanline in this case, ntsc or pal), and 8 bits depth (one byte per sample).

    You can use the same kind of command to generate a wav file, if you want to look at it with Audacity:
    sox --no-dither --norm song.wav --type wav --encoding un --channels 1 --rate 15720 --bits 8 song_ntsc_15k.wav
    For example to see if you are using the full amplitude range.

    Other rates I have used for my ntsc examples: 7860 (every two scan lines), 21013, 31440.

    In my final experiments I was using the rate command as an effect, because you can use more parameters like this:
    sox --no-dither mix2.wav --type raw --encoding un --channels 1 --bits 8 mix2_15k_ms.raw rate -m -s 15720
    It would be better that you read the Sox documentation for the explanation of the "-m -s" parameters, but after experimenting with the quality settings that was the option that sounded better for me.

    I also experimented with the compand command:
    sox --no-dither song.wav --type wav song_amp.wav compand 0.3,1 6:−70,−60,−20 −5 −90 0.2
    This one, with the same parameters, is explained in the documentation.
    It's a kind of "normalization" but can apply different levels in different parts of the song.

    Well, after all this you have an 8 bit song that can be directly used in the A8, with the pcm4+4 (ex pdm) technique.
    But if you wanted to use the pwm technique, for example at 15720 Hz (one sample per scanline), you need to reduce the 0-255 range to something like 0-109.
    For that I used a script in C# where the algorithm is a simple scaling like this:

    private void ByteArrayRemapRange(byte[] byteArray, int arraySize, byte minValue, byte maxValue, byte newMinValue, byte newMaxValue)
    {
     for (int i = 0; i < arraySize; i++)
     {
      float remapFactor = (float)(newMaxValue - newMinValue) / (maxValue - minValue);
      float newValue = (byteArray[i] - minValue) * remapFactor + newMinValue;
      int newValueInt = Mathf.RoundToInt(newValue);
      byteArray[i] = (byte)newValueInt;
     }
    }

    This lives in a Unity project, along other code that I use to transform data to the A8 needs, so is not exactly a useful tool right now :)

    • Like 3
  5. Updated code to play the "song 2" and the "megamix" with the PDM technique.

    Also included the 1Mb cart images for both, and in NTSC and PAL versions.

     

    pdm_carts.zip

     

    Now it plays at 15.7KHz (15.6KHz in pal), with 8 bits of depth, same memory usage as before, without the carrier tone.

    Also there is no click sound at the end, the wave fits on the screen, and it can be aborted with the start key.

    A win-win x) .. thanks to Xuel and kool kitty89.

     

    So maybe the conclusion of this thread is to not use PWM and only use PDM when possible :)

     

    • Like 10
  6. With 15KHz you can leave the screen "on" in any graphics mode probably.

    And at least in narrow playfield (32 bytes wide), with the menu "on" (the six lines of graphic 0) it sounded almost equal to me.

    First scan line of a char line is "nasty" for the timing, but it seems ok with this.. should test it more anyway.

     

    I would try to do the second song in 31KHz later, it just fit in the 1Mb cart.

    • Like 2
  7. Hi.
    I 've been doing some testing of the PWM technique to play samples (thanks Phaeron and Xuel for the examples).
    Is nothing great, but I think that maybe the code could be of use to people doing similar experiments.

     

    post-11240-0-92768700-1525486033.png

    It's for a 1Mb cart and there are two small songs only, but in different qualities.

    The options are:

    1 - Song 1, PWM at 15720 Hz, sample values between 0 and 109, a little lower than 7bit depth. "Normal" PWM quality, with one sample per scan line.

    2 - Song 1, PWM at 21013 Hz, sample values between 0 and 80, higher than 6bit depth. This is a failed experiment.. I tried to play 4 samples every 3 scan lines, but getting the perfect timing for this seems impossible, because of the refresh cycles.

    I wasn't that far off, but the small imperfections in timing are enough to add an undesired frequency sound.

    3 - Song 1, PWM at 31440 Hz, sample values between 0 and 52, lower than 6bit depth. This worked well but it eats memory x) (30 seconds max for a 1Mb cart).

    This plays two samples per scan line, the timing was a little tricky because you need to avoid the refresh cycles and also balance your worst case code branch with the rest of the code.

    The good thing is that the normal carrier frequency produced by PWM (that at 15KHz is still annoying for some people) is not an issue.

    The bad thing is that playing more samples in the same time, implies that the bit depth is lower (for PWM).. so at the end of the day I don't think this is an improvement over the 15KHz PWM.

    4 - Song 1, at 15720 Hz, sample values between 0 and 15, classic 4bit depth. This could sound better, but I didn't allowed much clipping, so maybe the volume is too low.

    5 - Song 2, PWM at 15720 Hz, same as the first option, but with a larger song.

    The 15720 Hz rate sounds perfect in NTSC and just a bit slower in PAL (there the rate should be 15600 Hz).
    All samples converted with Sox and then with some scripts in C#, to move the data to the correct range allowed by every method.
    Main code is in rtech_cart.asm, done in Mads.

    I think that using 15KHz PWM is an improvement over the classic 4bit sound, if you are playing songs without much silence (where the 15Khz carrier frequency can bother some people).

    Also you can do some simple track sequencing with the screen on, so a nice intro for a game in a 1MB cart can use this. I already have code for this, but that's coming later :)

    pwm.zip

     

    • Like 14
  8. Hi!

     

    Just a little "quality of life" update to this.. version 1.84 with some small changes.

     

    The changelog is inside the "pad.asm" file as always, but basically:

     

    - Added intro music by Miker, at the start of a level.

    - Added sound effects for losing a life, for an extra life and for picking a powerup.

    - Created a sound priority system for the sound effects.

    - Added visual effect for the open exits at the end of a level.

    - Increased mouse control min speed (at least in emulation it feels better, hope someone in real hardware can test it someday).

    - Plus other small improvements.

     

    All code included. Any feedback is welcome.

     

    Picture with all current levels:

     

    post-11240-0-07784200-1524205992_thumb.png

     

    Small video:

     

     

    Regards!

     

    Pad_1_84.zip

    • Like 17
    • Thanks 1
  9. Hi NVR,

     

    I would like to ask your permission to use your code base as part of a set of videos I am looking to put together on Game Programming on the Atari. This set of videos has two purposes, first to help me further my understanding of the code and concepts and two to hopefully invite people to join with comments and suggestions which should help others and me further our understanding.

     

    Thanks again for the great engine.

    Sure, go ahead.

     

    It's here to be used :)

    • Like 1
  10. That island deserves its own game x)

    I think you should test how it looks while moving, maybe an animated gif could be enough to see if there is any unanticipated "weirdness" going on..

    But at least the bullets should use the mask, they look a lot better that way.. and they are small, so the rendering cost should be low.

     

    Now.. if Popmilo's test don't appear soon enough, someone else could be tempted to do them :P

    • Like 1
  11. I'm on it. You want separate animation frames or palette shifting sparkles? ;)

     

    I like the falling star idea! I was also thinking of having the shimmering line-scrolling or some small birds at the end maybe, but I didn't know if there would be enough resources left.

    Haha, if you are going to do it, full animation frames would be better and more flexible :P

    Below the sun area you have 3 color registers available (you used two colors in the current sun reflection).

     

    The falling star could be done with players, in the screen area over the sun.

    The top of the sun is done with all the players at the end, so if there are small birds they should fly between the sun and the heroes (small area), or just over the sun.

     

    Also, try to use the even luminances in the 256 color palette (0, 2, 4, .. 14), if you want a direct conversion for the A8 :)

  12. I agree with both of you, but not for now x)

     

    I also wanted to do that. Doing the movement with fine scrolling should be "easy".

    Probably it would be better to merge the movement and the "sparkle" into animation frames, but someone would need to provide them to me :)

     

    At some point I started looking at sunset gif's:

    post-11240-0-13518100-1523905346.gif

    post-11240-0-82552800-1523905362.gif

    post-11240-0-25370600-1523905372.gif

     

    Other ideas: a falling star at the end, the sun setting down slowly, some stars appearing at the top of the sky, the heroes jumping from the cliff..

    • Like 1
  13. Mini development blog:

     

    The background color is changed every line with a big DLI, that starts at the top of the screen, and ends several scan lines after the bottom of the screen.

    After the section of the DLI that controls the background colors, we do a lot of other things, like playing the RMT music, managing the logic state of the demo, or resetting some registers for the next frame.

     

    There is no VBI, and the main code loop only have a "Here jmp Here" instruction.

    If you want to see how much time is available per frame, just hold any CONSOL key (and set Altirra's overscan mode to "full").

     

    Apart from changing the background colors, the "main" section of the DLI also modify other color registers, the P/M's (positions, colors and size) and the Prior register (yep, the timing was tight sometimes, so self modifying code was used in some points).

    The title and the sun graphics are done in g15 mode. A part of the sun, the heroes and the terrain are done using all the P/M's. The scrolling text is in char mode Antic4.

     

    The demo has 5 internal states:

    - The title fade-in is done changing the value of 3 color registers.

     

    - The background fade-in is done changing one pointer, so the DLI code take the background colors from a new table.

     

    - The movement of the sun is done with horizontal fine scrolling (and updating the LMS's in the display list), using a wide screen mode. At the same time the P/M's position is updated.

     

    - The movement of the title image that leaves the screen is done changing the LMS pointer for that area in the display list (no use of VSCROL here). At the same time, to avoid crossing a 4K area, or having a lot of empty memory after the image, I just start writing blank line instructions directly into the display list.

     

    - When starting the movement of the scrolling text we change the display list for another with char lines.

    Also we change the wide playfield mode to use narrow mode. This helps with the timing for the DLI, because of the badline for every char line used.

    The movement of the text is done using vertical scrolling and updating the top LMS, as usual.

    The color masks at the top and bottom are done updating the char colors. The only tricky part is the bottom mask, where you also need to change the P/M's priority per line (between been in top, and been behind).

     

    There is no pal version for now. It would mean changing the colors, adjusting the times for every part and changing the music.

    Trying to do 2 RMT's calls in the same frame could be difficult, but PAL has more time per frame. I don't know if that would sound correct.

    The only "bad" thing of the NTSC version is that the sun looks "thin", if you use the correct pixel ratio (at least in Altirra).

     

    There are a lot of comments in the code for anyone that want to take a look, but also many hard coded numbers x)

    This was a fast, "just program, don't think" job, most of the time :)

     

    • Like 3
  14. Awesome! That's great! Now for the overworld demo lol... :P

    Haha.. I was afraid you would say something like that.

     

    Hope you don't mind the small changes, most of them were forced by the hardware limits :)

    The heroes lost some weight..

     

    The one thing that I miss the most, are the subtle color changes for the background, thanks to the 7800 being able to use its 256 color palette there..

    I did what I can to not miss any detail, but in a couple of lines I had to "dither" some dark orange zones.

  15. Here are the assets for the mockup. The gradient would not actually be a stored graphic, but rather a raster effect where background color entry #0 is changed every so many scanlines. This could be tweaked for less (or more) scanline changes, depending on CPU time needs. The title logo and prologue text would be the only bg "tiles". the sun and hero silhouettes would both be sprites. Everything is in 160p, 4-color mode and using the A78 palette used by A7800 emulator.

    Hey Fragmare!

     

    Go figure.. less than a week later, someone found a port of the Solaria's intro for the A8 computers, and with source included x)

     

    http://atariage.com/forums/topic/277766-solarias-code/

     

    I'm just leaving this here.. maybe something can be useful to 7800 programmers.. (difficult, but you never know :))

     

    Regards.

    • Like 2
  16. Hi, couldn't resist doing this..

     

    Here is a port of the Solaria "teaser" done for our A8's (ntsc version only for now).

    The original palette used the 256 colors of the 7800, so it loses some of the more subtle color variations of the background, but is more or less the same.

    Also the scrolling text doesn't start from the bottom.. that maybe can be done, but it would be a pain in the ass x)

    It can be moved down right now, but it doesn't look that good starting near the sun (it loses legibility).

     

    post-11240-0-40551000-1523775737.png

     

    I used most of the assets that Fragmare posted here http://atariage.com/forums/topic/277344-sword-of-solaria-final-fantasy-style-jrpg-7800-graphicsmusic-mockup/

     

    Would post a video and talk more about the code later (source and all files included).

     

    Regards!

     

    Solaria.zip

    • Like 9
  17. Really like that mockup :)

     

    Just 4 colors because is bitmap graphics?, what would be the grey color at the top of the ship then?

    And was black not the background color just to get blue at the borders?

     

    I had my old demo/mockup with a similar idea:

     

    post-11240-0-54311600-1523500988.png

     

    Char graphics, 2 players for the player's ship and weapons, 2 players for the enemies (moving enemies or static in the terrain) and the missiles for most of the enemy shots, but probably is a little limiting (in gameplay terms) doing it like that.

     

     

    I presume we're still talking about that vertical SHMUP thingy ? That's the easiest one in terms of performance, as the only thing that needs to be 60 fps is the main player.

    All other enemies - they can run in different framerate. 30 fps, 20 fps or 15 fps. At 15 fps, the CPU has quite a huge number of cycles. Does the playfield need to run at 60 fps ? Then a screen would scroll in 3 seconds and that's a darn fast SHMUP.

     

    So, just adjust the speed of moving (of the sprites) to correspond with the target framerate and nobody will notice anything, as even at 15 fps, you are still moving sprites by 1 pixel. The only difference would be that during a second, instead of moving 60 pixels, they would move 15 pixels (e.g. just the speed is different).

     

    Granted, the complexity of having 3 different framerates may be slightly challenging from implementation standpoint, but you could start with a compromise - say 20 fps for all entities (3 NTSC vblanks) - which gives you ~60,000 cycles for CPU (minus WSYNC). You will still have the option of doubling the speed by skipping every other pixel, which still looks smooth, giving you up to 40px / second.

    I was thinking of something similar, having the full game running at 30 fps (25 in pal) to be able to do things that you don't see normally in the A8.

     

    This old demo scrolls the screen once every two frames, and I think it looks good enough:

     

     

    But thinking about your examples, I assume that we are talking about updating or not the software sprites position (or animation frame).. not just the enemy internal logic (that for me is irrelevant in processing time).

    In that case wouldn't it look a little strange if we don't update the sprite for a frame, but the screen scrolls in that frame (moving the software sprite with it)?

    If the screen didn't scroll also in that frame then all is good, but then we need them both in sync and maybe that was what you were implying..

    • Like 9
×
×
  • Create New...