Jump to content
IGNORED

Playing VGM files in XB (?)


Recommended Posts

I gave that a shot cause I was curious, and it did work well. If you combined that process with loading your biggest music file, we could write a quick additional CALL LINK that would let you overwrite it with other music files. (By picking your largest one, the XB pointers will leave enough room for any of them).

 

The gotcha is determining the patch to the player's search function. Depends, I guess - is the new REF/DEF table always at the same address? In my test, anyway, the top appears to be at FFE6, so that's the value to patch with. There are only two changes needed to the player:

 

* find the MUSIC def (might also be "music")
	li r1,>ffe6		* This seems to be top of HMLOADER space
SGLP1
	c r1,@>F000     * arbitrary, but room for 28 entries
	jl sgdn1		* done search, no luck

 

Attached is "tiSNHi" (obj and a99) so you can play with it. Tested and it works for me here. My thinking on changing the music is we write a quick little loader that searches this new REF/DEF table for MUSIC, and then overwrites it with the newly loaded data. The only gotcha will be getting it in there from TML... my test here shows only 1436 bytes of VDP free, so a normal PROGRAM loader is probably out of the question. Though... ISTR I wrote a by-sector loader for the Megademo, maybe we can adapt that. Then we only need 256 bytes of stack space for each sector to be read. So my question would be -- how do I get a safe 256 bytes of VRAM, Senior Falcon? Or is there a better way?

 

tiSNHi.objtiSNHi.a99

 

 

  • Like 2
Link to comment
Share on other sites

Thank you both again for your perseverance in helping me!  Unfortunately I haven't been able to try the high memory method yet because apparently I am missing HMLOADER from my Juwel folder...(?)  Maybe I don't have the latest version--that wouldn't be the first time :/  I  need to look into that.  So I take it then that I would just load tiSNHi.obj after loading HMLOADER in the way Senior Falcon outlined? And then the music (just to make sure I'm understanding this correctly)

 

Sorry, I'd try this out myself but I got to locate HMLOADER first.  Meanwhile I've been trying to cut my code down to get it ready to test with music.  At first it consisted of a title/introductory sequence and then sets up the first part of the game.  For testing purposes (probably permanent purposes) I've cut out the game engine so it is just an elaborate title sequence.  This cuts the file down to 10K so it should be perfect for testing with music.  Going forward at least I know to keep my program segments limited to not much more than 20K.  Since I'm pretty early into coding this thing I feel I can work inside of this limitation for the sake of having music.  As for the specific music I think for starters I'm going to stick with the tracks I posted here--the longer one at least; we'll see about the feasibility of getting both of them in there a little later I suppose (I still haven't tried combining the tracks into one SBF file yet as Tursi suggests but that's next on my to-do list).

 

 Tursi, I saw your comment about putting the music in VDP RAM and playing with the console player...  I was wondering what this is exactly as I have heard mention to it before?  Clearly this can be accessed from RXB but is this at all related to the "sound tableimage.gif.ce10cf742f3a33fdf995aeea44f3a012.gif" music that can be played from XB256?  I'm just curious but regardless, I think memory might be too tight for me going that route as I am using bitmapped graphics and some of the music is probably too complex.  For my particular needs I think we are definitely on the right track getting your VGM player working in TML.  :)  

  • Like 1
Link to comment
Share on other sites

11 hours ago, ruthven said:

Thank you both again for your perseverance in helping me!  Unfortunately I haven't been able to try the high memory method yet because apparently I am missing HMLOADER from my Juwel folder...(?)  Maybe I don't have the latest version--that wouldn't be the first time 😕 I  need to look into that.  So I take it then that I would just load tiSNHi.obj after loading HMLOADER in the way Senior Falcon outlined? And then the music (just to make sure I'm understanding this correctly)

 

Sorry, I'd try this out myself but I got to locate HMLOADER first.  Meanwhile I've been trying to cut my code down to get it ready to test with music.  At first it consisted of a title/introductory sequence and then sets up the first part of the game.  For testing purposes (probably permanent purposes) I've cut out the game engine so it is just an elaborate title sequence.  This cuts the file down to 10K so it should be perfect for testing with music.  Going forward at least I know to keep my program segments limited to not much more than 20K.  Since I'm pretty early into coding this thing I feel I can work inside of this limitation for the sake of having music.  As for the specific music I think for starters I'm going to stick with the tracks I posted here--the longer one at least; we'll see about the feasibility of getting both of them in there a little later I suppose (I still haven't tried combining the tracks into one SBF file yet as Tursi suggests but that's next on my to-do list).

 

 Tursi, I saw your comment about putting the music in VDP RAM and playing with the console player...  I was wondering what this is exactly as I have heard mention to it before?  Clearly this can be accessed from RXB but is this at all related to the "sound tableimage.gif.ce10cf742f3a33fdf995aeea44f3a012.gif" music that can be played from XB256?  I'm just curious but regardless, I think memory might be too tight for me going that route as I am using bitmapped graphics and some of the music is probably too complex.  For my particular needs I think we are definitely on the right track getting your VGM player working in TML.  :)  

I found HMLoader in my TML folder. :) It's definitely there in the Classic99 contributors folder (which may be out of date, but I expect a similar layout).

 

The console playlist player probably isn't as helpful as I thought. With only 1400 bytes of VRAM free as a baseline, you're going to struggle to fit the music there. At least you have control over the CPU memory. :)

 

Link to comment
Share on other sites

14 hours ago, Tursi said:

I found HMLoader in my TML folder.

Thanks, didn't think to check there as I don't work off the TML disk directly too often.  OK, inching my way ever closer...  Following Senior Falcon's instructions I got Tursi's player and some music loaded into high memory and playing in TML!  So that's a good start, however I cannot load anything in TML after loading this "1 line XB program" that has the music/player embedded.  Or rather, I can, but then I lose the player routines and presumably the music as well.  As a test I loaded the music in TML per instructions above and once the music was playing, tried loading my title sequence I was referring to earlier and this just crashed the system.  So then I got the music running in TML again and this time loaded a real simple program that just prints "This is a test" on the screen--this didn't crash, however the music that was already playing began to get really wonky, flat like a broken down jukebox or something :) , rather amusing actually but unfortunately not the effect I'm going for! :) 

 

I suppose this is probably to be expected, huh?  I'm guessing I overwrote some memory somewhere by loading another file...  so would the idea be to code my program within that 1 line XB program that HMLOADER spits out?  Because I did try adding some TML code there and sure enough that all worked fine.  If this is the case I will need to somehow copy over my code from my existing program into this new high memory code.  I can live with that if it gets music going in my game!

  • Like 1
Link to comment
Share on other sites

When you list that one line program, you will only see that line. But there is more to the program than that. All the data for the music player is included in that program - you just cannot list it.

Even though the program does not look like much, you have to add the lines to it. OLD DSK1.PROGRAM or RUN "DSK1.PROGRAM" will just overwrite it. The CALL LOAD in line 3 is important. You can make it a different line number, but the CALL LOAD must be performed before any CALL LINK.

 

There are a few ways to add XB lines to this program with the embedded music. Assuming your program is called TMLPROG,

1 - before you use HMLOADER, type OLD DSK1.TMLPROG. Then SAVE "DSK1.TMLPROG-M,MERGE"

Then use HMLOADER to load your music files, then MERGE DSK1.TMLPROG-M

2 - Using Classic99, before you use HMLOADER, type OLD DSK1.TMLPROG. Then LIST "CLIP" This copies the program to the clipboard. You can paste this into a text editor if you want, which lets you look at it and make changes.

Then use HMLOADER to load your music files, then at the top bar, choose EDIT, then PASTE XB.

3 - There are other tools such as Stevie or TIDBIT that let you program XB using a text editor.

 

Once you have added the lines of XB code, you can edit the program normally. When you have saved the program with the embedded music files, then when you OLD DSK1... or RUN "DSK1..." the music files are part of it and will be loaded along with the XB code. It sounds like you intend to have a number of programs, with each one running another. You can embed just the desired music needed for each program. You don't need to included unused music.

 

Whatever method you choose, the principle is always the same. First load the music files with HMLOADER, then add the XB lines to the program created by HMLOADER.

 

