Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - NewRisingSun

Pages: [1] 2 3 4
1
It is a DOS .COM file written in x86 assembly language a long time ago, only updated to fix a bug here and there. There is no such thing as a "Win32 build" for that, short of a complete rewrite.  :P

SND2MID.COM converts from Sierra sound resource format to Standard MIDI File format. Syntax is: "snd2mid  devices   files". "Devices" can be "*" for all, or "a" for AdLib, "m" for Roland MT-32, "h" for "General MIDI", "s" for "PC Speaker", "t" for "Tandy", and so on. More than one letter is possible, and "files" can be more than one file. Example "snd2mid am *.snd" converts all .snd files, extracting only tracks for devices AdLib and Roland MT-32. The track names of the resulting Standard MIDI File have device lists in brackets that are needed by Sierra's SMF.EXE for re-conversion. Reverb controllers that MT32.DRV translates into System Exclusive Messages are kept as they are, and all other events are untouched. This makes it possible to later convert the Standard MIDI Files back to Sierra sound resource format.

2
It is not clear what exactly are you asking for. You mentioned "SCI0-SCI10" to SCI11, which seems wrong because SCI11 and SCI32 use the exact same format for sound resources as SCI1. The only format difference is between SCI0 and everything afterwards.

To convert from SCI0 to SCI1+, you need to convert back to Standard MIDI Files first, then from those Standard MIDI Files to SCI1's sound resource format using Sierra's original SMF.EXE utility, which I assume has made the rounds by now. I have written utilities a long time ago that convert from SCI0 and SCI1+ sound resources to Standard MIDI, converting all or merely selected devices, and optionally translating reverb controllers to MT-32 sysex messages, as MT32.DRV would do. I have sent them to Spikey previously, and can send them to you, but ONLY if you state that this is what you want. Note that these convertersion utilities have been written a long time ago and therefore only exist as DOS .COM files.

3
SCI Development Tools / Re: OPL timbre tool for Windows/Mac/Linux
« on: May 31, 2017, 10:38:16 PM »
LBA are files from Little Big Adventure. The game uses one set of MIDI files with different instrument banks for OPL2 (SAMPLE.AD) and OPL3 (SAMPLE.OPL).

LOSTVIK are files from The Lost Vikings. The MIDI files differ between OPL2 and OPL3 as well, hence the two directories.

To play an example file, go into the directory containing the XMI file you want to play (example: title.xmi), then in DOSBox, type "..\XPLAY title.xmi ..\SBFM.ADV" for OPL2 (SBFM.ADV will automatically use SAMPLE.AD) and "..\XPLAY title.xmi ..\SBP2FM.ADV" for OPL3 (SBP2FM.ADV will automatically use SAMPLE.OPL).

4
SCI Development Tools / Re: OPL timbre tool for Windows/Mac/Linux
« on: May 31, 2017, 04:33:10 AM »
There is some variation between SCI versions in their 3.PAT format.
- SCI0 and 1.0 have 48 instruments, followed by 0xAB 0xCD if 48 more instruments follow
- SCI1.1 has 190 instruments, 128 melodic plus 62 rhythm channel instruments, followed by 62 bytes specifying the actual note pitch (MIDI note) for the drum notes starting with note 0x1B (Kick drum).

Another format of interest might be Miles Design' AIL 2.x (e.g. SAMPLE.AD, SAMPLE.OPL), which supports both 2-OP and 4-OP instruments. I can provide specs if interested. Also, you might want to switch to the Nuked FM emulation core at some point for its greater accuracy.

5
Nice. Given the improved sound quality of the AppleIIgs versions, I think those deserve an update as well. ;)

6
Yep. I made a video:


7
On second look, there are three small differences in the game logic as well:

1. Room 18, when typing "kill elf":
Code: [Select]
"I'm surprised at you! that is very\nimpolite!"changed to
Code: [Select]
"I'm surprised at you! That is very\nimpolite!"
2. Room 21:
Code: [Select]
if (roomObjectActive==1 && haveGoat==1) {
print("There is a witch in the area, but\n having that menacing goat with you,\n she will keep her distance.");
set(v113);
}
if (roomObjectActive==1 && haveGoat==1) {
print("There is a witch in the area, but with\n the shield no harm will come to you.");
}
changed to
Code: [Select]
if (roomObjectActive==1 && haveGoat==1) {
print("There is a witch in the area, but\n having that menacing goat with you,\n she will keep her distance.");
set(v113);
}
if (roomObjectActive==1 && haveShield==1) {
print("There is a witch in the area, but with\n the shield no harm will come to you.");
}

