1 /* FCE Ultra - NES/Famicom Emulator
\r
3 * Copyright notice for this file:
\r
4 * Copyright (C) 2002,2003 Xodnizel
\r
6 * This program is free software; you can redistribute it and/or modify
\r
7 * it under the terms of the GNU General Public License as published by
\r
8 * the Free Software Foundation; either version 2 of the License, or
\r
9 * (at your option) any later version.
\r
11 * This program is distributed in the hope that it will be useful,
\r
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
14 * GNU General Public License for more details.
\r
16 * You should have received a copy of the GNU General Public License
\r
17 * along with this program; if not, write to the Free Software
\r
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
27 #include "general.h"
\r
30 #include "palette.h"
\r
31 #include "palettes/palettes.h"
\r
36 #define M_PI 3.14159265358979323846
\r
39 static int ntsccol=0;
\r
40 static int ntsctint=46+10;
\r
41 static int ntschue=72;
\r
43 /* These are dynamically filled/generated palettes: */
\r
44 pal palettei[64]; // Custom palette for an individual game.
\r
45 pal palettec[64]; // Custom "global" palette.
\r
46 pal paletten[64]; // Mathematically generated palette.
\r
48 static void CalculatePalette(void);
\r
49 static void ChoosePalette(void);
\r
50 static void WritePalette(void);
\r
54 static pal *palpoint[8]=
\r
63 void FCEUI_SetPaletteArray(uint8 *pal)
\r
66 palpoint[0]=palette;
\r
70 palpoint[0]=palettec;
\r
73 palpoint[0][x].r=*((uint8 *)pal+x+x+x);
\r
74 palpoint[0][x].g=*((uint8 *)pal+x+x+x+1);
\r
75 palpoint[0][x].b=*((uint8 *)pal+x+x+x+2);
\r
78 FCEU_ResetPalette();
\r
82 void FCEUI_SetNTSCTH(int n, int tint, int hue)
\r
87 FCEU_ResetPalette();
\r
90 static uint8 lastd=0;
\r
91 void SetNESDeemph(uint8 d, int force)
\r
93 static uint16 rtmul[7]={32768*1.239,32768*.794,32768*1.019,32768*.905,32768*1.023,32768*.741,32768*.75};
\r
94 static uint16 gtmul[7]={32768*.915,32768*1.086,32768*.98,32768*1.026,32768*.908,32768*.987,32768*.75};
\r
95 static uint16 btmul[7]={32768*.743,32768*.882,32768*.653,32768*1.277,32768*.979,32768*.101,32768*.75};
\r
99 /* If it's not forced(only forced when the palette changes),
\r
100 don't waste cpu time if the same deemphasis bits are set as the last call.
\r
107 else /* Only set this when palette has changed. */
\r
113 for(x=0;x<0x40;x++)
\r
125 FCEUD_SetPalette(x|0xC0,m,n,o);
\r
128 if(!d) return; /* No deemphasis, so return. */
\r
134 for(x=0;x<0x40;x++)
\r
148 FCEUD_SetPalette(x|0x40,m,n,o);
\r
154 /* Converted from Kevin Horton's qbasic palette generator. */
\r
155 static void CalculatePalette(void)
\r
159 double s,luma,theta;
\r
160 static uint8 cols[16]={0,24,21,18,15,12,9,6,3,0,33,30,27,0,0,0};
\r
161 static uint8 br1[4]={6,9,12,12};
\r
162 static double br2[4]={.29,.45,.73,.9};
\r
163 static double br3[4]={0,.24,.47,.77};
\r
168 s=(double)ntsctint/128;
\r
170 if(z==0) {s=0;luma=((double)br1[x])/12;}
\r
179 theta=(double)M_PI*(double)(((double)cols[z]*10+ (((double)ntschue/2)+300) )/(double)180);
\r
180 r=(int)((luma+s*sin(theta))*256);
\r
181 g=(int)((luma-(double)27/53*s*sin(theta)+(double)10/53*s*cos(theta))*256);
\r
182 b=(int)((luma-s*cos(theta))*256);
\r
192 paletten[(x<<4)+z].r=r;
\r
193 paletten[(x<<4)+z].g=g;
\r
194 paletten[(x<<4)+z].b=b;
\r
199 static int ipalette=0;
\r
201 void FCEU_LoadGamePalette(void)
\r
209 fn=FCEU_MakeFName(FCEUMKF_PALETTE,0,0);
\r
211 if((fp=fopen(fn,"rb")))
\r
214 fread(ptmp,1,192,fp);
\r
218 palettei[x].r=ptmp[x+x+x];
\r
219 palettei[x].g=ptmp[x+x+x+1];
\r
220 palettei[x].b=ptmp[x+x+x+2];
\r
227 void FCEU_ResetPalette(void)
\r
236 static void ChoosePalette(void)
\r
238 if(FCEUGameInfo.type==GIT_NSF)
\r
242 else if(ntsccol && !PAL && FCEUGameInfo.type!=GIT_VSUNI)
\r
245 CalculatePalette();
\r
248 palo=palpoint[pale];
\r
251 void WritePalette(void)
\r
256 FCEUD_SetPalette(x,unvpalette[x].r,unvpalette[x].g,unvpalette[x].b);
\r
257 if(FCEUGameInfo.type==GIT_NSF)
\r
259 //for(x=0;x<128;x++)
\r
260 // FCEUD_SetPalette(x,x,0,x);
\r
265 FCEUD_SetPalette(x+128,palo[x].r,palo[x].g,palo[x].b);
\r
266 SetNESDeemph(lastd,1);
\r
270 void FCEUI_GetNTSCTH(int *tint, int *hue)
\r
276 static int controlselect=0;
\r
277 static int controllength=0;
\r
279 void FCEUI_NTSCDEC(void)
\r
281 if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI &&!PAL && FCEUGameInfo.type!=GIT_NSF)
\r
288 which=controlselect==1?ntschue:ntsctint;
\r
290 if(which<0) which=0;
\r
291 if(controlselect==1)
\r
293 else ntsctint=which;
\r
294 CalculatePalette();
\r
301 void FCEUI_NTSCINC(void)
\r
303 if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI && !PAL && FCEUGameInfo.type!=GIT_NSF)
\r
308 switch(controlselect)
\r
311 if(ntschue>128) ntschue=128;
\r
312 CalculatePalette();
\r
315 if(ntsctint>128) ntsctint=128;
\r
316 CalculatePalette();
\r
324 void FCEUI_NTSCSELHUE(void)
\r
326 if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI && !PAL && FCEUGameInfo.type!=GIT_NSF){controlselect=1;controllength=360;}
\r
329 void FCEUI_NTSCSELTINT(void)
\r
331 if(ntsccol && FCEUGameInfo.type!=GIT_VSUNI && !PAL && FCEUGameInfo.type!=GIT_NSF){controlselect=2;controllength=360;}
\r
334 void FCEU_DrawNTSCControlBars(uint8 *XBuf)
\r
340 if(!controllength) return;
\r
344 if(controlselect==1)
\r
346 DrawTextTrans(XBuf+128-12+180*256, 256, (uint8 *)"Hue", 0x85);
\r
349 else if(controlselect==2)
\r
351 DrawTextTrans(XBuf+128-16+180*256, 256, (uint8 *)"Tint", 0x85);
\r
356 for(x=0;x<which;x+=2)
\r
358 for(x2=6;x2>=-6;x2--)
\r
360 XBaf[x-256*x2]=0x85;
\r
365 for(x2=2;x2>=-2;x2--)
\r
366 XBaf[x-256*x2]=0x85;
\r