I would be cautious when using RESequence with embedded code. There may be sequences of bytes that RES changes because it decides they are line numbers. If you do resequence, back up your work so you can recover the XB part of the program if necessary.

 

As mentioned above, another option would be to use a sound list in VDP. There are some small areas of VDP ram that can be used. I will do some research to see if this can be done.

 

I see that HMLOADER is not part of the JUWEL package. In my next release (hopefully soon) I will be sure that it is included.

  • Like 2
Link to comment
Share on other sites

A quick test shows that you can play a sound list from vdp using The Missing Link. The real problem is that there is not a lot of room in VDP for the sound list. I found 254 bytes that might be OK to use as long as you do not load pictures or use disk access. If you do not use sprites, the sprite pattern table (256 bytes) would be available.

What can you do with 256 bytes? In my test, adapted from the XB256 demo, there is a scale that goes up an octave, then back down an octave, then repeats. This takes 86 bytes. So 256 bytes might be able to play some simple music, but there is not a lot of room there.

It would probably be better to use a custom player for the sound list that reads the bytes from cpu memory and puts them into the sound generator. It is hard to believe it would take more than 100 bytes or so for the player, and the data is already in the program as a data statement. So that might be a simpler approach.

I understand that Tursi's player is more sophisticated than the player built into the TI, so that is almost certainly the way to go. However, the player takes about 1000 bytes, and if the music data requires more memory than a normal sound list, that might be a problem for you.

  • Like 2
Link to comment
Share on other sites

Thanks so much for explaining that all out for me!  Yeah, I knew that "one line XB program" had more to it than the one visible line of code--I just kept referring to it that way so as to be clear what specific file I was referencing.  But yeah, what you outlined above was pretty much the way I was thinking it needed to work but I just wanted to get confirmation on this.  The only thing I really wasn't sure about was the initial loading of the playback routine/music--at first I figured this code would just be imported into my existing program (which is kind of the way I can do it from regular XB with Tursi's demo program).  But now I see the opposite is true for this case, which is no problem given the various methods of accomplishing this.  Thanks BTW for teaching me how the MERGE command works in this way--so far I had only been using it to compile my programs which (per your instructions) I had basically just been hitting enter a whole bunch of times! :)  Also thanks very much for informing me about LIST "CLIP"--I knew there had to be a way to do this but I hadn't gotten around to asking.  :) 

 

Yes, this project I'm working on now (and most others for that matter) will run from a bunch of chain-linked programs.  This due to the scope of it, the additional space/memory limitations when using music, and just the fact that I'm not exactly the most efficient programmer. :)  

 

8 hours ago, senior_falcon said:

It sounds like you intend to have a number of programs, with each one running another. You can embed just the desired music needed for each program. You don't need to included unused music.

Perfect, I actually did try this last night and got it working so I'm glad for confirmation that this is the proper approach.  And in fact--Tursi, this may eliminate the need for "clearing" the music data as we were talking about a while back.  I figure I'm probably only going to get a couple of tracks combined into a single .SBF at the 8k limit, but honestly, each of my game's program segments are probably going to be reasonably small (I mean play-time wise) so even just 2 tracks would probably cover it.  By the time I need a third track to begin would probably be about the time I'm loading another program segment that itself would have a couple new tracks of music embedded with it.  And the act of loading a new program naturally clears that memory out and refreshes it with new music, so this is perfect for my needs actually!

 

Guys, I want to thank you both so much for getting me to this point! :)  I'm pretty much 95% there now, and if nothing else I can at least make cool demos now with nice music and graphics!  The only thing I might check back on is switching tracks when I have a couple pieces of music in the embedded SBF (cause I haven't actually tried this yet--I know there are some instructions from Tursi above that I will give a shot but very likely I will end up getting confused about something knowing me).  That and looping the music--which I actually did figure out when I was tinkering with Tursi's XB program, so I'll probably be good there.  It's good to know the order of operations now and to have a good idea of program size limitations when making room for music.  So I think I'll leave it at that for now, at least until some specific issue comes up.  Thanks again!!

 

 

 

  • Like 2
Link to comment
Share on other sites

