+static struct Vertex __attribute__((aligned(4))) g_vertices[2];
+static unsigned short __attribute__((aligned(16))) localPal[0x100];
+static int dynamic_palette = 0, need_pal_upload = 0, blit_16bit_mode = 0;
+static int fbimg_offs = 0;
+
+static void set_scaling_params(void)
+{
+ int src_width, fbimg_width, fbimg_height, fbimg_xoffs, fbimg_yoffs;
+ g_vertices[0].x = g_vertices[0].y =
+ g_vertices[0].z = g_vertices[1].z = 0;
+
+ fbimg_height = (int)(240.0 * currentConfig.scale + 0.5);
+ if (Pico.video.reg[12] & 1) {
+ fbimg_width = (int)(320.0 * currentConfig.scale * currentConfig.hscale40 + 0.5);
+ src_width = 320;
+ } else {
+ fbimg_width = (int)(256.0 * currentConfig.scale * currentConfig.hscale32 + 0.5);
+ src_width = 256;
+ }
+
+ if (fbimg_width >= 480) {
+ g_vertices[0].u = (fbimg_width-480)/2;
+ g_vertices[1].u = src_width - (fbimg_width-480)/2;
+ fbimg_width = 480;
+ fbimg_xoffs = 0;
+ } else {
+ g_vertices[0].u = 0;
+ g_vertices[1].u = src_width;
+ fbimg_xoffs = 240 - fbimg_width/2;
+ }
+
+ if (fbimg_height >= 272) {
+ g_vertices[0].v = (fbimg_height-272)/2;
+ g_vertices[1].v = 240 - (fbimg_height-272)/2;
+ fbimg_height = 272;
+ fbimg_yoffs = 0;
+ } else {
+ g_vertices[0].v = 0;
+ g_vertices[1].v = 240;
+ fbimg_yoffs = 136 - fbimg_height/2;
+ }
+
+ g_vertices[1].x = fbimg_width;
+ g_vertices[1].y = fbimg_height;
+ if (fbimg_xoffs < 0) fbimg_xoffs = 0;
+ if (fbimg_yoffs < 0) fbimg_yoffs = 0;
+ fbimg_offs = (fbimg_yoffs*512 + fbimg_xoffs) * 2; // dst is always 16bit
+
+ lprintf("set_scaling_params:\n");
+ lprintf("offs: %i, %i\n", fbimg_xoffs, fbimg_yoffs);
+ lprintf("xy0, xy1: %i, %i; %i, %i\n", g_vertices[0].x, g_vertices[0].y, g_vertices[1].x, g_vertices[1].y);
+ lprintf("uv0, uv1: %i, %i; %i, %i\n", g_vertices[0].u, g_vertices[0].v, g_vertices[1].u, g_vertices[1].v);
+}
+
+static void do_slowmode_pal(void)
+{
+ unsigned int *spal=(void *)Pico.cram;
+ unsigned int *dpal=(void *)localPal;
+ int i;
+
+ for (i = 0x3f/2; i >= 0; i--)
+ dpal[i] = ((spal[i]&0x000f000f)<< 1)|((spal[i]&0x00f000f0)<<3)|((spal[i]&0x0f000f00)<<4);
+
+ if (Pico.video.reg[0xC]&8) // shadow/hilight?
+ {
+ // shadowed pixels
+ for (i = 0x3f/2; i >= 0; i--)
+ dpal[0x20|i] = dpal[0x60|i] = (spal[i]>>1)&0x738e738e;
+ // hilighted pixels
+ for (i = 0x3f; i >= 0; i--) {
+ int t=localPal[i]&0xe71c;t+=0x4208;
+ if (t&0x20) t|=0x1c;
+ if (t&0x800) t|=0x700;
+ if (t&0x10000) t|=0xe000;
+ t&=0xe71c;
+ localPal[0x80|i]=(unsigned short)t;
+ }
+ localPal[0xe0] = 0;
+ }
+ Pico.m.dirtyPal = 0;
+ need_pal_upload = 1;
+}
+
+static void do_slowmode_lines(int line_to)
+{
+ int line = 0, line_len = (Pico.video.reg[12]&1) ? 320 : 256;
+ unsigned short *dst = (unsigned short *)VRAM_STUFF + 512*240/2;
+ unsigned char *src = (unsigned char *)VRAM_CACHED_STUFF + 16;
+ if (!(Pico.video.reg[1]&8)) { line = 8; dst += 512*8; src += 512*8; }
+
+ for (; line < line_to; line++, dst+=512, src+=512)
+ amips_clut(dst, src, localPal, line_len);
+}
+
+static void EmuScanPrepare(void)
+{
+ HighCol = (unsigned char *)VRAM_CACHED_STUFF + 8;
+ if (!(Pico.video.reg[1]&8)) HighCol += 8*512;
+
+ dynamic_palette = 0;
+ if (Pico.m.dirtyPal)
+ do_slowmode_pal();