3. Room 65:
Code: [Select]
"As the wicked witch flew over her\n house, she dropped you... into her\n cage! If you can't get out, you may\n become the secret ingredient in this\n witches brew!" changed to
Code: [Select]
"As the wicked witch flew over her\n house, she dropped you... into her\n cage! If you can't get out, you may\n become the secret ingredient in this\n witch's brew!"
Everything else is the same, as I have verified by using GALextract on both disk images, then comparing all files using Windows' FC command.

8
I can find the relevant sections in MAIN.EXE. Basically, GAL has two separate logic scripts for each room, the first logic script dealing with things such as moving objects around, check ego's position, and so on; the second logic script checking and acting upon "said" strings. The source code snippet calls the first logic script the "position logic table", and second logic the "text logic table". AGI of course combines both types into a single logic per room, and Sierra's AGI documentation to my knowledge calls them just "logics", not "logic tables". And what the snippet calls "action table" are just commands outside of a test command block (or inside a curly brace, to speak in source code terms) in AGI, which in GAL again are in a separate section of the room data file.

The code does not seem to use any scoping of names --- procedures are just simple code labels instead of using the Assembler's "PROC" directive, which was introduced with Intel's ASM86 assembler in 1978 and adopted by Microsoft's Macro Assembler in 1981. Due to the lack of scoping, the code in some sections jumps around wildly in the code segment, basically jumping from one end of a procedure right into the middle of another one at the other end of the segment. The code also uses no constants for things like interrupt 10 subfunction numbers. Variable names are shortened to the point of being unintelligible - what the code snippet calls "wtprt" I had named "waitForMsgFinish" in my disassembly, so "wtprt" apparently stands for something like "waitPrint". And why the hell is scanning the "position logic table" called "check-mate"?

Overall, the programming style seems archaic even by 1984 standards. I'm a bit disappointed that this is what original source code looks like. :)

9
The previously-available PC-CGA version had an August 16th 1984 date of MAIN.EXE. An earlier version of the game has now been acquired, dated May 31st 1984. Comparing the two versions shows that the game logic, graphics and sound are byte-for-byte identical; only interpreter (MAIN.EXE) as well as the boot sector and loader code changed. (The title screen code is in MAIN.EXE; logic code is not interpreted until the first actual game screen.) Notably, the earlier version only supports CGA composite mode, not RGB mode, and does not credit Chris Iden at the title screen, similar to the IBM PCjr release.

And, most interestingly, the disk again had a snippet of original source code in it!
Code: [Select]
        mov     [di+saveptr],ax         ;save buffer pointer
        mov     ax,[si+word ptr outxpos]
        mov     [di+word ptr xpos],ax   ;positions
        pop     bx
        call    setcel
        mov     al,[di+steptime]
        or      al,al
        jnz     stepok
        mov     al,1
stepok: mov     [di+steptime],al        ;set default steptime
        mov     [di+stepclock],al       ;set stepclock
        ret
setcel: mov     al,[bx]                 ;loop count
        mov     ah,0
        xor     bx,bx                   ;if 1 loop, get loop 0
        dec     ax
        jz      stcel
        inc     bx                      ;if 2 loops, get loop 1
        dec     ax
        jz      stcel
        inc     bx                      ;if 4 loops, get loop 2
        xor     ax,ax
stcel:  push    bp
        mov     bp,sp
        push    ax                      ;pass cel #
        push    bx                      ;pass loop #
        push    di                      ;pass table pointer
        call    getstcel
        pop     di                      ;get table pointer
        pop     bx                      ;get loop #
        mov     sp,bp
        pop     bp
        mov     [di+celcnt],al          ;set cel count
        mov     [di+curl],bl            ;set loop #
        ret
trashem:lea     si,objtab               ;animation table pointer
        lea     di,chuck                ;object table pointer
        mov     ch,outlen               ;object table entry length
        mov     cl,4                    ;nibble shifter
