-
Notifications
You must be signed in to change notification settings - Fork 117
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ELKS Image Viewer #2205
Comments
Very cool!! Can you post some screenshots on your repo? |
I read through all your ELKS Viewer source - that's some fantastic graphics programming you've done, very impressive!! Everything is nicely done, very easy to read and understand. Nice work on all the palette functions! I'm seeing now how you could possibly get the whole project ported over from OWC to ELKS C86, by just rewriting/renaming graphics.c using C86 asm statements in C, in particular plot_pixel which is very close to write_vid, which we've already got written in C86 ASM. I think that plan should work well, as long as you can keep all But first just getting graphics.c ported to C86; looks pretty straightforward, except possible for I also notice in your not-used-yet dither.c there's some functionality to write a 4-bit VGA color value in planar mode ( Anyways, very nice stuff, thanks for posting it! |
Yay! Thanks for the kind words. I'll do just last default palette adjustments and then add mode 12 (16-color 640x480 mode). The code is pretty portable, and after tests with dosbox-x with 8086 emulation (including 4.77 MHz clock), I can say the tools have pretty good speed. Of course lots of basic things are missing, like scaling (full-screen mode), centering, zoom, etc. But with time we get there. And yes - lets port to C86, I agree, that would be cool, I'll be able develop on ELKS (on my thinkpad T430) for ELKS. When I look at demoscene 8086 samples (usually for DOS, but that could be easily portable to ELKS), a book8088 can be an arts machine! |
I've been looking at Nano-X and have found a very old 640x480 mode 12 driver I'd written decades ago - in MASM source nonetheless! Give me a few days and I'll port that over to OWC and C86 and add it to examples/vgatest.c. You can then use that as the basis for your higher-resolution graphics. The code will also support 640x350 EGA mode. |
That's very impressive, better graphics than I had imagined. I guess the difference between the BMP and JPG are that the BMP was created from an original with a custom palette, while the JPG is decoded then displayed into a standard palette? BTW, I have the VGA 640x480 16-color (mode 12h) draw functions completed and working for C86. They're written in AS86 assembly language and should be very fast. I'll be posting a PR on 8086-toolchain with vgatest.c used to call it. The routines in draw pixel, draw horizontal line, draw vertical line, draw filled rectangle and read pixel. |
Indeed, the 8-bit bmp was created from an original 24-bit image with ImageMagick, which chose an optimized palette, and no conversion is done (by bmpview), while the colored JPG is using the fast 24-RGB to 8-bit with a standard palette conversion.
Thanks! |
I got a bit confused here in the 4-bit routine drawpixel:
It is a assumed here the standard 4-bit palette is being used, right? How does exactly this bit mask work? I'm too used to planar modes I suspect. ps: and I need to keep supporting OW compiler (for jpg), but I also need to keep in place all support for "paletted" operation for 4-bit and 8-bit too, as this is needed for fast operation of bmpviewer. I already ported the palette manipulation funtions to C86 - all good. |
When trying to compile bmpview with C86:
Compiler is exploding, may be on casts. We need to investigate. "graphics.c" compiles, but with warnings:
|
No - the vga-4bp.s is not a linear mode nor a palette mode, is using the hard-to-understand 4-plane VGA mode, which requires fiddling with various VGA registers then writing into each of the VGA planes. The "color" in this case is a 4-bit color (0-15), which correspond to the standard 0-15 colors in CGA 16-color palette modes though. That may be what your question was?
I plan on supporting OWC as well, but haven't had time to convert this new C86 AS86 routine to WASM format and also accept input via registers, instead of on the stack. Of course, a pragma aux could be used to cause OWC to push the parameters on the stack before calling, which might be the best first approach. Supporting three assemblers is a pain in the butt. I will get back to this but am knee deep trying to get Nano-X working with a window manager and other issues.
So it seems that what you're requesting is a 4-bit palette mode, an 8-bit palette mode, and then in addition the higher resolution 4-bit planar mode, all for VGA? This gets complicated in a hurry for the 4-bit palette and planar modes, depending on how you want to keep the source images in memory (or whether they're not in memory, but created on the fly directly to the display). We can talk in depth about that if you tell me how you plan on manipulating the images. The C86 graphics.c functions don't support any memory-image containers or fast blit image output. Instead, they just draw pixels directly to the screen, a very slow and ancient method of doing things. Of course, on ancient hardware, sometimes it's too slow to decode into memory and then copy that (possibly with conversion) to a display. In the newer Microwindows, everything got complicated quickly in this regard and a design choice was made to keep all pixmaps (internal images) in a "normalized" format, which was usually 32bpp ARGB. Then, a large host of conversion blitters (fast output routines) were written that would convert ARGB to 565, 555, 332, palette, planar-4, etc. This allowed all the image converters to be vastly simplified. More on that also if you're interested.
Nice! |
Sounds like you've run into yet another C86 compiler bug. It would probably be worth it to follow the BYU advice here, at least for the time being: don't use casts and break down complex expressions into simpler expressions, even if a temp variable needs to be used. Try that route. If you find a single statement (preferably without casts) that breaks C86, post it and I can add that to my list of C86 things to investigate. Good luck! |
Found many issues in C86, and workarounded at least in ppmview to check if the graphics function were working - and yes! It worked! But the speed is slower than with OW. I have a feeling I'll do a last port to ia16-gcc to compare speed. I opened some issues in 8086-toolchain with the errors I noticed. I'm with fingers crossed for a Nano-X window manager! I'm always taking a look on it, it is very cool, I want to use it more. btw, right now elks-viewer always write directly to screen, no tool buffers the whole encoded or decoded image on memory (apart of video memory, already in the appropriate format). |
That's definitely the way to do things on limited RAM machines; I've been thinking a lot about this during the recent Nano-X port. Keep RAM-based bitmaps (pixmaps) not only uses up tons of memory which we don't have, but there's no easy way to quickly display them when running in VGA 4-plane mode, since a fast REP MOVSB or memcpy won't work. The newer Nano-X has lots of support for buffered windows and offscreen pixmaps, but the cost of conversion between RGB and planar is very high for our slow 8086 targets! I'm going to take a pass at optionally disabling these features in order to keep the code size down - we're currently at 55k code size in the Nano-X server - almost out of space. |
ELKS Viewer ppmview and bmpview are able to be compiled - after porting using your routines - with C86! Nano-X! Soon I'll start playing with it, after finishing the viewer. Would the large model be a good candidate for Nano-X server? |
Are you thinking of porting Nano-X to OWC? I would say there's not much reason to do that, as it was recently discovered that our ancient ELKS version can't support the window manager without heavy refactoring, and I just got the main Microwindows repo version runnable on ELKS. Nano-X isn't malloc-heavy, so small pointers are fine; we are almost out of the first 64k code segment, but ia16-elf-gcc supports an additional far text segment in medium model, so there's not much point in porting to another compiler, especially since there's a number of other problems to fix in the short term. If you want to start getting involved with Nano-X, I would suggest looking briefly at the client-side demos in nanox/demos/*.c, they're quite old, but give an example of how a client process opens the connection with GrOpen, then proceeds to make graphics calls with GrNewWindow, GrText, etc. Its designed so that clients can be linked with the server for a standalone graphics program, but the resulting size will always be way larger than the stuff we're doing with the VGA library. In general, for fast operation, a Nano-X client doesn't usually deal with graphical bits on the client side, but instead just sends "high level instructions" over to the server for drawing. This doesn't have to be the case, but otherwise all the graphics pixel data would have to be sent over a UNIX socket, which is very slow. This also implies that the image loading and decoding routines should reside on the server. There's still lots of room for improvement on that end, but currently for debugging purposes all that's turned off for the time being. We can discuss more as you become a bit more familiar with it and understand what you'd like to use Nano-X for or what you'd like to add to it. |
I suppose that sounds about right, given that C86 does very little optimization. My inspection of C86 code produced shows that each and every C statement "starts from scratch" literally re-loading any registers from their stack holding places, without regard for registers already having a usable value. Unless a tight loop is being performed, this may not matter much, depending on the real need for speed. To be fair in comparison with C86 though you'd probably want to use small mode OWC, right? |
I'll try now with small model on OWC. |
I finally managed to understand (to some extent) and port the 4-bit code to OW. Indeed... not easy to understand the VGA operation! |
Now with modes 0x10, 0x12 and 0x13 supported, may be I can also choose a CGA mode, so we cover virtually all supported ELKS graphics configuration? I can see the options are modes 0x4, 0x5 and 0x6. May be mode 0x5? I plan to use function pointers, as you suggested, in order to keep the code clean with all different compilers, modes and color space conversions. ps: I found this code for CGA (and Hercules!) which seems ok for the needs of the image viewer: https://github.com/cyningstan/cgalib/blob/master/src/screen.c , it compiles with OpenWatcom already, and could also enable first class monochrome support too. |
You can say that again! I'm still struggling with "one last" Nano-X drawing bug and the NX drivers use two different VGA write modes, definitely hard to keep it all straight.
Nano-X is using mode 6 (640x480 2-color monochrome), but frankly it's pretty ugly, unless I suppose you're actually on a B&W screen (does anybody even have or use those anymore?) This choice was probably made because running Nano-X on 320x200 (4-color mode 4 or 4-greyscale mode 5) doesn't really cut it for a windowing system. I would say that for images it would be better to support 320x200 4-color mode 4. But frankly, its also hardly worth it. For those tinkerers that might actually want to see something graphical on their CGA, we have Nano-X, but I doubt anyone actually uses that either.
Cool! It would be nice to try to keep application source code clean by using a single unchanging function call name, like fill_rect or draw_pixel for instance, that automatically binds with a set of function pointers possibly using a macro, or something trickier keeping compiler or display differences in a single struct, all with the same name. Nothing would have to be initialized with separate calls nor using tons of . or -> member access stuff in the applications graphics source, and the linker would essentially bind the function pointers to their appropriate routines at link time, providing fast access using a single function pointer and no other indirections. |
After some days of struggling I managed to get the 4-bit mode working with optimized palette for grayscale or embedded image palette. I think I'll stop adding support for new modes for modes, at least for now. Still some bugs here and there, but things are starting to settle down.
Nice to know. I'm eager to see the Nano-X window manager.
Agreed. I'll leave CGA support for later if there is interest.
Indeed, that is the plan. For draw_pixel and palette conversion functions. |
@ghaerr, I noticed you updated recently the vga 4bp code in nano-x. Should I bring it to elks-viewer, or the optimization is irrelevant for such usage? |
No, the optimizations in Nano-X were in the VGA-to-VGA blit code, which is used for scrolling the VGA RAM. Also, the toolchain VGA graphics code is written in AS86 assembly while the Nano-X driver is written completely in C. |
Today I released the first version of ELKS Viewer, version 0.1!:
https://github.com/rafael2k/elks-viewer/releases/tag/0.1
ELKS Viewer is composed by standalone viewers:
Only mode VGA 0x13 (320x200 256 colors) is supported for now.
The text was updated successfully, but these errors were encountered: