ghaerr / elks

Embeddable Linux Kernel Subset - Linux for 8086
Other
1k stars 108 forks source link

Games development on ELKS #871

Open toncho11 opened 3 years ago

toncho11 commented 3 years ago

Let's take this example of Snake compiled by Turbo C:

https://github.com/ashmew2/snake-game/blob/master/Final.cpp

@ghaerr Maybe graphics.h can be mapped to Nano-X? But on 8086 computers Naxo-X looks slow for games. For example

pawosm-arm commented 3 years ago

The topic of porting graphic libraries and 90's games to ELKS should be preceded by a more substantial discussion regarding the graphics in ELKS in general. I never had occasion to work with nx before meeting ELKS (my past experience with NuttX from which nx originated never went beyond the nsh command line sessions), so I can't really say how good or bad this library is. I just have impression that I already saw things more mature than nx, like Photon on QNX or DirectFB on Linux. Even things like GUILib for multiplatform SDL library seemed more mature despite all of its limitations. And there is also John Elliott's SdSDL library for SDL which emulates GSX and VDI graphics that originates from CP/M and DOS (before MS Windows). And that was the direction I was looking for: John Elliot's fork of GSX/VDI-based GEM (the mighty FreeGEM) works really lovely on both of my XT machines (one 8088, one 8086 based), far better than nx on ELKS on the same machines, though I suspect the secret is in the underlying OS: there's no multitasking in DOS, hence GEM can consume all of the CPU time for handling mouse-driven graphics operations. Yet anyway, it only shows that doing GUI on XT is possible and the user experience does not need to suffer. BTW, Windows 3.0 was the last version of MS Windows that could be installed on 8086 and it offered some kind of multitasking, still being capable of providing good enough user experience.

One more thing I remember from the past. My very first Linux back in the 90s (some very early version of RedHat) was installed on some very low end i386 machine equipped with ISA 8-bit VGA graphics card (probably the same I've installed during ELKS times into my Turbo XT to replace Hercules mono graphics card that was installed into it originally). Running X at 640x480x16 offered terrible user experience and 16-color palette looked awful. Yet I managed to force X server to run with 320x200x256 mode and it really started to fly! The user experience was amazing. I guess two factors were playing their role here: lower resolution and a whole byte per pixel which simplified all of the graphic operations. I think it's one of the possible directions nx on ELKS could also explore. In the end, those demos don't really display much of the content on screen. See how GEOS looks like on C64, it's low resolution and it's still really cool (speaking of GEOS, it was ported to 8086 XT's too, yet to my disappointment its final XT-compatible version was working much slower than FreeGEM).

tkchia commented 3 years ago

Hello @toncho11, hello @pawosm-arm,

Well, the graphics stuff aside --- I think @ghaerr can comment further on that --- it is obvious that porting Turbo C++ specific code to, well, anything that is not Turbo C++, is going to take some effort. I do not see this as a bug per se: there is no real urgent need for ELKS to be compatible with a non-standard programming interface (even if it will be a "nice thing to have").

pawosm-arm commented 3 years ago

I remember the times when porting from Turbo C++ was all about getting rid of '#include ' :)

tkchia commented 3 years ago

Hello @toncho11 , hello @pawosm-arm,

I remember the times when porting from Turbo C++ was all about getting rid of '#include ' :)

Well, I guess there are different ways of doing the porting task. :-|

In case you missed it: on the MS-DOS front, I have been working on a libi86 project. It aims to implement, for gcc-ia16, non-standard C library extensions that are present in the Open Watcom C runtime and (to some degree) the Turbo C++ runtime.

I am currently keeping this library separate from the underlying C library (newlib-ia16) that implements the core C99 and POSIX functionality.

(<conio.h> support is mostly complete (for MS-DOS, that is). As for graphics, both Open Watcom and Turbo C++ have very rich graphics libraries, and it is not very easy to "just reimplement" them. And that is even without having to worry about multi-tasking or multi-window interfaces...)

If there is real demand, perhaps I can look into extending the scope of libi86 to also work on ELKS, in addition to MS-DOS.

Thank you!