Sounds good! When you are combining tracks, they will share the compression with each other, so if they have any similarity two tracks together should take up less space than the two tracks individually. It's not usually as large a benefit as I originally hoped, but it's there and I use it when I have multiple songs. (When I did the Thunder Force III tribute, I actually ran a script that brute force tested every combination to see which songs compressed the best together...).

 

When you do get to that point, we'll need to change the patch code that changes which song to play, as the XB code I posted searches the wrong list. Or, probably better, we could add an argument to CALL LINK("SONGGO") to specify the song in one step. But in the meantime, the XB code in the readme needs to change like so (just the start and end addresses):

 

11000 REM FIND ADDRESS OF SONGACTIVE, SET IT IN 'ACTIVE' (HIMEM)
11005 REM THEN USE CALL PEEK(ACTIVE,A) AND CHECK A
11030 REM SEARCH TOP DOWN (HARD CODED ROOM FOR 5 ENTRIES)
11040 FOR PTR=-26 TO -66 STEP -8
11050 CALL PEEK(PTR,N1,N2,N3,N4,N5,N6)::REM CHECK NAME SONGGO (LOWERCASE/UPPERCASE)
11060 IF N1<>83 OR N2<>79 OR N3<>78 OR N4<>71 OR N5<>71 OR N6<>79 THEN 11100
11070 CALL PEEK(PTR+6,N1,N2)
11080 ACTIVE=N1*256+N2-7
11090 PTR=0
11100 NEXT PTR
11110 RETURN

--Play different index in same sound bank--
This time you can patch the actual assembly language to change the starting song index, in a multi-song bank.
This assumes a fixed offset forward from SONGGO. Again, you can cache the final value N to use repeatedly.

12000 REM PATCH SONGGO WITH INDEX IN 'I' (first song is 0)
12030 REM SEARCH TOP DOWN (HARD CODED ROOM FOR 5 ENTRIES)
12040 FOR PTR=-26 TO -66 STEP -8
12050 CALL PEEK(PTR,N1,N2,N3,N4,N5,N6)::REM CHECK NAME SONGGO (LOWERCASE/UPPERCASE)
12060 IF N1<>83 OR N2<>79 OR N3<>78 OR N4<>71 OR N5<>71 OR N6<>79 THEN 12100
12070 CALL PEEK(PTR+6,N1,N2)
12080 N=N1*256+N2+84
12090 CALL LOAD(N,I)
12095 PTR=0
12100 NEXT PTR
12110 RETURN

 

In both cases I changed the PTR loop to the hard coded address of the high memory table. This meant I could delete the CALL PEEK and math that calculated where to stop. To help performance and memory usage, I also deleted the check for 'music' or 'songgo' in lowercase. They won't get hit in any normal case and are a waste of memory when memory's tight. ;)

 

Edited by Tursi
  • Like 2
Link to comment
Share on other sites

On 3/23/2024 at 10:23 PM, senior_falcon said:

I have been working with SteveB on how to add additional A/L subs to a compiled program, and this method may work for you.

Forgive me, I'm a bit slow...  this method of getting the music working in TML that we've been discussing where I merge my code in with the high memory-embedded music program--is this just for getting it to work in regular non-compiled TML or should this method also work compiled?  I was originally under the assumption that this should compile but I had some difficulty and now looking at your above comment, I'm realizing that maybe this is something you are still trying to work out in general?  I say this because as I go through the compiling process I see the message "Put runtime in low memory?" which defaults to N.  So I change this to Y figuring I need to spare the high memory for the music that is loaded there.  Only problem is that further into the compiling process I'm informed that I cannot use additional assembly routines with the runtime in low memory.  So that's a catch 22, and if this is something you're still trying to figure out generally speaking then I'll just shut up and let you get to your thing. :)  I just wanted to make sure I'm understanding this correctly is all.  That said, don't get me wrong--I'm still thrilled to get this awesome music playing even in uncompiled TML! 

 

But just on the off chance this was supposed to compile--I'm wondering where that line CALL LINK("TML16") would go?  Since that is mentioned in the manual to be placed at the very beginning (line 1), but also you've instructed me not to place any CALL LINKs before the line 3 CALL LOAD(8192,243,028) which is in the music embedded file that ultimately gets compiled.  So I ended up trying it both ways (leaving the runtime in high memory) but both times the compiled file gave me a "SYNTAX ERROR" when run.

  • Like 1
