# Throbbing memories

## “Uh, what’s a throbber?”

This thing:

![A crop of a browser toolbar with its throbber](/bits/throbbing-memories/throbber.png)
A typical browser throbber

Many people don’t seem to know that word. Some are even afraid of it, thinking
it means something that may not be NSFW. But no. A throbber is a loading icon,
or loading animation. That’s it. It’s all that because it loops, it follows a
rhythm, a beat, it throbs.

As someone who likes anything retro, one strange thing I wanted to find one
morning was the original throbber from Netscape. In the heyday of Netscape, the
browser and many of its popular competitors had a large icon representing itself
in the end of the main window’s toolbar. That icon would then animate anytime a
page loaded. Connections were slow in the time, so people felt better looking at
something reassuring them the browser was working.

Internet Explorer had its “blue E” logo turn (metaphorically and literally) into
Earth, and Mosaic had some large space pipes funnelling electric pulses into a
spinning planet. For its throbber, Netscape displayed a meteor shower covering
its giant “N” logo.

I found it online, but they all looked upscaled and blurry or janky. I didn’t
like that. I wanted the original. But how?

## Finding the original Netscape throbber

Okay, I knew right away that all I had to do was basically find the original
browser’s executable, `netscape.exe`, then just extract the animation out of it
with a program to extract its resources, including images and icons.

But I hit a few bumps in the road, which I’ll go over a bit.

### Download the Netscape install discs