pawosm-arm commented 3 years ago

I wonder how far we can go with this... It's like with Fuzix for Z80 machines where ability to run CP/M programs was considered.

Mellvik commented 3 years ago

 I wonder how far we can go with this... It's like with Fuzix for Z80 machines where ability to run CP/M programs was considered.

Interesting digression @pawosm-arm, I'm curious: anything in particular from cp/m you're interested in?

It may be worthwhile remembering that cp/m and fuzix ran on a different and incompatible architecture (from x86), and most programs were written in assembler. Still, I have 3 operating cp/m machines...

-Mellvik

toncho11 commented 3 years ago

Nice digression. We need that 👍

By the way is it possible to change the priority of a process in ELKS? There is a nice sys call, but no nice command? Maybe this will make a game run a bit faster.

While we wait for @ghaerr I think making a layer that allows for quick porting of turbo C programs and games will be interesting. I mean I want to use ELKS and have software for it. Ok some people are focused only on the kernel and they do not care about userland, but not me.

pawosm-arm commented 3 years ago

@toncho11 I think the 'bug' label here is slightly misleading.

@Mellvik,

Interesting digression @pawosm-arm, I'm curious: anything in particular from cp/m you're interested in?

Although interesting, this digression should not grow here as it barely touches the matter of this ticket. As for CP/M, having beefed up Spectrum +3 in a workable condition I've got a native machine to run CP/M Plus with all of the stuff I remember from the 80s. I also have Spectrum Next that also can boot CP/M Plus yet comparing to +3, the support for on-board peripherals isn't complete which leaves me with a sense of disappointment.

It may be worthwhile remembering that cp/m and fuzix ran on a different and incompatible architecture (from x86), and most programs were written in assembler. Still, I have 3 operating cp/m machines...

I'm slightly confused here. Both Fuzix and CP/M were originally targeting Z80 machines hence the idea of running CP/M software in Fuzix wasn't that terrible (considering simplicity of CP/M). And this simplicity was a key here: I suspect providing similar compatibility layer in ELKS to enable running 8088/8086 DOS programs would be more difficult.

In case of CP/M, attempts to support other architectures (e.g. CP/M-86 or CP/M-68k) never gained popularity due to competition from the natively developed operating systems that were better suited to those machines.

Anyway, there is some trace of the feature I've mentioned here in Fuzix's git repo: https://github.com/EtchedPixels/FUZIX/blob/master/Applications/cpm/runcpm.c

EOOT.

ghaerr commented 3 years ago

Hello everyone,

Well, there's a lot that got discussed today, here's a few of my thoughts...

one needs to rewrite the needed functions from graphics.h. Functions needed for this game are: fillpoly, drawpoly, settextstyle, outtextstyle, outtextxy, setfillstyle, floodfill, setcolor, rectangle

Yes, defining a distinct set of graphics functions, preferably across more than just one game, is a great way to start. Then, the entire function-set can be analyzed a bit and a graphics engine/library used as an API-bridge. Having done a heck of a lot of graphics engine programming, I also highly recommend keeping things simple in the beginning, and adding complexity only after getting the initial game(s) initially drawing. For instance, fill, draw poly and rectangle are pretty basic, but floodfill can get complicated. Text output is a whole 'nother discussion, but if a fixed-size font can be used, things are simplified considerably.

Maybe graphics.h can be mapped to Nano-X? But on 8086 computers Naxo-X looks slow for games.

Yes, a lot of the graphics could be mapped to Nano-X, but it will likely be too slow. The biggest reasons for this (to be covered in more detail later) are 1) the lower level routines are written in C, not ASM, and 2) Nano-X has an additional layer of overlapping window management and clipping support.

I have a number of graphics translation libraries for various embedded systems like Arduino, but what is really needed here is an (older) 8086 graphics library with direct, fast EGA support.

I never had occasion to work with nx before meeting ELKS (my past experience with NuttX from which nx originated never went beyond the nsh command line sessions), so I can't really say how good or bad this library is. I just have impression that I already saw things more mature than nx, like Photon on QNX or DirectFB on Linux. Even things like GUILib for multiplatform SDL library seemed more mature.