Link to comment
Share on other sites

13 hours ago, ruthven said:

Forgive me, I'm a bit slow...  this method of getting the music working in TML that we've been discussing where I merge my code in with the high memory-embedded music program--is this just for getting it to work in regular non-compiled TML or should this method also work compiled? 

What you are doing will only work in uncompiled TML running in XB. I am still working out the details on how to make it run with a compiled program. Some minor changes must be made in the assembly code, and some changes to the compiler. This will take a few days or more to iron out. I am trying to make it as simple and versatile as possible.

As part of this effort, I am almost done making it so TML can use sound lists in high memory, which is a different approach to making music. I will post a simple program demonstrating this in the next couple of days.

  • Like 3
Link to comment
Share on other sites

I worked out most of the bugs and now can play a sound list while running The Missing Link.

Here is a simple demo that runs under TML. It does polyspirals, and while doing them, it plays a scale up an octave, then back down.

If you press any key it plays "charge" without interrupting the scale being played.

The sound list is the same format as those created by SLCOMPILER and SLCONVERT in the JUWEL package.

Now to get it to work with compiled XB and TML...

 

POLYSOUND


3 CALL LOAD(8192,255,178)
4 CALL LINK("PLAY","SCALE")
5 CALL LINK("CLEAR"):: CALL LINK("PUTPEN",92,120,0):: ANG=90+RND*180  
6 FOR I=1 TO 100 :: CALL LINK("FWD",I,ANG)
20 CALL KEY(0,K,S):: IF S=1 THEN CALL LINK("PLAY","CHARGE")
25 NEXT I
30 GOTO 5  

 

 

 

Edited by senior_falcon
  • Like 4
Link to comment
Share on other sites

20 hours ago, senior_falcon said:

What you are doing will only work in uncompiled TML running in XB. I am still working out the details on how to make it run with a compiled program.

Understood.  Very good sir, thanks!  :)  And I will give the sound lists a try as well.

  • Like 1
Link to comment
Share on other sites

Making S L O W but steady progress on this. I wrote the compiler compatible code for the sound list player 2 nights ago, thinking to test it last night.

Last night, I spend well over an hour just to get the code loaded so I could test it. And then of course, it crashed. Tonight I worked out what was wrong, and now can play a sound list from compiled XB/TML.

The good news is that it works. The bad news is that it is very sluggish.

It turns out that when I converted TML for compatibility with the compiler, I took out the LIMI 2 and LIMI 0 that were in the pixel routine. So the only LIMI's were when it returned to the compiler. When printing a long line, the interrupts don't happen as often as they should, and sounds/sprites do not get updated fast enough. Tursi's player uses the interrupt too, so that would be a problem there as well. But at least fixing TML should be easy.

Once it is working reliably, there are a number of things that must happen to make it more fool proof. And then of course, trying to document it in an intelligible way.

Edited by senior_falcon
  • Like 5
Link to comment
Share on other sites

On 4/4/2024 at 10:40 PM, senior_falcon said:

Making S L O W but steady progress on this. I wrote the compiler compatible code for the sound list player 2 nights ago, thinking to test it last night.

Last night, I spend well over an hour just to get the code loaded so I could test it. And then of course, it crashed.

Thanks very much for taking the time with all this, it is much appreciated!

 

On 4/4/2024 at 10:40 PM, senior_falcon said:

Tonight I worked out what was wrong, and now can play a sound list from compiled XB/TML.

The good news is that it works. The bad news is that it is very sluggish.

Good to know--I was in fact going to ask if sound lists could be used in TML (compiled or otherwise)... now I see it is something you are still working with.

 

On 4/4/2024 at 10:40 PM, senior_falcon said:

It turns out that when I converted TML for compatibility with the compiler, I took out the LIMI 2 and LIMI 0 that were in the pixel routine. So the only LIMI's were when it returned to the compiler. When printing a long line, the interrupts don't happen as often as they should, and sounds/sprites do not get updated fast enough. Tursi's player uses the interrupt too, so that would be a problem there as well.

