Re: Exact wait();
Hey, let's say I want to make a heart sprite in Dink beat every two seconds with sp_size() matching a midi beat in the background. To my agony, the wait() only waits for at least 2000 milliseconds making the heart beats out of sync.
Uh, any ideas to make it more precise? I am pretty sure I'm asking too much of the Dink engine, but maybe someone here have a trick to make it work?

Uh, any ideas to make it more precise? I am pretty sure I'm asking too much of the Dink engine, but maybe someone here have a trick to make it work?
Somehow futz around with frame delay settings to make one loop of the sequence run in 2 seconds? On the other hand, this is also tic-based, and will probably mess up if you go into the inventory screen.
Isn't there a DinkC command that polls for the current time? Check that every 100ms or so, and see if it's within the 2s range of the last heartbeat. This will probably also mess up if you go into the inventory screen.
I don't know how to get around the inventory screen business. You can overrule the enter key behaviour to just not work, or to show_inventory() manually, but I don't know if the code after show_inventory() is run at all, or after showing the inventory, or what.
Umm... good luck
Isn't there a DinkC command that polls for the current time? Check that every 100ms or so, and see if it's within the 2s range of the last heartbeat. This will probably also mess up if you go into the inventory screen.
I don't know how to get around the inventory screen business. You can overrule the enter key behaviour to just not work, or to show_inventory() manually, but I don't know if the code after show_inventory() is run at all, or after showing the inventory, or what.
Umm... good luck

September 22nd 2014, 07:40 AM

Quizghost


The inventory button is disabled by default so don't worry about it. The get date idea seems promising I must say, didn't think about it. I'll get back here if I encounter any trouble.
It looks like get_time_real() only has minute resolution, however.
Crud, that's correct. Any more ideas?

Convert the midi into a .wav, split it into many 2-second parts, then playsound() each part at the same time that you change the heart's size.
Kind of labour-intensive, and might result in jumpy music instead of jumpy hearts.
Kind of labour-intensive, and might result in jumpy music instead of jumpy hearts.

As far as I know, your best bet is probably just making the midi into a .wav like Scratcher said, except combine the heartbeat with the wav using some software like a midi program or audacity.
Not easy either, and the file size will be large for it. But at least it will sound correct.
If you use Dink Aural+ it could be made into a smaller file, if you don't mind requiring the player to have aural+.
Not easy either, and the file size will be large for it. But at least it will sound correct.
If you use Dink Aural+ it could be made into a smaller file, if you don't mind requiring the player to have aural+.
Wow, this is a real bummer. A rhythm element would be so cool, but the engine just isn't made for it, is it?
Yeah, I'm trying to make a rythm-thing outta this. Seeeeeems highly unlikely it will work at the moment.

Oh I'm sorry, I read it wrong... I thought you meant the heartbeat sound wasn't playing on time, not the graphic was out of sync. Next time I must read twice.
Unfortunately my Dink prowess is not high enough to help with this particular problem... Though if I'm not mistaken, the wait() command can even be different timings on different kinds of machines. I hope I'm wrong about that though.

Unfortunately my Dink prowess is not high enough to help with this particular problem... Though if I'm not mistaken, the wait() command can even be different timings on different kinds of machines. I hope I'm wrong about that though.
I had the same problem, the first part of the intro to Shrine of the Dragon is meant to sync to the music but the loading first time screws up the timing... to get it to work you have to start the game once to start the music playing, then restart.
After realising that the timing would probably be different on different PCs anyway, I gave up
After realising that the timing would probably be different on different PCs anyway, I gave up

Hey, this is just a wild-ass guess, but does setting sp_timing to 1 help at all?
Nope.
Test:
I was thinking of implementing the beat in the hearts frames and set it on repeat,time it with sp_timing, play a sound every frame when about two seconds have passed. But that's lame!

