support for Famicom 3D System games (thanks Carl Kenner!)

This commit is contained in:
dborth 2010-12-26 23:44:46 +00:00
parent d49a820ded
commit 789eeaf38e
7 changed files with 507 additions and 20 deletions

View File

@ -7,7 +7,7 @@
¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤
FCE Ultra GX is a modified port of the FCE Ultra Nintendo Entertainment
system for x86 (Windows/Linux) PC's. With it you can play NES games on your
system for x86 (Windows/Linux) PCs. With it you can play NES games on your
Wii/GameCube.
-=[ Features ]=-
@ -24,14 +24,19 @@ Wii/GameCube.
* Original/filtered/unfiltered video modes
* Turbo Mode - up to 2x the normal speed
* Cheat support (.CHT files and Game Genie)
* Famicom 3D System support
* IPS/UPS automatic patching support
* NES Compatibility Based on FCEUX 2.1.3
* NES Compatibility Based on FCEUX 2.1.4
* Open Source!
×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬
|0O×øo· UPDATE HISTORY ·oø×O0|
`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨'
[3.2.4]
* Support for Famicom 3D System games (thanks Carl Kenner!)
[3.2.3 - October 7, 2010]
* Sync with upstream SVN - fixes a few specific game issues
@ -402,11 +407,12 @@ Wii
On the Wii, you can load roms from SD card (Front SD or SD Gecko), USB, DVD,
or SMB share. Note that if you are using the Homebrew Channel, to load from
USB, DVD, or SMB you will first have to load FCEUGX from SD, and then set
your load method preference. To load roms from a Windows network share (SMB)
you will have to edit FCEUGX.xml on your SD card with your network settings,
or edit fceuconfig.cpp from the source code and compile. If you edit and compile
the source, you can use wiiload and the Homebrew Channel to load and play
FCEUGX completely over the network, without needing an SD card.
your load method preference.
If you are planning to use your Network (LAN) to load and/or save games from
you will need to enter in the SMB share settings you haveve setup on your
computer via the Settings menu. You will need to enter in the SMB Share IP,
Share Name, Share Username and Share Password.
Gamecube
------------
@ -423,6 +429,20 @@ can be changed under Controller Configuration ('Special' button).
Compatibility is limited, so check that the game in question works on
FCE Ultra 0.98.12 for Windows before asking for help.
-=[ 3D Game Support ]=-
Supported Famicom 3D System games:
* Highway Star
* Famicom Grand Prix II
* 3D Hot Rally
* JJ (Tobidase Daisakusen Part 2)
* Cosmic Epsilon
* Attack Animal Gakuen
Supported anaglyph games:
* The 3-D Battles of World Runner (Tobidase Daisakusen)
* Rad Racer
-[ Emulator Options ]-
Palette - The colors used while viewing the game:

View File

@ -44,6 +44,9 @@
#include "fceultra/types.h"
void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count);
void FCEUD_UpdatePulfrich(uint8 *XBuf, int32 *Buffer, int Count);
void FCEUD_UpdateLeft(uint8 *XBuf, int32 *Buffer, int Count);
void FCEUD_UpdateRight(uint8 *XBuf, int32 *Buffer, int Count);
extern "C" {
extern void __exception_setreload(int t);
@ -309,6 +312,141 @@ void USBGeckoOutput()
devoptab_list[STD_ERR] = &gecko_out;
}
//CAK: We need to know the OUT1 pin of the expansion port for Famicom 3D System glasses
extern uint8 shutter_3d;
//CAK: We need to know the palette in RAM for red/cyan anaglyph 3D games (3D World Runner and Rad Racer)
extern uint8 PALRAM[0x20];
bool shutter_3d_mode, anaglyph_3d_mode, eye_3d;
bool old_shutter_3d_mode = 0, old_anaglyph_3d_mode = 0;
uint8 prev_shutter_3d = 0, prev_prev_shutter_3d = 0;
uint8 pal_3d = 0, prev_pal_3d = 0, prev_prev_pal_3d = 0;
bool CheckForAnaglyphPalette()
{
//CAK: It can also have none of these when all blacks
bool hasRed = false, hasCyan = false, hasOther = false;
pal_3d = 0;
//CAK: first 12 background colours are used for anaglyph (last 4 are for status bar)
for (int i = 0; i < 12; i++)
{
switch (PALRAM[i] & 63)
{
case 0x00:
case 0x0F: //CAK: blacks
break;
case 0x01:
case 0x11:
case 0x0A:
case 0x1A:
case 0x0C:
case 0x1C:
case 0x2C: //CAK: cyan
hasCyan = true;
break;
case 0x05:
case 0x15:
case 0x06:
case 0x16: //CAK: reds
hasRed = true;
break;
default:
hasOther = true;
}
}
if (hasOther || (hasRed && hasCyan))
return false;
//CAK: last 8 sprite colours are used for anaglyph (first 8 are for screen-level sprites)
for (int i = 24; i < 32; i++)
{
switch (PALRAM[i] & 63)
{
case 0x00:
case 0x0F: //CAK: blacks
break;
case 0x01:
case 0x11:
case 0x0A:
case 0x1A:
case 0x0C:
case 0x1C:
case 0x2c: //CAK: cyan
hasCyan = true;
break;
case 0x05:
case 0x15:
case 0x06:
case 0x16: //CAK: reds
hasRed = true;
break;
default:
hasOther = true;
}
}
if (hasOther || (hasRed && hasCyan) || (!hasRed && !hasCyan))
return false;
eye_3d = hasCyan;
if (hasCyan)
pal_3d = 2;
else
pal_3d = 1;
return true;
}
//CAK: Handles automatically entering and exiting stereoscopic 3D mode, and detecting which eye to draw
void Check3D()
{
//CAK: Stereoscopic 3D game mode detection
shutter_3d_mode = (shutter_3d != prev_shutter_3d && shutter_3d == prev_prev_shutter_3d);
prev_prev_shutter_3d = prev_shutter_3d;
prev_shutter_3d = shutter_3d;
if (shutter_3d_mode)
{
fskip = 0;
eye_3d = !shutter_3d;
}
else if (old_shutter_3d_mode)
{
//CAK: exited stereoscopic 3d mode, reset frameskip to 0
fskip = 0;
fskipc = 0;
frameskip = 0;
}
else
{
//CAK: Only check anaglyph when it's not a Famicom 3D System game
//Games are detected as anaglyph, only when they alternate between a very limited red palette
//and a very limited blue/green palette. It's very unlikely other games will do that, but
//not impossible.
anaglyph_3d_mode = CheckForAnaglyphPalette() && pal_3d != prev_pal_3d && pal_3d == prev_prev_pal_3d && prev_pal_3d != 0;
prev_prev_pal_3d = prev_pal_3d;
prev_pal_3d = pal_3d;
if (anaglyph_3d_mode)
{
fskip = 0;
}
else if (old_anaglyph_3d_mode)
{
//CAK: exited stereoscopic 3d mode, reset frameskip to 0
fskip = 0;
fskipc = 0;
frameskip = 0;
}
//CAK: TODO: make a backup of palette whenever not in anaglyph mode,
//and use it to override anaglyph's horible palette for full colour 3D
//note the difficulty will be that palette entries get rearranged to
//animate the road and will still need to be rearranged in our backup palette
}
old_shutter_3d_mode = shutter_3d_mode;
old_anaglyph_3d_mode = anaglyph_3d_mode;
}
/****************************************************************************
* main
* This is where it all happens!
@ -316,6 +454,7 @@ void USBGeckoOutput()
int main(int argc, char *argv[])
{
#ifdef HW_RVL
u32 ios = IOS_GetVersion();
if(!SupportedIOS(ios))
@ -325,7 +464,8 @@ int main(int argc, char *argv[])
if(SupportedIOS(preferred))
IOS_ReloadIOS(preferred);
}
#endif
//USBGeckoOutput(); // uncomment to enable USB gecko output
__exception_setreload(8);
@ -454,8 +594,18 @@ int main(int argc, char *argv[])
}
}
//CAK: Currently this is designed to be used before the frame is emulated
Check3D();
FCEUI_Emulate(&gfx, &sound, &ssize, fskip);
FCEUD_Update(gfx, sound, ssize);
if (!shutter_3d_mode && !anaglyph_3d_mode)
FCEUD_Update(gfx, sound, ssize);
else if (eye_3d)
FCEUD_UpdateRight(gfx, sound, ssize);
else
FCEUD_UpdateLeft(gfx, sound, ssize);
SyncSpeed();
if(ResetRequested)

View File

@ -71,6 +71,7 @@ extern INPUTCFC *FCEU_InitFamilyTrainerB(void);
extern INPUTCFC *FCEU_InitOekaKids(void);
extern INPUTCFC *FCEU_InitTopRider(void);
extern INPUTCFC *FCEU_InitBarcodeWorld(void);
extern INPUTCFC *FCEU_InitFamicom3D(void);
//---------------
//global lag variables
@ -406,7 +407,7 @@ static void SetInputStuffFC()
switch(portFC.type)
{
case SIFC_NONE:
portFC.driver=&DummyPortFC;
portFC.driver=FCEU_InitFamicom3D(); //CAK: originally this used &DummyPortFC;
break;
case SIFC_ARKANOID:
portFC.driver=FCEU_InitArkanoidFC();

View File

@ -0,0 +1,42 @@
/****************************************************************************
* This file handles the Stereoscopic 3D shutter-glasses of Famicom 3D System
* They worked the way a modern 3D TV works, but at a much lower refresh rate
* All we do here is set a global variable to the state of the OUT1 pin
****************************************************************************/
/* FCE Ultra - NES/Famicom Emulator
*
* Copyright notice for this file:
* Copyright (C) 2010 Carl Kenner
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "share.h"
uint8 shutter_3d;
static void Write(uint8 V)
{
shutter_3d = (V >> 1) & 1;
}
static INPUTCFC Famicom3D={0,Write,0,0,0,0};
INPUTCFC *FCEU_InitFamicom3D(void)
{
return(&Famicom3D);
}

View File

@ -78,6 +78,48 @@ void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int32 Count)
GetJoy(); // check controller input
}
//CAK: Stereoscopic 3D Update functions
//CAK: This buffer saves the previous frame (usually the left eye)
// so it can be mixed with the current frame (usually the right eye)
uint8 XBufLeft[256*256];
//CAK: This uses the previous frame for the right eye, and the current frame for the left eye
// It then sets the previous frame to the current frame. This is only for the Orb-3D game, and hasn't
// been tested yet. Probably more than one frame difference will be needed, which requires a circluar
// buffer of several frames.
void FCEUD_UpdatePulfrich(uint8 *XBuf, int32 *Buffer, int32 Count)
{
if(Buffer && Count > 0)
PlaySound(Buffer, Count); // play sound
if(XBuf) {
RenderStereoFrames(XBuf, XBufLeft); // output video frame
memcpy(XBufLeft, XBuf, sizeof(XBufLeft)); // output video frame
}
GetJoy(); // check controller input
}
//CAK: This doesn't actually draw anything, it just saves the frame in a buffer while we wait
// for the corresponding right frame.
void FCEUD_UpdateLeft(uint8 *XBuf, int32 *Buffer, int32 Count)
{
if (Buffer && Count > 0)
PlaySound(Buffer, Count); // play sound
if (XBuf)
memcpy(XBufLeft, XBuf, sizeof(XBufLeft)); // output video frame
GetJoy(); // check controller input
}
//CAK: This draws the saved left frame and the passed in right frame together in 3D.
// How it so isn't relevant to this function, since the stereoscopic methods are handled in gcvideo.cpp
void FCEUD_UpdateRight(uint8 *XBuf, int32 *Buffer, int32 Count)
{
if (Buffer && Count > 0)
PlaySound(Buffer, Count); // play sound
if (XBuf)
RenderStereoFrames(XBufLeft, XBuf); // output video frames
GetJoy(); // check controller input
}
// Netplay
int FCEUD_SendData(void *data, uint32 len)
{

View File

@ -72,10 +72,15 @@ struct pcpal {
static unsigned int gcpalette[256]; // Much simpler GC palette
static unsigned short rgb565[256]; // Texture map palette
bool AnaglyphPaletteValid = false; //CAK: Has the anaglyph palette below been generated yet?
static unsigned short anaglyph565[64][64]; //CAK: Texture map left right combination anaglyph palette
static void GenerateAnaglyphPalette(); //CAK: function prototype for generating the anaglyph palette
static long long prev;
static long long now;
extern bool shutter_3d_mode, anaglyph_3d_mode; //CAK: only used for the SyncSpeed function because 3D is 30Hz
/* New texture based scaler */
typedef struct tagcamera
{
@ -208,8 +213,12 @@ void setFrameTimer()
void SyncSpeed()
{
if((vmode_60hz && normaldiff == 16667) || (!vmode_60hz && normaldiff == 20000))
return; // same timing as game - no adjustment necessary
// same timing as game - no adjustment necessary
if((vmode_60hz && normaldiff == 16667) || (!vmode_60hz && normaldiff == 20000))
if (!shutter_3d_mode && !anaglyph_3d_mode) return; //CAK: But don't exit if in a 30/25Hz 3D mode.
//CAK: Note that the 3D modes (except Pulfrich) still call this function at 60/50Hz, but half the
// time there is no video rendering to go with it, so we need some delays.
now = gettime();
u32 diff = diff_usec(prev, now);
@ -220,7 +229,7 @@ void SyncSpeed()
}
else if (diff > normaldiff)
{
frameskip++;
frameskip++; //CAK: In 3D this will be ignored, then reset to 0 when leaving 3D
}
else // ahead, so hold up
{
@ -767,6 +776,132 @@ void RenderFrame(unsigned char *XBuf)
LWP_ResumeThread (vbthread);
}
/****************************************************************************
* RenderFrame
*
* Render a single frame
****************************************************************************/
void RenderStereoFrames(unsigned char *XBufLeft, unsigned char *XBufRight)
{
// Ensure previous vb has complete
while ((LWP_ThreadIsSuspended (vbthread) == 0) || (copynow == GX_TRUE))
usleep (50);
// swap framebuffers
whichfb ^= 1;
// video has changed
if(UpdateVideo)
{
UpdateVideo = 0;
ResetVideo_Emu(); // reset video to emulator rendering settings
}
//CAK: May need to regenerate the anaglyph 3D palette that is used below
if (!AnaglyphPaletteValid)
GenerateAnaglyphPalette();
int width, height;
u8 borderheight = 0;
u8 borderwidth = 0;
// 0 = off, 1 = vertical, 2 = horizontal, 3 = both
if(GCSettings.hideoverscan == 1 || GCSettings.hideoverscan == 3)
borderheight = 8;
if(GCSettings.hideoverscan >= 2)
borderwidth = 8;
u16 *texture = (unsigned short *)texturemem + (borderheight << 8) + (borderwidth << 2);
u8 *Lsrc1 = XBufLeft + (borderheight << 8) + borderwidth;
u8 *Lsrc2 = XBufLeft + (borderheight << 8) + borderwidth + 256;
u8 *Lsrc3 = XBufLeft + (borderheight << 8) + borderwidth + 512;
u8 *Lsrc4 = XBufLeft + (borderheight << 8) + borderwidth + 768;
u8 *Rsrc1 = XBufRight + (borderheight << 8) + borderwidth;
u8 *Rsrc2 = XBufRight + (borderheight << 8) + borderwidth + 256;
u8 *Rsrc3 = XBufRight + (borderheight << 8) + borderwidth + 512;
u8 *Rsrc4 = XBufRight + (borderheight << 8) + borderwidth + 768;
// fill the texture with red/cyan anaglyph
for (height = 0; height < 240 - (borderheight << 1); height += 4)
{
for (width = 0; width < 256 - (borderwidth << 1); width += 4)
{
// Row one
*texture++ = anaglyph565[(*Lsrc1++) & 63][(*Rsrc1++) & 63];
*texture++ = anaglyph565[(*Lsrc1++) & 63][(*Rsrc1++) & 63];
*texture++ = anaglyph565[(*Lsrc1++) & 63][(*Rsrc1++) & 63];
*texture++ = anaglyph565[(*Lsrc1++) & 63][(*Rsrc1++) & 63];
// Row two
*texture++ = anaglyph565[(*Lsrc2++) & 63][(*Rsrc2++) & 63];
*texture++ = anaglyph565[(*Lsrc2++) & 63][(*Rsrc2++) & 63];
*texture++ = anaglyph565[(*Lsrc2++) & 63][(*Rsrc2++) & 63];
*texture++ = anaglyph565[(*Lsrc2++) & 63][(*Rsrc2++) & 63];
// Row three
*texture++ = anaglyph565[(*Lsrc3++) & 63][(*Rsrc3++) & 63];
*texture++ = anaglyph565[(*Lsrc3++) & 63][(*Rsrc3++) & 63];
*texture++ = anaglyph565[(*Lsrc3++) & 63][(*Rsrc3++) & 63];
*texture++ = anaglyph565[(*Lsrc3++) & 63][(*Rsrc3++) & 63];
// Row four
*texture++ = anaglyph565[(*Lsrc4++) & 63][(*Rsrc4++) & 63];
*texture++ = anaglyph565[(*Lsrc4++) & 63][(*Rsrc4++) & 63];
*texture++ = anaglyph565[(*Lsrc4++) & 63][(*Rsrc4++) & 63];
*texture++ = anaglyph565[(*Lsrc4++) & 63][(*Rsrc4++) & 63];
}
Lsrc1 += 768 + (borderwidth << 1); // line 4*N
Lsrc2 += 768 + (borderwidth << 1); // line 4*(N+1)
Lsrc3 += 768 + (borderwidth << 1); // line 4*(N+2)
Lsrc4 += 768 + (borderwidth << 1); // line 4*(N+3)
Rsrc1 += 768 + (borderwidth << 1); // line 4*N
Rsrc2 += 768 + (borderwidth << 1); // line 4*(N+1)
Rsrc3 += 768 + (borderwidth << 1); // line 4*(N+2)
Rsrc4 += 768 + (borderwidth << 1); // line 4*(N+3)
texture += (borderwidth << 3);
}
// load texture into GX
DCFlushRange(texturemem, TEX_WIDTH * TEX_HEIGHT * 4);
// clear texture objects
GX_InvalidateTexAll();
// render textured quad
draw_square(view);
GX_DrawDone();
if(ScreenshotRequested)
{
if(GCSettings.render == 0) // we can't take a screenshot in Original mode
{
oldRenderMode = 0;
GCSettings.render = 2; // switch to unfiltered mode
UpdateVideo = 1; // request the switch
}
else
{
ScreenshotRequested = 0;
TakeScreenshot();
if(oldRenderMode != -1)
{
GCSettings.render = oldRenderMode;
oldRenderMode = -1;
}
ConfigRequested = 1;
}
}
// EFB is ready to be copied into XFB
VIDEO_SetNextFramebuffer(xfb[whichfb]);
VIDEO_Flush();
copynow = GX_TRUE;
// Return to caller, don't waste time waiting for vb
LWP_ResumeThread (vbthread);
}
/****************************************************************************
* TakeScreenshot
*
@ -953,14 +1088,107 @@ void Menu_DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 f
GX_End();
}
static void OptimisedAnaglyph(u8 *r, u8 *g, u8 *b, u8 lr, u8 lg, u8 lb, u8 rr, u8 rg, u8 rb)
{
// The left eye needs to see a bit of every colour mixed into the red channel
// otherwise it will have trouble matching it to the right eye.
// the left eye also needs to be brighter.
int ar = (lr * 600 + lg * 300 + lb * 200) / 1000;
if (ar > 255)
ar = 255;
*r = ar;
int ag = (rg * 700 + rr * 200) / 1000;
if (ag > 255)
ag = 255;
*g = ag;
*b = rb;
}
#if 0
//CAK: This 3D palette is for high contrast white on black games like Falsion
static void RedBlueMonoAnaglyph(u8 *r, u8 *g, u8 *b, u8 lr, u8 lg, u8 lb, u8 rr, u8 rg, u8 rb)
{
// The left eye needs to see a bit of every colour mixed into the red channel
// otherwise it will have trouble matching it to the right eye.
// the left eye also needs to be brighter.
int ar = (lr * 300 + lg * 500 + lb * 200) / 1000;
if (ar > 255)
ar = 255;
*r = ar;
*g = 0;
int ab = (rr * 300 + rg * 500 + rb * 200) / 1000;
if (ab > 255)
ab = 255;
*b = ab;
}
//CAK: This 3D palette is for high contrast white on black games like Falsion
static void RedGreenMonoAnaglyph(u8 *r, u8 *g, u8 *b, u8 lr, u8 lg, u8 lb, u8 rr, u8 rg, u8 rb)
{
// The left eye needs to see a bit of every colour mixed into the red channel
// otherwise it will have trouble matching it to the right eye.
// the left eye also needs to be brighter.
int ar = (lr * 300 + lg * 500 + lb * 200) / 1000;
if (ar > 255)
ar = 255;
*r = ar;
int ab = (rr * 300 + rg * 500 + rb * 200) / 1000;
if (ab > 255)
ab = 255;
*g = ab;
*b = 0;
}
//CAK: This 3D palette is for high contrast white on black games like Falsion
static void RedCyanMonoAnaglyph(u8 *r, u8 *g, u8 *b, u8 lr, u8 lg, u8 lb, u8 rr, u8 rg, u8 rb)
{
// The left eye needs to see a bit of every colour mixed into the red channel
// otherwise it will have trouble matching it to the right eye.
// the left eye also needs to be brighter.
int ar = (lr * 300 + lg * 500 + lb * 200) / 1000;
if (ar > 255)
ar = 255;
*r = ar;
int ab = (rr * 300 + rg * 500 + rb * 200) / 2000;
if (ab > 255)
ab = 255;
*g = ab;
*b = ab;
}
//CAK: This 3D palette is good for games which were already in anaglyph
static void FullColourAnaglyph(u8 *r, u8 *g, u8 *b, u8 lr, u8 lg, u8 lb, u8 rr, u8 rg, u8 rb)
{
// The left eye needs to see a bit of every colour mixed into the red channel
// otherwise it will have trouble matching it to the right eye.
// the left eye also needs to be brighter.
*r = lr;
*g = rg;
*b = rb;
}
#endif
//CAK: Create an RGB 565 colour (used in textures) for this stereoscopic 3D combination of 2 NES colours.
static void GenerateAnaglyphPalette()
{
for (int left = 0; left < 64; left++)
{
for (int right = 0; right < 64; right++)
{
u8 ar, ag, ab;
OptimisedAnaglyph(&ar, &ag, &ab, pcpalette[left].r, pcpalette[left].g, pcpalette[left].b, pcpalette[right].r, pcpalette[right].g, pcpalette[right].b);
anaglyph565[left][right] = ((ar & 0xf8) << 8) | ((ag & 0xfc) << 3) | ((ab & 0xf8) >> 3);
}
}
AnaglyphPaletteValid = true;
}
/****************************************************************************
* rgbcolor
*
* Support routine for gcpalette
****************************************************************************/
static unsigned int rgbcolor(unsigned char r1, unsigned char g1, unsigned char b1,
unsigned char r2, unsigned char g2, unsigned char b2) {
static unsigned int rgbcolor(u8 r1, u8 g1, u8 b1, u8 r2, u8 g2, u8 b2)
{
int y1,cb1,cr1,y2,cb2,cr2,cb,cr;
y1=(299*r1+587*g1+114*b1)/1000;
@ -983,8 +1211,8 @@ static unsigned int rgbcolor(unsigned char r1, unsigned char g1, unsigned char b
* A shadow copy of the palette is maintained, in case the NES Emu kernel
* requests a copy.
****************************************************************************/
void FCEUD_SetPalette(unsigned char index, unsigned char r, unsigned char g,
unsigned char b) {
void FCEUD_SetPalette(u8 index, u8 r, u8 g, u8 b)
{
/*** Make PC compatible copy ***/
pcpalette[index].r = r;
pcpalette[index].g = g;
@ -997,13 +1225,16 @@ void FCEUD_SetPalette(unsigned char index, unsigned char r, unsigned char g,
rgb565[index] = ((r & 0xf8) << 8) |
((g & 0xfc) << 3) |
((b & 0xf8) >> 3);
/*** Will need to generate stereoscopic palette later. ***/
AnaglyphPaletteValid = false;
}
/****************************************************************************
* GetPalette
****************************************************************************/
void FCEUD_GetPalette(unsigned char i, unsigned char *r, unsigned char *g,
unsigned char *b) {
void FCEUD_GetPalette(u8 i, u8 *r, u8 *g, u8 *b)
{
*r = pcpalette[i].r;
*g = pcpalette[i].g;
*b = pcpalette[i].b;
@ -1019,7 +1250,7 @@ void SetPalette()
else
{
// Now setup this palette
unsigned char i,r,g,b;
u8 i,r,g,b;
for ( i = 0; i < 64; i++ )
{

View File

@ -24,6 +24,7 @@ void InitGCVideo ();
void StopGX();
void ResetVideo_Emu ();
void RenderFrame(unsigned char *XBuf);
void RenderStereoFrames(unsigned char *XBufLeft, unsigned char *XBufRight); //CAK: Stereoscopic 3D
void setFrameTimer();
void SyncSpeed();
void SetPalette();