t0:     add     si,grplen               ;point to next animation table
        mov     dl,[si]                 ;get room entry
        cmp     dl,0                    ;not terminator?
        jz      t1
        mov     byte ptr [si],0
        cmp     dl,flags.roomflag       ;in this room?
        jne     t0
        mov     al,[si+disknum]         ;get this object's #
        mul     ch                      ;offset of this obj's table entry
        mov     bx,ax
        mov     dh,[di+bx+outroom]
        and     dh,80h
        or      dl,dh                   ;maintain ego possession
        mov     [di+bx+outroom],dl      ;set this obj's room # entry
        mov     ah,[si+curl]
        mov     al,[si+curcel]          ;combine loop & cel values
        shl     ah,cl
        or      al,ah
        mov     [di+bx+outlupcel],al    ;set loop & cel entry
        mov     ax,word ptr [si+xpos]
        mov     word ptr [di+bx+outxpos],ax      ;set position entries
        jmp     t0              ;process the 3 non-ego animation tables
t1:     add     di,inobjtab     ;point to 1st object table's anitbl entry
        mov     cx,110          ;object count minus 1 (ego)
outlup: add     di,outlen       ;point to next object table
        mov     byte ptr [di],0 ;clear all objs' animation table entries
        loop    outlup          ;process all objects' tables
        mov     chuckptr,0              ;clear loaded objects count
        lea     di,objtab
        mov     byte ptr [di+grplen],0  ;terminate animation tables
        mov     ax,curact
        mov     objptr,ax               ;reset free memory pointer
        mov     cx,40-9
        lea     di,soundpos
        add     di,18
        lea     ax,stopsnd
;        rep     stosw                   ;set all non-res. sound ptrs to silence
        ret
loadego:call    wtprt
        mov     al,0
        call    load_obj                ;get ego
        lea     di,objtab               ;object table pointer
        mov     [di+lgrpptr],ax         ;set loop group pointer
        lea     bx,alterego
        mov     [bx],ax                 ;ditto
        mov     al,0
        mov     [di+disknum],al
        mov     [di+objnum],al
        mov     [di+curcel],al          ;disk #, obj # & cel # = 0
        mov     [di+curl],al            ;loop # = 2
        mov     [di+stepclock],1        ;stepclock = 1

        lea     bx,chuck                ;out table pointer
        mov     ax,[bx+word ptr outxpos]
        mov     [di+word ptr xpos],ax   ;set positions
        mov     ax,savetab
        mov     [di+saveptr],ax         ;set save buffer pointer


        mov     [di+celcnt],8           ;cel count = 8
        push    bp
        mov     bp,sp
        mov     ax,6
        push    ax                      ;pass cel #
        mov     al,0
        push    ax                      ;pass loop #
        push    di                      ;pass table pointer
        call    getstcel                ;set step sizes, cel pointer & stepclock
        mov     sp,bp
        pop     bp
        mov     flags.roomflag,1
        mov     dx,0
        call    dwt

        lea     ax,objtab
        mov     tabptr,ax
        cmp     cpyseq,0
        jnz     ldgrtn
        call    ers
ldgrtn: ret

clearscrn:
        push    ax
        mov     ax,600h
        jmp     sc1
scroll: push    ax
        mov     ax,601h
sc1:    push    bx
        push    cx
        push    dx
        mov     cx,1500h
        mov     dx,1827h
        mov     bh,0
        call    wtprt
        int     10h
        mov     dx,1800h
        jmp     short stcr






setcsr: push    ax
        push    bx
        push    cx
        push    dx
stcr:   mov     curchar,dl
        mov     ah,2
        mov     bh,0
        call    wtprt
        int     10h
        pop     dx
        pop     cx
        pop     bx
        pop     ax
        ret











term    equ     0ffh
skip    equ     0feh
psn     equ     0fdh
flag    equ     0fch
always  equ     0fbh
ignore  equ     0fah
unknown equ     0f9h












;                              Say-what?
;           Scans the text logic table ( @texptr or @texany )
;       for true sequences of conditions [ text, flag & position ]
;   then passes a pointer for the action table [ @actptr or @actany ]
;  to ACTMODUL to execute the action string for the matched conitions.

