diff --git a/CHANGELOG b/CHANGELOG index f20ed6939c9..7a96fb2b47a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -36,7 +36,7 @@ Next version: written regardless of gate status. Prior code returned the stale latched value of the counter as it was prior to shutting off the gate and writing the counter, causing timing issues. - - Fix restoring minimized window on TTF output (issue #4248) (maron2000) + - Fix restoring minimized window on TTF output (Issue #4248) (maron2000) - Fix macos crash on launch when output=surface or auto (SDL2) (maron2000) - Update in-tree SDL2 library to ver 2.28.2 (maron2000) - Updated build tool for MinGW lowend builds required for the updated SDL2 @@ -44,6 +44,8 @@ Next version: features. (maron2000) - Debugger RUN and RUNWATCH commands were broken, fix. Make sure debugger shortcut triggers execution to stop whether in RUN or RUNWATCH mode. + - Fix SETCOLORS command didn't change color when output=ttf.(Issue #4503) + Also fixed the values reported were wrong. (maron2000) 2023.09.01 - Disable by default message confirmation after snapshot and AVI video diff --git a/src/dos/dos_programs.cpp b/src/dos/dos_programs.cpp index 6e2d7da55af..a6d0a032793 100644 --- a/src/dos/dos_programs.cpp +++ b/src/dos/dos_programs.cpp @@ -8145,35 +8145,42 @@ static void COLOR_ProgramStart(Program * * make) { *make=new COLOR; } -bool setVGAColor(const char *colorArray, int i) { +alt_rgb altBGR[16], *rgbcolors = (alt_rgb*)render.pal.rgb; +bool setVGAColor(const char *colorArray, int j) { if (!IS_VGA_ARCH||!CurMode) return false; const char * nextRGB = colorArray; - int rgbVal[4] = {-1,-1,-1,-1}; - if (sscanf(nextRGB, " ( %d , %d , %d)", &rgbVal[0], &rgbVal[1], &rgbVal[2]) == 3) { - for (int i = 0; i< 3; i++) { - if (rgbVal[i] < 0 || rgbVal[i] > 255) - return false; - } - } else if (sscanf(nextRGB, " #%6x", (unsigned int*)(&rgbVal[3])) == 1) { - if (rgbVal[3] < 0) + uint8_t rgbVal[3] = {0}; + int32_t red, green, blue; + int32_t nextRGB_val = -1; + if (sscanf(nextRGB, " ( %d , %d , %d)", (int32_t*)&red, (int32_t*)&green, (int32_t*)&blue) == 3) { + if(red >= 0) rgbVal[0] = (uint8_t)(red & 0xFF); + if(green >= 0) rgbVal[1] = (uint8_t)(green & 0xFF); + if(blue >= 0) rgbVal[2] = (uint8_t)(blue & 0xFF); + } else if (sscanf(nextRGB, " #%6x", (uint32_t*)&nextRGB_val) == 1) { + if (nextRGB_val < 0) return false; - for (int i = 0; i < 3; i++) { - rgbVal[2-i] = rgbVal[3]&255; - rgbVal[3] >>= 8; + for (int i = 2; i >= 0; i--) { + rgbVal[i] = nextRGB_val&255; + nextRGB_val >>= 8; } } else return false; - IO_ReadB(mem_readw(BIOS_VIDEO_PORT)+6); - IO_WriteB(VGAREG_ACTL_ADDRESS, i+32); - uint8_t imap=IO_ReadB(VGAREG_ACTL_READ_DATA); - IO_WriteB(VGAREG_DAC_WRITE_ADDRESS, imap); - IO_WriteB(VGAREG_DAC_DATA, (rgbVal[0]+3)*63/255); - IO_WriteB(VGAREG_DAC_DATA, (rgbVal[1]+3)*63/255); - IO_WriteB(VGAREG_DAC_DATA, (rgbVal[2]+3)*63/255); + + for(int i = j > -1 ? j : 0; i < (j > -1 ? j + 1 : 16); i++) { + IO_ReadB(mem_readw(BIOS_VIDEO_PORT) + 6); + IO_WriteB(VGAREG_ACTL_ADDRESS, i + 32); + uint8_t imap = IO_ReadB(VGAREG_ACTL_READ_DATA); + IO_WriteB(VGAREG_DAC_WRITE_ADDRESS, imap); + IO_WriteB(VGAREG_DAC_DATA, rgbVal[0] >> 2); + IO_WriteB(VGAREG_DAC_DATA, rgbVal[1] >> 2); + IO_WriteB(VGAREG_DAC_DATA, rgbVal[2] >> 2); + rgbcolors[j].red = rgbVal[0]; + rgbcolors[j].green = rgbVal[1]; + rgbcolors[j].blue = rgbVal[2]; + } return true; } -alt_rgb altBGR[16], *rgbcolors = (alt_rgb*)render.pal.rgb; #if defined(USE_TTF) extern alt_rgb altBGR1[16]; extern bool colorChanged; @@ -8224,9 +8231,12 @@ void SETCOLOR::Run() if (p==NULL) { #if defined(USE_TTF) bool colornul = staycolors || (IS_VGA_ARCH && (altBGR1[i].red > 4 || altBGR1[i].green > 4 || altBGR1[i].blue > 4) && rgbcolors[i].red < 5 && rgbcolors[i].green < 5 && rgbcolors[i].blue < 5); - altBGR[i].red = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].red:rgbcolors[i].red; - altBGR[i].green = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].green:rgbcolors[i].green; - altBGR[i].blue = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].blue:rgbcolors[i].blue; + rgbcolors[i].red = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].red:rgbcolors[i].red; + rgbcolors[i].green = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].green:rgbcolors[i].green; + rgbcolors[i].blue = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].blue:rgbcolors[i].blue; + altBGR[i].red = rgbcolors[i].red; + altBGR[i].green = rgbcolors[i].green; + altBGR[i].blue = rgbcolors[i].blue; WriteOut("Color %d: (%d,%d,%d) or #%02x%02x%02x\n",i,altBGR[i].red,altBGR[i].green,altBGR[i].blue,altBGR[i].red,altBGR[i].green,altBGR[i].blue); #else WriteOut("Color %d: (%d,%d,%d) or #%02x%02x%02x\n",i,rgbcolors[i].red,rgbcolors[i].green,rgbcolors[i].blue,rgbcolors[i].red,rgbcolors[i].green,rgbcolors[i].blue); @@ -8275,11 +8285,15 @@ void SETCOLOR::Run() #if defined(USE_TTF) } else if (setColors(value,i)) { bool colornul = staycolors || (IS_VGA_ARCH && (altBGR1[i].red > 4 || altBGR1[i].green > 4 || altBGR1[i].blue > 4) && rgbcolors[i].red < 5 && rgbcolors[i].green < 5 && rgbcolors[i].blue < 5); - altBGR[i].red = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].red:rgbcolors[i].red; - altBGR[i].green = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].green:rgbcolors[i].green; - altBGR[i].blue = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].blue:rgbcolors[i].blue; - WriteOut("Color %d => (%d,%d,%d) or #%02x%02x%02x\n",i,altBGR[i].red,altBGR[i].green,altBGR[i].blue,altBGR[i].red,altBGR[i].green,altBGR[i].blue); + rgbcolors[i].red = (colornul || (colorChanged && !IS_VGA_ARCH)) ? altBGR1[i].red : rgbcolors[i].red; + rgbcolors[i].green = (colornul || (colorChanged && !IS_VGA_ARCH)) ? altBGR1[i].green : rgbcolors[i].green; + rgbcolors[i].blue = (colornul || (colorChanged && !IS_VGA_ARCH)) ? altBGR1[i].blue : rgbcolors[i].blue; + altBGR[i].red = rgbcolors[i].red; + altBGR[i].green = rgbcolors[i].green; + altBGR[i].blue = rgbcolors[i].blue; + WriteOut("Color %d => (%d,%d,%d) or #%02x%02x%02x\n",i, rgbcolors[i].red, rgbcolors[i].green, rgbcolors[i].blue, rgbcolors[i].red, rgbcolors[i].green, rgbcolors[i].blue); resetFontSize(); + setVGAColor(value, i); // also change pallette value for non-TTF output } else WriteOut("Invalid color value - %s\n",value); #endif @@ -8289,10 +8303,13 @@ void SETCOLOR::Run() for (int i = 0; i < 16; i++) { #if defined(USE_TTF) bool colornul = staycolors || (IS_VGA_ARCH && (altBGR1[i].red > 4 || altBGR1[i].green > 4 || altBGR1[i].blue > 4) && rgbcolors[i].red < 5 && rgbcolors[i].green < 5 && rgbcolors[i].blue < 5); - altBGR[i].red = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].red:rgbcolors[i].red; - altBGR[i].green = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].green:rgbcolors[i].green; - altBGR[i].blue = colornul||(colorChanged&&!IS_VGA_ARCH)?altBGR1[i].blue:rgbcolors[i].blue; - WriteOut("Color %d: (%d,%d,%d) or #%02x%02x%02x\n",i,altBGR[i].red,altBGR[i].green,altBGR[i].blue,altBGR[i].red,altBGR[i].green,altBGR[i].blue); + rgbcolors[i].red = colornul || (colorChanged && !IS_VGA_ARCH) ? altBGR1[i].red : rgbcolors[i].red; + rgbcolors[i].green = colornul || (colorChanged && !IS_VGA_ARCH) ? altBGR1[i].green : rgbcolors[i].green; + rgbcolors[i].blue = colornul || (colorChanged && !IS_VGA_ARCH) ? altBGR1[i].blue : rgbcolors[i].blue; + altBGR[i].red = rgbcolors[i].red; + altBGR[i].green = rgbcolors[i].green; + altBGR[i].blue = rgbcolors[i].blue; + WriteOut("Color %d: (%d,%d,%d) or #%02x%02x%02x\n",i, rgbcolors[i].red, rgbcolors[i].green, rgbcolors[i].blue, rgbcolors[i].red, rgbcolors[i].green, rgbcolors[i].blue); #else WriteOut("Color %d: (%d,%d,%d) or #%02x%02x%02x\n",i,rgbcolors[i].red,rgbcolors[i].green,rgbcolors[i].blue,rgbcolors[i].red,rgbcolors[i].green,rgbcolors[i].blue); #endif diff --git a/src/ints/int10_pal.cpp b/src/ints/int10_pal.cpp index 8a6c80c8719..e606b74a657 100644 --- a/src/ints/int10_pal.cpp +++ b/src/ints/int10_pal.cpp @@ -29,6 +29,7 @@ void GFX_EndTextLines(bool force); bool setColors(const char *colorArray, int n); #endif +bool setVGAColor(const char* colorArray, int j); static INLINE void ResetACTL(void) { IO_Read(real_readw(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS) + 6u); } @@ -241,6 +242,7 @@ void INT10_SetSingleDACRegister(uint8_t index,uint8_t red,uint8_t green,uint8_t } setColors(value,imap[index]); if (ttf.inUse) GFX_EndTextLines(true); + setVGAColor(value, imap[index]); #endif } @@ -270,7 +272,7 @@ void INT10_SetDACBlock(uint16_t index,uint16_t count,PhysPt data) { IO_Write(VGAREG_DAC_DATA,blue); #if defined(USE_TTF) if (start==16) { - sprintf(value,"(%d,%d,%d)",red*255/63, green*255/63, blue*255/63); + sprintf(value,"(%d,%d,%d)",(red<<2|red>>4), (green<<2|green>>4), (blue<<2|blue>>4)); str+=std::string(value)+" "; } #endif @@ -289,18 +291,20 @@ void INT10_SetDACBlock(uint16_t index,uint16_t count,PhysPt data) { IO_Write(VGAREG_DAC_DATA,ic); #if defined(USE_TTF) if (start==16) { - sprintf(value,"(%d,%d,%d)",red*255/63, green*255/63, blue*255/63); + sprintf(value,"(%d,%d,%d)", (red << 2 | red >> 4), (green << 2 | green >> 4), (blue << 2 | blue >> 4)); str+=std::string(value); } #endif } } + + if(str.size()) { #if defined(USE_TTF) - if (str.size()) { - setColors(str.c_str(),-1); - if (ttf.inUse) GFX_EndTextLines(true); - } + setColors(str.c_str(), -1); + if(ttf.inUse) GFX_EndTextLines(true); #endif + setVGAColor(str.c_str(), -1); + } } void INT10_GetDACBlock(uint16_t index,uint16_t count,PhysPt data) { diff --git a/src/output/output_ttf.cpp b/src/output/output_ttf.cpp index 2195df046d9..1ca54678e76 100644 --- a/src/output/output_ttf.cpp +++ b/src/output/output_ttf.cpp @@ -124,6 +124,7 @@ int menuwidth_atleast(int width), FileDirExistCP(const char *name), FileDirExist void AdjustIMEFontSize(void),refreshExtChar(void), initcodepagefont(void), change_output(int output), drawmenu(Bitu val), KEYBOARD_Clear(void), RENDER_Reset(void), DOSBox_SetSysMenu(void), GetMaxWidthHeight(unsigned int *pmaxWidth, unsigned int *pmaxHeight), SetWindowTransparency(int trans), resetFontSize(void), RENDER_CallBack( GFX_CallBackFunctions_t function ); bool isDBCSCP(void), InitCodePage(void), CodePageGuestToHostUTF16(uint16_t *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/), systemmessagebox(char const * aTitle, char const * aMessage, char const * aDialogType, char const * aIconType, int aDefaultButton); std::string GetDOSBoxXPath(bool withexe=false); +bool setVGAColor(const char* colorArray, int i); #if defined(C_SDL2) void GFX_SetResizeable(bool enable); @@ -242,9 +243,9 @@ void setVGADAC() { IO_WriteB(VGAREG_ACTL_ADDRESS, i+32); imap[i]=IO_ReadB(VGAREG_ACTL_READ_DATA); IO_WriteB(VGAREG_DAC_WRITE_ADDRESS, imap[i]); - IO_WriteB(VGAREG_DAC_DATA, (altBGR1[i].red+3)*63/255); - IO_WriteB(VGAREG_DAC_DATA, (altBGR1[i].green+3)*63/255); - IO_WriteB(VGAREG_DAC_DATA, (altBGR1[i].blue+3)*63/255); + IO_WriteB(VGAREG_DAC_DATA, rgbColors[i].red>>2); + IO_WriteB(VGAREG_DAC_DATA, rgbColors[i].green>>2); + IO_WriteB(VGAREG_DAC_DATA, rgbColors[i].blue>>2); } } } @@ -261,34 +262,35 @@ bool setColors(const char *colorArray, int n) { staycolors = strlen(colorArray) && *colorArray == '+'; const char* nextRGB = colorArray + (staycolors?1:0); uint8_t * altPtr = (uint8_t *)altBGR1; - int rgbVal[3] = {-1,-1,-1}; - for (int colNo = 0; colNo < (n>-1?1:16); colNo++) { - if (n>-1) altPtr+=4*n; - if (sscanf(nextRGB, " ( %d , %d , %d)", &rgbVal[0], &rgbVal[1], &rgbVal[2]) == 3) { // Decimal: (red,green,blue) + int8_t rgbVal[3] = {-1,-1,-1}; + int32_t nextRGB_val = -1; + for (int colNo = n>-1?n:0; colNo < (n>-1?n+1:16); colNo++) { + if (sscanf(nextRGB, " ( %d , %d , %d)", (int32_t*)&rgbVal[0], (int32_t*)&rgbVal[1], (int32_t*)&rgbVal[2]) == 3) { // Decimal: (red,green,blue) for (int i = 0; i< 3; i++) { if (rgbVal[i] < 0 || rgbVal[i] > 255) return false; - altPtr[i] = rgbVal[i]; } while (*nextRGB != ')') nextRGB++; nextRGB++; - } else if (sscanf(nextRGB, " #%6x", ((unsigned int*)(&rgbVal[0]))) == 1) { // Hexadecimal - if (rgbVal[0] < 0) + } else if (sscanf(nextRGB, " #%6x", (uint32_t*)&nextRGB_val) == 1) { // Hexadecimal + if (nextRGB_val < 0) return false; - for (int i = 0; i < 3; i++) { - altPtr[2-i] = rgbVal[0]&255; - rgbVal[0] >>= 8; + for (int i = 2; i >= 0; i--) { + rgbVal[i] = nextRGB_val&255; + nextRGB_val >>= 8; } nextRGB = strchr(nextRGB, '#') + 7; } else return false; - altPtr += 4; - } - for (int i = n>-1?n:0; i < (n>-1?n+1:16); i++) { - altBGR0[i].blue = (altBGR1[i].blue*2 + 128)/4; - altBGR0[i].green = (altBGR1[i].green*2 + 128)/4; - altBGR0[i].red = (altBGR1[i].red*2 + 128)/4; + for(int i = n > -1 ? n : 0; i < (n > -1 ? n + 1 : 16); i++) { + altBGR0[i].red = rgbColors[i].red; + altBGR0[i].green = rgbColors[i].green; + altBGR0[i].blue = rgbColors[i].blue; + } + rgbColors[colNo].blue = (uint8_t)rgbVal[2]; + rgbColors[colNo].green = (uint8_t)rgbVal[1]; + rgbColors[colNo].red = (uint8_t)rgbVal[0]; } setVGADAC(); colorChanged=justChanged=true; @@ -694,8 +696,9 @@ void OUTPUT_TTF_Select(int fsize) { str+=std::string(value)+" "; } if (str.size()) { - setColors(str.c_str(),-1); - colorChanged=justChanged=false; + colorChanged = justChanged = false; + setColors(str.c_str(), -1); + //setColors("#000000 #0000aa #00aa00 #00aaaa #aa0000 #aa00aa #aa5500 #aaaaaa #555555 #5555ff #55ff55 #55ffff #ff5555 #ff55ff #ffff55 #ffffff",-1); } } SetBlinkRate(ttf_section); @@ -1329,7 +1332,6 @@ void AutoBoxDraw_mapper_shortcut(bool pressed) { if (ttf.inUse) resetFontSize(); } -bool setVGAColor(const char *colorArray, int i); void ttf_reset_colors() { if (ttf.inUse) { SetVal("ttf", "colors", "");