Actually, Nano-X originated from NanoGUI, which itself was based on some very early code by David I. Bell, the same guy that interestingly enough wrote sash and a lot of the basic command line utilities used in ELKS. I took that code back in the 1990's and started the Microwindows Project, whose original goal was to implement the Win32 GDI as well as an Xlib-like API onto Linux framebuffer systems (those with video cards implementing a flat frame buffer rather than the complicated and slow original EGA/VGA card hardware). Back in 1999, version 0.86 was the last version small enough to run on 8086 systems, and I ported it to ELKS. So we're running a code snapshot from 21 years ago. The landmine game is particularly old-fashioned looking; it was written by David Bell himself and a contributed port to Microwindows was made over 20 years ago. There are lots of other much better-looking Nano-X graphics, but most all are too big to run on ELKS,. The name was changed from Microwindows to Nano-X when Microsoft sent a cease and desist letter. Check out what Nano-X looks like today; unfortunately its all way too big for ELKS.

But I digress. Back to @pawosm-arm's points, SDL, DirectFB, etc - are all too large for ELKS. Since the ELKS applications (not the kernel) will be writing directly to the EGA, what we should seriously consider would be an older, fast EGA library. Those libraries would likely use a different assembler than ia16-gcc-as (which is gcc compatible and AT&T syntax). Another option would be to use the EGA draw routines from Nano-X written in ASM (elkcmd/nano-X/drivers/asmplan4.s), but they would need to be ported from the BCC/AS86 assembler, and the speed would likely improve considerably. Nano-X is written as three layers (driver, engine and API), and the driver and engine could be used without the window-management API overhead, which would help. Its all a bit complicated, but doable.

By the way is it possible to change the priority of a process in ELKS? There is a nice sys call, but no nice command? Maybe this will make a game run a bit faster.

There's no way to change the priority of a process in ELKS (yet); but when a single program is running, which is usually the case, there's no need for it - the system runs the single process as fast as can be, only taking timer interrupts, which increment a few counters, and then the interrupted process is immediately continued.

toncho11 commented 3 years ago

There is another solution:

Alfonso Martone found a way to convert DOS Turbo-C programs to enable these to run with ELKS. For this he developed the exe2elks DOS utility program and a small libc without DOS system calls. You compile your C program with this small libc library instead of the standard Turbo-C libc. Then you use the exe2elks utility to convert the generated executable in the DOS EXE format to a 16bit OMAGIC aout file as required by ELKS.

So if we accept that the Turbo C graphics.h is not using DOS system calls (I actually do not know) then we could compile a game with Turbo C and:

So again:

printf should come from ia16 gcc I suppose.

What do you think? Are the differences in compiling linking and function parameters handling so different ? This solution can solve the problem of speed because I believe Turbo C routines are already optimized.

pawosm-arm commented 3 years ago

Actually, Nano-X originated from NanoGUI, which itself was based on some very early code by David I.

Argh, this name reuse, so common in Open Source world. Indeed nx graphics in NuttX and nx graphics in ELKS are completely different things of completely different origins. Both had the same purpose in common which is being lightweight, and that confused me. So porting nx from NuttX may be one more path to follow or avoid.

Anyway, ability to change resolution (and bytes per pixel) would be a great addition to current graphics layer in ELKS, but only if it doesn't overcomplicate the current codebase.

pawosm-arm commented 3 years ago

Speaking of Turbo C++, it brings me some of my late school days memories, you can have a glimpse here, https://www.youtube.com/watch?v=N8z5kQFhJ9A yet note I'll probably pull it down soon, there's too much cringe in this :)

Anyway, looking forward, if you're serious about DOS compatibility in ELKS, IPX would be a nice addition, we had a lot of fun playing those early multiplayer games back in the 90's.

ghaerr commented 3 years ago

@toncho11,

Alfonso Martone found a way to convert DOS Turbo-C programs to enable these to run with ELKS. For this he developed the exe2elks DOS utility program and a small libc without DOS system calls. You compile your C program with this small libc library instead of the standard Turbo-C libc.

