Community
AGI Programming => AGI Development Tools => Topic started by: Collector on November 02, 2018, 11:32:17 PM
-
BTW, lance, not to hijack the thread, but did you get any further with your C# interpreter?
-
I haven't worked on it since May 2017, but I really must get back to it. I had just finished the save game feature at that point, so should be able to try playing through a few games now.
-
Perhaps I should split this off its own thread and leave this thread for Nickyv2003's question.
-
Split from Nickyv2003's walkthrough thread.
-
I haven't worked on it since May 2017, but I really must get back to it. I had just finished the save game feature at that point, so should be able to try playing through a few games now.
I've reinstalled Visual Studio, checked out the source code again, and started trying to work out where I got to. It looks like I was starting to work on decoding the sound resources. The AGI Library didn't support that, so I was starting to add that in. I lost my old local checkout of the code when my Windows VM died at some point mid last year. A good thing I was regularly pushing the code to bitbucket.
I think I still had to return to the rendering at some point. It was mostly in line with the original AGI interpreter, but there were a few areas where it wasn't quite right. To be honest though, it would only have been in quite obscure scenarios and probably difficult to notice.
-
Did I ever give you the source to the Visual AGI sound editor? They never got around porting it to C# from C++, but it may be of some help. And if you get anywhere with adding it to the AGI Library it could help with adding it to the rest of Visual AGI IDE. At that point the only big thing left for it would be the compiler. I did contact Gustaf Wennerholm on Facebook a while back. He probably be interested if we managed to complete Visual AGI.
-
Yes, I think you did send it to me, and I have got it somewhere. I will probably take a look at it to get some ideas.
-
I've been making some progress on the C# AGI interpreter. The sounds are now playing. I went down the route of using some SN76489 emulation code to generate 16 bit sample data at 44100 samples per second. The SN76489 is the sound chip used in the IBM PC Jr and therefore what Sierra coded the original AGI interpreter to output to. As you probably know, all the AGI sounds had four part sound as a consequence of this, the fourth voice being noise. I found some SN76489 emulation code already available on the Internet written in C#. It was part of a VGM Player written in C#. The author had ported the code to C# from another project. I thought I'd see if I could make use of it in this C# AGI interpreter. Seems to do the job well. When an AGI sound is played, the interpreter now uses the raw SOUND data to feed into the SN76489 emulation to produce the samples, then wraps it up with Wave file headers, and then plays it as a Wave file memory stream. I've tried playing the generated Wave file data with three different media playing libraries. One is the built in C# SoundPlayer, which works but isn't as flexible for checking whether the background sound has finished playing. I've also tried the NAudio and CSCore libraries. CSCore seems the nicest from what I've seen so far.
So its coming along. I'm now starting to play through a few games to pick up more bugs. Found a few already. I'll keep doing that for a few weeks I think.
-
I've finally managed to get to the top of the beanstalk in KQ1, with the help of the saved game functionality. Even with it it took me about 15 minutes to get to the top. :)
So this is now as far as I've got through playing KQ1 with the new C# interpreter. In the process of climbing the beanstalk, I exhausted all the free saved game slots and wrapped around to overwrite the first one again. Seems I have a bug in there somewhere, because it then falls over when I try to restore it. Should be easy to track down. I suspect that it is incorrectly keeping track of the number of saved games and doesn't account for the limit. Something like that. I'm going to fix that first then continue on with playing KQ1 through to the end. I'm about two thirds through the game I'd say.
-
Nice to see progress.
-
Seems I have a bug in there somewhere, because it then falls over when I try to restore it. Should be easy to track down. I suspect that it is incorrectly keeping track of the number of saved games and doesn't account for the limit. Something like that. I'm going to fix that first then continue on with playing KQ1 through to the end. I'm about two thirds through the game I'd say.
Turns out that there were two bugs in there. One bug exposed the other one. Both are fixed now, and saving and restoring games seems to be fully working.
And I just finished playing through to the end of KQ1! :)
The strange thing is that I've noticed a few issues when playing my Ruby Cast demo. I'll have to check those out. I'm surprised I didn't see similar issues in KQ1. They are the kind of issues, to do with sentence recognition, that I would have thought would have affected KQ1 as well. But maybe Ruby Cast is more broken than I thought. I'll have to try it in the original AGI interpreter and compare.
-
The strange thing is that I've noticed a few issues when playing my Ruby Cast demo. I'll have to check those out. I'm surprised I didn't see similar issues in KQ1. They are the kind of issues, to do with sentence recognition, that I would have thought would have affected KQ1 as well. But maybe Ruby Cast is more broken than I thought. I'll have to try it in the original AGI interpreter and compare.
I have now fixed the parsing issues that I had noticed in The Ruby Cast. I can see why they didn't affect KQ1. I did find some rooms in SQ2 where the bugs could be seen though. But all fixed now.
I fixed a number of other bugs as well, including a long standing picture bug with the Space Quest 2 title screen. Turns out that the Visual AGI library had a bug in it where it wasn't executing "Fill" commands in some scenarios where it should have been.
The only bug I'm aware of that is currently outstanding is associated with sound playing. It seems that it holds down some notes for too long. It isn't obvious with most sounds, but there are a few where a note is held down for far too long. I'll start looking at that now.
And then after that I'll be adding AGI v3 support to Visual AGI's AGI Library. Should be straight forward.
-
I'll be interested to see the changes to the library.
-
The only bug I'm aware of that is currently outstanding is associated with sound playing. It seems that it holds down some notes for too long. It isn't obvious with most sounds, but there are a few where a note is held down for far too long. I'll start looking at that now.
And then after that I'll be adding AGI v3 support to Visual AGI's AGI Library. Should be straight forward.
The sound bug has been fixed now, and I have also added the ability to load AGI V3 games.
So far I have tried KQ4, Gold Rush, MH1, and MH2. Haven't tried the AGI V3 build of BC yet. - For KQ4, the whole opening story played through fine, with the music playing nicely in the background. Didn't spot any issues. But after the game itself started, ego's loop wasn't changing when I changed walking direction. It did, however, change loops properly and as expected when ego walked into water, which means the mechanism itself is fine, but for some reason the default ego View isn't switching loops. I will take a look at that over the next day or so.
In Gold Rush, I spotted a minor issue to do with the user input prompt. Might take a look at that one tonight.
In MH1 and MH2, both games fell over with an Exception. Haven't taken a look to see why yet. In the case of MH1, the opening story/credits played through fine, but in MH2, it crashes almost immediately. I haven't yet implemented the AGI V3 specific commands, so might be to do with that. I guess I'll find out soon.
-
For KQ4, the whole opening story played through fine, with the music playing nicely in the background. Didn't spot any issues. But after the game itself started, ego's loop wasn't changing when I changed walking direction. It did, however, change loops properly and as expected when ego walked into water, which means the mechanism itself is fine, but for some reason the default ego View isn't switching loops. I will take a look at that over the next day or so.
I've fixed this one but it was an interesting problem. The main Rosella ego View has 5 loops. Not certain yet whether the extra one was in the original game or whether it inadvertently was added at some point when loaded into an editor. I'll try to rule that out soon.
I discovered another issue to do with non-default base priority values. KQ4 uses a base priority of 73. My priority band calculations were incorrectly using this. It has now been fixed.
I'm quite keen to try playing the whole of KQ4 through now and see where I get to.
In Gold Rush, I spotted a minor issue to do with the user input prompt. Might take a look at that one tonight.
Also fixed.
MH1 and MH2, both games fell over with an Exception. Haven't taken a look to see why yet. In the case of MH1, the opening story/credits played through fine, but in MH2, it crashes almost immediately. I haven't yet implemented the AGI V3 specific commands, so might be to do with that. I guess I'll find out soon.
There were several issues with the Manhunter games. Their logic scripts seem to do things that pretty much none of the other games do. This revealed a couple of areas where I wasn't quite doing things the same as in the original AGI interpreter, particularly around room changing and game clock updates. That is fixed now.
It is now possible to play both MH games. The main thing outstanding is the hold.key and release.key AGI v3 commands. Currently without them it means the round ball "ego" that you move around on the maps doesn't stop moving if you stop pressing the cursor key. Shouldn't take much to implement hold.key and release.key to resolve this.
-
If you are talking about view.000 being the main view, then yes version 2 only has four loops. It has been some time since I have last looked at Visual AGI, but my memory is that it could not open any AGI3 resources. I am assuming that you added support for decoding these too, not just AGI3 logic support. I need to go through the project again to refamiliarize myself with it.
-
Yes, it does say version 2, but the strange thing is that I've checked the timestamps of the vol files and they're all still 1988, which suggests they haven't been modified.
I have found another issue with KQ4. It only seems to affect KQ4. There are a few pictures that the AGI Library does not load, complaining that in the 0xF7 "relative draw" command that Y hits a value of 168, which it says is invalid. That sounds fair enough, but if I comment out that check, these pictures load fine and are drawn fine by my Interpreter. Not sure at this point whether this is somehow "bad" data that the original AGI Interpreter (and my Interpreter) is handling without issue, or whether there is something wrong in the AGI Library's Picture drawing code. I'm tempted to leave this validation check commented out since the Pictures are working fine like that.
Since my last update, I discovered an omission in my SOUND resource decoding that I have fixed. It wasn't catering for early termination of a voice with two consecutive 0xFF bytes.
And hold.key and release.key have been implemented, so the MH games are feeling like the real thing now.
I've been looking back over games that I thought I had working fine, and noticed that MUMG has a number of rendering issues. I recall discovering this back in early 2017. I thought I had fixed it, but perhaps I was partway through trying to resolve this when I was distracting by other things. It is to do with when animated objects are drawn. What MUMG does is to draw some animated objects to screen (e.g. speech bubble), and then immediately sets them to stop updating. The main Interpreter cycle doesn't redraw "stopped" animated objects; it only redraws those that are updating. So what MUMG does is to then position text on top of the "stopped" animated object, which it expects to stay on the screen. Currently my Interpreter is redrawing the stopped animated objects, which it shouldn't be in order to be compatible. So I'll need to take a look at that now. The way the original AGI Interpreter manages and redraws its "stopped" and "updating" objects though is like a ball of spaghetti, so its a matter of extracting the key parts in a cleaner design. I've got it all written out in a notebook, so hopefully I can get this solved soon.
Edit: Oh, forgot to mention that yes, I added AGIV3 support for loading of all resources. Mainly its just the LZW compression, and the Picture compression.
-
The way the original AGI Interpreter manages and redraws its "stopped" and "updating" objects though is like a ball of spaghetti, so its a matter of extracting the key parts in a cleaner design.
Oh yes, oh yes. That was one of the major sticking points in SCI as well. I suspect much of it was brought over unchanged.
-
If you are talking about view.000 being the main view, then yes version 2 only has four loops. It has been some time since I have last looked at Visual AGI, but my memory is that it could not open any AGI3 resources. I am assuming that you added support for decoding these too, not just AGI3 logic support. I need to go through the project again to refamiliarize myself with it.
There is definitely something weird going on with VIEW.0 in KQ4. My first workaround for this broke MUMG. Since the original AGI interpreter handles playing KQ4 fine, then it is coping with this extra Loop, even though the fragments of original AGI interpreter source indicate that AGI V2 would not have handled it. So I started wondering how scummvm handles this (since I've already ruled out the extra Loop having been introduced by an editor, due to timestamps on the KQ4 files still being 1988). Turns out that it has a specific workaround coded for KQ4:
https://github.com/scummvm/scummvm/blob/master/engines/agi/view.cpp
if (!(screenObj->flags & fFixLoop)) {
switch (screenObj->loopCount) {
case 2:
case 3:
loopNr = loopTable2[screenObj->direction];
break;
case 4:
loopNr = loopTable4[screenObj->direction];
break;
default:
// for KQ4
if (getVersion() == 0x3086 || getGameID() == GID_KQ4)
loopNr = loopTable4[screenObj->direction];
break;
}
}
My workaround was almost the same but without the AGI interpreter version and game ID check. This breaks MUMG though, which is why it seems that it is necessary to have a game specific check.
-
ScummVM does use an abbreviated MD5 check (from the first 5000 bytes), usually on the logdir file for AGI games to determine not just the game, but the game version as well. I used this for my Sierra game version detector tool. Wouldn't such an approach cause a problem with using it on the fly to run a new game, especially one still under development where the target file for the check would be constantly changing.
-
So I started wondering how scummvm handles this (since I've already ruled out the extra Loop having been introduced by an editor, due to timestamps on the KQ4 files still being 1988). Turns out that it has a specific workaround coded for KQ4:
https://github.com/scummvm/scummvm/blob/master/engines/agi/view.cpp
Turns out this fix goes all the way back to Sarien (which was imported to ScummVm), some 18 years ago:
https://github.com/cmatsuoka/sarien/commit/2e38cdc (https://github.com/cmatsuoka/sarien/commit/2e38cdc)
-
So I started wondering how scummvm handles this (since I've already ruled out the extra Loop having been introduced by an editor, due to timestamps on the KQ4 files still being 1988). Turns out that it has a specific workaround coded for KQ4:
https://github.com/scummvm/scummvm/blob/master/engines/agi/view.cpp
Turns out this fix goes all the way back to Sarien (which was imported to ScummVm), some 18 years ago:
https://github.com/cmatsuoka/sarien/commit/2e38cdc (https://github.com/cmatsuoka/sarien/commit/2e38cdc)
I suspected as much. It wouldn't have taken long to see the issue in KQ4, in fact its right there in the first room. I like the commit comment. :)
-
ScummVM does use an abbreviated MD5 check (from the first 5000 bytes), usually on the logdir file for AGI games to determine not just the game, but the game version as well. I used this for my Sierra game version detector tool. Wouldn't such an approach cause a problem with using it on the fly to run a new game, especially one still under development where the target file for the check would be constantly changing.
I've decided to go with simply the Game ID check for now, i.e. "KQ4" in this case. Its the same string they use when building saved game filenames. It seems that there is no need to check the specific AGI version because KQ4 was only released with the one version of Interpreter as far as I know.
-
Which interpreter version does your KQ4 game use? If it's 3.002.102, that version included a new reserved flag, f20, which if set would allow views with more than 4 loops to automatically choose loops without problem. Could that be the problem you've encountered?
-
Yeah, that would definitely explain it. Let me check the version... its 3.002.086 apparently, but it certainly behaves differently with regards to the automatic loop choosing than what AGI V2 does. Is it possible that f20 feature is there for all of AGI V3? I haven't checked yet whether f20 is set at this point in the version I have, but will do soon.
-
I've checked this now, and flag 20 is not set. So I guess that agrees with the fact that only 3.002.102 and above use flag 20 for controlling this.
Version 3.002.086 must be doing something similar but not controlled by flag 20.
-
For PC I am aware of only three versions of the game; 2.0, 2.2, and 2.3, but all use 3.002.086. The demo uses 3.002.102.
Do the Easter eggs in 2.0 work OK in your interpreter?
-
I assume they would. I've tried a couple of the easy to get to ones, and they work. I haven't played through much of KQ4 yet though.
I'm looking at my list of known issues at the moment. For some reason saved games don't work at all in Gold Rush. It completely ignores it when I select Save game in the menu. Really weird. I guess as soon as I start debugging that, all will become obvious. That's probably the main one at the moment, but I haven't played through much of any game other than KQ1 so far.
-
Gold Rush seems to be another one that has multiple versions, but all use the same interpreter, 3.002.149.
-
I've checked this now, and flag 20 is not set. So I guess that agrees with the fact that only 3.002.102 and above use flag 20 for controlling this.
Version 3.002.086 must be doing something similar but not controlled by flag 20.
If you have verified that it works correctly with the original DOS interpreter, I would love to get a copy of that interpreter file; I've decompiled all AGI versions that I have, including all v3 versions. I can confirm that only 3.002.102 and above use flag 20. I've examined the code in the 3.002.086 version I have, and there is nothing there that I can see that would change loops (without specific code in the logic), so I would love to know if the interpreter file I have is authentic (the date/time stamp is 8/31/1988 12:38PM). Would you mind sharing your file?
Also, I don't have access to my original disks (I'm on temporary assignment for work away from home for several months). Could I ask for a copy of the game files for your KQ4 version as well? Thx!
-
Also, is your source code available for your C# interpreter? I'd be happy to take a look at any sections where you have questions/concerns; I might be able to find issues quickly based on my decompilation efforts.
-
Also, is your source code available for your C# interpreter? I'd be happy to take a look at any sections where you have questions/concerns; I might be able to find issues quickly based on my decompilation efforts.
The project is currently a fork of Collector's AGI/SCI Developer repo in Bitbucket. That repo is described as a merger of SCI Developer and Visual AGI. It has a separate AGI Library that Visual AGI uses to load and save resources, although it didn't have anything to deal with SOUND or LOGIC resources when I started out with the Interpreter, and it didn't have anything for loading AGI V3 games either. The reason I forked Collector's repo is because one of the end goals is that it would be possible to run an AGI game from within the Visual AGI part of the IDE, so it is built on top of that AGI Library.
So having said all that, Collector's repo is currently private, and my fork of his repo is also private. If you create a Bitbucket account though, or already have one, then I can share my repo with you so that you can take a look. It would be very helpful actually. It would be good to get your feedback on what you see in there. I know there are still a number of outstanding issues. I was playing through SQ2 last night (nearly half way through I think) and spotted another four issues I need to take a look at. There are also several issues in KQ4.
-
If you have verified that it works correctly with the original DOS interpreter, I would love to get a copy of that interpreter file; I've decompiled all AGI versions that I have, including all v3 versions. I can confirm that only 3.002.102 and above use flag 20. I've examined the code in the 3.002.086 version I have, and there is nothing there that I can see that would change loops (without specific code in the logic), so I would love to know if the interpreter file I have is authentic (the date/time stamp is 8/31/1988 12:38PM). Would you mind sharing your file?
The date/time stamp of my one is 7/25/1988 12:43PM, as it currently appears on my harddisk. The AGI file is 40866 bytes. I can't recall now where I found this one, but I've had it for a while I think. I can confirm that the game definitely handles the loop changing even though the VIEW has 5 loops.
Also, I don't have access to my original disks (I'm on temporary assignment for work away from home for several months). Could I ask for a copy of the game files for your KQ4 version as well? Thx!
PM sent.
-
I've checked this now, and flag 20 is not set. So I guess that agrees with the fact that only 3.002.102 and above use flag 20 for controlling this.
Version 3.002.086 must be doing something similar but not controlled by flag 20.
I found it! It's a bug that's unique to version 3.002.086. Here's the code in v2.917 (which is identical in all versions up to 3.002.086:
mov [bp+newloop], 4 ; set newloop value = 4(means no loop change)
test word ptr [si+flags], FIXED_LOOP ; fixed loop?
jnz short setTheLoop ; if fixed, don't change loop
cmp byte ptr [si+loop_count], 2 ; loop count
jz short autoloop_sm ; if 2 loops, jump to small-loop selector
cmp byte ptr [si+loop_count], 3
jnz short autoloop_lg ; if three, also use small loop selector
; but if NOT three, go on to further check
autoloop_sm:
mov al, [si+obj_dir] ; use object direction
sub ah, ah
mov bx, ax ; to
mov al, loop_small[bx] ; convert direction to correct loop
jmp short changeLoopVal
autoloop_lg:
cmp byte ptr [si+loop_count], 4 ; if loop count != 4
jnz short setTheLoop ; don't change the loop
mov al, [si+obj_dir] ; if loop count == 4
sub ah, ah ; use object direction
mov bx, ax ; to
mov al, loop_large[bx] ; convert direction to correct loop
changeLoopVal:
mov [bp+newloop], al
setTheLoop:
... ; change loop if newloop value has changed (!= 4)
In 3.002.0086, they made one very small change (marked with ***):
mov [bp+newloop], 4 ; set newloop value = 4(means no loop change)
test word ptr [si+flags], FIXED_LOOP ; fixed loop?
jnz short setTheLoop ; if fixed, don't change loop
cmp byte ptr [si+loop_count], 2 ; loop count
jz short autoloop_sm ; if 2 loops, jump to small-loop selector
cmp byte ptr [si+loop_count], 3
jnz short autoloop_lg ; if three, also use small loop selector
; but if NOT three, go on to further check
autoloop_sm:
mov al, [si+obj_dir] ; use object direction
sub ah, ah
mov bx, ax ; to
mov al, loop_small[bx] ; convert direction to correct loop
jmp short changeLoopVal
autoloop_lg:
cmp byte ptr [si+loop_count], 4 ; if loop count ***<*** 4
***jb*** short setTheLoop ; don't change the loop
mov al, [si+obj_dir] ; if loop count ***>*** 4
sub ah, ah ; use object direction
mov bx, ax ; to
mov al, loop_large[bx] ; convert direction to correct loop
changeLoopVal:
mov [bp+newloop], al
setTheLoop:
... ; change loop if newloop value has changed (!=4)
The change in that test from 'jnz' to 'jb' has the effect of always changing the loop no matter how many loops are in the view. In version 3.002.098 (not 3.002.102, as I previously thought), the check for flag f20 was added which fixed the problem.
The upshot of this is that for all versions up to 3.002.086, objects assigned a view with more than 4 loops will not update loop based on direction; in version 3.002.086 objects will update loop based on direction no matter how many loops there are; and in versions beyond 3.002.086 objects with more than 4 loops will only update loop if flag f20 is TRUE.
-
Thanks for solving that mystery. That definitely explains it then. Looks like I will have to add specific version checks in there to make it truly compatible.
-
Thanks for solving that mystery. That definitely explains it then. Looks like I will have to add specific version checks in there to make it truly compatible.
The one thing I've learned after all this time studying AGI is that Sierra was terrible at error checking and that a lot of their code (in the interpreter) was a bit sloppy in handling non-standard data. When opening Sierra games you gotta check for a whole bunch of things that can cause problems.
For example, when I loaded KQ4 yesterday, I found there are four resources (picture 150, 151 and view 198, 199) that point to non-existent VOL files. And there are five pictures (2, 10, 15, 102, 115) that have bad data for pixels (using a Y value of 168 occurs a bunch of times in all those pictures). Sierra's interpreter will happily overflow the picture buffer without complaining (the stuff that gets overwritten is whatever is beyond the picture buffer in memory, which is not even allocated to the program!). So they display with no visible effects, but if you want to draw them in a new interpreter or editor, you have to account for that.
-
For example, when I loaded KQ4 yesterday, I found there are four resources (picture 150, 151 and view 198, 199) that point to non-existent VOL files. And there are five pictures (2, 10, 15, 102, 115) that have bad data for pixels (using a Y value of 168 occurs a bunch of times in all those pictures). Sierra's interpreter will happily overflow the picture buffer without complaining (the stuff that gets overwritten is whatever is beyond the picture buffer in memory, which is not even allocated to the program!). So they display with no visible effects, but if you want to draw them in a new interpreter or editor, you have to account for that.
Yes, I've come across both of those issues in KQ4 already. For resources that point to non-existent VOL files, I think we can just ignore that. Clearly they're unused resources, and logic scripts must not be referring to them. Some of the other games have that issue as well.
For those pictures where the 0xF7 relative draw tool is drawing down to Y = 168, I'm not 100% sure what to do. If I remove the validation check, then they load fine and render fine in my Interpreter, but then that means we're allowing an original Sierra game to violate rules that our own editors enforce. Sierra's original PICTURE editor must have allowed them to draw down to 168, perhaps as a result of a bug maybe? Given this issue is in KQ4, maybe it was one of their later PICTURE editors. This issue doesn't seem to be in any other game that I've noticed so far.
I guess what I need to do is put some sort of option for disabling that validation into the Picture part of the AGI Library. Maybe original games can use the AGI Library with validation turned off, whereas the picture tool in Visual AGI would have to run with it turned on, although it probably doesn't need to, because if it has been written properly, it won't let such data be created.
-
Sierra's original PICTURE editor must have allowed them to draw down to 168, perhaps as a result of a bug maybe? Given this issue is in KQ4, maybe it was one of their later PICTURE editors. This issue doesn't seem to be in any other game that I've noticed so far.
I have 2 versions of Sierra's PICTURE editor: PIC.EXE (1987-02-23) and PE.EXE (1987-05-28).
I did not check them out yet, but you are welcome to do so: I just released my stash of AGI tools in this thread: http://sciprogramming.com/community/index.php?topic=1814.0 (http://sciprogramming.com/community/index.php?topic=1814.0)
-
For those pictures where the 0xF7 relative draw tool is drawing down to Y = 168, I'm not 100% sure what to do. If I remove the validation check, then they load fine and render fine in my Interpreter, but then that means we're allowing an original Sierra game to violate rules that our own editors enforce. Sierra's original PICTURE editor must have allowed them to draw down to 168, perhaps as a result of a bug maybe? Given this issue is in KQ4, maybe it was one of their later PICTURE editors. This issue doesn't seem to be in any other game that I've noticed so far.
As I mentioned earlier, in the interpreter, the position is converted to a linear offset in the picture memory buffer (pos = 160*y+x). The interpreter doesn't bother checking either X or Y; so when the offset exceeds the actual buffer size, AGI just sets that byte in memory even thought it's a buffer overflow. But since the picture buffer is the very last hunk of memory that is allocated, it doesn't overwrite any AGI data. So it looks just fine in AGI.
In WinAGI, I just do a check every time a pixel is plotted. If the linear offset exceeds the buffer size, I just ignore it. That way the picture will be rendered the same as in AGI.
-
Sierra's original PICTURE editor must have allowed them to draw down to 168, perhaps as a result of a bug maybe? Given this issue is in KQ4, maybe it was one of their later PICTURE editors. This issue doesn't seem to be in any other game that I've noticed so far.
I have 2 versions of Sierra's PICTURE editor: PIC.EXE (1987-02-23) and PE.EXE (1987-05-28).
I did not check them out yet, but you are welcome to do so: I just released my stash of AGI tools in this thread: http://sciprogramming.com/community/index.php?topic=1814.0 (http://sciprogramming.com/community/index.php?topic=1814.0)
Thx Omer. Maybe I will try to decompile these to see it there is a bug that allowed a Y value of 168 to slip in.
-
I was playing through SQ2 last night (nearly half way through I think) and spotted another four issues I need to take a look at.
Actually there were five issues I had spotted in SQ2 at the nearly halfway through mark. All now fixed, so I'll continue playing through to the end now.
-
Actually there were five issues I had spotted in SQ2 at the nearly halfway through mark. All now fixed, so I'll continue playing through to the end now.
I've finished playing SQ2 through to the end. I did notice a couple of minor issues that I need to take a look at. The text in one of the text windows was wrapped differently. I thought I had that working properly, but I'll need to take another look and see why this particular one isn't right. And there was one sentence that it didn't understand that the original appears to understand, which has made me realise I have't implemented ignored words yet. Not sure how I've got so far without that.
AGKorson is helping me with an issue in KQ4 to do with effective Y calculation of fixed priority objects that I will hopefully have resolved later today. Thanks Andrew for identifying the issue.
Assuming I fix the above issues over the next day, then the main outstanding issue I have at the moment is in MH2. For some reason it hangs on the WAIT icon after leaving the passage way that leads to Tad Timov's office to return outside. The scripts seem to be stuck in some kind of loop, which means whatever it is waiting for the Interpreter to do, it obviously isn't doing.
Next game I want to try playing through to the end is KQ4.
-
Looks like it is the AGI3 games where you are finding issues.
-
It's a mixture actually. All the early issues I found in KQ1, because that was the first game I was trying to play through. Then above I've recently mentioned seven issues I found while playing SQ2, which is AGI v2. But I have found a lot of issues in the AGI v3 games as well. There are a lot of AGI v2 games I haven't played through much of, so there could be other issues in there. I did spend quite a bit of time looking at DDP and MUMG because they do some unusual things, unusual when compared with the core set of AGI v2 games. There were quite a few issues I worked through with those two games.
-
And there was one sentence that it didn't understand that the original appears to understand, which has made me realise I have't implemented ignored words yet. Not sure how I've got so far without that.
So turns out I have implemented ignored words already. The bit that isn't working is recognising the longest "word" when it is trying to match the input line with recognised word numbers. This recognition is breaking down when an ignored word is involved. So in the sentence "cut glass with cutter", it is ignoring "with" as expected, but is then matching "glass cutter" as a whole word, because that has a word number, which is probably a synonym of "cutter", and having ignored "with", it now thinks "glass" and "cutter" are next to each other. I can think of a quick way of fixing this already. Will try that now.
-
Okay, that parsing issue is now fixed.
The text in one of the text windows was wrapped differently. I thought I had that working properly, but I'll need to take another look and see why this particular one isn't right.
And I've found the cause of this text window issue as well. When Roger searches the dead body of Vohaul, the message that is displayed has two spaces between two of the words (as stored in the LOGIC resource), but when it renders it to screen, it removes one of the spaces so that only one space is rendered between these two words.
-
I did spend quite a bit of time looking at DDP and MUMG because they do some unusual things, unusual when compared with the core set of AGI v2 games.
The booter version of DDP? The "DOS" version floating around on the internet is actually a hacked version of the booter that crashes at points when you press certain keys like escape.
-
The booter version of DDP? The "DOS" version floating around on the internet is actually a hacked version of the booter that crashes at points when you press certain keys like escape.
There is a DOS version according to NewRisingSun here (https://www.vogons.org/viewtopic.php?f=33&t=50096).
-
The booter version of DDP? The "DOS" version floating around on the internet is actually a hacked version of the booter that crashes at points when you press certain keys like escape.
There is a DOS version according to NewRisingSun here (https://www.vogons.org/viewtopic.php?f=33&t=50096).
No, not the original booter version, although I know the booter version is available on the Wayback Machine. According to that information from NewRisingSun, it appears that I have the rare DOS 1.50 version of DDP, since that is the version that comes up in the game. I can't remember now where I got it from, but the file timestamps indicate that I've had it for at least 8 years, which isn't long after I joined sciprogramming.com. I just tried downloading the DDP version on Al Lower's web site and that doesn't currently work with my Interpreter straight off. It doesn't like the OBJECT file, so I replaced it with the OBJECT file from the version I have. That allowed the game to start up properly, but after I viewed the game version within the game, it fell over with an error that I haven't investigated yet. So still a bit of work to do then for that version of DDP. NewRisingSun says that one is the Amiga data files running on a DOS Interpreter. Is there also a hacked version of the booter available? It wouldn't surprise me.
-
I just tried downloading the DDP version on Al Lower's web site and that doesn't currently work with my Interpreter straight off. It doesn't like the OBJECT file, so I replaced it with the OBJECT file from the version I have. That allowed the game to start up properly, but after I viewed the game version within the game, it fell over with an error that I haven't investigated yet.
The AGI Interpreter used by the version on Al's site is 2.272. I think my Interpreter is not compatible with early versions of the original Interpreter at this stage, so that is probably a good test case. I know that various things changed between the versions that I am not yet accounting for.
-
Perhaps my memory is wrong and I was thinking of the hacked Amiga version, not booter. I would be interested in seeing the DOS 1.50 version.
This does bring up a question of how hard would it be to add support for AGI games from other platforms? Then there are the fan games that have memory or stack issues that will run in NAGI, but not the original interpreters.
-
I doubt that I would extend the Interpreter to support other platforms. At the moment I see it as covering all of the DOS AGI V2 and V3 games. Not sure if I'll extend it to AGI V1. There seems little point. One of the main goals was to integrate it with Visual AGI, i.e. run a game created within Visual AGI. That requirement doesn't need to support many different versions of platforms I don't think.
Regarding fan made games and memory issues, in theory my Interpreter should be able to play all of the fan made games without any such issues, because it doesn't have the same memory limitations. So it is a bit like NAGI in that regard. It would certainly allow you to run a game that would not work in the original Interpreter. Not sure if that is a good or bad thing. It would probably be quite difficult to exactly match the original AGI Interpreter's memory management and restrictions.
-
You have a point about AGI1 games. I am not sure if I even have any outside of what may be on some of my booter disks. I do have a copy of the 2nd IBM release of the original KQ, but wouldn't that be GAL, more than purely AGI? I wish I had a means of extracting the files from my booter disks.
-
AGKorson is helping me with an issue in KQ4 to do with effective Y calculation of fixed priority objects that I will hopefully have resolved later today. Thanks Andrew for identifying the issue.
...
Next game I want to try playing through to the end is KQ4.
Andrew's suggestion on how to fix the effective Y issue did indeed fix the problem I was having with one of the dwarves in the mine.
I've started playing through KQ4 and I'm now up to about a third of the way through I'd say. I discovered another bug in the room with the pool and cupid. It wouldn't understand it when I said "get bow". Turns out that I hadn't properly implemented the "AND" part of "if" statements, in that I hadn't put in the shortcut break out when it encounters the first condition that is false. So what it was doing was evaluating everything in the AND. Normally that wouldn't have mattered, but some test conditions have side effects, "said" being the one in this case. There were multiple "get bow" said tests in the room script, and it believed it had already matched the input with an earlier test, but actually it should never have tested that particular "said". All I was missing was a "break" in one of my for loops. That fixed the issue and I was able to progress.
-
I just noticed the attached priority screen from PICTURE 57 in KQ4AGI (the witches cave).
-
Hmmm, how does that even work?
-
Not sure if this is what you mean, but since all of those blue control lines are drawn above the black control line, then there is no way that they can affect ego or the witch that chases her. Their base line would stop at the black control line and not go any higher. So one of the game developers (John Hamilton I assume) must have thought it would be fun to put some control line graffiti in that area of the priority screen. I've seen other not so obvious examples of this in other rooms. For example, in room 110, I can see CHRIS written in black control lines within one area, which would be Chris Hoyt. There is something else written in another area on that priority screen but I can't make it out. - Also in room 26, one of them has written "HI" in one area. - I wonder how many other Sierra games have examples of this.
-
I've started playing through KQ4 and I'm now up to about a third of the way through I'd say.
I have now finished playing through to the end of KQ4. So that I could get through as quickly as possible, I've been following video walkthroughs. In this particular case, it was a walkthrough that got the maximum or 230 points.
I did find another blocking bug along the way. Actually it was blocking in more ways than one. It blocked my progress getting further in the game, and it was to do with the rendering of a blocking control line. I had a bug in my add.to.pic implementation to do with the rendering of the control box that prevented the ghost boy from climbing the ladder. So I fixed that then was able to play through to the end.
There is another bug I noticed, I think to do with the follow.ego implementation. Pretty much any character that tries to chase ego just seems to randomly move, more like a wander, but not even that. Every step seems to be randomly placed, like its doing some kind of weird dance. I hadn't noticed any follow.ego issues in other games so far. I plan to go back and confirm that its working in earlier games, and if so, then take a closer look at the KQ4 LOGIC scripts for the rooms where this happens to see what is going on.
p.s. I just tried out two more of the KQ4AGI easter eggs, the "beam me up" one and the "rap kq" one.
-
There is another bug I noticed, I think to do with the follow.ego implementation. Pretty much any character that tries to chase ego just seems to randomly move, more like a wander, but not even that. Every step seems to be randomly placed, like its doing some kind of weird dance. I hadn't noticed any follow.ego issues in other games so far. I plan to go back and confirm that its working in earlier games, and if so, then take a closer look at the KQ4 LOGIC scripts for the rooms where this happens to see what is going on.
This bug is now fixed. It turns out that my Interpreter was updating the stopped flag too often. It should only update it when the step time counter hits zero. It was correctly updating the animated object's position on the counter hitting zero, but for updates to the stopped flag, it was doing this on all values of the step time counter. The result was that it thought the animated object was stopped (i.e. hadn't moved) in the current cycle (which is true, but is of no relevance if it hasn't tried to update the animated object's position in that cycle). This lead to the seemingly random movement, because the follow ego logic chooses a random direction if the animated object is stopped by something. So my Interpreter was mistakenly thinking it had been stopped when it hadn't and therefore making it select a random direction to avoid whatever had supposedly stopped it.
I also fixed two other bugs I found in KQ4: One of these was in any room with a zombie. The whole game slowed down to a complete halt for about 10 seconds whenever the first zombie came out of the ground. Turns out this was due to the Logic script trying to start the same sound 20 times in a row. I assume that in the original AGI interpreter, this didn't have any impact on performance, e.g. perhaps it just immediately started playing the sound again from the start with no noticeable effect, but in my Interpreter, it generates the WAVE file data on the fly before playing a sound and doing this 20 times in quick succession was slowly things down to a crawl. I considered caching generated sounds, which perhaps I might still do for the current room. For now I've got a check in there that if it tries to play a sound that is already playing, it just leaves it playing and does nothing. This fixes the issue in the zombie rooms.
The other issue was in the KQ4 Help screen. It was being displayed with a black background where the original game has a white background. This was being caused by a difference in how the background colour is used when switching to the text screen. The original Interpreter sets the text attribute value using the currently set background and foreground, and then uses the background part of the text attribute when clearing the screen. I changed my Interpreter to do the same and now this issue is also resolved.
There is only one other issue I know of now that affects KQ4, and also SQ2, in fact it is possible that it affects all games but so far I have only observed it in those two games. For some reason the "Save game" option in the menu stops responding after a while. All other menu options continue to work. I had a similar issue a while back that affected a number of menu options, but this new issue seems to affect only the "Save game" option. That will be the next issue I try to track down.
-
There is only one other issue I know of now that affects KQ4, and also SQ2, in fact it is possible that it affects all games but so far I have only observed it in those two games. For some reason the "Save game" option in the menu stops responding after a while. All other menu options continue to work. I had a similar issue a while back that affected a number of menu options, but this new issue seems to affect only the "Save game" option. That will be the next issue I try to track down.
And now this issue has also been resolved. The issue was that the Interpreter wasn't re-enabling all menu items when restoring or restarting after death. I also noticed that I wasn't setting the RESTART flag on a restart, which meant that the credits and story weren't being skipped for games that use that flag.
-
I can't believe it is coming up 4 years since I last worked on this, and 6 years this December since I began work on it.
I had to read through this topic from the beginning to remind myself where I was up to and what I had tested. So it sounds like I played through KQ1, SQ2 and KQ4 to the end. I also did some exploratory testing on other games, and discovered specific rendering issues in games like MUMG that I fixed. I vaguely recall I still had intermittent issues with saved games but that they were generally working. Rather than continue playing through the rest of the games to the end, and trying to find and fix further issues, I thought it was well past the time I should release an initial build for other people to try out and help find bugs.
I plan to do that this weekend. I'm not far off now. I've worked out how to build an installer for the app, added an icon for it (a random emoji character from Twemoji that I just might keep, as I think it looks cool as an icon, despite not being related), and adding in some of the bare minimum niceties that you'd expect, such as a command line option for game path, and if not present, then checking current dir, and if no game there then pop up a folder selection dialog. And automatic game detection. Oh, and I updated the project to the latest Visual Studio 2022.
What I'm not sure about at the moment is what .NET Framework version to target. By default, it seems to have set it to .NET Framework 4.8. I've read online that there is also a .NET 5 and .NET 6 available, and a .NET 7 preview, but that those are no longer the .NET Framework? Apparently new development should target .NET 6, but Microsoft says that there is no need to migrate existing .NET Framework apps to .NET 6. I've found tutorials online that cover migrating a .NET Framework Winforms app to .NET 5/6 but I'm not sure if it is worth it at the moment. As far as I can tell, .NET Framework 4.8 is available on Windows 7 upwards, so perhaps it is a good one to leave it on for now. It has been around since April 2019.
I should probably mention that I've been building this on Windows 11. Not sure if that makes a difference.
-
...such as a command line option for game path...
@AGKorson, I was trying to use the command line option in my AGI interpreter ("AGILE") to configure its use with WinAGI, but it appears that the "Optional Command Line Switches" field in the WinAGI Properties dialog doesn't save. I've tried filling it out numerous times, and every time when I reopen the Properties dialog, it is empty again. Attempting to Run the game results in my AGI interpreter starting up in such a way that it is obvious the command line parameters haven't been passed through.
I'm using version 2.2.5 of WinAGI.
Currently my interpreter takes a single command line argument, being simply the path of the folder containing the AGI game files. I've tested it from a DOS prompt and it works fine.
-
@AGKorson, I was trying to use the command line option in my AGI interpreter ("AGILE") to configure its use with WinAGI, but it appears that the "Optional Command Line Switches" field in the WinAGI Properties dialog doesn't save. I've tried filling it out numerous times, and every time when I reopen the Properties dialog, it is empty again. Attempting to Run the game results in my AGI interpreter starting up in such a way that it is obvious the command line parameters haven't been passed through.
I'm using version 2.2.5 of WinAGI.
Currently my interpreter takes a single command line argument, being simply the path of the folder containing the AGI game files. I've tested it from a DOS prompt and it works fine.
Sorry about that. I'll check it out this weekend and get a fix out shortly.
-
What I'm not sure about at the moment is what .NET Framework version to target. By default, it seems to have set it to .NET Framework 4.8. I've read online that there is also a .NET 5 and .NET 6 available, and a .NET 7 preview, but that those are no longer the .NET Framework? Apparently new development should target .NET 6, but Microsoft says that there is no need to migrate existing .NET Framework apps to .NET 6. I've found tutorials online that cover migrating a .NET Framework Winforms app to .NET 5/6 but I'm not sure if it is worth it at the moment. As far as I can tell, .NET Framework 4.8 is available on Windows 7 upwards, so perhaps it is a good one to leave it on for now. It has been around since April 2019.
The whole .Net stuff is such a confusing mess. .NET Framework 4.8 will have the best compatibility, but it's a dead-end. Aside from a minor bugfix release 2 months ago (4.8.1), it stopped development in 2019. Back about 6-7 years ago, MS rewrote .net from the ground up to make it more platform agnostic. They called the new one .NET Core, retroactively renaming the old one to .NET Framework. That was about the same time they released .Net Framework 4.6.2. They updated both in parallel, and continued to call the new one Core up to .NET Core 3.1. Then the next version they called .NET 5 to make it obvious it was intended to succeed 4.8. Since then .NET 6 has come out, which is the current LTS release.
It's kinda like how Windows XP was the next iteration of the Windows NT product line but still replaced Windows 9x, which was itself a dead-end.
Incidentally, not that this applies to you, but for dll applications to ease upgrading you can compile against something called .NET Standard 2.0, which is a subset of code shared by .Net Framework and .NET. Those dll's will be compatible with both .Net Framework and .Net Core applications. (Not .NET Standard 2.1 though.)
You should be able to compile most of your existing code against .NET 6, but upgrading your project from .Net Framework to .NET isn't a simple 1-click process. I mean, it's not hard, but changing from one .Net Framework to another .Net Framework is as simple as changing the target in a drop-down; changing from .Net Framework to .NET is not that simple. There are some pretty fundamental changes to the project files between the two.
I've been slowly moving all my personal and professional projects to .NET 6, and it's been pretty painless for the most part. The biggest hurdle for me was Visual Studio's WinForms designer is buggy on HighDPI displays. They have a workaround, but that broke in Visual Studio 17.3.1... haven't been able to test later versions, so I've stuck to 17.2.6 for now.
-
I now have a github action set up on my repo that builds the AGILE installer package whenever I push to the master branch. So for those who are interested in trying it out already, you can download the package from the latest successful build here:
https://github.com/lanceewing/agile/actions/workflows/build.yml
When you install it, it's going to give you warnings about being an unknown publisher, as that's what I am at the moment ;D. I'll need to look into how to resolve that.
I know that there are still bugs in the interpreter, in fact a couple of older games fell over when I tried them today, but I wanted to make something available to others already to try out, otherwise I'll probably be testing it forever. If anyone finds any bugs, please let me know, either by posting to this topic, or by raising an issue on the github repo.
I'm keen to know what people think of it. :D
-
It's not building for me. It is not finding the AGI library. Is this your modified AGI library from Visual AGI? Are you going to release the library source, too?
I am using VS Community 2019 on Win10, not sure if that makes any difference other than the installer project is incompatible.
-
I'm using the latest Visual Studio Community 2022. The GitHub action workflow is building it fine but that is probably because I've told it to use windows-latest, which has VS 2022 on it. Yes, the AGILibrary is the one built from my fork of your repo, but I would have also compiled that with VS 2022.
Rather than building from source, have you tried installing and running the built installer from the github action that I linked to? The latest successful build has an artifact called AGILE.zip that you can download, extract and then install by running the setup.exe.
Ah, okay. It looks like the artifact isn't able to be downloaded by other people for some reason. I've just viewed the page, and although the artifact is shown, it doesn't have the link to download it. Not ideal. When I'm logged in, I get the download link. I think I might need to upload a proper release to the releases section as maybe I'm the only one who can see the download link.
-
Okay, for now I will attach the latest build to this message for people to try. I'm interested to know if it actually runs on people's machines.
-
Seemed to work well on win10. SQ1, SQ2, KQ3, Black Cauldron, Manhunter SanFran all launch and work fine on the first few screens. I played PQ1 until I crashed the cruiser with no issues. Seems pretty solid so far!
Edit: it freezes on the soon to be finished SQ1 French translation, but that uses the AGK string hack (https://sciprogramming.com/community/index.php?topic=1870.msg12903#msg12903) to support extended characters.Might be nice to see support for that down the road.
-
Thanks. Great to know that it is working fine for someone else, particularly on Win 10, as I hadn't tried that myself yet. I've been running on Win 11.
Regarding the memory hack, yeah, I was wondering whether I might be able to support that at some point. Would be interesting though, as obviously the code injection itself wouldn't work. Perhaps I can somehow recognise those calls, for certain features, and activate the same features in response. It would break as soon as someone slightly tweaks the injected code though.
-
Just trying SQ2 now. Works great. The noise channel of Tandy 3-voice comes out a little gimped though. It doesn't sound like it should. For reference, just skip the intro of SQ2 and listen to Roger sweeping the space deck.
-
Yeah, I'll probably have to go back to the sound, particularly the noise. Do the tone voices sound okay?
In what way is the noise gimped? Do you have a link to a video of SQ2 running on an IBM PC JR for comparison? Original machine rather than emulator. I couldn't find one online for SQ2. There are other games, like BC, but couldn't spot SQ2. I've been trying to implement it based on the SN76496 chip, and what is known about it, but I don't think it is quite right yet.
-
Just tried it on KQ4 v2.0. It takes quite a while to load, but seems to run well after it does. This is on Win10 x64 Pro. After tomorrow I'll get a day off and will explore it some more. I still want to try to get it to build on my system. Guess I'll have to install 2022. Do you have any extensions installed that are required? How current is the AGI library on your fork?
-
Yeah, KQ4 is one that I've also noticed takes a while to load. AGILE actually decodes everything up front, which makes it a lot quicker when ego is walking between the various rooms, but for some of the larger games, the delay up front is noticeable. I haven't looked into where the majority of the time is being spent. The LZW decompression of all the V3 resources, in addition to decoding all the resources, might be why the V3 games take a while longer to load. How many seconds would you say it is taking to load KQ4 for you?
The only extension I have installed is the Visual Studio Installer Projects 2022 extension.
Regarding whether my fork of the AGILibrary is current in bitbucket, yes, all the code has been pushed.
-
If you cannot speed up the loading, perhaps add a message that it is loading the game so the user knows it is working. At first I thought that AGILE failed to launch.
-
Yeah, I'll probably have to go back to the sound, particularly the noise. Do the tone voices sound okay?
In what way is the noise gimped? Do you have a link to a video of SQ2 running on an IBM PC JR for comparison? Original machine rather than emulator. I couldn't find one online for SQ2. There are other games, like BC, but couldn't spot SQ2. I've been trying to implement it based on the SN76496 chip, and what is known about it, but I don't think it is quite right yet.
Actually it seems like it just doesn't make any sounds. Or if it does it tries to make sound with a tone instead of noise. I can't find any authentic IBM PCjr footage except for this video
https://www.youtube.com/watch?v=cv1I3t2tg4Y
The only noise that sounds however is when the hovercraft is moving at 1:18.
The only other thing I notice is that unlike the above footage, the tones don't have a volume envelope. The volume falls off at a certain rate on every tone on the PC jr and Tandy 1000. ScummVM's PC jr emulation is the most perfect I've heard both with noise channel and tone volume envelopes. Even better than DOSBox's.
Incidentally, I just tried running the AGI Demo 2 game (which has the SQ2 demo in it) and it doesn't seem to like it. Navigating to each page of demos with F9 and F10 works once in a while, but I can't hit a number to select a demo to run. It just doesn't respond.
-
If you cannot speed up the loading, perhaps add a message that it is loading the game so the user knows it is working. At first I thought that AGILE failed to launch.
Yeah, I agree. I'll try to pop up something to show that it is loading, whether that is just a simple dialog, or the AGILE window in a loading mode. The AGILibrary did/does have code in it to show the progress of its decoding, but I disabled that, as it was very low level, and tended to slow things down. It's useful during development, particularly when a game is failing to load, but not really appropriate for a release version. I probably need a simple progress bar replacement, or simple message like you suggested.
-
I'd say an AGILE window in a loading mode makes the most sense. Now that you mention it, I remember that Visual AGI showed a loading progress when loading a game. Perhaps put the progress bar in a second thread?
-
Actually it seems like it just doesn't make any sounds. Or if it does it tries to make sound with a tone instead of noise.
It is definitely making a noise sound for me, quite distinct from the tone, but it probably isn't right yet. What does the rushing water sound like for you in Black Cauldron when you're in the scenes with the stream?
For King's Quest 2, the waves breaking are meant to make a noise sound, which I've seen on Youtube videos for the PC JR version. I know that AGILE doesn't sound right for that one either. It sounds a lot more like crashing rather than a wave breaking.
I can't find any authentic IBM PCjr footage except for this video
https://www.youtube.com/watch?v=cv1I3t2tg4Y
The only noise that sounds however is when the hovercraft is moving at 1:18.
Thanks. I'll take a look at that one later today.
The only other thing I notice is that unlike the above footage, the tones don't have a volume envelope. The volume falls off at a certain rate on every tone on the PC jr and Tandy 1000. ScummVM's PC jr emulation is the most perfect I've heard both with noise channel and tone volume envelopes. Even better than DOSBox's.
I have seen in the comments that DOSBox uses the MAME source code for this emulation. Haven't checked to see if they're currently in sync, but a comment in the code implies that it was at some point.
I think I see what bit in the scummvm code is handling this volume envelope. There is some "dissolve" data defined, which is set differently for different AGI versions. Hmmm, not sure how that could be the case though, as what you are describing sounds more like a feature of the hardware rather than AGI versions. But "dissolve" does sound like it might be related to what you describe. I noticed that NAGI also has that dissolve data defined (a comment in there also calls it "fade out"):
https://github.com/sonneveld/nagi/blob/master/src/sound/sound_gen.c#L46
From what you can hear, do you think that this "fade out" happens from the point that the tone ends, i.e. at the point that its duration count has ended? Or do you think it fades out leading up to the point where the duration count ends? - This distinction will determine whether each channel needs to generate/mix both its current tone and also the fade out of the previously tone simultaneously.
Incidentally, I just tried running the AGI Demo 2 game (which has the SQ2 demo in it) and it doesn't seem to like it. Navigating to each page of demos with F9 and F10 works once in a while, but I can't hit a number to select a demo to run. It just doesn't respond.
That sounds like something I can hopefully fix more quickly than how the sound sounds. I'll take a look later on.
Keep feeding through any issues you find. I think I'll start adding them as github Issues so that I can track what I've looked at and fixed.
-
For King's Quest 2, the waves breaking are meant to make a noise sound, which I've seen on Youtube videos for the PC JR version. I know that AGILE doesn't sound right for that one either. It sounds a lot more like crashing rather than a wave breaking.
Actually, now that I've tried KQ2 again, the breaking waves in AGILE do sound very similar to SCUMMVM at the moment.
...and now that I've listened again to a video of the original sound, they're both similar to the original machine, but neither one sounds quite right.
https://www.youtube.com/watch?v=clYqTsC3Ww0
https://www.youtube.com/watch?v=OWmXzPMk0ik
https://www.youtube.com/watch?v=IseMpY0OULk
The real machine sounds more... "watery/ocean-y/wavey", hard to describe what I mean, but AGILE and SCUMMVM sound artificial, whereas the original sounds like that wave breaking noise that we hear at the beach. Both AGILE and SCUMMVM seem to have this repeating smashing noise rather than a smoother noise.
-
How difficult would aspect correction be? Ideally switchable.
-
It shouldn't be too difficult to fix the height and width of the graphics so that it maintains the original aspect ratio. At the moment, it stretches to fill the window, which means you can make it look however you want, as the window is resizable. I haven't mentioned it yet, but you can press F11 to toggle full screen as well. I chose F11 to go full screen because it isn't a key that existed back when these AGI games were made, and F11 is the full screen key in browsers, so is familiar.
I'm wondering now how I might support the setting of the aspect ratio correction option. I want to avoid a launcher screen in the app itself, and I'd prefer not to have an options window, so I guess that leaves me with command line options and a config file. Hmmm, I guess I could have a certain key combination pop up an options window, a key or key combination that AGI doesn't use, but I think I'll hold off on that and start with the config file and command line options.
I currently have F12 as showing the priority screen, but that is an "undocumented" feature that I might remove, in fact I'd forgotten that I'd done that. So I could repurpose the F12 key to toggle aspect ratio correction, but there will be more options required at some point, and I'll quickly run out of non-AGI keys, so the config file and command line options will need to be introduced. I guess I could have F11 cover all display options, so F11 is toggle full screen and perhaps ALT-F11 toggles aspect ratio correction. Maybe CTRL-F11 and SHIFT-F11 could be other display related features at some point. I could make F12 multi featured like that as well, to toggle various things. Will I need more than 8 toggleable options? ;D
-
Incidentally, I just tried running the AGI Demo 2 game (which has the SQ2 demo in it) and it doesn't seem to like it. Navigating to each page of demos with F9 and F10 works once in a while, but I can't hit a number to select a demo to run. It just doesn't respond.
That sounds like something I can hopefully fix more quickly than how the sound sounds. I'll take a look later on.
This is happening in all 5 demo packs. Weird. Sometimes F9 works, sometimes it doesn't. For me, F10 seems to work every second time I hit it, and if I hold down F10, then it continuously scrolls through the pages, but it doesn't do the same thing when I hold down F9. The "H" key doesn't work, but SHIFT-H does work, but then "C" works fine without SHIFT.
Time to dig into the LOGIC scripts and my keyboard event handling code.
-
The numbers 1-9 were easy to fix. I literally hadn't mapped those as keys that you can set a controller for! :-[
So I can now start up the games, i.e. hit a number and then ENTER to play, but the F9 and F10 are still temperamental. That issue is different. When they do nothing, there isn't even a "key" on the waiting queue for it, so it must be a bug in the code that tracks when those keys are hit. I haven't started looking at why yet.
Not sure why, for me, the "h" key doesn't work unless I use it with SHIFT. The LOGIC script maps both "H" and "h" to the same thing. Obviously a bug in there somewhere.
Edit: I think I need to review the mappings for all other controller keys, as I think there will be more missing. Yeah, I can see quite a few that are missing. Probably not used much though.
-
Showing the priority screen makes sense given that the original Idea of the project was to be a way to test run a game in development. As to full screen you could just use the standard Alt+Enter that most applications use.
One other thought about full screen and aspect correction is that currently if you have the window stretched for aspect correction and then go to full screen it goes back to the starting aspect, letterboxed. For aspect correction full screen it would have to be pillarboxed. Some might want it stretched top to bottom, left to right.
I am going to try to upgrade to the latest VS in the next day or two so I can build this.
-
I just installed VS2022 and the installer extension and got it to build. What 2019 was not telling me was that NAudio and the AGI library were compiled with a later target framework than AGIL so the build failed. An easy fix. I easily implemented the aspect correction for windowed mode, though it could stand refinement. I just added a context menu in order to not use any of the function keys or adding a menubar and nothing else is using the mouse. It could easily be moved to any where else, from a key press or menubar.
/// <summary>
/// Turn aspect correctiion on
/// </summary>
private void cntxtMenuAspectCorrectionOn_Click(object sender, EventArgs e)
{
this.ClientSize = new System.Drawing.Size(960, 732);
if (cntxtMenuAspectCorrectionOn.Checked == true)
cntxtMenuAspectCorrectionOff.Checked = false;
else
cntxtMenuAspectCorrectionOff.Checked = true;
}
/// <summary>
/// Turn aspect correctiion off
/// </summary>
private void cntxtMenuAspectCorrectionOff_Click(object sender, EventArgs e)
{
this.ClientSize = new System.Drawing.Size(960, 600);
if (cntxtMenuAspectCorrectionOff.Checked == true)
cntxtMenuAspectCorrectionOn.Checked = false;
else
cntxtMenuAspectCorrectionOn.Checked = true;
}
This is just a quick and dirty fix. Turning it off just reverts to your default initial form size. Ideally it would based on the user's chosen overall window size. Also it does not address full screen.
-
The only other thing I notice is that unlike the above footage, the tones don't have a volume envelope. The volume falls off at a certain rate on every tone on the PC jr and Tandy 1000.
Do you think that what the following web page describes is the same thing that you're describing above?
https://www.smspower.org/Development/SN76489#TheImperfectSN76489
If so, then at the moment it seems that I'm outputting the perfect square wave, but the real thing had this decay/leakage going on, that probably wasn't intended, but was a characteristic of the sound (??).
I was reading up on the SN76489 (the IBM PC jr used the SN76496, but it is essentially the same thing) and its use in the BBC Micro. Apparently BBC BASIC implemented a volume envelope within software, in order to create different sounds. I keep thinking back to the NAGI and scummvm source code, which has different dissolve data for different AGI interpreter versions:
https://github.com/scummvm/scummvm/blob/master/engines/agi/sound_pcjr.cpp#L105
Repeating the comment from the above source below:
// 0 = no dissolve.. just play for as long as it's meant to be played
// this was used in older v2.4 and under games i THINK
// 1 = not used
// 2 = v2.9+ games used a shorter dissolve
// 3 (default) = v3 games used this dissolve pattern.. slightly longer
Is this true? Do interpreters 2.4xx and below not have any volume envelope decay happening? And do 2.9XX and V3 games have it, but with different lengths of "dissolve"?
If so, does this imply that the AGI interpreter is using software to manipulate the volume envelope?
I might need @AGKorson to weigh in on this with his knowledge from disassembling the various AGI interpreter versions.
-
As to full screen you could just use the standard Alt+Enter that most applications use.
Yeah, that's a good call. I could support both. I tend to hang out in the browser quite a lot, both while working, and outside work, so F11 is what came to my mind first. But dosbox, scummvm, etc. are using Alt-Enter, so would be good to be consistent with them.
One other thought about full screen and aspect correction is that currently if you have the window stretched for aspect correction and then go to full screen it goes back to the starting aspect, letterboxed. For aspect correction full screen it would have to be pillarboxed. Some might want it stretched top to bottom, left to right.
Yes, I was imagining that if the aspect ratio correction is not active, then it would stretch to fill the full screen in both directions, but if aspect ratio correction is active, then it would be pillarboxed for most people, as they'd generally have a wider screen. How I imagine it working is the same as in scummvm, where if you resize the window, it dynamically adjusts, maintaining the aspect ratio (assuming that option is enabled). So depending on what size you've adjusted the window do, it could be either pillarboxed or letterboxed, within the window.
-
I just installed VS2022 and the installer extension and got it to build. What 2019 was not telling me was that NAudio and the AGI library were compiled with a later target framework than AGIL so the build failed. An easy fix.
That's good to hear, that you having it building now. I tried to make the target framework for AGILE 4.8 everywhere that I could find a setting for it. Is it that, when loading into VS2019, it changes back to an older version of the framework? I haven't tried this myself. I was using VS2017 the last time I worked on it, and VS2015 before that (I think). I did switch to the latest version of NAudio as part of recent changes.
I easily implemented the aspect correction for windowed mode, though it could stand refinement. I just added a context menu in order to not use any of the function keys or adding a menubar and nothing else is using the mouse. It could easily be moved to any where else, from a key press or menubar.
I quite like the idea of a context menu actually. I think it is a good middle ground between a config file/command line options and having a proper menubar or launch screen with options section. My preference is not to have a menubar in the actual game window, but a context menu might be okay. I guess it could support everything, i.e. config file, command line options, context menu, and keyboard shortcuts (assuming they're not used by the interpreter).
I may end up supporting the mouse within the interpreter itself, but that might not be for a while.
This is just a quick and dirty fix. Turning it off just reverts to your default initial form size. Ideally it would based on the user's chosen overall window size. Also it does not address full screen.
Yeah, I agree. It should ideally be based on the user's chosen window size. I haven't yet looked into it though. I've added it as an Issue to the github project, which I'm planning to use as my todo list.
-
I thought an approach to working from the user's chosen window size would be to use the user's width and basing height as a ratio of that width. Shouldn't take that much to modify my code to do it.
As to a config, this is one of the strong points of dotNET. It has a native config system that writes an XML in a %AppData% sub folder. No need to touch the Registry. If you go to properties/settings from the Solution Explorer you can easily add settings to be saved automatically. In my build I have form location and size stored on close. I have also added a lastBrowsePath string to store the last opened game folder, so next launch the browse dialog will open to that folder. For debug purposes I added a "Open User.config" item to the context menu if there are problems. I did encounter a problem with it creating a completely new config on every launch instead of using the previous one. I fixed it by completing the version and file build info in the Assembly Information from Properties/Application tab. Now it uses the same config on every launch, at least per application location and/or user.
Also, several of the references and DLLs in the package are not needed. Some of the references are in the Windows directory. Microsoft.Win32.Registry is not needed by AGILE, So I removed it. Perhaps the installer needs it, but I have not looked at that, yet. For distribution the only files that are needed are the NAudio and AGILibrary DLLs and the main EXE.
-
Navigating to each page of demos with F9 and F10 works once in a while
I have discovered the cause of this one, and have pushed a fix to my github repo. Haven't created a new build yet. The cause was that F10 shifts focus to the window menu, by default. Apparently this is the default behaviour for Windows apps. So what was happening is that F10 shifted focus to there, then pressing F9 after that meant that F9 was never seen by AGILE. It also meant that only every second F10 was making it into AGILE.
I have fixed this by suppressing the keypress event for F10. I found that solution on stackoverflow. Now it seems to be working quite well. The Function keys were tracked through the keydown and keyup events anyway, and not my keypress event handler, so it doesn't matter that keypress is suppressed for F10.
I may have to do something similar for other key combinations that we discover are behaving strangely.
-
// 0 = no dissolve.. just play for as long as it's meant to be played
// this was used in older v2.4 and under games i THINK
// 1 = not used
// 2 = v2.9+ games used a shorter dissolve
// 3 (default) = v3 games used this dissolve pattern.. slightly longer
Is this true? Do interpreters 2.4xx and below not have any volume envelope decay happening? And do 2.9XX and V3 games have it, but with different lengths of "dissolve"?
If so, does this imply that the AGI interpreter is using software to manipulate the volume envelope?
Yes, that is correct. Earlier versions (2.440 and earlier) did not have the dissolve feature. Version 2.089 also had no global volume control (all notes played at whatever attenuation value assigned to the note). Global volume control was added in version 2.272.
In all versions the interpreter sets up a 60 Hz timer that manages sound output. When a sound is playing, at each tick, each channel is checked for a change in note, and then volume is set for each channel (by combining note attenuation with global attenuation).
Beginning with version 2.903, dissolve values were also combined to generate note volume. The dissolve data was an array of 68 bytes in 2.9x versions and 78 bytes in 3.x versions. At each timer tick, a pointer to the dissolve data would increment, until the end was reached (indicated by a value of 0x80h). If the sound was longer than that the last value was used, with no further dissolve changes. In 2.9x versions, the dissolve lasted 68 ticks (1.13 seconds), and in 3.x versions it lasted 78 ticks (1.3 seconds).
I haven't done much analysis of the hardware side of the sounds, so I don't know exactly how the sound chip is controlled. The IN and OUT port opcodes are used to manipulate the chip, but I don't know what exactly is happening.
Dissolve Data for 2.9x:
FE FD FE FF 00 00 01 01
01 01 02 02 02 02 02 02
02 02 03 03 03 03 03 03
03 04 04 04 04 05 05 05
05 06 06 06 06 06 07 07
07 07 08 08 08 08 09 09
09 09 0A 0A 0A 0A 0B 0B
0B 0B 0B 0B 0C 0C 0C 0C
0C 0C 0D 80
Dissolve data for 3.x:
FE FD FE FF 00 00 00 00
00 01 01 01 01 01 01 02
02 02 02 02 02 02 02 02
02 03 03 03 03 03 03 03
03 04 04 04 04 04 05 05
05 05 05 06 06 06 06 06
07 07 07 07 08 08 08 08
09 09 09 09 0A 0A 0A 0A
0B 0B 0B 0B 0B 0B 0C 0C
0C 0C 0C 0C 0D 80
If you want it, I could send you the assembly code for the sound functions so you can examine how the sound chip is manipulated.
-
Yeah, that would be great, especially the bit with the application of the dissolve data. Thanks.
-
As to a config, this is one of the strong points of dotNET. It has a native config system that writes an XML in a %AppData% sub folder. No need to touch the Registry. If you go to properties/settings from the Solution Explorer you can easily add settings to be saved automatically. In my build I have form location and size stored on close. I have also added a lastBrowsePath string to store the last opened game folder, so next launch the browse dialog will open to that folder. For debug purposes I added a "Open User.config" item to the context menu if there are problems.
I also had the idea of saving the window size and location, and the last browse path, in some kind of preferences, but hadn't yet looked into how to implement it. Sounds like we're thinking along the same lines.
Did you want to open a pull request to my repo with those changes? I can then merge them. I'd be quite happy for you and others to start submitting changes.
I did encounter a problem with it creating a completely new config on every launch instead of using the previous one. I fixed it by completing the version and file build info in the Assembly Information from Properties/Application tab. Now it uses the same config on every launch, at least per application location and/or user.
Strange. I would have thought that the same app would pick up the same config. Was it that the config was being associated with the version of the app? Or did I misunderstand? I'd probably have to see the changes to get a better idea of the cause. Glad that you found a fix for it though.
Also, several of the references and DLLs in the package are not needed. Some of the references are in the Windows directory. Microsoft.Win32.Registry is not needed by AGILE, So I removed it. Perhaps the installer needs it, but I have not looked at that, yet. For distribution the only files that are needed are the NAudio and AGILibrary DLLs and the main EXE.
Yeah, I was wondering why those extra DLL files had been added. I couldn't figure out how to stop it from adding those and wasn't sure what it was that had added them. I set up the installer project to use the output of the AGILE project as its input, and for some reason it added those DLLs.
-
It seemed to me that we were thinking along the same lines, too. There were a couple of things that I was going to suggest, like checking for a game in the app's own folder so it could work like NAGI does, but as I started browsing through the code I saw you had already implemented them. My next day off I'll open a pull request.
The reason that it was not using the same config every time is that it automatically generates an AppData folder name if the assembly does not have complete versioning info. No problem if it has all if this info.
-
My next day off I'll open a pull request.
Thanks.
I noticed that you've now forked the repo, so are probably preparing to create the pull request soon. FYI, I was committing a few changes over the past day, so I thought I might list some of the things I've been changing this week:
- I only just pushed a change to also support ALT-ENTER for toggling full screen mode.
- Fixed all of the "key input" issues that MusicallyInspired mentioned earlier from the AGI Demos. There were actually three different issues: (1) 0-9 couldn't be mapped to a controller, now fixed. (2) F10 was shifting focus to the window menu; now fixed. (3) Alpha keys were being added twice in some scenarios; also now fixed.
- Fixed another issue seen in the AGI Demos (and KQ3) where display strings written on top of the status line were being overdrawn each interpreter cycle. The status line is now drawn only in the same scenarios as the original interpreter, so display command text will stay.
-
Yeah, KQ4 is one that I've also noticed takes a while to load. AGILE actually decodes everything up front, which makes it a lot quicker when ego is walking between the various rooms, but for some of the larger games, the delay up front is noticeable. I haven't looked into where the majority of the time is being spent. The LZW decompression of all the V3 resources, in addition to decoding all the resources, might be why the V3 games take a while longer to load.
Ha! How embarrassing :-[ ;D. I just noticed that AGILE is decoding the game twice. It does it once while deciding whether the selected folder contains a game, and then it does it again just before running the game. This obviously wasn't what I intended, so I've just fixed that locally (will push the fix in a few minutes) and the games are now "loading" twice as quickly. So in the case of KQ4, before fixing this, it was taking 8 seconds on my Surface tablet to start up, but now it takes 4 seconds.
I'm still going to add the "Loading..." text, but this change will make things noticeable quicker for some games.
-
I had changed the full screen to Alt+Enter in my fork, too. I am trying to get used to the GitHub Desktop. It is a fair bit different than Bitbucket's Atlassian. After I installed it, it created a tutorial project that I deleted locally, but can't get rid of it on Bitbucket.
I wonder if it might not make a little more sense to move some of the game loading from the Program.cs to a AgileForm Form_Load event. This would allow the form to load right away and display a label that says "Loding". I have added it to load other settings like remembering form location and size.
I changed the aspect correction to base the ratio from the user's chosen width. I have not done anything about full screen aspect correction as that will have to be handled differently.
-
I wonder if it might not make a little more sense to move some of the game loading from the Program.cs to a AgileForm Form_Load event. This would allow the form to load right away and display a label that says "Loding".
Yeah, I was thinking that I would have to make such a change to add in the Loading text.
I am trying to get used to the GitHub Desktop. It is a fair bit different than Bitbucket's Atlassian. After I installed it, it created a tutorial project that I deleted locally, but can't get rid of it on Bitbucket.
I have merged your pull request into my repo now. I'm not sure why, but when I was reviewing the diffs for the pull request, it looked like it had picked up a number of files that I don't think you had changed but were older versions of files that I had recently changed. They were probably the version of those files at the time that you created the fork and I had subsequently made changes to them. So as part of the review, I pushed back edits to your master branch to align those files with the latest version on my master at the moment. This included files such as TextGraphics.cs, UserInput.cs, Interpreter.cs, GameState.cs, and Commands.cs.
After merging the PR, the code wouldn't build, due to the post build events that had been added. They all failed due to the path not being found. The build errors that the github action encountered can be seen on github here:
(you'll need to be logged into github to see them):
https://github.com/lanceewing/agile/actions/runs/3259094831/jobs/5351675917#step:8:84
I had the same errors trying to build it on my PC.
So for now, I have removed those post build copy steps to get the build working again. The build is green again on github:
https://github.com/lanceewing/agile/actions
-
For those who are interested in trying the latest, I have attached the most recently built AGILE zip to this message. This is the one from the latest green build on github.
@MusicallyInspired, do the tone channels now sound closer to what you would expect? I have now implemented the dissolve logic. To me, it sounds a lot better in some of the games I have tried, e.g. KQ4 and BC. I haven't yet changed anything with the noise channel, so in SQ2, the broom noises are still being cut short for some reason. It makes me wonder whether there is a general "cutting short" issue with sounds. I'll probably start looking into this now.
This build also has the various fixes for the AGI Demo 2 that you identified.
And it has Collector's changes, to add the context menu, and the saving of certain state, i.e. last game folder, and the window size and position.
-
Yeah, I didn't make any changes to those AGI classes, only the form and settings files and whatever automatic changes to the AGILE.csproj.
As to the post build events, it would compiled just fine by adding a "bin" directory in the base project directory. Not needed, but I only had it as convenience to not have to dig through the sub folders to get to the new compile. It was also to only copy the needed files without things like the pdb and config files. Only the EXE, the AGILibrary.dll and NAudio dlls are needed for distribution. I had not intended it to be merged with your branch. I am still trying to get used to
I see that it is no longer adding the unneeded DLLs. Not sure if you managed it or it came from my branch. Removing the unneeded references fixed it.
-
I see that it is no longer adding the unneeded DLLs. Not sure if you managed it or it came from my branch. Removing the unneeded references fixed it.
Yeah, that must have come from your changes.
-
I apologize I've been really busy.
If so, does this imply that the AGI interpreter is using software to manipulate the volume envelope?
Yes, as has already been said, this is the case. The SN76489 (and others in the family) just aren't complex enough to have settings for volume envelopes. It just generates the tones at the requested level and duration and that's it. The envelopes are all handled in software. In fact, among the Sierra tools that were leaked semi-recently there's one for the Tandy driver for SCI games that was used to create Tandy patch files that were solely meant for creating custom volume envelopes for each channel per game.
@MusicallyInspired, do the tone channels now sound closer to what you would expect? I have now implemented the dissolve logic. To me, it sounds a lot better in some of the games I have tried, e.g. KQ4 and BC. I haven't yet changed anything with the noise channel, so in SQ2, the broom noises are still being cut short for some reason. It makes me wonder whether there is a general "cutting short" issue with sounds. I'll probably start looking into this now.
This build also has the various fixes for the AGI Demo 2 that you identified.
One thing I noticed right away is it forces me to uninstall the previous version before installing the new one. I kind of wish it would just install right on top of it or at least offer a way to automatically uninstall it before installing instead of having to bring up Control Panel->Add/Remove Programs manually. I tried to install it to one of my additional hard drives but it complains about not having permission to write there (even though it creates the folder just fine) which forces me to run the installer as admin. But these are small gripes, especially for a beta. ;D
That said, yes the sound is great! But unfortunately, while watching the SQ2 demo in AGI Demo Pack 1, the sound resources overlap. When Vohaul shows up on the screen the the SQ2 theme is still playing and doesn't stop. Then on the next screen the hovercraft sound overlaps with itself. And then that overlaps with the next screen, and the final short tune at the end. Basically sounds aren't stopping when they're supposed to somehow along the lines.
And yeah, the broom sound effect seems to be truncated. It does sound like a noise channel sound and not a tone like I previously erroneously thought.
-
I am wondering if it might not be best to just zip Agile. An MSI seems a bit heavy handed for what can used for what is essentially a portable app. It needs no Registry entries or system files written. All settings are saved in its AppData folder during usage.
A zip or even an NSIS installer is more transparent as the files are easily extracted from either. Additionally, a zip distribution would allow the user to simply extract it to an AGI game folder to run that game automatically without any browse for game dialog, like NAGI.
-
One thing I noticed right away is it forces me to uninstall the previous version before installing the new one. I kind of wish it would just install right on top of it or at least offer a way to automatically uninstall it before installing instead of having to bring up Control Panel->Add/Remove Programs manually. I tried to install it to one of my additional hard drives but it complains about not having permission to write there (even though it creates the folder just fine) which forces me to run the installer as admin. But these are small gripes, especially for a beta. ;D
I recall that there was an option, when configuring the installer project, to force uninstall first. I might see what happens if I change that option to false, e.g. does it install on top instead.
That said, yes the sound is great! But unfortunately, while watching the SQ2 demo in AGI Demo Pack 1, the sound resources overlap. When Vohaul shows up on the screen the the SQ2 theme is still playing and doesn't stop. Then on the next screen the hovercraft sound overlaps with itself. And then that overlaps with the next screen, and the final short tune at the end. Basically sounds aren't stopping when they're supposed to somehow along the lines.
Hmmm, okay. I think I know what might be causing that. I'll look at that one next.
And yeah, the broom sound effect seems to be truncated. It does sound like a noise channel sound and not a tone like I previously erroneously thought.
I have found the cause of this. The SOUND resource decoding code wasn't calculating the end of the noise channel correctly. I've fixed this in my github repository and the broom sweeping sounds a lot better now. It will be in the next build I put out, which might be the start of next week.
-
I am wondering if it might not be best to just zip Agile. An MSI seems a bit heavy handed for what can used for what is essentially a portable app. It needs no Registry entries or system files written. All settings are saved in its AppData folder during usage.
A zip or even an NSIS installer is more transparent as the files are easily extracted from either. Additionally, a zip distribution would allow the user to simply extract it to an AGI game folder to run that game automatically without any browse for game dialog, like NAGI.
I wasn't sure what people would prefer. I went with the MSI because I thought they might like to get it added to their Windows menu, but maybe people would prefer to unzip it themselves, wherever they like, such as, like you say, in a game folder. I guess it could be provided in two forms, both an MSI and ZIP. The current ZIP contains the MSI and a setup.exe. When I read up on why the installer project creates both, apparently the setup.exe does checks on dependencies. I wasn't sure if that meant the .NET framework, or other dependencies. If it is the latter, then there are no other dependencies. If someone were to run the MSI directly (rather than the setup.exe), and they didn't have the .NET framework installed, would it prompt them to do so? And is there a difference between how that behaves when running the setup.exe vs the MSI?
What do other people prefer? A ZIP of only the application files themselves? Or the MSI & setup.exe files? If everyone here prefers the ZIP of only the main AGILE.exe and dll files, then I'll go with that. Let me know what you all think.
-
ZIP. I don't ever depend on adding programs to the Start Menu. Just desktop shortcuts if anything. And I do that manually if I wish. I'm not a big fan of installers in general. Though, many appreciate it of course judging by Collector's popular patches and custom installers, but that's a different case really where one is trying to get the original games working properly. I don't even use installers for DOSBox. I wouldn't for ScummVM either but the daily builds only come in installer EXE form so not much I can do about it. But if I could get ZIPs of them instead, I would.
-
First choice Zip, second NSIS. It would be a very simple script and could add it to the start menu and/or desktop. It could also be in the Windows remove program list as well as be treated as a simple ZIP with 7zip. Both a zip and an NSIS installer could be offered and let the user choose which they want to want to download.
I can easily see many that would want to simply drop the Agile files in their AGI game folders to run each game as if it was a native Windows game, or whatever platform Agile will run on.
-
I was experimenting doing and it somehow it got mixed up on my GitHub repo and I can't seem to get it to revert back to the same as your master. It is showing 19 commits that were nothing more than restoring it to the same state as your repo. Not sure if I'll need to remove my Agile repository and rebranch it. From now on I'll do my experimentation on another copy and not my local GitHub repo.
I have a couple of additions that I want to commit. One is just a fix for the context menu to check the chosen aspect ratio item on relaunch. I have also added an argument for the program.cs that would send a selected game folder to Agile on a folder context menu item, "Run with Agile". This would require a static location for the program. Right click on an AGI game folder and select "Run with Agile". Probably needs to give a message if no AGI game is found in that folder and then open the browse dialog.
-
My vote?s for ZIP while you?re still in development. A faster update cycle and your target audience during such probably prefers the zip. When you get to a stable release phase the installer is nice as long at looks/acts modern. The MSI one you?re using doesn?t.
I gave it a look today, and there were two UI-type annoyances I had. I hate that folder dialog. Can you implement something like https://stackoverflow.com/a/15386992/57611 (https://stackoverflow.com/a/15386992/57611), and toggling the aspect ratio correction on and off caused the window to slowly get wider. I would expect changing the aspect ratio to only affect hight.
I can?t really speak to the technical AGI aspects. Leisure Suit Larry worked for the 30s I played it.
-
My vote's for ZIP while you're still in development. A faster update cycle and your target audience during such probably prefers the zip. When you get to a stable release phase the installer is nice as long at looks/acts modern. The MSI one you're using doesn't.
Cool. That's three people in a row so far that prefer the ZIP for now. Windows programming and installers are all new to me, so I wasn't really sure what options I had. I have never heard of the NSIS installer that Collector mentioned. Will need to look that up. Is that an example of a more modern looking/acting one?
I gave it a look today, and there were two UI-type annoyances I had. I hate that folder dialog. Can you implement something like https://stackoverflow.com/a/15386992/57611 (https://stackoverflow.com/a/15386992/57611), and toggling the aspect ratio correction on and off caused the window to slowly get wider. I would expect changing the aspect ratio to only affect hight.
Yeah, I agree about the aspect ratio option. I'll take a look at that. I still have a ticket under the Issues on github to properly implement aspect ratio correction. I know Collector said that this was an initial short term solution for now. I have an idea of an alternative approach that involves keeping the window size the same but adjusting how the image is rendered within it, so that it gets the black bands either above or to the side (letterbox/pillarbox), depending on the window size.
Regarding the folder browser dialog, I also totally agree. I spent a long time searching online trying to make that default FolderBrowserDialog look and behave better, but it seems that it just doesn't have the capability. I think how I have it is about as good as that one gets. I did see that there were alternative implementations to the default one that I could use, so perhaps now is the time to take a look at one of those. Thanks for the stackoverflow link. I think I might give that implementation a go.
-
First choice Zip, second NSIS. It would be a very simple script and could add it to the start menu and/or desktop. It could also be in the Windows remove program list as well as be treated as a simple ZIP with 7zip. Both a zip and an NSIS installer could be offered and let the user choose which they want to want to download.
Is setting up an NSIS installer something that you could try on your fork of the repo? I was thinking I should leave that to someone who knows what they are doing.
-
I was experimenting doing and it somehow it got mixed up on my GitHub repo and I can't seem to get it to revert back to the same as your master. It is showing 19 commits that were nothing more than restoring it to the same state as your repo. Not sure if I'll need to remove my Agile repository and rebranch it. From now on I'll do my experimentation on another copy and not my local GitHub repo.
I'm not familiar with merging forks back to the original repo. I'm very familiar with pull requests that involve merging a feature branch back to master within the same repo, as we use github every day at work, but never with forked repos. I wonder whether the appropriate best practice for forked repos is to create a feature branch in the forked repo, and then do a pull request to get that feature branch merged back into the original repo, from where it could then be merged back to master in the original repo, and then the forked repo could then resync master with the original repo? Just thinking out loud. Will need to read up on the best practice.
I would also have to read up on whether it is possible to "re branch" a forked repo, as you suggested. I'm sure there must be a way, either to rebranch/recreate the fork from the current original repo state, or to bring the forked repo back to exactly the same state as the original repo.
I have a couple of additions that I want to commit. One is just a fix for the context menu to check the chosen aspect ratio item on relaunch. I have also added an argument for the program.cs that would send a selected game folder to Agile on a folder context menu item, "Run with Agile". This would require a static location for the program. Right click on an AGI game folder and select "Run with Agile". Probably needs to give a message if no AGI game is found in that folder and then open the browse dialog.
Sounds like a useful feature. Yeah, if we can work out the best set of steps to follow to merge features from a forked repo, then we can get that submitted as another pull request.
-
NSIS (http://nsis.sourceforge.net/Main_Page) is very flexible. You can easily customize the UI or look. It can have as light of a footprint on the user's system as a self extracting zip, but in a "wizard" form. What I am thinking is that the installer should write nothing more in the Registry than what is required for the uninstaller (little more than a path to the program) and the folder context menu I talked about. The only systems files it would write would be the start menu shortcuts.
I'll write this NSIS installer after I get my Git repo straightened out. I can implement the folder context menu from it. I can also add a preference for it in the options form that simply use the assembly's current path for it, even if the user downloaded a zip instead of the installer.
Right now with my branch you can start a game from:
- The same browse dialog as Lance's main repo, but starting from the last used folder selected. Restarting the same game only requires you to hit enter when the dialog opens.
- Copying the Agile exe and DLLs to a game's folder and starting Agile from there. A shortcut can be made from that copy of the Agile exe to directly run that game.
- Right clicking an AGI game's folder and selecting "Run with Agile". This would work as an IDE add-on where the the IDE would only have to pass a game's folder path to Agile to run it. It could work like SCI Companion's plugin system. Just drop a folder with Agile in it in the IDE's "Plugin" subfolder.
Currently the aspect correction in my branch keeps the current width and changes only the height of the window. My Agile context menu currently includes an open config file for viewing and editing. This is mostly for debugging purposes and can be removed from the release version. It looks for the system's default XML editor and if it does not find one it will offer the user to select one. But mostly the config file will be unseen by the user. Given that the config is unique per location, if a user wants to have a copy in each AGI game like NAGI, each will have its own preferences. Official games could have its aspect ratio set to true, while any fan games that had its graphics created for the wider aspect could have its aspect ratio set to false, for example.
Anyway, this is what I have done with it so far. I'm having a blast playing with this.
-
Right clicking an AGI game's folder and selecting "Run with Agile". This would work as an IDE add-on where the the IDE would only have to pass a game's folder path to Agile to run it. It could work like SCI Companion's plugin system. Just drop a folder with Agile in it in the IDE's "Plugin" subfolder.
Honestly, that feature's a hard pass from me. The amount of folder on my computer that I do not want to open in Agile far exceeds that amount of folders I do. Having a folder-browser dialog that I can paste a url into solves that ease of use problem for me.
Copying the Agile exe and DLLs to a game's folder and starting Agile from there.
That's a good one though. In fact, Agile should automatically check the folder it's run from for a valid AGI game and run it if found, otherwise prompt with the folder browser dialog. And command-line arguments are of course good too.
-
The folder context menu could easily be an option from the installer or a preference setting in Agile itself. If added to a preference dialog it could be added or removed at the users discretion. One other ability it has is that the folder path flag allows is that you can drop an AGI folder on an Agile shortcut to start the game, with or without the folder context menu.
Agile already checks its folder the see if there is an AGI game in it, first.
-
Agile already checks its folder the see if there is an AGI game in it, first.
Oh awesome. I didn't realize.
-
I gave it a look today, and there were two UI-type annoyances I had. I hate that folder dialog. Can you implement something like https://stackoverflow.com/a/15386992/57611 (https://stackoverflow.com/a/15386992/57611), and toggling the aspect ratio correction on and off caused the window to slowly get wider. I would expect changing the aspect ratio to only affect hight.
Yeah, I agree about the aspect ratio option. I'll take a look at that. I still have a ticket under the Issues on github to properly implement aspect ratio correction. I know Collector said that this was an initial short term solution for now. I have an idea of an alternative approach that involves keeping the window size the same but adjusting how the image is rendered within it, so that it gets the black bands either above or to the side (letterbox/pillarbox), depending on the window size.
Going back to this one, do people have a preference with regards to how the aspect ratio correction works? The current quick solution that Collector implemented adjusts the window size to make the aspect ratio correct. This works because the image inside the window automatically stretches to fill the window. I've been working on an alternative implementation, as mentioned above, where the window size stays the same, but the image inside the window is adjusted, so that we get those letterbox/pillarbox black bands. I don't see any issue with that, as its exactly how scummvm does it, and it has to be done that way for full screen in any case. It seems to be working quite well. I just added an event handler for the window resize and adjusted the PictureBox to match, keeping it centered, and maintaining the aspect ratio. I can set it up such that this happens only when the aspect correction option is ticked, and if it isn't, then it would instead fill the window size as it currently does.
-
I don't see a need to pillarbox or letterbox a window. Full screen is another matter. This is how DOSBox handles it, even if the window size cannot be changed on the fly without access to its command line. My current method merely adjusts height, keeping the user's current width. It also remembers aspect correction between sessions. The main reason for the selection is for the proper aspect for which the art was created. All of the official games' art would be best with aspect correction, but many of the fan games' art would have been made without.
What might be nice whichever option is selected, is to force it to keep the same aspect ratio when a window is stretched. I might be able to implement this.
-
What might be nice whichever option is selected, is to force it to keep the same aspect ratio when a window is stretched. I might be able to implement this.
This is essentially what I have implemented. - Edit: Actually, perhaps you meant to keep the window size in the same aspect ratio when resized. I'm not doing that yet, but I can see how that would avoid the need for the letterbox/pillarbox affect.
Since my last post, I've come up with a hybrid between your code and the "keep same aspect ratio when the window is stretched", in relation to the PictureBox. So what I've got it doing at the moment is that when the aspect ratio correction is turned on, it adjusts the GameScreen PictureBox size to the correct aspect ratio to fit in the current window size (depending on the current window dimensions, this might mean that it matches either the width or the height, whichever is appropriate for the current dimensions) and then it crops the window size to exactly fit that adjusted GameScreen size, which is using your code. Then if the user happens to adjust the window size, which I do a lot actually, then they will get the letterbox/pillarbox effect (Edit: Although, as mentioned above, I guess we could dynamically adjust the window size to keep it cropped to the PictureBox when not in fullscreen mode). I don't think it makes sense to adjust the window size when exiting out of aspect correction mode though, in fact I think that is what caused the issue Charles reported. So I've removed the ClientSize adjustment that was happening when turning off aspect correction and instead the image just fills up, i.e. stretches to fill, whatever size the window is currently in (i.e. when aspect correction mode is off).
I'll create a branch on my repo, and a PR associated with it, so that you can see the changes I've made. I think it works quite well. I'll leave it unmerged and just as example code for now, until we agree how the whole thing should work.
I guess whichever way we go, the new code I've written works well for full screen, so is good for that scenario.
-
In my branch when correction (4:3) is turned off the width remains the same and only the height reduces to 8:5 ratio. If the problem is that the the window becomes taller than the display's height. Easy enough to add a check to prevent that.
-
I've got it all working quite nicely now, both in full screen mode, and window mode.
This pull request describes and shows the changes:
https://github.com/lanceewing/agile/pull/12
https://github.com/lanceewing/agile/pull/12/files
The magic is mostly happening in the new AdjustGameScreen method. The description text in the pull request describes what it is doing.
I have attached a new build with those changes from the associated feature branch. I haven't merged it to master yet, as not sure if this behaviour is what people prefer. Give it a go to see what you think.
@MusicallyInspired, this build also has the noise channel fix. The SQ2 broom sweeping sounds much better now.
-
Works pretty well for aspect correction. What about doing the same thing for an 8:5 ratio for no aspect correction? we could add a stretch item to the context menu that would allow the user to stretch the window to any dimensions they want. This could allow the old behavior to completely fill the screen in full screen mode.
-
So your proposal is to support three different modes, 4:3, 8:5, and stretch? Yeah, that should be straight forward, I just need to add an extra bit of calculation code into that AdjustGameScreen method for when aspect correction is turned off, and it would only do that if the stretch option is also turned off. Do you think the 8:5 mode would get much use?
I was playing through KQ2 yesterday (over half way so far) and its quite nice being in the 4:3 mode. That's what I'm preferring as a user, in fact I am wondering now whether it is better if a completely clean install of AGILE (with no preferences saved yet) should maybe start in the 4:3 mode from the beginning. It is the original look, as you say, so seems to make sense to start like that.
I'll start adding the 8:5 calculation to my branch now.
Edit: I've just been having a look. I think to implement the Stretch mode, we will need to change the tick boxes to work more like radio buttons. What I mean is that we wouldn't be able to support unchecking an option, e.g. unchecking Aspect Correction On. Currently when the user does that, it is assuming that the Aspect Correction Off option should be automatically checked in response, as there are only two options, but with the introduction of Stretch, then it won't be able to do that. So I think unchecking would be ignored, and changing modes would require clicking the new mode to switch to.
Edit 2: I have an initial version of it working locally. I have noticed that when I repeatedly switch between the 4:3 and 8:5 modes, the window gets smaller on each iteration. I'm going to make it a bit smarter so that this doesn't happen.
Edit 3: Found the bug. AdjustGameScreen was checking current window dimensions when deciding whether to adjust the width or height rather than the screen dimensions. That is obviously wrong. Should have it fixed in a couple of minutes.
-
Those changes are now complete and I think working quite well. I've pushed the changes to the same pull request, so you can see them here:
https://github.com/lanceewing/agile/pull/12/files
A new build of AGILE from that code is attached for you to test out.
I'll now get back to my playthrough of KQ2 :)
-
The checked state of the aspect items would be a rather trivial thing to do. Just clicking one item would uncheck either of the other two. Checking stretch would uncheck aspect correction and no aspect correction. There is no radio button options available in a Winforms context menu strip, but if you look at my code for the click event of the context menu items you'll see that it unchecks the other if checked. The same logic can easily be expanded to three items to make them behave like radio buttons.
I have added an aspect bool to the settings file to remember checked states between sessions. Would have to modify this setting to include stretch. Maybe a string instead that holds the name of which option was last selected. I have added a full screen option to the context menu and have changed the settings to retain screen metrics only if exiting in windowed mode in my build. I have not uploaded this to my GitHub repo, yet.
-
The checked state of the aspect items would be a rather trivial thing to do. Just clicking one item would uncheck either of the other two. Checking stretch would uncheck aspect correction and no aspect correction. There is no radio button options available in a Winforms context menu strip, but if you look at my code for the click event of the context menu items you'll see that it unchecks the other if checked. The same logic can easily be expanded to three items to make them behave like radio buttons.
Yeah, the above describes exactly how I implemented it. You can see it if you scroll to the bottom of the page showing the file diffs:
https://github.com/lanceewing/agile/pull/12/files
I have added an aspect bool to the settings file to remember checked states between sessions. Would have to modify this setting to include stretch. Maybe a string instead that holds the name of which option was last selected.
Yeah, that would be good. I was thinking that it would need this setting.
I have added a full screen option to the context menu and have changed the settings to retain screen metrics only if exiting in windowed mode in my build. I have not uploaded this to my GitHub repo, yet.
Adding full screen to the context menu is another good feature.
Have you tried my new build yet (attached to my previous message)? Is it now behaving like you'd expect, with regards to 4:3, 8:5, and stretch modes?
-
Yes, I've tried it. I still need to get my repo on GitHub sorted out.
-
I announced it on the SHP forums to see if we can get a few new testers. http://sierrahelp.com/forums/viewtopic.php?f=86&t=6124
-
Cool, thanks. I see that you've added the Fullscreen option to that one, and incorporated my changes as well. Do you have the code in your repo yet? I would like to merge back some of the features I don't have yet.
I hadn't mentioned it so far, but I finished the playthrough of KQ2. I found a couple of bugs along the way, one of which is fixed on my master branch.
-
I have been fighting GitHub and finally think I have sorted through whatever issues I was having. Somehow I did not find it as intuitive as Bitbucket with Atlassian's SourceTree. I have made a pull request.
-
Thanks, I'll take a look. I assume you have noticed "Mark Yu" getting quite involved in the project. I first noticed him when he forked the repo a few weeks back, and since then he has submitted a few pull requests and been involved in discussions with me with regards to some of the outstanding issues. You can see them under the Issues page in github. He discovered an interesting character encoding issue in KQ2, with the sign behind the tree that promotes other games. Turns out the AGILibrary wasn't treating characters as CP437 when coverting the bytes to a string, so none of the extended characters were rendered properly. The promo in question was using the 0xFF (non-breaking space), which AGILE was rendering as "?". I'm about to merge a fix for that one. After that, all extended characters will render properly in AGI text mode (and even the graphics mode actually, but I know that the original AGI interpreter didn't render extended chars properly in graphics mode; only text mode).
I'm then going to review one of his pull requests, the one that fixes the SQ promo easter egg seen through the hole in KQ2. I discovered that bug during my KQ2 playthrough, raised the Issue, and Mark discovered the cause and a fix a few hours later. Turns out it is related to an issue I "fixed" when I played MH2 back in 2019, but my "fix" seems to have introduced a different bug. Looking back at my fix, it looks more like a workaround, so I might revisit that fix to see exactly what the issue in MH2 was, as I can't remember now, and I didn't create a Bitbucket issue at the time, or put enough detail into the commit comment. I guess that rediscovering it will involve temporarily reverting some code back to how it was back then, playing MH2 for a bit, and then hopefully rediscovering what the issue was.
-
I have been fighting GitHub and finally think I have sorted through whatever issues I was having. Somehow I did not find it as intuitive as Bitbucket with Atlassian's SourceTree. I have made a pull request.
I've just been reviewing it. It looks like the pull request was initially reverting some of my recent changes to the AnimatedObjects and Defines classes. I know that you wouldn't have made those changes, so I think it must be another merge conflict resolution bug. I've fixed both and pushed back to your repo, so they are no longer in the pull request.
-
@Collector, I have just merged some changes to add the "Loading" message while a game is being decoded. Now when AGILE first starts up, it shows the AGILE window immediately and then goes into the logic of selecting the game folder and decoding the game. While the game is being decoded, a message is displayed within the middle of the AGILE game screen (in the AGI font) saying "Loading... Please wait". I implemented this by doing what we were discussing earlier, i.e. moving the game folder selection and decoding into the AgileForm class.
The changes are showing in this PR:
https://github.com/lanceewing/agile/pull/23/files
-
Made one slight addition. I added a call to AdjustGameScreen after the form gets last settings for the
context menu aspect correction to sync Agile's window with selected aspect setting.
-
Thanks, I've just merged it.
Mark Yu found another bug, this time seen in KQ1, where, after a restart, none of the controllers were working. Turns out that AGILE was clearing the key to controller mappings as part of a restart, whereas the original AGI interpreter clears only the current state of the controllers, not the key mappings. I think I misread the original AGI interpreter source code fragments when I first wrote that bit. Anyway, that issue is now fixed and recently pushed to master.
-
Made one slight addition. I added a call to AdjustGameScreen after the form gets last settings for the
context menu aspect correction to sync Agile's window with selected aspect setting.
I've just pushed a small change inside the ToggleFullscreen method, as I noticed it wasn't updating the full screen option in the context menu. So when using ALT-ENTER to toggle full screen, the tick in the context menu wasn't reflecting that. I've added a line inside ToggleFullscreen to set the context menu option to match the full screen state after the toggle.
-
Looks like all of the features are coming together. Now if we could get a few more testers to play through some of the games to squash some of the bugs. I could ask on some of the Sierra Facebook groups to see if there are any takers.
-
Trying SQ2 with the latest build Collector posted on the SHP forums. The sound of the sweeping is still wrong (though it sounds like the truncation problem is solved). I decided to test between AGILE, ScummVM, and DOSBox to see how they all measured up. To my surprise it seems like ScummVM doesn't produce the sound correctly either. So while ScummVM has the best tone emulation (until now) with its volume envelope on the notes, DOSBox has the best noise emulation. I took a screen capture. The first one (top left) is AGILE, the second one (top right) is ScummVM, and the bottom one is DOSBox.
https://drive.google.com/file/d/1tFzwrzeT_8URmg6C_f_Lv3VTWRibc-zZ/view?usp=share_link
EDIT: I decided after to do a tone comparison as well and was surprised again at the result. AGILE's tone generation sounds perfect and crisp. ScummVM's tone is great but it sounds like it's also aliasing. And DOSBox's sounds like there's a filter over it so the crispness is lost. Or perhaps the tones generated are not perfect square waves? The tone falloff is also not as noticeable. Just thought it'd be an interesting share. So AGILE's tone generation is the crispiest of them all! :D
https://drive.google.com/file/d/1JZJG1Unfuh8oIXblXZHeJhgaKqIBrknT/view?usp=sharing
-
Agree on the noise channel. DOSBox does it more like what you would want, at least without hearing it on an actual Tandy.
Yeah, you can hear the difference with tone, petty much as you inscribed. SVM does sound as if it is using some sort of smoothing and DOSBox sounds muffled.
-
Was testing with Donald Duck's Playground. There is a hacked version of either the booter or Amiga version, I forget which, to run in DOS. If you run the game in DOS and press the Escape key it crashes with:
"Bad action: 161
Press ESC to quit."
In Agile it does not crash. However, I realized that the menubar is not hidden when you press ESC again. This is true of this hacked version as well as v1.50 int2.440. This does not occur in DOSBox. Going to a new room does reset the menubar in AGILE. This is not an issue with SQ1. I'll have to see if this occurs in any other game.
Lance, do you need either DDPG to check it out?
-
Trying SQ2 with the latest build Collector posted on the SHP forums. The sound of the sweeping is still wrong (though it sounds like the truncation problem is solved). I decided to test between AGILE, ScummVM, and DOSBox to see how they all measured up. To my surprise it seems like ScummVM doesn't produce the sound correctly either. So while ScummVM has the best tone emulation (until now) with its volume envelope on the notes, DOSBox has the best noise emulation. I took a screen capture. The first one (top left) is AGILE, the second one (top right) is ScummVM, and the bottom one is DOSBox.
https://drive.google.com/file/d/1tFzwrzeT_8URmg6C_f_Lv3VTWRibc-zZ/view?usp=share_link
Thanks for sharing that. Yeah, I can definitely hear that all three sound different.
Did I mention yet that I managed to find the full SQ2 game playing on an IBM PC JR and Tandy 1000 on Youtube? We could add that as a 4th and 5th comparison.
There's this one:
https://www.youtube.com/watch?v=hZI-2nqGe_o
which says IBM PC in the title, but it is playing the 4 voice sound, so I think it must be the IBM PC JR. Edit: It doesn't really look like a PC JR though. Could standard PCs have the PC JR sound added?
There are a few Tandy 1000 videos as well of SQ2.
EDIT: I decided after to do a tone comparison as well and was surprised again at the result. AGILE's tone generation sounds perfect and crisp. ScummVM's tone is great but it sounds like it's also aliasing. And DOSBox's sounds like there's a filter over it so the crispness is lost. Or perhaps the tones generated are not perfect square waves? The tone falloff is also not as noticeable. Just thought it'd be an interesting share. So AGILE's tone generation is the crispiest of them all! :D
https://drive.google.com/file/d/1JZJG1Unfuh8oIXblXZHeJhgaKqIBrknT/view?usp=sharing
Cool! Nice to know :D
-
Just noticed that if you minimize the Agile Window when you restore it the window is unusably tiny.
-
I found and fixed the problem with the restoration of the minimized window, but it won't let me do a pull request. Don't know if it is because of my previous request has not been commited or not. It was a simple fix. In the form resize method I added a FormWindowState check state before it allows the AdjustGameScreen. It no longer fires if the window has been minimized.
-
Thanks. I have merged your PR now, so both of those changes are now on master.
Initially it didn't compile after the merge, due to the generated settings designer file being out of sync with the new setting, but I fixed that on master by regenerating the designer class. It is compiling fine now.
-
Was testing with Donald Duck's Playground. There is a hacked version of either the booter or Amiga version, I forget which, to run in DOS. If you run the game in DOS and press the Escape key it crashes with:
"Bad action: 161
Press ESC to quit."
In Agile it does not crash. However, I realized that the menubar is not hidden when you press ESC again. This is true of this hacked version as well as v1.50 int2.440. This does not occur in DOSBox. Going to a new room does reset the menubar in AGILE. This is not an issue with SQ1. I'll have to see if this occurs in any other game.
Okay, thanks. I will hopefully have some time today to take a look. Just working my way through the pull requests that have been submitted from Mark. He has been finding and fixing a few more things.
I think the hacked version of DDP might be the one for download on Al Lowe's website, and if so, then I guess that is a version that is going to be quite common, perhaps even the most common these days.
Lance, do you need either DDPG to check it out?
I have both already (Edit: Assuming the one on Al Lowe's website is the hacked one)
-
I grabbed the one for Al's site and it did seem to be the same, but Agile didn't ID it as an AGI game. Turns out that the game data files are read only, but turning that attribute off allows Agile to recognize it as AGI.
It is the same. Note that the logdir hash is that of the Amiga version.
-
A follow up to MI's observation on the noise channel. The crashing waves sound on the beach of KQ2 in Agile has a weird reverb. I DOSBox there is next to no reverb. SVM has this reverb, too, but slightly more muted than Agile.
-
Turns out that the game data files are read only, but turning that attribute off allows Agile to recognize it as AGI.
That's strange, about the read only. Oh, I think I know why. I'm using the AGI Library, built for Visual AGI, so it probably opens all files in read/write mode, regardless of whether it is for reading or writing. There would be no need for AGILE to open for writing. I might be able to change that in the Library.
-
It's been confirmed by a friend of mine that DOSBox actually does impose a filter over the Tandy 3-voice tones after some digging he did in the past to find out why it sounded different. His quote:
I believe it's because pure squarewaves sound "weird" when played through what amounts to high-end stereo equipment (our modern speakers)...
(high-end from the point of view of 80s gear)
So it's doing a sort of simulation of "cheap speaker buried in a metal box"
-
Not sure about that. Accurate sound emulation has been a priority for Qbix. Unfortunately he has not been around much lately to ask. He does not seem to be much of a fan of anti-aliasing of graphics, either.
-
I think I know why. I'm using the AGI Library, built for Visual AGI, so it probably opens all files in read/write mode, regardless of whether it is for reading or writing. There would be no need for AGILE to open for writing. I might be able to change that in the Library.
It should have had a read only error message rather than simply "no AGI game found". I don't know if I or anyone else will pick up Visual AGI again, but it would be nice to have these improvements/updates to the library usable by the IDE, too. Perhaps fix it to be switchable with an "if" or conditional statement that would allow the library to be used by either.
-
Hello,
Mark here (vafada in github) just dropping by to say hello and I guess this is the place to discuss AGI development.
Thanks Lance for open sourcing AGILE and JAGI!
I've learned a lot about gamedev by just looking at code of those 2 projects.
Loved Sierra games when I was growing up. And now as a programmer, learning how Sierra games work was mind blowing and exciting!
-
Mark here (vafada in github) just dropping by to say hello and I guess this is the place to discuss AGI development.
Welcome Mark! Yes, this is the current place to discuss AGI and SCI development. There have been several message forum websites in the past that were used, but they've all gone now. I think the previous one for AGI died back in 2010, ironically just as I was rejoining the community after being away for over 10 years.
Thanks Lance for open sourcing AGILE and JAGI!
And thanks for helping out with the fixes.
JAGI was already open source on sourceforge, written by the mysterious "Dr Zoltan". I still to this day have no idea who that was. I was using JAGI to explore some of the Apple II AGI v1 games a few years back.
-
Welcome, Mark! Now all three Agile branches are represented in this thread. This is more or less the inheritor of the old Mega Tokyo forum. If you noticed some members here have "MT Veteran" for the Mega Tokyo forum. I do not have it because even though I used to post there I never setup an MT account because it allowed guest posting. Mega Tokyo is where I first met some of the Sierra community People, like Omer Mor.
After MT, Cloudee started this site for SCI and the AGI forum moved on to the one on Chris Cromer's old agigames.com. When that went under Cloudee added the AGI forum here. Since then many of the old AGI people have found their way here, not just Lance, but others including Chris Cromer, Peter Kelly and others. If you recognize any of the names of fan AGI game designers you will find a number of them here.
With Phil's SCI Companion and its fantastic decompiler & plugin system We have some great SCI development tools with some new SCI utilities popping up here and there. Robert Lindsey, the lead programmer for KQ6 has seen the SCI decompilation archive and said he had a real kick strolling down memory lane reviewing a lot of the source code he originally wrote.
Now we are getting some new AGI tools with Andrew Korson's WinAGI in active development and now AGILE.
-
Somebody on SHP noticed popping during the intro to Manhunter when the ships are circling the mountain. The pop seems to be just before the initial sound attack.
-
Yeah, I think I've heard some popping here and there as well. I'll create an Issue for it.
-
That's Manhunter 2.
-
where can i get a legit copy of both manhunter ? steam and GOG doesn't sell it
-
Huh. Seems like you're right. I bought (or I should say "re"-bought) a lot of my Sierra games again from GOG. Over the years, I've probably bought some of these games (digitally) a second or third time. But you're right about the Manhunter games. Obviously you can buy them physically on things like ebay, but they may not work these days, and seem rather expensive compared to the digital forms. I was trying to copy my old original game disks to disk images recently and almost all of them had bad sectors, or perhaps the floppy drive was no good (tried about 5 different drives with varying success). I think this is where something like the Kyroflux that @Collector uses would come in.
So given that it doesn't appear to be possible to buy them anymore, then I guess this is kind of an Abandonware scenario? It is sad really, as I quite liked those games.
I'm not sure how archive.org get away with this kind of thing, but both games are available to play online on there, and if you check the browser network tab, you'll see that they download the games files, e.g.:
https://archive.org/details/msdos_Manhunter_2_-_San_Francisco_1989
downloads this zip:
https://cors.archive.org/cors/msdos_Manhunter_2_-_San_Francisco_1989/Manhunter_2_-_San_Francisco_1989.zip
which contains the game files.
-
I can provide most of the AGI games. PM me the next time you need one.
-
In Agile it does not crash. However, I realized that the menubar is not hidden when you press ESC again. This is true of this hacked version as well as v1.50 int2.440. This does not occur in DOSBox. Going to a new room does reset the menubar in AGILE. This is not an issue with SQ1. I'll have to see if this occurs in any other game.
I found the bug that was causing this and have fixed it on the master branch.
-
Somebody on SHP noticed popping during the intro to Manhunter when the ships are circling the mountain. The pop seems to be just before the initial sound attack.
I've found the cause for this one as well. This stackoverflow explains the problem:
https://stackoverflow.com/questions/34946363/pop-at-the-beginning-of-playback
...and sure enough, I'm generating a header section for the WAVE data, but NAudio doesn't need that, in fact it is playing it as if it is audio data!! ;D
Removing the header from the data has stopped the popping. I'll push the fix soon.
Edit: That is now fixed and pushed to the master branch.
-
https://cors.archive.org/cors/msdos_Manhunter_2_-_San_Francisco_1989/Manhunter_2_-_San_Francisco_1989.zip
which contains the game files.
how do you play this with AGILE? the file are named differently... no DIR files.... VOL file has mh2 prefix
-
how do you play this with AGILE? the file are named differently... no DIR files.... VOL file has mh2 prefix
This is how an AGI V3 game is recognised. They have a DIR file with the game ID as the prefix, and likewise the VOL files have the game ID as the prefix as well.
I didn't actually try running it until now, but yeah, its not being recognised by AGILE. It is because the MH2DIR file is in lowercase, in fact all the files are lowercase in that zip, but AGILE in the most part tolerates that. There is a bug in the AGILibrary where it deduces the V3 game signature (id) by using the DIR file, i.e. it looks for the prefix before the DIR bit to get the V3 signature. That is failing because the C# code in that bit is not case insensitive. It's a quick fix that I've made locally and confirmed it works. I'll push that soon and will let you know when done.
-
I've just pushed the fixed AGILibrary version to the AGILE master branch and have confirmed the game now loads and plays.
-
Have you had a chance to look at the NSIS installer script? An MSI seems rather heavy handed for something that really does not need to be installed. Plus, as I mentioned, an NSIS installer can be treated like a simple zip with 7zip. The script also gives the user the option to add the "Run in AGILE" folder shell extension, which can be easily removed by either the uninstaller or from the AGILE options dialog.
All you need is to install NSIS (https://nsis.sourceforge.io/Download) and drop my AddOptions.nsh into the NSIS "Include" folder. You only need to edit the "!define RESOURCE_NAME " path in the script to match the folder with the binaries. For an editor you can use Notepad++, HM NIS EDIT (https://hmne.sourceforge.net/) or even my SCI Companion plugin, NSISPublisher.
I used a GPL as the license and the README.md for a readme file, but can be whatever you decide.
-
I installed NSIS, then the Registry plugin, as that didn't come be default. A couple of warnings when it ran, about the language, but it has successfully produced a file called AGILESetup.exe.
When I run it, the installation works fine. I get the option in the windows menu, and on the desktop. Both of those work.
Unfortunately the "Run in AGILE" folder extension isn't working. I'm getting the following message:
Windows cannot access the specified device, path or file. You may not have the appropriate permissions to access the item.
which is quite strange, as these are all folders that I've created myself, and copied the files inside, and I'm trying the "Run in AGILE" option with the same user.
I've checked the Security permissions on the folder, and my user has full control, but it still isn't working. Any tips for what might be wrong?
-
I have located the problem. A tool that I have used for years to convert exported reg files to NSIS script used to work flawlessly has started to add extra escape characters to the script. I have it fixed and will have it replaced on my repo after I get back from work today.
-
Thanks @Collector. I can confirm that it is now working for me. I really like the ease at which the game can be run using the folder shell exception. Very useful.
Regarding the choice of open source license, I don't really know the difference between the various licenses, so I'll go with whatever the rest of you recommend. You have it as GPL2 at the moment. Is GPL2 a good one? I see that there are various others that appear to be more commonly used, e.g. in the Top 20 list below:
https://www.synopsys.com/blogs/software-security/top-open-source-licenses/
What are the main differences? And what do you think would be appropriate for something like AGILE? The page linked to above discusses the "risk" from a commercial project perspective, so doesn't directly apply here (unless a company wanted to create a commercial product using AGILE).
Another interesting article here:
https://www.mend.io/resources/blog/open-source-licenses-trends-and-predictions/
It shows that GPL licenses are declining in popularity each year, whereas permissive licenses, such as the MIT and Apache one, are in general growing when compared to copy theft license usage.
I guess it doesn't matter much for AGILE, because I doubt that a commercial product is going to use it, and perhaps we wouldn't want it to anyway. I like the idea of anything based on AGILE also being open source.
-
Trying SQ2 with the latest build Collector posted on the SHP forums. The sound of the sweeping is still wrong (though it sounds like the truncation problem is solved). I decided to test between AGILE, ScummVM, and DOSBox to see how they all measured up. To my surprise it seems like ScummVM doesn't produce the sound correctly either. So while ScummVM has the best tone emulation (until now) with its volume envelope on the notes, DOSBox has the best noise emulation.
It might take a while for me to work out why the noise emulation is wrong. I can't see the problem at the moment. I tried dropping the dosbox code into AGILE (with obvious conversion from C to C#) and it didn't seem to make much difference that I could hear. AGILE still sounded wrong, and still different from dosbox. The only bit of code from dosbox that I tried though was specifically the bit that shifts the LFSR and taps the feedback bits, as I assumed that that would be where the main difference affecting sound would be. Apparently not though.
The dosbox code for handling the LFSR feedback is certainly different from AGILE, in fact the dosbox source code seems to be different from the comment at the top of the file that describes how the feedback works. At least I couldn't tie back that description to the code. But as I say, despite it being different, using the dosbox feedback approach didn't make a noticeable difference, and AGILE still sounded wrong. So I'm beginning to think that the issue is outside of the shift and feedback part of the code.
-
It's really authentic already at any rate. If it had to be this way forever and couldn't be fine-tuned it wouldn't be the worst thing.
-
Thanks @Collector. I can confirm that it is now working for me. I really like the ease at which the game can be run using the folder shell exception. Very useful.
Regarding the choice of open source license, I don't really know the difference between the various licenses, so I'll go with whatever the rest of you recommend. You have it as GPL2 at the moment. Is GPL2 a good one? I see that there are various others that appear to be more commonly used, e.g. in the Top 20 list below:
https://www.synopsys.com/blogs/software-security/top-open-source-licenses/
What are the main differences? And what do you think would be appropriate for something like AGILE? The page linked to above discusses the "risk" from a commercial project perspective, so doesn't directly apply here (unless a company wanted to create a commercial product using AGILE).
Another interesting article here:
https://www.mend.io/resources/blog/open-source-licenses-trends-and-predictions/
It shows that GPL licenses are declining in popularity each year, whereas permissive licenses, such as the MIT and Apache one, are in general growing when compared to copy theft license usage.
I guess it doesn't matter much for AGILE, because I doubt that a commercial product is going to use it, and perhaps we wouldn't want it to anyway. I like the idea of anything based on AGILE also being open source.
I was not really choosing a license, just grabbed one I had to build the installer. I have no preference which one. Just need replace the existing one with whatever chosen license in the NSIS-Installer folder and change the file name in the script accordingly. I have no problem with a permissive license, but would like anyone that uses it for something else keep their project open source, too.
https://choosealicense.com/
-
@lance.ewing
I'm still watching the repo... I've been playing PQ, trying to finish the game using AGILE. PQ is such a pain to play (not fun)
So far, no issue are popping up... so I haven't been posting issue... So its been quiet on my end.. but yeah I'm still lurking behind the scenes.
-
@vafada, no more issues is good news. You found a couple in PQ. I guess with each new game tested, we might find additional issues. It seems to be the way so far. I am planning to start playing through another game soon. I'm thinking either SQ1 or GR.
-
I decided on playing through SQ1, the version using v2.089 of the AGI interpreter. The one issue I've found so far is that the quit command doesn't have a parameter in that version of AGI, which I had a placeholder TODO comment in the code for already but hadn't got around to implementing. That is now fixed though. I'm getting close to the end of the game. Should finish it later today.
-
As expected, AGILE happily ignores CPC since it is tied to the original Sierra interpreter, not the game data.
-
Yeah, obviously no issue with that form of copy protection. I have been thinking about adding a feature to detect the games with questions at the start, e.g. MH1, GR, KQ4, LSL, and automatically skip those checks, as they're quite annoying. Shouldn't be too difficult to implement.
I have finished playing through SQ1. Next on the list for me to play is Gold Rush. vafada finished playing through PQ and found another interesting bug to do with add.to.pics in the final scene that has now been fixed.
Has anyone noticed that the Folder Browser Dialog sometimes doesn't scroll down to the selected folder, even though a folder is preselected? Quite often it does scroll down, but not always. I've found a workaround to make it always scroll down to the selected folder, but it is a bit hacky, so I thought I'd ask if anyone else has noticed this issue before I put the hack in to address this.
-
Setting the root folder to RootFolder "MyComputer" is supposed to do that. Since adding that I have not noticed it not scrolling to the selected folder. The only thing that I can think of is that it is not loading its config file or the lastBrowsePath value is null or invalid. When it happens is MyComputer selected? I am curious as to the hack you devised.
I like the idea of skipping the CP questions. Gold Rush v3 (Software Farm version) has no copy check questions, which is why I always use it when I play the game. What about making skipping optional? Skipping the age questions in LSL would be nice as well. I don't remember if LSL1 has different "dirtyness" levels based on how well you do with the age questions the way some later games in the series.
Skip CP and Dirtyness checkboxes could be added to the options form.
-
As to the folder browser scroll to selected, I found this: https://social.msdn.microsoft.com/Forums/windows/en-US/6df8e181-750e-4e14-b707-96ff5c6f43c4/set-folderbrowserdialog-focus-on-treeview-on-the-selected-folder-in-c-winform?forum=csharpgeneral
-
Setting the root folder to RootFolder "MyComputer" is supposed to do that. Since adding that I have not noticed it not scrolling to the selected folder. The only thing that I can think of is that it is not loading its config file or the lastBrowsePath value is null or invalid. When it happens is MyComputer selected? I am curious as to the hack you devised.
By "My Computer" do you mean "This PC"? That is the name of the top level node in the tree for me, which I assume is the same thing. Yeah, searching that online a bit, it sounds like it was renamed a few years back, and its the same thing. So given that, then yes, "This PC" is always at the top of the tree of nodes, regardless of whether the scroll down happens or doesn't happen, and in both cases the preselected game folder is highlighted. What I mean is that even though the selected folder is always highlighted, it is sometimes not visible as it is outside the area currently shown, due to it not having scrolled down. It has the feel of a timing issue, e.g. perhaps the scroll bit sometimes kicks in before the selection has been fully applied, but that is just a wild guess. No idea what the code for that component looks like.
The hack I devised is simply to issue a couple of key strokes in code. For example, the down key followed by the up key caused it to scroll down to the selected folder, and the net effect is that it is still selected. The down key would actually move one item down in the list of folders, and the up key would move back up one item, thus taking it back to where it started. This is really hacky, but seems to work for me. But if no one else is seeing this, then maybe it isn't an urgent thing to fix.
I like the idea of skipping the CP questions. Gold Rush v3 (Software Farm version) has no copy check questions, which is why I always use it when I play the game. What about making skipping optional? Skipping the age questions in LSL would be nice as well. I don't remember if LSL1 has different "dirtyness" levels based on how well you do with the age questions the way some later games in the series.
Yeah, the way I'm implementing the patches, it would be trivial to wrap it with a new preference setting.
-
As to the folder browser scroll to selected, I found this: https://social.msdn.microsoft.com/Forums/windows/en-US/6df8e181-750e-4e14-b707-96ff5c6f43c4/set-folderbrowserdialog-focus-on-treeview-on-the-selected-folder-in-c-winform?forum=csharpgeneral
None of the answers mentioned directly on that page fix the issue, but one of the links to stackoverflow from that page is where I got the "issue key strokes" approach from. They use different keys from what I am using though, as the keys they suggested didn't work in my case. That makes me think that perhaps the keys that work for me won't work for others, which makes the whole thing seem even more hacky. I even tried some of the very involved approaches mentioned on stackoverflow, involving a lot of code, and those didn't work either. Only the keystroke hack is working for me so far.
-
Yes, it used to be called "My Computer" since the days of Win9x. The statement for this folder is still "Environment.SpecialFolder.MyComputer". Desktop is at the topmost, but if that is used as root it never scrolls. If the selected folder is highlighted simply hitting enter will load that folder, even if not visible.
I'd say implement your hack. If we find a better solution later it can always be changed.
-
I'd say implement your hack. If we find a better solution later it can always be changed.
Okay, I have just done that. There was a little more to it than simply sending the keys. It needs to be done in a new async task. Without that, it doesn't work, but with it run in an async task, it appears to work every time. I haven't been able to see it fail after making this change. It is a variation of this stackoverflow answer:
https://stackoverflow.com/questions/6942150/why-folderbrowserdialog-dialog-does-not-scroll-to-selected-folder#answer-72376104
Just hoping that it doesn't break it for other people.
@vafada and @Collector, would you both be able to try that out to confirm that it still works for you?
-
Its not consistent... sometimes i can see the selected folder... sometimes i need to scroll
-
Ditto.
-
And to confirm, was it like that already for both of you before that change?
-
And to confirm, was it like that already for both of you before that change?
I cannot comment on this... when using AGILE.. I never use the folder browser window... i always used command line arguements
-
I hadn't noticed it before since most of what I was checking was more GUI things. Just hitting the enter key as soon as the dialog shows opens the selected folder. So it probably was not scrolling at time and I never noticed. I should try the TAB, TAB, RIGHT combination to see if it as inconsistent as DOWN, UP.
-
Yeah, I was going to suggest that you try that. I'm on Windows 11 btw. I could try it on Windows 10 to see how that behaves for me.
-
It is inconsistent with that for me as well. It seems that what has focus when the dialog appears varies. If the focus is on the OK or Cancel buttons these sendkey commands seem to just send the focus back and forth between the buttons and not the treeview. Might need to roll our own browser dialog to set the focus where it needs to be.
-
OK, I just made a folder browser dialog using gong-shell (https://github.com/grokys/gong-shell) and it works perfectly, but is far too slow.
There may be other controls that are faster.
-
It seems that what has focus when the dialog appears varies. If the focus is on the OK or Cancel buttons these sendkey commands seem to just send the focus back and forth between the buttons and not the treeview.
Perhaps an even uglier hack would be to do a key sequence like this:
private void ScrollSelectedPathIntoView()
{
System.Threading.Tasks.Task.Run(() =>
{
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("{DOWN}");
SendKeys.SendWait("{UP}");
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("{DOWN}");
SendKeys.SendWait("{UP}");
SendKeys.SendWait("{TAB}");
SendKeys.SendWait("{DOWN}");
SendKeys.SendWait("{UP}");
});
}
Since there are only three things to TAB between, then it would in theory not matter which one starts off with the focus, since it would tab to each and do a down/up.
That still works for me, Does it work for you when you change it to the above @Collector and @vafada?
-
Failing that, then I think this option might be working for me:
https://stackoverflow.com/questions/6942150/why-folderbrowserdialog-dialog-does-not-scroll-to-selected-folder#answer-15440926
I thought I had tried this previously, but perhaps not, as it seems to be working consistently now.
I basically just copied the code into a new class called FolderBrowserLauncher, then launch the standard FolderBrowserDialog using that FolderBrowserLauncher class, using the ShowFolderBrowser method in that class. The purpose of that FolderBrowserLauncher class is to locate the treeview and send it a message that will make it scroll down. There are some comments that perhaps the slight delay needs to be longer, e.g. if it is a slower computer, but so far it seems to be working for me.
This FolderBrowserLauncher class, from that stackoverflow answer, also uses the sendkeys approach as a fallback, but I've set a breakpoint on that and it isn't hitting it, so the main solution seems to be working for me.
If I try the FolderBrowserDialog directly, I'm getting it scrolling down about 50% of the time, e.g. 5 out of 10 attempts. But calling it through the FolderBrowserLauncher class, it is 100%.
-
Okay, I think I am going to push that to the github repo.
I tried it over and over again, and eventually I did get it to fail to scroll, so I increased the interval of the Timer from 10 to 50ms, tried again, and saw another occurrence after a while, so increased it to 100ms, and now I think it isn't happening at all; at least for me. Sometimes, when the dialog hasn't scrolled down itself, it is possible to see it scroll down due to the workaround, but given it is after 100ms, it isn't really noticeable unless you're looking for it.
As I say, I've pushed the change, so let me know how it works for you.
Changes can be seen here:
https://github.com/lanceewing/agile/commit/4048dc5526b27fdfd884d04e54f804f2859f5570
-
I came across a reference that .NET Core uses a newer folder browser dialog, so I tried to change it to .NET Core, but that option it is not available to the project. So I tried to recreate it from scratch. You cannot copy and paste controls between the two. I imported all of the AGI classes and recreated the main form. The browse dialog seems to always show the selected, but even though it compiles without error, it fails to load a game and does not throw any errors to help trace where the failure is. It will take some time to track it down.
Even if I fix it, do we really want to use .NET Core when many will not have that runtime installed? The NSIS installer could check what .NET runtimes are on a users machine, but I don't know if .NET Core can be installed on older Windows.
As I said, my gong-shell based custom folder dialog seems to work 100%, but it seems unacceptably too slow to me. I don't know what alternative controls there are to gong-shell or if they would be any faster.
Edit: I made a stand alone app with the custom browser using .NET 6.0 and the speed seems OK.
-
I came across a reference that .NET Core uses a newer folder browser dialog, so I tried to change it to .NET Core, but that option it is not available to the project. So I tried to recreate it from scratch. You cannot copy and paste controls between the two. I imported all of the AGI classes and recreated the main form. The browse dialog seems to always show the selected, but even though it compiles without error, it fails to load a game and does not throw any errors to help trace where the failure is. It will take some time to track it down.
Yeah, I came across the same reference a while back and decided that I'd rather stay on the .NET Framework than move to .NET Core.
Even if I fix it, do we really want to use .NET Core when many will not have that runtime installed? The NSIS installer could check what .NET runtimes are on a users machine, but I don't know if .NET Core can be installed on older Windows.
Yeah, good question. As I say, I think I'd prefer to stay on .NET Framework 4.8.
I did spend some time trying to use a normal "full" open file dialog instead of the FolderBrowserDialog, but I just didn't like the result. I found it harder to use, and it looked too complex for what it needed to be. I think the current FolderBrowserDialog serves the purpose well, in general. It is only this small issue, where it sometimes doesn't scroll down, that we need a reliable fix for.
Did you try the latest code that I pushed to github? Just wondering if that worked for you.
-
Yes, I did and it seems to miss as often as the other ones. Give the test app I posted a try and see how it works for you. I might try to see if I can speed it up with 4.8. I like how it not only scrolls to the selected folder, but displays it in the middle of the treeview instead of the bottom edge.
-
Yeah, that seems to work quite well, and still has the same look and feel. For me, it doesn't always display the selected folder in the middle, in fact the first couple of times I tried it, the selection was at the bottom edge. It seemed to depend on what folder I had previously selected. Given where my games are on my C: drive, I seem to always get it at the bottom edge if I select an AGI game folder. I don't think that matters though. I'm happy that the folder is visible, i.e. that it has scrolled down.
Yeah, see if you can get it working like that on 4.8
-
Here is an experimental branch with my custom browser dialog in 4.8. Take a look and if you like it I'll update my branch with the new dialog and send a pull request.
https://github.com/ABranscom/AGILE-with-custom-folder-browser-
-
Unfortunately the solution doesn't compile as is. It isn't able to find the AGILibrary or NAudio. The AGILibrary seemed to be completely missing, and for some reason the paths to the NAudio packages are broken.
I'm trying to get those fixed at the moment so that I can launch the project to try it out.
Edit: It is strange. The NAudio folders are there, but they're all missing the DLL files. I have copied them over from my repo, so now its loading that bit fine.
Getting a different error now: "'AgileForm' does not contain a definition for 'GetSelectedPath' and no accessible extension method 'GetSelectedPath' accepting a first argument of type 'AgileForm' could be found". Let me see if I can deduce what to add to fix that...
Edit 2: No, its not obvious, and its getting too late for me now. I'll let you fix it and I'll check again in the morning.
-
I have been following this thread with some interest, as I use the same dialog box in WinAGI in a number of places. I'm busy with another project right now, but I did find some time yesterday to take a look at my implementation to see if the behavior is similar. And it is- I find that on my Surface tablet, running latest version of Windows 11, it never seems to fail scrolling to the current item. (I got tired of opening/closing the dialog after several dozen attempts...) But on a Windows 10 Enterprise system, it has only scrolled properly once out of closer to a hundred tries. dunno why it's so different between OS versions.
In VB6, I can't access the folder browser directly, so I use an API call. This works really well, and it also allows me to set a callback function for the dialog, which I use to initialize the dialog box, and also to extract the selected folder when the user makes a change. So I thought it might be easy to fix by using the callback function to send the 'ensurevisible' message as part of initialization.
But that didn't work; it appears the dialog box is not completely set up when the callback function is sent the 'initialized' message, so results didn't change at all. When examining the messages sent to the callback function, it looks like some additional setup occurs after 'initialization', which affects when the treelist updates, so it sometimes 'resets' even after it was originally forced to show the selection.
But since the 'selection-changed' message for the default/initial selection seems to hit AFTER initialization, I modified the callback to force visibility whenever the selection CHANGES - that works perfectly! (Well, it hasn't failed yet on any system I've tested yet). And since the selection will always be visible after startup, it doesn't affect the dialog while the user is browsing/selecting after startup.
Here is the code I use, in case you're interested - it's in VB of course, but it's not that complicated, and I assume you could easily convert to C# if you wanted to. (I will do it myself at some point in order to use in my C# WinAGI project, but I have my other work to finish first.)
'folder dialog api declarations
Public Declare Function SHBrowseForFolder Lib "shell32" (lpbi As BrowseInfo) As Long
Public Declare Function SHGetPathFromIDList Lib "shell32" (ByVal pidList As Long, ByVal lpBuffer As String) As Long
Public Declare Function GetWindowText Lib "user32" (ByVal hWnd As Long, ByVal lpString As String, ByVal nMaxCount As Long) As Long
Public Declare Function GetClassName Lib "user32.dll" Alias "GetClassNameA" (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
'directory browser constants
Public Const MAX_PATH = 260
Public Const BFFM_INITIALIZED = 1
Public Const BFFM_SELCHANGED = 2
Public Const BFFM_VALIDATEFAILEDA = 3
Public Const BFFM_VALIDATEFAILEDW = 4
Public Const BFFM_IUNKNOWN = 5
Public Const BFFM_SETSTATUSTEXT = (WM_USER + 100)
Public Const BFFM_ENABLEOK = (WM_USER + 101)
Public Const BFFM_SETSELECTION = (WM_USER + 102)
Public Const BIF_RETURNONLYFSDIRS = 1
Public Const BIF_DONTGOBELOWDOMAIN = 2
Public Const BIF_STATUSTEXT = 4
Public Const BIF_USENEWUI = 64
Public Const TV_FIRST As Long = 4352
Public Const TVM_SELECTITEM = (TV_FIRST + 11)
Public Const TVM_GETNEXTITEM As Long = (TV_FIRST + 10)
Public Const TVM_GETITEM = (TV_FIRST + 12)
Public Const TVM_ENSUREVISIBLE As Long = (TV_FIRST + 20)
Public Const TVGN_ROOT = 0
Public Const TVGN_NEXT = 1
Public Const TVGN_CHILD = 4
Public Const TVGN_FIRSTVISIBLE = 5
Public Const TVGN_NEXTVISIBLE = 6
Public Const TVGN_CARET = 9
'according to most recent MSDN, use CoTaskMemFree in place of ITMalloc.Free
Private Declare Sub CoTaskMemFree Lib "ole32" (pv As Long)
Public Declare Function GetWindow Lib "user32" (ByVal hWnd As Long, ByVal uCmd As Long) As Long
Public Const GW_HWNDFIRST = 0
Public Const GW_HWNDLAST = 1
Public Const GW_HWNDNEXT = 2
Public Const GW_HWNDPREV = 3
Public Const GW_OWNER = 4
Public Const GW_CHILD = 5
Public Const GW_ENABLEDPOPUP = 6
'
' GetNewDir function - uses an API call to show the system folder selection dialog
'
' hWnd is the handle of the window that will be the parent of the dialog box
' DialogMsg is the text shown at top of the dialog as a description of its purpose
'
Public Function GetNewDir(ByVal hWnd As Long, DialogMsg As String)
On Error GoTo ErrHandler
Dim lpIDList As Long
Dim biNewDir As BrowseInfo
'build browser info structure
With biNewDir
'handle of parent window
.hWndOwner = hWnd
'message that appears above treelist
.lpszTitle = DialogMsg
'set flags
.ulFlags = BIF_RETURNONLYFSDIRS + BIF_DONTGOBELOWDOMAIN + BIF_USENEWUI + BIF_STATUSTEXT
'set pointer to callback address
.lpfnCallback = ByValAddressOf(AddressOf BrowseCallbackProc)
.pszDisplayName = String$(MAX_PATH, 32)
End With
'show browser, get pidl
lpIDList = SHBrowseForFolder(biNewDir)
'if not canceled (valid pidl returned)
If lpIDList Then
'last msg sent to callback function
'has gotten us the name of the chosen folder
GetNewDir = SelectedFolder
'according to most recent MSDN info, use CoTaskMemFree
'to free up the lpIDList handle and the root handle
CoTaskMemFree lpIDList
End If
' Whether successful or not, free the PIDL which was used to
' identify the My Computer virtual folder.
CoTaskMemFree biNewDir.pIDLRoot
Exit Function
ErrHandler:
'*'Debug.Print "bad thing happened: "; Err.Number, Err.Description
Resume Next
End Function
'
' BrowseCallbackProc function
'
Public Function BrowseCallbackProc(ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Dim rtn As Long
Dim lpDir As Long
Dim shCurDir As String
Dim lngLen As Long
Dim tmpStr As String
Dim treeitem As Long
On Error GoTo ErrHandler
Select Case uMsg
Case BFFM_INITIALIZED
'set directory by passing string pointer by Value
'(pass 1(true) for wParam)
rtn = SendMessageByString(hWnd, BFFM_SETSELECTION, 1, BrowserStartDir)
' it seems logical that we could force the selected item to be visible
' by sending a msg to the treelist right after initialization
' BUT it seems that there are additional things that happen to the
' control AFTER this initialization call which still cause the control
' to occasionally fail to scroll the treelist
' fix is to force it when a selection is changed; that seems to work
' every time!
Case BFFM_SELCHANGED
shCurDir = String$(MAX_PATH, 0)
If (SHGetPathFromIDList(wParam, shCurDir)) Then
shCurDir = Left$(shCurDir, InStr(shCurDir, vbNullChar) - 1)
lpDir = lstrcat(shCurDir, vbNullString)
rtn = SendMessage(hWnd, BFFM_SETSTATUSTEXT, 1, ByVal lpDir)
End If
SelectedFolder = shCurDir
' force the current selection to be visible by finding the treelist
' control and sending a ENSUREVISIBLE message
' begin with main dialog handle; find the child control under it
' that is the container for the tree (it has a class name of
' 'SHBrowseForFolder ShellNameSpace Control'
Debug.Print "main dialog window: "; Hex(hWnd)
rtn = GetWindow(hWnd, GW_CHILD)
Do Until rtn = 0
Debug.Print "dialog child: "; Hex(rtn); " - '";
tmpStr = Space(256)
lngLen = GetClassName(rtn, tmpStr, 255)
tmpStr = Left(tmpStr, lngLen)
Debug.Print tmpStr & "'"
'is this the container?
If tmpStr = "SHBrowseForFolder ShellNameSpace Control" Then
'get first child of the container
rtn = GetWindow(rtn, GW_CHILD)
Exit Do
End If
'if not, get next window
rtn = GetWindow(rtn, GW_HWNDNEXT)
Loop
' if found, now search for the actual treelist control inside
' the container control
Do Until rtn = 0
Debug.Print "container child: "; Hex(rtn); " - '";
tmpStr = Space(256)
lngLen = GetClassName(rtn, tmpStr, 255)
tmpStr = Left(tmpStr, lngLen)
Debug.Print tmpStr & "'"
'is this the treelist?
If tmpStr = "SysTreeView32" Then
'success
Exit Do
End If
'if not, get next window
rtn = GetWindow(rtn, GW_HWNDNEXT)
Loop
'if found, send the message to force it to be visible
If rtn > 0 Then
'get the selected item
treeitem = SendMessage(rtn, TVM_GETNEXTITEM, TVGN_CARET, 0)
Debug.Print "item: "; treeitem
If treeitem <> 0 Then
'now force it to show the selected item?
SendMessage rtn, WM_SETFOCUS, 0, 0
rtn = SendMessage(rtn, TVM_ENSUREVISIBLE, 0&, treeitem)
Debug.Print "selected - "; rtn
End If
Else
Debug.Print "Treelist not found"
End If
End Select
Exit Function
ErrHandler:
Debug.Print "error: "; Err.Number; " - "; Err.Description
Resume Next
End Function
-
@Lance, just comment out/delete the agileForm.GetSelectedPath(); line in the FolderBrowser.cs. It was a leftover from an attempt to solve a problem that I fixed in a different way. For some reason GitHub Desktop readded it.
-
@Collector, I had tried that, just to see what would happen, but it immediately throws a NullReferenceException on startup, from the following line:
folderBrowser.ShowDialog();
The folderBrowser instance has a value, but it seems that the ShowDialog call is throwing the NullReferenceException. This is why I thought maybe the compile error that I'd commented out was for something that was required and so hadn't tried to go further. So I've tried that again, and it is still throwing the NullReferenceException. It seems to be coming out of the native part of what ShowDialog ends up calling.
If I do this in Debug mode, and choose to Continue a couple of times, then the dialog becomes usable, but when I click on a game folder, e.g. "kq2", then it throws the NullReferenceException again. If I click "Continue", it throws it again, and if I click "Continue" again, then finally it loads the selected game.
-
Here is the code I use, in case you're interested - it's in VB of course, but it's not that complicated, and I assume you could easily convert to C# if you wanted to. (I will do it myself at some point in order to use in my C# WinAGI project, but I have my other work to finish first.)
Thanks, I'll give that a go when I next get a chance. Glad that you've got something that works on both a setup like mine (I also have Windows 11 on a surface tablet), and a Windows 10 system. That sounds promising, if I can convert that to C#.
-
Not sure what is going on with that. I thought that there might be something else missing from the GitHub repo, so I downloaded it, added the DLLs and commented that line out and it ran without error. The only difference there should be from the main branch is the addition of the FolderBrowser form, the GongShell.dll reference and a couple of changes in the AgileForm.
-
I tried doing everything again, from cloning a fresh copy of the repo, copying in the DLLs, commenting out the line of code, but it's still happening. Not sure why.
I've attached an image of what it looks like.
-
Here is the code I use, in case you're interested - it's in VB of course, but it's not that complicated, and I assume you could easily convert to C# if you wanted to. (I will do it myself at some point in order to use in my C# WinAGI project, but I have my other work to finish first.)
Thanks, I'll give that a go when I next get a chance. Glad that you've got something that works on both a setup like mine (I also have Windows 11 on a surface tablet), and a Windows 10 system. That sounds promising, if I can convert that to C#.
I have hacked together something in C# that does the same as what you're doing. I didn't actually convert your code, but found some C#, I think from a stackoverflow page I'd already linked to in an earlier message, that already had the callback method. I then added the extra bit for the TVM_ENSUREVISIBLE into the BFFM_SELCHANGED case and it seems to do the trick.
Sometimes it is already scrolled down, but in the cases when it isn't already scrolled down, there is an obvious delay before it scrolls down, which will be the ensure visible code kicking in on the selection change.
-
But since the 'selection-changed' message for the default/initial selection seems to hit AFTER initialization, I modified the callback to force visibility whenever the selection CHANGES - that works perfectly! (Well, it hasn't failed yet on any system I've tested yet). And since the selection will always be visible after startup, it doesn't affect the dialog while the user is browsing/selecting after startup.
I have just pushed to my repo my hacked together version of this, as mentioned in my previous post. It could probably do with some code tidying up by someone that understands more what is happening in the code. There might be some redundant bits in there.
@AGKorson, are you able to test this on both of your systems?
@Collector, can you test this on your system?
-
I was messing around with my GongShell solution and I think Windows 10 has broken it or at least has made it unstable. I have manage to get it to work flawlessly, but later randomly throws errors. Then again, the project has been abandoned for some time, now. It seems stable with .NET Core, but that is not viable solution.
I was thinking that a real fix would involve a PInvoke. I'm getting an odd error with this update:
The designer must create an instance of type System.Windows.Forms.CommonDialog', but it cannot because the type is declared as abstract
Which is odd since there is no designer for this class. However it does compile and seems to address the issue. I am not sure why VS is not treating it as simply a non WinForm class. Since this works well for me I I'll be abandoning my GongShell branch.
I am curious as to what this is from. There are references to unrelated things such as selecting a printer or computer dialog as well as references to an 'EditBox', none of which is needed by AGILE. I can probably trim the unused parts out for AGILE, but I am in the middle of an 8day work week and won't have much time for a few days.
-
I was thinking that a real fix would involve a PInvoke. I'm getting an odd error with this update:
The designer must create an instance of type System.Windows.Forms.CommonDialog', but it cannot because the type is declared as abstract
Which is odd since there is no designer for this class. However it does compile and seems to address the issue. I am not sure why VS is not treating it as simply a non WinForm class.
Yeah, I'm not surprised actually, as I did kind of hack it. I think there were some "designer" comments in there, which I ripped out not really understanding what they were used for. Perhaps they were important ;D.
Since this works well for me I I'll be abandoning my GongShell branch.
I am curious as to what this is from. There are references to unrelated things such as selecting a printer or computer dialog as well as references to an 'EditBox', none of which is needed by AGILE. I can probably trim the unused parts out for AGILE, but I am in the middle of an 8day work week and won't have much time for a few days.
Okay, thanks for confirming that it works for you.
Now that I think back, I think it was from someone's github repo, and I got the link from a stackoverflow answer. Let me see if I can find it again...
Found it. It came from here:
https://github.com/jkells/folder-browser-dialog-example/blob/master/FolderBrowserDialogEx.cs
and then I added the bit that does the ensure visible when the selection changes.
I'm happy for whoever knows what they're doing to clean it up. I did notice all those unused bits that you mention, but haven't yet tried to rip them out.
Edit: Since this solution is now working for everyone, I'll remove the FolderBrowserLauncher class from the repo, as that was from the previous attempt.
-
I removed all of the most obvious unneeded methods and variables. There was quite a bit. There may be more that could be removed, but not much. I also added the required NSIS plugin for the NSIS installer for convenience.
It is nice to not have to muddle though the age questions for LSL, but I cannot remember if LSLAGI had a dirtiness setting. In SCI you can skip the age questions with a script, but it can drop the "dirtiness level" its lowest setting. If LSLAGI has no dirtiness level it does not matter, but if it does will this patch keep it at its highest level? I haven't had a chance to see if the house buyer shows up in Gold Rush!. This was a bug with the most common cracked GR game.
I see it does not bypass the manual check questions of KQ4, but the 'marble' bypass still works with version 2.0, as well as the pirate Easter Egg.
-
I removed all of the most obvious unneeded methods and variables. There was quite a bit. There may be more that could be removed, but not much. I also added the required NSIS plugin for the NSIS installer for convenience.
Thanks, I have merged your PR.
It is nice to not have to muddle though the age questions for LSL, but I cannot remember if LSLAGI had a dirtiness setting. In SCI you can skip the age questions with a script, but it can drop the "dirtiness level" its lowest setting. If LSLAGI has no dirtiness level it does not matter, but if it does will this patch keep it at its highest level?
I don't recall it having a dirtiness level, but I do remember that the later games had it. @vafada implemented the question skipping patch for LSL1, so he may know. Even now I have to look up the answers to those questions. I wouldn't have a clue in some cases. Perhaps the questions have dated a bit, and some seem American specific. Either way, it is definitely a nice feature to skip them ;)
I haven't had a chance to see if the house buyer shows up in Gold Rush!. This was a bug with the most common cracked GR game.
Can you elaborate on the bug?
I have both the cracked and uncracked versions. I was going to start playing GR through to the end, which I guess means all three journey paths. Might take a while to get through this one.
One thing I did notice is that, before the question skipping patch was added to AGILE, the cracked version of GR showed a partly broken title screen, whereas after the patch, it now shows the correct looking title screen. Not sure why yet. I guess whatever broke it (probably where the crack is) has been skipped by the patch AGILE applies. I am half expecting there to be issues further down the track whilst playing GR, in relation to the patch, which may require further work. I'm guessing the house buyer bug that you mentioned might be one. It's been a long time since I played GR beyond a few screens, so can't recall it now.
I see it does not bypass the manual check questions of KQ4, but the 'marble' bypass still works with version 2.0, as well as the pirate Easter Egg.
Really? Is it definitely a clean copy? I've tried it with versions 2.0, 2.2 and 2.3 and the manual check skip patch works for all of them. What version of KQ4 does it show in the window title?
-
As to the Gold Rush bug, https://www.sierragamers.com/forums/topic/gold-rush-problem/
King's Quest 4 v2.0 int3.002.086 still asks the questions. I just noticed that it says it is an unrecognized game and realized that this is a copy that was decompiled and recompiled.
-
@AGKorson, are you able to test this on both of your systems?
I couldn't find an installer, so I just downloaded your repo and am checking it out in VS. It seems to be working fine for me. No surprise there.
I noticed your code uses GetDlgItem call to locate the treeview- I like that better than my way (searching for object classname text). I've implemented that in my WiAGI project, so thx for that.
I have a couple suggestions to improve your code -
- Get rid of the editbox. The editbox is the text input control just below the treeview. It lets the user type in a folder location manually. But I'd bet nobody is ever going to do that given how complex folder hierarchies are these days. To make it disappear, change the _showEditBox property to false in the Reset method.
- Skip the search for dialog handle in the callback function. There's no need to look for it- the handle is passed as the first argument of the callback function.
- Use the default root folder. If you set _rootFolderLocation to zero, instead of forcing it to the Desktop, the root folder will default to the user's Desktop, but with the custom folder icons instead of the generic yellow folder. Also, when I run AGILE with the original code that sets root to the Desktop, the starting folder is always the root, instead of last folder. The call to SHGetPathFromIDList in the callback function fails when the dialog first loads. After loading, it starts working correctly. I'm not sure what's going on there, but if you just use the default, that issue doesn't show up.
One other glitch I noticed is that when the main form is first shown, the "Loading... Please wait" message flashes briefly before the folder dialog is displayed. It would look better if no message is shown until a game is actually being loaded.
-
As to the Gold Rush bug, https://www.sierragamers.com/forums/topic/gold-rush-problem/
My patch sounds quite similar to what the cracked version has done then. Instead of changing the DIR file though, it changes LOGIC.0 so that the new.room command that goes to room 129 instead goes to 73. So very similar, but not exactly the same. It sounds like I might encounter some of the same issues though, as it isn't running LOGIC.129 at all. I probably need a different patch then, as the same speed issue will probably happen.
From reading those posts, I understand now why my patch, when applied to the cracked version, doesn't have the title screen bug that the cracked version without the patch does.
King's Quest 4 v2.0 int3.002.086 still asks the questions. I just noticed that it says it is an unrecognized game and realized that this is a copy that was decompiled and recompiled.
Yeah, that would explain it. The game detection is based on the md5 checksum of the DIR file, so if it has been recompiled, then that will be different.
-
I have a couple suggestions to improve your code -
Thanks for the suggestions. Yeah, we'll definitely get those incorporated. I agree that the editbox won't be used much.
One other glitch I noticed is that when the main form is first shown, the "Loading... Please wait" message flashes briefly before the folder dialog is displayed. It would look better if no message is shown until a game is actually being loaded.
Okay, I'll take a look at that as well.
-
AGKorson, you must have grabbed it before Lance merged my cleanup. I had already removed the editbox references and should be gone from Lance's repo. That editbox control was in a demo form from the original project that Lance found. Agile only uses the FolderSelectionDialog class from that project.
-
I don't think LSL1 has a dirtiness level... I've playthru the entire LSL1 w/o answering the trivia by modifying the LOGIC file using WinAGI and compiling it back and did not notice anything different.
I did all the naughty stuff in the game (got the top score)
-
I've been playing thru games using AGILE and fixing bugs as I see them and so far so good
I've finished
KQ1, KQ2, KQ3
LSL1
PQ1
currently playing Black Cauldron
I just bought Gold Rush in Steam and will play that after
been busy at work also so haven't played that much
-
I compiled a new NSIS installer and added a preview release on my fork so anyone that wants to try AGILE and does not want to bother having to compile it can grab the installer. My branch is currently in sync with Lance's master branch. Since it is an NSIS installer you can treat it as a simple ZIP file with 7zip. If you run the installer instead, it will give you the option to add the "Run in AGILE" folder shell extension as well as a desktop shortcut. It will add no files in system folders other than in the Start Menu and has a light foot on the registry. Only AGILE path info for the uninstaller and the folder shell extension, which can be removed or readded via the AGILE options dialog.
https://github.com/ABranscom/AGILE
-
AGKorson, you must have grabbed it before Lance merged my cleanup. I had already removed the editbox references and should be gone from Lance's repo. That editbox control was in a demo form from the original project that Lance found. Agile only uses the FolderSelectionDialog class from that project.
The edit box was still present on my branch after merging your pull request, and looking at the changes in the PR, it doesn't look like the edit box was removed. It did remove the setter and getter for it though, but the field itself was still there and being set to true on reset. I have now removed it and pushed the change to my master branch on github.
-
I've finished
KQ1, KQ2, KQ3
LSL1
PQ1
currently playing Black Cauldron
I just bought Gold Rush in Steam and will play that after
I have so far played through:
KQ1, KQ2, KQ4
SQ1, SQ2
My plan was also to play Gold Rush next, but I'll let you do that, as it sounds like you might have more time than me over the coming weeks.
-
- Skip the search for dialog handle in the callback function. There's no need to look for it- the handle is passed as the first argument of the callback function.
That one is a classic copy and paste issue. I simply copied that code from an example on stackoverflow and didn't check to see if the method already had that value.
I have now removed it and it is still working. That allowed me to also remove the constant for the dialog title, which makes it a bit cleaner. I've just pushed the change to my repo.
-
- Use the default root folder. If you set _rootFolderLocation to zero, instead of forcing it to the Desktop, the root folder will default to the user's Desktop, but with the custom folder icons instead of the generic yellow folder. Also, when I run AGILE with the original code that sets root to the Desktop, the starting folder is always the root, instead of last folder. The call to SHGetPathFromIDList in the callback function fails when the dialog first loads. After loading, it starts working correctly. I'm not sure what's going on there, but if you just use the default, that issue doesn't show up.
I didn't completely follow what you were saying with this one but I'll take your word for it. Currently it is setting the RootFolder to MyComputer. I have tried commenting that line out, and it changes to have Desktop at the root, rather than "This PC". Given that, I couldn't work out what you meant by the second bit regarding the original code that sets root to Desktop, or in what scenario the starting folder is always the root.
But in summary, is this the line you are saying should be removed, from the AgileForm class:
folderDialog.RootFolder = Environment.SpecialFolder.MyComputer;
-
One other glitch I noticed is that when the main form is first shown, the "Loading... Please wait" message flashes briefly before the folder dialog is displayed. It would look better if no message is shown until a game is actually being loaded.
This one will be a bit involved it seems. The problem is that it starts be seeing if it can load a game from the current directory, and if there happens to be a game in there, then we would want to show the Loading message. That is where we're getting that message flash up, i.e. while it is trying to load a game from the current directory. If there is no game in the currently directory, then it pops up the dialog.
The problem is that the AGILibrary is trying to load the game, i.e. fully decode the game, which can take a few seconds for some games. For example, if you happened to run AGILE in a directory containing KQ4 (as KQ4 is an example of a long to load one), or if you launched AGILE from WinAGI when editing KQ4, then we would want the Loading message to be displayed at that point. So AGILE displays the Loading message before it calls the AGILibrary to decode the game.
In order to stop it being displayed in the scenario where the directory doesn't contain a game, I'll need to change the AGILibrary to provide a "test directory to see if there is an AGI game" method. Sounds fairly straight forward though, so I'll give it a go later on. I'd then call that first, and that would do a quick check for the standard data files (perhaps looking for WORDS.TOK is enough to recognise a game dir; it doesn't have to be full proof) and only then would it show the message before decoding the game.
-
I just noticed that the number of Stars for the agile project in github went down by 1. I'm sure it was 5 over the past few weeks. Did somebody accidentally unstar it? Or was that deliberate? ;D
Actually, while I've mentioned it, it would be cool for everyone with a github account to Star the project. That might give it a bit more visibility.
-
In order to stop it being displayed in the scenario where the directory doesn't contain a game, I'll need to change the AGILibrary to provide a "test directory to see if there is an AGI game" method. Sounds fairly straight forward though, so I'll give it a go later on. I'd then call that first, and that would do a quick check for the standard data files (perhaps looking for WORDS.TOK is enough to recognise a game dir; it doesn't have to be full proof) and only then would it show the message before decoding the game.
It was much quicker to implement than I thought. No need to change the AGILibrary, as testing for a single file's existence, e.g. WORDS.TOK, is a one liner. So that is now fixed and pushed to my repo.
-
Yeah, that's the one. Setting to folderDialog.RootFolder = 0; does make it use the desktop as root. Although with modern Windows' Libraries being placed above the hard drives Desktop is repeated a couple down besides the actual folder in the user's space.
-
I got an idea that some may find handy. I added a "Create Shortcut to Game" item to the context menu. Once a game is loaded clicking this item will create an Agile shortcut to the desktop with an argument of the current game's folder. This shortcut will start the game in Agile by double clicking the shortcut. If there is interest I will polish it up and do a pull request.
-
I just noticed that the number of Stars for the agile project in github went down by 1. I'm sure it was 5 over the past few weeks. Did somebody accidentally unstar it? Or was that deliberate? ;D
This might have been me. :-[
I'm pretty sure I starred it in the past, but it wasn't when I checked just now. I have remedied the situation.
-
I didn't completely follow what you were saying with this one but I'll take your word for it. Currently it is setting the RootFolder to MyComputer. I have tried commenting that line out, and it changes to have Desktop at the root, rather than "This PC". Given that, I couldn't work out what you meant by the second bit regarding the original code that sets root to Desktop, or in what scenario the starting folder is always the root.
I didn't explain that very well. Let me try again.
When I run AGILE with the current code, I get this:
(https://i.imgur.com/BHsAtR5m.png)
It always shows the 'This PC' as the starting directory, no matter what the SelectedPath property is set to. Stepping through the code, I find that in the callback function, when the BFFM_SELCHANGED message is sent during dialog initialization, the SHGetPathFromIDList call does not return a valid path.
After the dialog loads, selecting a directories by clicking also sends BFFM_SELCHANGED message. The SHGetPathFromIDList does return valid paths for these changes.
If you don't set a root directory, which means making sure the pidlRoot member of browseInfo is set to zero (by doing that explicitly, or by deleting these lines
if (_rootFolderLocation == IntPtr.Zero) {
PInvoke.Shell32.SHGetSpecialFolderLocation(hWndOwner, (int)this._rootFolder, ref _rootFolderLocation);
if (_rootFolderLocation == IntPtr.Zero) {
PInvoke.Shell32.SHGetSpecialFolderLocation(hWndOwner, 0, ref _rootFolderLocation);
if (_rootFolderLocation == IntPtr.Zero) {
throw new InvalidOperationException("FolderBrowserDialogNoRootFolder");
}
}
}
from the RunDialog method), then the browser uses the default root (the user's Desktop) giving this:
(https://i.imgur.com/VVuozpGm.png)
With this change, stepping through the code in the BFFM_SELCHANGED message handler shows that the SHGetPathFromIDList call returns valid paths for the startup directory, which results in it being selected/displayed on startup, as shown above.
I don't know why the SHGetPathFromIDList doesn't return valid paths during startup in the first case, but does in the latter. A quick check of the Microsoft reference page for SHGetPathFromIDList shows that it's no longer supported, and links to other APIs that should be used instead. I didn't bother trying to figure that all out, since it's simpler to just use the browser's default root instead of trying to force a root.
But in summary, is this the line you are saying should be removed, from the AgileForm class:
folderDialog.RootFolder = Environment.SpecialFolder.MyComputer;
No, that by itself doesn't do the trick. If you do that you do get the Desktop be the root, but the code I mention above still runs, which forces the root to the Desktop instead of defaulting to the Desktop, giving this result:
(https://i.imgur.com/OWZ9N4Rm.png)
This gives just the actual file folders in Desktop; not all the 'special folders' that are also usually accessible from the Desktop. So you can't browse to folders that are outside the Desktop folder hierarchy. And it also fails to set the starting directory (same glitch/bug as when setting This PC to be root.)
In summary, to go with the default root, delete the code I showed above. You can also delete line you referenced, and code for setting the RootFolder. And in the RunDialog method, change this line
browseInfo.pidlRoot = _rootFolderLocation;
to
browseInfo.pidlRoot = IntPtr.Zero;
-
@AGKorson, thanks for the explanation, and also for the pull request with the changes. I have merged it and tested it locally. All is working well.
-
I seem to be hitting that Gold Rush bug when its patched by AGILE:
On the Steam Version of Gold Rush:
https://store.steampowered.com/app/308000/Gold_Rush_Classic/
When AGILE patches the game, changing the game speed to `Fast` or `Fastest` prevents the elapsed time from moving
The patch mod in AGILE for gold rush, `Changes the new.room(129) to be new.room(73)` In Logic 0
I checked Logic 129 on my game and here's what I have:
if (isset(newRoom))
{
set(f150);
animationInterval = 0;
prevent.input();
program.control();
status.line.off();
v220 = 33;
v164 = elapsedSeconds;
++v164;
}
if (v164 == elapsedSeconds)
{
++v221;
if (v221 == 2)
{
v221 = 0;
if (v222 < 240)
{
++v222;
}
if (v222 == 240 &&
v172 < 240)
{
++v172;
}
}
}
if (elapsedSeconds > v164)
{
v167 = v222;
v167 /= 3;
v165 = v222;
v165 /= 4;
if (v165 > 20)
{
v165 = 20;
}
v152 = 0;
if (isset(f158))
{
animationInterval = 2;
new.room(Logic1);
}
else
{
new.room(Logic73);
}
}
return();
I still can't figure out why `normal` and `slow` increments the time (seconds) but not for `Fast` and `Fastest`
Might not be worth fixing also since this seems to me a version with no copy protection?
-
Ok, I believe I found the issue.
Logic 129 contains this block of code
v167 = v222;
v167 /= 3;
v165 = v222;
v165 /= 4;
Logic 0 uses those two vars (167, 165) when changing game speed:
if (animationInterval == 0) // fastest
{
v166 = v167;
}
if (animationInterval == 1) //fast
{
v166 = v165;
}
with Logic 129 skipped v167 and v165 will be 0 so this block of code in Logic 0 which increments to seconds variable will never be executed
if (v156 == v166)
{
v156 = 0;
++v152; // v152 contains the elapsed seconds variable
}
and as @collector mentioned...
haven't had a chance to see if the house buyer shows up in Gold Rush!.
The house buyer did not show up after i sold the house... this is at the beginning of the game
I played thru the steam version and no issues... Seconds was incrementing on all game speed.... i guess for the Steam version they just removed the code in the LOGIC file that does copy protection instead if skipping Logic
-
The steam version is version 3.0, which is the Software Farm (O'Neill Bros) published version. It is the one that i worked with Sunlight Games to release. It never had copy protection and does not need to be patched. All of the earlier versions were published by Sierra with the manual check copy protection and is subject to the buyer not showing bug.
-
I believe the bug only took place if you put the game in any speed except Normal?
I made my own LOGIC patch with AGI Studio years back that skipped the copy protection. It's my goto now when I want to play it. I think I even patched the Apple IIgs version this way. But I still like keeping the original around so I can do my "last words" at the gallows. ;D
EDIT: Never mind, I had tried to patch the IIGS version but it must not have worked or I ran into too much trouble at the time.
-
The steam version is version 3.0, which is the Software Farm (O'Neill Bros) published version. It is the one that i worked with Sunlight Games to release. It never had copy protection and does not need to be patched. All of the earlier versions were published by Sierra with the manual check copy protection and is subject to the buyer not showing bug.
The problem is, AGILE doesn't distinguish between steam and earlier versions and just patches the LOGIC file and skips LOGIC 129.
There must be some way for AGILE to check if the Gold Rush that's being ran needs to be patched or not to skip copy protection.
Edit: Opened a PR for version 3.0: https://github.com/lanceewing/agile/pull/62/files
-
I have fully decompiled the Goldrush logics. You can find that here:
https://sciprogramming.com/community/index.php?topic=1942.msg13926#msg13926
Logic 129 is the main startup logic (named "lgc.Start" in the decompile) and is the first logic called when the game begins. After it does the timer check (details on exactly what it's doing are included in the comments of lgc.Start), it then calls new.room(rm.MainStreet) [rm.MainStreet is Logic 1] if restarting, or new.room(lgc.InitQuiz) [lgc.InitQuiz is Logic 125], which begins the copy protection question sequence. If the correct answer is entered, the copy protection calls new.room(rm.Title) [rm.Title is Logic 73], which begins the game's opening title sequence.
If you want to bypass the copy protection without breaking gameplay, the easiest way is to change the "new.room(lgc.InitQuiz);" line in lgc.Start to "new.room(rm.Title);"
In logic numbers, that's change the "new.room(125);" line in Logic 129 to "new.room(73);".
-
Cool, thanks @AGKorson. I'll give that a go in about 4 hours, when I'm back home... unless someone else submits the PR in the meantime ;D
-
FYI, Gold Rush ver 3.0 doesn't contain "new.room(125);" line in Logic 129
The code I pasted on https://sciprogramming.com/community/index.php?topic=1796.msg15870#msg15870 is the entire code for Logic 129 in Gold Rush v3.
-
FYI, Gold Rush ver 3.0 doesn't contain "new.room(125);" line in Logic 129
The code I pasted on https://sciprogramming.com/community/index.php?topic=1796.msg15870#msg15870 is the entire code for Logic 129 in Gold Rush v3.
Which confirms what I said about how to skip the copy protection. They made the exact same change.
-
Which confirms what I said about how to skip the copy protection. They made the exact same change.
I've just made the change you suggested to AGILE's GR patch and confirmed that it works. I have pushed the change to my repo.
-
Getting an index out of range exception with the KQ4 demo at line 206
foreach (Resource sound in volume.Sounds) Sounds[sound.Index] = (Sound)sound;
in the GameState class.
I am also getting a few unrecognized games with several versions of KQ4. Need to add the hashes for these versions. One thing that I borrowed from SVM for my Sierra Version tool was to copy the hash to the clipboard of any unrecognized game to add to the game lookup table. I'll look into it when I get a little more time. Without looking I assume that you are getting the hash from the LOGDIR?
-
Yes, the LOGDIR for the V2 games and the DIR file for the V3 games.
Which versions of KQ4 are not recognised? Are they recognised by scummvm? I assume not, as I copied all the md5 values from scummvm, so it should have all the PC games recognised by scummvm.
-
I didn't realize that you had added the pathc game option to the options form and the default is false, so it was not skipping the manual check. Turns out that there was only one unrecognized game, King's Quest 4 v2.2 int3.002.086 (5.25"). I'll add the hash to the gameDefinitions when I get a little more time in a couple of days.
I did a pull request. It included some missed null checks
-
Yes, @vafada added the option to the options form for patching. Works quite well from the testing I did.
I have merged your pull request.
-
Regarding the folder browser:
https://github.com/dotnet/winforms/pull/57
-
Thanks, I'll take a look at that when I get a free moment, maybe tomorrow. Tbh, I've got quite used to the current folder browser dialog, from having used it so much by now, but I'll implement the alternative on a feature branch to create a build that people can compare, and then maybe we can hold a short poll to see what people think.
-
I like what we have now. Simple and straight forward and works every time.
-
@lance.ewing not sure if you have been monitoring the git repo. but i posted a bug for GR rendering.
Looks like an AGILibrary.dll bug so i can't help fix.
https://github.com/lanceewing/agile/issues/64
Also any chance you'll open source AGI Library?
-
@lance.ewing not sure if you have been monitoring the git repo. but i posted a bug for GR rendering.
Looks like an AGILibrary.dll bug so i can't help fix.
https://github.com/lanceewing/agile/issues/64
Yes, I saw that. Haven't had a chance to take a look at it yet.
Also any chance you'll open source AGI Library?
I'm building the AGI Library from a fork of @Collector's repo in bitbucket, where it is a sub-project of the "AGI-SCI Developer" repo. So I didn't want to create a different home for that but treat bitbucket as the "master" location, so that the "AGI-SCI Developer" would get the benefit of any changes I make. The repo is private, as @Collector's repo is private, but I can add you as a user. There is a 5 user limit for free private repos on bitbucket, and so far there are only 4 users that have been added: @Collector, @AGKorson, Peter Kelly and myself. It would make sense for you to also be added. So if you have a bitbucket user, let me know and I'll search for you to add your user to the project.
@Collector, at some point I will request my AGI Library changes to be merged back to your repo.
-
https://bitbucket.org/vafada/
-
It appears that I'll need your email address in order to invite you. PM it to me if you don't want it to be publicly visible in these forums.
-
@vafada, something seems to have changed in bitbucket with adding users. I don't recall it being so hard. I have sent you an invite to a new group I created, as that was the only way I could see to invite someone. I didn't previously have a group defined. Perhaps once you accept the invite, I might be able to add you specifically to the repo.
-
@lance.ewing not sure if you have been monitoring the git repo. but i posted a bug for GR rendering.
Looks like an AGILibrary.dll bug so i can't help fix.
https://github.com/lanceewing/agile/issues/64
I have found the cause of the bug, and even though I didn't directly write the picture part of the AGI Library, I suspect that it is based on PICEDIT, which was in turn based on SHOWPIC from around 1997. The same bug is in those, so I suspect I may be the ultimate cause of this bug ;D
I am just about to fix it. Will report back here when it is done.
-
This fix for the GR picture bug is now pushed to my repo.
-
@vafada, something seems to have changed in bitbucket with adding users. I don't recall it being so hard. I have sent you an invite to a new group I created, as that was the only way I could see to invite someone. I didn't previously have a group defined. Perhaps once you accept the invite, I might be able to add you specifically to the repo.
I accepted the invite... but I can't see any repo
-
I have been thinking about splitting out the SCI part of Developer since it is unlikely that the SCI part will ever be finished and the AGI part is closer to usability with the further development of the library. I could then move the AGI project over to GitHub if there would be any interest.
-
I accepted the invite... but I can't see any repo
I finally found the option to invite you to the repo. That is what I was looking for in the first place, but could only spot the invite to the group, and I can see that you are now in the group.
You should now have the invite for the repo.
-
I have been thinking about splitting out the SCI part of Developer since it is unlikely that the SCI part will ever be finished and the AGI part is closer to usability with the further development of the library. I could then move the AGI project over to GitHub if there would be any interest.
Yeah, that sounds like a really good idea to me, both the splitting out of the AGI parts (which contains the AGI Library), and also moving it into github.
I think I should probably send you a pull request of my AGILibrary changes before you start on the split and move though. I'll get back to you later on when I think I have a pull request ready. There is an old version of AGILE in my bitbucket repo, which it might make sense if I remove before creating the pull request, since we already have that (AGILE) in github, and besides, that AGILE code is now quite old.
-
I think I should probably send you a pull request of my AGILibrary changes before you start on the split and move though. I'll get back to you later on when I think I have a pull request ready. There is an old version of AGILE in my bitbucket repo, which it might make sense if I remove before creating the pull request, since we already have that (AGILE) in github, and besides, that AGILE code is now quite old.
@Collector, this is now done and I've sent you a pull request.
-
I have been thinking about splitting out the SCI part of Developer since it is unlikely that the SCI part will ever be finished and the AGI part is closer to usability with the further development of the library. I could then move the AGI project over to GitHub if there would be any interest.
Yes!
-
I have started to strip out the SCI stuff, but am starting to wonder if I should just start with my latest copy of Visual AGI and add in the features I have in Developer. Developer started as SCI and I think it will have a lot of debris left that will take some effort and time to weed out.
After I get it in better shape I'll create a new repo on GitHub.
-
I have started to strip out the SCI stuff, but am starting to wonder if I should just start with my latest copy of Visual AGI and add in the features I have in Developer. Developer started as SCI and I think it will have a lot of debris left that will take some effort and time to weed out.
Yeah, that might be a better approach. I assume that the new AGI Library version should still be compatible with the original Visual AGI.
I saw that you have seen my pull request for your bitbucket repo. Have you merged it back yet? Or, given the above, I'm guessing you are planning to start from scratch with the latest copy of Visual AGI and my latest AGI Library version in a new repo?
-
I have just replaced the library project with your updated one. It seems to work OK, but I have not done any extensive testing. I looked at Visual AGI again and it would be fairly involved to redo all of the features I have in the combined project, so for now I am just cutting out the SCI stuff. I have made some good progress so far. It is also letting me refactor the code. If it becomes too much of a pain I'll take another look at Visual AGI. I won't create a new repo until I make some more progress and then I'll send an invite to the two of you when I do.
-
Don't have time to try to track it down, now, but AGILE does not accept any keyboard input at the start of the 1986 x-mas card.
-
Don't have time to try to track it down, now, but AGILE does not accept any keyboard input at the start of the 1986 x-mas card.
its crashing AGILibrary on room 13
I assume there is a bug when parsing the logic file in xmas 1986
GetDestinationAddress = 274
but the Dictionary doesn't have key = 274
Exception thrown: 'System.Collections.Generic.KeyNotFoundException' in mscorlib.dll
ex: The given key was not present in the dictionary.
System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at AGI.Resource.Logic.JumpAction.GetDestinationActionIndex() in C:\Users\Mark\Downloads\AGILibrary\AGI Library\Resource.cs:line 2857
-
I haven't had a chance to look in detail yet but I did notice (in WinAGI) that the logic 13 script has a few unusual labels and goto statements. It should be able to handle it but maybe not. Will need to step through the logic decoding to see what is going on. I might get a chance tomorrow.
-
The other thing I noticed in WinAGI is that this LOGIC has two return statements at the end of it. I suspect that that is probably the issue. It is a conditional branch that is falling over. I think it is jumping to the very end, i.e. the second return statement, but the LOGIC decoding is probably stopping at the first return statement, thinking that that indicates the end. Should be an easy fix.
-
No, it seems like the double "return" in LOGIC.13 is decoded fine.
It looks to me like it might be LOGIC.99 that is the problem. The 274 key value is actually in relation to LOGIC 99. Viewing that LOGIC in WinAGI shows that the "if" at the end of the script is missing an ending } which makes me wonder if maybe the LOGIC is missing something for it to jump to, i.e. the location the conditional jump is jumping to doesn't exist. I guess I could either add some code to always ensure that the decoded LOGIC has a "return" at the end, so that in cases like this there is always something to jump to, or I instead make the conditional branch more robust, so that it assumes that a missing jump location means to the end.
That second option doesn't feel clean to mean though. I think I prefer the decoding adding a "return" at the end if there isn't one.
-
I think I prefer the decoding adding a "return" at the end if there isn't one.
I've made this change locally on my machine and it seems to fix the issue. Unfortunately there is another issue lurking behind that one, something to do with AGI String 0, being that that String is null. I added a quick hack for that to interpret that as an empty string and that has allowed it to continue and now it appears to be showing the Christmas card without any further issues, looping back to the beginning once it has been through all the screens.
I'll make these changes permanently at some point over the next day or so. I just want to think more about why the AGI String was null and why it is only this XMAS card that it is happening on. I assume something to do with the older interpreter version.
-
The other thing I noticed in WinAGI is that this LOGIC has two return statements at the end of it.
The extra return command is because Sierra's compiler (cg.exe) automatically adds a return statement at the end of every logic. If the programmer included a return in their source code, the compiled logic would then end with two return statements. (Goldrush also has a few examples of this phenomenon.)
It does not have any effect on gameplay; the extra return statement is never used.
-
No, it seems like the double "return" in LOGIC.13 is decoded fine.
It looks to me like it might be LOGIC.99 that is the problem. The 274 key value is actually in relation to LOGIC 99. Viewing that LOGIC in WinAGI shows that the "if" at the end of the script is missing an ending } which makes me wonder if maybe the LOGIC is missing something for it to jump to, i.e. the location the conditional jump is jumping to doesn't exist. I guess I could either add some code to always ensure that the decoded LOGIC has a "return" at the end, so that in cases like this there is always something to jump to, or I instead make the conditional branch more robust, so that it assumes that a missing jump location means to the end.
That second option doesn't feel clean to mean though. I think I prefer the decoding adding a "return" at the end if there isn't one.
The reason for this odd situation is because this logic (it's a debug logic, probably borrowed from some other game) ends with a quit command, but was originally compiled in version 2.089 (or earlier) when the quit command didn't take an argument. So the last byte of the logic, before the message section, is in fact a return (byte code 00). But since the interpreter packaged with the game is 2.272, WinAGI thinks the quit command needs an argument, so it uses the 00 byte code. (If you change the target interpreter version to 2.089, the logic decompiles correctly.)
I know it was compiled in a version that uses no arguments for quit because of the size of the 'if' block that the quit command is inside of. It correctly points to the byte code 00 when the 'if' block returns false.
Even though the logic is being run in version 2.272 interpreter, it works fine in MSDOS because the 'if' block has the correct offset value. And if the 'said' command evaluates to TRUE, you also don't see any effect of this when run in MSDOS because the quit command terminates the game immediately, and never tries to read past the end of the logic.
You did help me find an obscure bug in WinAGI's decompiler. Since the decompiler thinks the last byte is part of the quit command, it hiccups when it then tries to add the ending bracket because the decompiler's index is one past the expected value. That's why the bracket is missing. I've added a check for this in case it comes up in any other games.
-
Unfortunately there is another issue lurking behind that one, something to do with AGI String 0, being that that String is null. I added a quick hack for that to interpret that as an empty string and that has allowed it to continue and now it appears to be showing the Christmas card without any further issues, looping back to the beginning once it has been through all the screens.
I'll make these changes permanently at some point over the next day or so. I just want to think more about why the AGI String was null and why it is only this XMAS card that it is happening on. I assume something to do with the older interpreter version.
The concept of a null string has no meaning in the MSDOS interpreter. When a game starts, the string table starts as all zeros. So any functions that read the string values will return a valid string of zero length. My guess is that your interpreter is not setting all 24 (or 12, depending on version) strings to valid zero length strings on start up. If you do that, you shouldn't have any problems with 'uninitialized' strings.
-
The reason for this odd situation is because this logic (it's a debug logic, probably borrowed from some other game) ends with a quit command, but was originally compiled in version 2.089 (or earlier) when the quit command didn't take an argument. So the last byte of the logic, before the message section, is in fact a return (byte code 00). But since the interpreter packaged with the game is 2.272, WinAGI thinks the quit command needs an argument, so it uses the 00 byte code. (If you change the target interpreter version to 2.089, the logic decompiles correctly.)
I know it was compiled in a version that uses no arguments for quit because of the size of the 'if' block that the quit command is inside of. It correctly points to the byte code 00 when the 'if' block returns false.
I'm trying to think through if that is the cause of the original issue that Collector reported and I think it is. AGILE will also be seeing that it is interpreter version 2.272 and will therefore decode the "quit" command with the parameter, which explains why the decoded LOGIC doesn't have a "return" at the end. AGILE does support the "quit" command without the parameter, but only if it thinks it is 2.089.
My workaround fixes the issue, and I guess it isn't going to harm anything, i.e. having an additional "return" statement at the end. It can't really determine that the LOGIC was compiled for 2.089, not when the XMAS card "game" was presumably compiled with a mixture of different CG compiler versions. I could add an interpreter version to the game detection data, but that would assume it applies to all LOGICs in the game, so it wouldn't work for this XMAS card game, unless we assume all LOGICs were compiled under 2.089.
-
The concept of a null string has no meaning in the MSDOS interpreter. When a game starts, the string table starts as all zeros. So any functions that read the string values will return a valid string of zero length. My guess is that your interpreter is not setting all 24 (or 12, depending on version) strings to valid zero length strings on start up. If you do that, you shouldn't have any problems with 'uninitialized' strings.
I suspected that this was the case, i.e. that AGI doesn't have this distinction. Thanks for confirming this. Yeah, your suspicion is correct, that AGILE doesn't initialise the AGI strings to be empty. I'll fix this now.
Edit: This is now fixed and pushed to my github repo.