diff --git a/release/whatsnew.txt b/release/whatsnew.txt index 39b45e58e..90c792a7e 100644 --- a/release/whatsnew.txt +++ b/release/whatsnew.txt @@ -25,19 +25,24 @@ Version 3.6 (XX XXth, 2024) - "Sounds good III" Updated LISY support to 5.28-91 (Linux for Gottlieb System1 & System80, Bally, Atari, Williams and 'Home' Pinballs) -Fix Capcom crashes in 64bit builds, reworked Capcom timings allowing all tables to behave 'normally' (no more delay on Flipper Football, DMD's animation at the right speed,...). +Fix Capcom crashes in 64bit builds Fix some external DMD alphanumeric mappings: GTS80B, GTS3, Hankin, Police Force, Riverboat Gambler, Algar, Alien Poker and 7 digit variants of Firepower -Added the emulation of physical bulbs & LEDs connected to binary outputs for WPC, GTS3, SAM, Whitestar and S11 hardware. This allows to dramatically improve e.g. lamp or flasher modulation (for example - the pulsing lights below the princess of TOTAN, or the Sauron eye of LOTR, or slowly fading lamps in Breakshot). This needs to be enabled before use, the same way as for the existing 'modulated' - solenoids: by setting SolMask(2) which is now a bitmask 1 is legacy modulated solenoids, 2 is physic model for solenoid outputs, 4 is physic model for lamps/GIs/Segment outputs. To be emulated correctly, - device connected to binary output must be defined. PinMame already has teh definition for lots of them (to be found in MACHINE_INIT of each driver) but if the one you want is missing, or you want to modify - it, use SolMask(xx) = type to change it where xx is the output to be modified (see vp_setSolMask), and yy is the type (see core.h). - This also opens the path for emulation of dimmed alphanum segments and strength modulated solenoids (for example Capcom Kingpin, or the way most modern hardware handle Power/Hold and EOS switch). +Added the emulation of physical bulbs & LEDs connected to binary outputs, for WPC, GTS3, SAM, Whitestar, Capcom and S11 hardware. + This allows to dramatically improve e.g. lamp or flasher modulation (for example the pulsing lights below the princess of TOTAN, + or the Sauron eye of LOTR, or slowly fading lamps in Breakshot). This needs to be enabled before use, the same way as for the existing + 'modulated' solenoids: by setting SolMask(2) which is now a bitmask: 1 is legacy modulated solenoids, 2 is physical model for solenoid + outputs, 4 is physical model for lamps/GIs/Segment outputs. To be emulated correctly, devices connected to binary output must be defined. + PinMAME already has the definition for lots of them (to be found in MACHINE_INIT of each driver) but if the one you want is missing, + or you want to modify it, use 'SolMask(xx) = type' to change it, where xx is the output to be modified (see vp_setSolMask), and yy is + the type (see core.h). Also see the updated core scripts coming with VPX. + This also opens up the path for emulation of dimmed alphanumerical segments and strength modulated solenoids + (for example Capcom Kingpin, or the way most modern hardware handle Power/Hold and EOS switch). *** CORE/CPU *** Fixed WPC General Illumination (GI) Dimming (most noticably if more than one GI line is involved, also all 8 levels are now handled properly) +Reworked Capcom emulation & timings, allowing all tables to behave 'normally' (no more delay on Flipper Football, DMD's animation at the right speed,...) Added Cosmic Flash sound emulation (Bell stole it from Bally's Squalk&Talk, but removed speech and DAC chips) Improved Zaccaria 11178 sound emulation a little (clown, poolcham, bbeltzac, mexico, zankor, spooky) Fixed Zaccaria strsphnx sound, background music works correctly now diff --git a/src/wpc/capcom.c b/src/wpc/capcom.c index b452eb14f..41c9e1b09 100644 --- a/src/wpc/capcom.c +++ b/src/wpc/capcom.c @@ -34,9 +34,9 @@ 09/21/03-09/24/03 - DMD working 100% incuding 256x64 size, switches, solenoids working on most games except kp, and ff 09/25/03 - First time game booted without any errors.. (Even though in reality, the U16 would still fail if not hacked around) 11/03/03 - First time sound was working almost fully (although still some glitches and much work left to do) - 11/09/03 - 50V Line finally reports a voltage & KP,FF fire hi-volt solenoids + 11/09/03 - 50V Line finally reports a voltage & KP,FF fire hi-volt solenoids 11/10/03 - Seem to have found decent IRQ4 freq. to allow KP & FF to fire sols 1 & 2 properly - 11/15/03 - 68306 optimized & true address mappings implemented, major speed improvements! + 11/15/03 - 68306 optimized & true address mappings implemented, major speed improvements! Hacks & Issues that need to be looked into: #1) Why do we need to adjust the CPU Speed to get the animations to display at correct speed? U16 related bug? @@ -88,13 +88,13 @@ #include "sndbrd.h" //Turn off when not testing mpg audio -#define TEST_MPGAUDIO 0 +#define TEST_MPGAUDIO 0 // Define to get read/write log to U16 #define VERBOSE_U16 0 // Define to 1 to patch ROM to disable error messages -#define SKIP_ERROR_MSG 0 +#define SKIP_ERROR_MSG 0 // Define to log lamp strobe timings #define LOG_LAMP_STROBE 0 @@ -146,18 +146,18 @@ static INTERRUPT_GEN(cc_vblank) { memset(coreGlobals.lampMatrix, 0, sizeof(coreGlobals.lampMatrix)); for (int i = 0; i < 8 + core_gameData->hw.lampCol; i++) for (int j = 0; j < 8; j++) - if (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + i * 8 + j].value >= 0.1) + if (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + i * 8 + j].value >= 0.1f) coreGlobals.lampMatrix[i] |= 1 << j; /*-- solenoids --*/ coreGlobals.solenoids = 0; for (int i = 0; i < 32; i++) - if (coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value >= 0.5) + if (coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value >= 0.5f) coreGlobals.solenoids |= 1 << i; /*-- update leds (they are PWM faded, so uses physic output) --*/ - coreGlobals.diagnosticLed = (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 8 * 8 + (core_gameData->hw.lampCol - 1) * 8 ].value >= 0.5 ? 1 : 0) - | (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 8 * 8 + (core_gameData->hw.lampCol - 1) * 8 + 1].value >= 0.5 ? 2 : 0); + coreGlobals.diagnosticLed = (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 8 * 8 + (core_gameData->hw.lampCol - 1) * 8 ].value >= 0.5f ? 1 : 0) + | (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 8 * 8 + (core_gameData->hw.lampCol - 1) * 8 + 1].value >= 0.5f ? 2 : 0); core_updateSw(TRUE); } @@ -196,7 +196,7 @@ static void cc_zeroCross(int data) { //PA7 - GRESET (output only) static READ16_HANDLER(cc_porta_r) { int data = locals.parallelA & 0xCF; - + // Hardware measure 5V DV and 50V DC voltage by performing pulses (using PULSE out signal) through a RC low pass filter (time constant is 363us, since it is a 11k resistor with a 33nF capacitor) // then reading the binary compared value against voltage divided from 5V or 50V line. So we compute the voltage at the capacitor and perform the comparison like the hardware // Some games seems to also have 5V line voltage with the same RC schematics as for 50V (f.e. in Airborne scematics but missing in Breakshot ones). There is no audit result for it. @@ -253,7 +253,7 @@ static WRITE16_HANDLER(cc_porta_w) { if(data !=0x0048 && data !=0x0040 && data !=0x0008) DBGLOG(("Port A write %04x\n",data)); - // Bulletin service 95-010a states that the diag led should goes bright then dims 4 times per second => PWM integration on the diag LED... + // Bulletin service 95-010a states that the diag led should go bright then dims 4 times per second => PWM integration on the diag LED... core_write_masked_pwm_output_8b(CORE_MODOUT_LAMP0 + 8 * 8 + (core_gameData->hw.lampCol - 1) * 8, (data & 0x08) >> 3, 0x01); // Cabinet switch voltage level comparator (either comparator from +5V with 2.2k/1.2k =>1.76V or 2.2k/3.9k => 3.20V), not sure why @@ -465,8 +465,8 @@ static WRITE16_HANDLER(u16_w) { case 0x200: { // IRQ1 Frequency, IRQ4 line 1/2/3 enable LOG_U16(("PC %08x - U16w IRQ1 f=%x IRQ4=%x [data@%03x=%04x] (%04x)\n", activecpu_get_pc(), (data >> 6) & 3, (data & 0x7) ^ 4, offset, data, mem_mask)); - //int irq1NCycles[] = { 22662, 11308, 5631, 2789 }; // Number of CPU cycles taken from startup check disassembly (value without IRQ1 adjusting on ACK) - int irq1NCycles[] = { 22602, 11248, 5571, 2729 }; // Number of CPU cycles taken from startup check disassembly (value with IRQ1 adjusting on ACK) + //static const int irq1NCycles[] = { 22662, 11308, 5631, 2789 }; // Number of CPU cycles taken from startup check disassembly (value without IRQ1 adjusting on ACK) + static const int irq1NCycles[] = { 22602, 11248, 5571, 2729 }; // Number of CPU cycles taken from startup check disassembly (value with IRQ1 adjusting on ACK) locals.u16IRQ1Period = TIME_IN_SEC(irq1NCycles[(data >> 6) & 3] / (double)CPU_CLOCK); timer_adjust(locals.u16IRQ1timer, locals.u16IRQ1Adjust ? (locals.u16IRQ1Period * 120.0 / 165.0) : locals.u16IRQ1Period, 0, locals.u16IRQ1Adjust ? (locals.u16IRQ1Period * 120.0 / 165.0) : locals.u16IRQ1Period); timer_adjust(locals.u16IRQ4Line1timer, locals.u16IRQ4Line1Period, 0, locals.u16IRQ4Line1Period); @@ -689,12 +689,12 @@ static MACHINE_INIT(cc) { // If wanted, we can skip the startup error messages by patching the rom (NOTE: MUST COME BEFORE WE COPY ROMS BELOW) #if SKIP_ERROR_MSG - //NOTE: Due to the way we load the roms, the fixaddress values must remove the top 8th bit, ie, - // 0x10092192 becomes 0x00092192 + //NOTE: Due to the way we load the roms, the fixaddress values must remove the top 8th bit, i.e. + // 0x10092192 becomes 0x00092192 UINT32 fixaddr = 0; switch (core_gameData->hw.gameSpecific1) { case 0: break; - case 1: case 2: fixaddr = 0x0009593c; break; //PM + case 1: case 2: fixaddr = 0x0009593c; break; //PM case 3: fixaddr = 0x0008ce04; break; //AB case 4: fixaddr = 0x00088204; break; //ABR case 5: case 6: fixaddr = 0x0008eb60; break; //BS @@ -750,7 +750,7 @@ static MACHINE_INIT(cc) { core_set_pwm_output_type(CORE_MODOUT_SOL0 + 28 - 1, 5, CORE_MODOUT_BULB_89_20V_DC_WPC); } else if (strncasecmp(gn, "kpb105", 6) == 0) { // KingPin - // To be checked since this is from VPX table (did not found a manual for this one) + // To be checked since this is from VPX table (did not find a manual for this one) coreGlobals.flipperCoils = 0xFFFFFFFFFFFF0908; core_set_pwm_output_type(CORE_MODOUT_SOL0 + 18 - 1, 2, CORE_MODOUT_BULB_89_20V_DC_WPC); core_set_pwm_output_type(CORE_MODOUT_SOL0 + 21 - 1, 11, CORE_MODOUT_BULB_89_20V_DC_WPC); @@ -884,7 +884,7 @@ CS3 = 30000000-3001ffff (RW) - NVRAM 0 0 (40000000) - /AUX I-O => Power Driver Board - Lamp matrices (and strobed switch matrix for Breakshot) 0 1 (40400000) - /EXT I-O => Power Driver Board - Solenoids / Switch Board (not present for Breakshot) 1 0 (40800000) - /SWITCH0 => 16 Cabinet switches - 1 1 (40c00000) - /CS => U16 custom chip + 1 1 (40c00000) - /CS => U16 custom chip */ static MEMORY_READ16_START(cc_readmem) { 0x00000000, 0x0007ffff, MRA16_RAM }, /* DRAM */ diff --git a/src/wpc/capgames.c b/src/wpc/capgames.c index f787f8276..7c3f0113c 100644 --- a/src/wpc/capgames.c +++ b/src/wpc/capgames.c @@ -5,7 +5,7 @@ #include "sndbrd.h" // CPU controlled flipper coils. Fast flips are also provided but are not 100% correct since the hardware is CPU controlled and pulse modulated -#define FLIP FLIP_SWNO(5,6) + FLIP_SOL(FLIP_LL | FLIP_LR | FLIP_UR | FLIP_UL) +#define FLIP (FLIP_SWNO(5,6) + FLIP_SOL(FLIP_LL | FLIP_LR | FLIP_UR | FLIP_UL)) /*-- DMD 128 X 32 --*/ const core_tLCDLayout cc_dispDMD128x32[] = { diff --git a/src/wpc/core.c b/src/wpc/core.c index 28f48dc10..a6e342528 100644 --- a/src/wpc/core.c +++ b/src/wpc/core.c @@ -87,7 +87,7 @@ void vp_setDIP(int bank, int value) { } extern void libpinmame_update_display(const int index, const struct core_dispLayout* p_layout, const void* p_data); #endif -INLINE UINT8 saturatedByte(double v) { return (UINT8)(255.0 * (v < 0.0 ? 0.0 : v > 1.0 ? 1.0 : v)); } +INLINE UINT8 saturatedByte(float v) { return (UINT8)(255.0f * (v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v)); } static void drawChar(struct mame_bitmap *bitmap, int row, int col, UINT32 bits, int type, int dimming); static UINT32 core_initDisplaySize(const struct core_dispLayout *layout); @@ -1230,12 +1230,8 @@ static void updateDisplay(struct mame_bitmap *bitmap, const struct rectangle *cl // -#ifdef VPINMAME - memset(AlphaNumericFrameBuffer,0x00,2048); -#endif - -#ifdef LIBPINMAME - memset(AlphaNumericFrameBuffer,0x00,4096); +#if defined(VPINMAME) || defined(LIBPINMAME) + memset(AlphaNumericFrameBuffer,0,sizeof(AlphaNumericFrameBuffer)); #endif switch (alpha_layout) { @@ -1474,7 +1470,7 @@ void core_updateSw(int flipEn) { float state[CORE_MODOUT_SOL_MAX]; core_getAllPhysicSols(state); for (ii = 0; ii < coreGlobals.nSolenoids; ii++) { - UINT8 v = saturatedByte(state[ii]); + UINT8 v = saturatedByte(state[ii]); if (v != locals.lastPhysicsOutput[CORE_MODOUT_SOL0 + ii]) { #ifdef LIBPINMAME OnSolenoid(ii + 1, v); @@ -1503,11 +1499,11 @@ void core_updateSw(int flipEn) { } else { UINT64 allSol = core_getAllSol(); - UINT64 chgSol = (allSol ^ locals.lastSol) & vp_getSolMask64(); + UINT64 chgSol = (allSol ^ locals.lastSol) & vp_getSolMask64(); locals.lastSol = allSol; - for (ii = 0; ii < CORE_FIRSTCUSTSOL + core_gameData->hw.custSol - 1; ii++) - { - if (chgSol & 0x01) { + for (ii = 0; ii < CORE_FIRSTCUSTSOL + core_gameData->hw.custSol - 1; ii++) + { + if (chgSol & 0x01) { OnSolenoid(ii + 1, allSol & 0x01); /*-- log solenoid number on the display (except flippers) --*/ if ((!pmoptions.dmd_only && (allSol & 0x01)) && ((ii < CORE_FIRSTLFLIPSOL) || (ii >= CORE_FIRSTSIMSOL))) { @@ -1524,9 +1520,9 @@ void core_updateSw(int flipEn) { proc_mechsounds(ii, allSol & 0x01); #endif } - chgSol >>= 1; - allSol >>= 1; - } + chgSol >>= 1; + allSol >>= 1; + } } /*-- check if we should use simulator keys --*/ @@ -2085,7 +2081,7 @@ typedef struct { { int type; /* bulb physical characteristics */ int isAC; /* AC or DC ? */ - float U; /* voltage (Volts) */ + float U; /* voltage (Volts) */ float serial_R; /* serial resistor (Ohms) */ } bulb; }; @@ -2216,7 +2212,7 @@ static MACHINE_INIT(core) { coreOutputinfos[CORE_MODOUT_PULSE].minPWMIntegrationTime = 0.0f; // binary output: fire as soon as a low to high transition is found, then go low if low and not pulsed coreOutputinfos[CORE_MODOUT_SOL_2_STATE].minPWMIntegrationTime = 0.001f; - // legacy binary output: like CORE_MODOUT_SOL_2_STATE but with legacy behavior of delaying the state by a few 'VBlank's (also used to have a bug on WPC which would only check if not pulsed but not base state) + // legacy binary output: like CORE_MODOUT_SOL_2_STATE but with legacy behavior of delaying the state by a few 'VBlank's (also used to have a bug on WPC which would only check if not pulsed but not base state) coreOutputinfos[CORE_MODOUT_LEGACY_SOL_2_STATE].minPWMIntegrationTime = 0.001f; // legacy binary output: return binary value for driver's getSol function coreOutputinfos[CORE_MODOUT_LEGACY_SOL_CUSTOM].minPWMIntegrationTime = 0.0f; @@ -2513,7 +2509,7 @@ void core_update_pwm_output(float now, int index, int isFlip) const int state = (coreGlobals.binaryOutputState[index >> 3] >> (index & 7)) & 1; output->elapsedInStateTime[state] += (now - output->dataTimestamp); output->dataTimestamp = now; - + const float elapsedSinceLastFlip = now - output->lastFlipTimestamp; const float minPWMIntegrationTime = coreOutputinfos[output->type].minPWMIntegrationTime; float integrationLength = output->elapsedInStateTime[0] + output->elapsedInStateTime[1]; @@ -2536,14 +2532,14 @@ void core_update_pwm_output(float now, int index, int isFlip) else if (integrationLength < minPWMIntegrationTime) { // Perform only the basic state accumulation for performance reasons - // This avoid doing full physics model integration for each state change on fast controllers like Capcom or SAM hardware - return; + // This avoid doing full physics model integration for each state change on fast controllers like Capcom or SAM hardware + return; } else if (elapsedSinceLastFlip < integrationLength) // integrationLength is >= minPWMIntegrationTime but last flip happened inside the integration period { // Last flip happened in this integration period: perform integration up to the last flip event (to align on end of pulse if applicable), keeping the remaining for later integration - now -= elapsedSinceLastFlip; - integrationLength -= elapsedSinceLastFlip; + now -= elapsedSinceLastFlip; + integrationLength -= elapsedSinceLastFlip; output->elapsedInStateTime[state] -= elapsedSinceLastFlip; pwmDutyCycle = output->elapsedInStateTime[1] / integrationLength; output->elapsedInStateTime[1 - state] = 0.0f; @@ -2570,14 +2566,14 @@ void core_update_pwm_output(float now, int index, int isFlip) output->value = (float)state; break; case CORE_MODOUT_SOL_2_STATE: { - // Apply the legacy solenoid behavior but directly updating coreGlobals on state change avoiding the latency of legacy implementation + // Apply the legacy solenoid behavior but directly updating coreGlobals on state change avoiding the latency of legacy implementation // (which used to handle PWM by 'or'ing solenoids states for a few 'VBlank's then deliver them, 'VBlank' being a custom 60Hz interrupt not corresponding to any hardware) - double prevValue = output->value; + double prevValue = output->value; if (isFlip && state == 0) { // If binary output is flipping to ON state, immediatly retain the ON state output->value = 1.0f; } - else if ((now - coreGlobals.physicOutputState[index].lastFlipTimestamp) > 0.060f) { + else if ((now - coreGlobals.physicOutputState[index].lastFlipTimestamp) > 0.060f) { // Output is in a stable state (not PWMed since at least 60ms), just report its value // TODO 60ms is likely too much. For example for Stern SAM, the sequence is 40ms pulse to lift flipper then 1ms pulse every 12ms to hold. output->value = (float)state; @@ -2665,7 +2661,7 @@ void core_update_pwm_output(float now, int index, int isFlip) const float dt = integrationLength < minPWMIntegrationTime ? integrationLength : minPWMIntegrationTime; // Keeps T within the range of the LUT (between room temperature and melt down point) output->state.bulb.filament_temperature = output->state.bulb.filament_temperature < 293.0f ? 293.0f : output->state.bulb.filament_temperature > (float) BULB_T_MAX ? (float) BULB_T_MAX : output->state.bulb.filament_temperature; - const float Ut = isAC ? (1.41421356f * sinf(60.0f * 2.0f * (float) PI * (integrationTime - coreGlobals.lastACZeroCrossTimeStamp)) * U) : U; + const float Ut = isAC ? (1.41421356f * sinf((float)(60.0 * 2.0 * PI) * (integrationTime - coreGlobals.lastACZeroCrossTimeStamp)) * U) : U; const float dT = dt * (float) bulb_heat_up_factor(bulb, output->state.bulb.filament_temperature, Ut, serial_R); output->state.bulb.filament_temperature += dT < 1000.0f ? dT : 1000.0f; core_eye_flicker_fusion(output, dt, (float) bulb_filament_temperature_to_emission(output->state.bulb.filament_temperature)); @@ -2709,7 +2705,7 @@ void core_update_pwm_output(float now, int index, int isFlip) } // Called periodically to perform PWM integration on all outputs. -// This is needed if we need multithreaded access to the output state like for VPinMame since integration is not thread safe. +// This is needed if we need multithreaded access to the output state like for VPinMAME since integration is not thread safe. void core_update_pwm_outputs(int unused) { float now = (float) timer_get_time(); diff --git a/src/wpc/gts3.c b/src/wpc/gts3.c index 3bb048a16..9cd3ccbe9 100644 --- a/src/wpc/gts3.c +++ b/src/wpc/gts3.c @@ -638,7 +638,7 @@ static void gts3dmd_init(void) { while (rootDrv->clone_of && (rootDrv->clone_of->flags & NOT_A_DRIVER) == 0) rootDrv = rootDrv->clone_of; const char* const gn = rootDrv->name; - if (strncasecmp(gn, "barbwire", 7) == 0) { // Barbwire + if (strncasecmp(gn, "barbwire", 8) == 0) { // Barbwire core_set_pwm_output_type(CORE_MODOUT_SOL0 + 13 - 1, 2, CORE_MODOUT_BULB_89_20V_DC_GTS3); // Playfield & Backbox flashers core_set_pwm_output_type(CORE_MODOUT_SOL0 + 16 - 1, 9, CORE_MODOUT_BULB_89_20V_DC_GTS3); // Playfield & Backbox flashers } diff --git a/src/wpc/sam.c b/src/wpc/sam.c index a4a10fca2..4ed22c8a5 100644 --- a/src/wpc/sam.c +++ b/src/wpc/sam.c @@ -1229,8 +1229,8 @@ static MACHINE_INIT(sam) { LOG(("Unable to create sam_snd.raw file\n")); #endif - // Initialize outputs - // Force physical output emulation since we use them to compute solenoids + // Initialize outputs + // Force physical output emulation since we use them to compute solenoids options.usemodsol |= CORE_MODOUT_FORCE_ON; coreGlobals.nGI = 1; coreGlobals.nLamps = 64 + core_gameData->hw.lampCol * 8; @@ -1272,10 +1272,10 @@ static MACHINE_INIT(sam) { int flashers[] = { 18, 20, 21, 22, 24, 26, 28, 31 }; for (int i = 0; i < sizeof(flashers) / sizeof(int); i++) coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + flashers[i] - 1].type = CORE_MODOUT_BULB_89_20V_DC_WPC; - coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 29].type = CORE_MODOUT_NONE; - coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 45].type = CORE_MODOUT_NONE; - coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 59].type = CORE_MODOUT_LED_STROBE_1_10MS; - coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 60].type = CORE_MODOUT_LED_STROBE_1_10MS; + coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 29].type = CORE_MODOUT_NONE; + coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 45].type = CORE_MODOUT_NONE; + coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 59].type = CORE_MODOUT_LED_STROBE_1_10MS; + coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + 60].type = CORE_MODOUT_LED_STROBE_1_10MS; } else if (strncasecmp(gn, "csi_240", 7) == 0) { // CSI // TODO no manual found on IPDB @@ -1300,7 +1300,7 @@ static MACHINE_INIT(sam) { core_set_pwm_output_type(CORE_MODOUT_SOL0 + 21 - 1, 3, CORE_MODOUT_BULB_89_20V_DC_WPC); core_set_pwm_output_type(CORE_MODOUT_SOL0 + 25 - 1, 8, CORE_MODOUT_BULB_89_20V_DC_WPC); } - else if (strncasecmp(gn, "mt_145h", 8) == 0) { // Mustang LE + else if (strncasecmp(gn, "mt_145h", 7) == 0) { // Mustang LE core_set_pwm_output_type(CORE_MODOUT_LAMP0, 80, CORE_MODOUT_LED_STROBE_1_10MS); // All LED core_set_pwm_output_type(CORE_MODOUT_SOL0 + 17 - 1, 5, CORE_MODOUT_BULB_89_20V_DC_WPC); core_set_pwm_output_type(CORE_MODOUT_SOL0 + 23 - 1, 1, CORE_MODOUT_BULB_89_20V_DC_WPC); @@ -1368,7 +1368,7 @@ static MACHINE_INIT(sam) { else if (strncasecmp(gn, "twenty4_150", 11) == 0) { // 24 // TODO no manual found on IPDB } - else if (strncasecmp(gn, "wof_500", 7) == 0) { // Wheel of fortune + else if (strncasecmp(gn, "wof_500", 7) == 0) { // Wheel of Fortune core_set_pwm_output_type(CORE_MODOUT_LAMP0 + 140, 175, CORE_MODOUT_LED); // Mini DMD (175 faded LEDs) core_set_pwm_output_type(CORE_MODOUT_LAMP0 + 60 - 1, 3, CORE_MODOUT_LED_STROBE_1_10MS); // Bumper LEDs core_set_pwm_output_type(CORE_MODOUT_SOL0 + 19 - 1, 3, CORE_MODOUT_BULB_89_20V_DC_WPC); @@ -1703,7 +1703,7 @@ static INTERRUPT_GEN(sam_vblank) { memset(coreGlobals.lampMatrix, 0, sizeof(coreGlobals.lampMatrix)); for (int i = 0; i < 8 + core_gameData->hw.lampCol; i++) for (int j = 0; j < 8; j++) - if (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + i * 8 + j].value >= 0.25) + if (coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + i * 8 + j].value >= 0.25f) coreGlobals.lampMatrix[i] |= 1 << j; /*-- display --*/ @@ -1715,7 +1715,7 @@ static INTERRUPT_GEN(sam_vblank) { /*-- solenoids --*/ coreGlobals.solenoids = 0; for (int i = 0; i < 32; i++) - if (coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value >= 0.5) + if (coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + i].value >= 0.5f) coreGlobals.solenoids |= 1 << i; /*-- GameOn for Fast Flips --*/ @@ -1832,7 +1832,7 @@ static PINMAME_VIDEO_UPDATE(samminidmd_update) { //const int target = 10 * 8 + (dmd_y * 5 + x) * 49 + (dmd_x * 7 + y); const int target = 10 * 8 + (dmd_y * 5 + x) * 49 + (dmd_x * 7 + y); float v = coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + target].value; - coreGlobals.dotCol[y + 1][x] = (UINT8)(15.0 * (v < 0.0 ? 0.0 : v > 1.0 ? 1.0 : v)); + coreGlobals.dotCol[y + 1][x] = (UINT8)(15.0f * (v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v)); } // Use the video update to output mini DMD as LED segments (somewhat hacky) for (ii = 0; ii < 5; ii++) { @@ -1852,9 +1852,9 @@ static PINMAME_VIDEO_UPDATE(samminidmd2_update) { for (kk = 0; kk < 5; kk++) { const int target = 140 + jj + (kk * 35); float v = coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + target].value; - coreGlobals.dotCol[kk + 1][jj] = (UINT8)(15.0 * (v < 0.0 ? 0.0 : v > 1.0 ? 1.0 : v)); + coreGlobals.dotCol[kk + 1][jj] = (UINT8)(15.0f * (v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v)); } - // Use the video update to output mini DMD as LED segments (somewhat hacky) + // Use the video update to output mini DMD as LED segments (somewhat hacky) for (ii = 0; ii < 35; ii++) { bits = 0; for (kk = 1; kk < 6; kk++) diff --git a/src/wpc/se.c b/src/wpc/se.c index c4b91472f..9e196f276 100644 --- a/src/wpc/se.c +++ b/src/wpc/se.c @@ -170,18 +170,18 @@ static INTERRUPT_GEN(se_vblank) { if (selocals.fastflipaddr > 0 && memory_region(SE_CPUREGION)[selocals.fastflipaddr - 1] > 0) { coreGlobals.solenoids |= 0x4000; coreGlobals.binaryOutputState[(CORE_MODOUT_SOL0 + 8) / 8] |= 0x40; - coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + 14].value = 1.0; + coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + 14].value = 1.0f; } else { coreGlobals.binaryOutputState[(CORE_MODOUT_SOL0 + 8) / 8] &= ~0x40; - coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + 14].value = 0.0; + coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + 14].value = 0.0f; } selocals.solenoids = coreGlobals.pulsedSolState; #ifdef PROC_SUPPORT if (coreGlobals.p_rocEn) { - static UINT64 lastSol = 0; - UINT64 allSol = core_getAllSol(); + static UINT64 lastSol = 0; + UINT64 allSol = core_getAllSol(); if (coreGlobals.p_rocEn) { int ii; UINT64 chgSol = (allSol ^ lastSol) & 0xffffffffffffffff; //vp_getSolMask64(); @@ -300,11 +300,11 @@ static MACHINE_INIT(se3) { core_set_pwm_output_type(CORE_MODOUT_SOL0 + 14, 2, CORE_MODOUT_NONE); // Fake solenoids for fast flip coreGlobals.nGI = 1; core_set_pwm_output_type(CORE_MODOUT_GI0, coreGlobals.nGI, CORE_MODOUT_BULB_44_5_7V_AC); - const struct GameDriver* rootDrv = Machine->gamedrv; - while (rootDrv->clone_of && (rootDrv->clone_of->flags & NOT_A_DRIVER) == 0) - rootDrv = rootDrv->clone_of; - const char* const grn = rootDrv->name; - if (strncasecmp(grn, "lotr", 4) == 0) { // The Lord of The Ring + const struct GameDriver* rootDrv = Machine->gamedrv; + while (rootDrv->clone_of && (rootDrv->clone_of->flags & NOT_A_DRIVER) == 0) + rootDrv = rootDrv->clone_of; + const char* const grn = rootDrv->name; + if (strncasecmp(grn, "lotr", 4) == 0) { // The Lord of The Rings core_set_pwm_output_type(CORE_MODOUT_SOL0 + 14 - 1, 1, CORE_MODOUT_BULB_89_20V_DC_WPC); core_set_pwm_output_type(CORE_MODOUT_SOL0 + 23 - 1, 1, CORE_MODOUT_BULB_89_20V_DC_WPC); core_set_pwm_output_type(CORE_MODOUT_SOL0 + 25 - 1, 3, CORE_MODOUT_BULB_89_20V_DC_WPC); @@ -399,7 +399,7 @@ static MACHINE_INIT(se) { while (rootDrv->clone_of && (rootDrv->clone_of->flags & NOT_A_DRIVER) == 0) rootDrv = rootDrv->clone_of; const char* const grn = rootDrv->name; - if (strncasecmp(grn, "rctycn", 8) == 0) { // Roller Coaster Tycoon + if (strncasecmp(grn, "rctycn", 6) == 0) { // Roller Coaster Tycoon core_set_pwm_output_type(CORE_MODOUT_SOL0 + 21 - 1, 3, CORE_MODOUT_BULB_89_20V_DC_WPC); core_set_pwm_output_type(CORE_MODOUT_SOL0 + 27 - 1, 1, CORE_MODOUT_BULB_89_20V_DC_WPC); core_set_pwm_output_type(CORE_MODOUT_SOL0 + 29 - 1, 4, CORE_MODOUT_BULB_89_20V_DC_WPC); diff --git a/src/wpc/vpintf.c b/src/wpc/vpintf.c index 7b461e253..6a870733b 100644 --- a/src/wpc/vpintf.c +++ b/src/wpc/vpintf.c @@ -16,8 +16,7 @@ static struct { mech_tInitData md; } locals; -INLINE double saturate(double v) { return v < 0.0 ? 0.0 : v > 1.0 ? 1.0 : v; } -INLINE UINT8 saturatedByte(double v) { return (UINT8)(255.0 * (v < 0.0 ? 0.0 : v > 1.0 ? 1.0 : v)); } +INLINE UINT8 saturatedByte(float v) { return (UINT8)(255.0f * (v < 0.0f ? 0.0f : v > 1.0f ? 1.0f : v)); } /*------------------------------- / Initialise/reset the VP interface @@ -73,7 +72,7 @@ int vp_getChangedLamps(vp_tChgLamps chgStat) { if (coreGlobals.nLamps && (options.usemodsol & CORE_MODOUT_ENABLE_LGIAS)) { for (ii = 0; ii < coreGlobals.nLamps; ii++) { - UINT8 val = (UINT8)saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + ii].value); + UINT8 val = saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + ii].value); if (val != locals.lastPhysicsOutput[CORE_MODOUT_LAMP0 + ii]) { chgStat[idx].lampNo = coreData->m2lamp ? coreData->m2lamp((ii / 8) + 1, ii & 7) : 0; chgStat[idx].currStat = val; @@ -86,7 +85,7 @@ int vp_getChangedLamps(vp_tChgLamps chgStat) { { UINT8 lampMatrix[CORE_MAXLAMPCOL]; memcpy(lampMatrix, coreGlobals.lampMatrix, sizeof(lampMatrix)); - int nCol = (core_gameData->gen & GEN_SAM) && (core_gameData->hw.lampCol > 2) ? 2 : core_gameData->hw.lampCol; + int nCol = (core_gameData->gen & GEN_SAM) && (core_gameData->hw.lampCol > 2) ? 2 : core_gameData->hw.lampCol; for (ii = 0; ii < CORE_STDLAMPCOLS + nCol; ii++) { int chgLamp = lampMatrix[ii] ^ locals.lastLampMatrix[ii]; if (chgLamp) { @@ -112,7 +111,7 @@ int vp_getChangedLamps(vp_tChgLamps chgStat) { // Backward compatibility for modulated LED & RGB LEDs of SAM hardware if ((core_gameData->gen & GEN_SAM) && (core_gameData->hw.lampCol > 2)) { for (ii = 80; ii < coreGlobals.nLamps; ii++) { - UINT8 val = (UINT8)saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + ii].value); + UINT8 val = saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_LAMP0 + ii].value); if (val != locals.lastPhysicsOutput[CORE_MODOUT_LAMP0 + ii]) { chgStat[idx].lampNo = ii + 1; chgStat[idx].currStat = val; @@ -139,17 +138,17 @@ int vp_getChangedSolenoids(vp_tChgSols chgStat) float state[CORE_MODOUT_SOL_MAX]; core_getAllPhysicSols(state); for (ii = 0; ii < coreGlobals.nSolenoids; ii++) { - UINT8 v = saturatedByte(state[ii]); + UINT8 v = saturatedByte(state[ii]); if (v != locals.lastPhysicsOutput[CORE_MODOUT_SOL0 + ii]) { chgStat[idx].solNo = ii + 1; - chgStat[idx].currStat = v; + chgStat[idx].currStat = v; idx += 1; locals.lastPhysicsOutput[CORE_MODOUT_SOL0 + ii] = v; } } } else { - UINT64 allSol = core_getAllSol(); + UINT64 allSol = core_getAllSol(); UINT64 chgSol = (allSol ^ locals.lastSol) & vp_getSolMask64(); locals.lastSol = allSol; for (ii = 0; ii < CORE_FIRSTCUSTSOL + core_gameData->hw.custSol - 1; ii++) @@ -176,7 +175,7 @@ int vp_getChangedGI(vp_tChgGIs chgStat) { { int idx = 0; for (int i = 0; i < coreGlobals.nGI; i++) { - UINT8 val = (UINT8)saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_GI0 + i].value); + UINT8 val = saturatedByte(coreGlobals.physicOutputState[CORE_MODOUT_GI0 + i].value); if (val != locals.lastPhysicsOutput[CORE_MODOUT_GI0 + i]) { chgStat[idx].giNo = i; chgStat[idx].currStat = val; @@ -193,7 +192,7 @@ int vp_getChangedGI(vp_tChgGIs chgStat) { int ii; memcpy(allGI, coreGlobals.gi, sizeof(allGI)); for (ii = 0; ii < CORE_MAXGI; ii++) { - if (allGI[ii] != locals.lastGI[ii]) { + if (allGI[ii] != locals.lastGI[ii]) { chgStat[idx].giNo = ii; chgStat[idx].currStat = allGI[ii]; idx += 1; @@ -371,8 +370,8 @@ int vp_getChangedLEDs(vp_tChgLED chgStat, UINT64 mask, UINT64 mask2) { for (ii = 0; ii < CORE_SEGCOUNT; ii++, mask >>= 1) { UINT16 chgSeg = coreGlobals.drawSeg[ii] ^ locals.lastSeg[ii]; - if (ii == 64) - mask = mask2; + if (ii == 64) + mask = mask2; if ((mask & 0x01) && chgSeg) { chgStat[idx].ledNo = ii; chgStat[idx].chgSeg = chgSeg; diff --git a/src/wpc/wpc.c b/src/wpc/wpc.c index 0e69cf4aa..f938a04c9 100644 --- a/src/wpc/wpc.c +++ b/src/wpc/wpc.c @@ -1267,10 +1267,10 @@ static MACHINE_INIT(wpc) { for (int i = 0; i < sizeof(flashers) / sizeof(int); i++) coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + flashers[i] - 1].type = CORE_MODOUT_BULB_89_20V_DC_WPC; } - else if (strncasecmp(gn, "hshot_p8", 7) == 0) { // Hot Shot + else if (strncasecmp(gn, "hshot_p8", 8) == 0) { // Hot Shot core_set_pwm_output_type(CORE_MODOUT_SOL0 + 17 - 1, 7, CORE_MODOUT_BULB_89_20V_DC_WPC); } - else if (strncasecmp(gn, "hurr_l2", 5) == 0) { // Hurricane + else if (strncasecmp(gn, "hurr_l2", 7) == 0) { // Hurricane core_set_pwm_output_type(CORE_MODOUT_SOL0 + 17 - 1, 12, CORE_MODOUT_BULB_89_20V_DC_WPC); } else if (strncasecmp(gn, "i500_11r", 8) == 0) { // Indiana 500 @@ -1323,7 +1323,7 @@ static MACHINE_INIT(wpc) { for (int i = 0; i < sizeof(flashers) / sizeof(int); i++) coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + flashers[i] - 1].type = CORE_MODOUT_BULB_89_20V_DC_WPC; } - else if (strncasecmp(gn, "pop_lx5", 7) == 0) { // Popeye Save The earth + else if (strncasecmp(gn, "pop_lx5", 7) == 0) { // Popeye Save The Earth int flashers[] = { 18, 19, 20, 21, 22, 23, 24, 26, 27, 28 }; for (int i = 0; i < sizeof(flashers) / sizeof(int); i++) coreGlobals.physicOutputState[CORE_MODOUT_SOL0 + flashers[i] - 1].type = CORE_MODOUT_BULB_89_20V_DC_WPC;