These aren’t hard to get.
[WinWorld has the Netscape Navigator 3.0 install discs.](https://winworldpc.com/product/netscape-navigator/30x)
Just go there.

If you’re feeling fancy, you can get Netscape Navigator **_Gold_** instead,
which comes with an HTML editor, Composer! (But for this, it’s completely
unnecessary.)

![Icons of disc volume images](/bits/throbbing-memories/images.png) The setup
discs

### Attempting to extract the files straight from the discs

TL;DR: Didn’t bother.

There are four install discs, but turns out everything you want is in the first
one, in a file called `SYSTEM.Z`. It looks like gzip, but knowing gzip isn’t
much in the Windows world, fair enough, I tried and it wasn’t that format.
Actually, it was a compression format for the popular InstallShield installation
software, which was already around in the day. I read you can get a `i6comp.exe`
executable and run in [DOSBox-X](https://dosbox-x.com) and extract the files.

But nope. That executable required Windows, and I think it was made for the
Windows of that time; don’t think it’ll run on Windows 11 today. I mean, I could
have tried in Wine while I’m still on macOS, but it sounded like more problems
than it’s worth, especially with all the OSes and VMs at my disposal. Why waste
hours to make Wine and that EXE work while I can just use those? I didn’t want
to pollute my Windows 11 setup with that old stuff either. So I took that route.

Since I’m likely to use the files on both macOS and Windows, I copied them to my
NAS, which both my computers can access.

### Installing Netscape

Turns out I already had a Windows 98 virtual machine (VM) in UTM. (You don’t?)
Probably set that up when I toyed with retro computing in
[_Retrosurfing_](https://remino.net/bits/retrosurfing/).

To save time, I copied all the contents of every installation discs into a
single CD-ROM volume image using
[_mtools_](https://www.gnu.org/software/mtools/) and macOS `hdiutil`, which I
could mount in UTM:

```sh
# Install mtools
brew install mtools

# `disk*.img` setup discs are in `Images` dir.
# Contents for CD is in `setup` dir.

for i in Images/Disk0*.img; do md setup/$( basename $i .img ); mcopy -i $i '::*' setup/$( basename $i .img ); done

hdiutil makehybrid -o setup.iso setup -iso -joliet

# Outputs `setup.iso` CD-ROM volume image.
```

<details markdown=1>
<summary>The content of the CD image should look like this:</summary>
```
Disk01/
	_INST32I.EX_
	_ISDEL.EXE
	_SETUP.DLL
	_SETUP.LIB
	DATA.1
	DISK1.ID
	INSTRSRC.DLL
	NETSCAPE.LCK
	README.TXT
	RSUTIL32.DLL
	SETUP.EXE
	SETUP.INI
	SETUP.INS
	SETUP.PKG
	SYSTEM.Z
Disk02/
	DATA.2
	DISK2.ID
	JAVA.Z
Disk03/
	DATA.3
	DISK3.ID
	PLUGINS.Z
Disk04/
	COOLTALK.Z
	DISK4.ID
```
</details>

With the CD image created, all I had to do was to use it in my Windows 98 VM,
find the `setup.exe` file in `Disk01` and run it. That started the Netscape
installation, which was straightforward. Of course, I skipped all the optional
components, like [CoolTalk](https://en.wikipedia.org/wiki/CoolTalk). I didn’t
even use that when Netscape 3 was popular, so I wasn’t about to use it now!

![Screen with setup dialogue on blue background](/bits/throbbing-memories/setup.png)
Installing Netscape…

<mark>⚠️ <strong>Watch out!</strong></mark> One thing I had to do is copy the CD
image from my NAS to my local volume. When I tried to mount the volume image
from a network share,
[UTM didn’t like it](https://github.com/utmapp/UTM/issues/5757).

### Drilling for `netscape.exe`

I didn’t have any kind of file sharing setup between that VM and macOS. Maybe
Samba shares on my NAS could have worked? I didn’t try.

Instead, I shut down the VM, and tried to convert the `qcow2` hard drive
image—which is in QEMU format, since UTM runs QEMU—of my VM into an `.img` file
I thought macOS would simply see as FAT drive, but that didn’t work:

```sh
# ⚠️ Output a file that couldn't be mounted:
qemu-img convert -f raw <uuid>.qcow2 -O raw c.img
```

Actually, funny enough, while DOSBox-X earlier couldn’t help me extract data
from that `SYSTEM.Z` file earlier, it can actually just mount that `.qcow2`
volume file directly! So, in DOSBox-X, I could make a directory to hold files I
want on my local drive, and mount the volume file, then copy the files:

```sh
# Make directory to mount in DOSBox-X to hold files:
mkdir transfer

# Start DOSBox-X
dosbox-x
```

```bat
rem In DOSBox-X

mount d transfer
mount e <uuid>.qcow2
e:
copy "E:\Program Files\Netscape\Navigator\Program\netscape.exe" d:
exit
```

### Extracting the resources

Then I moved from macOS to my Windows 11 PC.

There's that old program by NirSoft which still works,
[_ResourcesExtract_](https://www.nirsoft.net/utils/resources_extract.html), and
lets you extract icons, bitmaps, cursors, and other things out of `.exe` or
`.dll` files. I installed it using
[WinGet](https://github.com/microsoft/winget-cli):

```bat
winget install resourcesextract
```

After starting _ResourcesExtract_ and locating my `netscape.exe` file, I
extracted all the resources into a directory. That gave me dozens of `.bmp`,
`.cur`, and `.iso` files.

There it was, the original animation…

[![A sprite with all its frames.](/bits/throbbing-memories/netscape_1100.png)](netscape_1100.png)
**`netscape_1100.bmp`**, the original sprite.

## Animating the sprite

If you do any web design, or any game design, for that matter, you are certainly
familiar with sprites: taking all the frames and putting them in a single image
side by side. Then when it comes time to animate the image, you just shift it to
the next frame.

Interestingly enough, while
[CSS has evolved to let us easily do sprite images](https://codepen.io/remino/pen/abggJey),
it was impossible to do in the time of Netscape 3, unlike how they did it
natively in their app. But I digress…

Okay, so what did I have? An image of 48 pixels high and 1,968 pixels wide.
Using Preview on macOS to measure a single frame, it looks like they are each
square. Thus, 1968 ÷ 48 pixels = 41 frames. The first frame looked like it is
the one shown by default when Navigator is idle, so I discarded it.

### Converting bitmap files (`.bmp`)

Sounds easy. Just need ImageMagick:

```
$ convert netscape_1100.bmp netscape_1100.png
convert: improper image header `netscape_1100.bmp' @ error/bmp.c/ReadBMPImage/711.
```

Oh…

Not sure why but those bitmaps are too old for ImageMagick.

Fortunately, FFMpeg has no problem with it:

```sh
ffmpeg -i netscape_1100.bmp netscape_1100.png
```

### Checking output PNG file

I wanted to be sure I got the exact colour for every pixel in the PNG file. For
that, I used Python to compare the two images and output a diff:

```python3
#!/usr/bin/env python


from PIL import Image, ImageChops

def image_diff(img1_path, img2_path, output_path):
    img1 = Image.open(img1_path)
    img2 = Image.open(img2_path)

    diff = ImageChops.difference(img1, img2)
    diff.save(output_path)

# Example usage
image_diff('netscape_1100.bmp', 'netscape_1100.png', 'diff_output.bmp')
```

Running the script above gave me a `diff_output.bmp` file which was all black,
meaning the colour of every pixel was the same.

### Slicing up the frames

That's pretty easy with ImageMagick:

```sh
magick netscape_1100.png -crop 48x48 +repage frame_%d.png
```

There. That gave me all the 41 frames from the sprite image.

### Stacking up every frame into an animated GIF

That one is easy with ImageMagick too:

```sh
# Skipping frame 0 used when the browser is idle:
magick -delay 14 -loop 0 frame_{1..40}.png -coalesce -dither None netscape.gif
```

That did the trick. The final touch was to optimize its size, using my favourite
Ruby gem for the job, [_image_optim_](https://github.com/toy/image_optim). That
one uses [Gifsicle](http://www.lcdf.org/gifsicle/) to make GIF files as small as
possible:

```sh
image_optim netscape.gif
```

## The Result!

[![A throbber of a meteor shower covering a giant N logo](/bits/throbbing-memories/netscape.gif)](netscape.gif)
The Netscape Throbber. Nice! {.throbber}

Okay, so I have that thing now. Why did I go get it and what will I do with it?

I dunno.

And yeah I know it was kind of a waste of time. (Yet, maybe it was good practice
with ImageMagick.)

Maybe I'll write more articles about messing around when I was in high school
again on [OMEGALOGIC](https://omegalogic.neocities.org/)? Maybe I'll make some
animations with the resources I extracted? Who knows… I can't even tell. But if
I do anything with those, I'll be sure to let you know here.

As I look at the animation closely, I wonder… Who made this animation? How was
it rendered? It looks like some early CG, and the dithering looks like it was
converted from a video. Who knows…

Btw, feel free to [download the resources](/bits/throbbing-memories/netscape.7z)
I extracted. I already converted the `.bmp` files into `.png` to save space.
Have fun with them!
