Have spent a bit of time working on ConsoleWrapper today:
- Fixed a major memory leak that was causing memory usage to climb indefinitely, until it caused ConsoleWrapper to crash. This was obviously a Bad Thing™. Memory usage now sits at a comfortable ~24MB on startup, and doesn’t increase significantly with use.
- Added a new built-in command (i.e. that doesn’t utilise CMD) for viewing images inline within ConsoleWrapper. Usage is VIEW IMAGENAME, where IMAGENAME is a valid image path. If the image is too large, it will automatically be resized to be visible within ConsoleWrapper. Here’s a screenshot with a couple of images displaying inline. Screenshot taken during animating from the top of the stream to the bottom, which is the cause of the funny-looking angle, and edge jaggies:
Click through to see full size. As an aside, looking at that less-than-savoury edge antialiasing, I’m kind of tempted to implement some AA. An easier way would be to just put a black border into the texture though. Maybe something for next update.
Also evident in this screenshot, is the new feature whereby strings are rendered as individual letters, each letter being a sprite. Unfortunately, this means kerning is lost, and the string renders with significant whitespace between each character. This is something I am working to fix, but seems to be related to .NET’s Graphics library overestimating font sizes when performing a MeasureString operation.
Using sprites has also seemed to result in sub-par performance (i.e. lower performance than the old method of using pre-rendered full string textures), and I’m not entirely sure why – it was meant to increase performance, if anything. This is especially noticeable when rendering large swathes of text, such as from a DIR command on a large directory. Definitely something else to work on improving and optimising.
Note that I haven’t put out a compiled release of this yet, but the latest source is available as always on SourceForge.
Update 27th April: Here is a video showing the latest changes (including a fix to kerning problems):
ConsoleWrapper has had another large overhaul over the last few weeks.
- The primary focus of the release has been creating an internal shell which will serve as a base for growing and improving ConsoleWrapper in the future. This internal shell supports a number of simple commands (with more to come!), and passes on anything it doesn’t understand to CMD.EXE.
- For now the only internally understood commands are EXIT and CD. This will likely expand in future (more about that below) – but for now even these two commands say a lot about the improved state of the shell. Firstly, because the internal shell (and not CMD) is watching for an EXIT command, we can run and exit a number of CMDs from within one instance of the internal shell. Secondly, the fact that we have CD represented internally hints at a very important improvement; the current directory is stored and managed by ConsoleWrapper! (And not CMD). This is important, for the following reasons:
- Directory state can be preserved across different instances of CMD (e.g. when Ctrl+C is pressed – ConsoleWrapper simply tells any new CMD it launches, what the current directory is).
- This will form the basis for tab completion. As I have been unable to pass TAB keystrokes to CMD, this has to be done internally by ConsoleWrapper – and knowing/changing the current directory is key to this.
- As hinted above, having an internal shell will allow for more complex features than simple tab completion. The shell already has the (currently not utilised) ability to store and track multiple running processes built right in. This will form the basis for a screen-esque capability (if you’ve ever used a Linux shell) – however ConsoleWrapper has the distinct advantage of being a 3D environment, potentially allowing for some clever transitions and ways of visualising multiple active consoles.
- Known limitations of this release include:
- STILL no TAB completion! It’s coming soon, I promise!
- The shell doesn’t recognise commands such as “e:” to change drives. Use “cd e:” instead. Note that if, for example, you’re browsing a folder in C:, you can use CD to jump straight to a folder in another drive, e.g. “cd e:\test”. Incidentally, you can’t use cd in that way with the standard Windows shell! You have to do it in two parts – “e:”, “cd \test”. The Windows shell tracks the “active” directory for each drive instead, and won’t change drives unless you explicitly tell it to with a command such as “e:”. Play round with it. I’m not sure which is better.
- Here are two things I want to add very soon. Neither of them are particularly straightforward though, so I’ll see how I get on…
- TAB completion!!!
- I want to completely rework the graphics pipeline so that it uses letter sprites instead of rendering strings on the fly. This will be important as more gets added into ConsoleWrapper (in terms of multiple consoles etc), and should stop the video stuttering seen when large swathes are text are generated. (Try running DIR on a large directory, for example. Then try resetting the device – resizing the window will do it – then hitting Ctrl+Home to scroll over the text you just created).
I took the time today to make a few small changes to ConsoleWrapper which should improve usability and stability, namely:
- A simple caret to show cursor position and improve text editing capability – as well as the ability to use the expected left/right, home/end, and backspace/delete keys. Note that it currently displays as a | character inserted into the text, so it will push characters to the right of it across by one position. It didn’t seem too distracting in my testing however.
- Improved stability when re-acquiring the graphics device. This should prevent crashes when another application temporarily takes full-screen possession of the device.
- Added very basic Ctrl+C support. I still cannot pass keystrokes to my internal CMD process, and so I cannot yet provide true interrupt functionality. Ctrl+C will simply kill the current console and spawn a new one. This has the unsatisfactory behaviour of spewing a new set of startup text, and the current directory is also lost. This is a very temporary solution to a common request. Hopefully a more satisfactory solution can be found soon.
One of the ways Console Wrapper is currently lacking, is that it doesn’t have a full set of features that one would expect from a regular console. Some are being built in (such as command history), but TAB completion, Ctrl-C process kill etc are still missing. These could be solved (in theory) by directly passing advanced keystrokes through to the console process.
ConsoleWrapper currently communicates with the console process via input and output streams. These allow for sending and receiving of string data, but not specific keystrokes (such as Ctrl-C). Unfortunately I’m still working on exactly how I can pass a key to the console. Because it doesn’t run in its own window (in order to capture input/output streams and hide the real console from the user) normal WinAPI methods for sending keystrokes do not work, as they target a window handle. In fact the regular console may not even have a message queue. So for now I’m stuck experimenting with SendMessage and WM_KEYDOWN, WM_KEYUP, etc. Not a nice clean .NET solution as I would have liked!
ConsoleWrapper is, in short, a Direct3D wrapper for a standard Windows console.
Output from any console application (usually cmd.exe) is redirected through ConsoleWrapper, slapped onto 3D geometry, and animated. Currently, animation is basically smooth scrolling with a small amount of perspective, but potential is almost limitless.
Picture running multiple terminals at once, flipping through them like pages on a book, with full transparency, reflection, and physics effects. Lines drop into view, and discarded applications quietly fade away. These are just some of the possible concepts which can be achieved using a 3D environment such as ConsoleWrapper.