mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
[Core/VDP]
* improved sprites processing accuracy. * fixed VBLANK transition line checks. * code cleanup and (minor) optimizations. [Core/Sound] * increased FM internal sample size to 32-bit to avoid overflow when adding channels. * added preliminary emulation of YM2612 DAC precision (can be configured to match real console output). * added configurable roll-off for FIR filtering in High-Quality FM mode. [Wii] *added support to enable/disable Video Encoder Trap Filter: can help reproducing "color blending" as on a real Genesis (composite video only). *added support to configure Video Encoder gamma correction.
This commit is contained in:
parent
62b3cce887
commit
ed11eb0133
28
HISTORY.txt
28
HISTORY.txt
@ -10,23 +10,25 @@ of samples per frame and keeping PSG & FM chips in sync.
|
||||
* improved PSG & FM chips synchronization with CPU execution (fixed point precision).
|
||||
* improved YM2612 core general accuracy (SSG-EG, CSM mode,...) (based upon Nemesis recent tests on real hardware)
|
||||
* improved YM2612 LFO emulation accuracy: fixes "Spider-Man & Venom : Separation Anxiety" (intro)
|
||||
* fixed YM2612 bug with Timer B: fixes "Langrisser Hikari II"/"Der Langrisser II" (Sega logo)
|
||||
* fixed YM2612 context saving/loading.
|
||||
* fixed YM2612 state upon reset.
|
||||
* removed outdated Gens YM2612 core
|
||||
* added faster FIR resampler (thanks to Blargg & AamirM), dropped libsamplerate support.
|
||||
* fixed YM2612 state on reset.
|
||||
* removed outdated & less accurate Gens YM2612 core
|
||||
* added preliminar emulation of YM2612 DAC original resolution (configurable).
|
||||
* added configurable & faster FIR resampler (thanks to Blargg & AamirM), dropped libsamplerate support.
|
||||
* added configurable Low-Pass filtering
|
||||
* added 3-Band Equalizer to support fully configurable sound filtering (thanks to Neil C).
|
||||
* added an option to boost SN76489 Noise Channel.
|
||||
* added configurable 3-Band Equalizer (thanks to Neil C).
|
||||
* added support for SN76489 Noise Channel boost (optional).
|
||||
* modified SN76489 cut-off frequency.
|
||||
|
||||
[Core/VDP]
|
||||
---------------
|
||||
* added support for CRAM writes during horizontal blanking.
|
||||
* added support for 2-Cell vertical scrolling in Interlaced 2 mode (unused by games ?)
|
||||
* fixed 2-Cell vertical scrolling when column 0 is shifted.
|
||||
* added support for CRAM writes during horizontal blanking (Striker, Zero the Kamikaze Squirrel,...)
|
||||
* added support for 2-Cell vertical scrolling in Interlaced 2 mode
|
||||
* fixed VBLANK transition line checks
|
||||
* improved sprite masking accuracy (thanks to Nemesis for his sprite test program)
|
||||
* improved HBLANK flag timing accuracy: fixes Mega Turrican (Sky level)
|
||||
* improved sprites processing timing accuracy: fixes (un)masked sprites in Mickey Mania (3D level), Sonic 2 (VS mode).
|
||||
* improved sprites processing accuracy: fixes (un)masked sprites in Mickey Mania (3D level), Sonic 2 (VS mode).
|
||||
* improved horizontal blanking & HINT/VINT occurence timing accuracy, as measured on real hardware.
|
||||
* improved H-Counter accuracy in 40-cell mode, as measured on real hardware.
|
||||
* improved color accuracy in VDP highlight mode to match results observed on real hardware.
|
||||
@ -54,14 +56,14 @@ of samples per frame and keeping PSG & FM chips in sync.
|
||||
|
||||
[Gamecube/Wii]
|
||||
---------------
|
||||
* new! FONT engine (using internal IPL font & GX hardware rendering).
|
||||
* new! GUI engine (with PCM/OGG sound support, using GX hardware rendering & multithreading).
|
||||
* new! interface design (incl. IR pointing, game snapshots, visual & sound effects, BGM...).
|
||||
* implemented new FONT engine (using internal IPL font & GX hardware rendering).
|
||||
* implemented custom GUI engine (with PCM/OGG sound support, multithreading & using GX hardware for rendering)
|
||||
* new interface design (incl. IR pointing, game snapshots, visual & sound effects, BGM...).
|
||||
* improved audio/video back-end synchronization to ensure 100% smooth video & audio playback.
|
||||
* improved reset button behavior, now works more like the real Genesis reset button.
|
||||
* improved lightgun cursors layout.
|
||||
* fixed stability issues and memory leaks.
|
||||
* compiled with Devkitpro/PPC r18 and last libogc/libfat (support for SDHC, new DVDX, etc)
|
||||
* compiled with devkitPPC r19 & libOGC 1.8.1 (SDHC support, new DVDX, etc)
|
||||
|
||||
|
||||
|
||||
|
@ -87,7 +87,8 @@ static inline void lightgun_update(int num)
|
||||
if (io_reg[5] & 0x80)
|
||||
{
|
||||
/* External Interrupt ? */
|
||||
if (reg[11] & 0x08) irq_status = (irq_status & ~0x40) | 0x12;
|
||||
if (reg[11] & 0x08)
|
||||
irq_status = (irq_status & ~0x40) | 0x12;
|
||||
|
||||
/* Horizontal Counter Latch:
|
||||
1) some games does not set HVC latch but instead use bigger X offset
|
||||
|
@ -48,7 +48,8 @@ void config_load(void)
|
||||
char version[16];
|
||||
fread(version, 16, 1, fp);
|
||||
fclose(fp);
|
||||
if (strcmp(version,VERSION)) return;
|
||||
if (strcmp(version,VERSION))
|
||||
return;
|
||||
|
||||
/* read file */
|
||||
fp = fopen(fname, "rb");
|
||||
@ -77,6 +78,8 @@ void config_default(void)
|
||||
config.lg = 1.0;
|
||||
config.mg = 1.0;
|
||||
config.hg = 1.0;
|
||||
config.rolloff = 0.995;
|
||||
config.dac_bits = 14;
|
||||
|
||||
/* system options */
|
||||
config.region_detect = 0;
|
||||
@ -100,6 +103,10 @@ void config_default(void)
|
||||
config.render = 0;
|
||||
config.ntsc = 0;
|
||||
config.bilinear = 1;
|
||||
#ifdef HW_RVL
|
||||
config.trap = 1;
|
||||
config.gamma = VI_GM_1_0 / 10.0;
|
||||
#endif
|
||||
|
||||
/* controllers options */
|
||||
config.gun_cursor[0] = 1;
|
||||
|
@ -42,6 +42,8 @@ typedef struct
|
||||
float lg;
|
||||
float mg;
|
||||
float hg;
|
||||
float rolloff;
|
||||
uint8 dac_bits;
|
||||
uint8 region_detect;
|
||||
uint8 force_dtack;
|
||||
uint8 addr_error;
|
||||
@ -59,6 +61,10 @@ typedef struct
|
||||
uint8 render;
|
||||
uint8 ntsc;
|
||||
uint8 bilinear;
|
||||
#ifdef HW_RVL
|
||||
uint8 trap;
|
||||
float gamma;
|
||||
#endif
|
||||
uint8 gun_cursor[2];
|
||||
uint8 invert_mouse;
|
||||
uint16 pad_keymap[4][MAX_KEYS];
|
||||
|
@ -1278,8 +1278,8 @@ void GUI_OptionBox(gui_menu *parent, optioncallback cb, char *title, void *optio
|
||||
else
|
||||
{
|
||||
/* float type */
|
||||
if (*(float *)option < 0.0) sprintf(msg,"-%1.2f",fabs(*(float *)option));
|
||||
else sprintf(msg,"%1.2f",fabs(*(float *)option));
|
||||
if (*(float *)option < 0.0) sprintf(msg,"-%1.3f",fabs(*(float *)option));
|
||||
else sprintf(msg,"%1.3f",fabs(*(float *)option));
|
||||
}
|
||||
|
||||
/* draw option text */
|
||||
|
@ -216,22 +216,24 @@ static gui_item items_options[5] =
|
||||
{NULL,Option_menu_png ,"","Menu settings", 370,286,60,92}
|
||||
};
|
||||
|
||||
/* Audio options menu */
|
||||
static gui_item items_audio[10] =
|
||||
/* Audio options */
|
||||
static gui_item items_audio[12] =
|
||||
{
|
||||
{NULL,NULL,"High-Quality FM: LINEAR", "Setup YM2612 resampling", 52,132,276,48},
|
||||
{NULL,NULL,"PSG Noise Boost: OFF", "Boost PSG Noise Channel", 52,132,276,48},
|
||||
{NULL,NULL,"PSG Volume: 2.50", "Adjust SN76489 output level", 52,132,276,48},
|
||||
{NULL,NULL,"FM Volume: 1.00", "Adjust YM2612 output level", 52,132,276,48},
|
||||
{NULL,NULL,"Filtering: 3-BAND EQ", "Setup Audio filtering", 52,132,276,48},
|
||||
{NULL,NULL,"Low Gain: 1.00", "Adjust EQ Low Band Gain", 52,132,276,48},
|
||||
{NULL,NULL,"Mid Gain: 1.00", "Adjust EQ Middle Band Gain", 52,132,276,48},
|
||||
{NULL,NULL,"High Gain: 1.00", "Adjust EQ High BandGain", 52,132,276,48},
|
||||
{NULL,NULL,"Low Freq: 200 Hz", "Adjust EQ Low Band Frequency", 52,132,276,48},
|
||||
{NULL,NULL,"High Freq: 20000 Hz", "Adjust EQ High Band Frequency",52,132,276,48}
|
||||
{NULL,NULL,"High-Quality FM: ON", "Enable/disable YM2612 resampling", 52,132,276,48},
|
||||
{NULL,NULL,"FM Roll-off: 0.999", "Adjust FIR low-pass filtering", 52,132,276,48},
|
||||
{NULL,NULL,"FM Resolution: MAX", "Adjust YM2612 DAC precision", 52,132,276,48},
|
||||
{NULL,NULL,"FM Volume: 1.00", "Adjust YM2612 output level", 52,132,276,48},
|
||||
{NULL,NULL,"PSG Volume: 2.50", "Adjust SN76489 output level", 52,132,276,48},
|
||||
{NULL,NULL,"PSG Noise Boost: OFF", "Boost SN76489 Noise Channel", 52,132,276,48},
|
||||
{NULL,NULL,"Filtering: 3-BAND EQ", "Setup Audio filtering", 52,132,276,48},
|
||||
{NULL,NULL,"Low Gain: 1.00", "Adjust EQ Low Band Gain", 52,132,276,48},
|
||||
{NULL,NULL,"Mid Gain: 1.00", "Adjust EQ Mid Band Gain", 52,132,276,48},
|
||||
{NULL,NULL,"High Gain: 1.00", "Adjust EQ High BandGain", 52,132,276,48},
|
||||
{NULL,NULL,"Low Freq: 200 Hz", "Adjust EQ Lowest Frequency", 52,132,276,48},
|
||||
{NULL,NULL,"High Freq: 20000 Hz", "Adjust EQ Highest Frequency", 52,132,276,48}
|
||||
};
|
||||
|
||||
/* System options menu */
|
||||
/* System options */
|
||||
static gui_item items_system[7] =
|
||||
{
|
||||
{NULL,NULL,"Console Region: AUTO", "Select system region", 52,132,276,48},
|
||||
@ -243,20 +245,28 @@ static gui_item items_system[7] =
|
||||
{NULL,NULL,"SVP Cycles: 1500", "Adjust SVP chip emulation speed", 52,132,276,48}
|
||||
};
|
||||
|
||||
/* Video options menu */
|
||||
/* Video options */
|
||||
#ifdef HW_RVL
|
||||
static gui_item items_video[10] =
|
||||
#else
|
||||
static gui_item items_video[8] =
|
||||
#endif
|
||||
{
|
||||
{NULL,NULL,"Display: PROGRESSIVE", "Select video mode type", 52,132,276,48},
|
||||
{NULL,NULL,"TV mode: 50/60Hz", "Select video refresh rate", 52,132,276,48},
|
||||
{NULL,NULL,"Bilinear Filter: OFF", "Enable/disable hardware filtering", 52,132,276,48},
|
||||
{NULL,NULL,"NTSC Filter: COMPOSITE", "Enable/disable NTSC software filtering", 52,132,276,48},
|
||||
{NULL,NULL,"Borders: OFF", "Enable/disable original overscan emulation",52,132,276,48},
|
||||
{NULL,NULL,"Aspect: ORIGINAL (4:3)", "Select display aspect ratio", 52,132,276,48},
|
||||
{NULL,NULL,"Screen Position (+0,+0)", "Adjust display position", 52,132,276,48},
|
||||
{NULL,NULL,"Screen Size (+0,+0)", "Adjust display size", 52,132,276,48}
|
||||
{NULL,NULL,"Display: PROGRESSIVE", "Select video signal type", 52,132,276,48},
|
||||
{NULL,NULL,"TV mode: 50/60Hz", "Select video signal frequency", 52,132,276,48},
|
||||
{NULL,NULL,"GX Bilinear Filter: OFF", "Enable/disable texture hardware filtering", 52,132,276,48},
|
||||
#ifdef HW_RVL
|
||||
{NULL,NULL,"VI Trap Filter: ON", "Enable/disable video hardware filtering", 52,132,276,48},
|
||||
{NULL,NULL,"VI Gamma Correction: 1.0","Adjust video hardware gamma correction", 52,132,276,48},
|
||||
#endif
|
||||
{NULL,NULL,"NTSC Filter: COMPOSITE", "Enable/disable NTSC software filtering", 52,132,276,48},
|
||||
{NULL,NULL,"Borders: OFF", "Enable/disable overscan emulation", 52,132,276,48},
|
||||
{NULL,NULL,"Aspect: ORIGINAL (4:3)", "Select display aspect ratio", 52,132,276,48},
|
||||
{NULL,NULL,"Screen Position (+0,+0)", "Adjust display position", 52,132,276,48},
|
||||
{NULL,NULL,"Screen Scaling (+0,+0)", "Adjust display scaling", 52,132,276,48}
|
||||
};
|
||||
|
||||
/* Preferences menu */
|
||||
/* Menu options */
|
||||
static gui_item items_prefs[7] =
|
||||
{
|
||||
{NULL,NULL,"Auto SRAM: OFF", "Enable/disable automatic SRAM", 52,132,276,48},
|
||||
@ -265,7 +275,7 @@ static gui_item items_prefs[7] =
|
||||
{NULL,NULL,"BGM Volume: 100", "Adjust background music volume", 52,132,276,48},
|
||||
{NULL,NULL,"BG Color: DEFAULT", "Change background color", 52,132,276,48},
|
||||
{NULL,NULL,"Screen Width: 658", "Adjust Screen Width", 52,132,276,48},
|
||||
{NULL,NULL,"Confirmation Box: OFF", "Enable/disable user confirmation", 52,132,276,48}
|
||||
{NULL,NULL,"Confirm Box: OFF", "Enable/disable user confirmation", 52,132,276,48}
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
@ -436,7 +446,7 @@ static gui_menu menu_audio =
|
||||
{
|
||||
"Audio Settings",
|
||||
0,0,
|
||||
10,4,6,0,
|
||||
8,4,6,0,
|
||||
items_audio,
|
||||
buttons_list,
|
||||
bg_list,
|
||||
@ -688,61 +698,146 @@ static void prefmenu ()
|
||||
* Audio Settings menu
|
||||
*
|
||||
****************************************************************************/
|
||||
static void soundmenu ()
|
||||
static int update_snd_items(void)
|
||||
{
|
||||
int ret, quit = 0;
|
||||
gui_menu *m = &menu_audio;
|
||||
gui_item *items = m->items;
|
||||
float psg_volume = (float)config.psg_preamp/100.0;
|
||||
int offset;
|
||||
float fm_volume = (float)config.fm_preamp/100.0;
|
||||
float psg_volume = (float)config.psg_preamp/100.0;
|
||||
|
||||
if (config.hq_fm)
|
||||
{
|
||||
sprintf (items[0].text, "High-Quality FM: ON");
|
||||
sprintf (items[1].text, "FM Roll-off: %1.3f",config.rolloff);
|
||||
strcpy (items[1].comment, "Adjust FIR low-pass filtering");
|
||||
offset = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (items[0].text, "High-Quality FM: OFF");
|
||||
offset = 1;
|
||||
}
|
||||
|
||||
strcpy(items[offset].comment, "Adjust YM2612 DAC precision");
|
||||
strcpy(items[offset+1].comment, "Adjust YM2612 output level");
|
||||
strcpy(items[offset+2].comment, "Adjust SN76489 output level");
|
||||
strcpy(items[offset+3].comment, "Boost SN76489 Noise Channel");
|
||||
strcpy(items[offset+4].comment, "Configure Audio filtering");
|
||||
|
||||
if (config.dac_bits < 14)
|
||||
sprintf (items[offset].text, "FM Resolution: %d bits", config.dac_bits);
|
||||
else
|
||||
sprintf (items[offset].text, "FM Resolution: MAX");
|
||||
|
||||
sprintf (items[offset+1].text, "FM Volume: %1.2f", fm_volume);
|
||||
sprintf (items[offset+2].text, "PSG Volume: %1.2f", psg_volume);
|
||||
sprintf (items[offset+3].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF");
|
||||
|
||||
sprintf (items[0].text, "High-Quality FM: %s", config.hq_fm ? "ON":"OFF");
|
||||
sprintf (items[1].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF");
|
||||
sprintf (items[2].text, "PSG Volume: %1.2f", psg_volume);
|
||||
sprintf (items[3].text, "FM Volume: %1.2f", (double)config.fm_preamp/100.0);
|
||||
if (config.filter == 2) sprintf (items[4].text, "Filtering: 3-BAND EQ");
|
||||
else if (config.filter == 1) sprintf (items[4].text, "Filtering: LOW PASS");
|
||||
else sprintf (items[4].text, "Filtering: OFF");
|
||||
if (config.filter == 2)
|
||||
{
|
||||
sprintf (items[5].text, "Low Gain: %1.2f", config.lg);
|
||||
strcpy (items[5].comment, "Adjust EQ Low Band Gain");
|
||||
sprintf (items[6].text, "Middle Gain: %1.2f", config.mg);
|
||||
sprintf (items[7].text, "High Gain: %1.2f", config.hg);
|
||||
sprintf (items[8].text, "Low Freq: %d", config.low_freq);
|
||||
sprintf (items[9].text, "High Freq: %d", config.high_freq);
|
||||
sprintf (items[offset+4].text, "Filtering: 3-BAND EQ");
|
||||
sprintf (items[offset+5].text, "Low Gain: %1.2f", config.lg);
|
||||
sprintf (items[offset+6].text, "Middle Gain: %1.2f", config.mg);
|
||||
sprintf (items[offset+7].text, "High Gain: %1.2f", config.hg);
|
||||
sprintf (items[offset+8].text, "Low Freq: %d", config.low_freq);
|
||||
sprintf (items[offset+9].text, "High Freq: %d", config.high_freq);
|
||||
strcpy (items[offset+5].comment, "Adjust EQ Low Band Gain");
|
||||
strcpy (items[offset+6].comment, "Adjust EQ Mid Band Gain");
|
||||
strcpy (items[offset+7].comment, "Adjust EQ High Band Gain");
|
||||
strcpy (items[offset+8].comment, "Adjust EQ Lowest Frequency");
|
||||
strcpy (items[offset+9].comment, "Adjust EQ Highest Frequency");
|
||||
m->max_items = offset + 10;
|
||||
}
|
||||
else if (config.filter == 1)
|
||||
{
|
||||
sprintf (items[5].text, "Low-Pass Rate: %d %%", config.lp_range);
|
||||
strcpy (items[5].comment, "Adjust Low Pass filter");
|
||||
sprintf (items[offset+4].text, "Filtering: LOW-PASS");
|
||||
sprintf (items[offset+5].text, "Low-Pass Rate: %d %%", config.lp_range);
|
||||
strcpy (items[offset+5].comment, "Adjust Low Pass filter");
|
||||
m->max_items = offset + 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (items[offset+4].text, "Filtering: OFF");
|
||||
m->max_items = offset + 5;
|
||||
}
|
||||
|
||||
sprintf (items[offset+6].text, "Middle Gain: %1.2f", config.mg);
|
||||
sprintf (items[offset+7].text, "High Gain: %1.2f", config.hg);
|
||||
sprintf (items[offset+8].text, "Low Freq: %d", config.low_freq);
|
||||
sprintf (items[offset+9].text, "High Freq: %d", config.high_freq);
|
||||
strcpy (items[offset+5].comment, "Adjust EQ Low Band Gain");
|
||||
strcpy (items[offset+6].comment, "Adjust EQ Mid Band Gain");
|
||||
strcpy (items[offset+7].comment, "Adjust EQ High Band Gain");
|
||||
strcpy (items[offset+8].comment, "Adjust EQ Lowest Frequency");
|
||||
strcpy (items[offset+9].comment, "Adjust EQ Highest Frequency");
|
||||
|
||||
return offset;
|
||||
}
|
||||
|
||||
static void soundmenu ()
|
||||
{
|
||||
int ret, quit = 0;
|
||||
u8 *temp;
|
||||
gui_menu *m = &menu_audio;
|
||||
gui_item *items = m->items;
|
||||
float fm_volume = (float)config.fm_preamp/100.0;
|
||||
float psg_volume = (float)config.psg_preamp/100.0;
|
||||
int offset = update_snd_items();
|
||||
GUI_InitMenu(m);
|
||||
|
||||
if (config.filter == 1)
|
||||
m->max_items = 6;
|
||||
else if (config.filter == 2)
|
||||
m->max_items = 10;
|
||||
else
|
||||
m->max_items = 5;
|
||||
|
||||
GUI_SlideMenuTitle(m,strlen("Audio "));
|
||||
|
||||
while (quit == 0)
|
||||
{
|
||||
ret = GUI_RunMenu(m);
|
||||
|
||||
/* special case */
|
||||
if (config.hq_fm)
|
||||
{
|
||||
if (ret == 1)
|
||||
{
|
||||
GUI_OptionBox(m,0,"FM Roll-off",(void *)&config.rolloff,0.001,0.800,1.000,0);
|
||||
sprintf (items[1].text, "FM Roll-off: %1.3f",config.rolloff);
|
||||
ret = 255;
|
||||
if (cart.romsize)
|
||||
{
|
||||
/* save YM2612 context */
|
||||
temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp)
|
||||
{
|
||||
/* save YM2612 context */
|
||||
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
|
||||
/* reinitialize audio timings */
|
||||
audio_init(snd.sample_rate,snd.frame_rate);
|
||||
sound_init();
|
||||
|
||||
/* restore YM2612 context */
|
||||
YM2612Restore(temp);
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (ret > 1)
|
||||
{
|
||||
ret--;
|
||||
}
|
||||
}
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
config.hq_fm ^= 1;
|
||||
sprintf (items[0].text, "High-Quality FM: %s", config.hq_fm ? "ON":"OFF");
|
||||
offset = update_snd_items();
|
||||
|
||||
if (cart.romsize)
|
||||
{
|
||||
/* save YM2612 context */
|
||||
unsigned char *temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp) memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp)
|
||||
{
|
||||
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
}
|
||||
|
||||
/* reinitialize audio timings */
|
||||
audio_init(snd.sample_rate,snd.frame_rate);
|
||||
@ -758,92 +853,119 @@ static void soundmenu ()
|
||||
break;
|
||||
|
||||
case 1:
|
||||
config.psgBoostNoise ^= 1;
|
||||
sprintf (items[1].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF");
|
||||
SN76489_BoostNoise(config.psgBoostNoise);
|
||||
config.dac_bits++;
|
||||
if (config.dac_bits > 14)
|
||||
config.dac_bits = 7;
|
||||
if (config.dac_bits < 14)
|
||||
sprintf (items[offset].text, "FM Resolution: %d bits", config.dac_bits);
|
||||
else
|
||||
sprintf (items[offset].text, "FM Resolution: MAX");
|
||||
|
||||
if (cart.romsize)
|
||||
{
|
||||
/* save YM2612 context */
|
||||
temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp)
|
||||
{
|
||||
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
}
|
||||
|
||||
/* reinitialize audio timings */
|
||||
audio_init(snd.sample_rate,snd.frame_rate);
|
||||
sound_init();
|
||||
|
||||
/* restore YM2612 context */
|
||||
if (temp)
|
||||
{
|
||||
YM2612Restore(temp);
|
||||
free(temp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
GUI_OptionBox(m,0,"PSG Volume",(void *)&psg_volume,0.01,0.0,5.0,0);
|
||||
sprintf (items[2].text, "PSG Volume: %1.2f", psg_volume);
|
||||
config.psg_preamp = (int)(psg_volume * 100.0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
GUI_OptionBox(m,0,"FM Volume",(void *)&fm_volume,0.01,0.0,5.0,0);
|
||||
sprintf (items[3].text, "FM Volume: %1.2f", fm_volume);
|
||||
sprintf (items[offset+1].text, "FM Volume: %1.2f", fm_volume);
|
||||
config.fm_preamp = (int)(fm_volume * 100.0);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
GUI_OptionBox(m,0,"PSG Volume",(void *)&psg_volume,0.01,0.0,5.0,0);
|
||||
sprintf (items[offset+2].text, "PSG Volume: %1.2f", psg_volume);
|
||||
config.psg_preamp = (int)(psg_volume * 100.0);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
config.filter ++;
|
||||
if (config.filter > 2) config.filter = 0;
|
||||
if (config.filter == 2)
|
||||
{
|
||||
m->max_items = 10;
|
||||
sprintf (items[4].text, "Filtering: 3-BAND EQ");
|
||||
sprintf (items[5].text, "Low Gain: %1.2f", config.lg);
|
||||
strcpy (items[5].comment, "Adjust EQ Low Band Gain");
|
||||
sprintf (items[6].text, "Middle Gain: %1.2f", config.mg);
|
||||
sprintf (items[7].text, "High Gain: %1.2f", config.hg);
|
||||
sprintf (items[8].text, "Low Freq: %d", config.low_freq);
|
||||
sprintf (items[9].text, "High Freq: %d", config.high_freq);
|
||||
}
|
||||
else if (config.filter == 1)
|
||||
{
|
||||
m->max_items = 6;
|
||||
sprintf (items[4].text, "Filtering: LOW PASS");
|
||||
sprintf (items[5].text, "Low-Pass Rate: %d %%", config.lp_range);
|
||||
strcpy (items[5].comment, "Adjust Low Pass filter");
|
||||
}
|
||||
else
|
||||
{
|
||||
sprintf (items[4].text, "Filtering: OFF");
|
||||
m->max_items = 5;
|
||||
m->offset = 1;
|
||||
m->selected = 3;
|
||||
}
|
||||
|
||||
/* reintialize EQ */
|
||||
audio_set_equalizer();
|
||||
|
||||
config.psgBoostNoise ^= 1;
|
||||
sprintf (items[offset+3].text, "PSG Noise Boost: %s", config.psgBoostNoise ? "ON":"OFF");
|
||||
SN76489_BoostNoise(config.psgBoostNoise);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (config.filter == 1)
|
||||
config.filter = (config.filter + 1) % 3;
|
||||
if (config.filter == 2)
|
||||
{
|
||||
GUI_OptionBox(m,0,"Low-Pass Rate",(void *)&config.lp_range,1,0,100,1);
|
||||
sprintf (items[5].text, "Low-Pass Rate: %d %%", config.lp_range);
|
||||
sprintf (items[offset+4].text, "Filtering: 3-BAND EQ");
|
||||
sprintf (items[offset+5].text, "Low Gain: %1.2f", config.lg);
|
||||
strcpy (items[offset+5].comment, "Adjust EQ Low Band Gain");
|
||||
m->max_items = offset + 10;
|
||||
audio_set_equalizer();
|
||||
}
|
||||
else if (config.filter == 1)
|
||||
{
|
||||
sprintf (items[offset+4].text, "Filtering: LOW-PASS");
|
||||
sprintf (items[offset+5].text, "Low-Pass Rate: %d %%", config.lp_range);
|
||||
strcpy (items[offset+5].comment, "Adjust Low Pass filter");
|
||||
m->max_items = offset + 6;
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI_OptionBox(m,0,"Low Gain",(void *)&config.lg,0.01,0.0,2.0,0);
|
||||
sprintf (items[5].text, "Low Gain: %1.2f", config.lg);
|
||||
audio_set_equalizer();
|
||||
sprintf (items[offset+4].text, "Filtering: OFF");
|
||||
m->max_items = offset + 5;
|
||||
}
|
||||
|
||||
while ((m->offset + 4) > m->max_items)
|
||||
{
|
||||
m->offset --;
|
||||
m->selected++;
|
||||
}
|
||||
break;
|
||||
|
||||
case 6:
|
||||
GUI_OptionBox(m,0,"Middle Gain",(void *)&config.mg,0.01,0.0,2.0,0);
|
||||
sprintf (items[6].text, "Middle Gain: %1.2f", config.mg);
|
||||
audio_set_equalizer();
|
||||
if (config.filter == 1)
|
||||
{
|
||||
GUI_OptionBox(m,0,"Low-Pass Rate",(void *)&config.lp_range,1,0,100,1);
|
||||
sprintf (items[offset+5].text, "Low-Pass Rate: %d %%", config.lp_range);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI_OptionBox(m,0,"Low Gain",(void *)&config.lg,0.01,0.0,2.0,0);
|
||||
sprintf (items[offset+5].text, "Low Gain: %1.2f", config.lg);
|
||||
audio_set_equalizer();
|
||||
}
|
||||
break;
|
||||
|
||||
case 7:
|
||||
GUI_OptionBox(m,0,"High Gain",(void *)&config.hg,0.01,0.0,2.0,0);
|
||||
sprintf (items[7].text, "High Gain: %1.2f", config.hg);
|
||||
GUI_OptionBox(m,0,"Middle Gain",(void *)&config.mg,0.01,0.0,2.0,0);
|
||||
sprintf (items[offset+6].text, "Middle Gain: %1.2f", config.mg);
|
||||
audio_set_equalizer();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
GUI_OptionBox(m,0,"Low Frequency",(void *)&config.low_freq,10,0,config.high_freq,1);
|
||||
sprintf (items[8].text, "Low Freq: %d", config.low_freq);
|
||||
GUI_OptionBox(m,0,"High Gain",(void *)&config.hg,0.01,0.0,2.0,0);
|
||||
sprintf (items[offset+7].text, "High Gain: %1.2f", config.hg);
|
||||
audio_set_equalizer();
|
||||
break;
|
||||
|
||||
case 9:
|
||||
GUI_OptionBox(m,0,"Low Frequency",(void *)&config.low_freq,10,0,config.high_freq,1);
|
||||
sprintf (items[offset+8].text, "Low Freq: %d", config.low_freq);
|
||||
audio_set_equalizer();
|
||||
break;
|
||||
|
||||
case 10:
|
||||
GUI_OptionBox(m,0,"High Frequency",(void *)&config.high_freq,100,config.low_freq,30000,1);
|
||||
sprintf (items[9].text, "High Freq: %d", config.high_freq);
|
||||
sprintf (items[offset+9].text, "High Freq: %d", config.high_freq);
|
||||
audio_set_equalizer();
|
||||
break;
|
||||
|
||||
@ -853,7 +975,6 @@ static void soundmenu ()
|
||||
}
|
||||
}
|
||||
|
||||
m->max_items = 10;
|
||||
GUI_DeleteMenu(m);
|
||||
}
|
||||
|
||||
@ -863,8 +984,9 @@ static void soundmenu ()
|
||||
****************************************************************************/
|
||||
static void systemmenu ()
|
||||
{
|
||||
int ret = 255;
|
||||
int quit = 0;
|
||||
int ret, quit = 0;
|
||||
float framerate;
|
||||
u8 *temp;
|
||||
gui_menu *m = &menu_system;
|
||||
gui_item *items = m->items;
|
||||
|
||||
@ -900,7 +1022,6 @@ static void systemmenu ()
|
||||
else
|
||||
{
|
||||
m->max_items = 6;
|
||||
if (m->offset > 2) m->offset--;
|
||||
}
|
||||
|
||||
GUI_InitMenu(m);
|
||||
@ -914,7 +1035,6 @@ static void systemmenu ()
|
||||
{
|
||||
case 0: /*** Region Force ***/
|
||||
config.region_detect = (config.region_detect + 1) % 4;
|
||||
|
||||
if (config.region_detect == 0)
|
||||
sprintf (items[0].text, "Console Region: AUTO");
|
||||
else if (config.region_detect == 1)
|
||||
@ -930,14 +1050,13 @@ static void systemmenu ()
|
||||
set_region();
|
||||
|
||||
/* update framerate */
|
||||
float framerate;
|
||||
if (vdp_pal)
|
||||
framerate = 50.0;
|
||||
else
|
||||
framerate = ((config.tv_mode == 0) || (config.tv_mode == 2)) ? (1000000.0/16715.0) : 60.0;
|
||||
|
||||
/* save YM2612 context */
|
||||
unsigned char *temp = memalign(32,YM2612GetContextSize());
|
||||
temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp)
|
||||
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
|
||||
@ -1000,7 +1119,6 @@ static void systemmenu ()
|
||||
sprintf (items[4].text, "Lock-On: SONIC & KNUCKLES");
|
||||
else
|
||||
sprintf (items[4].text, "Lock-On: OFF");
|
||||
|
||||
if (cart.romsize)
|
||||
{
|
||||
system_reset(); /* clear any patches first */
|
||||
@ -1015,7 +1133,7 @@ static void systemmenu ()
|
||||
sprintf (items[5].text, "Cartridge Swap: %s", config.hot_swap ? "ON":"OFF");
|
||||
break;
|
||||
|
||||
case 6: /*** SVP emulation ***/
|
||||
case 6: /*** SVP cycles per line ***/
|
||||
GUI_OptionBox(m,0,"SVP Cycles",(void *)&SVP_cycles,1,1,1500,1);
|
||||
sprintf (items[6].text, "SVP Cycles: %d", SVP_cycles);
|
||||
break;
|
||||
@ -1033,10 +1151,23 @@ static void systemmenu ()
|
||||
* Video Settings menu
|
||||
*
|
||||
****************************************************************************/
|
||||
#ifdef HW_RVL
|
||||
#define VI_OFFSET 5
|
||||
static void update_gamma(void)
|
||||
{
|
||||
VIDEO_SetGamma((int)(config.gamma * 10.0));
|
||||
VIDEO_Flush();
|
||||
}
|
||||
#else
|
||||
#define VI_OFFSET 3
|
||||
#endif
|
||||
|
||||
static void videomenu ()
|
||||
{
|
||||
u16 state[2];
|
||||
int ret, quit = 0;
|
||||
float framerate;
|
||||
u8 *temp;
|
||||
gui_menu *m = &menu_video;
|
||||
gui_item *items = m->items;
|
||||
|
||||
@ -1054,40 +1185,45 @@ static void videomenu ()
|
||||
else
|
||||
sprintf (items[1].text, "TV Mode: 50/60HZ");
|
||||
|
||||
sprintf (items[2].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
sprintf (items[2].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
|
||||
#ifdef HW_RVL
|
||||
sprintf (items[3].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF");
|
||||
sprintf (items[4].text, "VI Gamma Correction: %1.1f", config.gamma);
|
||||
#endif
|
||||
|
||||
if (config.ntsc == 1)
|
||||
sprintf (items[3].text, "NTSC Filter: COMPOSITE");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: COMPOSITE");
|
||||
else if (config.ntsc == 2)
|
||||
sprintf (items[3].text, "NTSC Filter: S-VIDEO");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: S-VIDEO");
|
||||
else if (config.ntsc == 3)
|
||||
sprintf (items[3].text, "NTSC Filter: RGB");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: RGB");
|
||||
else
|
||||
sprintf (items[3].text, "NTSC Filter: OFF");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF");
|
||||
|
||||
sprintf (items[4].text, "Borders: %s", config.overscan ? "ON" : "OFF");
|
||||
sprintf (items[VI_OFFSET+1].text, "Borders: %s", config.overscan ? "ON" : "OFF");
|
||||
|
||||
if (config.aspect == 1)
|
||||
sprintf (items[5].text,"Aspect: ORIGINAL (4:3)");
|
||||
sprintf (items[VI_OFFSET+2].text,"Aspect: ORIGINAL (4:3)");
|
||||
else if (config.aspect == 2)
|
||||
sprintf (items[5].text, "Aspect: ORIGINAL (16:9)");
|
||||
sprintf (items[VI_OFFSET+2].text, "Aspect: ORIGINAL (16:9)");
|
||||
else
|
||||
sprintf (items[5].text, "Aspect: SCALE");
|
||||
sprintf (items[VI_OFFSET+2].text, "Aspect: MANUAL SCALE");
|
||||
|
||||
sprintf (items[6].text, "Screen Position: (%s%02d,%s%02d)",
|
||||
sprintf (items[VI_OFFSET+3].text, "Screen Position: (%s%02d,%s%02d)",
|
||||
(config.xshift < 0) ? "":"+", config.xshift,
|
||||
(config.yshift < 0) ? "":"+", config.yshift);
|
||||
sprintf (items[7].text, "Screen Scaling: (%s%02d,%s%02d)",
|
||||
|
||||
sprintf (items[VI_OFFSET+4].text, "Screen Scaling: (%s%02d,%s%02d)",
|
||||
(config.xscale < 0) ? "":"+", config.xscale,
|
||||
(config.yscale < 0) ? "":"+", config.yscale);
|
||||
|
||||
GUI_InitMenu(m);
|
||||
|
||||
if (config.aspect)
|
||||
m->max_items = 7;
|
||||
m->max_items = VI_OFFSET+4;
|
||||
else
|
||||
m->max_items = 8;
|
||||
m->max_items = VI_OFFSET+5;
|
||||
|
||||
GUI_InitMenu(m);
|
||||
GUI_SlideMenuTitle(m,strlen("Video "));
|
||||
|
||||
while (quit == 0)
|
||||
@ -1126,14 +1262,13 @@ static void videomenu ()
|
||||
config.tv_mode = (config.tv_mode + 1) % 3;
|
||||
|
||||
/* update framerate */
|
||||
float framerate;
|
||||
if (vdp_pal)
|
||||
framerate = 50.0;
|
||||
else
|
||||
framerate = ((config.tv_mode == 0) || (config.tv_mode == 2)) ? (1000000.0/16715.0) : 60.0;
|
||||
|
||||
/* save YM2612 context */
|
||||
unsigned char *temp = memalign(32,YM2612GetContextSize());
|
||||
temp = memalign(32,YM2612GetContextSize());
|
||||
if (temp)
|
||||
memcpy(temp, YM2612GetContextPtr(), YM2612GetContextSize());
|
||||
|
||||
@ -1161,58 +1296,94 @@ static void videomenu ()
|
||||
}
|
||||
break;
|
||||
|
||||
case 2: /*** bilinear filtering ***/
|
||||
case 2: /*** GX Texture filtering ***/
|
||||
config.bilinear ^= 1;
|
||||
sprintf (items[2].text, "Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
sprintf (items[2].text, "GX Bilinear Filter: %s", config.bilinear ? " ON" : "OFF");
|
||||
break;
|
||||
|
||||
case 3: /*** NTSC filter ***/
|
||||
#ifdef HW_RVL
|
||||
case 3: /*** VIDEO Trap filtering ***/
|
||||
config.trap ^= 1;
|
||||
sprintf (items[3].text, "VI Trap Filter: %s", config.trap ? " ON" : "OFF");
|
||||
break;
|
||||
|
||||
case 4: /*** VIDEO Gamma correction ***/
|
||||
if (cart.romsize)
|
||||
{
|
||||
update_gamma();
|
||||
state[0] = m->arrows[0]->state;
|
||||
state[1] = m->arrows[1]->state;
|
||||
m->max_buttons = 0;
|
||||
m->max_images = 0;
|
||||
m->arrows[0]->state = 0;
|
||||
m->arrows[1]->state = 0;
|
||||
m->screenshot = 255;
|
||||
strcpy(m->title,"");
|
||||
GUI_OptionBox(m,update_gamma,"VI Gamma Correction",(void *)&config.gamma,0.1,0.1,3.0,0);
|
||||
m->max_buttons = 4;
|
||||
m->max_images = 6;
|
||||
m->arrows[0]->state = state[0];
|
||||
m->arrows[1]->state = state[1];
|
||||
m->screenshot = 0;
|
||||
strcpy(m->title,"Video Settings");
|
||||
sprintf (items[4].text, "VI Gamma Correction: %1.1f", config.gamma);
|
||||
VIDEO_SetGamma(VI_GM_1_0);
|
||||
VIDEO_Flush();
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI_WaitPrompt("Error","Please load a game first !\n");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
case VI_OFFSET: /*** NTSC filter ***/
|
||||
config.ntsc = (config.ntsc + 1) % 4;
|
||||
if (config.ntsc == 1)
|
||||
sprintf (items[3].text, "NTSC Filter: COMPOSITE");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: COMPOSITE");
|
||||
else if (config.ntsc == 2)
|
||||
sprintf (items[3].text, "NTSC Filter: S-VIDEO");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: S-VIDEO");
|
||||
else if (config.ntsc == 3)
|
||||
sprintf (items[3].text, "NTSC Filter: RGB");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: RGB");
|
||||
else
|
||||
sprintf (items[3].text, "NTSC Filter: OFF");
|
||||
sprintf (items[VI_OFFSET].text, "NTSC Filter: OFF");
|
||||
break;
|
||||
|
||||
case 4: /*** overscan emulation ***/
|
||||
case VI_OFFSET+1: /*** overscan emulation ***/
|
||||
config.overscan ^= 1;
|
||||
sprintf (items[4].text, "Borders: %s", config.overscan ? "ON" : "OFF");
|
||||
sprintf (items[VI_OFFSET+1].text, "Borders: %s", config.overscan ? "ON" : "OFF");
|
||||
break;
|
||||
|
||||
case 5: /*** aspect ratio ***/
|
||||
case VI_OFFSET+2: /*** aspect ratio ***/
|
||||
config.aspect = (config.aspect + 1) % 3;
|
||||
if (config.aspect == 1)
|
||||
sprintf (items[5].text,"Aspect: ORIGINAL (4:3)");
|
||||
sprintf (items[VI_OFFSET+2].text,"Aspect: ORIGINAL (4:3)");
|
||||
else if (config.aspect == 2)
|
||||
sprintf (items[5].text, "Aspect: ORIGINAL (16:9)");
|
||||
sprintf (items[VI_OFFSET+2].text, "Aspect: ORIGINAL (16:9)");
|
||||
else
|
||||
sprintf (items[5].text, "Aspect: SCALED");
|
||||
sprintf (items[VI_OFFSET+2].text, "Aspect: MANUAL SCALE");
|
||||
|
||||
if (config.aspect)
|
||||
{
|
||||
/* disable items */
|
||||
m->max_items = 7;
|
||||
m->max_items = VI_OFFSET+4;
|
||||
|
||||
/* reset menu selection */
|
||||
if (m->offset > 3)
|
||||
if (m->offset > VI_OFFSET)
|
||||
{
|
||||
m->offset = 3;
|
||||
m->offset = VI_OFFSET;
|
||||
m->selected = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* enable items */
|
||||
m->max_items = 8;
|
||||
m->max_items = VI_OFFSET+5;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 6: /*** screen position ***/
|
||||
case VI_OFFSET+3: /*** screen position ***/
|
||||
if (cart.romsize)
|
||||
{
|
||||
state[0] = m->arrows[0]->state;
|
||||
@ -1230,7 +1401,7 @@ static void videomenu ()
|
||||
m->arrows[1]->state = state[1];
|
||||
m->screenshot = 0;
|
||||
strcpy(m->title,"Video Settings");
|
||||
sprintf (items[6].text, "Screen Position: (%s%02d,%s%02d)",
|
||||
sprintf (items[VI_OFFSET+3].text, "Screen Position: (%s%02d,%s%02d)",
|
||||
(config.xshift < 0) ? "":"+", config.xshift,
|
||||
(config.yshift < 0) ? "":"+", config.yshift);
|
||||
}
|
||||
@ -1240,7 +1411,7 @@ static void videomenu ()
|
||||
}
|
||||
break;
|
||||
|
||||
case 7: /*** screen scaling ***/
|
||||
case VI_OFFSET+4: /*** screen scaling ***/
|
||||
if (cart.romsize)
|
||||
{
|
||||
state[0] = m->arrows[0]->state;
|
||||
@ -1258,7 +1429,7 @@ static void videomenu ()
|
||||
m->arrows[1]->state = state[1];
|
||||
m->screenshot = 0;
|
||||
strcpy(m->title,"Video Settings");
|
||||
sprintf (items[7].text, "Screen Scaling: (%s%02d,%s%02d)",
|
||||
sprintf (items[VI_OFFSET+4].text, "Screen Scaling: (%s%02d,%s%02d)",
|
||||
(config.xscale < 0) ? "":"+", config.xscale,
|
||||
(config.yscale < 0) ? "":"+", config.yscale);
|
||||
}
|
||||
@ -1274,7 +1445,6 @@ static void videomenu ()
|
||||
}
|
||||
}
|
||||
|
||||
m->max_items = 8;
|
||||
GUI_DeleteMenu(m);
|
||||
}
|
||||
|
||||
@ -1548,7 +1718,7 @@ static void ctrlmenu(void)
|
||||
m->buttons[9].shift[3] = 0;
|
||||
|
||||
/* update title */
|
||||
strcpy(m->title,"Controller Settings");
|
||||
sprintf(m->title,"Controller Settings");
|
||||
}
|
||||
break;
|
||||
|
||||
@ -1600,7 +1770,7 @@ static void ctrlmenu(void)
|
||||
m->buttons[9].shift[3] = 0;
|
||||
|
||||
/* update title */
|
||||
strcpy(m->title,"Controller Settings");
|
||||
sprintf(m->title,"Controller Settings");
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1900,6 +2070,9 @@ static void ctrlmenu(void)
|
||||
/* update selector */
|
||||
m->selected -= m->buttons[m->selected].shift[2];
|
||||
|
||||
/* restore title */
|
||||
sprintf(m->title,"Controller Settings");
|
||||
|
||||
/* stay in menu */
|
||||
update = 0;
|
||||
}
|
||||
@ -1960,9 +2133,6 @@ static void ctrlmenu(void)
|
||||
m->buttons[8].shift[3] = 0;
|
||||
m->buttons[9].shift[3] = 0;
|
||||
|
||||
/* clear menu title */
|
||||
strcpy(m->title,"Controller Settings");
|
||||
|
||||
/* clear menu items */
|
||||
memset(&m->items[0],0,sizeof(gui_item));
|
||||
memset(&m->items[1],0,sizeof(gui_item));
|
||||
|
@ -367,6 +367,7 @@ static void gxStart(void)
|
||||
GX_Init(&gp_fifo, DEFAULT_FIFO_SIZE);
|
||||
GX_SetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
||||
GX_SetCullMode(GX_CULL_NONE);
|
||||
GX_SetClipMode(GX_CLIP_DISABLE);
|
||||
GX_SetDispCopyGamma(GX_GM_1_0);
|
||||
GX_SetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
|
||||
GX_SetColorUpdate(GX_TRUE);
|
||||
@ -426,18 +427,21 @@ static void gxResetRendering(u8 type)
|
||||
GX_Flush();
|
||||
}
|
||||
|
||||
/* Reset GX 2D rendering */
|
||||
static void gxResetView(GXRModeObj *tvmode)
|
||||
/* Reset GX rendering mode */
|
||||
static void gxResetMode(GXRModeObj *tvmode)
|
||||
{
|
||||
Mtx44 p;
|
||||
f32 yScale = GX_GetYScaleFactor(tvmode->efbHeight, tvmode->xfbHeight);
|
||||
u16 xfbHeight = GX_SetDispCopyYScale(yScale);
|
||||
u16 xfbWidth = tvmode->fbWidth;
|
||||
if (xfbWidth & 15) // xfb width is 16 pixels aligned
|
||||
xfbWidth = (xfbWidth & ~15) + 16;
|
||||
|
||||
GX_SetCopyClear((GXColor)BLACK,0x00ffffff);
|
||||
GX_SetViewport(0.0F, 0.0F, tvmode->fbWidth, tvmode->efbHeight, 0.0F, 1.0F);
|
||||
GX_SetScissor(0, 0, tvmode->fbWidth, tvmode->efbHeight);
|
||||
GX_SetDispCopySrc(0, 0, tvmode->fbWidth, tvmode->efbHeight);
|
||||
GX_SetDispCopyDst(tvmode->fbWidth, xfbHeight);
|
||||
GX_SetDispCopyDst(xfbWidth, xfbHeight);
|
||||
GX_SetCopyFilter(tvmode->aa, tvmode->sample_pattern, (tvmode->xfbMode == VI_XFBMODE_SF) ? GX_FALSE : GX_TRUE, tvmode->vfilter);
|
||||
GX_SetFieldMode(tvmode->field_rendering, ((tvmode->viHeight == 2 * tvmode->xfbHeight) ? GX_ENABLE : GX_DISABLE));
|
||||
guOrtho(p, tvmode->efbHeight/2, -(tvmode->efbHeight/2), -(tvmode->fbWidth/2), tvmode->fbWidth/2, 100, 1000);
|
||||
@ -497,42 +501,56 @@ static void gxSetAspectRatio(int *xscale, int *yscale)
|
||||
/* Reset GX/VI hardware scaler */
|
||||
static void gxResetScaler(u32 width, u32 height)
|
||||
{
|
||||
/* get Aspect Ratio (depends on current configuration) */
|
||||
int xscale,yscale;
|
||||
int xscale = 0;
|
||||
int yscale = 0;
|
||||
int offset = 0;
|
||||
|
||||
/* retrieve screen aspect ratio */
|
||||
gxSetAspectRatio(&xscale, &yscale);
|
||||
|
||||
/* GX horizontal scaling (done during EFB rendering) */
|
||||
/* by default, use maximal EFB width */
|
||||
/* default EFB width */
|
||||
rmode->fbWidth = 640;
|
||||
|
||||
/* no filtering, disable GX horizontal scaling */
|
||||
if (!config.bilinear && !config.ntsc)
|
||||
{
|
||||
/* filtering (soft or hard) is disabled, let VI handles horizontal scaling */
|
||||
if ((width * 2) <= 640)
|
||||
rmode->fbWidth = width * 2; /* GX scaling enabled (simple doubler) */
|
||||
rmode->fbWidth = width * 2;
|
||||
else if (width <= 640)
|
||||
rmode->fbWidth = width; /* GX scaling disabled */
|
||||
rmode->fbWidth = width;
|
||||
}
|
||||
|
||||
/* VI horizontal scaling (done during EFB->XFB copy) */
|
||||
int offset = 0;
|
||||
/* configure VI width */
|
||||
if ((xscale * 2) > rmode->fbWidth)
|
||||
{
|
||||
/* max width = 720 pixels */
|
||||
if (xscale > 360)
|
||||
{
|
||||
/* save offset for later */
|
||||
offset = xscale - 360;
|
||||
offset = ((xscale - 360) * rmode->fbWidth) / rmode->viWidth;
|
||||
|
||||
/* maximal width */
|
||||
xscale = 360;
|
||||
}
|
||||
|
||||
/* VI horizontal scaling is enabled */
|
||||
/* enable VI upscaling */
|
||||
rmode->viWidth = xscale * 2;
|
||||
rmode->viXOrigin = (720 - (xscale * 2)) / 2;
|
||||
|
||||
/* update GX horizontal scaling (disabled if no offset) */
|
||||
xscale = (rmode->fbWidth / 2) + ((offset * rmode->fbWidth) / rmode->viWidth);
|
||||
/* default GX horizontal scaling */
|
||||
xscale = (rmode->fbWidth / 2);
|
||||
|
||||
/* handle additional upscaling */
|
||||
if (offset)
|
||||
{
|
||||
/* no filtering, reduce EFB width to increase VI upscaling */
|
||||
if (!config.bilinear && !config.ntsc)
|
||||
rmode->fbWidth -= (offset * 2);
|
||||
|
||||
/* increase GX horizontal scaling */
|
||||
else
|
||||
xscale += offset;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -547,9 +565,7 @@ static void gxResetScaler(u32 width, u32 height)
|
||||
|
||||
/* Configure GX vertical scaling (480i/576i/480p) */
|
||||
if (config.render)
|
||||
{
|
||||
yscale = yscale * 2;
|
||||
}
|
||||
|
||||
/* Set GX scaler (Vertex Position matrix) */
|
||||
square[6] = square[3] = xshift + xscale;
|
||||
@ -1256,18 +1272,24 @@ void gx_video_Stop(void)
|
||||
gxTextureClose(&crosshair[0]);
|
||||
gxTextureClose(&crosshair[1]);
|
||||
|
||||
/* reset GX */
|
||||
/* GX menu rendering */
|
||||
gxResetRendering(1);
|
||||
gxResetView(vmode);
|
||||
gxResetMode(vmode);
|
||||
|
||||
/* VSYNC default callbacks */
|
||||
/* default VI settings */
|
||||
VIDEO_SetPreRetraceCallback(NULL);
|
||||
VIDEO_SetPostRetraceCallback(gx_input_UpdateMenu);
|
||||
#ifdef HW_RVL
|
||||
VIDEO_SetTrapFilter(1);
|
||||
VIDEO_SetGamma(VI_GM_1_0);
|
||||
#endif
|
||||
|
||||
/* reset VI & adjust overscan */
|
||||
/* default TV mode */
|
||||
vmode->viWidth = config.screen_w;
|
||||
vmode->viXOrigin = (VI_MAX_WIDTH_NTSC - vmode->viWidth)/2;
|
||||
VIDEO_Configure(vmode);
|
||||
|
||||
/* starts menu rendering */
|
||||
gxDrawScreenshot(0xff);
|
||||
gxSetScreen();
|
||||
}
|
||||
@ -1281,6 +1303,11 @@ void gx_video_Start(void)
|
||||
else
|
||||
gc_pal = 0;
|
||||
|
||||
#ifdef HW_RVL
|
||||
VIDEO_SetTrapFilter(config.trap);
|
||||
VIDEO_SetGamma((int)(config.gamma * 10.0));
|
||||
#endif
|
||||
|
||||
/* VSYNC callbacks */
|
||||
/* in 60hz mode, frame emulation is synchronized with Video Interrupt */
|
||||
if (!gc_pal && !vdp_pal)
|
||||
@ -1288,7 +1315,7 @@ void gx_video_Start(void)
|
||||
VIDEO_SetPostRetraceCallback(NULL);
|
||||
VIDEO_Flush();
|
||||
|
||||
/* switch interlaced/progressive video settings */
|
||||
/* set interlaced or progressive video mode */
|
||||
if (config.render == 2)
|
||||
{
|
||||
tvmodes[2]->viTVMode = VI_TVMODE_NTSC_PROG;
|
||||
@ -1300,7 +1327,7 @@ void gx_video_Start(void)
|
||||
tvmodes[2]->xfbMode = VI_XFBMODE_DF;
|
||||
}
|
||||
|
||||
/* overscan */
|
||||
/* overscan emulation */
|
||||
if (config.overscan)
|
||||
{
|
||||
bitmap.viewport.x = (reg[12] & 1) ? 16 : 12;
|
||||
@ -1347,10 +1374,10 @@ void gx_video_Start(void)
|
||||
if (config.gun_cursor[1] && (input.dev[5] == DEVICE_LIGHTGUN))
|
||||
crosshair[1] = gxTextureOpenPNG(Crosshair_p2_png,0);
|
||||
|
||||
/* apply changes on next video update */
|
||||
/* force changes on next video update */
|
||||
bitmap.viewport.changed = 1;
|
||||
|
||||
/* reset GX rendering */
|
||||
/* GX emulation rendering */
|
||||
gxResetRendering(0);
|
||||
|
||||
/* resynchronize emulation with VSYNC*/
|
||||
@ -1375,9 +1402,11 @@ void gx_video_Update(void)
|
||||
if (vwidth != old_vwidth)
|
||||
return;
|
||||
|
||||
/* special cases */
|
||||
/* interlaced mode */
|
||||
if (config.render && interlaced)
|
||||
vheight = vheight << 1;
|
||||
|
||||
/* ntsc filter */
|
||||
if (config.ntsc)
|
||||
vwidth = (reg[12]&1) ? MD_NTSC_OUT_WIDTH(vwidth) : SMS_NTSC_OUT_WIDTH(vwidth);
|
||||
|
||||
@ -1396,19 +1425,19 @@ void gx_video_Update(void)
|
||||
/* load texture object */
|
||||
GX_LoadTexObj(&texobj, GX_TEXMAP0);
|
||||
|
||||
/* reset TV mode */
|
||||
/* update TV mode */
|
||||
if (config.render)
|
||||
rmode = tvmodes[gc_pal*3 + 2];
|
||||
else
|
||||
rmode = tvmodes[gc_pal*3 + interlaced];
|
||||
|
||||
/* reset aspect ratio */
|
||||
/* update aspect ratio */
|
||||
gxResetScaler(vwidth,vheight);
|
||||
|
||||
/* reset GX */
|
||||
gxResetView(rmode);
|
||||
/* update GX rendering mode */
|
||||
gxResetMode(rmode);
|
||||
|
||||
/* change VI mode */
|
||||
/* update VI mode */
|
||||
VIDEO_Configure(rmode);
|
||||
VIDEO_Flush();
|
||||
}
|
||||
@ -1548,7 +1577,7 @@ void gx_video_Init(void)
|
||||
/* Initialize GX */
|
||||
gxStart();
|
||||
gxResetRendering(1);
|
||||
gxResetView(vmode);
|
||||
gxResetMode(vmode);
|
||||
|
||||
/* initialize FONT */
|
||||
if (!FONT_Init())
|
||||
|
@ -33,9 +33,9 @@
|
||||
#define SK_UPMEM "/genplus/sk2chip.bin"
|
||||
|
||||
#ifdef HW_RVL
|
||||
#define VERSION "version 1.3.2W"
|
||||
#define VERSION "version 1.4.0W"
|
||||
#else
|
||||
#define VERSION "version 1.3.2G"
|
||||
#define VERSION "version 1.4.0G"
|
||||
#endif
|
||||
|
||||
#define osd_input_Update() gx_input_UpdateEmu()
|
||||
|
547
source/gx/vi_encoder.c
Normal file
547
source/gx/vi_encoder.c
Normal file
@ -0,0 +1,547 @@
|
||||
/****************************************************************************
|
||||
* vi_encoder.c
|
||||
*
|
||||
* Wii Audio/Video Encoder support
|
||||
*
|
||||
* Copyright (C) 2009 Hector Martin (marcan)
|
||||
* Additional code by Eke-Eke
|
||||
*
|
||||
* 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
|
||||
*
|
||||
***************************************************************************/
|
||||
#if defined(HW_RVL)
|
||||
|
||||
#include <string.h>
|
||||
#include <gccore.h>
|
||||
#include <ogcsys.h>
|
||||
#include <ogc/machine/processor.h>
|
||||
|
||||
/****************************************************************************
|
||||
* I2C driver by Hector Martin (marcan)
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#define _SHIFTL(v, s, w) \
|
||||
((u32) (((u32)(v) & ((0x01 << (w)) - 1)) << (s)))
|
||||
#define _SHIFTR(v, s, w) \
|
||||
((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
|
||||
|
||||
extern void udelay(int us);
|
||||
|
||||
static u32 i2cIdentFirst = 0;
|
||||
static u32 i2cIdentFlag = 1;
|
||||
static vu16* const _viReg = (u16*)0xCC002000;
|
||||
static vu32* const _i2cReg = (u32*)0xCD800000;
|
||||
|
||||
static inline void __viOpenI2C(u32 channel)
|
||||
{
|
||||
u32 val = ((_i2cReg[49]&~0x8000)|0x4000);
|
||||
val |= _SHIFTL(channel,15,1);
|
||||
_i2cReg[49] = val;
|
||||
}
|
||||
|
||||
static inline u32 __viSetSCL(u32 channel)
|
||||
{
|
||||
u32 val = (_i2cReg[48]&~0x4000);
|
||||
val |= _SHIFTL(channel,14,1);
|
||||
_i2cReg[48] = val;
|
||||
return 1;
|
||||
}
|
||||
static inline u32 __viSetSDA(u32 channel)
|
||||
{
|
||||
u32 val = (_i2cReg[48]&~0x8000);
|
||||
val |= _SHIFTL(channel,15,1);
|
||||
_i2cReg[48] = val;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline u32 __viGetSDA()
|
||||
{
|
||||
return _SHIFTR(_i2cReg[50],15,1);
|
||||
}
|
||||
|
||||
static inline void __viCheckI2C()
|
||||
{
|
||||
__viOpenI2C(0);
|
||||
udelay(4);
|
||||
|
||||
i2cIdentFlag = 0;
|
||||
if(__viGetSDA()!=0) i2cIdentFlag = 1;
|
||||
}
|
||||
|
||||
static u32 __sendSlaveAddress(u8 addr)
|
||||
{
|
||||
u32 i;
|
||||
|
||||
__viSetSDA(i2cIdentFlag^1);
|
||||
udelay(2);
|
||||
|
||||
__viSetSCL(0);
|
||||
for(i=0;i<8;i++) {
|
||||
if(addr&0x80) __viSetSDA(i2cIdentFlag);
|
||||
else __viSetSDA(i2cIdentFlag^1);
|
||||
udelay(2);
|
||||
|
||||
__viSetSCL(1);
|
||||
udelay(2);
|
||||
|
||||
__viSetSCL(0);
|
||||
addr <<= 1;
|
||||
}
|
||||
|
||||
__viOpenI2C(0);
|
||||
udelay(2);
|
||||
|
||||
__viSetSCL(1);
|
||||
udelay(2);
|
||||
|
||||
if(i2cIdentFlag==1 && __viGetSDA()!=0) return 0;
|
||||
|
||||
__viSetSDA(i2cIdentFlag^1);
|
||||
__viOpenI2C(1);
|
||||
__viSetSCL(0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static u32 __VISendI2CData(u8 addr,void *val,u32 len)
|
||||
{
|
||||
u8 c;
|
||||
s32 i,j;
|
||||
u32 level,ret;
|
||||
|
||||
if(i2cIdentFirst==0) {
|
||||
__viCheckI2C();
|
||||
i2cIdentFirst = 1;
|
||||
}
|
||||
|
||||
_CPU_ISR_Disable(level);
|
||||
|
||||
__viOpenI2C(1);
|
||||
__viSetSCL(1);
|
||||
|
||||
__viSetSDA(i2cIdentFlag);
|
||||
udelay(4);
|
||||
|
||||
ret = __sendSlaveAddress(addr);
|
||||
if(ret==0) {
|
||||
_CPU_ISR_Restore(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__viOpenI2C(1);
|
||||
for(i=0;i<len;i++) {
|
||||
c = ((u8*)val)[i];
|
||||
for(j=0;j<8;j++) {
|
||||
if(c&0x80) __viSetSDA(i2cIdentFlag);
|
||||
else __viSetSDA(i2cIdentFlag^1);
|
||||
udelay(2);
|
||||
|
||||
__viSetSCL(1);
|
||||
udelay(2);
|
||||
__viSetSCL(0);
|
||||
|
||||
c <<= 1;
|
||||
}
|
||||
__viOpenI2C(0);
|
||||
udelay(2);
|
||||
__viSetSCL(1);
|
||||
udelay(2);
|
||||
|
||||
if(i2cIdentFlag==1 && __viGetSDA()!=0) {
|
||||
_CPU_ISR_Restore(level);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__viSetSDA(i2cIdentFlag^1);
|
||||
__viOpenI2C(1);
|
||||
__viSetSCL(0);
|
||||
}
|
||||
|
||||
__viOpenI2C(1);
|
||||
__viSetSDA(i2cIdentFlag^1);
|
||||
udelay(2);
|
||||
__viSetSDA(i2cIdentFlag);
|
||||
|
||||
_CPU_ISR_Restore(level);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void __VIWriteI2CRegister8(u8 reg, u8 data)
|
||||
{
|
||||
u8 buf[2];
|
||||
buf[0] = reg;
|
||||
buf[1] = data;
|
||||
__VISendI2CData(0xe0,buf,2);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
static void __VIWriteI2CRegister16(u8 reg, u16 data)
|
||||
{
|
||||
u8 buf[3];
|
||||
buf[0] = reg;
|
||||
buf[1] = data >> 8;
|
||||
buf[2] = data & 0xFF;
|
||||
__VISendI2CData(0xe0,buf,3);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
static void __VIWriteI2CRegister32(u8 reg, u32 data)
|
||||
{
|
||||
u8 buf[5];
|
||||
buf[0] = reg;
|
||||
buf[1] = data >> 24;
|
||||
buf[2] = (data >> 16) & 0xFF;
|
||||
buf[3] = (data >> 8) & 0xFF;
|
||||
buf[4] = data & 0xFF;
|
||||
__VISendI2CData(0xe0,buf,5);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
static void __VIWriteI2CRegisterBuf(u8 reg, int size, u8 *data)
|
||||
{
|
||||
u8 buf[0x100];
|
||||
buf[0] = reg;
|
||||
memcpy(&buf[1], data, size);
|
||||
__VISendI2CData(0xe0,buf,size+1);
|
||||
udelay(2);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* A/V functions support (Eke-Eke)
|
||||
*
|
||||
****************************************************************************/
|
||||
static const u8 gamma_coeffs[][33] =
|
||||
{
|
||||
/* GM_0_0 */
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
|
||||
},
|
||||
|
||||
/* GM_0_1 */
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x03, 0x97, 0x3B, 0x49,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x80, 0x1B, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_2 */
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x28, 0x00, 0x5A, 0x02, 0xDB, 0x0D, 0x8D, 0x30, 0x49,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x10, 0x00, 0x10, 0x40, 0x11, 0x00, 0x18, 0x80, 0x42, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_3 */
|
||||
{
|
||||
0x00, 0x00, 0x00, 0x7A, 0x02, 0x3C, 0x07, 0x6D, 0x12, 0x9C, 0x27, 0x24,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x10, 0x00, 0x10, 0xC0, 0x15, 0x80, 0x29, 0x00, 0x62, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_4 */
|
||||
{
|
||||
0x00, 0x4E, 0x01, 0x99, 0x05, 0x2D, 0x0B, 0x24, 0x14, 0x29, 0x20, 0xA4,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x00, 0x10, 0x10, 0x40, 0x12, 0xC0, 0x1D, 0xC0, 0x3B, 0x00, 0x78, 0xC0, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_5 */
|
||||
{
|
||||
0x00, 0xEC, 0x03, 0xD7, 0x08, 0x00, 0x0D, 0x9E, 0x14, 0x3E, 0x1B, 0xDB,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x10, 0xC0, 0x16, 0xC0, 0x27, 0xC0, 0x4B, 0x80, 0x89, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_6 */
|
||||
{
|
||||
0x02, 0x76, 0x06, 0x66, 0x0A, 0x96, 0x0E, 0xF3, 0x13, 0xAC, 0x18, 0x49,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x12, 0x00, 0x1C, 0x00, 0x32, 0x80, 0x59, 0xC0, 0x96, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_7 */
|
||||
{
|
||||
0x04, 0xEC, 0x08, 0xF5, 0x0C, 0x96, 0x0F, 0xCF, 0x12, 0xC6, 0x15, 0x80,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x14, 0x00, 0x22, 0x00, 0x3C, 0xC0, 0x66, 0x40, 0x9F, 0xC0, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_8 */
|
||||
{
|
||||
0x08, 0x00, 0x0B, 0xAE, 0x0E, 0x00, 0x10, 0x30, 0x11, 0xCB, 0x13, 0x49,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x16, 0x80, 0x28, 0xC0, 0x46, 0x80, 0x71, 0x00, 0xA7, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_0_9 */
|
||||
{
|
||||
0x0B, 0xB1, 0x0E, 0x14, 0x0F, 0x2D, 0x10, 0x18, 0x10, 0xE5, 0x11, 0x80,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x19, 0x80, 0x2F, 0x80, 0x4F, 0xC0, 0x7A, 0x00, 0xAD, 0xC0, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_0 */
|
||||
{
|
||||
0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00, 0x10, 0x00,
|
||||
0x10, 0x20, 0x40, 0x60, 0x80, 0xA0, 0xEB,
|
||||
0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x60, 0x00, 0x80, 0x00, 0xA0, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_1 */
|
||||
{
|
||||
0x14, 0xEC, 0x11, 0xC2, 0x10, 0x78, 0x0F, 0xB6, 0x0F, 0x2F, 0x0E, 0xB6,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x21, 0x00, 0x3C, 0xC0, 0x5F, 0xC0, 0x89, 0x00, 0xB7, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_2 */
|
||||
{
|
||||
0x19, 0xD8, 0x13, 0x33, 0x10, 0xD2, 0x0F, 0x6D, 0x0E, 0x5E, 0x0D, 0xA4,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x25, 0x00, 0x43, 0x00, 0x66, 0xC0, 0x8F, 0x40, 0xBB, 0x40, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_3 */
|
||||
{
|
||||
0x1E, 0xC4, 0x14, 0x7A, 0x11, 0x0F, 0xF, 0x0C, 0x0D, 0xA1, 0x0C, 0xB6,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x29, 0x00, 0x49, 0x00, 0x6D, 0x40, 0x94, 0xC0, 0xBE, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_4 */
|
||||
{
|
||||
0x24, 0x00, 0x15, 0x70, 0x11, 0x0F, 0x0E, 0xAA, 0x0D, 0x0F, 0x0B, 0xDB,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x2D, 0x40, 0x4E, 0xC0, 0x73, 0x00, 0x99, 0x80, 0xC1, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_5 */
|
||||
{
|
||||
0x29, 0x3B, 0x16, 0x3D, 0x11, 0x0F, 0x0E, 0x30, 0x0C, 0x7D, 0x0B, 0x24,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x31, 0x80, 0x54, 0x40, 0x78, 0x80, 0x9D, 0xC0, 0xC4, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_6 */
|
||||
{
|
||||
0x2E, 0x27, 0x17, 0x0A, 0x10, 0xD2, 0x0D, 0xE7, 0x0B, 0xEB, 0x0A, 0x80,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x35, 0x80, 0x59, 0x80, 0x7D, 0x40, 0xA1, 0xC0, 0xC6, 0x40, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_7 */
|
||||
{
|
||||
0x33, 0x62, 0x17, 0x5C, 0x10, 0xD2, 0x0D, 0x6D, 0x0B, 0x6D, 0x09, 0xED,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x39, 0xC0, 0x5E, 0x40, 0x82, 0x00, 0xA5, 0x40, 0xC8, 0x40, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_8 */
|
||||
{
|
||||
0x38, 0x4E, 0x17, 0xAE, 0x10, 0xB4, 0x0D, 0x0C, 0x0A, 0xF0, 0x09, 0x6D,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x3D, 0xC0, 0x62, 0xC0, 0x86, 0x40, 0xA8, 0x80, 0xCA, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_1_9 */
|
||||
{
|
||||
0x3D, 0x3B, 0x18, 0x00, 0x10, 0x5A, 0x0C, 0xC3, 0x0A, 0x72, 0x09, 0x00,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x41, 0xC0, 0x67, 0x40, 0x8A, 0x00, 0xAB, 0x80, 0xCB, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_0 */
|
||||
{
|
||||
0x41, 0xD8, 0x18, 0x28, 0x10, 0x3C, 0x0C, 0x49, 0x0A, 0x1F, 0x08, 0x92,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x45, 0x80, 0x6B, 0x40, 0x8D, 0xC0, 0xAE, 0x00, 0xCD, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_1 */
|
||||
{
|
||||
0x46, 0x76, 0x18, 0x51, 0x0F, 0xE1, 0x0C, 0x00, 0x09, 0xB6, 0x08, 0x36,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x49, 0x40, 0x6F, 0x40, 0x91, 0x00, 0xB0, 0x80, 0xCE, 0x40, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_2 */
|
||||
{
|
||||
0x4A, 0xC4, 0x18, 0x7A, 0x0F, 0xA5, 0x0B, 0x9E, 0x09, 0x63, 0x07, 0xDB,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x4C, 0xC0, 0x73, 0x00, 0x94, 0x40, 0xB2, 0xC0, 0xCF, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_3 */
|
||||
{
|
||||
0x4F, 0x13, 0x18, 0x51, 0x0F, 0x69, 0x0B, 0x6D, 0x09, 0x0F, 0x07, 0x80,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x50, 0x40, 0x76, 0x40, 0x97, 0x00, 0xB5, 0x00, 0xD0, 0xC0, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_4 */
|
||||
{
|
||||
0x53, 0x13, 0x18, 0x7A, 0x0F, 0x0F, 0x0B, 0x24, 0x08, 0xBC, 0x07, 0x36,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x53, 0x80, 0x79, 0xC0, 0x99, 0xC0, 0xB7, 0x00, 0xD1, 0xC0, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_5 */
|
||||
{
|
||||
0x57, 0x13, 0x18, 0x51, 0x0E, 0xF0, 0x0A, 0xC3, 0x08, 0x7D, 0x06, 0xED,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x56, 0xC0, 0x7C, 0xC0, 0x9C, 0x80, 0xB8, 0xC0, 0xD2, 0xC0, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_6 */
|
||||
{
|
||||
0x5B, 0x13, 0x18, 0x28, 0x0E, 0x96, 0x0A, 0x92, 0x08, 0x29, 0x06, 0xB6,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x5A, 0x00, 0x7F, 0xC0, 0x9E, 0xC0, 0xBA, 0x80, 0xD3, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_7 */
|
||||
{
|
||||
0x5E, 0xC4, 0x18, 0x00, 0x0E, 0x78, 0x0A, 0x30, 0x08, 0x00, 0x06, 0x6D,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x5D, 0x00, 0x82, 0x80, 0xA1, 0x40, 0xBC, 0x00, 0xD4, 0x80, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_8 */
|
||||
{
|
||||
0x62, 0x76, 0x17, 0xD7, 0x0E, 0x1E, 0x0A, 0x00, 0x07, 0xC1, 0x06, 0x36,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x60, 0x00, 0x85, 0x40, 0xA3, 0x40, 0xBD, 0x80, 0xD5, 0x40, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_2_9 */
|
||||
{
|
||||
0x65, 0xD8, 0x17, 0xAE, 0x0D, 0xE1, 0x09, 0xCF, 0x07, 0x82, 0x06, 0x00,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x62, 0xC0, 0x87, 0xC0, 0xA5, 0x40, 0xBF, 0x00, 0xD6, 0x00, 0xEB, 0x00
|
||||
},
|
||||
|
||||
/* GM_3_0 */
|
||||
{
|
||||
0x69, 0x3B, 0x17, 0x85, 0x0D, 0xA5, 0x09, 0x86, 0x07, 0x43, 0x05, 0xDB,
|
||||
0x10, 0x1D, 0x36, 0x58, 0x82, 0xB3, 0xEB,
|
||||
0x10, 0x00, 0x65, 0x80, 0x8A, 0x40, 0xA7, 0x40, 0xC0, 0x40, 0xD6, 0x80, 0xEB, 0x00
|
||||
}
|
||||
};
|
||||
|
||||
void __VISetTiming(u8 timing)
|
||||
{
|
||||
__VIWriteI2CRegister8(0x00,timing);
|
||||
}
|
||||
|
||||
void __VISetYUVSEL(u8 dtvstatus)
|
||||
{
|
||||
u8 vdacFlagRegion = 0;
|
||||
u32 currTvMode = _SHIFTR(_viReg[1],8,2);
|
||||
if(currTvMode==VI_PAL || currTvMode==VI_EURGB60)
|
||||
vdacFlagRegion = 2;
|
||||
else if(currTvMode==VI_MPAL)
|
||||
vdacFlagRegion = 1;
|
||||
|
||||
__VIWriteI2CRegister8(0x01, _SHIFTL(dtvstatus,5,3)|(vdacFlagRegion&0x1f));
|
||||
}
|
||||
|
||||
void __VISetVBICtrl(u16 data)
|
||||
{
|
||||
__VIWriteI2CRegister16(0x02, data);
|
||||
}
|
||||
|
||||
void __VISetTrapFilter(u8 disable)
|
||||
{
|
||||
if (disable)
|
||||
__VIWriteI2CRegister8(0x03, 0);
|
||||
else
|
||||
__VIWriteI2CRegister8(0x03, 1);
|
||||
}
|
||||
|
||||
void __VISet3in1Output(u8 enable)
|
||||
{
|
||||
__VIWriteI2CRegister8(0x04,enable);
|
||||
}
|
||||
|
||||
void __VISetCGMS(u16 value)
|
||||
{
|
||||
__VIWriteI2CRegister16(0x05, value);
|
||||
}
|
||||
|
||||
void __VISetWSS(u16 value)
|
||||
{
|
||||
__VIWriteI2CRegister16(0x08, value);
|
||||
}
|
||||
|
||||
void __VISetRGBOverDrive(u8 value)
|
||||
{
|
||||
u32 currTvMode = _SHIFTR(_viReg[1],8,2);
|
||||
if (currTvMode == VI_DEBUG)
|
||||
__VIWriteI2CRegister8(0x0A,(value<<1)|1);
|
||||
else
|
||||
__VIWriteI2CRegister8(0x0A,0);
|
||||
}
|
||||
|
||||
void __VISetOverSampling(void)
|
||||
{
|
||||
__VIWriteI2CRegister8(0x65,1);
|
||||
}
|
||||
|
||||
void __VISetCCSEL(void)
|
||||
{
|
||||
__VIWriteI2CRegister8(0x6a,1);
|
||||
}
|
||||
|
||||
void __VISetFilterEURGB60(u8 enable)
|
||||
{
|
||||
__VIWriteI2CRegister8(0x6e, enable);
|
||||
}
|
||||
|
||||
void __VISetVolume(u16 value)
|
||||
{
|
||||
__VIWriteI2CRegister16(0x71,value);
|
||||
}
|
||||
|
||||
void __VISetClosedCaption(u32 value)
|
||||
{
|
||||
__VIWriteI2CRegister32(0x7a, value);
|
||||
}
|
||||
|
||||
void __VISetGamma(VIGamma gamma)
|
||||
{
|
||||
u8 *data = (u8 *)&gamma_coeffs[gamma][0];
|
||||
__VIWriteI2CRegisterBuf(0x10, 0x21, data);
|
||||
}
|
||||
|
||||
/* User Configurable */
|
||||
|
||||
void VIDEO_SetGamma(VIGamma gamma)
|
||||
{
|
||||
__VISetGamma(gamma);
|
||||
}
|
||||
|
||||
void VIDEO_SetTrapFilter(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
__VISetTrapFilter(0);
|
||||
else
|
||||
__VISetTrapFilter(1);
|
||||
}
|
||||
|
||||
#endif
|
29
source/gx/vi_encoder.h
Normal file
29
source/gx/vi_encoder.h
Normal file
@ -0,0 +1,29 @@
|
||||
/****************************************************************************
|
||||
* vi_encoder.c
|
||||
*
|
||||
* Wii Audio/Video Encoder support
|
||||
*
|
||||
* Copyright (C) 2009 Hector Martin (marcan)
|
||||
* Additional code by Eke-Eke
|
||||
*
|
||||
* 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
|
||||
*
|
||||
***************************************************************************/
|
||||
#if defined(HW_RVL)
|
||||
|
||||
extern void VIDEO_SetGamma(VIGamma gamma);
|
||||
extern void VIDEO_SetTrapFilter(bool enable);
|
||||
|
||||
#endif
|
@ -23,7 +23,7 @@ static int step = STEREO;
|
||||
static int input_per_cycle;
|
||||
static double ratio = 1.0;
|
||||
|
||||
static void gen_sinc(double rolloff, int width, double offset, double spacing, double scale, int count, short *out )
|
||||
static void gen_sinc(double rolloff, int width, double offset, double spacing, double scale, int count, sample_t *out )
|
||||
{
|
||||
double w, rolloff_cos_a, num, den, sinc;
|
||||
double const maxh = 256;
|
||||
@ -138,7 +138,7 @@ void Fir_Resampler_clear()
|
||||
}
|
||||
}
|
||||
|
||||
double Fir_Resampler_time_ratio( double new_factor )
|
||||
double Fir_Resampler_time_ratio( double new_factor, double rolloff )
|
||||
{
|
||||
ratio = new_factor;
|
||||
|
||||
@ -177,7 +177,7 @@ double Fir_Resampler_time_ratio( double new_factor )
|
||||
|
||||
for ( i = 0; i < res; i++ )
|
||||
{
|
||||
gen_sinc( ROLLOFF, (int) (WIDTH * filter + 1) & ~1, pos, filter,
|
||||
gen_sinc( rolloff, (int) (WIDTH * filter + 1) & ~1, pos, filter,
|
||||
(double) (0x7FFF * GAIN * filter),
|
||||
(int) WIDTH, impulses[i] );
|
||||
|
||||
|
@ -8,15 +8,14 @@
|
||||
#define MAX_RES 32
|
||||
#define WIDTH 16
|
||||
#define WRITE_OFFSET (WIDTH * STEREO) - STEREO
|
||||
#define ROLLOFF 0.990
|
||||
#define GAIN 1.0
|
||||
|
||||
typedef short sample_t;
|
||||
typedef long int sample_t;
|
||||
|
||||
extern int Fir_Resampler_initialize( int new_size );
|
||||
extern void Fir_Resampler_shutdown( void );
|
||||
extern void Fir_Resampler_clear( void );
|
||||
extern double Fir_Resampler_time_ratio( double new_factor );
|
||||
extern double Fir_Resampler_time_ratio( double new_factor, double rolloff );
|
||||
extern double Fir_Resampler_ratio( void );
|
||||
extern int Fir_Resampler_max_write( void );
|
||||
extern sample_t* Fir_Resampler_buffer( void );
|
||||
|
@ -54,7 +54,7 @@ static inline void fm_update(unsigned int cycles)
|
||||
}
|
||||
|
||||
/* select input sample buffer */
|
||||
int16 *buffer = Fir_Resampler_buffer();
|
||||
int32 *buffer = Fir_Resampler_buffer();
|
||||
if (buffer)
|
||||
{
|
||||
Fir_Resampler_write(cnt << 1);
|
||||
@ -139,7 +139,7 @@ void sound_init(void)
|
||||
if (config.hq_fm)
|
||||
{
|
||||
fm_cycles_ratio = 144 * 7 * (1 << 11);
|
||||
Fir_Resampler_time_ratio(mclk / (double)snd.sample_rate / (144.0 * 7.0));
|
||||
Fir_Resampler_time_ratio(mclk / (double)snd.sample_rate / (144.0 * 7.0), config.rolloff);
|
||||
}
|
||||
|
||||
#ifdef LOGSOUND
|
||||
|
@ -131,7 +131,6 @@
|
||||
#include <math.h>
|
||||
|
||||
#include "shared.h"
|
||||
#include "Fir_Resampler.h"
|
||||
|
||||
/* globals */
|
||||
#define FREQ_SH 16 /* 16.16 fixed point (frequency calculations) */
|
||||
@ -164,10 +163,6 @@
|
||||
#define TL_RES_LEN (256) /* 8 bits addressing (real chip) */
|
||||
|
||||
|
||||
#define MAXOUT (+32767)
|
||||
#define MINOUT (-32768)
|
||||
|
||||
|
||||
/* TL_TAB_LEN is calculated as:
|
||||
* 13 - sinus amplitude bits (Y axis)
|
||||
* 2 - sinus sign bit (Y axis)
|
||||
@ -1736,8 +1731,8 @@ INLINE void OPNWriteReg(int r, int v)
|
||||
CH->ams = lfo_ams_depth_shift[(v>>4) & 0x03];
|
||||
|
||||
/* PAN : b7 = L, b6 = R */
|
||||
ym2612.OPN.pan[ c*2 ] = (v & 0x80) ? ~0 : 0;
|
||||
ym2612.OPN.pan[ c*2+1 ] = (v & 0x40) ? ~0 : 0;
|
||||
ym2612.OPN.pan[ c*2 ] = (v & 0x80) ? ~((1 << (14 - config.dac_bits)) - 1) : 0;
|
||||
ym2612.OPN.pan[ c*2+1 ] = (v & 0x40) ? ~((1 << (14 - config.dac_bits)) - 1) : 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@ -2033,10 +2028,10 @@ unsigned int YM2612Read(void)
|
||||
}
|
||||
|
||||
/* Generate 16 bits samples for ym2612 */
|
||||
void YM2612Update(short int *buffer, int length)
|
||||
void YM2612Update(long int *buffer, int length)
|
||||
{
|
||||
int i;
|
||||
int lt,rt;
|
||||
long int lt,rt;
|
||||
|
||||
/* refresh PG increments and EG rates if required */
|
||||
refresh_fc_eg_chan(&ym2612.CH[0]);
|
||||
@ -2195,4 +2190,19 @@ void YM2612Restore(unsigned char *buffer)
|
||||
setup_connection(&ym2612.CH[3],3);
|
||||
setup_connection(&ym2612.CH[4],4);
|
||||
setup_connection(&ym2612.CH[5],5);
|
||||
|
||||
/* update channels mask */
|
||||
unsigned int mask = ~((1 << (14 - config.dac_bits)) - 1);
|
||||
ym2612.OPN.pan[0] = ym2612.OPN.pan[0] ? mask : 0;
|
||||
ym2612.OPN.pan[1] = ym2612.OPN.pan[1] ? mask : 0;
|
||||
ym2612.OPN.pan[2] = ym2612.OPN.pan[2] ? mask : 0;
|
||||
ym2612.OPN.pan[3] = ym2612.OPN.pan[3] ? mask : 0;
|
||||
ym2612.OPN.pan[4] = ym2612.OPN.pan[4] ? mask : 0;
|
||||
ym2612.OPN.pan[5] = ym2612.OPN.pan[5] ? mask : 0;
|
||||
ym2612.OPN.pan[6] = ym2612.OPN.pan[6] ? mask : 0;
|
||||
ym2612.OPN.pan[7] = ym2612.OPN.pan[7] ? mask : 0;
|
||||
ym2612.OPN.pan[8] = ym2612.OPN.pan[8] ? mask : 0;
|
||||
ym2612.OPN.pan[9] = ym2612.OPN.pan[9] ? mask : 0;
|
||||
ym2612.OPN.pan[10] = ym2612.OPN.pan[10] ? mask : 0;
|
||||
ym2612.OPN.pan[11] = ym2612.OPN.pan[11] ? mask : 0;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
extern int YM2612Init(float clock, int rate);
|
||||
extern int YM2612ResetChip(void);
|
||||
extern void YM2612Update(short int*buffer, int length);
|
||||
extern void YM2612Update(long int *buffer, int length);
|
||||
extern void YM2612Write(unsigned int a, unsigned int v);
|
||||
extern unsigned int YM2612Read(void);
|
||||
extern unsigned char *YM2612GetContextPtr(void);
|
||||
|
116
source/system.c
116
source/system.c
@ -25,8 +25,6 @@
|
||||
#include "Fir_Resampler.h"
|
||||
#include "eq.h"
|
||||
|
||||
#define SND_SIZE (snd.buffer_size * sizeof(int16))
|
||||
|
||||
/* Global variables */
|
||||
t_bitmap bitmap;
|
||||
t_snd snd;
|
||||
@ -50,24 +48,24 @@ void audio_set_equalizer(void)
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
* AUDIO stream update
|
||||
* AUDIO stream update & mixing
|
||||
****************************************************************/
|
||||
static int llp,rrp;
|
||||
static int32 llp,rrp;
|
||||
|
||||
int audio_update (void)
|
||||
{
|
||||
int i, l, r;
|
||||
int ll = llp;
|
||||
int rr = rrp;
|
||||
int32 i, l, r;
|
||||
int32 ll = llp;
|
||||
int32 rr = rrp;
|
||||
|
||||
int psg_preamp = config.psg_preamp;
|
||||
int fm_preamp = config.fm_preamp;
|
||||
int filter = config.filter;
|
||||
uint32 factora = (config.lp_range << 16) / 100;
|
||||
uint32 factorb = 0x10000 - factora;
|
||||
int psg_preamp = config.psg_preamp;
|
||||
int fm_preamp = config.fm_preamp;
|
||||
int filter = config.filter;
|
||||
uint32 factora = (config.lp_range << 16) / 100;
|
||||
uint32 factorb = 0x10000 - factora;
|
||||
|
||||
int16 *fm = snd.fm.buffer;
|
||||
int16 *psg = snd.psg.buffer;
|
||||
int32 *fm = snd.fm.buffer;
|
||||
int16 *psg = snd.psg.buffer;
|
||||
|
||||
#ifdef NGC
|
||||
int16 *sb = (int16 *) soundbuffer[mixbuffer];
|
||||
@ -109,11 +107,11 @@ int audio_update (void)
|
||||
for (i = 0; i < size; i ++)
|
||||
{
|
||||
/* PSG samples (mono) */
|
||||
l = r = ((*psg++) * psg_preamp)/100;
|
||||
l = r = (((*psg++) * psg_preamp) / 100);
|
||||
|
||||
/* FM samples (stereo) */
|
||||
l += (*fm++ * fm_preamp)/100;
|
||||
r += (*fm++ * fm_preamp)/100;
|
||||
l += ((*fm++ * fm_preamp) / 100);
|
||||
r += ((*fm++ * fm_preamp) / 100);
|
||||
|
||||
/* filtering */
|
||||
if (filter & 1)
|
||||
@ -131,27 +129,31 @@ int audio_update (void)
|
||||
r = do_3band(&eq,r);
|
||||
}
|
||||
|
||||
/* clipping */
|
||||
if (l > 32767) l = 32767;
|
||||
else if (l < -32768) l = -32768;
|
||||
if (r > 32767) r = 32767;
|
||||
else if (r < -32768) r = -32768;
|
||||
/* clipping (16-bit samples) */
|
||||
if (l > 32767)
|
||||
l = 32767;
|
||||
else if (l < -32768)
|
||||
l = -32768;
|
||||
if (r > 32767)
|
||||
r = 32767;
|
||||
else if (r < -32768)
|
||||
r = -32768;
|
||||
|
||||
/* update sound buffer */
|
||||
#ifndef NGC
|
||||
snd.buffer[0][i] = l;
|
||||
snd.buffer[1][i] = r;
|
||||
snd.buffer[0][i] = r;
|
||||
snd.buffer[1][i] = l;
|
||||
#else
|
||||
*sb++ = r;
|
||||
*sb++ = l;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* save delayed samples for next frame */
|
||||
/* save filtered samples for next frame */
|
||||
llp = ll;
|
||||
rrp = rr;
|
||||
|
||||
/* save remaining samples for next frame */
|
||||
/* keep remaining samples for next frame */
|
||||
memcpy(snd.fm.buffer, fm, (snd.fm.pos - snd.fm.buffer) << 1);
|
||||
memcpy(snd.psg.buffer, psg, (snd.psg.pos - snd.psg.buffer) << 1);
|
||||
|
||||
@ -182,19 +184,19 @@ int audio_init (int samplerate, float framerate)
|
||||
|
||||
#ifndef NGC
|
||||
/* Output buffers */
|
||||
snd.buffer[0] = (int16 *) malloc(SND_SIZE);
|
||||
snd.buffer[1] = (int16 *) malloc(SND_SIZE);
|
||||
snd.buffer[0] = (int16 *) malloc(snd.buffer_size * sizeof(int16));
|
||||
snd.buffer[1] = (int16 *) malloc(snd.buffer_size * sizeof(int16));
|
||||
if (!snd.buffer[0] || !snd.buffer[1])
|
||||
return (-1);
|
||||
#endif
|
||||
|
||||
/* SN76489 stream buffers */
|
||||
snd.psg.buffer = (int16 *) malloc(SND_SIZE);
|
||||
snd.psg.buffer = (int16 *) malloc(snd.buffer_size * sizeof(int16));
|
||||
if (!snd.psg.buffer)
|
||||
return (-1);
|
||||
|
||||
/* YM2612 stream buffers */
|
||||
snd.fm.buffer = (int16 *) malloc(SND_SIZE * 2);
|
||||
snd.fm.buffer = (int32 *) malloc(snd.buffer_size * sizeof(int32) * 2);
|
||||
if (!snd.fm.buffer)
|
||||
return (-1);
|
||||
|
||||
@ -232,14 +234,14 @@ void audio_reset(void)
|
||||
snd.fm.pos = snd.fm.buffer;
|
||||
#ifndef NGC
|
||||
if (snd.buffer[0])
|
||||
memset (snd.buffer[0], 0, SND_SIZE);
|
||||
memset (snd.buffer[0], 0, snd.buffer_size * sizeof(int16));
|
||||
if (snd.buffer[1])
|
||||
memset (snd.buffer[1], 0, SND_SIZE);
|
||||
memset (snd.buffer[1], 0, snd.buffer_size * sizeof(int16));
|
||||
#endif
|
||||
if (snd.psg.buffer)
|
||||
memset (snd.psg.buffer, 0, SND_SIZE);
|
||||
memset (snd.psg.buffer, 0, snd.buffer_size * sizeof(int16));
|
||||
if (snd.fm.buffer)
|
||||
memset (snd.fm.buffer, 0, SND_SIZE * 2);
|
||||
memset (snd.fm.buffer, 0, snd.buffer_size * sizeof(int32) * 2);
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
@ -339,8 +341,11 @@ int system_frame (int do_skip)
|
||||
}
|
||||
odd_frame ^= 1;
|
||||
|
||||
/* clear VBLANK and DMA flags */
|
||||
status &= 0xFFE5;
|
||||
/* clear VBLANK, DMA, FIFO FULL & field flags */
|
||||
status &= 0xFEE5;
|
||||
|
||||
/* set FIFO EMPTY flag */
|
||||
status |= 0x0200;
|
||||
|
||||
/* even/odd field flag (interlaced modes only) */
|
||||
if (odd_frame && interlaced)
|
||||
@ -382,19 +387,34 @@ int system_frame (int do_skip)
|
||||
if (dma_length)
|
||||
vdp_update_dma();
|
||||
|
||||
/* vertical blanking */
|
||||
if (status & 8)
|
||||
{
|
||||
/* render overscan */
|
||||
if (!do_skip && ((line < end_line) || (line >= start_line)))
|
||||
render_line(line, 1);
|
||||
|
||||
/* clear any pending Z80 interrupt */
|
||||
if (zirq)
|
||||
{
|
||||
zirq = 0;
|
||||
z80_set_irq_line(0, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
/* active display */
|
||||
if (line <= vdp_height)
|
||||
else
|
||||
{
|
||||
/* H Interrupt */
|
||||
if(--h_counter < 0)
|
||||
{
|
||||
h_counter = reg[10];
|
||||
hint_pending = 1;
|
||||
hint_pending = 0x10;
|
||||
if (reg[0] & 0x10)
|
||||
irq_status = (irq_status & ~0x40) | 0x14;
|
||||
}
|
||||
|
||||
/* vertical retrace */
|
||||
/* end of active display */
|
||||
if (line == vdp_height)
|
||||
{
|
||||
/* render overscan */
|
||||
@ -423,32 +443,20 @@ int system_frame (int do_skip)
|
||||
mcycles_z80 = mcycles_vdp + 788;
|
||||
|
||||
/* V Interrupt */
|
||||
vint_pending = 1;
|
||||
vint_pending = 0x20;
|
||||
if (reg[1] & 0x20)
|
||||
irq_status = (irq_status & ~0x40) | 0x36;
|
||||
}
|
||||
else if (!do_skip)
|
||||
{
|
||||
/* sprites are processed during horizontal blanking */
|
||||
parse_satb(0x80 + line);
|
||||
if (reg[1] & 0x40)
|
||||
parse_satb(0x80 + line);
|
||||
|
||||
/* render scanline */
|
||||
render_line(line, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* render overscan */
|
||||
if (!do_skip && ((line < end_line) || (line >= start_line)))
|
||||
render_line(line, 1);
|
||||
|
||||
/* clear any pending Z80 interrupt */
|
||||
if (zirq)
|
||||
{
|
||||
zirq = 0;
|
||||
z80_set_irq_line(0, CLEAR_LINE);
|
||||
}
|
||||
}
|
||||
|
||||
/* process line */
|
||||
m68k_run(mcycles_vdp + MCYCLES_PER_LINE);
|
||||
|
@ -61,8 +61,8 @@ typedef struct
|
||||
int16 *buffer[2]; /* Signed 16-bit stereo sound data */
|
||||
struct
|
||||
{
|
||||
int16 *pos;
|
||||
int16 *buffer;
|
||||
int32 *pos;
|
||||
int32 *buffer;
|
||||
} fm;
|
||||
struct
|
||||
{
|
||||
|
385
source/vdp.c
385
source/vdp.c
@ -58,7 +58,7 @@ uint16 ntbb; /* Name table B base address */
|
||||
uint16 ntwb; /* Name table W base address */
|
||||
uint16 satb; /* Sprite attribute table base address */
|
||||
uint16 hscb; /* Horizontal scroll table base address */
|
||||
uint8 border; /* Border color index */
|
||||
|
||||
uint8 bg_name_dirty[0x800]; /* 1= This pattern is dirty */
|
||||
uint16 bg_name_list[0x800]; /* List of modified pattern indices */
|
||||
uint16 bg_list_index; /* # of modified patterns in list */
|
||||
@ -66,7 +66,6 @@ uint8 bg_pattern_cache[0x80000]; /* Cached and flipped patterns */
|
||||
uint8 playfield_shift; /* Width of planes A, B (in bits) */
|
||||
uint8 playfield_col_mask; /* Vertical scroll mask */
|
||||
uint16 playfield_row_mask; /* Horizontal scroll mask */
|
||||
uint32 y_mask; /* Name table Y-index bits mask */
|
||||
uint16 hc_latch; /* latched HCounter (INT2) */
|
||||
uint16 v_counter; /* VDP scanline counter */
|
||||
uint32 dma_length; /* Current DMA remaining bytes */
|
||||
@ -84,6 +83,7 @@ static const uint8 shift_table[] = { 6, 7, 0, 8 }; /* fixes Window Bug test
|
||||
static const uint8 col_mask_table[] = { 0x0F, 0x1F, 0x0F, 0x3F };
|
||||
static const uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF };
|
||||
|
||||
static uint8 border; /* Border color index */
|
||||
static uint16 sat_base_mask; /* Base bits of SAT */
|
||||
static uint16 sat_addr_mask; /* Index bits of SAT */
|
||||
static uint32 dma_endCycles; /* 68k cycles to DMA end */
|
||||
@ -154,13 +154,27 @@ void vdp_reset(void)
|
||||
memset ((char *) vsram, 0, sizeof (vsram));
|
||||
memset ((char *) reg, 0, sizeof (reg));
|
||||
|
||||
addr = 0;
|
||||
addr_latch = 0;
|
||||
code = 0;
|
||||
pending = 0;
|
||||
addr = 0;
|
||||
addr_latch = 0;
|
||||
code = 0;
|
||||
pending = 0;
|
||||
hint_pending = 0;
|
||||
vint_pending = 0;
|
||||
irq_status = 0;
|
||||
hc_latch = 0;
|
||||
v_counter = 0;
|
||||
dmafill = 0;
|
||||
dma_length = 0;
|
||||
dma_endCycles = 0;
|
||||
dma_type = 0;
|
||||
odd_frame = 0;
|
||||
im2_flag = 0;
|
||||
interlaced = 0;
|
||||
fifo_write_cnt = 0;
|
||||
fifo_lastwrite = 0;
|
||||
fifo_latency = 192; /* default FIFO timings */
|
||||
|
||||
status = 0x200; /* fifo empty */
|
||||
status |= vdp_pal; /* PAL/NTSC flag */
|
||||
status = vdp_pal | 0x0200; /* FIFO empty */
|
||||
|
||||
ntab = 0;
|
||||
ntbb = 0;
|
||||
@ -168,61 +182,48 @@ void vdp_reset(void)
|
||||
satb = 0;
|
||||
hscb = 0;
|
||||
|
||||
sat_base_mask = 0xFE00;
|
||||
sat_addr_mask = 0x01FF;
|
||||
|
||||
border = 0x00;
|
||||
sat_base_mask = 0xFE00;
|
||||
sat_addr_mask = 0x01FF;
|
||||
playfield_shift = 6;
|
||||
playfield_col_mask = 0x0F;
|
||||
playfield_row_mask = 0x0FF;
|
||||
|
||||
bg_list_index = 0;
|
||||
memset ((char *) bg_name_dirty, 0, sizeof (bg_name_dirty));
|
||||
memset ((char *) bg_name_list, 0, sizeof (bg_name_list));
|
||||
bg_list_index = 0;
|
||||
memset ((char *) bg_pattern_cache, 0, sizeof (bg_pattern_cache));
|
||||
|
||||
playfield_shift = 6;
|
||||
playfield_col_mask = 0x0F;
|
||||
playfield_row_mask = 0x0FF;
|
||||
|
||||
hint_pending = 0;
|
||||
vint_pending = 0;
|
||||
irq_status = 0;
|
||||
|
||||
hc_latch = 0;
|
||||
v_counter = 0;
|
||||
|
||||
dmafill = 0;
|
||||
dma_length = 0;
|
||||
dma_endCycles = 0;
|
||||
|
||||
im2_flag = 0;
|
||||
interlaced = 0;
|
||||
odd_frame = 0;
|
||||
|
||||
fifo_write_cnt = 0;
|
||||
|
||||
/* reset HVC tables */
|
||||
vctab = (vdp_pal) ? vc_pal_224 : vc_ntsc_224;
|
||||
vctab = vdp_pal ? vc_pal_224 : vc_ntsc_224;
|
||||
hctab = cycle2hc32;
|
||||
|
||||
/* reset display area */
|
||||
bitmap.viewport.w = 256;
|
||||
bitmap.viewport.h = 224;
|
||||
|
||||
/* reset border area */
|
||||
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0;
|
||||
bitmap.viewport.y = config.overscan ? (vdp_pal ? 32 : 8) : 0;
|
||||
bitmap.viewport.changed = 1;
|
||||
|
||||
/* reset overscan area */
|
||||
bitmap.viewport.x = 0;
|
||||
bitmap.viewport.y = 0;
|
||||
if (config.overscan)
|
||||
{
|
||||
bitmap.viewport.x = 12;
|
||||
bitmap.viewport.y = vdp_pal ? 32 : 8;
|
||||
}
|
||||
|
||||
/* initialize some registers (normally set by BIOS) */
|
||||
if (config.bios_enabled != 3)
|
||||
{
|
||||
reg_w(0 , 0x04); /* Palette bit set */
|
||||
reg_w(1 , 0x04); /* Mode 5 enabled */
|
||||
reg_w(10, 0xff); /* HINT disabled */
|
||||
reg_w(12, 0x81); /* H40 mode */
|
||||
reg_w(15, 0x02); /* auto increment */
|
||||
}
|
||||
|
||||
/* default FIFO timing */
|
||||
fifo_latency = 192;
|
||||
}
|
||||
|
||||
void vdp_shutdown(void)
|
||||
@ -262,36 +263,38 @@ void vdp_restore(uint8 *vdp_regs)
|
||||
/* reinitialize palette */
|
||||
color_update(0x00, *(uint16 *)&cram[border << 1]);
|
||||
for(i = 1; i < 0x40; i += 1)
|
||||
{
|
||||
color_update(i, *(uint16 *)&cram[i << 1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* DMA Timings update */
|
||||
/* DMA update */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
void vdp_update_dma()
|
||||
{
|
||||
int dma_cycles = 0;
|
||||
uint32 dma_cycles = 0;
|
||||
|
||||
/* DMA timings table index */
|
||||
int index = (4 * dma_type) + ((reg[12] & 1)*2);
|
||||
if ((status&8) || !(reg[1] & 0x40)) index++;
|
||||
/* update DMA timings */
|
||||
uint32 index = dma_type;
|
||||
if ((status & 8) || !(reg[1] & 0x40))
|
||||
++index;
|
||||
if (reg[12] & 1)
|
||||
index+=2;
|
||||
|
||||
/* DMA transfer rate (bytes per line) */
|
||||
int rate = dma_rates[index];
|
||||
uint32 rate = dma_rates[index];
|
||||
|
||||
/* 68k cycles left */
|
||||
int left_cycles = (mcycles_vdp + MCYCLES_PER_LINE) - mcycles_68k;
|
||||
if (left_cycles < 0) left_cycles = 0;
|
||||
int32 left_cycles = (mcycles_vdp + MCYCLES_PER_LINE) - mcycles_68k;
|
||||
if (left_cycles < 0)
|
||||
left_cycles = 0;
|
||||
|
||||
/* DMA bytes left */
|
||||
int dma_bytes = (left_cycles * rate) / MCYCLES_PER_LINE;
|
||||
uint32 dma_bytes = (left_cycles * rate) / MCYCLES_PER_LINE;
|
||||
|
||||
#ifdef LOGVDP
|
||||
error("[%d(%d)][%d(%d)] DMA type %d (%d access/line)-> %d access (%d remaining) (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE,dma_type, rate, dma_length, dma_bytes, m68k_get_reg (NULL, M68K_REG_PC));
|
||||
error("[%d(%d)][%d(%d)] DMA type %d (%d access/line)-> %d access (%d remaining) (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE,dma_type/4, rate, dma_length, dma_bytes, m68k_get_reg (NULL, M68K_REG_PC));
|
||||
#endif
|
||||
|
||||
/* determinate DMA length in CPU cycles */
|
||||
@ -309,9 +312,9 @@ void vdp_update_dma()
|
||||
}
|
||||
|
||||
/* update 68k cycles counter */
|
||||
if (dma_type < 2)
|
||||
if (dma_type < 8)
|
||||
{
|
||||
/* 68K COPY to V-RAM */
|
||||
/* 68K to VRAM, CRAM, VSRAM */
|
||||
/* 68K is frozen during DMA operation */
|
||||
mcycles_68k += dma_cycles;
|
||||
|
||||
@ -344,13 +347,11 @@ void vdp_ctrl_w(unsigned int data)
|
||||
if ((data & 0xC000) == 0x8000)
|
||||
{
|
||||
/* VDP register write */
|
||||
uint8 r = (data >> 8) & 0x1F;
|
||||
uint8 d = data & 0xFF;
|
||||
reg_w(r,d);
|
||||
reg_w((data >> 8) & 0x1F,data & 0xFF);
|
||||
}
|
||||
else pending = 1;
|
||||
|
||||
addr = ((addr_latch & 0xC000) | (data & 0x3FFF));
|
||||
addr = addr_latch | (data & 0x3FFF);
|
||||
code = ((code & 0x3C) | ((data >> 14) & 0x03));
|
||||
}
|
||||
else
|
||||
@ -358,30 +359,29 @@ void vdp_ctrl_w(unsigned int data)
|
||||
/* Clear pending flag */
|
||||
pending = 0;
|
||||
|
||||
/* Update address and code registers */
|
||||
addr = ((addr & 0x3FFF) | ((data & 3) << 14));
|
||||
code = ((code & 0x03) | ((data >> 2) & 0x3C));
|
||||
|
||||
/* Save address bits A15 and A14 */
|
||||
addr_latch = (addr & 0xC000);
|
||||
addr_latch = (data & 3) << 14;
|
||||
|
||||
/* Update address and code registers */
|
||||
addr = addr_latch | (addr & 0x3FFF);
|
||||
code = ((code & 0x03) | ((data >> 2) & 0x3C));
|
||||
|
||||
/* DMA operation */
|
||||
if ((code & 0x20) && (reg[1] & 0x10))
|
||||
{
|
||||
switch (reg[23] & 0xC0)
|
||||
switch (reg[23] >> 6)
|
||||
{
|
||||
case 0x00: /* V bus to VDP DMA */
|
||||
case 0x40: /* V bus to VDP DMA */
|
||||
dma_vbus();
|
||||
break;
|
||||
|
||||
case 0x80: /* VRAM fill */
|
||||
case 2: /* VRAM fill */
|
||||
dmafill = 1;
|
||||
break;
|
||||
|
||||
case 0xC0: /* VRAM copy */
|
||||
case 3: /* VRAM copy */
|
||||
dma_copy();
|
||||
break;
|
||||
|
||||
default: /* V bus to VDP DMA */
|
||||
dma_vbus();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -411,40 +411,34 @@ void vdp_ctrl_w(unsigned int data)
|
||||
* Return VDP status
|
||||
*
|
||||
* Bits are
|
||||
* 0 0:1 ntsc:pal
|
||||
* 0 0:1 ntsc:pal
|
||||
* 1 DMA Busy
|
||||
* 2 During HBlank
|
||||
* 3 During VBlank
|
||||
* 4 Frame Interlace 0:even 1:odd
|
||||
* 4 0:1 even:odd field (interlaced modes)
|
||||
* 5 Sprite collision
|
||||
* 6 Too many sprites per line
|
||||
* 7 v interrupt occurred
|
||||
* 8 Write FIFO full
|
||||
* 9 Write FIFO empty
|
||||
* 10 - 15 Next word on bus
|
||||
* 10 - 15 Open Bus
|
||||
*/
|
||||
unsigned int vdp_ctrl_r(void)
|
||||
{
|
||||
/* update FIFO flags */
|
||||
fifo_update();
|
||||
if (fifo_write_cnt < 4)
|
||||
{
|
||||
status &= 0xFEFF;
|
||||
if (fifo_write_cnt == 0) status |= 0x200;
|
||||
}
|
||||
else status ^= 0x200;
|
||||
|
||||
/* update DMA Busy flag */
|
||||
if ((status & 2) && !dma_length && (mcycles_68k >= dma_endCycles))
|
||||
status &= 0xFFFD;
|
||||
|
||||
unsigned int temp = status;
|
||||
uint32 temp = status;
|
||||
|
||||
/* display OFF: VBLANK flag is set */
|
||||
if (!(reg[1] & 0x40))
|
||||
temp |= 0x08;
|
||||
|
||||
/* HBLANK flag (Sonic 3 and Sonic 2 "VS Modes", Lemmings 2, Mega Turrican) */
|
||||
/* HBLANK flag (Sonic 3 and Sonic 2 "VS Modes", Lemmings 2, Mega Turrican, Gouketsuji Ichizoku) */
|
||||
if ((mcycles_68k % MCYCLES_PER_LINE) < 588)
|
||||
temp |= 0x04;
|
||||
|
||||
@ -466,7 +460,8 @@ unsigned int vdp_hvc_r(void)
|
||||
uint8 vc = vctab[v_counter];
|
||||
|
||||
/* interlace mode 2 */
|
||||
if (im2_flag) vc = (vc << 1) | ((vc >> 7) & 1);
|
||||
if (im2_flag)
|
||||
vc = (vc << 1) | ((vc >> 7) & 1);
|
||||
|
||||
#ifdef LOGVDP
|
||||
error("[%d(%d)][%d(%d)] VDP HVC Read -> 0x%04x (%x)\n", v_counter, mcycles_68k/MCYCLES_PER_LINE, mcycles_68k, mcycles_68k%MCYCLES_PER_LINE,(vc << 8) | hc, m68k_get_reg (NULL, M68K_REG_PC));
|
||||
@ -492,10 +487,12 @@ void vdp_data_w(unsigned int data)
|
||||
return;
|
||||
}
|
||||
|
||||
/* update VDP FIFO (during HDISPLAY only) */
|
||||
/* restricted VDP writes during active display */
|
||||
if (!(status&8) && (reg[1]&0x40))
|
||||
{
|
||||
/* update VDP FIFO */
|
||||
fifo_update();
|
||||
|
||||
if (fifo_write_cnt == 0)
|
||||
{
|
||||
/* reset cycle counter */
|
||||
@ -508,12 +505,13 @@ void vdp_data_w(unsigned int data)
|
||||
/* increase FIFO word count */
|
||||
fifo_write_cnt ++;
|
||||
|
||||
/* is FIFO full ? */
|
||||
/* FIFO full ? */
|
||||
if (fifo_write_cnt >= 4)
|
||||
{
|
||||
/* update VDP status flag */
|
||||
status |= 0x100;
|
||||
|
||||
/* VDP latency (Chaos Engine, Soldiers of Fortune, Double Clutch) */
|
||||
/* CPU is delayed (Chaos Engine, Soldiers of Fortune, Double Clutch) */
|
||||
if (fifo_write_cnt > 4)
|
||||
mcycles_68k = fifo_lastwrite + fifo_latency;
|
||||
}
|
||||
@ -580,6 +578,16 @@ int vdp_int_ack_callback(int int_level)
|
||||
#ifdef LOGVDP
|
||||
error("---> VINT cleared\n");
|
||||
#endif
|
||||
/* update IRQ status */
|
||||
if (hint_pending & reg[0])
|
||||
{
|
||||
irq_status = 0x14;
|
||||
}
|
||||
else
|
||||
{
|
||||
irq_status = 0x00;
|
||||
m68k_set_irq(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -587,17 +595,18 @@ int vdp_int_ack_callback(int int_level)
|
||||
#ifdef LOGVDP
|
||||
error("---> HINT cleared\n");
|
||||
#endif
|
||||
/* update IRQ status */
|
||||
if (vint_pending & reg[1])
|
||||
{
|
||||
irq_status = 0x16;
|
||||
}
|
||||
else
|
||||
{
|
||||
irq_status = 0x00;
|
||||
m68k_set_irq(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* update IRQ status */
|
||||
irq_status = 0;
|
||||
if (vint_pending && (reg[1] & 0x20))
|
||||
irq_status |= 0x16;
|
||||
else if (hint_pending && (reg[0] & 0x10))
|
||||
irq_status |= 0x14;
|
||||
else
|
||||
m68k_set_irq(0);
|
||||
|
||||
return M68K_INT_ACK_AUTOVECTOR;
|
||||
}
|
||||
|
||||
@ -613,8 +622,20 @@ static inline void fifo_update()
|
||||
if (fifo_read > 0)
|
||||
{
|
||||
fifo_write_cnt -= fifo_read;
|
||||
if (fifo_write_cnt < 0)
|
||||
fifo_write_cnt = 0;
|
||||
|
||||
/* update VDP status flags */
|
||||
if (fifo_write_cnt < 4)
|
||||
{
|
||||
/* FIFO is not full anymore */
|
||||
status &= 0xFEFF;
|
||||
|
||||
if (fifo_write_cnt <= 0)
|
||||
{
|
||||
/* FIFO is empty */
|
||||
status |= 0x200;
|
||||
fifo_write_cnt = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* update cycle count */
|
||||
fifo_lastwrite += (fifo_read * fifo_latency);
|
||||
@ -636,7 +657,8 @@ static inline void data_w(unsigned int data)
|
||||
#endif
|
||||
|
||||
/* Byte-swap data if A0 is set */
|
||||
if (addr & 1) data = (data >> 8) | (data << 8);
|
||||
if (addr & 1)
|
||||
data = ((data >> 8) | (data << 8)) & 0xFFFF;
|
||||
|
||||
/* Copy SAT data to the internal SAT */
|
||||
if ((addr & sat_base_mask) == satb)
|
||||
@ -705,10 +727,6 @@ static inline void data_w(unsigned int data)
|
||||
addr += reg[15];
|
||||
}
|
||||
|
||||
/*
|
||||
The reg[] array is updated at the *end* of this function, so the new
|
||||
register data can be compared with the previous data.
|
||||
*/
|
||||
static inline void reg_w(unsigned int r, unsigned int d)
|
||||
{
|
||||
#ifdef LOGVDP
|
||||
@ -726,79 +744,95 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
||||
{
|
||||
case 0: /* CTRL #1 */
|
||||
|
||||
/* look for changed bits */
|
||||
r = d ^ reg[r];
|
||||
reg[0] = d;
|
||||
|
||||
/* Line Interrupt */
|
||||
if (((d&0x10) != (reg[0]&0x10)) && hint_pending)
|
||||
if ((r & 0x10) && hint_pending)
|
||||
{
|
||||
/* update IRQ status */
|
||||
irq_status = 0x50;
|
||||
if (vint_pending && (reg[1] & 0x20))
|
||||
if (vint_pending & reg[1])
|
||||
irq_status |= 0x26;
|
||||
else if (d & 0x10)
|
||||
irq_status |= 4;
|
||||
}
|
||||
|
||||
/* Palette bit */
|
||||
if ((d&0x04) != (reg[0]&0x04))
|
||||
if (r & 0x04)
|
||||
{
|
||||
/* Update colors */
|
||||
reg[0] = d;
|
||||
int i;
|
||||
color_update (0x00, *(uint16 *) & cram[border << 1]);
|
||||
for (i = 1; i < 0x40; i += 1)
|
||||
{
|
||||
color_update (i, *(uint16 *) & cram[i << 1]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 1: /* CTRL #2 */
|
||||
|
||||
/* look for changed bits */
|
||||
r = d ^ reg[r];
|
||||
reg[1] = d;
|
||||
|
||||
/* Frame Interrupt */
|
||||
if (((d&0x20) != (reg[1]&0x20)) && vint_pending)
|
||||
if ((r & 0x20) && vint_pending)
|
||||
{
|
||||
/* update IRQ status */
|
||||
irq_status = 0x50;
|
||||
if (d & 0x20)
|
||||
irq_status |= 0x26;
|
||||
else if (hint_pending && (reg[0] & 0x10))
|
||||
else if (hint_pending & reg[0])
|
||||
irq_status |= 4;
|
||||
}
|
||||
|
||||
/* See if the viewport height has actually been changed */
|
||||
if ((d & 8) != (reg[1] & 8))
|
||||
if (r & 0x08)
|
||||
{
|
||||
/* update viewport */
|
||||
bitmap.viewport.changed = 1;
|
||||
bitmap.viewport.h = (d & 8) ? 240 : 224;
|
||||
if (config.overscan) bitmap.viewport.y = ((vdp_pal ? 288 : 240) - bitmap.viewport.h) / 2;
|
||||
|
||||
/* update VC table */
|
||||
/* PAL mode only ! */
|
||||
if (vdp_pal)
|
||||
vctab = (d & 8) ? vc_pal_240 : vc_pal_224;
|
||||
{
|
||||
if (d & 8)
|
||||
{
|
||||
bitmap.viewport.h = 240;
|
||||
if (config.overscan)
|
||||
bitmap.viewport.y = 24;
|
||||
vctab = vc_pal_240;
|
||||
}
|
||||
else
|
||||
{
|
||||
bitmap.viewport.h = 224;
|
||||
if (config.overscan)
|
||||
bitmap.viewport.y = 32;
|
||||
vctab = vc_pal_224;
|
||||
}
|
||||
|
||||
/* update viewport */
|
||||
bitmap.viewport.changed = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Display status modified during Horizontal Blanking (Legend of Galahad, Lemmings 2, */
|
||||
/* Nigel Mansell's World Championship Racing, Deadly Moves, Power Athlete). */
|
||||
/* Nigel Mansell's World Championship Racing, Deadly Moves, Power Athlete, ...) */
|
||||
/* */
|
||||
/* Note that this is not entirely correct since we are cheating with the HBLANK period limits */
|
||||
/* and still redrawing the whole line. This is done because some game (PAL version of Nigel */
|
||||
/* Mansell's World Championship Racing actually) appear to disable display outside HBLANK. On */
|
||||
/* real hardware, the raster line would appear partially blanked. */
|
||||
if (((d&0x40) != (reg[1]&0x40)) && !(status & 8))
|
||||
if ((r & 0x40) && !(status & 8))
|
||||
{
|
||||
if (mcycles_68k <= (hint_68k + 860))
|
||||
{
|
||||
reg[1] = d;
|
||||
#ifdef LOGVDP
|
||||
error("Line redrawn (%d sprites) \n",object_index_count);
|
||||
#endif
|
||||
/* If display was disabled during HBLANK (Mickey Mania 3D level), sprite processing is limited */
|
||||
/* Below values have been deducted from testing on this game, accurate emulation would require */
|
||||
/* to know exact sprite (pre)processing timings. Hopefully, they don't seem to break any other */
|
||||
/* games, so they might not be so much inaccurate. */
|
||||
if ((d&0x40) && (mcycles_68k % MCYCLES_PER_LINE >= 360) && (object_index_count > 5))
|
||||
object_index_count = 5;
|
||||
|
||||
if ((d&0x40) && (object_index_count > 5) && (mcycles_68k % MCYCLES_PER_LINE >= 360))
|
||||
object_index_count = 5;
|
||||
#ifdef LOGVDP
|
||||
error("Line redrawn (%d sprites) \n",object_index_count);
|
||||
#endif
|
||||
/* re-render line */
|
||||
render_line(v_counter, 0);
|
||||
}
|
||||
@ -810,46 +844,46 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
||||
break;
|
||||
|
||||
case 2: /* NTAB */
|
||||
reg[2] = d;
|
||||
ntab = (d << 10) & 0xE000;
|
||||
break;
|
||||
|
||||
case 3: /* NTWB */
|
||||
ntwb = (d << 10) & 0xF800;
|
||||
if(reg[12] & 1) ntwb &= 0xF000;
|
||||
reg[3] = d;
|
||||
if (reg[12] & 1)
|
||||
ntwb = (d << 10) & 0xF000;
|
||||
else
|
||||
ntwb = (d << 10) & 0xF800;
|
||||
break;
|
||||
|
||||
case 4: /* NTBB */
|
||||
reg[4] = d;
|
||||
ntbb = (d << 13) & 0xE000;
|
||||
break;
|
||||
|
||||
case 5: /* SATB */
|
||||
reg[5] = d;
|
||||
if (reg[12] & 1)
|
||||
{
|
||||
sat_base_mask = 0xFC00;
|
||||
sat_addr_mask = 0x03FF;
|
||||
}
|
||||
satb = (d << 9) & 0xFC00;
|
||||
else
|
||||
{
|
||||
sat_base_mask = 0xFE00;
|
||||
sat_addr_mask = 0x01FF;
|
||||
}
|
||||
satb = (d << 9) & sat_base_mask;
|
||||
satb = (d << 9) & 0xFE00;
|
||||
|
||||
break;
|
||||
|
||||
case 7:
|
||||
/* See if the border color has actually changed */
|
||||
reg[7] = d;
|
||||
/* See if the background color has actually changed */
|
||||
d &= 0x3F;
|
||||
if (d != border)
|
||||
{
|
||||
/* Mark the border color as modified */
|
||||
/* update background color */
|
||||
border = d;
|
||||
color_update(0x00, *(uint16 *)&cram[(border << 1)]);
|
||||
color_update(0x00, *(uint16 *)&cram[(d << 1)]);
|
||||
|
||||
/* Background color modified during Horizontal Blanking (Road Rash 1,2,3)*/
|
||||
/* background color modified during Horizontal Blanking (Road Rash 1,2,3)*/
|
||||
if (!(status & 8) && (mcycles_68k <= (mcycles_vdp + 860)))
|
||||
{
|
||||
/* remap colors */
|
||||
reg[7] = d;
|
||||
remap_buffer(v_counter,bitmap.viewport.w + 2*bitmap.viewport.x);
|
||||
#ifdef LOGVDP
|
||||
error("--> Line remapped\n");
|
||||
@ -863,38 +897,51 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
||||
break;
|
||||
|
||||
case 12:
|
||||
|
||||
/* look for changed bits */
|
||||
r = d ^ reg[r];
|
||||
reg[12] = d;
|
||||
|
||||
/* See if the viewport width has actually been changed */
|
||||
if ((d & 1) != (reg[12] & 1))
|
||||
if (r & 0x01)
|
||||
{
|
||||
if (d & 1)
|
||||
{
|
||||
/* Update display-dependant registers */
|
||||
ntwb = (reg[3] << 10) & 0xF000;
|
||||
satb = (reg[5] << 9) & 0xFC00;
|
||||
sat_base_mask = 0xFC00;
|
||||
sat_addr_mask = 0x03FF;
|
||||
satb = (reg[5] << 9) & sat_base_mask;
|
||||
|
||||
/* Update HC table */
|
||||
hctab = cycle2hc40;
|
||||
|
||||
/* Update viewport width */
|
||||
bitmap.viewport.w = 320;
|
||||
if (config.overscan) bitmap.viewport.x = 16;
|
||||
if (config.overscan)
|
||||
bitmap.viewport.x = 16;
|
||||
|
||||
/* Update fifo timings */
|
||||
fifo_latency = ((code & 0x0F) == 0x01) ? 384 : 192;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update display-dependant registers */
|
||||
ntwb = (reg[3] << 10) & 0xF800;
|
||||
satb = (reg[5] << 9) & 0xFE00;
|
||||
sat_base_mask = 0xFE00;
|
||||
sat_addr_mask = 0x01FF;
|
||||
satb = (reg[5] << 9) & sat_base_mask;
|
||||
|
||||
/* Update HC table */
|
||||
hctab = cycle2hc32;
|
||||
|
||||
/* Update viewport width */
|
||||
bitmap.viewport.w = 256;
|
||||
if (config.overscan) bitmap.viewport.x = 12;
|
||||
if (config.overscan)
|
||||
bitmap.viewport.x = 12;
|
||||
|
||||
/* Update fifo timings */
|
||||
fifo_latency = ((code & 0x0F) == 0x01) ? 420 : 210;
|
||||
}
|
||||
|
||||
/* Update viewport */
|
||||
@ -905,27 +952,23 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
||||
}
|
||||
|
||||
/* See if the S/TE mode bit has changed */
|
||||
if ((d & 8) != (reg[12] & 8))
|
||||
if (r & 0x08)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The following color update check this value */
|
||||
reg[12] = d;
|
||||
|
||||
/* Update colors */
|
||||
int i;
|
||||
color_update (0x00, *(uint16 *) & cram[border << 1]);
|
||||
for (i = 1; i < 0x40; i += 1)
|
||||
{
|
||||
color_update (i, *(uint16 *) & cram[i << 1]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 13: /* HScroll Base Address */
|
||||
reg[13] = d;
|
||||
hscb = (d << 10) & 0xFC00;
|
||||
break;
|
||||
|
||||
case 16: /* Playfield size */
|
||||
reg[16] = d;
|
||||
playfield_shift = shift_table[(d & 3)];
|
||||
playfield_col_mask = col_mask_table[(d & 3)];
|
||||
playfield_row_mask = row_mask_table[(d >> 4) & 3];
|
||||
@ -935,10 +978,11 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
||||
reg[17] = d;
|
||||
window_clip();
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write new register value */
|
||||
reg[r] = d;
|
||||
default:
|
||||
reg[r] = d;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
@ -955,11 +999,13 @@ static inline void reg_w(unsigned int r, unsigned int d)
|
||||
static inline void dma_copy(void)
|
||||
{
|
||||
int name;
|
||||
int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
int source = (reg[22] << 8 | reg[21]) & 0xFFFF;
|
||||
if (!length) length = 0x10000;
|
||||
uint32 length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
uint32 source = (reg[22] << 8 | reg[21]) & 0xFFFF;
|
||||
|
||||
dma_type = 3;
|
||||
if (!length)
|
||||
length = 0x10000;
|
||||
|
||||
dma_type = 12;
|
||||
dma_length = length;
|
||||
vdp_update_dma();
|
||||
|
||||
@ -982,15 +1028,16 @@ static inline void dma_copy(void)
|
||||
/* 68K Copy to VRAM, VSRAM or CRAM */
|
||||
static inline void dma_vbus (void)
|
||||
{
|
||||
uint32 base, source = ((reg[23] & 0x7F) << 17 | reg[22] << 9 | reg[21] << 1) & 0xFFFFFE;
|
||||
uint32 source = ((reg[23] & 0x7F) << 17 | reg[22] << 9 | reg[21] << 1) & 0xFFFFFE;
|
||||
uint32 base = source;
|
||||
uint32 length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
uint32 temp;
|
||||
|
||||
if (!length) length = 0x10000;
|
||||
base = source;
|
||||
if (!length)
|
||||
length = 0x10000;
|
||||
|
||||
/* DMA timings */
|
||||
dma_type = (code & 0x06) ? 1 : 0;
|
||||
dma_type = (code & 0x06) ? 4 : 0;
|
||||
dma_length = length;
|
||||
vdp_update_dma();
|
||||
|
||||
@ -1055,11 +1102,13 @@ static inline void dma_vbus (void)
|
||||
static inline void dma_fill(unsigned int data)
|
||||
{
|
||||
int name;
|
||||
int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
if (!length) length = 0x10000;
|
||||
uint32 length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
|
||||
if (!length)
|
||||
length = 0x10000;
|
||||
|
||||
/* DMA timings */
|
||||
dma_type = 2;
|
||||
dma_type = 8;
|
||||
dma_length = length;
|
||||
vdp_update_dma();
|
||||
|
||||
|
@ -46,7 +46,7 @@ extern uint16 ntbb;
|
||||
extern uint16 ntwb;
|
||||
extern uint16 satb;
|
||||
extern uint16 hscb;
|
||||
extern uint8 border;
|
||||
|
||||
extern uint8 bg_name_dirty[0x800];
|
||||
extern uint16 bg_name_list[0x800];
|
||||
extern uint16 bg_list_index;
|
||||
|
Loading…
Reference in New Issue
Block a user