I have to say, somewhat amazing piece of work by Alfonso. He's definitely provided the basics, that should, possibly without modifications, work today (we upgraded the ELKS a.out format slightly earlier this year, but still support the original a.out format, calling it "v0").

The bigger issue with this approach is that the development is all done on DOS, right? So TurboC is run on DOS to compile and link any TC program, along with the TC graphics library, and Alfonso's DOS-to-ELKS conversion libc which allows the program to run on ELKS without modification. It's a slick way to solve this problem. Perhaps you should try running his sample programs and see if/how they run on ELKS today, for a start.

toncho11 commented 3 years ago

I compiled a minimal program that draws a rectangle with Turbo C and then applied exe2elks. For the map file generated by Turbo C and required by exe2elks there are 3 options "Segments", "Publics" and "Detailed". I think I wen with "Segments".

It says "invalid argument" on ELKS.

ghaerr commented 3 years ago

I compiled a minimal program that draws a rectangle with Turbo C and then applied exe2elks. It says "invalid argument" on ELKS.

This is very likely due to the exe2elks output a.out binary format not being compatible with ELKS now. We will need to make some changes to exe2elks.c. I won't be able to compile it, since I don't have access to DOS. Take a quick look at exe2elks.c, and familiarize yourself with it. Make sure you can compile it up from scratch to exe2elks.exe. Please post the non-working minimal program binary, and then I'll help determine what fields in the "elks" struct we need to change. I don't think it will be much.

toncho11 commented 3 years ago

Here it is: DEMO3.zip

toncho11 commented 3 years ago

If this is the correct disassembly: DEMO3.txt

then it means that there are 19 int $0x21 DOS calls ... more than I have hoped.

toncho11 commented 3 years ago

OK I see now ... probably I need to use the .bat file provided by Alfonso to set the proper options of tcc and tlink ... to generate a better executable ... I was using the IDE with .map file generation enabled.

ghaerr commented 3 years ago

probably I need to use the .bat file provided by Alfonso to set the proper options of tcc and tlink ... to generate a better executable

Yes, the idea is to compile with TC but link with Alfonso's special library that replaces all the TC libc calls to int 21h with ELKS system calls, and then rewrite the .EXE MZ format to ELKS a.out format.

toncho11 commented 3 years ago

Ok it is going to take much more time. Turbo C loads a graphical driver. So that is why there were many int 21 calls I suppose. It access the disk and it loads the driver - a EGAVGA.BGI file in my case as I am using VGA card. The good news is that I can convert the .bgi to .obj with bgiobj.exe and use it while linking .

toncho11 commented 3 years ago

This is a direct example of Alfonso:

HELLO.zip

It says "invalid argument". We need to fix that first before going deeper into the graphics library.

How do you disassemble it? objdump -s -x -D -b binary -m i8086 hello It does not print all the lines I think ?

ghaerr commented 3 years ago

@toncho11,

I'm not exactly sure what the problem is with ELKS running that (v0 format a.out header) executable, but I have a workaround that works:

chmem -h can be run on the executable, setting the same heap size as the program says it wanted originally; chmem will then set the header to type v1 and it will run. This should work on any executables produced by Alfonso's tools for the time being. I'll look into and fix either ELKS or your elks2exec.c so this won't be required after v0.4.0.

Screen Shot 2020-11-19 at 4 28 28 PM

How do you disassemble it?

It appears we don't have a way to disassemble linked binaries... the objdump86 program should be able to work, but it seems to want to work on .o files only. I'll look into that later also, unless you can find a decent 8086 disassembler on the net somewhere. I would like to add disassembly capability directly into an ELKS command.

toncho11 commented 3 years ago

It is far more complicated ... I can not even compile a normal exe with the integrated bgi driver.

@pawosm-arm Do you know how to do that? How to compile from command line with graphics.lib, egavga.obj and registerbgidriver(EGAVGA_driver) ? I can not make it to work.

toncho11 commented 3 years ago

Interesting ... I tried to contact Alfonso ... but there is no working email ... nor any other contact information ...

pawosm-arm commented 3 years ago

