hi-ban
Member
- Joined
- Jan 31, 2011
- Messages
- 100
I have a problem:
The emulator i'm working in, use a scaler (1.5x) which (don't know why) uses RGB343 color as source, and RGB565 as dest.
This leads to my problem: when setting a color palette, the colors show ok when using no scaling, but when using the 1.5x scaler, the colors are slightly different than expected.
I suppose that some color information is "lost" when translating a color from RGB565(16bit) to RGB343(10bit) before doing the scaling operation.
The only solution to this, is making the scaler to use RGB565 for both source and dest. But i am quite noob in programming.
Any help with this? Ideas? Explanations? Here is the code:
And also (case 1 y 2):
The emulator i'm working in, use a scaler (1.5x) which (don't know why) uses RGB343 color as source, and RGB565 as dest.
This leads to my problem: when setting a color palette, the colors show ok when using no scaling, but when using the 1.5x scaler, the colors are slightly different than expected.
I suppose that some color information is "lost" when translating a color from RGB565(16bit) to RGB343(10bit) before doing the scaling operation.
The only solution to this, is making the scaler to use RGB565 for both source and dest. But i am quite noob in programming.
Any help with this? Ideas? Explanations? Here is the code:
Code:
static un16 buffer[3][240];
/*
** Appears to expect source/dest framebuffer pixels to be 16bpp
** But expects source to be in RGB343 format. Looks like it may expect dest to be RGB565.
** 1.5 scaler with "smoothing", i.e. 160x144 -> 239x215 BUT centered/centred in a 320x240 screen.
** It looks like it does a 2 pass conversion:
** 1) increase 3x
** 2) decrease by 2x
*/
void ohb_scale3x(){
un16 *dst = buffer[0];
un16 *src = (un16*)fb.ptr;
un16 *base = (un16*)vid_fb.ptr + 3880;
int x,y;
un16 A,B,C,D,E,F,G,H,I;
memset(buffer,0,480*3);
// Top-left
SCALE3X(0,1,0,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
// Top
for(x=1; x<159; x+=2){
SCALE3X(-1,1,0,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,0,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
}
// Top-Right
SCALE3X(-1,0,0,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;
for(y=1; y<142; y+=2){
// left
SCALE3X(0,1,-160,160,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
// middle
for(x=1; x<159; x+=2){
SCALE3X(-1,1,-160,160,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,-160,160,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
}
// right
SCALE3X(-1,0,-160,160,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;
memcpy(base,buffer[0],480);
memcpy(base+320,buffer[1],480);
memcpy(base+640,buffer[2],480);
dst=(un16*)buffer;
base += 960;
memset(buffer,0,480*3);
// left
SCALE3X(0,1,-160,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
// middle
for(x=1; x<159; x+=2){
SCALE3X(-1,1,-160,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,-160,160,dst[0],dst[0],dst[1],dst[0],dst[0],dst[1],dst[240],dst[240],dst[241]);
dst++, src++;
}
// right
SCALE3X(-1,0,-160,160,dst[0],dst[1],dst[1],dst[0],dst[1],dst[1],dst[240],dst[241],dst[241]);
dst+=2, src++;
}
// left
SCALE3X(0,1,-160,0,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
// middle
for(x=1; x<159; x+=2){
SCALE3X(-1,1,-160,0,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;
SCALE3X(-1,1,-160,0,dst[0],dst[0],dst[1],dst[240],dst[240],dst[241],dst[240],dst[240],dst[241]);
dst++, src++;
}
// right
SCALE3X(-1,0,-160,0,dst[0],dst[1],dst[1],dst[240],dst[241],dst[241],dst[240],dst[241],dst[241]);
dst+=2, src++;
memcpy(base,buffer[0],480);
memcpy(base+320,buffer[1],480);
memcpy(base+640,buffer[2],480);
}
/*
** Appears to expect source/dest framebuffer pixels to be 16bpp
** But expects source to be in RGB343 format. Looks like it may expect dest to be RGB565.
** 1.5 scaler, i.e. 160x144 -> 239x215 BUT centered/centred in a 320x240 screen.
*/
void ohb_render(){
fb.cc[0].r = screen->format->Rloss+2;
fb.cc[1].r = screen->format->Gloss+2;
fb.cc[2].r = screen->format->Bloss+2;
vid_fb.dirty = 0;
pal_dirty();
un16 *mix, *buf;
un16 *src = (un16*)fb.ptr;
un16 *dst = (un16*)vid_fb.ptr + 3880;
int x,y;
for(y=0; y<144; y+=2){
mix = buffer[0];
for(x=0; x<160; x+=2){
*(dst++) = (*(mix++) = (*src<<1))<<1;
*mix = *(src++);
*(dst++) = (*(mix++) += *src)<<1;
*(dst++) = (*(mix++) = (*(src++)<<1))<<1;
}
dst += 80;
mix = buffer[0];
buf = buffer[1];
for(x=0; x<160; x+=2){
*(dst++) = *(mix++) + ((*(buf++) = (*src<<2))>>1);
*buf = *(src++)<<1;
*(dst++) = *(mix++) + ((*(buf++) += (*src<<1))>>1);
*(dst++) = *(mix++) + ((*(buf++) = (*(src++)<<2))>>1);
}
dst += 80;
memcpy(dst, buffer[1], 480);
dst += 320;
}
}
And also (case 1 y 2):
Code:
void scaler_init(int scaler_number){
switch (upscaler){
case 1: /* 1.5 scaler */
case 2: /* 1.5 scaler with some smoothing ala scale3x / scale2x */
/* RGB343 */
fb.cc[0].r = screen->format->Rloss+2;
fb.cc[1].r = screen->format->Gloss+2;
fb.cc[2].r = screen->format->Bloss+2;
break;
case 3: /* Ayla full screen 320x240 (no aspect ration preservation) */
case 0: /* no scale, that is, native */
default:
/* RGB565 */
fb.cc[0].r = screen->format->Rloss;
fb.cc[1].r = screen->format->Gloss;
fb.cc[2].r = screen->format->Bloss;
//ohb_ayla_dingoo_scale();
break;
}
vid_fb.dirty = 1;
pal_dirty();
}