saywhat:
        mov     lgcflg,1        ;flag text table checks
        mov     si,txtptr       ;get text logics table pointer
        jmp     chklup

;                             Check-mate!
;         Scans the position logic table ( @posptr or @posany )
;        for true sequences of conditions  [ flags & positions ]
;   then passes a pointer for the action table [ @actptr or @actany ]
;  to ACTMODUL to execute the action string for the matched conitions.

chekmate:
        mov     lgcflg,0        ;flag position table checks
        mov     

10
SCI Development Tools / Re: Hacking SQ1VGA with SCICompanion v3
« on: March 29, 2017, 08:50:35 PM »
The track name must start with a list of devices that should play this track and a few other things in square brackets, followed by the regular track name if wanted:
*: Applies to all devices, typically channel 16 defining loop points.
a: Track played by ADL.DRV
j: Track played by CMS.DRV
g: Track played by MTBLAST.DRV
h: Track played by GENMIDI.DRV or Windows 3.1 Extended MIDI ("High synth")
l: Track played by Windows 3.1 Basic MIDI ("Low synth")
m: Track played by MT32.DRV
s: Track played by STD.DRV
t: Track played by TANDY3V.DRV
A sound driver's function number 0 returns in CH its device letter minus ASCII 61h ('a') to the interpreter, i.e. MT-32 returns 0Ch ('m' minus 'a'). In some games, MTBLAST.DRV plays 'm' rather than 'g' tracks, and in games composed for MT-32 but with a GENMIDI.DRV added after-market, or after composition (PQ1, Laura Bow), GENMIDI plays 'm' rather than 'g' tracks as well while remapping program change numbers based on 4.PAT information.

Special characters:
!: Do not remap channel ("Locked channel"). Required for MT-32 rhythm tracks (MIDI channel 10).
#: Track is initially disabled ("Ghost channel"), but can be enabled by game. Used for multiple melody lines, for example in LSL6.
Number 0-9 before "/": Initial voice allocation (i.e. number of voices used by MIDI channel)
Number 0-9 after "/: Pre-emption priority. Channels without it cannot be pre-empted, i.e. will never be disabled for the benefit of MIDI sound effects. Sierra's MIDI code is too confusing for me to tell whether it's a higher or a lower priority that makes a channel more or less likely to be pre-empted.

Example:
"[ajmt2/1] Melody": Played by AdLib, Game Blaster, MT-32, Tandy; initially allocate 2 voices, pre-emption priority 1.
"[gm!] Rhythm": General MIDI/MT-32 rhythm track.

11
SCI Development Tools / Re: Hacking SQ1VGA with SCICompanion v3
« on: March 29, 2017, 02:40:18 PM »
Attached find one example. 572bad.v56 was saved by SCI Companion and was rejected by MAKEVOLS as "corrupt". Loading that file in Sierra's original View Editor 256 and immediately saving it produces 572GOOD.V56, which MAKEVOLS does accept.

12
SCI Development Tools / Re: Hacking SQ1VGA with SCICompanion v3
« on: March 27, 2017, 12:07:40 PM »
Quote
This is probably why ScummVM does not recognize it. The map file has been changed.
Good.

Quote from: troflip
Yeah, that would be very useful.
I'll do a write-up, but it might take a while. Is there a binary build available with these issues corrected? Then I would only report those issues that persist.

Quote from: spiffythedog
There were a few scripts that didn't compile properly with SCI Companion (causing weird anomalies during gameplay), which necessitated NRS to use some original developer tools in order to properly implement the new fixes
I only used three original developer tools: SMF.EXE, View Editor 256, and MAKEVOLS. MAKEVOLS would claim that some view resources that were saved by SCI Companion were "corrupt". I loaded them in View Editor 256, where they displayed without problems, then immediately saved them, which produced somewhat different files that MAKEVOLS would then accept. I used SMF.EXE to reconvert Standard MIDI Files to .SND files after I made some changes to them (in particular, adding the choreography triggers to the Madonna music).

13
AGI Development Tools / Re: AGI v1 resource extractor and sound converter
« on: November 11, 2016, 04:40:13 PM »
Figured out how to prevent CG from giving the "output buffer overflow" error. I had used the -b parameter before, but with values that were too high or too low. CG likes values between 4096 and 8192, and the value might not be the same for every script.

