Hi,
I need a help with modification of Orbiter for Nokia Internet Tablets. Basically, it works fine. But when I built the Orbiter from the latest 0710 sources I found the problem with icons on floorplan. Let me first a clarify the Orbiter's logic (as I understand it). All icons on the floor plan have color pink (255, 102, 255). When the screen with floor plan is opened the Orbiter starts checking all pixels from the screen area to compare their colors with pink. If such pixel is found its color is replaced by proper color (red, yellow, black etc). There is a hack (which works fine with current version of the Orbiter) to fill icons by proper color. I just increase the maximum difference between RGB parts of pink and retrieved pixel to 10 (originally it's 3):
if ( abs(Source[0]-red)<max_diff && abs(Source[1]-green)<max_diff && abs(Source[2]-blue)<max_diff )
The problem with Nokia is that. It uses 16bit surface but on-screen Orbiter - 32bit. I solved a problem with comparison source color (pink, 32bit) with retrieved pixel color (16bit) by using SDL_GetRGB function:
SDL_GetRGB((Uint32)Pixel, m_pScreenImage->format, &red, &green, &blue);
But now I have to convert replacement color from 32bit to 16. I don't have a lot of SDL of C++ knowledge. So, any help will be very appreciated!
You can find the code in the Orbiter/SDL/OrbiterRenderer_SDL.cpp, method OrbiterRenderer_SDL::ReplaceColorInRectangle. Here is a my version of that method:
void OrbiterRenderer_SDL::ReplaceColorInRectangle(int x, int y, int width, int height, PlutoColor ColorToReplace, PlutoColor ReplacementCol
or, DesignObj_Orbiter *pObj/* = NULL*/)
{
SDL_PixelFormat * PF = m_pScreenImage->format;
Uint32 PlutoPixelDest, PlutoPixelSrc, Pixel;
Uint8 red, green, blue;
#ifdef DEBUG
LoggerWrapper::GetInstance()->Write(LV_STATUS, "ReplaceColor: ColorToReplace --> %u %u %u : ReplacementColor --> %u %u %u",
ColorToReplace.R(), ColorToReplace.G(), ColorToReplace.B(),
ReplacementColor.R(), ReplacementColor.G(), ReplacementColor.B());
#endif
//PlutoPixelSrc = (ColorToReplace.R() << PF->Rshift) | (ColorToReplace.G() << PF->Gshift) | (ColorToReplace.B() << PF->Bshift); // | (C
olorToReplace.A() << PF->Ashift);
PlutoPixelSrc = (ColorToReplace.R() << rshift) | (ColorToReplace.G() << gshift) | (ColorToReplace.B() << bshift); // | (ColorToReplace.
A() << PF->Ashift);
unsigned char *Source = (unsigned char *) &PlutoPixelSrc;
//PlutoPixelDest = ReplacementColor.R() << PF->Rshift | ReplacementColor.G() << PF->Gshift | ReplacementColor.B() << PF->Bshift;// TOD
O -- this should work | ReplacementColor.A() << PF->Ashift;
// By some reason, SDL pixel format doesn't take into account byte order (for Nokia it's - little endian). As result pixel color is wrong after
// shift. I use values from the SDL_Helper/SDL_Defs.h
PlutoPixelDest = (ReplacementColor.R() << rshift) | (ReplacementColor.G() << gshift) | (ReplacementColor.B() << bshift);// TODO -- thi
s should work | ReplacementColor.A() << PF->Ashift;
for (int j = 0; j < height; j++)
{
for (int i = 0; i < width; i++)
{
// we may need locking on the surface
Pixel = SDLGraphic::getpixel(m_pScreenImage, i + x, j + y);
unsigned char *pPixel = (unsigned char *) &Pixel;
#ifndef MAEMO_NOKIA770
const int max_diff = 3;
if ( abs(Source[0]-pPixel[0])<max_diff && abs(Source[1]-pPixel[1])<max_diff && abs(Source[2]-pPixel[2])<max_diff && abs(Source[
3]-pPixel[3])<max_diff )
{
SDLGraphic::putpixel(m_pScreenImage,i + x, j + y, PlutoPixelDest);
}
#else
const int max_diff = 5;
//SDLGraphic::get_RGB(m_pScreenImage, Pixel);
SDL_GetRGB((Uint32)Pixel, m_pScreenImage->format, &red, &green, &blue);
LoggerWrapper::GetInstance()->Write(LV_STATUS, "Source=%u %u %u - Pixel=%u %u %u \n", Source[0], Source[1], Source[2], red, gre
en, blue);
//if ( abs(Source[0]-pPixel[0])<max_diff && abs(Source[1]-pPixel[1])<max_diff && abs(Source[2]-pPixel[2])<max_diff )
if ( abs(Source[0]-red)<max_diff && abs(Source[1]-green)<max_diff && abs(Source[2]-blue)<max_diff )
{
SDLGraphic::putpixel(m_pScreenImage,i + x, j + y, PlutoPixelDest);
LoggerWrapper::GetInstance()->Write(LV_STATUS, "Replace pixel: %u %u %u - 0x%x\n!",
Source[0], Source[1], Source[2], PlutoPixelDest);
}
else
{
LoggerWrapper::GetInstance()->Write(LV_STATUS, "Do not do anything!");
}
#endif
}
}
PlutoRectangle rect(x, y, width, height);
}
All pixel operation are implemented in the Orbiter/SDL/SDLGraphic.cpp