Ah, that explains some of the behavior I noticed when I first got some music working with my latest TML project.  I was noticing the music slowing down as text was being printed to the screen.  I wasn't too bothered by it as I was just thrilled to have it working at all.  Also I thought compiling it might solve the issue but now I understand the issue is deeper rooted.  I also had some sprites moving on the screen with auto-motion that just stopped dead in their tracks once issuing Tursi's CALL LINK("STOPSN") command.  I was going to ask about it but clearly this must be related.  I noticed sprites still seemed to work OK once the music was loaded and playing so I've kept it really simple so far.

 

In fact I've shifted gears for now while Senior_Falcon works on the above.  I've been happy just getting a bunch of music loaded in regular XB using Senior_Falcon's HIMEM technique as it seems to load pretty quickly.  Previously I had converted all my SBFs into self-loading looped music with Tursi's QuickPlayer.  I then converted the EA files into XB loadable files with some code I found on this forum (EA2XB) so they could all be loaded quickly from an XB menu.  The menu was called LOAD to keep all typing to a minimum--the idea being to autoload the menu, select the track with a single keystroke, the music plays and loops indefinitely until I press FCTN 0 to reset the computer, then repeat the process to select the next track.  This works well enough as the computer can be reset and autoloaded very quickly.  But I like this new method of loading the music into HIMEM more--it affords more control, like choosing whether or not to loop the music and then have the computer automatically start the next track (selecting a random track even).  Since I have my actual TI connected to a stereo system, I like the idea of loading up my program and just letting it play music randomly unmanned while I'm doing something else around the house! :)

 

  • Like 2
Link to comment
Share on other sites

But on that note--Tursi, I do have a question for you concerning your last post about finding the memory addresses in high memory...  I notice your adjusted code above, apart from being slightly different in places, is also missing some of the original lines of code.  Specifically I'm referring to line 11010 CALL PEEK(8196,N1,N1)::REM GET TOP OF FREE RAM and 11020 N=N1*256+N2.  Also I notice in your above code that you did not post any changes to the first section staring at line 10000 REM FIND ADDRESS OF MUSIC TAG AND RETURN IN 'A'.  In that section the very next lines of code are 10010 CALL PEEK(8196,N1,N2)::REM GET TOP OF FREE RAM and 10020 N=N1*256+N2 which are identical to the omitted lines of code from your post above.  So I'm wondering was I supposed to keep the omitted lines of code in from the original program?  In my program I've included all the code from line 10000 through 10110 of your original XB program, then replaced the rest with what you've posted above (keeping those lines in question omitted).  Now when my program issues a CALL PEEK(ACTIVE,A) I get a NUMERIC OVERFLOW and the program crashes back to the BASIC prompt.  When I type PRINT ACTIVE it reveals ACTIVE=60915 (if that provides any clue)...(?)

  • Like 1
Link to comment
Share on other sites

7 hours ago, ruthven said:

I also had some sprites moving on the screen with auto-motion that just stopped dead in their tracks once issuing Tursi's CALL LINK("STOPSN") command. 

Hmm... my first thought was that maybe I forgot to restore the interrupt, but no, I restore it to the original saved one. Not sure why that's killing your sprite motion...

 

 

Link to comment
Share on other sites

7 hours ago, ruthven said:

But on that note--Tursi, I do have a question for you concerning your last post about finding the memory addresses in high memory...  I notice your adjusted code above, apart from being slightly different in places, is also missing some of the original lines of code.  Specifically I'm referring to line 11010 CALL PEEK(8196,N1,N1)::REM GET TOP OF FREE RAM and 11020 N=N1*256+N2.  Also I notice in your above code that you did not post any changes to the first section staring at line 10000 REM FIND ADDRESS OF MUSIC TAG AND RETURN IN 'A'.  In that section the very next lines of code are 10010 CALL PEEK(8196,N1,N2)::REM GET TOP OF FREE RAM and 10020 N=N1*256+N2 which are identical to the omitted lines of code from your post above.  So I'm wondering was I supposed to keep the omitted lines of code in from the original program?  In my program I've included all the code from line 10000 through 10110 of your original XB program, then replaced the rest with what you've posted above (keeping those lines in question omitted).  Now when my program issues a CALL PEEK(ACTIVE,A) I get a NUMERIC OVERFLOW and the program crashes back to the BASIC prompt.  When I type PRINT ACTIVE it reveals ACTIVE=60915 (if that provides any clue)...(?)