With that in mind, I have managed to decompile and recompile AGI v3 logics as well. I had never noticed that AGI v3 games usually do not encrypt the message strings with "Avis Durgan", probably because the LZW compression makes it unnecessary. Most logics don't have encrypted messages, a few do, probably the ones that are so small that LZW compression isn't used. I had to modify CG.EXE by replacing "Avis Durgan" with a zero string so I could compare the original and recompiled bytecode properly. Added support for non-encrypted messages to AGIdecompile. Also added the additional AGI v3 commands to SYSDEFS.v2.

Therefore, I managed to decompile and recompile with identical results:
  • Donald Duck's Playground v1.0Q, AGI v2.001
  • Gold Rush v2.01, AGI v3.002.149
  • King's Quest I v1.0U, AGI v2.272
  • King's Quest II v2.2, AGI v2.426
  • King's Quest III v1.01, AGI v2.272
  • Leisure Suit Larry v1.0, AGI v2.440
  • Mixed-up Mother Goose (no version number), AGI v2.915
  • Manhunter New York v1.22, AGI v3.002.107 (Has one bad jump instruction in RM.159, jumps into the middle of an IF block?)
  • Police Quest v2.0G, AGI 2.917
  • Space Quest v1.0X, AGI 2.089
  • Space Quest II v2.0F, AGI v2.936
  • King's Quest IV v2.0: has strange jumps in rm0 that causes AGIdecompile to lose sight of its braces, and the AGI interpreter to crash or behave erratically when CTRL+R is pressed in CGA mode. As this does not occur in v2.3 of the game, I attribute this entirely to an error in the original bytecode. CG v3.14 freezes upon compiling several of the decompiled KQ4 scripts apparently because of their very long said strings (five to six words). But those that do compile are identical to their originals as well.
Now, to figure out what's going on with CG and AGIv1 sources.

14
AGI Development Tools / Re: AGI v1 resource extractor and sound converter
« on: November 11, 2016, 02:17:20 PM »
After having rewritten the ELSE/GOTO handling at least five times, AGIdecompile now produces sources that when fed to CG now yield 100% identical byte codes. I have tried this successfully with KQ3 v2.14, SQ v1.0X, KQ2 v2.2., and Donald Duck's Playground v1.0Q. SQ v1.0x (AGI v2.089) and DP require modifying SYSDEFS so that quit() has no argument, and DP v1.0Q (AGI v2.001) additionally requires set.game.id to have a NUM instead of a MSGNUM argument.

The version of CG that I have (v3.14) so far refuses to compile AGI v1 scripts at all; complaining that it does not know the "==" etc. operators. How strange.

15
AGI Development Tools / Re: AGI v1 resource extractor and sound converter
« on: November 08, 2016, 12:01:21 PM »
There are two systematic differences:
  • My decompiler outputs the final return(). CG expects source files to have no return() at the end, and always adds its own. Therefore, when recompiling files produced by AGIdecompile, the recompiled files have two returns at the end. I should modify AGIdecompile to suppress the final return().
  • The original logic files sometimes have FE 00 00, which means jump +0, which has absolutely no effect. AGIdecompile ignores such instructions, as they may confuse my resolving of jumps to ELSE braces. But when CG recompiles those source files, the recompiled logics don't have the FE 00 00 either. So I wonder how they got there in the first place, since obviously they are not generated by CG. I could imagine the programmer inserting an explicit GOTO to a label that immediately follows the GOTO, for example because there used to be code in-between that was removed at some point. This occurs several times in BC.
There are eight logics in KQ2 v2.2 with other differences that I still need to investigate. When I decompile these recompiled logics again, the sources are completely identical, for what it's worth.

Also, CG does not compile a few sources at all but exits with an "output buffer overflow", notably PQ's rm0. That happens exclusively with late 1987 games, while my CG.EXE has a late 1986 time stamp. Either I need to specify a command-line option that enlarges the "output buffer", or the later games need a newer CG.EXE. I don't think that's the fault of the decompiler though.

Pages: [1] 2 3 4

SMF 2.0.19 | SMF © 2021, Simple Machines
Simple Audio Video Embedder

Page created in 0.037 seconds with 20 queries.