Files
RP412/RP_L4/RPL4MPPR.h
T
CydandClaude Opus 5 05f993b9aa Picking a preset no longer blinds the mode lamps
The six PRESET switches down the map's right flank stored their lamps in
modeLamp[], which holds four. Indices 4 and 5 ran off the end into
presetLamp[0..1], so the whole thing stayed self-consistent by memory
layout and nobody noticed - but it overwrote the four control-mode lamps
made moments earlier, and BASIC/STANDARD/VETERAN/MASTER on the upper-right
MFD were never lit again. presetLamp[], meanwhile, went unused.

The preset pass now fills the array it was always meant to, and the lamp
work moves out of the switch handler into a virtual NotifyOfPresetChange
that PresetEnable announces itself. That closes the second gap in passing:
keyboard 1-6 changed the mappings without touching the lamps, leaving the
flank showing a preset that was no longer in force. Both routes now go
through one place. The lamp arrays are also cleared in the constructor -
only the mapping loops ever filled them, and NOMODES skips those.

Verified by dumping the commanded RIO lamp states out of the running game
(PadRIO, TEST.EGG, at rest in Basic mode). Before and after are identical
except lamp 0x33, BASIC, which goes from 14 dim to 3c lit. The preset
lamps are unchanged: they worked by accident, and now work by
construction.

docs/CONTROL-PRESETS.md is the research behind it. The presets are not a
map feature at all - each is a complete factory layout for the four
mappable stick buttons, one mode-mask bit apiece, with all 26 vehicles
carrying their own six-preset table in RPL4.RES for both the pod RIO and
the Thrustmaster.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 11:43:02 -05:00

326 lines
7.0 KiB
C++

#pragma once
#include "..\rp\vtvmppr.h"
class L4Lamp;
//##########################################################################
//#################### ThrustmasterMapper ############################
//##########################################################################
class L4VTVControlsMapper:
public VTVControlsMapper
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data Support
//
public:
static Derivation *GetClassDerivations();
static SharedData DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Messaging Support
//
public:
enum {
KeypressMessageID = VTVControlsMapper::NextMessageID,
NextMessageID
};
void
KeypressMessageHandler(ReceiverDataMessageOf<ControlsKey> *message);
protected:
static const HandlerEntry
MessageHandlerEntries[];
//static MessageHandlerSet MessageHandlers;
static MessageHandlerSet& GetMessageHandlers();
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model Support
//
public:
typedef void
(L4VTVControlsMapper::*Performance)(Scalar time_slice);
void
SetPerformance(Performance performance)
{
Check(this);
activePerformance = (Simulation::Performance)performance;
}
void
CreateTemporaryEventMappings(
Receiver *receiver,
Receiver::MessageID config_message_id
),
RemoveTemporaryEventMappings(),
AddOrErase(
unsigned int button_ID,
Receiver *target,
Receiver::MessageID message_ID
),
AddOrErase(
unsigned int button_ID,
ControlsButton *destination
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction Support
//
public:
L4VTVControlsMapper(
VTV *player_vehicle,
int subsystem_ID,
SubsystemResource *subsystem_resource,
SharedData &shared_data = DefaultData
);
~L4VTVControlsMapper();
Logical
TestInstance() const;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Controls mode switching
//
void
SetControlsMode(int new_mode),
SetConfigurationMode(Logical new_state);
void
NotifyOfControlModeChange(int new_mode),
NotifyOfConfigurationModeChange(Logical new_state);
ModeMask
GetPresetModeMask()
{
Check(this);
return previousPresetModeMask;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Preset controls switching
//
void
PresetEnable(int preset_number);
// Announced by PresetEnable for EVERY preset change, whichever way it was
// triggered - map-flank switch or keyboard. Platforms carrying preset
// lamps move them here; the base mapper has none.
virtual void
NotifyOfPresetChange(int old_preset, int new_preset);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Protected data
//
protected:
enum
{
presetCount = 6 // limited to number of switches!
};
ModeMask
previousPresetModeMask;
int
previousPresetNumber;
};
//##########################################################################
//#################### ThrustmasterMapper ############################
//##########################################################################
class VTVThrustmasterMapper:
public L4VTVControlsMapper
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data Support
//
public:
static Derivation *GetClassDerivations();
static SharedData DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Messaging Support
//
public:
void
KeypressMessageHandler(ReceiverDataMessageOf<ControlsKey> *message);
protected:
static const HandlerEntry
MessageHandlerEntries[];
static MessageHandlerSet
MessageHandlers;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model Support
//
public:
typedef void
(VTVThrustmasterMapper::*Performance)(Scalar time_slice);
void
InterpretControls(Scalar time_slice);
void
SetPerformance(Performance performance)
{
Check(this);
activePerformance = (Simulation::Performance)performance;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction Support
//
public:
VTVThrustmasterMapper(
VTV *player_vehicle,
int subsystem_ID,
SubsystemResource *subsystem_resource
);
~VTVThrustmasterMapper();
Logical
TestInstance() const;
private:
ControlsScalar
leftPedal,
rightPedal;
};
//##########################################################################
//########################### RIOMapper ##############################
//##########################################################################
class VTVRIOMapper :
public L4VTVControlsMapper
{
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Shared Data Support
//
public:
static Derivation *GetClassDerivations();
static SharedData DefaultData;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Messaging Support
//
public:
enum {
SwitchModeMessageID = L4VTVControlsMapper::NextMessageID,
SelectPresetMessageID,
CenterJoystickMessageID,
ConfigureControlsMessageID, // duplicate of VTVControlsMapper msg
NextMessageID
};
void
KeypressMessageHandler(ReceiverDataMessageOf<ControlsKey> *message);
void
SwitchModeMessageHandler(
ReceiverDataMessageOf<ControlsButton> *message
);
void
SelectPresetMessageHandler(
ReceiverDataMessageOf<ControlsButton> *message
);
void
CenterJoystickMessageHandler(
ReceiverDataMessageOf<ControlsButton> *message
);
void
ConfigureControlsMessageHandler(
ReceiverDataMessageOf<ControlsButton> *message
);
protected:
static const HandlerEntry
MessageHandlerEntries[];
static MessageHandlerSet
MessageHandlers;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Model Support
//
public:
typedef void
(VTVRIOMapper::*Performance)(Scalar time_slice);
void
InterpretControls(Scalar time_slice);
void
NotifyOfControlModeChange(int new_mode);
void
NotifyOfConfigurationModeChange(Logical new_state);
void
NotifyOfPresetChange(int old_preset, int new_preset);
void
SetPerformance(Performance performance)
{
Check(this);
activePerformance = (Simulation::Performance)performance;
}
void
AddOrErase(
unsigned int button_ID,
Receiver *target,
Receiver::MessageID message_ID
);
void
AddOrErase(
unsigned int button_ID,
ControlsButton *destination
);
void
AddOrErase(
unsigned int button_ID,
Scalar *destination
);
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Construction and Destruction Support
//
public:
VTVRIOMapper(
VTV *player_vehicle,
int subsystem_ID,
SubsystemResource *subsystem_resource
);
~VTVRIOMapper();
Logical
TestInstance() const;
protected:
int
previousControlMode;
enum
{
configLampCount=2,
modeLampCount=4
};
L4Lamp
*configLamp[configLampCount],
*modeLamp[modeLampCount],
*presetLamp[presetCount];
private:
ControlsButton
throttleUp,
throttleDown,
throttleReverse;
ControlsScalar
leftPedal,
rightPedal;
};