Yes, I just assume the addresses, because the pointers that I was referencing before only apply to low memory. There may be pointers for the high memory table but I don't know where they are. ;)

 

You're not supposed to merge the code blocks, no. I deleted the lines that looked at pointers that I don't have anymore and replaced the numbers they used to calculate with hard coded values instead. Note the following lines:

 

11030 REM SEARCH TOP DOWN (HARD CODED ROOM FOR 5 ENTRIES)
11040 FOR PTR=-26 TO -66 STEP -8

 

The comment describes what we're doing, the PTR represents the search loop - note that the values are not variables now. If there are pointers I can use to make it neat, we can use those, but if this works that's fine.

 

You don't need the subroutine at 10000. That's only for loading multiple SBF files, which we have agreed is not the way to move forward. :)

 

Link to comment
Share on other sites

Thanks for clearing that up.  So now I've deleted the first portion (lines 10000-10110).  I just have the exact code above and my program GOSUBs to it before attempting to play it with CALL LINK("SONGGO").  Now I'm getting a NUMERIC OVERFLOW in line 12090 CALL LOAD(N,I)...(?)  I'll try re-copy/pasting in case I messed something up...

 

1 hour ago, Tursi said:
9 hours ago, ruthven said:

I also had some sprites moving on the screen with auto-motion that just stopped dead in their tracks once issuing Tursi's CALL LINK("STOPSN") command. 

Hmm... my first thought was that maybe I forgot to restore the interrupt, but no, I restore it to the original saved one. Not sure why that's killing your sprite motion...

This was during my very first test getting this to work in TML.  The first time I tried getting that music to work with my "title screen/introduction" program, I did as you suggested and issued the CALL LINK("STOPSN") command before the music even began playing (following your original XB example program as a guide).  My program starts right off with sprites moving on the screen but with the STOPSN command issued first, the sprites would only be drawn to the screen but not move.  As a test I removed the STOPSN command and changed nothing else about my code and once again the sprites moved as they did before.  So then I omitted the STOPSN command and just immediately played the music which didn't interrupt sprite activity.  I was just so excited to see everything finally coming together that I didn't think much of it at the time.  Figured I'd tackle that later but apparently there are deeper complications senior_falcon is trying to work out.

Link to comment
Share on other sites

Yeah, he's working on his playlist player first, so it may be a while. But I can certainly try to fix my bugs in the meantime. I haven't done much with XB, so I have to sort of work my way through it.

 

I see the issue. STOPSN blindly overwrites the interrupt hook with whatever is saved, but if you never called SONGGO, then nothing was ever saved, so the TML interrupt is lost. It worked for me because I always tested the player first, violating my own instructions. ;)

 

The numeric overflow is because I forgot moving to high memory requires negative addresses, and I didn't test it. Apologies!

 

I decided to go ahead and do it (sort of) properly. I never linked CALL LINK very much so I'm not quick at coding for it. But rather than forcing you to use these slow XB functions, we can speed it up a bit by adding a little more assembly.

 

This now uses the pointer at >2000 to find the new table, so that should prevent too many dependencies. Senior_falcon, it does assume the first two instructions will remain the same LI/CI and pulls the addresses from those. Is that okay?

 

So all the XB subroutines can be tossed - I've provided CALL LINKs which will be faster and take up less space:

 

CALL LINK("STOPSN") - still the same function, but works correctly now and won't break your interrupts. ;)

CALL LINK("SONGGO",X) - X is the song index in the SBF file - 0 for the first one. There's no range checking - if you pass one that's too large it'll probably crash, so always save your code before you run it. X can be a variable or an inline number, but not an array.

CALL LINK("ACTIVE",X) - X must be a simple variable (not an array). It will receive 0 if the music is not playing, or non-zero (usually 1, but I didn't check all cases) if it is.

 

The enclosed zip file includes a TML program with a multi-song songbank for example. Hope this is fun!

 

TMLSample.zip

 

 

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

PERFECT!  Thanks so much! :)  I've been playing around with your updated routines and they will definitely fit my needs perfectly!  I appreciate you including a simplified means of selecting the music track within the SONGGO command itself--I haven't even tried this yet as I'm still just loading single track music embedded BASIC programs at the moment.  But the CALL LINK("ACTIVE",variable) is VERY appreciated! :)  Sure beats all that XB code and hey, it works in high memory first shot!

 