Test:
void main ( void ) { int &hrt = create_sprite(50, 350, 0, 52, 1); sp_timing(&hrt, 1); beat: sp_size(&hrt, 100); wait(2000); sp_size(&hrt, 140); wait(2000); goto beat; }
I was thinking of implementing the beat in the hearts frames and set it on repeat,time it with sp_timing, play a sound every frame when about two seconds have passed. But that's lame!
So, is the issue that the hearts don't beat together or that they do but it's not steady with the music?
That script with a 4/4 metronome in the background. Tempo 120 should be 2 seconds between bars. Heart gets out of sync almost instantly!
I don't know how to make the wait() command any more precise. That seems to be the problem. Maybe looping a wait(1); 2000 times would help, but probably not. It just seems like to me the higher the number in the wait command, the easier it is to mess up.
If it's such simple tiks and toks (and not actual musical music), can't you just use playsound? I mean creating a tik.wav and a tok.wav, and something like this:
void main ( void ) { int &hrt = create_sprite(50, 350, 0, 52, 1); int &tiktok beat: wait(250); // ^ tempo, however long it should take between each beat &tiktok+=1 if (&tiktok < 4) playsound(tik) if (&tiktok >= 4) { playsound(TOK) &tiktok=0 if (sp_size(&hrt,-1) == 100) sp_size(&hrt, 140); else sp_size(&hrt, 100); } goto beat; }
While it may be possible to have the visual effect and the sound play at the same time, I don't think that solves the problem. It still won't be properly rhythmic. I don't think a rhythm effect is possible in the Dink engine.
Won't it? I mean, it's one thing to time something to real world time (such as the midi, which is always 120 seconds long), and another to time something to game time. As long as the timing is moderately consistant internally, there should still be a rhythm the player can follow. (Even if each wait(250) ends up being 342, or 203, or 500 milliseconds of real time). If it's really jumpy internally, too, then that's a big problem...
It's dependend on computer speed I think. So you'll have to optimize the timing for every computer the DMOD will be played on.
I'll try some things I have in mind when I have the time.

One more idea. I'm not sure exactly how could use this, and it's also at probably a bug, but anyway this command:
returns a value that seems to be up-time in milliseconds.
sp_attack_wait(¤t_sprite, -1);
returns a value that seems to be up-time in milliseconds.
returns a value that seems to be up-time in milliseconds.
... How do you find these things? xD
I'm pretty sure it will still be attached to the frame cycle though.
... How do you find these things? xD
I'm pretty sure it will still be attached to the frame cycle though.
By trying stuff?
Anyway my thought is that even though it probably wont make timing any more precise each cycle, it would give a fixed point of reference so you can avoid getting further and further out of synch.
Anyway my thought is that even though it probably wont make timing any more precise each cycle, it would give a fixed point of reference so you can avoid getting further and further out of synch.
Hm, I still need some help with this.
Paul, could you evaluate a bit or post some code? Not getting further out of sync is a great thing!

Paul, could you evaluate a bit or post some code? Not getting further out of sync is a great thing!
That sp_attack_wait trick is pretty cool.
If anyone wants to see what Paul is describing:
For the beating heart you'll want to query your brain 10 sprite and adjust the wait time off of the value given by sp_attack_wait.
If anyone wants to see what Paul is describing:
// sp_attack_wait returns the raw time at which the sprite is able to attack next. // - DinkC Ref void main( void ) { sp_brain(¤t_sprite, 10); sp_target(¤t_sprite, 1); sp_attack_wait(¤t_sprite, 1000); } void attack( void ) { int &say = sp_attack_wait(¤t_sprite, -1); say("&say", 1); sp_attack_wait(¤t_sprite, 1000); }
For the beating heart you'll want to query your brain 10 sprite and adjust the wait time off of the value given by sp_attack_wait.
Alright, so your code above could be re-written this way:
I did quickly test this, but only to make sure it works at all. I can't promise it's any more accurate, though I think it should be.
void main ( void ) { int &hrt = create_sprite(50, 350, 0, 52, 1); int &now; int &then = sp_attack_wait(&hrt, -1); beat: sp_size(&hrt, 100); loopa: wait(10); &now = sp_attack_wait(&hrt, -1); &now -= &then; if (&now < 2000) goto loopa; &then += 2000; sp_size(&hrt, 140); loopb: wait(10); &now = sp_attack_wait(&hrt, -1); &now -= &then; if (&now < 2000) goto loopb; &then += 2000; goto beat; }
I did quickly test this, but only to make sure it works at all. I can't promise it's any more accurate, though I think it should be.
That is a neat find. What "raw time" does sp_attack_wait return, exactly? Last night when I tried this, the timer was counting at two hours. Now it was at 900 seconds, which is just 15 minutes.
EDIT: Ooh, it's the time that has passed since you turned your computer on. Fascinating!
EDIT: Ooh, it's the time that has passed since you turned your computer on. Fascinating!