320×200×256 color mode
How to set Nano X to 256 320×200×256 color mode in ELKS?
Low resolution 256-color modes are not currently supported. Only EGA 640x350x16 and VGA 640x480x16 are operational.
This just made my other nxapp useless.
Where are the 16 colors defined? It it a standard VGA 16 colors palette or X11 ? What is it?
How to set Nano X to 256 320×200×256 color mode in ELKS?
This just made my other nxapp useless.
It was my understanding that your Mode X driver discussed in #137 was going to provide the 320x200x256 color mode you are inquiring about?
Where are the 16 colors defined? It it a standard VGA 16 colors palette or X11 ? What is it?
The EGA/VGA screen driver for Nano-X runs on ELKS and uses the default 16-color EGA/VGA hardware palette. Nano-X takes an application-specified RGB value and maps that to (hopefully) the current hardware palette using the palette table in engine/devpal4.c:
/*
* Standard palette for 16 color systems.
*/
const MWPALENTRY mwstdpal4[16] = {
/* 16 EGA colors, arranged in VGA standard palette order*/
RGBDEF( 0 , 0 , 0 ), /* black*/
RGBDEF( 0 , 0 , 128 ), /* blue*/
RGBDEF( 0 , 128, 0 ), /* green*/
RGBDEF( 0 , 128, 128 ), /* cyan*/
RGBDEF( 128, 0 , 0 ), /* red*/
RGBDEF( 128, 0 , 128 ), /* magenta*/
RGBDEF( 128, 64 , 0 ), /* adjusted brown*/
RGBDEF( 192, 192, 192 ), /* ltgray*/
RGBDEF( 128, 128, 128 ), /* gray*/
RGBDEF( 0 , 0 , 255 ), /* ltblue*/
RGBDEF( 0 , 255, 0 ), /* ltgreen*/
RGBDEF( 0 , 255, 255 ), /* ltcyan*/
RGBDEF( 255, 0 , 0 ), /* ltred*/
RGBDEF( 255, 0 , 255 ), /* ltmagenta*/
RGBDEF( 255, 255, 0 ), /* yellow*/
RGBDEF( 255, 255, 255 ), /* white*/
};
Thank you. The real motivation of mode X was less memory and potentially faster rendering on slow systems.
Is it possible to set at runtime 16 grayscaled colors like that:
GR_PALETTE pal; pal.count = 16; // number of entries to update pal.palette[i].r = ...; // 0–255 pal.palette[i].g = ... pal.palette[i].b = ...
GrSetSystemPalette(&pal);
Use the gray 16 grayscaled colors.
And finally restore the original palette afterward, so that other Nano X apps can display properly.
Actually it won't work, because change is instant, affecting everything else already on the screen. It depends on what you need.
I have a problem with changing the palette. It blocks the whole program. I use:
if (use_gray16) {
GR_PALETTE pal1;
pal1.count = 1;
for (int i = 0; i < 16 && i < pal.count; i++) {
unsigned char v = (unsigned char)(i * 17); /* 0..255 -> 16 steps */
pal1.palette[0].r = v;
pal1.palette[0].g = v;
pal1.palette[0].b = v;
GrSetSystemPalette(i, &pal1);
}
LOG("Installed 16 grayscale entries (0..15)");
}
What is the correct way? Is the setting the palette even possible on ELKS version?
@ghaerr waiting for your feedback.
I am trying also:
if (use_gray16) {
GR_PALETTE gpal;
gpal.count = 16;
for (int i = 0; i < 16; i++) {
/* KEEP GUI COLORS INTACT */
if (i == 0 || i == 7 || i == 8 || i == 15) {
gpal.palette[i] = pal.palette[i];
continue;
}
unsigned char v = (unsigned char)(i * 17);
gpal.palette[i].r = v;
gpal.palette[i].g = v;
gpal.palette[i].b = v;
}
GrSetSystemPalette(0, &gpal);
palette_modified = 1;
/* update drawing colors */
for (int i = 0; i < 16; i++)
color_from_index[i] = GR_RGB(
gpal.palette[i].r,
gpal.palette[i].g,
gpal.palette[i].b);
}
Is it possible that this is a bug in Nano-X?
Is the setting the palette even possible on ELKS version?
No, setting the hardware palette has not been implemented in the EGA/VGA driver.
To implement setting the hardware palette, the function VGA_setpalette() in drivers/scr_vga.c needs to be written.
I have a problem with changing the palette. It blocks the whole program.
That is strange, since the VGA_setpalette function current does nothing and just returns.
Actually it won't work, because change is instant, affecting everything else already on the screen.
That's correct. Palette mode operation has pretty much fallen out of favor in multi-client systems for just this reason.
Thanks!
I am still interested in having it. You mean here: https://github.com/ghaerr/microwindows/blob/12e6cb607c09d793299e6157c9d2395b134f0ece/src/drivers/scr_vga.c#L178
So it should be:
static void
VGA_setpalette(PSD psd, int first, int count, MWPALENTRY *pal)
{
int i;
/* Program VGA DAC starting index */
outp(0x3C8, first);
for (i = 0; i < count; i++) {
/* VGA DAC uses 6-bit values (0–63), Nano-X uses 8-bit (0–255) */
outp(0x3C9, pal[i].r >> 2);
outp(0x3C9, pal[i].g >> 2);
outp(0x3C9, pal[i].b >> 2);
}
}
I am using this code and it compiles OK, but still halts in my Nano X app.
static void
VGA_setpalette(PSD psd, int first, int count, MWPALENTRY *pal)
{
int i;
/* Start writing at palette index 'first' */
outb(0x3C8, first);
for (i = 0; i < count; i++) {
/* VGA DAC uses 6-bit values (0–63), Nano-X uses 8-bit (0–255) */
outb(0x3C9, pal[i].r >> 2);
outb(0x3C9, pal[i].g >> 2);
outb(0x3C9, pal[i].b >> 2);
}
}
I don't have a VGA manual to check, but yes, that looks like the right idea.
The fact that it freezes as before (as if nothing changed) suggests some other problem.
but still halts in my Nano X app.
Sounds like something else is wrong, since as I pointed out above, even having an empty VGA_setpalette routine should not cause your app to hang.
This is how I call it:
if (use_gray16) {
GR_PALETTE gpal;
gpal.count = 16; /* VGA has exactly 16 DAC entries */
for (int i = 0; i < 16; i++) {
unsigned char v = (unsigned char)((i * 255) / 15);
gpal.palette[i].r = v;
gpal.palette[i].g = v;
gpal.palette[i].b = v;
}
GrSetSystemPalette(0, &gpal);
palette_modified = 1;
LOG("Applied 16-gray palette");
}
It seems the call to GrSetSystemPalette does the crash.
It seems the call to GrSetSystemPalette does the crash.
Try commenting out that call to verify, and comment out code within VGA_setpalette in drivers/scr_vga.c.
If GrSetSystemPalette is verified to crash, even with nothing in VGA_setpalette(), try commenting out the following two lines in nanox/srvfunc.c:
/* Set the system palette entries from first for count*/
void
GrSetSystemPalette(GR_COUNT first, GR_PALETTE *pal)
{
#if MW_FEATURE_PALETTE
SERVER_LOCK();
GdSetPalette(rootwp->psd, first, pal->count, pal->palette);
// if (first == 0) // <---- comment out these two lines to see if any effect
// GsRedrawScreen();
SERVER_UNLOCK();
#endif
}
No 256 color mode. Palette change will take time to implement properly.