mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-23 12:32:34 +00:00
- Implemented some more controllers for the OPL player:
* RPN select (controllers 100 and 101) * RPN 0 (pitch bend sensitivity) * NPRN select (controllers 98 and 99) * Data entry (controllers 6 and 38) * All notes off (controller 123) * All sounds off (controller 120) * Reset controllers (controller 121) SVN r1195 (trunk)
This commit is contained in:
parent
49565ccb84
commit
fae19e87b7
8 changed files with 321 additions and 65 deletions
|
@ -82,9 +82,9 @@ void musicBlock::writeModulation(uint slot, struct OPL2instrument *instr, int st
|
|||
instr->trem_vibr_2 | state);
|
||||
}
|
||||
|
||||
uint musicBlock::calcVolume(uint channelVolume, uint MUSvolume, uint noteVolume)
|
||||
uint musicBlock::calcVolume(uint channelVolume, uint channelExpression, uint noteVolume)
|
||||
{
|
||||
noteVolume = ((ulong)channelVolume * MUSvolume * noteVolume) / (256*127);
|
||||
noteVolume = ((ulong)channelVolume * channelExpression * noteVolume) / (127*127);
|
||||
if (noteVolume > 127)
|
||||
return 127;
|
||||
else
|
||||
|
@ -107,7 +107,8 @@ int musicBlock::occupyChannel(uint slot, uint channel,
|
|||
volume = driverdata.channelLastVolume[channel];
|
||||
else
|
||||
driverdata.channelLastVolume[channel] = volume;
|
||||
ch->realvolume = calcVolume(driverdata.channelVolume[channel], 256, ch->volume = volume);
|
||||
ch->realvolume = calcVolume(driverdata.channelVolume[channel],
|
||||
driverdata.channelExpression[channel], ch->volume = volume);
|
||||
if (instrument->flags & FL_FIXED_PITCH)
|
||||
note = instrument->note;
|
||||
else if (channel == PERCUSSION)
|
||||
|
@ -273,7 +274,9 @@ void musicBlock::OPLpitchWheel(uint channel, int pitch)
|
|||
uint i;
|
||||
uint id = channel;
|
||||
|
||||
pitch >>= 7;
|
||||
// Convert pitch from 14-bit to 7-bit, then scale it, since the player
|
||||
// code only understands sensitivities of 2 semitones.
|
||||
pitch = (pitch - 8192) * driverdata.channelPitchSens[channel] / (200 * 128) + 64;
|
||||
driverdata.channelPitch[channel] = pitch;
|
||||
for(i = 0; i < io->OPLchannels; i++)
|
||||
{
|
||||
|
@ -298,6 +301,7 @@ void musicBlock::OPLchangeControl(uint channel, uchar controller, int value)
|
|||
case ctrlPatch: /* change instrument */
|
||||
OPLprogramChange(channel, value);
|
||||
break;
|
||||
|
||||
case ctrlModulation:
|
||||
driverdata.channelModulation[channel] = value;
|
||||
for(i = 0; i < io->OPLchannels; i++)
|
||||
|
@ -320,19 +324,28 @@ void musicBlock::OPLchangeControl(uint channel, uchar controller, int value)
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrlVolume: /* change volume */
|
||||
driverdata.channelVolume[channel] = value;
|
||||
/* fall-through */
|
||||
case ctrlExpression: /* change expression */
|
||||
if (controller == ctrlExpression)
|
||||
{
|
||||
driverdata.channelExpression[channel] = value;
|
||||
}
|
||||
for(i = 0; i < io->OPLchannels; i++)
|
||||
{
|
||||
struct channelEntry *ch = &channels[i];
|
||||
if (ch->channel == id)
|
||||
{
|
||||
ch->time = MLtime;
|
||||
ch->realvolume = calcVolume(value, 256, ch->volume);
|
||||
ch->realvolume = calcVolume(driverdata.channelVolume[channel],
|
||||
driverdata.channelExpression[channel], ch->volume);
|
||||
io->OPLwriteVolume(i, ch->instr, ch->realvolume);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrlPan: /* change pan (balance) */
|
||||
driverdata.channelPan[channel] = value -= 64;
|
||||
for(i = 0; i < io->OPLchannels; i++)
|
||||
|
@ -345,14 +358,76 @@ void musicBlock::OPLchangeControl(uint channel, uchar controller, int value)
|
|||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrlSustainPedal: /* change sustain pedal (hold) */
|
||||
driverdata.channelSustain[channel] = value;
|
||||
if (value < 0x40)
|
||||
releaseSustain(channel);
|
||||
break;
|
||||
|
||||
case ctrlNotesOff: /* turn off all notes that are not sustained */
|
||||
for (i = 0; i < io->OPLchannels; ++i)
|
||||
{
|
||||
if (channels[i].channel == id)
|
||||
{
|
||||
if (driverdata.channelSustain[id] < 0x40)
|
||||
releaseChannel(i, 0);
|
||||
else
|
||||
channels[i].flags |= CH_SUSTAIN;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrlSoundsOff: /* release all notes for this channel */
|
||||
for (i = 0; i < io->OPLchannels; ++i)
|
||||
{
|
||||
if (channels[i].channel == id)
|
||||
{
|
||||
releaseChannel(i, 0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrlRPNHi:
|
||||
driverdata.channelRPN[id] = (driverdata.channelRPN[id] & 0x007F) | (value << 7);
|
||||
break;
|
||||
|
||||
case ctrlRPNLo:
|
||||
driverdata.channelRPN[id] = (driverdata.channelRPN[id] & 0x3F80) | value;
|
||||
break;
|
||||
|
||||
case ctrlNRPNLo:
|
||||
case ctrlNRPNHi:
|
||||
driverdata.channelRPN[id] = 0x3FFF;
|
||||
break;
|
||||
|
||||
case ctrlDataEntryHi:
|
||||
if (driverdata.channelRPN[id] == 0)
|
||||
{
|
||||
driverdata.channelPitchSens[id] = value * 100 + (driverdata.channelPitchSens[id] % 100);
|
||||
}
|
||||
break;
|
||||
|
||||
case ctrlDataEntryLo:
|
||||
if (driverdata.channelRPN[id] == 0)
|
||||
{
|
||||
driverdata.channelPitchSens[id] = value + (driverdata.channelPitchSens[id] / 100) * 100;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void musicBlock::OPLresetControllers(uint chan, int vol)
|
||||
{
|
||||
driverdata.channelVolume[chan] = vol;
|
||||
driverdata.channelExpression[chan] = 127;
|
||||
driverdata.channelSustain[chan] = 0;
|
||||
driverdata.channelLastVolume[chan] = 64;
|
||||
driverdata.channelPitch[chan] = 64;
|
||||
driverdata.channelRPN[chan] = 0x3fff;
|
||||
driverdata.channelPitchSens[chan] = 200;
|
||||
}
|
||||
|
||||
void musicBlock::OPLprogramChange(uint channel, int value)
|
||||
{
|
||||
driverdata.channelInstr[channel] = value;
|
||||
|
@ -364,10 +439,7 @@ void musicBlock::OPLplayMusic(int vol)
|
|||
|
||||
for (i = 0; i < CHANNELS; i++)
|
||||
{
|
||||
driverdata.channelVolume[i] = vol; /* default volume 127 for MUS (full volume) */
|
||||
driverdata.channelSustain[i] = 0;
|
||||
driverdata.channelLastVolume[i] = 64;
|
||||
driverdata.channelPitch[i] = 64;
|
||||
OPLresetControllers(i, vol);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -379,18 +451,6 @@ void musicBlock::OPLstopMusic()
|
|||
releaseChannel(i, 1);
|
||||
}
|
||||
|
||||
void musicBlock::OPLchangeVolume(uint volume)
|
||||
{
|
||||
uchar *channelVolume = driverdata.channelVolume;
|
||||
uint i;
|
||||
for(i = 0; i < io->OPLchannels; i++)
|
||||
{
|
||||
struct channelEntry *ch = &channels[i];
|
||||
ch->realvolume = calcVolume(channelVolume[ch->channel & 0xF], volume, ch->volume);
|
||||
io->OPLwriteVolume(i, ch->instr, ch->realvolume);
|
||||
}
|
||||
}
|
||||
|
||||
int musicBlock::OPLloadBank (FileReader &data)
|
||||
{
|
||||
static const uchar masterhdr[8] = { '#','O','P','L','_','I','I','#' };
|
||||
|
|
|
@ -468,15 +468,21 @@ void OPLMIDIDevice::HandleEvent(int status, int parm1, int parm2)
|
|||
{
|
||||
case 0: OPLchangeControl(channel, ctrlBank, parm2); break;
|
||||
case 1: OPLchangeControl(channel, ctrlModulation, parm2); break;
|
||||
case 6: OPLchangeControl(channel, ctrlDataEntryHi, parm2); break;
|
||||
case 7: OPLchangeControl(channel, ctrlVolume, parm2); break;
|
||||
case 10: OPLchangeControl(channel, ctrlPan, parm2); break;
|
||||
case 11: OPLchangeControl(channel, ctrlExpression, parm2); break;
|
||||
case 38: OPLchangeControl(channel, ctrlDataEntryLo, parm2); break;
|
||||
case 64: OPLchangeControl(channel, ctrlSustainPedal, parm2); break;
|
||||
case 67: OPLchangeControl(channel, ctrlSoftPedal, parm2); break;
|
||||
case 91: OPLchangeControl(channel, ctrlReverb, parm2); break;
|
||||
case 93: OPLchangeControl(channel, ctrlChorus, parm2); break;
|
||||
case 98: OPLchangeControl(channel, ctrlNRPNLo, parm2); break;
|
||||
case 99: OPLchangeControl(channel, ctrlNRPNHi, parm2); break;
|
||||
case 100: OPLchangeControl(channel, ctrlRPNLo, parm2); break;
|
||||
case 101: OPLchangeControl(channel, ctrlRPNHi, parm2); break;
|
||||
case 120: OPLchangeControl(channel, ctrlSoundsOff, parm2); break;
|
||||
case 121: OPLchangeControl(channel, ctrlResetCtrls, parm2); break;
|
||||
case 121: OPLresetControllers(channel, 100); break;
|
||||
case 123: OPLchangeControl(channel, ctrlNotesOff, parm2); break;
|
||||
case 126: OPLchangeControl(channel, ctrlMono, parm2); break;
|
||||
case 127: OPLchangeControl(channel, ctrlPoly, parm2); break;
|
||||
|
|
|
@ -154,9 +154,12 @@ struct OPLdata {
|
|||
uchar channelVolume[CHANNELS]; // volume
|
||||
uchar channelLastVolume[CHANNELS]; // last volume
|
||||
schar channelPan[CHANNELS]; // pan, 0=normal
|
||||
schar channelPitch[CHANNELS]; // pitch wheel, 0=normal
|
||||
schar channelPitch[CHANNELS]; // pitch wheel, 64=normal
|
||||
uchar channelSustain[CHANNELS]; // sustain pedal value
|
||||
uchar channelModulation[CHANNELS]; // modulation pot value
|
||||
ushort channelPitchSens[CHANNELS]; // pitch sensitivity, 2=default
|
||||
ushort channelRPN[CHANNELS]; // RPN number for data entry
|
||||
uchar channelExpression[CHANNELS]; // expression
|
||||
};
|
||||
|
||||
struct OPLio {
|
||||
|
@ -227,9 +230,9 @@ struct musicBlock {
|
|||
void OPLpitchWheel(uint channel, int pitch);
|
||||
void OPLchangeControl(uint channel, uchar controller, int value);
|
||||
void OPLprogramChange(uint channel, int value);
|
||||
void OPLresetControllers(uint channel, int vol);
|
||||
void OPLplayMusic(int vol);
|
||||
void OPLstopMusic();
|
||||
void OPLchangeVolume(uint volume);
|
||||
|
||||
int OPLloadBank (FileReader &data);
|
||||
|
||||
|
@ -250,7 +253,7 @@ protected:
|
|||
|
||||
void writeFrequency(uint slot, uint note, int pitch, uint keyOn);
|
||||
void writeModulation(uint slot, struct OPL2instrument *instr, int state);
|
||||
uint calcVolume(uint channelVolume, uint MUSvolume, uint noteVolume);
|
||||
uint calcVolume(uint channelVolume, uint channelExpression, uint noteVolume);
|
||||
int occupyChannel(uint slot, uint channel,
|
||||
int note, int volume, struct OP2instrEntry *instrument, uchar secondary);
|
||||
int releaseChannel(uint slot, uint killed);
|
||||
|
@ -273,12 +276,17 @@ enum MUSctrl {
|
|||
ctrlChorus,
|
||||
ctrlSustainPedal,
|
||||
ctrlSoftPedal,
|
||||
_ctrlCount_,
|
||||
ctrlSoundsOff = _ctrlCount_,
|
||||
ctrlRPNHi,
|
||||
ctrlRPNLo,
|
||||
ctrlNRPNHi,
|
||||
ctrlNRPNLo,
|
||||
ctrlDataEntryHi,
|
||||
ctrlDataEntryLo,
|
||||
|
||||
ctrlSoundsOff,
|
||||
ctrlNotesOff,
|
||||
ctrlMono,
|
||||
ctrlPoly,
|
||||
ctrlResetCtrls
|
||||
};
|
||||
|
||||
#define OPL_SAMPLE_RATE 49716.0
|
||||
|
|
143
src/v_pfx.cpp
143
src/v_pfx.cpp
|
@ -52,6 +52,9 @@ static void Palette32Generic (const PalEntry *pal);
|
|||
static void Palette32RGB (const PalEntry *pal);
|
||||
static void Palette32BGR (const PalEntry *pal);
|
||||
|
||||
static void Scale8 (BYTE *src, int srcpitch,
|
||||
void *destin, int destpitch, int destwidth, int destheight,
|
||||
fixed_t xstep, fixed_t ystep, fixed_t xfrac, fixed_t yfrac);
|
||||
static void Convert8 (BYTE *src, int srcpitch,
|
||||
void *destin, int destpitch, int destwidth, int destheight,
|
||||
fixed_t xstep, fixed_t ystep, fixed_t xfrac, fixed_t yfrac);
|
||||
|
@ -69,6 +72,11 @@ void PfxState::SetFormat (int bits, uint32 redMask, uint32 greenMask, uint32 blu
|
|||
{
|
||||
switch (bits)
|
||||
{
|
||||
case -8:
|
||||
Convert = Scale8;
|
||||
SetPalette = NULL;
|
||||
break;
|
||||
|
||||
case 8:
|
||||
Convert = Convert8;
|
||||
SetPalette = NULL;
|
||||
|
@ -132,7 +140,7 @@ void PfxState::SetFormat (int bits, uint32 redMask, uint32 greenMask, uint32 blu
|
|||
default:
|
||||
I_FatalError ("Can't draw to %d-bit displays", bits);
|
||||
}
|
||||
if (bits != 8)
|
||||
if (bits != 8 && bits != -8)
|
||||
{
|
||||
RedLeft = AnalyzeMask (redMask, &RedShift);
|
||||
GreenLeft = AnalyzeMask (greenMask, &GreenShift);
|
||||
|
@ -260,7 +268,7 @@ static void Palette32BGR (const PalEntry *pal)
|
|||
|
||||
// Bitmap converters -------------------------------------------------------
|
||||
|
||||
static void Convert8 (BYTE *src, int srcpitch,
|
||||
static void Scale8 (BYTE *src, int srcpitch,
|
||||
void *destin, int destpitch, int destwidth, int destheight,
|
||||
fixed_t xstep, fixed_t ystep, fixed_t xfrac, fixed_t yfrac)
|
||||
{
|
||||
|
@ -273,8 +281,129 @@ static void Convert8 (BYTE *src, int srcpitch,
|
|||
BYTE *dest = (BYTE *)destin;
|
||||
|
||||
if (xstep == FRACUNIT && ystep == FRACUNIT)
|
||||
{
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
memcpy(dest, src, destwidth);
|
||||
dest += destpitch;
|
||||
src += srcpitch;
|
||||
}
|
||||
}
|
||||
else if (xstep == FRACUNIT/2 && ystep == FRACUNIT/2)
|
||||
{
|
||||
BYTE *dest2 = dest + destpitch;
|
||||
destpitch = destpitch * 2 - destwidth;
|
||||
srcpitch -= destwidth / 2;
|
||||
for (y = destheight / 2; y != 0; --y)
|
||||
{
|
||||
for (x = destwidth / 2; x != 0; --x)
|
||||
{
|
||||
BYTE foo = src[0];
|
||||
dest[0] = foo;
|
||||
dest[1] = foo;
|
||||
dest2[0] = foo;
|
||||
dest2[1] = foo;
|
||||
dest += 2;
|
||||
dest2 += 2;
|
||||
src += 1;
|
||||
}
|
||||
dest += destpitch;
|
||||
dest2 += destpitch;
|
||||
src += srcpitch;
|
||||
}
|
||||
}
|
||||
else if (xstep == FRACUNIT/4 && ystep == FRACUNIT/4)
|
||||
{
|
||||
int gap = destpitch * 4 - destwidth;
|
||||
srcpitch -= destwidth / 4;
|
||||
for (y = destheight / 4; y != 0; --y)
|
||||
{
|
||||
for (BYTE *end = dest + destpitch; dest != end; dest += 4)
|
||||
{
|
||||
BYTE foo = src[0];
|
||||
dest[0] = foo;
|
||||
dest[1] = foo;
|
||||
dest[2] = foo;
|
||||
dest[3] = foo;
|
||||
dest[0 + destpitch] = foo;
|
||||
dest[1 + destpitch] = foo;
|
||||
dest[2 + destpitch] = foo;
|
||||
dest[3 + destpitch] = foo;
|
||||
dest[0 + destpitch*2] = foo;
|
||||
dest[1 + destpitch*2] = foo;
|
||||
dest[2 + destpitch*2] = foo;
|
||||
dest[3 + destpitch*2] = foo;
|
||||
dest[0 + destpitch*3] = foo;
|
||||
dest[1 + destpitch*3] = foo;
|
||||
dest[2 + destpitch*3] = foo;
|
||||
dest[3 + destpitch*3] = foo;
|
||||
src += 1;
|
||||
}
|
||||
dest += gap;
|
||||
src += srcpitch;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
destpitch -= destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
fixed_t xf = xfrac;
|
||||
x = destwidth;
|
||||
while (((size_t)dest & 3) && x != 0)
|
||||
{
|
||||
*dest++ = src[xf >> FRACBITS];
|
||||
xf += xstep;
|
||||
x--;
|
||||
}
|
||||
for (savedx = x, x >>= 2; x != 0; x--)
|
||||
{
|
||||
DWORD work;
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
work = src[xf >> FRACBITS] << 24; xf += xstep;
|
||||
work |= src[xf >> FRACBITS] << 16; xf += xstep;
|
||||
work |= src[xf >> FRACBITS] << 8; xf += xstep;
|
||||
work |= src[xf >> FRACBITS]; xf += xstep;
|
||||
#else
|
||||
work = src[xf >> FRACBITS]; xf += xstep;
|
||||
work |= src[xf >> FRACBITS] << 8; xf += xstep;
|
||||
work |= src[xf >> FRACBITS] << 16; xf += xstep;
|
||||
work |= src[xf >> FRACBITS] << 24; xf += xstep;
|
||||
#endif
|
||||
*(DWORD *)dest = work;
|
||||
dest += 4;
|
||||
}
|
||||
for (savedx &= 3; savedx != 0; savedx--, xf += xstep)
|
||||
{
|
||||
*dest++ = src[xf >> FRACBITS];
|
||||
}
|
||||
yfrac += ystep;
|
||||
while (yfrac >= FRACUNIT)
|
||||
{
|
||||
yfrac -= FRACUNIT;
|
||||
src += srcpitch;
|
||||
}
|
||||
dest += destpitch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void Convert8 (BYTE *src, int srcpitch,
|
||||
void *destin, int destpitch, int destwidth, int destheight,
|
||||
fixed_t xstep, fixed_t ystep, fixed_t xfrac, fixed_t yfrac)
|
||||
{
|
||||
if ((destwidth | destheight) == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int x, y, savedx;
|
||||
BYTE *dest = (BYTE *)destin;
|
||||
|
||||
destpitch -= destwidth;
|
||||
if (xstep == FRACUNIT && ystep == FRACUNIT)
|
||||
{
|
||||
srcpitch -= destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
|
@ -311,7 +440,6 @@ static void Convert8 (BYTE *src, int srcpitch,
|
|||
}
|
||||
else
|
||||
{
|
||||
destpitch -= destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
fixed_t xf = xfrac;
|
||||
|
@ -367,9 +495,9 @@ static void Convert16 (BYTE *src, int srcpitch,
|
|||
int x, y, savedx;
|
||||
WORD *dest = (WORD *)destin;
|
||||
|
||||
destpitch = (destpitch >> 1) - destwidth;
|
||||
if (xstep == FRACUNIT && ystep == FRACUNIT)
|
||||
{
|
||||
destpitch = (destpitch >> 1) - destwidth;
|
||||
srcpitch -= destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
|
@ -402,7 +530,6 @@ static void Convert16 (BYTE *src, int srcpitch,
|
|||
}
|
||||
else
|
||||
{
|
||||
destpitch = (destpitch >> 1) - destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
fixed_t xf = xfrac;
|
||||
|
@ -454,9 +581,9 @@ static void Convert24 (BYTE *src, int srcpitch,
|
|||
int x, y;
|
||||
BYTE *dest = (BYTE *)destin;
|
||||
|
||||
destpitch = destpitch - destwidth*3;
|
||||
if (xstep == FRACUNIT && ystep == FRACUNIT)
|
||||
{
|
||||
destpitch = destpitch - destwidth*3;
|
||||
srcpitch -= destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
|
@ -475,7 +602,6 @@ static void Convert24 (BYTE *src, int srcpitch,
|
|||
}
|
||||
else
|
||||
{
|
||||
destpitch = destpitch - destwidth*3;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
fixed_t xf = xfrac;
|
||||
|
@ -511,9 +637,9 @@ static void Convert32 (BYTE *src, int srcpitch,
|
|||
int x, y, savedx;
|
||||
DWORD *dest = (DWORD *)destin;
|
||||
|
||||
destpitch = (destpitch >> 2) - destwidth;
|
||||
if (xstep == FRACUNIT && ystep == FRACUNIT)
|
||||
{
|
||||
destpitch = (destpitch >> 2) - destwidth;
|
||||
srcpitch -= destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
|
@ -540,7 +666,6 @@ static void Convert32 (BYTE *src, int srcpitch,
|
|||
}
|
||||
else
|
||||
{
|
||||
destpitch -= destwidth;
|
||||
for (y = destheight; y != 0; y--)
|
||||
{
|
||||
fixed_t xf = xfrac;
|
||||
|
|
|
@ -460,6 +460,7 @@ bool D3DFB::CreateResources ()
|
|||
}
|
||||
if (FAILED(D3DDevice->CreatePixelShader (GammaFixerDef, &GammaFixerShader)))
|
||||
{
|
||||
// Cannot print during screen creation.
|
||||
// Printf ("Using Shader Model 1.4: Windowed mode gamma will not work.\n");
|
||||
GammaFixerShader = NULL;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
** Code to let ZDoom use DirectDraw 3
|
||||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2006 Randy Heit
|
||||
** Copyright 1998-2008 Randy Heit
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
@ -132,12 +132,12 @@ DDrawFB::DDrawFB (int width, int height, bool fullscreen)
|
|||
BlitSurf = NULL;
|
||||
Clipper = NULL;
|
||||
GDIPalette = NULL;
|
||||
ClipRegion = NULL;
|
||||
ClipSize = 0;
|
||||
BufferCount = 1;
|
||||
Gamma = 1.0;
|
||||
BufferPitch = Pitch;
|
||||
FlipFlags = vid_vsync ? DDFLIP_WAIT : DDFLIP_WAIT|DDFLIP_NOVSYNC;
|
||||
PixelDoubling = 0;
|
||||
|
||||
NeedGammaUpdate = false;
|
||||
NeedPalUpdate = false;
|
||||
|
@ -239,20 +239,21 @@ bool DDrawFB::CreateResources ()
|
|||
if (mode->width == Width && mode->height == Height)
|
||||
{
|
||||
TrueHeight = mode->realheight;
|
||||
PixelDoubling = mode->doubling;
|
||||
break;
|
||||
}
|
||||
}
|
||||
hr = DDraw->SetDisplayMode (Width, TrueHeight, bits = vid_displaybits, vid_refreshrate, 0);
|
||||
hr = DDraw->SetDisplayMode (Width << PixelDoubling, TrueHeight << PixelDoubling, bits = vid_displaybits, vid_refreshrate, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
hr = DDraw->SetDisplayMode (Width, TrueHeight, bits = vid_displaybits, 0, 0);
|
||||
hr = DDraw->SetDisplayMode (Width << PixelDoubling, TrueHeight << PixelDoubling, bits = vid_displaybits, 0, 0);
|
||||
bits = 32;
|
||||
while (FAILED(hr) && bits >= 8)
|
||||
{
|
||||
hr = DDraw->SetDisplayMode (Width, Height, bits, vid_refreshrate, 0);
|
||||
hr = DDraw->SetDisplayMode (Width << PixelDoubling, Height << PixelDoubling, bits, vid_refreshrate, 0);
|
||||
if (FAILED(hr))
|
||||
{
|
||||
hr = DDraw->SetDisplayMode (Width, Height, bits, 0, 0);
|
||||
hr = DDraw->SetDisplayMode (Width << PixelDoubling, Height << PixelDoubling, bits, 0, 0);
|
||||
}
|
||||
bits -= 8;
|
||||
}
|
||||
|
@ -290,6 +291,7 @@ bool DDrawFB::CreateResources ()
|
|||
// Create the primary surface
|
||||
ddsd.dwFlags = DDSD_CAPS;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE;
|
||||
// PixelDoubling = 1;
|
||||
do
|
||||
{
|
||||
hr = DDraw->CreateSurface (&ddsd, &PrimarySurf, NULL);
|
||||
|
@ -304,8 +306,8 @@ bool DDrawFB::CreateResources ()
|
|||
MaybeCreatePalette ();
|
||||
|
||||
// Resize the window to match desired dimensions
|
||||
int sizew = Width + GetSystemMetrics (SM_CXSIZEFRAME)*2;
|
||||
int sizeh = Height + GetSystemMetrics (SM_CYSIZEFRAME) * 2 +
|
||||
int sizew = (Width << PixelDoubling) + GetSystemMetrics (SM_CXSIZEFRAME)*2;
|
||||
int sizeh = (Height << PixelDoubling) + GetSystemMetrics (SM_CYSIZEFRAME) * 2 +
|
||||
GetSystemMetrics (SM_CYCAPTION);
|
||||
LOG2 ("Resize window to %dx%d\n", sizew, sizeh);
|
||||
VidResizing = true;
|
||||
|
@ -334,8 +336,8 @@ bool DDrawFB::CreateResources ()
|
|||
|
||||
// Create the backbuffer
|
||||
ddsd.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_CAPS;
|
||||
ddsd.dwWidth = Width;
|
||||
ddsd.dwHeight = Height;
|
||||
ddsd.dwWidth = Width << PixelDoubling;
|
||||
ddsd.dwHeight = Height << PixelDoubling;
|
||||
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | (UseBlitter ? DDSCAPS_SYSTEMMEMORY : 0);
|
||||
|
||||
hr = DDraw->CreateSurface (&ddsd, &BackSurf, NULL);
|
||||
|
@ -661,6 +663,11 @@ void DDrawFB::MaybeCreatePalette ()
|
|||
NeedPalUpdate = true;
|
||||
}
|
||||
}
|
||||
if (PixelDoubling)
|
||||
{
|
||||
UsePfx = true;
|
||||
GPfx.SetFormat (-8, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -681,11 +688,6 @@ void DDrawFB::ReleaseResources ()
|
|||
Unlock ();
|
||||
}
|
||||
|
||||
if (ClipRegion != NULL)
|
||||
{
|
||||
delete[] ClipRegion;
|
||||
ClipRegion = NULL;
|
||||
}
|
||||
SAFE_RELEASE( Clipper );
|
||||
SAFE_RELEASE( PrimarySurf );
|
||||
SAFE_RELEASE( BackSurf );
|
||||
|
@ -1110,8 +1112,8 @@ void DDrawFB::Update ()
|
|||
if (UsePfx)
|
||||
{
|
||||
GPfx.Convert (MemBuffer, BufferPitch,
|
||||
writept, Pitch, Width, Height,
|
||||
FRACUNIT, FRACUNIT, 0, 0);
|
||||
writept, Pitch, Width << PixelDoubling, Height << PixelDoubling,
|
||||
FRACUNIT >> PixelDoubling, FRACUNIT >> PixelDoubling, 0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1207,8 +1209,8 @@ bool DDrawFB::PaintToWindow ()
|
|||
if (LockSurf (NULL, NULL) != NoGood)
|
||||
{
|
||||
GPfx.Convert (MemBuffer, BufferPitch,
|
||||
Buffer, Pitch, Width, Height,
|
||||
FRACUNIT, FRACUNIT, 0, 0);
|
||||
Buffer, Pitch, Width << PixelDoubling, Height << PixelDoubling,
|
||||
FRACUNIT >> PixelDoubling, FRACUNIT >> PixelDoubling, 0, 0);
|
||||
LockingSurf->Unlock (NULL);
|
||||
if (FAILED (hr = PrimarySurf->Blt (&rect, BackSurf, NULL, DDBLT_WAIT|DDBLT_ASYNC, NULL)))
|
||||
{
|
||||
|
|
|
@ -108,6 +108,7 @@ class Win32Video : public IVideo
|
|||
void AddD3DModes (D3DFORMAT format);
|
||||
void AddLowResModes ();
|
||||
void AddLetterboxModes ();
|
||||
void ScaleModes (int doubling);
|
||||
|
||||
friend class DDrawFB;
|
||||
friend class D3DFB;
|
||||
|
@ -193,13 +194,13 @@ private:
|
|||
LPDIRECTDRAWSURFACE LockingSurf;
|
||||
LPDIRECTDRAWCLIPPER Clipper;
|
||||
HPALETTE GDIPalette;
|
||||
BYTE *ClipRegion;
|
||||
DWORD ClipSize;
|
||||
PalEntry Flash;
|
||||
int FlashAmount;
|
||||
int BufferCount;
|
||||
int BufferPitch;
|
||||
int TrueHeight;
|
||||
int PixelDoubling;
|
||||
float Gamma;
|
||||
|
||||
bool NeedGammaUpdate;
|
||||
|
|
|
@ -185,7 +185,18 @@ bool Win32Video::InitD3D9 ()
|
|||
FreeModes ();
|
||||
AddD3DModes (D3DFMT_X8R8G8B8);
|
||||
AddD3DModes (D3DFMT_R5G6B5);
|
||||
AddLowResModes ();
|
||||
if (Args->CheckParm ("-2"))
|
||||
{ // Force all modes to be pixel-doubled.
|
||||
ScaleModes (1);
|
||||
}
|
||||
else if (Args->CheckParm ("-4"))
|
||||
{ // Force all modes to be pixel-quadrupled.
|
||||
ScaleModes (2);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLowResModes ();
|
||||
}
|
||||
AddLetterboxModes ();
|
||||
if (m_Modes == NULL)
|
||||
{ // Too bad. We didn't find any modes for D3D9. We probably won't find any
|
||||
|
@ -256,12 +267,24 @@ void Win32Video::InitDDraw ()
|
|||
"If you started ZDoom from a fullscreen DOS box, run it from "
|
||||
"a DOS window instead. If that does not work, you may need to reboot.");
|
||||
}
|
||||
if (OSPlatform == os_Win95)
|
||||
if (Args->CheckParm ("-2"))
|
||||
{ // Force all modes to be pixel-doubled.
|
||||
ScaleModes(1);
|
||||
}
|
||||
else if (Args->CheckParm ("-4"))
|
||||
{ // Force all modes to be pixel-quadrupled.
|
||||
ScaleModes(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Windows 95 will let us use Mode X. If we didn't find any linear
|
||||
// modes in the loop above, add the Mode X modes here.
|
||||
AddMode (320, 200, 8, 200, 0);
|
||||
AddMode (320, 240, 8, 240, 0);
|
||||
if (OSPlatform == os_Win95)
|
||||
{
|
||||
// Windows 95 will let us use Mode X. If we didn't find any linear
|
||||
// modes in the loop above, add the Mode X modes here.
|
||||
AddMode (320, 200, 8, 200, 0);
|
||||
AddMode (320, 240, 8, 240, 0);
|
||||
}
|
||||
AddLowResModes ();
|
||||
}
|
||||
AddLetterboxModes ();
|
||||
}
|
||||
|
@ -358,7 +381,7 @@ void Win32Video::AddLowResModes()
|
|||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height &&
|
||||
mode->doubling == 0&&
|
||||
mode->doubling == 0 &&
|
||||
mode->height >= 200*2 &&
|
||||
mode->height <= 480*2 &&
|
||||
mode->width >= 320*2 &&
|
||||
|
@ -371,7 +394,7 @@ void Win32Video::AddLowResModes()
|
|||
{
|
||||
nextmode = mode->next;
|
||||
if (mode->realheight == mode->height &&
|
||||
mode->doubling == 0&&
|
||||
mode->doubling == 0 &&
|
||||
mode->height >= 200*4 &&
|
||||
mode->height <= 480*4 &&
|
||||
mode->width >= 320*4 &&
|
||||
|
@ -455,6 +478,36 @@ void Win32Video::FreeModes ()
|
|||
m_Modes = NULL;
|
||||
}
|
||||
|
||||
// For every mode, set its scaling factor. Modes that end up with too
|
||||
// small a display area are discarded.
|
||||
|
||||
void Win32Video::ScaleModes (int doubling)
|
||||
{
|
||||
ModeInfo *mode, **prev;
|
||||
|
||||
prev = &m_Modes;
|
||||
mode = m_Modes;
|
||||
|
||||
while (mode != NULL)
|
||||
{
|
||||
assert(mode->doubling == 0);
|
||||
mode->width >>= doubling;
|
||||
mode->height >>= doubling;
|
||||
mode->realheight >>= doubling;
|
||||
mode->doubling = doubling;
|
||||
if ((mode->width & 7) != 0 || mode->width < 320 || mode->height < 200)
|
||||
{ // Mode became too small. Delete it.
|
||||
*prev = mode->next;
|
||||
delete mode;
|
||||
}
|
||||
else
|
||||
{
|
||||
prev = &mode->next;
|
||||
}
|
||||
mode = *prev;
|
||||
}
|
||||
}
|
||||
|
||||
void Win32Video::StartModeIterator (int bits, bool fs)
|
||||
{
|
||||
m_IteratorMode = m_Modes;
|
||||
|
|
Loading…
Reference in a new issue