19 hours ago, Tursi said:

I haven't done much with XB, so I have to sort of work my way through it.

Appreciate that you're willing to do this for me, considering I'm (perhaps) the only one out there nuts enough to try to get all this working in BASIC.  I like to think that at least this information is out there now in case anyone else wants to follow in my footsteps.  In the meantime, if I'm the only one then I wear it as a badge of honor. :)

 

Hopefully I'll be good on the questions for a while now as I wait for senior_falcon's updated compiler.

  • Like 2
Link to comment
Share on other sites

Making some good progress on this. There is not really that much code to do, it's just that I am not very fast at it.

I wanted to copy the LSB of a memory address to the MSB, so the same byte was in both.

With R1 pointing to the address, I did this:

MOVB @WKSP+3,*R1

And then wondered why it didn't work. What I should have done, of course, is:

MOVB @1(R1),*R1

 

  • Like 4
Link to comment
Share on other sites

Thank you and no rush--I have plenty to do with my current projects before they're really at the music-stage anyway.

 

It's not much but I thought I'd share this anyway, for anyone following along who is interested or just likes some classic NES VGM tunes playing on their TI...  I always wanted to hear Tursi's Mega Man 2 tracks that are built into Classic 99 running on my real machine...  well here's the next best thing: a Mega Man VGM sampler running from XB.  I did this as a test of getting lots of music loaded into high memory by separating the tracks into their own embedded BASIC programs as described above.  The method seems to work well with one caveat--most of these music files are actually too big to fit into memory when running TML.  I found a work-around, a way to load them in regular XB.  Normally if you try to load these in XB without TML you get a SYNTAX ERROR in the CALL LOAD line.  But I noticed that these music files would play if I tried them after loading HMLOADER.  So I modified HMLOADER deleting all lines of code except for line 110 which sets everything up (obviously there is some embedded assembly in here as well).  I also modded it to RUN my own menu program called MENU1.  This modified version of HMLOADER I saved as MENU, so all you have to do is RUN "DSK1.MENU" which sets everything up the way HMLOADER would, then it runs my MENU1 program which sets up the screen and lets you select the music.  This all works great in regular XB even despite some of these music files being quite large. I made these VGMs myself as I was unsatisfied with the looping of the VGMs I found online--I took pains to make sure each track plays through it's main loop twice before ending as I think it just makes for a nicer listening experience.  Yeah, I could have just programmed it to loop back exactly once before advancing to the next track but it's a bit complicated as most of these tracks have a sort of "introductory" part at the beginning before the main loop.  Instead I just captured the music for exactly the amount of time I was looking for which kept coding simple.

 

The main purpose of this little demo was to have it play Mega Man tracks at random on it's own which it does.  After a track plays through twice it will randomly select another track unless the loop is engaged by pressing 2 (at which point it will loop indefinitely until the loop is disengaged).  Once the track is playing, the menu will no longer respond--you can only engage/disengage the loop or stop the music by hitting space bar or enter.  Once the music is stopped the menu becomes active again and you can select another track or go back into random mode.  I made it this way on purpose as I wasn't initially sure if I could get clean looping with the program reading through so much code looking for input for all the options on my menu.  But it works--it's a little janky but whatever... :)

 

On a sidenote: I did make the discovery that all this works in XB256 without the memory constraints of TML.  This is very exciting to me as I've been meaning to check out XB256 for other projects anyway.  I might even try another Mega Man VGM sampler with XB256 as that would provide me with more character pattern memory...  then I could make my Mega Man sprite do more than just stand there and blink!  :) 

 

Not sure what's more convenient for people so I'm providing this in both .DSK and .ZIP format (if you want easier access to the individual files).  The .DSK image is for CF7 and sounds GREAT on my real machine!

 

 

 

MEGAMANVGM.dsk MegaManVGM.zip

  • Like 3
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...