417
edits
(Added done stuff on 2007-07-02.) |
(Fixed link (palex.py -> agi-palex.py)) |
||
(117 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
= [[User:Buddha^|Buddha^]]'s Google Summer of Code 2007 Project Diary = | |||
Here's the archive of the project diary I kept during my | |||
Google Summer of Code 2007 participation. | |||
== 2007-05-28 (Monday) - GSoC starts! == | == 2007-05-28 (Monday) - GSoC starts! == | ||
Line 408: | Line 413: | ||
** White text with a red (Unchosen) or cyan (Chosen) background. | ** White text with a red (Unchosen) or cyan (Chosen) background. | ||
** An example: Cancel in a Restart/Cancel-dialog. | ** An example: Cancel in a Restart/Cancel-dialog. | ||
(Correction to the above (Added on 2007-07-05): All chosen elements have black text color, not white). | |||
Some elements aren't in color. Like the elements in the top dropdown menu. | Some elements aren't in color. Like the elements in the top dropdown menu. | ||
Line 427: | Line 434: | ||
checked out branch-0-10-0 so I might commit the Gold Rush intro workaround | checked out branch-0-10-0 so I might commit the Gold Rush intro workaround | ||
to it too in addition to the trunk. Tomorrow I'm going to do some work too ;-) | to it too in addition to the trunk. Tomorrow I'm going to do some work too ;-) | ||
== 2007-07-03 (Tuesday) - First workaround backport and Amiga style menus prove a little bit problematic == | |||
Backported the Gold Rush intro skipping bug's workaround to the 0.10.0 branch. | |||
Investigated ScummVM's AGI engine's menu system a bit. It's not without its difficulties | |||
though, as in Amiga AGI games in a selection box there is no concept of a currently | |||
chosen element unless you go and click on them with your mouse. In ScummVM's AGI engine | |||
there always is a chosen element in a selection box by default. It wouldn't be very | |||
intuitive e.g. if you had an orange button (Currently chosen) on the left and a red | |||
button on the right and you'd press right to change the selected button and the left | |||
button would change color to green and the right button would change color to cyan. | |||
How would you know which of the buttons is the currently chosen one and which is not | |||
if you didn't know about the color coding beforehand? | |||
So I've got two ways to make the Amiga style menus happen: | |||
* Make it so that you have to click on things with your mouse (Or whatever emulates a mouse) because that's the way Amiga AGI games did it. | |||
** This would get around the problem of not knowing what button is selected based on the button's color as you'd have to go and click on the button you want to press. | |||
** This would also be more faithful to the Amiga AGI games as they did it this way (At least as far as I know). | |||
** This would change the usability of the ScummVM's AGI engine in Amiga mode because now you'd have to click on things to press them. | |||
** Probably a bit harder to implement than the latter approach. | |||
* Make somehow apparent which of the buttons is currently selected (E.g. draw a black border around the chosen button). | |||
** This also would get around the problem of not knowing what button is selected as you'd see it by the chosen button's obvious border coloring (Or whatever method would be used). | |||
** This wouldn't be completely faithful to the Amiga AGI games as they didn't have a currently chosen button as far as I know. | |||
** This wouldn't change the usability of the ScummVM's AGI engine from its current state. | |||
** Probably a bit easier to implement than the former approach. | |||
== 2007-07-04 (Wednesday) - Investigating EGA & Amiga-ish palette & doing groundwork for implementing Amiga style menus == | |||
Took a look at the Amiga-ish palette (newPalette-array in engines/agi/graphics.cpp) and the | |||
normal EGA palette (egaPalette-array in engines/agi/graphics.cpp). Compared them a bit. | |||
Here's how they look: | |||
[[Image:scummvm-0.10.0-agi-palette_comparison.png|frame|center|EGA (Top) vs. Amiga-ish (Bottom) palette]] | |||
Here's only the EGA palette on its own as a 8x2 image (Scaled up by a factor of 40 for easier visibility), so one can more easily compare the different shades of similar colors: | |||
[[Image:scummvm-0.10.0-agi-egaPalette.png|frame|center|EGA palette (Top: Colors 0-7. Bottom: Colors 8-15)]] | |||
And here's the Amiga-ish palette on its own: | |||
[[Image:scummvm-0.10.0-agi-newPalette.png|frame|center|Amiga-ish palette (Top: Colors 0-7. Bottom: Colors 8-15)]] | |||
Pondered about the way to pass information to the drawButton-function in the AGI engine. Probably | |||
going to pass some struct to it that has info on what colors to use in which situation (e.g. use this | |||
color when a positive button is in focus, use this color when a negative button is unchosen etc). | |||
Consulted Sev about which way to go about the Amiga style menus and yes, I'm going to implement them by a | |||
little non-authenticity by using a border around the currently chosen button. This has the positive aspect | |||
of not altering the usability of ScummVM from its current state. | |||
== 2007-07-05 (Thursday) - Working on Amiga style menus implementation == | |||
Took screenshots of a couple of Amiga AGI games using WinUAE 1.4.2a. | |||
Worked on the Amiga style menus implementation. Probably going to | |||
try a bit different way at the implementation tomorrow. | |||
Screenshots from King's Quest I and King's Quest III on Amiga showing different button colors (Screenshots taken with WinUAE 1.4.2a): | |||
=== King's Quest I (Amiga) screenshots === | |||
[[Image:kq1-amiga-restart_dialog-no_presses.png|frame|center|King's Quest I (Amiga): Restart-dialog. No buttons are being pressed with the mouse.]] | |||
[[Image:kq1-amiga-restart_dialog-pressing_restart.png|frame|center|King's Quest I (Amiga): Restart-dialog. Restart-button is being pressed with the mouse.]] | |||
[[Image:kq1-amiga-restart_dialog-pressing_cancel.png|frame|center|King's Quest I (Amiga): Restart-dialog. Cancel-button is being pressed with the mouse.]] | |||
=== King's Quest III (Amiga) screenshots === | |||
[[Image:kq3-amiga-save_dialog-no_presses.png|frame|center|King's Quest III (Amiga): Save-dialog. No buttons are being pressed with the mouse.]] | |||
[[Image:kq3-amiga-save_dialog-pressing_ok.png|frame|center|King's Quest III (Amiga): Save-dialog. OK-button is being pressed with the mouse.]] | |||
== 2007-07-06 (Friday) - Amiga cursors and palette == | |||
ScummVM's AGI engine has a SCI-style black & white mouse cursor. I added | |||
an Amiga cursor for the Amiga rendering mode (Color values taken from some | |||
Amiga AGI game - I don't remember which - running on WinUAE 1.4.2a). Also took | |||
the Amiga-style busy mouse cursor (An hourglass) from Space Quest II | |||
running on WinUAE 1.4.2a and added its data to ScummVM. The busy mouse cursor | |||
is not used at the moment though. But its there, if someone likes to implement | |||
using it. | |||
Clone2727 on #scummvm had made a [http://wiki.scummvm.org/index.php/AGI/Palettes page] | |||
on ScummVM's wiki for showcasing different palettes used in ScummVM's AGI engine. | |||
It turned out my fiddlings with GIMP for the visualization of | |||
ScummVM's AGI engine's palettes didn't go to waste as the images I made (See my | |||
[http://wiki.scummvm.org/index.php/User:Buddha%5E/GSoC2007-ProjectDiary#2007-07-04_.28Wednesday.29_-_Investigating_EGA_.26_Amiga-ish_palette_.26_doing_groundwork_for_implementing_Amiga_style_menus 2007-07-04 diary entry]) found their way to that page. | |||
Talked about Amiga palettes etc with Raziel_AOne on #scummvm. He told how he | |||
had modified King's Quest's - it was probably I or II - executable back in | |||
the day on Amiga in order to change King Graham's skin color from yellow to pink. | |||
The hack wasn't without its difficulties though, as some of trees etc turned pink | |||
too :-). Raziel just wanted to know if there was a way to modify ScummVM so | |||
King Graham's skin color in King's Quest I & II would be pink. Of course its | |||
possible but off the top of my head it may require some sprite specific | |||
modifications. Came to the conclusion that an engine-specific GUI-option | |||
for turning the skin color modification on would be good after talking about | |||
it with Raziel and Sev. | |||
It turned out that different Amiga AGI games use a different palette. | |||
As it dawned on me that Raziel had sometime hex-edited a Sierra AGI executable | |||
on Amiga in order to change the palette I thought that that's gotta be the | |||
place where the palette is defined. So I asked enthusiastically if he could show | |||
me the position in the executable. Later he sent me an email with the | |||
info and also some of the different palettes from various Amiga AGI games. | |||
Amiga AGI game palettes, here I come :-). | |||
== 2007-07-07 (Saturday) - Comparing menu borders and decoding Amiga cursor format == | |||
Compared different menu border styles for the Amiga-style menus with GIMP. Probably | |||
going to simply use a thick black border around the currently chosen button as its | |||
easy to code and in my opinion it looks sufficiently intuitive and ok. | |||
Also looked at the cursor files that come with some of the Amiga AGI games | |||
(The files are named Busy and Pointer). Finally figured them out almost | |||
completely. | |||
=== Amiga AGI games' cursor format === | |||
My current theory on the format is as follows (Based on the Busy and Pointer -files | |||
from the Amiga version of King's Quest III): | |||
==== Cursor's bitmap data ==== | |||
* Starts with four bytes of zero. | |||
** Don't know what these are for. Maybe flags? | |||
** Were zero in both Busy and Pointer -files. | |||
* 16-bit big endian word: Bitplane 0 of row 0 | |||
** The most significant bit is graphically the leftmost one | |||
** The least significant bit is graphically the rightmost one | |||
* 16-bit big endian word: Bitplane 1 of row 0 | |||
* 16-bit big endian word: Bitplane 0 of row 1 | |||
* 16-bit big endian word: Bitplane 1 of row 1 | |||
* ... and so on for all the rows 0-15 | |||
==== Cursor's palette ==== | |||
* Again four bytes of zero. | |||
** Don't know what these are for. Maybe flags? | |||
** Were zero in Both Busy and Pointer -files. | |||
* Then the palette for four colors: | |||
* Palette entry for color 0: | |||
** 16-bit big endian word: ARGB-color with 4-bits per color component | |||
*** Alpha is bits 12-15 | |||
**** Value of 0x0F means the color is totally transparent | |||
*** Red is bits 8-11 | |||
*** Green is bits 4-7 | |||
*** Blue is bits 0-3 | |||
* Likewise palette entries for colors 1, 2 and 3 | |||
That's it. So the files are 80 bytes long, the bitmap is 16x16 in size | |||
and uses 4 colors. Some of the zero bytes are still such that I'm not | |||
completely sure what they're there for. And I'm not 100% sure about | |||
the first palette entry if its really just that and not some other | |||
data but it does fit the theory nicely. | |||
Here are images of the Busy and Pointer -files: | |||
[[Image:Amiga-AGI-Busy-Cropped.png|frame|none|Busy -mouse cursor]] | |||
[[Image:Amiga-AGI-Pointer-Cropped.png|frame|none|Pointer -mouse cursor]] | |||
== 2007-07-09 (Monday) - Amiga AGI game palette extracting == | |||
Today I made a command line tool for detecting and extracting | |||
Amiga AGI game palettes. You can make it print out a C-array | |||
of the 16-color 12-bit RGB palette if its found. Removes | |||
duplicate palettes too (Found in some file I tried). | |||
Here's the format of the Amiga AGI games' palettes: | |||
* The palette consists of 16 colors. | |||
* Each color consists of red, green and blue components (In this order). | |||
* Each component is a 16-bit big endian word in range 0-15 (i.e. 4 bits). | |||
The palette should be found in the game's executable file. | |||
I use the following heuristic for detecting a possible palette from a file: | |||
* First color must be black i.e. R = G = B = 0 | |||
* Last color must be white i.e. R = G = B = 0x0F | |||
* All components of all colors must be in range 0-15 | |||
* No other black color must exist in the palette than the first color | |||
** Added to help weed out some false positives | |||
== 2007-07-10 (Tuesday) - Added Amiga-style menus (i.e. colored options) == | |||
Added Amiga-style colored options | |||
([http://sourceforge.net/tracker/index.php?func=detail&aid=657645&group_id=24759&atid=382573 FR #657645]) to the trunk. | |||
Here are the differences (That I can think of at the moment) | |||
to the original Amiga AGI engine: | |||
* Buttons are a bit thinner than in the original Amiga AGI engine | |||
* Currently chosen button has a black border around it | |||
** There was no such thing in the original Amiga AGI engine | |||
* Pressed buttons changed color in the original Amiga AGI engine | |||
** Currently ScummVM's AGI engine doesn't use the pressed state although there is some support for it in the code | |||
== 2007-07-11 (Wednesday) - Added Amiga AGI game palette extractor tool == | |||
Went to town ([http://www.pori.fi/english/ Pori]) to buy some new clothes. Didn't do very much strictly work today. | |||
Mostly worked on the Python version of the Amiga AGI game palette extractor. | |||
I had made a C++ version of it but felt that it might be good to learn a | |||
language that would be easier to do things fast in. And as Python had come | |||
up in discussions with a good friend of mine, I thought, why not try it. | |||
I started dabbling with Python a day or two ago. Just downloaded the Python Windows installer | |||
and the HTML-version of the documentation from [http://python.org/ python.org]. | |||
Seems like a nice language. Laughed out loud at some of the Monty Python jokes | |||
in the examples :-). Like the list of strings ['cat', 'window', 'defenestrate'] in this | |||
[http://docs.python.org/tut/node6.html#SECTION006200000000000000000 example]. | |||
Like what? Defenestrate? What's that? Have a look what Meyer-Webster has to say about | |||
[http://www.m-w.com/dictionary/defenestrate defenestrate] :-). | |||
So I made a tool for extracting palettes from Amiga AGI games' executable files | |||
and added it to ScummVM's trunk. You can see the source code [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/tools/agi-palex.py?revision=28035&view=markup here]. | |||
My first Python program, yay! | |||
== 2007-07-12 (Thursday) - Did more work on the Amiga AGI palettes == | |||
Worked on the Amiga AGI game palette extractor tool. Added wildcard | |||
support and a preliminary test that speeded the program up like a gazillion times or so :-). | |||
== 2007-07-13 (Friday) - Left for a short vacation in eastern Finland == | |||
Went to eastern Finland to the city of Kouvola with my parents and my older brother. | |||
The occasion was my older brother's godparents' son's graduation party. Worked a bit | |||
on the ride with my laptop. Did some additional tool hacking with Python to parse the | |||
data Raziel_AOne sent me about different Amiga AGI palettes. Also made a program to | |||
compare different palettes so I can easily see which ones are unique. | |||
== 2007-07-14 (Saturday) - Some festivities and a trip back from eastern Finland == | |||
Celebrated my older brother's godparents' son's graduation and left back for the city of Pori. | |||
Did a bit of work on sorting out the different Amiga AGI palettes on the way back. | |||
== 2007-07-15 (Sunday) - Sorted out the Amiga AGI palettes == | |||
Talked with Raziel_AOne, got original palette data from him. Compared all the palette | |||
data I have and found that there are only three unique palettes. | |||
Added the different Amiga AGI palettes to ScummVM | |||
and modified palette handling in the AGI engine | |||
so it'll be easier to enable the support for those | |||
palettes later (Now the palette data just is there | |||
but isn't used yet). | |||
=== The three generations of Amiga AGI palettes === | |||
From all the Amiga AGI games I and Raziel_AOne gathered | |||
palette data from I found only three unique palettes. | |||
Here's my current theory on them: | |||
* First generation Amiga AGI palette | |||
** Used with Amiga AGI versions 2.0xx - 2.1xx | |||
** Used with Amiga AGI games released in 1986-1987 | |||
*** Maybe also earlier game versions use this palette? | |||
** Examples of different AGI versions using this palette: | |||
*** 2.082 (King's Quest I v1.0U 1986) | |||
*** 2.082 (Space Quest I v1.2 1986) | |||
*** 2.090 (King's Quest III v1.01 1986-11-08) | |||
*** 2.107 (King's Quest II v2.0J 1987-01-29) | |||
*** x.yyy (Black Cauldron v2.00 1987-06-14) | |||
*** x.yyy (Larry I v1.05 1987-06-26) | |||
* Second generation Amiga AGI palette | |||
** Used with Amiga AGI versions 2.2xx | |||
** Used with Amiga AGI games released in 1988 | |||
** Examples of different AGI versions using this palette: | |||
*** 2.202 (Space Quest II v2.0F. Intro says 1988. ScummVM 0.10.0 detects as 1986-12-09) | |||
* Third generation Amiga AGI palette | |||
** Used with Amiga AGI versions 2.3xx | |||
** Used with Amiga AGI games released in 1989 | |||
** Examples of different AGI versions using this palette: | |||
*** 2.310 (Police Quest I v2.0B 1989-02-22) | |||
*** 2.316 (Gold Rush! v2.05 1989-03-09) | |||
*** x.yyy (Manhunter I v1.06 1989-03-18) | |||
*** 2.333 (Manhunter II v3.06 1989-08-17) | |||
*** 2.333 (King's Quest III v2.15 1989-11-15) | |||
Palette data comparison (12-bit RGB data): | |||
(From color 0 to 15 from top to bottom, from first to third generation from left to right) | |||
* 0x000, 0x000, 0x000 (No difference) | |||
* 0x00F, 0x00F, 0x00B (Some difference) | |||
* 0x080, 0x080, 0x0B0 (Some difference) | |||
* 0x0DB, 0x0DB, 0x0BB (Some difference) | |||
* 0xC00, 0xC00, 0xB00 (Some difference) | |||
* 0xB7D, 0xB7D, 0xB0B (Major difference) | |||
* 0x850, 0x850, 0xC70 (Some difference) | |||
* 0xBBB, 0xBBB, 0xBBB (No difference) | |||
* 0x777, 0x777, 0x777 (No difference) | |||
* 0x0BF, 0x0BF, 0x00F (Major difference) | |||
* 0x0E0, 0x0E0, 0x0F0 (Some difference) | |||
* 0x0FD, 0x0FD, 0x0FF (Some difference) | |||
* 0xF98, 0xF98, 0xF00 (Major difference) | |||
* 0xF70, 0xD0F, 0xF0F (Major difference) | |||
* 0xEE0, 0xEE0, 0xFF0 (Some difference) | |||
* 0xFFF, 0xFFF, 0xFFF (No difference) | |||
== 2007-07-16 (Monday) - Worked on the online AGI256 and AGI256-2 documentation == | |||
Added information about AGI256 and AGI256-2 to the AGI Specifications page. | |||
The info is in the [[AGI/Specifications/Other#Extensions | Fan-Made Extensions]] section. | |||
I'm quite pleased with the general descriptions but not so much with the implementation details | |||
subpages for AGI256 and AGI256-2. They're a bit of a mess at the moment to say it politely ;). | |||
== 2007-07-17 (Tuesday) - Banged my head to the wall with bug #1751483 == | |||
Tried to fix [https://sourceforge.net/tracker/?func=detail&atid=418820&aid=1751483&group_id=37116 bug #1751483] | |||
(Description: "AGI: The -x command-line option appears to be broken"). | |||
Was somehow unfocused today, did only about a half a day's work. | |||
Didn't get far with the bugfixing as I banged my head to the wall with it | |||
for some hours. It just seemed that yes, the save_slot parameter does get correctly | |||
parsed from the command line and set to the configuration manager's key | |||
save_slot but doesn't for some unknown reason get to the AGI engine at all. | |||
Sooo... it seems that it was just the way I used the command line options that | |||
made it act that way. I did use the --save-slot i.e. -x command line option but | |||
used the launcher with it to choose a game. Oh well, I did realize that after | |||
some hours :) and now I can at least reproduce the bug on my machine (By also | |||
giving the game's name on the command line, not just the save slot number). | |||
The problem with my approach was that if no game was given on the command line | |||
the save_slot's value was cleared when loading a game. It got cleared as a part | |||
of the configuration manager's transient domain (kTransientDomain i.e. | |||
__TRANSIENT) that got cleared at game loading. So no wonder the value never | |||
got to the AGI engine's side at all :-). | |||
And yeah, it's broken at the moment, the bug is true. With Police Quest I's | |||
PC version I also got the menus to disappear when loading some save game for it | |||
from the command line. And when I tried accessing the menu the game | |||
died. So it's definitely broken. But I haven't come up with a reasonably | |||
easy way to fix it yet and starting work on the Apple IIGS sound support | |||
is around the corner so I'll probably put this bug back to the pool. | |||
== 2007-07-18 (Wednesday) - Started looking into Apple IIGS sound support == | |||
Searched the net for information on Apple IIGS sound. Read some. | |||
Filled in the mid-term student survey with quite a bit of comments. | |||
== 2007-07-19 (Thursday) - Apple IIGS files == | |||
Wasn't very productive today. But at least found [http://ciderpress.sourceforge.net/ Ciderpress] | |||
after several hours of searching. | |||
Briefly tried the Apple IIGS version of King's Quest I. Went to the castle's front door, | |||
typed "open door" and pressed enter. A popup box springed up telling me the door opens | |||
and the door opened, but Graham just stood there and I couldn't move him anymore. | |||
So clearly the support's not perfect yet :-). | |||
== 2007-07-20 (Friday) - A brief look into the current Apple IIGS sound implementation == | |||
Looked a bit into the current Apple IIGS sound implementation and read some more | |||
of the AGI specifications about the Apple IIGS sound. | |||
== 2007-07-23 (Monday) - Starting looking into ScummVM's audio related code == | |||
Got back from a weekend visit to Turku. I hadn't redirected my snail mail so I | |||
went to Turku to check if I had received any mail (More like to check if I had got | |||
any bills that I needed to pay). But luckily there weren't many bills, only one | |||
credit card bill and it wasn't large. So came back to the countryside, here near | |||
Pori. | |||
Started looking into ScummVM's audio related code so I'll know what classes to use | |||
for what needed functionality in the Apple IIGS sound implementation. The MIDI parsing | |||
related code looks promising... as it seems that the Apple IIGS AGI engine uses MIDI | |||
data. But I'll have to recheck that once I get to implementing it (Or a bit *before* | |||
that :-)). | |||
== 2007-07-24 (Tuesday) - Looking at the current Apple IIGS sound implementation == | |||
Been feeling a bit weird today after dinner. Like my legs are a bit cold but some | |||
parts of my body are a bit warmer than usual. Maybe I'm getting sick or having a | |||
fever coming on... we'll see. | |||
Took another look at the current Apple IIGS sound implementation in ScummVM. Loaded up some | |||
resource files (The *vol.* files) from Apple IIGS AGI games as raw 8 bit unsigned 8kHz | |||
sample data into Audacity and pressed play: MIAUUU! PRRRR! SQUEAAK! | |||
KRRRKRRRRKRRRRRRRRRR! "All aboard!" etc. Yeah, there's sample data in there alright :-). | |||
== 2007-07-25 (Wednesday) - Dumping Apple IIGS sound files == | |||
Made ScummVM dump out the Apple IIGS MIDI and sample files and then converted | |||
the samples to .au-format using Python (It's got a library for outputting .au-files | |||
so it wasn't very hard). Here's a sound from Gold Rush: | |||
[[media:gold_rush-apple_iigs-sample-068.au | A man yelling "All aboard!"]]. | |||
Possibly going to mess with [http://www.mess.org/ MESS] to better understand | |||
how the sound works with Apple IIGS AGI games. | |||
== 2007-07-26 (Thursday) - Some recreation == | |||
Took the day off and looked a bit at [http://en.wikipedia.org/wiki/Sanitarium_(videogame) Sanitarium] | |||
with IDA among other things. And had some snails and onion soup :). | |||
BTW Sanitarium uses Smacker for videos (There's a DLL so it's not hard to spot :-)). | |||
And the game's main executable holds a nice collection of error and debug | |||
messages that help reverse engineering. | |||
== 2007-07-27 (Friday) - Apple IIGS sample loading == | |||
Made routines for loading Apple IIGS AGI sample resources and making | |||
audio streams out of them. Took influence from the AIFF-loading routine | |||
from ScummVM's source code. | |||
== 2007-07-28 (Saturday) - Decoding Apple IIGS sample header, Part 1 == | |||
Modified a byte in an Apple IIGS AGI sample resource's header (At | |||
header offset 2) and tried the sample out by running the game | |||
using KEGS32 and MESS. So it turned out that that header byte | |||
handles playing pitch. And it's definitely exponential | |||
with 2**(1/12) as the base. The value seems to wrap around after 0x7F. | |||
== 2007-07-29 (Sunday) - Decoding Apple IIGS sample header, Part 2 == | |||
Inspected how the byte in Apple IIGS AGI sample resource's header | |||
offset 4 affects the playing of the sample. It is the volume control, | |||
probably logarithmic, but not 100% sure about that yet. | |||
Fiddled a bit with some other header offsets and got something | |||
interesting and/or weird to happen but don't yet know what they | |||
really did :-). | |||
The Apple IIGS AGI sample resource's header is 54 bytes long and | |||
by the header comparisons I've done the following header offsets | |||
are the most varying ones (Some other bytes also vary, but only | |||
between two values in the data I've compared): | |||
* Header offset 2 | |||
** The playing pitch | |||
* Header offset 4 | |||
** Volume control | |||
* Header offsets 8 and 9 | |||
** Sample size in bytes (Little endian 16-bit word) | |||
* Header offset 44 | |||
** Unknown function, uses values x*9 for x in {0, 1, 2, 3, 4, 5, 6} | |||
* Header offset 45 | |||
** Unknown function, uses values 0, 2, 6 | |||
* Header offset 50 | |||
** Unknown function, uses values x*9 for x in {1, 2, 3, 4, 5, 6} | |||
* Header offset 51 | |||
** Unknown function, uses values 0, 1, 2, 7 | |||
== 2007-07-30 (Monday) - Locating Apple IIGS instruments and Atari ST and Apple IIGS palettes == | |||
Played with [http://hte.sourceforge.net/ HT Editor] to find out where the instrument | |||
data is in different Apple IIGS AGI games. Found out the offsets into the games' executables | |||
but haven't yet compared the instrument data between games to see how much of it is shared data. | |||
Also looked into the SIERRASTANDARD-file that comes with Apple IIGS AGI games. | |||
It's a 65536 bytes long file containing raw unsigned 8-bit mono PCM-audio data used | |||
by the instruments. The file is identical between all the Apple IIGS AGI games I've | |||
tested, excluding Space Quest I (It has a couple of different sounds). | |||
As I was going through the Apple IIGS AGI executables in search for the instrument data | |||
I also thought why not look for the palette data as well. Tried out a couple of possibilities | |||
and finally found the palette with the search key (0xBB, 0x0B). As I had looked up from | |||
Wikipedia that Apple IIGS used a 4096 (12-bit) palette it helped to narrow down the | |||
search possibilities. Bytes 0xBB, 0x0B define an AGI palette color 7, which is gray. | |||
So I looked through all the Apple IIGS game data I had for different palettes and compared | |||
them. | |||
According to the data I have compared there are two different Apple IIGS AGI palettes. | |||
The first one is older and is only used in Space Quest I (AGI version 1.002) and it | |||
is identical to the oldest generation [[User:Buddha%5E/GSoC2007-ProjectDiary#The_three_generations_of_Amiga_AGI_palettes | Amiga AGI palette]]. | |||
All other games (AGI versions 1.003 - 3.003) use a slightly different palette that's otherwise | |||
identical to the first one but has a different color 13. Older palette uses an orange 0xF70 | |||
(12-bit RGB) there but all others use a light purple 0xD9F. | |||
Just for the kicks I also looked through Atari ST AGI executables for palette data. | |||
Wikipedia helped here again as it told me that the original Atari ST had a 64-color | |||
palette. So after some searching I found the palette data. Extracted palettes from | |||
all the Atari ST AGI executables I had access to and compared the data. I only | |||
found a single identical palette shared between all of the Atari ST AGI games. | |||
Here it is: | |||
<pre> | |||
/** | |||
* Atari ST AGI palette. | |||
* Used by all of the tested Atari ST AGI games. | |||
* 16 RGB colors. 3 bits per color component. | |||
*/ | |||
static const byte atariStAgiPalette[16 * 3] = { | |||
0x0, 0x0, 0x0, | |||
0x0, 0x0, 0x7, | |||
0x0, 0x4, 0x0, | |||
0x0, 0x5, 0x4, | |||
0x5, 0x0, 0x0, | |||
0x5, 0x3, 0x6, | |||
0x4, 0x3, 0x0, | |||
0x5, 0x5, 0x5, | |||
0x3, 0x3, 0x2, | |||
0x0, 0x5, 0x7, | |||
0x0, 0x6, 0x0, | |||
0x0, 0x7, 0x6, | |||
0x7, 0x2, 0x3, | |||
0x7, 0x4, 0x7, | |||
0x7, 0x7, 0x4, | |||
0x7, 0x7, 0x7 | |||
}; | |||
</pre> | |||
== 2007-07-31 (Tuesday) - Comparing Apple IIGS instruments == | |||
Made a quick Python program for seeking out the instrument data from | |||
Apple IIGS AGI executables and comparing them. I used a part of the first | |||
instrument's starting data ('\x7f\x00\x0f\x78\x0a\x00\x78\x00\x00\x00\x14\x05') | |||
as the search string. Here's what I found out: | |||
There are two partially different instrument sets. | |||
One is from the oldest test subject (Space Quest I using AGI 1.002) | |||
and the other is from the newer games using AGI 1.003 - AGI 3.003. | |||
Space Quest I has 26 instruments (1192 bytes), all others have 28 instruments (1292 bytes). | |||
16 of the instruments are shared between the two data sets so | |||
Space Quest I has 10 unique instruments. The unique instruments | |||
are 2, 4, 13, 14, 17, 18, 20, 21, 22, 23 (Zero-based numbering). | |||
All instruments are 44 bytes in length excluding instruments 6, 7 and 8 | |||
of the newer instrument set (And instruments that are identical with them, | |||
of course). Instrument 6 of the newer instrument set is 80 bytes in length, | |||
instruments 7 and 8 are 56 bytes. | |||
Here are the starting offsets for instrument data in the tested Apple IIGS AGI executables: | |||
* 0x80AD | |||
** SQ.SYS16 (Space Quest I, AGI 1.002) | |||
* 0x844E | |||
** LL.SYS16 (Leisure Suit Larry I, AGI 1.003) | |||
* 0x8469 | |||
** DEMO.SYS16 (AGI Demo 2, AGI 1.005) | |||
** KQ.SYS16 (King's Quest I, AGI 1.006) | |||
** PQ.SYS16 (Police Quest I, AGI 1.007) | |||
* 0x84B7 | |||
** KQ2.SYS16 (King's Quest II, AGI 1.013) | |||
** MG.SYS16 (Mixed-Up Mother Goose, AGI 1.013) | |||
** KQ3.SYS16 (King's Quest III, AGI 1.014) | |||
* 0x6563 | |||
** SQ2.SYS16 (Space Quest II, AGI 1.014) | |||
* 0x8979 | |||
** MH.SYS16 (Manhunter I, AGI 2.004) | |||
** KQ4.SYS16 (King's Quest IV, AGI 2.006) | |||
** BC.SYS16 (The Black Cauldron, AGI 3.001) | |||
** GR.SYS16 (Gold Rush, AGI 3.003) | |||
BTW I also found out that by going 4 bytes backwards from the start | |||
of the instrument data you'll find a little endian 16-bit | |||
word giving the length of the whole instrument set (So it's | |||
1192 with Space Quest I, 1292 with all the others). | |||
== 2007-08-01 (Wednesday) - Instrument data, palette commits and Apple IIGS AGI debug mode triggers == | |||
Still played a bit with the Python program that handles the | |||
Apple IIGS instrument data extraction. Now I feel like I'm | |||
getting a bit of a hang of the instrument data. | |||
Here's an odd bit of logic code I found from Apple IIGS | |||
version of King's Quest I (I added the comments): | |||
<pre> | |||
if (v20 == 0) // v20 is computer type, value 0 is IBM-PC | |||
set.game.id("PQ"); // Police Quest?! | |||
else | |||
set.game.id("KQ"); | |||
</pre> | |||
Look at [[AGI/Specifications/Internals#Variables_used_by_the_interpreter | variables used by AGI]] for info on v20. | |||
Like what? Why? Why would the game want to change its game ID | |||
based on what computer it's being run on? Totally weird... | |||
Also found some word triggers for Apple IIGS AGI debug modes: | |||
* Police Quest I | |||
** pqdbg | |||
** stink bug | |||
* King's Quest I | |||
** kqdbg | |||
* King's Quest II | |||
** kq2dbg | |||
* King's Quest III | |||
** kq3dbg | |||
** mice ass | |||
* Space Quest II | |||
** sq2dbg | |||
Encountered CE in the games' version numbers (Example: "1.0K 11/22/88 CE") | |||
and wondered about what it meant. After looking through some of the messages | |||
in the logic resources I think CE probably means Carlos Escobar as he's credited as | |||
the maker of (At least some - if not all - of) the Apple IIGS AGI versions. | |||
Committed the Apple IIGS and Atari ST palettes to the trunk (Here's the | |||
[http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/graphics.cpp?r1=28114&r2=28387&sortby=file diff]). | |||
== 2007-08-02 (Thursday) - Trying to figure out Apple IIGS sample header == | |||
Tried to figure out what the unknown bytes in the Apple IIGS AGI sample resource's header do. | |||
Finally figured out bytes at header offsets 44, 45, 50 and 51. According to my current | |||
theory bytes 45 and 51 contain channel info and playing mode and bytes 44 and 50 control | |||
played wave length. They're all encoded in the same fashion as the same info in Apple IIGS | |||
instruments (More info [[AGI/Specifications/Sound#MIDI_sequences | here]]). | |||
Committed the Apple IIGS AGI sample loading code to the trunk | |||
(/scummvm/trunk/engines/agi/sound.cpp: diff to | |||
[http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=27024&r2=28404&sortby=date r28404] and | |||
[http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28404&r2=28405&sortby=date r28405]) | |||
== 2007-08-03 (Friday) - Figured out most of the missing parts of the Apple IIGS sample header == | |||
Finally figured out most of the missing parts of the Apple IIGS sample header (A not-so-pretty | |||
[http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28405&r2=28432&diff_format=l diff]. | |||
Look at struct IIgsSampleHeader). I had pondered whether there was some kind of an envelope in the header... | |||
and there is! It's actually identical to a part of the Apple IIGS instrument header. Making | |||
that connection was the key. Looking at the sample headers' histogram in Open Office also helped | |||
(I had made a Python program for gathering the data and outputting it as comma separated values | |||
to a text file. Open Office can import those .CSV-files so it's easy to read the data in). | |||
Also as a side thing I extracted the Apple IIGS AGI arrow cursor data from a screenshot and | |||
committed it to the trunk | |||
([http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/graphics.cpp?r1=28387&r2=28436 Diff]). | |||
Here's what the Apple IIGS AGI arrow cursor looks like on a blue background: | |||
[[Image:AppleIIgs-AGI-arrow_cursor-upscale_x10.png|frame|none|Apple IIGS AGI arrow cursor]] | |||
On a different note I watched Assembly 2007's Oldskool Demo competition online during the night. | |||
Vic-20, Atari 2600 and NES demos, whee :-). The NES demo had nice speech effects for the credits. | |||
If you're interested be sure to check out the 64kB intro compo and the main demo compo today using | |||
[http://www.assemblytv.net/2007/stream-en Assembly TV]. | |||
== 2007-08-04 (Saturday) - A couple of compilation fixes == | |||
Carch on #scummvm told of a couple of compilation problems that | |||
ScummVM's current trunk has on on Windows (VS2003), Xbox (VS2003) and Xbox 360 | |||
(VS2005). We investigated the problems together and I committed the | |||
fixes to the trunk ([http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28445&r2=28446&sortby=date Here] and | |||
[http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/kyra/script.cpp?r1=28297&r2=28447&sortby=date here]). | |||
In Kyra's code an object wasn't converted automatically to a boolean value even though it | |||
had an operator bool defined so I added an explicit bool conversion and that fixed the problem. | |||
In the AGI code there was a problem with automatic selection of the wanted version of the | |||
pow-function. So I replaced the offending pow-function call with a constant value as it | |||
actually was calculating a constant and not a variable and it worked. Carch also gave another | |||
way to fix the problem and that was to replace the pow(2, 1/12.0) call with a pow(2.0, 1/12.0) | |||
call. That way the compiler knew to choose the pow(double, double) version of the pow-function. | |||
== 2007-08-06 (Monday) - Mostly a holiday == | |||
Didn't sleep much last night (About 3,5h or so) and my sister came to visit | |||
with her children. Played with my niece, took an evening nap, ate, watched | |||
Michio Kaku's Time-documentary's 4th part and also Simpsons etc. So this | |||
was mostly a holiday. | |||
== 2007-08-07 (Tuesday) - Working on Apple IIGS instrument loading == | |||
Worked on Apple IIGS instrument loading code for ScummVM. | |||
== 2007-08-08 (Wednesday) - Some more work on the Apple IIGS instrument loading == | |||
Worked some more on the Apple IIGS instrument and wave file loading code | |||
(Here's today's tiny [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28501&r2=28505 commit]). | |||
== 2007-08-09 (Thursday) - Committed Apple IIGS instrument and wave file loading code == | |||
Committed the Apple IIGS instrument and wave file loading code to the trunk. | |||
Diffs: | |||
* Small commits: | |||
** [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28505&r2=28506 Removed old loadInstruments()] | |||
** [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28506&r2=28507 Brought back and changed some variables from inside a #if 0 ... #endif] | |||
* The main bulk of code: | |||
** Added Apple IIGS instruments and wave file loading. (Apple IIGS music playing is broken at the moment) | |||
*** [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28507&r2=28508 Code] | |||
*** [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.h?r1=27024&r2=28508 Header definitions] | |||
Also learned that the command line tool svn doesn't convert "\n" to a newline (I gave a commit log with the -m parameter | |||
to the svn-tool with a "\n" in it. It didn't convert it at all but just copied it as it is to the commit log). | |||
== 2007-08-10 (Friday) - True sample size calculation and taking variables apart == | |||
Worked on fixing the Apple IIGS samples' sizes as they can be smaller in reality | |||
than what's saved in the sample headers. It can be so because a zero in the sample | |||
data stream will end the sample prematurely (That's something the Apple IIGS's | |||
sound chip [http://en.wikipedia.org/wiki/Apple_IIGS#Audio_features Ensoniq ES5503 DOC] did). | |||
Also decided to be more free with how I save data in the memory, that is I decided to take | |||
apart some bit field variables read from files and save them in the memory as multiple | |||
variables etc. So the data should now be easier to use. | |||
== 2007-08-13 (Monday) - Restructured some of the Apple IIGS sound code etc == | |||
Restructured some of the Apple IIGS sound code (Put functions inside structs etc). | |||
Realized when talking with Sev that the code submission and evaluation deadline | |||
is next monday, on the 20th. That hadn't really sunk in yet in my mind so this means | |||
this week's going to include lots of ScummVM hacking :). | |||
== 2007-08-14 (Tuesday) - General Apple IIGS sound hacking #1 == | |||
Worked on the Apple IIGS sound code. | |||
== 2007-08-15 (Wednesday) - General Apple IIGS sound hacking #2 == | |||
More work on the Apple IIGS sound code. | |||
== 2007-08-16 (Thursday) - Inspecting Apple IIGS MIDI sound resources == | |||
Played around with the Apple IIGS AGI midi sound resources. Yep, they're | |||
standard MIDI files with a 16-bit little endian 0x0002 header. Sometimes they | |||
start with 0xFC (Stop sequence) right after the header with no encoded delta-time | |||
before the command. And sometimes they end by simply exhausting the midi stream's | |||
length and not giving a 0xFC (Although it might be just that I'm not parsing the | |||
files 100% correctly yet and that's what's making it happen). Also some of the | |||
midi streams seem to have additional data after the first encountered 0xFC. I | |||
looked at the additional trailing data from some of the files and at a first | |||
glance it seems they're full of commands for centering the pitch wheel on different | |||
channels, setting some default values for different controllers or something like that. | |||
Here are some statistics about the Apple IIGS AGI midi sound resources I tested: | |||
* Used commands in the Apple IIGS AGI midi resources (Approximate counts): | |||
** 0x80: 00064488 "Note off" (Varying parameters) | |||
** 0x90: 00065516 "Note on" (Varying parameters) | |||
** 0xB0: 00006252 "Controller" (Varying parameters) | |||
** 0xC0: 00001574 "Program Change" (Varying parameters) | |||
** 0xE0: 00000146 "Pitch Wheel" (Only used with parameter 0x2000 i.e. wheel center) | |||
** 0xFC: 00000271 "Stop sequence" (No parameters for this, ends the stream) | |||
(Update on 2007-08-30: The numbers given above aren't totally correct as | |||
I parsed delta-time as a variable length quantity - rather than a single byte | |||
as it seems to be in these files - when I generated these statistics). | |||
== 2007-08-17 (Friday) - First Apple IIGS sample playing! == | |||
Got an experimental and not-pretty sound mixing code to run and heard the first | |||
Apple IIGS sample playing at a near reasonable pitch too :-). Whee! Getting something | |||
concrete done raises the spirit! Had some red wine and blue cheese for | |||
celebration :-). | |||
== 2007-08-18 (Saturday) - More Apple IIGS sound hacking == | |||
It seems samples aren't looped if a zero in the sample is encountered. So even | |||
if the mode for the sample is set to looping but a zero is encountered in the | |||
sample data the sample will not loop, it will just end. | |||
Whee! Seems like I got most of the samples to play at a correct pitch now! | |||
BTW as a random thought King's Quest III's Apple IIGS version doesn't have | |||
speed settings (slow/normal/fast/fastest) at all, so it can be a pain to play | |||
it using ScummVM. Might have to force some speed settings to the menus... | |||
Played around with the envelopes and as I found out after little testing that | |||
the relative pitch and envelope increment values are 16-bit little endian | |||
values, not 16-bit big endian as I had assumed before, the enveloping started | |||
to sound more authentic like. | |||
== 2007-08-19 (Sunday) - Some more Apple IIGS MIDI hacking == | |||
=== Broken MIDI files === | |||
Seems like King's Quest II's starting song (Greensleeves, sound resource 0) | |||
isn't parsed right. Here's its start: | |||
<pre> | |||
00000000 02 -- 02 00 means that it's an Apple IIGS midi sequence | |||
00000001 00 00 c0 16 -- Then some program changes (command 0xC?) | |||
00000005 00 c8 20 00 -- ... | |||
00000009 c2 14 00 c3 -- ... | |||
0000000d 22 00 c4 22 -- ... | |||
00000011 00 c5 22 00 -- ... | |||
00000015 c6 2a 00 c7 -- ... | |||
00000019 26 00 c1 14 -- ... | |||
0000001d 01 b0 07 69 -- Delta-time 01: controller 7, chan 0, val 0x69 | |||
00000021 00 b8 07 76 -- Delta-time 00: controller 7, chan 8, val 0x76 | |||
00000025 00 b2 07 6d -- Delta-time 00: controller 7, chan 2, val 0x6d | |||
00000029 00 b3 07 7c -- Delta-time 00: controller 7, chan 3, val 0x7c | |||
0000002d 00 b4 07 7c -- Delta-time 00: controller 7, chan 4, val 0x7c | |||
00000031 00 b5 07 7c -- Delta-time 00: controller 7, chan 5, val 0x7c | |||
00000035 00 b6 07 76 -- Delta-time 00: controller 7, chan 6, val 0x76 | |||
00000039 00 b7 07 76 -- Delta-time 00: controller 7, chan 7, val 0x76 | |||
0000003d 00 b1 07 6a -- Delta-time 00: controller 7, chan 1, val 0x6a | |||
00000041 85 90 40 26 -- BUT HERE IT BREAKS DOWN at 0x41 with byte 0x85 | |||
00000045 00 93 4c 26 -- Here are really note on commands (Parsed as controller commands)! | |||
</pre> | |||
So at 0x41 with byte 0x85 it's taken as a first byte of a variable | |||
length quantity (Delta-time here) that's more than one byte long because | |||
the value is over 0x80! After that the data is parsed as controller | |||
commands which it really isn't, it's note on and note off commands. | |||
Why is this this way? What to do? Some bandaid fixing maybe?-) | |||
We'll see... | |||
More breakage: | |||
King's Quest IV's MIDI sound resource 14: | |||
<pre> | |||
00000021 00 b7 07 5a | |||
00000025 d3 96 56 47 -- Here at 0x25 with 0xd3 again the same kind of breakage | |||
00000029 00 97 4a 47 | |||
</pre> | |||
King's Quest IV's MIDI sound resource 39: | |||
<pre> | |||
0000001a 00 b5 07 63 | |||
0000001e 99 95 40 1d -- Here at 0x1e with 0x99 again the same kind of breakage | |||
00000022 11 93 40 44 | |||
</pre> | |||
King's Quest IV's MIDI sound resource 46: | |||
<pre> | |||
0000003d 00 b8 07 73 | |||
00000041 ea 97 43 7c -- Here at 0x41 with 0xea again the same kind of breakage | |||
00000045 00 98 43 7c | |||
</pre> | |||
King's Quest IV's MIDI sound resource 105: | |||
<pre> | |||
0000001a 00 b7 07 71 | |||
0000001e ec 94 3e 23 -- Here at 0x1e with 0xec again the same kind of breakage | |||
00000022 00 95 4a 23 | |||
</pre> | |||
King's Quest IV's MIDI sound resource 109: | |||
<pre> | |||
00000017 00 b3 07 78 | |||
0000001b 93 93 31 4e -- Here at 0x1b with 0x93 again the same kind of breakage | |||
0000001f 02 91 59 52 | |||
</pre> | |||
King's Quest IV's MIDI sound resource 207: | |||
<pre> | |||
0000001a 00 b5 00 78 | |||
0000001e 8a 95 3e 54 -- Here at 0x1e with 0x8a again the same kind of breakage | |||
00000022 03 40 41 05 | |||
</pre> | |||
Mixed-Up Mother Goose's MIDI sound resource 7: | |||
<pre> | |||
0000003d 00 b8 07 73 | |||
00000041 95 92 43 6f -- Here at 0x41 with 0x95 again the same kind of breakage | |||
00000045 00 95 4f 66 | |||
</pre> | |||
Mixed-Up Mother Goose's MIDI sound resource 37: | |||
<pre> | |||
0000003d 00 b8 07 72 | |||
00000041 96 92 47 76 -- Here at 0x41 with 0x96 again the same kind of breakage | |||
00000045 00 95 53 73 | |||
</pre> | |||
=== Possible explanation for the broken MIDI files === | |||
It might just be that Apple IIGS AGI MIDI files don't use a variable | |||
length quantity for the delta-time but always use a single byte delta-time | |||
which *can* be >= 0x80! Investigating... (If this is so then it's a non-standard | |||
behaviour for a MIDI file) | |||
Update! Okay, so it seems these MIDI files don't use variable length quantities | |||
for delta-time. Delta-time is always one single byte even if it might be >= 0x80. | |||
But! That delta-time byte also acts as a shorthand for commands like 0xFC | |||
(Stop sequence) or 0xF8 (Timer sync). | |||
So let's read a single byte from the stream. If it's 0xFC it stops the | |||
sequence right there. If it's 0xF8 we can probably just jump over it as we | |||
probably don't need it. Otherwise you use the byte's value as a delta-time | |||
and then you read the command byte, parameters etc normally (Running status | |||
is also used). At least this is my current theory based on experiments with | |||
a Python program I wrote for parsing these MIDI files. | |||
I checked some files and yes it really does seem we do need to check for end | |||
of sequence (0xFC) before reading the delta-time as some files do use 0xFC | |||
where the delta-time would be. | |||
=== I'm going bughunting... be vevy vevy quiet! === | |||
I wasn't planning on going bughunting but as I tried to submit | |||
my MIDI parsing/stepping-through code into SVN I found out that | |||
sound didn't work with AGI in the SVN. Possibly Fingolfin inadvertently | |||
broke it with the OOficiation/clean-up -commits to the AGI's sound code | |||
or made the bug somehow come up more easily (At least AFAIK it | |||
didn't crash like that before ;-)). Well, in the wee hours I disgruntently | |||
tried to fix the bug and at last I succeeded (Here's the [http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/engines/agi/sound.cpp?r1=28671&r2=28672&sortby=date diff] | |||
for the fix. The crash was happening because the PCjr sound mixing code tried to use uninitialized values (e.g. phase, ins) when mixSound was called before anything was playing). | |||
Come to think of it I'm not really sure how it has been able to *not* crash before :). | |||
After fixing the crashing bug I got to the point where I could commit | |||
the MIDI parsing/stepping-through code into the SVN. Whee, it's not | |||
perfect (Speed's probably off), it doesn't use the MIDI classes yet etc, | |||
but it steps through the MIDI files (That aren't totally standard) hopefully | |||
quite correctly :). | |||
== 2007-08-20 (Monday) - Juryrigged Apple IIGS MIDI output for first sound testing! == | |||
Juryrigged the Apple IIGS MIDI parsing code to fill the sound buffer with a sine wave | |||
when encountering a Note On -command in the MIDI stream (Using the Note On -command's | |||
note frequency data to adjust the sine wave's frequency too). What sounds I got :-) | |||
heh, but at least I recognized the Greensleeves -theme from King's Quest II's intro ;). | |||
Hopefully the wiki's upload file functionality will be working again in the near | |||
future so I could upload a sample of the buzzes I saved from the testings :). | |||
Later today I thought about the mixing stuff and I'm thinking it quite probable that | |||
we'll hear some real samples soon! (Not possibly the correct samples yet because | |||
the Program Change -command's parameter isn't deciphered yet so I'm not certain what | |||
instrument should go where). | |||
== 2007-08-21 (Tuesday) - Oscillator mode comparison etc == | |||
Compared the used oscillator modes in the Apple IIGS AGI games from | |||
both the instruments and samples: | |||
I found these used combinations of modes: | |||
* Both waves (A and B) in an oscillator use the same mode: | |||
** Oneshot (Used very much by samples and by a few instruments (Probably drums, I presume)) | |||
** Loop (Used quite much by samples, very much by instruments) | |||
** Loop + Halt (The only thing using this is the unique instrument that has four oscillators) | |||
** Swap (The only thing using this is the unique instrument that has four oscillators) | |||
* Waves A and B in an oscillator use different modes: | |||
** Oneshot / Loop + Halt (Used quite much by samples and by a few instruments) | |||
** Loop / Loop + Halt (The only thing using this is Police Quest I's sample 12) | |||
** Swap / Swap + Halt (The only thing using this is Gold Rush's sample 60) | |||
This means I can ignore the Sync (Amplitude Modulation) oscillator mode for now | |||
as it's not used by at least the Apple IIGS AGI games I tested. And ignoring the | |||
Swap oscillator mode isn't going to hurt much *if* the one unique instrument that | |||
has four oscillators isn't used much (I don't know how much it's used yet though, | |||
so there's still a bit of a risk). Oh, and I do presume the Gold Rush's sample 60 | |||
isn't used very widely :-) (It's a sound of a horse's hoof hitting pavement). | |||
== 2007-08-22 (Wednesday) - My birthday! == | |||
This is my birthday! Yay! Spent most of the day with my family, played with | |||
my niece (We were a bunny family and we were scared of the wolves around our | |||
house so we called the police who came and locked the wolves into prison and | |||
shot the ones that tried to run away :-)), had some coffee and cake, went | |||
to sauna and watched Zorba The Greek during the late evening. | |||
Oh and I discovered/realized that at least Apple IIGS King's Quest I's volume | |||
files are not encrypted. So I can just go and write new MIDI codes straight | |||
into the files and run the game through an emulator to try to hear what | |||
program change corresponds to what instrument. Whee :-) This is good. | |||
== 2007-08-23 (Thursday) - Investigating MIDI controller commands and instruments == | |||
Used Python to write test MIDI data into Apple IIGS King's Quest I's disk image | |||
(Straight onto the MIDI sound resource number 0 i.e. the intro song) and ran it through MESS | |||
and KEGS32. It seems you can use just about any controller on a channel and all | |||
it does is change its volume :-). So controller 0, 7, 64, whatever, they seem to | |||
be only for changing volume (Haven't done extensive testing yet, so it is possible | |||
they may act differently in some situations). | |||
Wrote some test MIDI data to see what the program changes do. They seem to change | |||
the instrument played on a channel, that's for sure, but I'm not yet sure of the | |||
mapping between the program change parameter and the instrument number. | |||
Also tried varying the velocity of note on and note off commands (Used program 36 | |||
on channel 0). It didn't do jack :). But! As the velocity information *is* there, | |||
it might be used even if Apple IIGS AGI didn't use it (There's of course the possibility | |||
that the emulators just mess it up somehow, but MESS should be quite good, eh?-)). | |||
So we might even hear more articulate versions of the songs using ScummVM if we'll | |||
use the velocity info! We shall see... | |||
== 2007-08-28 (Tuesday) - Reverse engineering the program change to instrument mapping == | |||
Been trying to reverse engineer the Apple IIGS AGI MIDI files' program change command's | |||
parameter value to instrument number mapping recently. Tried a few approaches that didn't work | |||
but came up with a way that works quite well. Here's the preliminary mapping from | |||
program numbers to instrument numbers (Instrument number 6 seems to be mostly used to | |||
mean an "undefined instrument" or a "not used instrument"): | |||
=== Preliminary MIDI program change to Apple IIGS AGI instrument mapping === | |||
Programs 0-9: | |||
* Instruments: 21, 22, 24, 25, 23, 26, 6, 6, 6, 6 | |||
Programs 10-19: | |||
* Instruments: 7, 9, 12, 8, 13, 11, 17, 10, 6, 6 | |||
Programs 20-29: | |||
* Instruments: 19, 18, 20, 14, 16, 6, 6, 6, 6, 6 | |||
Programs 30-39: | |||
* Instruments: 0, 1, 2, 4, 3, 5, 17, 2, 2, 2 | |||
** The trailing 2's are probably somehow modified so they don't sound identical | |||
Programs 40-49: | |||
* Instruments: 27, 15, 15, 27, 6, 6, 6, 6, 6, 6 | |||
I'd venture that the used instruments in different base 10 | |||
parts (First ten programs, second ten programs etc) are | |||
different instrument categories (e.g. programs 20-29 are | |||
for drums). Haven't yet tested this but it would seem logical. | |||
Oh and this preliminary mapping is for the newer Apple IIGS AGI instrument set (i.e. | |||
used by all other test subjects except Space Quest I). | |||
== 2007-08-29 (Wednesday) - Program changes comparison etc == | |||
Here's some info about the Apple IIGS AGI MIDI files' program changes: | |||
Older Apple IIGS AGI instrument set: (Space Quest I, AGI v1.002): | |||
* Used programs: [0, 1, 2, 4, 5, 10, 16, 20, 22, 32, 33, 36, 38, 39, 40] | |||
* Unused programs (Range 0-43): [3, 6, 7, 8, 9, 11, 12, 13, 14, 15, 17, 18, 19, 21, 23, 24, 25, 26, 27, 28, 29, 30, 31, 34, 35, 37, 41, 42, 43] | |||
Newer Apple IIGS AGI instrument set: (All others together, AGI v1.003+): | |||
* Used programs: [0, 1, 2, 3, 4, 5, 10, 11, 12, 13, 14, 15, 16, 20, 21, 22, 23, 24, 29, 30, 31, 32, 33, 34, 35, 36, 38, 39, 40, 41, 42, 43] | |||
* Unused programs (Range 0-43): [6, 7, 8, 9, 17, 18, 19, 25, 26, 27, 28, 37] | |||
Not using programs 6-9 and 18-19 makes sense because they use | |||
the instrument 6 that seems and sounds somewhat weird. | |||
Not using programs 25-29 would make sense for the same reason | |||
but it seems program 29 is used... by only Manhunter I's MIDI | |||
sound resources 116 and 142! So it *might* be only a fluke but | |||
not necessarily so. | |||
Programs 32 and 37-39 seem to use the same instrument but still | |||
sound different. Although program 37 seems not to be used | |||
at all there are still programs 32, 38 and 39 to look into. | |||
Maybe some additional tweaking somewhere else than in the | |||
instrument data? | |||
Programs 40 and 43 use the same samples and probably the same instrument. | |||
Same goes for programs 41 and 42. Gotta investigate them more closely too... | |||
As a sidenote program 17 seems ok but for some reason it seems not to be used | |||
at all. Maybe just not a particularly popular instrument?-) | |||
== 2007-08-30 (Thursday) - SIERRASTANDARD investigation etc == | |||
The Apple IIGS AGI uses a file named SIERRASTANDARD that holds | |||
the sample data used by the instruments. It's 65536 bytes in size, | |||
it holds 8-bit unsigned sample data and all the different samples | |||
start on 256 byte boundaries. None of the SIERRASTANDARD files I've | |||
tested have zeroes in them (A zero would mark a premature end of a sample). | |||
After some investigation (Looking at the file rawly imported into Audacity) etc | |||
here's some info on it (This info applies directly to the newer SIERRASTANDARD | |||
file used with Apple IIGS AGI v1.003+. There are some little differences in | |||
the older SIERRASTANDARD file that's used at least with Space Quest I (AGI v1.002)): | |||
=== Samples in the newer SIERRASTANDARD file === | |||
* Number of samples (Not all unique!): | |||
** 34 | |||
* Sample redundancy (May be incomplete): | |||
** Samples 18 and 30 are identical (A base drum) | |||
** Samples 21 and 31 are identical (Sounds like a drum stick hit) | |||
** Samples 24 and 32 are identical (Sounds like hihat) | |||
** Samples 27 and 33 are identical (Sounds quite like a shaman drum) | |||
* "Dummy" samples | |||
** Sample 4 is full of byte 0x50 (i.e. about -0.38 if amplitude is normalized to range [-1, +1]) | |||
* Unused samples (i.e. not used by the instrument data. May be incomplete): | |||
** None of the instruments in either the older or the newer instrument set use samples 29-33 | |||
*** This means we could theoretically ditch the last 16KiB of the SIERRASTANDARD file | |||
** None of the instruments in the older instrument set use samples 2-4 | |||
** None of the instruments in the newer instrument set use sample 4 | |||
* Sample sizes log2 (2**x will give the true sample size): | |||
** sampleSizesLog2 = [10, 10, 10, 9, 9, 10, 10, 10, 10, 10, 10, 11, 10, 10, 10, 10, 10, 10, 11, 10, 10, 11, 10, 10, 11, 10, 10, 11, 14, 13, 11, 11, 11, 11] | |||
* Sample sizes (This table can be calculated from the sample sizes log2): | |||
** sampleSizes = [1024, 1024, 1024, 512, 512, 1024, 1024, 1024, 1024, 1024, 1024, 2048, 1024, 1024, 1024, 1024, 1024, 1024, 2048, 1024, 1024, 2048, 1024, 1024, 2048, 1024, 1024, 2048, 16384, 8192, 2048, 2048, 2048, 2048] | |||
*** Way to calculate this with Python: sampleSizes = map(lambda x: 2**x, sampleSizesLog2) | |||
*** Note that sum(sampleSizes) should always be 65536 (The size of SIERRASTANDARD) | |||
* Sample positions (This table can be calculated from the sample sizes): | |||
** samplePos = [0, 1024, 2048, 3072, 3584, 4096, 5120, 6144, 7168, 8192, 9216, 10240, 12288, 13312, 14336, 15360, 16384, 17408, 18432, 20480, 21504, 22528, 24576, 25600, 26624, 28672, 29696, 30720, 32768, 49152, 57344, 59392, 61440, 63488] | |||
*** Way to calculate this with Python: samplePos = [sum(sampleSizes[:end]) for end in xrange(len(sampleSizes))] | |||
=== Differences between the older SIERRASTANDARD and the newer SIERRASTANDARD file === | |||
Here are all the differences between the older and the newer SIERRASTANDARD file: | |||
* Sample 2 (Offsets 2048-3071) differs between SIERRASTANDARD versions | |||
** Sample data | |||
*** The older version of sample 2 starts with some real sample data but a bit over half of it is completely silent (i.e. centerline i.e. byte 0x80) | |||
*** Newer version of sample 2 contains real sample data | |||
** Instrument usage | |||
*** None of the instruments of the older instrument set use sample 2 | |||
*** Instruments 19 and 20 of the newer instrument set use sample 2 | |||
* Sample 3 (Offsets 3072-3583) differs between SIERRASTANDARD versions | |||
** Sample data | |||
*** The older version of sample 3 is full of byte 0x50 | |||
*** The newer version of sample 3 contains real sample data | |||
** Instrument usage | |||
*** None of the instruments of the older instrument set use sample 3 | |||
*** Instrument 4 of the newer instrument set uses sample 3 | |||
* Sample 17 (Offsets 17408-18431) differs between SIERRASTANDARD versions | |||
** Sample data | |||
*** Both versions of SIERRASTANDARD use real sample data here | |||
*** Newer version's sample has a higher pitch than the old version and the wave looks more triangle like | |||
** Instrument usage | |||
*** Instruments 5 and 18 of the older instrument set uses this sample | |||
*** Instrument 6 of the newer instrument set uses this sample | |||
* Sample 27 (Offsets 30720-32767) differs between SIERRASTANDARD versions | |||
** Sample data | |||
*** The older version of sample 27 consists mostly of silence (Byte 0x80) followed by some 0x0F | |||
*** The newer version uses real sample data here (Identical to the last sample i.e. sample 33) | |||
** Instrument usage | |||
*** Instruments 5 and 23 of the older instrument set use this sample | |||
*** Instruments 6 and 25 of the newer instrument set use this sample | |||
== 2007-12-11 (Tuesday) - End of GSoC 2007 project diary == | |||
I thought I'd add a clarifying end note to my project diary. I'm not going to update the | |||
diary anymore but I leave it here for archival purposes. It might prove an interesting or even | |||
a useful read for someone else applying for GSoC in ScummVM. It was a good ride... |
edits