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();
}
	
	