Show HN: WinGPT – AI assistant for Windows 3.1 (dialup.net)
Hey HN, I didn't want my Gateway 4DX2-66 from 1993 to be left out of the AI revolution, so I built an AI Assistant for Windows 3.1, based on the OpenAI API.
The most interesting parts of building this were:
- Getting TLS 1.2 and 1.3 working on Windows 3.1 so that WinGPT could directly connect to OpenAI's server without relying on a modern machine for TLS termination.
- Learning about the memory segmentation architecture on 16-bit Windows, including the difference between far and near pointers.
- Building the UI in plain C code with the Windows API and limited selection of controls in Windows 3.1.
You can check it out here and learn more about what it was like to build it: https://www.dialup.net/wingpt/
91 comments
[ 3.0 ms ] story [ 145 ms ] threadYou are a friendly but concise chat bot. Answer all questions in the present tense as if it is 1992, and make no reference to the current year.
Prompt : I want to use ChatGPT as if it was the 1990s and ChatGPT existed (in its current form) in the 1990s. I talk to you normally and you answer normally as ChatGPT (no mention of this 1990s setup or the timeframe in reference to now). The only difference is you pretend its the 1990s and answer accordingly. Stay in character, you play yourself. I need you to pretend it's the 1990s but otherwise behave as ChatGPT normally would. Never mention anything past the 1990s or that would indicate we are not in the 1990s. Do not mention this conversation (it's a pre-prompt). Let's go. First question : which internet browser do you recommend ?
Answer: There are several good browsers available currently. For instance, Netscape Navigator has been very popular due to its user-friendly interface and robust features. It's currently one of the most widely used browsers.
However, Microsoft has also introduced Internet Explorer, which is integrated with their Windows operating system. This might be more convenient if you're already using a Windows platform.
There's also Mosaic, developed by the National Center for Supercomputing Applications (NCSA), which pioneered many of the user interface elements we see in modern browsers.
All these browsers have their pros and cons, so it ultimately depends on your personal needs and preferences.
Q : Who are the top paid actors this decade? A : During the 1990s, some of the highest-grossing actors have been:
Tom Cruise - He's been in a string of successful films including the "Mission: Impossible" franchise which started in 1996.
Harrison Ford - Known for his roles in iconic franchises like "Indiana Jones" and "Star Wars", Ford has continued his successful streak into this decade.
Jim Carrey - With his unique brand of physical comedy, Carrey has starred in a number of high-grossing comedies including "Ace Ventura: Pet Detective", "The Mask", and "Liar Liar".
Arnold Schwarzenegger - He's enjoyed continued success in the '90s, particularly with the "Terminator" series.
Mel Gibson - After the success of "Lethal Weapon" series, Gibson has maintained his status as one of Hollywood's top earners, directing and starring in "Braveheart" in the mid '90s.
Remember that these rankings can vary year by year based on the number of films released, their box office performance, and the actors' negotiated salaries.
It is great to see Windows 3.1 software again.
I am just going to leave this here, strictly for the retro enthusiasts: https://www.xfce-look.org/p/1016410
IIRC it ships with Windows 2000, but works on Windows 95 too.
That's in a separate page here: https://www.dialup.net/wingpt/tls.html
...and is well worth reading. I'm surprised you had trouble getting a TLS implementation to fit in 64k of code and data, since a lot of deeply-embedded stuff (some even using 8-bit CPUs with bankswitching) for IoT and similar applications support TLS 1.2.
It's a sad day when slightly older operating systems have trouble accessing the internet.
ouch
I remember being told that modern cryptography isn't usable on old CPUs simply because of the amount of unoptimizable number crunching involved. As in, some steps of the key exchange algorithm would take so long that the server would time out. But apparently that's not a problem for a 386 despite being old and slow?
Now...this is obviously for sending small amounts of data at low (very) bit rates 'securely', not modern web or streaming or anything fun like that. And my understanding is that the real killer in trying to do something like TLS on such small platforms is the key generation/exchange/management part. YMMV.
You can trade space for CPU time using SAX-style parsing[1]. SAX-style parsing visits each node of a tree from top to bottom, firing events for each node visited. The amount of memory required compared to fully parsing JSON is negligible, and writing a custom SAX-style parser for JSON shouldn't be too difficult. There are existing SAX-style JSON parsers you can examine as well.[2]
[1]: https://en.wikipedia.org/wiki/Simple_API_for_XML [2]: https://rapidjson.org/md_doc_sax.html
Goes to show that we waste literal orders of magnitudes of memory for small gains in developer productivity. Is programming raw Windows controls hard? Sure. But Delphi or VB on Win95 was arguably (much) more productive than modern day UI toolkits, and the resulting apps consumed a fraction of the resources. The main thing they lacked was mobile support and DPI awareness!
A few years back I was building a B2B website for companies to manage event listings[1], fully modern React stack.
I wanted to get the backend API up and running first so I threw together a prototype in WinForms and C#. I had been writing React all day every day for a couple years at that point, and I hadn't used C# or WinForms for quite a few years (3 or 4 at least).
Also none of the GCP APIs I was using had official C# WinForms libraries (hah!) but of course everything had nice React integrations.
So anyway, within a day and a half or so I have a C# desktop app up and running that has about 80% of the site's planned functionality implemented. It is ugly, but it works.
Over 3 months later I have the React site up and running.
The React site supported Mobile and Desktop browsers, and it looked nicer, but the productivity to create the React site was literal orders of magnitude less.
FWIW I had a similar experience going from React to Svelte, I got done in 3 days what would have taken me weeks in React.
(For those paying attention, Svelte was still slower than C#!)
Part of the difference is that we expect web apps to be all shiny and work at any screen size with fancy CSS, vs a desktop app which can just do its thing.
The other part is that, IMHO, HTML+CSS are crap for laying out application UIs. Better than what they used to be, but still absurdly complicated.
[1] Create their business profile, list and manage events on a timeline/calendar, view attendees, send announcements to attendees, real time view of people as they show up to the event by hooking into Geo-locating on the phone, manage photos, and so on and so forth.
Not just absurdly complicated, but also absurdly inconsistent. If you write an app in JS+HTML+CSS and use Electron to deploy it, the UI could literally be anything, as can the controls, etc. Nothing matches the OS UI neither, and standards have gone out of the window :(
This may be seen by some people as an advantage though. For example my work computer is a Mac and my personal laptop runs Windows & Linux and I specifically like when application's UX is consistent across the different operating systems...
I think this is an underestimation, to be honest. What I struggled with native code to be able to do when I was younger is now stuff that literally anyone can do using any number of off the shelf libraries and tools targeting web browsers. This is an amazing achievement and not a bad thing in and of itself; if anything, what I lament the most is that the browser is killing native apps by being a "better" overall option.
Most software companies nowadays take it for granted that they need to ship some kind of web access to their network service, so that's the first thing they work on. Next they probably want to support iPhone and Windows, and probably Android, macOS, maybe even Linux... There are some options that cover each of these platforms to some degree, but by this point they probably already have at least a proof of concept in a web browser, and with a single NPM install, they can have that show up in a separate window, ready to ship with an installer and deployment system (not a great one mind you, but still.)
This wouldn't be as much of a problem if there were good, production-quality, efficient native code GUI frameworks that could efficiently target the DOM and native UIs across Windows, macOS, Android and iPhone, have first-class support for native text input with IME and platform-native semantics as well as accessibility support with screen reader integration, deal with responsive UI changes when dealing with different scree sizes, and have robust but performant DPI-independent visuals that handle fractional scale correctly. (Easy stuff, right?)
But there's not. And although I love Delphi VCL, or even just raw Win32, it's just not most of that either. Supporting all of these platforms is very hard. Browsers do a very good job and are often some of the best sources of example code for writing deep platform-specific code you can find. And best of all, since you're targeting web anyway most of the time, and browser engines are "native code", it's a hell of a lot easier to just ship the browser or at least JS engine to platforms that already run native code than it is to try to create an isomorphic native code solution that can also run in a browser environment.
I think that things will get better, eventually. But, they'll probably get worse before they get better.
Problem is, iteration speed mattered more to people than almost anything else including raw productivity. The world changed faster than Delphi did. Borland could have recognized the trend of hacking browsers into making apps was representing some fundamentally unarticulated need and come up with e.g. an Object Pascal interpreter. They could have done some sort of "Delphi Browser", for instance, and it would have gained adoption, but their codebase was fundamentally oriented around producing native Windows apps so it would have been difficult to make that move. Plus, Borland were basically guests on the Windows platform and tended to follow Microsoft's lead. Microsoft were pushing ActiveX as the way to bridge the web and the Windows world; Borland realized too late that ActiveX wasn't going to meet people's needs. They saw the web first as not a competitor, and then later as a mere carrier for Delphi apps, and then later still pushed using Delphi for writing web servers but its strengths didn't apply there.
So the lessons I took away from this were really about unarticulated preferences that you have to learn about by watching what people do, not what they say, and also the overwhelming importance of deployment - still a blind spot for most web competitors today. Up until last year if you wanted to use a Delphi-like platform with web-like deployment where apps are always refreshed on launch there just wasn't much out there. Even Electron only offers fully asynchronous desktop-style updates. I have a little company that makes products for fixing deployment of desktop apps (within the constraints of the native platforms), which adds a web-like deployment mode called aggressive updates (https://hydraulic.dev/). With that an update check is done on every launch, so you can iterate very fast as long as your users restart the app from the time to time or of course you can force it when the time is right, no different to requiring users to close and reload tabs for a SPA.
Anyway, I disagree that the main thing they lacked was mobile + DPI. Delphi, VB, GTK, Cocoa etc had lost the desktop before smartphones mattered at all because they lacked a good deployment and update system, and the ability to push out fixes and changes instantly mattered more than all the other features combined.
It mattered for developers. Users couldn’t care less.
While I do agree that back in the day, we missed standardized update systems, we do have them now (Flatpack, Winget, the stores …) and they could have appeared sooner if the industry did not plunge entirely in this web thing.
Sure the old days were not perfect but we are now in such an extreme opposite that your computer doesn’t even compute anything except a browser engine.
I think users do appreciate fast iteration. If they report a bug in the morning and it's fixed by the afternoon, that feels very different to reporting a bug and being told it'll get fixed in the next version which ships in 2 months. Even very basic and subtle differences between web and non-web apps matter here, for example, the lack of version numbers, the precise control over caching policy, the refresh button all make big differences to the overall feel of things.
Here is the answer of ChatGPT4 when asked the same question about the status bar (I truncated the code output because it's very long):
Using the Shell Common Controls in Windows 3.1 can be a bit tricky due to its older architecture and limited capabilities, but it's certainly doable.
However, there are a few complications to note:
1. Windows 3.1 does not natively support the status bar as a control. Status bars are part of the Common Controls library introduced in Win32, specifically, it was introduced in Windows 95 with COMCTL32.DLL. Windows 3.1 is a 16-bit environment and does not include this library.
2. If you want a status bar in a Windows 3.1 application, you'll have to draw and manage it yourself.
3. Windows 3.1 programming is largely obsolete. It can be a fun academic exercise or a necessity for maintaining legacy software, but if you're developing new software it would be much more practical to use a more modern version of Windows and its associated API.
Assuming that you still want to go ahead, here's a basic idea of how you might implement a status bar yourself:
http://www.calmira.net/source/index.htm
Now half of my UIs have "Tap to...." labels when localized. So many amazing modern UI tools and the rockstar developers wielding them can't even make a draggable sidebar.
I do, however have considerably more time for script kiddies.
Even resizing regular windows was not always an option, and if it was, it was very rarely thought through by the developers. I vividly remember that the Swing framework for Java was very special just because of this, as in you couldn't really specify it in pixels where your components would be placed, you'd have all sorts of strategies to divide and position them. (Not saying it was any good, but certainly a notable effort.)
Not only that, but window resizing was something that had to be implemented for each window, so lots of applications had unresizeable dialogs and only the "document" area was resizeable.
Even worse, the use of pixel positioning meant that nothing was scaleable. High-DPI display? Choose (a) not being able to read anything or (b) bad linear rescale by a limited number of scales.
I too am a fan of the simplicity and clarity of the old Windows UI, and Microsoft haven't really managed to improve on it, but let's not pretend it doesn't have serious limitations.
Yes, I remember modals not being resizable, I was there. That was not the point.
A suggestion (which seems easy enough to implement, I might give it a try if I can get the build environment set up): make the system prompt customizable in the Options dialog. Having it be 1992 is fun, but kinda limiting. I might actually use this at some point -- if you're on your retro computer, trying to solve a problem, it might actually make some semblance of sense to use this rather than dig out a modern computer or smartphone.
Remembrance unlocked! There are really near (offset only) and far (segment + offset) pointers in x86 16 bit architecture. Also near and far jumps. Gods, how long ago was that...
The built in network stack and applications in Windows 3.11 is limited to file, print sharing and maybe sending some popup messages.
Apps I use daily: totalcmd, clipx, far, sublime text ( only for edit text, code with intellij )