overclocking: allow to choose between post-render and vblank extra scanlines.
fix #704
This commit is contained in:
parent
6a385ddf0b
commit
88a6999e49
|
@ -183,7 +183,8 @@ static CFGSTRUCT fceuconfig[] =
|
||||||
AC(force_grayscale),
|
AC(force_grayscale),
|
||||||
AC(dendy),
|
AC(dendy),
|
||||||
AC(extrascanlines),
|
AC(extrascanlines),
|
||||||
AC(overclocked),
|
AC(vblankscanlines),
|
||||||
|
AC(overclock_enabled),
|
||||||
AC(skip_7bit_overclocking),
|
AC(skip_7bit_overclocking),
|
||||||
AC(palnotch),
|
AC(palnotch),
|
||||||
AC(palsaturation),
|
AC(palsaturation),
|
||||||
|
|
|
@ -566,19 +566,21 @@ BEGIN
|
||||||
PUSHBUTTON "Enter",400,444,107,16,28
|
PUSHBUTTON "Enter",400,444,107,16,28
|
||||||
END
|
END
|
||||||
|
|
||||||
TIMINGCONFIG DIALOGEX 23, 157, 203, 83
|
TIMINGCONFIG DIALOGEX 23, 157, 203, 110
|
||||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Timing Configuration"
|
CAPTION "Timing Configuration"
|
||||||
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
FONT 8, "MS Sans Serif", 0, 0, 0x0
|
||||||
BEGIN
|
BEGIN
|
||||||
DEFPUSHBUTTON "Close",1,137,61,56,14
|
DEFPUSHBUTTON "Close",1,137,87,56,14
|
||||||
CONTROL "Disable speed throttling used when sound is disabled.",CB_DISABLE_SPEED_THROTTLING,
|
CONTROL "Disable speed throttling used when sound is disabled.",CB_DISABLE_SPEED_THROTTLING,
|
||||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,8,183,12
|
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,8,183,12
|
||||||
CONTROL "Set high-priority thread.",CB_SET_HIGH_PRIORITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,24,102,12
|
CONTROL "Set high-priority thread.",CB_SET_HIGH_PRIORITY,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,24,102,12
|
||||||
CONTROL "Overclocking (old PPU only).",CB_OVERCLOCKING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,42,101,10
|
CONTROL "Overclocking (old PPU only).",CB_OVERCLOCKING,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,41,101,10
|
||||||
EDITTEXT IDC_EXTRA_SCANLINES,122,38,61,14,ES_AUTOHSCROLL
|
EDITTEXT IDC_EXTRA_SCANLINES,104,55,84,14,ES_AUTOHSCROLL
|
||||||
LTEXT "Extra scanlines:",IDC_STATIC,127,26,51,8
|
LTEXT "Post-render scanlines:",IDC_STATIC,21,57,74,8
|
||||||
CONTROL "Don't overclock 7-bit samples.",CB_SKIP_7BIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,58,111,10
|
CONTROL "Don't overclock 7-bit samples.",CB_SKIP_7BIT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,10,87,111,10
|
||||||
|
EDITTEXT IDC_VBLANK_SCANLINES,104,68,84,14,ES_AUTOHSCROLL
|
||||||
|
LTEXT "VBlank scanlines:",IDC_STATIC,21,71,76,8
|
||||||
END
|
END
|
||||||
|
|
||||||
MOVIEOPTIONS DIALOGEX 65520, 76, 147, 222
|
MOVIEOPTIONS DIALOGEX 65520, 76, 147, 222
|
||||||
|
@ -1618,7 +1620,7 @@ BEGIN
|
||||||
LEFTMARGIN, 10
|
LEFTMARGIN, 10
|
||||||
RIGHTMARGIN, 193
|
RIGHTMARGIN, 193
|
||||||
TOPMARGIN, 8
|
TOPMARGIN, 8
|
||||||
BOTTOMMARGIN, 52
|
BOTTOMMARGIN, 101
|
||||||
END
|
END
|
||||||
|
|
||||||
"MOVIEOPTIONS", DIALOG
|
"MOVIEOPTIONS", DIALOG
|
||||||
|
|
|
@ -582,6 +582,7 @@
|
||||||
#define IDC_BUTTON9 1148
|
#define IDC_BUTTON9 1148
|
||||||
#define TASEDITOR_FIND_NEXT_SIMILAR_MARKER 1148
|
#define TASEDITOR_FIND_NEXT_SIMILAR_MARKER 1148
|
||||||
#define IDC_SYMBOLIC_ADDRESS 1148
|
#define IDC_SYMBOLIC_ADDRESS 1148
|
||||||
|
#define IDC_VBLANK_SCANLINES 1148
|
||||||
#define IDC_HISTORYLIST 1149
|
#define IDC_HISTORYLIST 1149
|
||||||
#define IDC_SYMBOLIC_NAME 1149
|
#define IDC_SYMBOLIC_NAME 1149
|
||||||
#define IDC_BOOKMARKSLIST 1150
|
#define IDC_BOOKMARKSLIST 1150
|
||||||
|
@ -638,7 +639,7 @@
|
||||||
#define IDC_MASK_UNUSED_GRAPHICS 1203
|
#define IDC_MASK_UNUSED_GRAPHICS 1203
|
||||||
#define CHECK_SOUND_SWAPDUTY 1203
|
#define CHECK_SOUND_SWAPDUTY 1203
|
||||||
#define CB_OVERCLOCKING 1203
|
#define CB_OVERCLOCKING 1203
|
||||||
#define CHECK_DEEMPH_SWAP 1203
|
#define CHECK_DEEMPH_SWAP 1203
|
||||||
#define IDC_VOLUMEGROUP 1204
|
#define IDC_VOLUMEGROUP 1204
|
||||||
#define IDC_OMITBLANK 1204
|
#define IDC_OMITBLANK 1204
|
||||||
#define IDC_CHECK3 1204
|
#define IDC_CHECK3 1204
|
||||||
|
|
|
@ -32,12 +32,15 @@ void CloseTimingDialog(HWND hwndDlg)
|
||||||
eoptions &= ~EO_NOTHROTTLE;
|
eoptions &= ~EO_NOTHROTTLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
overclocked = (IsDlgButtonChecked(hwndDlg, CB_OVERCLOCKING) == BST_CHECKED);
|
overclock_enabled = (IsDlgButtonChecked(hwndDlg, CB_OVERCLOCKING) == BST_CHECKED);
|
||||||
skip_7bit_overclocking = (IsDlgButtonChecked(hwndDlg, CB_SKIP_7BIT) == BST_CHECKED);
|
skip_7bit_overclocking = (IsDlgButtonChecked(hwndDlg, CB_SKIP_7BIT) == BST_CHECKED);
|
||||||
|
|
||||||
GetDlgItemText(hwndDlg, IDC_EXTRA_SCANLINES, str, 4);
|
GetDlgItemText(hwndDlg, IDC_EXTRA_SCANLINES, str, 4);
|
||||||
sscanf(str,"%d",&extrascanlines);
|
sscanf(str,"%d",&extrascanlines);
|
||||||
|
|
||||||
|
GetDlgItemText(hwndDlg, IDC_VBLANK_SCANLINES, str, 4);
|
||||||
|
sscanf(str,"%d",&vblankscanlines);
|
||||||
|
|
||||||
if (extrascanlines < 0)
|
if (extrascanlines < 0)
|
||||||
{
|
{
|
||||||
extrascanlines = 0;
|
extrascanlines = 0;
|
||||||
|
@ -45,14 +48,21 @@ void CloseTimingDialog(HWND hwndDlg)
|
||||||
sprintf(str,"%d",extrascanlines);
|
sprintf(str,"%d",extrascanlines);
|
||||||
SetDlgItemText(hwndDlg,IDC_EXTRA_SCANLINES,str);
|
SetDlgItemText(hwndDlg,IDC_EXTRA_SCANLINES,str);
|
||||||
}
|
}
|
||||||
else if (overclocked && newppu)
|
else if (vblankscanlines < 0)
|
||||||
|
{
|
||||||
|
vblankscanlines = 0;
|
||||||
|
MessageBox(hwndDlg, "Overclocking is when you speed up your CPU, not slow it down!", "Error", MB_OK);
|
||||||
|
sprintf(str,"%d",vblankscanlines);
|
||||||
|
SetDlgItemText(hwndDlg,IDC_VBLANK_SCANLINES,str);
|
||||||
|
}
|
||||||
|
else if (overclock_enabled && newppu)
|
||||||
{
|
{
|
||||||
MessageBox(hwndDlg, "Overclocking doesn't work with new PPU!", "Error", MB_OK);
|
MessageBox(hwndDlg, "Overclocking doesn't work with new PPU!", "Error", MB_OK);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
EndDialog(hwndDlg, 0);
|
EndDialog(hwndDlg, 0);
|
||||||
|
|
||||||
totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0);
|
totalscanlines = normalscanlines + (overclock_enabled ? extrascanlines : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,16 +85,20 @@ BOOL CALLBACK TimingConCallB(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||||
CheckDlgButton(hwndDlg, CB_DISABLE_SPEED_THROTTLING, BST_CHECKED);
|
CheckDlgButton(hwndDlg, CB_DISABLE_SPEED_THROTTLING, BST_CHECKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(overclocked)
|
if(overclock_enabled)
|
||||||
CheckDlgButton(hwndDlg, CB_OVERCLOCKING, BST_CHECKED);
|
CheckDlgButton(hwndDlg, CB_OVERCLOCKING, BST_CHECKED);
|
||||||
|
|
||||||
if(skip_7bit_overclocking)
|
if(skip_7bit_overclocking)
|
||||||
CheckDlgButton(hwndDlg, CB_SKIP_7BIT, BST_CHECKED);
|
CheckDlgButton(hwndDlg, CB_SKIP_7BIT, BST_CHECKED);
|
||||||
|
|
||||||
SendDlgItemMessage(hwndDlg,IDC_EXTRA_SCANLINES,EM_SETLIMITTEXT,3,0);
|
SendDlgItemMessage(hwndDlg,IDC_EXTRA_SCANLINES, EM_SETLIMITTEXT,3,0);
|
||||||
|
SendDlgItemMessage(hwndDlg,IDC_VBLANK_SCANLINES,EM_SETLIMITTEXT,3,0);
|
||||||
|
|
||||||
sprintf(str,"%d",extrascanlines);
|
sprintf(str,"%d",extrascanlines);
|
||||||
SetDlgItemText(hwndDlg,IDC_EXTRA_SCANLINES,str);
|
SetDlgItemText(hwndDlg,IDC_EXTRA_SCANLINES,str);
|
||||||
|
|
||||||
|
sprintf(str,"%d",vblankscanlines);
|
||||||
|
SetDlgItemText(hwndDlg,IDC_VBLANK_SCANLINES,str);
|
||||||
|
|
||||||
CenterWindowOnScreen(hwndDlg);
|
CenterWindowOnScreen(hwndDlg);
|
||||||
|
|
||||||
|
|
|
@ -95,12 +95,14 @@ using namespace std;
|
||||||
// overclock the console by adding dummy scanlines to PPU loop
|
// overclock the console by adding dummy scanlines to PPU loop
|
||||||
// disables DMC DMA and WaveHi filling for these dummies
|
// disables DMC DMA and WaveHi filling for these dummies
|
||||||
// doesn't work with new PPU
|
// doesn't work with new PPU
|
||||||
bool overclocked = 0;
|
bool overclock_enabled = 0;
|
||||||
// 7-bit samples have priority over overclocking
|
// 7-bit samples have priority over overclocking
|
||||||
bool skip_7bit_overclocking = 1;
|
bool skip_7bit_overclocking = 1;
|
||||||
int normalscanlines;
|
int normalscanlines;
|
||||||
int extrascanlines = 0;
|
int extrascanlines = 0;
|
||||||
int totalscanlines;
|
int totalscanlines;
|
||||||
|
int vblankscanlines = 0;
|
||||||
|
bool overclocking = 0;
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
int AFon = 1, AFoff = 1, AutoFireOffset = 0; //For keeping track of autofire settings
|
int AFon = 1, AFoff = 1, AutoFireOffset = 0; //For keeping track of autofire settings
|
||||||
|
@ -149,7 +151,7 @@ void FCEU_TogglePPU(void) {
|
||||||
if (newppu) {
|
if (newppu) {
|
||||||
FCEU_DispMessage("New PPU loaded", 0);
|
FCEU_DispMessage("New PPU loaded", 0);
|
||||||
FCEUI_printf("New PPU loaded");
|
FCEUI_printf("New PPU loaded");
|
||||||
overclocked = 0;
|
overclock_enabled = 0;
|
||||||
} else {
|
} else {
|
||||||
FCEU_DispMessage("Old PPU loaded", 0);
|
FCEU_DispMessage("Old PPU loaded", 0);
|
||||||
FCEUI_printf("Old PPU loaded");
|
FCEUI_printf("Old PPU loaded");
|
||||||
|
@ -727,6 +729,7 @@ void FCEUI_Emulate(uint8 **pXBuf, int32 **SoundBuf, int32 *SoundBufSize, int ski
|
||||||
|
|
||||||
timestampbase += timestamp;
|
timestampbase += timestamp;
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
|
soundtimestamp = 0;
|
||||||
|
|
||||||
*pXBuf = skip ? 0 : XBuf;
|
*pXBuf = skip ? 0 : XBuf;
|
||||||
if (skip == 2) { //If skip = 2, then bypass sound
|
if (skip == 2) { //If skip = 2, then bypass sound
|
||||||
|
@ -873,10 +876,10 @@ void FCEU_ResetVidSys(void) {
|
||||||
PAL = w ? 1 : 0;
|
PAL = w ? 1 : 0;
|
||||||
|
|
||||||
if (newppu)
|
if (newppu)
|
||||||
overclocked = 0;
|
overclock_enabled = 0;
|
||||||
|
|
||||||
normalscanlines = (dendy ? 290 : 240)+newppu; // use flag as number!
|
normalscanlines = (dendy ? 290 : 240)+newppu; // use flag as number!
|
||||||
totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0);
|
totalscanlines = normalscanlines + (overclock_enabled ? extrascanlines : 0);
|
||||||
FCEUPPU_SetVideoSystem(w || dendy);
|
FCEUPPU_SetVideoSystem(w || dendy);
|
||||||
SetSoundVariables();
|
SetSoundVariables();
|
||||||
}
|
}
|
||||||
|
@ -965,7 +968,7 @@ void FCEUI_SetRegion(int region) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
normalscanlines += newppu;
|
normalscanlines += newppu;
|
||||||
totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0);
|
totalscanlines = normalscanlines + (overclock_enabled ? extrascanlines : 0);
|
||||||
FCEUI_SetVidSystem(pal_emulation);
|
FCEUI_SetVidSystem(pal_emulation);
|
||||||
RefreshThrottleFPS();
|
RefreshThrottleFPS();
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
|
|
@ -8,11 +8,13 @@ extern int newppu;
|
||||||
void ResetGameLoaded(void);
|
void ResetGameLoaded(void);
|
||||||
|
|
||||||
//overclocking-related
|
//overclocking-related
|
||||||
extern bool overclocked;
|
extern bool overclock_enabled;
|
||||||
extern bool skip_7bit_overclocking;
|
extern bool skip_7bit_overclocking;
|
||||||
extern int normalscanlines;
|
extern int normalscanlines;
|
||||||
extern int extrascanlines;
|
extern int extrascanlines;
|
||||||
extern int totalscanlines;
|
extern int totalscanlines;
|
||||||
|
extern int vblankscanlines;
|
||||||
|
extern bool overclocking;
|
||||||
|
|
||||||
extern bool AutoResumePlay;
|
extern bool AutoResumePlay;
|
||||||
extern char romNameWhenClosingEmulator[];
|
extern char romNameWhenClosingEmulator[];
|
||||||
|
|
|
@ -1747,6 +1747,12 @@ int FCEUPPU_Loop(int skip) {
|
||||||
TriggerNMI();
|
TriggerNMI();
|
||||||
}
|
}
|
||||||
X6502_Run((scanlines_per_frame - 242) * (256 + 85) - 12);
|
X6502_Run((scanlines_per_frame - 242) * (256 + 85) - 12);
|
||||||
|
if (vblankscanlines)
|
||||||
|
{
|
||||||
|
overclocking = 1;
|
||||||
|
X6502_Run(vblankscanlines * (256 + 85) - 12);
|
||||||
|
overclocking = 0;
|
||||||
|
}
|
||||||
PPU_status &= 0x1f;
|
PPU_status &= 0x1f;
|
||||||
X6502_Run(256);
|
X6502_Run(256);
|
||||||
|
|
||||||
|
@ -1809,13 +1815,17 @@ int FCEUPPU_Loop(int skip) {
|
||||||
if (DMC_7bit && skip_7bit_overclocking)
|
if (DMC_7bit && skip_7bit_overclocking)
|
||||||
totalscanlines = normalscanlines;
|
totalscanlines = normalscanlines;
|
||||||
else
|
else
|
||||||
totalscanlines = normalscanlines + (overclocked ? extrascanlines : 0);
|
totalscanlines = normalscanlines + (overclock_enabled ? extrascanlines : 0);
|
||||||
|
|
||||||
for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/
|
for (scanline = 0; scanline < totalscanlines; ) { //scanline is incremented in DoLine. Evil. :/
|
||||||
deempcnt[deemp]++;
|
deempcnt[deemp]++;
|
||||||
if (scanline < normalscanlines)
|
if (scanline < normalscanlines)
|
||||||
DEBUG(FCEUD_UpdatePPUView(scanline, 1));
|
DEBUG(FCEUD_UpdatePPUView(scanline, 1));
|
||||||
DoLine();
|
DoLine();
|
||||||
|
if (scanline < normalscanlines || scanline == totalscanlines)
|
||||||
|
overclocking = 0;
|
||||||
|
else
|
||||||
|
overclocking = 1;
|
||||||
}
|
}
|
||||||
DMC_7bit = 0;
|
DMC_7bit = 0;
|
||||||
|
|
||||||
|
|
|
@ -1052,7 +1052,7 @@ int FlushEmulateSound(void)
|
||||||
int x;
|
int x;
|
||||||
int32 end,left;
|
int32 end,left;
|
||||||
|
|
||||||
if(!timestamp) return(0);
|
if(!soundtimestamp) return(0);
|
||||||
|
|
||||||
if(!FSettings.SndRate)
|
if(!FSettings.SndRate)
|
||||||
{
|
{
|
||||||
|
@ -1073,7 +1073,7 @@ int FlushEmulateSound(void)
|
||||||
|
|
||||||
if(GameExpSound.HiFill) GameExpSound.HiFill();
|
if(GameExpSound.HiFill) GameExpSound.HiFill();
|
||||||
|
|
||||||
for(x=timestamp;x;x--)
|
for(x=soundtimestamp;x;x--)
|
||||||
{
|
{
|
||||||
uint32 b=*tmpo;
|
uint32 b=*tmpo;
|
||||||
*tmpo=(b&65535)+wlookup2[(b>>16)&255]+wlookup1[b>>24];
|
*tmpo=(b&65535)+wlookup2[(b>>16)&255]+wlookup1[b>>24];
|
||||||
|
|
|
@ -59,7 +59,7 @@ extern unsigned char *cdloggerdata;
|
||||||
|
|
||||||
extern uint32 soundtsoffs;
|
extern uint32 soundtsoffs;
|
||||||
extern bool swapDuty;
|
extern bool swapDuty;
|
||||||
#define SOUNDTS (timestamp + soundtsoffs)
|
#define SOUNDTS (soundtimestamp + soundtsoffs)
|
||||||
|
|
||||||
void SetNESSoundMap(void);
|
void SetNESSoundMap(void);
|
||||||
void FrameSoundUpdate(void);
|
void FrameSoundUpdate(void);
|
||||||
|
|
|
@ -32,6 +32,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
X6502 X;
|
X6502 X;
|
||||||
uint32 timestamp;
|
uint32 timestamp;
|
||||||
|
uint32 soundtimestamp;
|
||||||
void (*MapIRQHook)(int a);
|
void (*MapIRQHook)(int a);
|
||||||
|
|
||||||
#define ADDCYC(x) \
|
#define ADDCYC(x) \
|
||||||
|
@ -39,7 +40,8 @@ void (*MapIRQHook)(int a);
|
||||||
int __x=x; \
|
int __x=x; \
|
||||||
_tcount+=__x; \
|
_tcount+=__x; \
|
||||||
_count-=__x*48; \
|
_count-=__x*48; \
|
||||||
if (scanline < normalscanlines || scanline == totalscanlines) timestamp+=__x; \
|
timestamp+=__x; \
|
||||||
|
if(!overclocking) soundtimestamp+=__x; \
|
||||||
}
|
}
|
||||||
|
|
||||||
//normal memory read
|
//normal memory read
|
||||||
|
@ -408,7 +410,7 @@ void X6502_Power(void)
|
||||||
{
|
{
|
||||||
_count=_tcount=_IRQlow=_PC=_A=_X=_Y=_P=_PI=_DB=_jammed=0;
|
_count=_tcount=_IRQlow=_PC=_A=_X=_Y=_P=_PI=_DB=_jammed=0;
|
||||||
_S=0xFD;
|
_S=0xFD;
|
||||||
timestamp=0;
|
timestamp=soundtimestamp=0;
|
||||||
X6502_Reset();
|
X6502_Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,7 +496,7 @@ extern int test; test++;
|
||||||
_tcount=0;
|
_tcount=0;
|
||||||
if(MapIRQHook) MapIRQHook(temp);
|
if(MapIRQHook) MapIRQHook(temp);
|
||||||
|
|
||||||
if (scanline < normalscanlines || scanline == totalscanlines)
|
if (!overclocking)
|
||||||
FCEU_SoundCPUHook(temp);
|
FCEU_SoundCPUHook(temp);
|
||||||
#ifdef _S9XLUA_H
|
#ifdef _S9XLUA_H
|
||||||
CallRegisteredLuaMemHook(_PC, 1, 0, LUAMEMHOOK_EXEC);
|
CallRegisteredLuaMemHook(_PC, 1, 0, LUAMEMHOOK_EXEC);
|
||||||
|
|
|
@ -47,9 +47,8 @@ void X6502_RunDebug(int32 cycles);
|
||||||
//------------
|
//------------
|
||||||
|
|
||||||
extern uint32 timestamp;
|
extern uint32 timestamp;
|
||||||
|
extern uint32 soundtimestamp;
|
||||||
extern int scanline;
|
extern int scanline;
|
||||||
extern int normalscanlines;
|
|
||||||
extern int totalscanlines;
|
|
||||||
|
|
||||||
#define N_FLAG 0x80
|
#define N_FLAG 0x80
|
||||||
#define V_FLAG 0x40
|
#define V_FLAG 0x40
|
||||||
|
|
Loading…
Reference in New Issue