@pawosm-arm Do you know how to do that? How to compile from command line with graphics.lib, egavga.obj and registerbgidriver(EGAVGA_driver) ? I can not make it to work.

Can you specify more details? Which 'command line': DOS, Linux, ELKS? (well, ELKS command line doesn't seem to have a linker). What kind of binary do you want to have in effect?

ghaerr commented 3 years ago

I can not even compile a normal exe with the integrated bgi driver.

Compile or link error? You're using TC on DOS so there should be no issues having TC compiling TC programs, including those with graphics.h. Alfonso's trickery is all at the link stage, linking with additional libraries, right? You'll probably need to study TC a bit and understand what options it has for graphics programs, should there be compilation issues with it.

toncho11 commented 3 years ago

I made progress. The first step is specific to Turbo C: integrate the BGI driver into the executable. This is to avoid the insertion of a code that searches for the BGI driver on the filesystem and thus requiring a lot of DOS 21 calls.

Here is the code:

#include<graphics.h>
#include<conio.h>
void main()
{
      int gm , gd ;
      int er;

      gd = VGA;
      gm = VGAHI;
      er = registerbgidriver(EGAVGA_driver);
      if( er < 0)
      {
            printf(" Graphics sys error :%s" , grapherrormsg(er));
            getch();
            exit(0);
      }
      initgraph(&gd , &gm , "");
      outtext("hi");
      getch();
      closegraph();
}

And build script: tcc demo4.c c:\tc\lib\graphics.lib c:\tc\egavga.obj

toncho11 commented 3 years ago

I reached a new error.

Code with minimal commands:

#include<graphics.h>
void main()
{
      int gm , gd ;
      int er;

      gd = VGA;
      gm = VGAHI;
      er = registerbgidriver(EGAVGA_driver);

      initgraph(&gd , &gm , "");
      outtext("hi");

      closegraph();
}

Next the compilation to object file is: tcc -c -M -O -Z -a- -d -w -ms -r- -Ic:\tcc4elks\smallibc c:\tc\demo4.c but I skipped the '-A' option that does not allow it compile (that my problem). I do not know what is it?

next is: tlink /n /s /d demo4, demo4, demo4, c:\tcc4elks\smallibc\smallibc c:\tc\lib\graphics c:\tc\egavga.obj

And it gives error:

Turbo Link  Version 2.0  Copyright (c) 1987, 1988 Borland International
Undefined symbol '_REGISTERBGIDRIVER' in module DEMO4.C
Undefined symbol '__GRAPHEXIT' in module GRAPHC
Undefined symbol '__GRAPHGETMEM' in module GRAPHC
Undefined symbol '__GRAPHFREEMEM' in module GRAPHC
Undefined symbol 'SCOPY@' in module GRAPHC
Undefined symbol 'LXMUL@' in module GRAPHC
Undefined symbol 'LDIV@' in module GRAPHC
Undefined symbol 'DGROUP@' in module GRAPH
Warning: no stack
pawosm-arm commented 3 years ago

Ok, now I can see what you're after. Sadly, back then I deliberately avoided BGI graphics as I rather preferred mode 13h and direct writes to the video memory.

toncho11 commented 3 years ago

Yes, but how did you draw a line? You did use some library I suppose?

ghaerr commented 3 years ago

@toncho11,

Does the graphics program link and run on DOS, when not linking with the tcc4elks smalllibc? It is important that everything compile, link, and run perfectly on DOS before adding the additional complexity of a substitute libc.

ghaerr commented 3 years ago

tlink /n /s /d demo4, demo4, demo4, c:\tcc4elks\smallibc\smallibc c:\tc\lib\graphics c:\tc\egavga.obj

After you get it working on DOS, I think the above command line has to include c0.obj or c0noargs.obj; a quick look at the c0.S source code shows it defines DGROUP and STACK.

pawosm-arm commented 3 years ago

Yes, but how did you draw a line? You did use some library I suppose?

I didn't! They were all bitmaps :)

ghaerr commented 3 years ago

Hello @toncho11,

Are you still working on getting Alfonso's Turbo-C -> ELKS conversion mechanism working? I've fixed ELKS to run programs converted by his exe2elks program in #890. Despite some of your last issues with getting the BGI driver linked in to the DOS program, I still think its a potentially good idea for porting DOS graphics programs to ELKS.

Thank you!

toncho11 commented 3 years ago

I will look into it when I have the time. Thank you!

toncho11 commented 3 years ago

Hi,

Is it possible to write directly to video memory in ELKS? Can you do something like int 13h in DOS ? How woud you put a pixel in the video memory under ELKS?

ghaerr commented 3 years ago

Is it possible to write directly to video memory in ELKS? Can you do something like int 13h in DOS ?

Are you talking text or graphics? For text mode output, BIOS int 10h works well, and it writes the video memory.

For graphical mode, you have to know the card type. ELKS really only supports EGA, which uses 4-plane memory and is a bit complicated, as each plane has to be written separately. The memory is at segment B000:0000h. To see how Nano-X writes graphical pixels, look at the driver in elkscmd/nano-X/drivers/scr_bios.c, vgaplan4.c and mempl4.c.

Thank you!

toncho11 commented 1 year ago

Today I found http://www.sandroid.org/TurboC/ which allows Turbo C code to be ported to gcc (I mean it helps). Maybe it is possible to combine our gcc 16 bit compiler with this library to produce an environment capable of compiling Turbo C programs for ELKS.

toncho11 commented 1 year ago

Hmm the conio.h is implemented by ncurses, but we could replace it with something provided by @tkchia. But then graphics.h is implented with Xlib ... That is the problem ... most Linux ports usually require X11. It could be implemented with http://grx.gnu.de.

ghaerr commented 1 year ago

Hello @toncho11,

I have written a very lightweight ncurses replacement, used by fm, in elkscmd/tui/curses.c. For graphics, the Nano-X API is very similar to X11, and can be found in elkscmd/nano-X/nanox. I'd recommend porting an ncurses (text-only) game first, to determine how well the tools work.

Thank you!

toncho11 commented 1 year ago

I think porting https://www.svgalib.org to ELKS can be good. There is a Doom and Quake port for SVGAlib. Also http://grx.gnu.de use it as a base. It seems SVGAlib does not have important dependencies.

toncho11 commented 1 year ago

Hello @ghaerr , I guess ELKS does not support framebuffer? Wouldn't be a good idea to add support? This way we could port graphics libraries that utilize the Linux framebuffer.

toncho11 commented 1 year ago

http://grx.gnu.de can be compiled with the Linux frame buffer as target.

ghaerr commented 1 year ago

Hello @toncho11,

I guess ELKS does not support framebuffer?

The problem isn't ELKS, but instead the combination of video cards available and older PCs. Many older PCs support VGA, which does not support framebuffer access, and newer cards basically require 32-bit access to any framebuffer. My Microwindows Project has supported framebuffer for over 20 years, but I've had to port an ancient version of it to ELKS because of our 16-bit limitation and requirement to run on 8086 based systems.

To help understand the problem, consider that frame buffers are generally supposed to be "linear addresses" which allow a single pointer to the "buffer" - this buffer is always larger than 64K in any of the higher resolutions, and that basically requires 32-bit access, as ELKS/8086 are limited to 64K offsets from a pointer. For example, a basic RGBA framebuffer at even 320x480 resolution would be 4 bytes x 320 x 480 = 614,400 bytes, well over the 65,536 byte 8086-only limit. Even 16-bit color at 320x480 would require 307,200 bytes of video RAM.

There may be VESA modes on some cards that support framebuffer which could possibly run on older PCs (I'd have to check that), but in general, even with building special ASM language access to their framebuffer all graphics output would run extremely slowly. That's one of the many reasons good graphics had to wait not only for 32-bit processors and a larger address space, but onboard graphics processors to handle all the bits that need to be moved for higher resolution displays.

Thank you!

toncho11 commented 1 year ago

I see. The only solution is to use direct access to the video card (VGA one). You were saying that "Nano-X is written as three layers (driver, engine and API), and the driver and engine could be used without the window-management API overhead, which would help. Its all a bit complicated, but doable.".

So can you provide (we are not in a hurry) such mode where the window-management API is not used? The idea is to use the low level VGA functions without going through the window-management wrapper, right? The idea is to have some init function and then directly draw a rectangle for example, then we can try moving a rectangle from left to right to see how fast it is. Sounds like Tetris :)

ghaerr commented 1 year ago

@toncho11,

Here's a program nxtest written using the Nano-X API which opens a 100x100 window and moves it around the screen, as quickly as possible, using the VGA driver. I've tested it on QEMU, try it yourself on your hardware and see how quick it compares. It can be exited by typing ESC. I've attached a screen recording to show its speed on QEMU, as well as its source code, in case you'd like to mess with it. nxtest.zip

Screencast

Source code:

#include <stdlib.h>
#include "nano-X.h"
/*
 * Nano-X test routines
 */

GR_WINDOW_ID w1;
GR_GC_ID gc;
GR_SCREEN_INFO si;
int x, y;
int w = 100;
int h = 100;
int dir = 5;

int main(int argc, char ** argv)
{
    GR_EVENT    event;

    if (GrOpen() < 0) {
        exit(1);
    }

    GrGetScreenInfo(&si);

    w1 = GrNewWindow(GR_ROOT_WINDOW_ID, 0, 0, w, h,
        0, WHITE, BLACK);

    GrSelectEvents(w1, GR_EVENT_MASK_BUTTON_DOWN |
        GR_EVENT_MASK_KEY_DOWN | GR_EVENT_MASK_EXPOSURE);

    GrMapWindow(w1);

    gc = GrNewGC();

    GrSetGCForeground(gc, BLACK);
    GrSetGCBackground(gc, BLACK);
    GrFillRect(GR_ROOT_WINDOW_ID, gc, 0, 0, si.cols, si.rows);

    while (1) {
        if (GrPeekEvent(&event))
            GrGetNextEvent(&event);
        if (x + dir + w >= si.cols || y + dir + h >= si.rows ||
            x + dir < 0 || y + dir  < 0) {
                dir = -dir;
        }
        x += dir;
        y += dir;
        GrMoveWindow(w1, x++, y++);
    }
}
toncho11 commented 1 year ago

OK. I need to read everything here: http://www.microwindows.org/microwindows_architecture.html to avoid confusion.

So you are using the Nano-X API that is starting with Gr (let's call it X-API). You are not using Device-Independent Routines (let's call it DIR). All DIR start with Gd. I suppose it is much easier to work with X-API as it can handle things like keyboard input, mouse input and in general it is a higher level API. But I was talking about the fact that this extra layer, which seems client-server based can also add delays. In general all nxdemos are very slow on my 8088/8086 machines. I suppose the idea is to test the X-API performance one more time before trying a DIR version?

ghaerr commented 1 year ago

So you are using the Nano-X API that is starting with Gr You are not using Device-Independent Routines

Yes - I just whipped together something quickly to build a program that will allow speed testing on your old PCs. In general, as long as a window is not obscured by another window (i.e. no clipping required), the device independent actual draw routines run at full speed. So there wasn't much point in writing code using Gd routines since as you point out mouse and keyboard handling come for free with the NX API.

With regards to client/server, you would be correct, except that our early version of Nano-X doesn't actually support or require client/server, and instead Nano-X is linked into each application directly (which is why the binaries are so large). However, being linked directly in also means there is no client/server overhead either and drawing is as fast as the hardware allows.

I need to read everything here: http://www.microwindows.org/microwindows_architecture.html to avoid confusion.

Yes, but only the Nano-X API section will be required for any coding. There are also some tutorials and ELJ articles on the microwindows.org website.

In general all nxdemos are very slow on my 8088/8086 machines.

It would be interesting to see just how slow this particular nxtest program runs on your older systems, as that will serve as a lower-end benchmark of how fast/slow any straightforward rectangle filling takes, and be indicative of the overall usefulness of which kinds of games might run well or be ported to ELKS using Nano-X.

toncho11 commented 1 year ago

So nxtest is 30 kb with the X server linked?

ghaerr commented 1 year ago

Yes, with the NX (Nano-X, not X) server linked.