-tbaud <rate> (9600-921600) overrides the COM1 baud rate while keeping old-RIO (type 0) protocol behavior unchanged; independent of -trio. SetupComm buffers 2/2 -> 1024/1024 only when the override is active. Rebuilt Release + Profile (0 errors), deployed rel.bin\MW4.exe to MW4\. run-firestorm driver: game-start now takes optional extra args. CLAUDE.md: branch notes incl. the CP949 comment-encoding hazard (mw4 sources must be edited byte-safely). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
3311 lines
89 KiB
C++
3311 lines
89 KiB
C++
#define USE_OVRIO
|
|
|
|
#include "criomain.h"
|
|
#include "Vehicle.hpp"
|
|
|
|
#ifdef _DEBUG
|
|
#define AUTO_DENY_TIME 30.0f
|
|
#else // !_DEBUG
|
|
#define AUTO_DENY_TIME 5.0f
|
|
#endif // _DEBUG
|
|
Time g_AUX_ADT = AUTO_DENY_TIME;
|
|
|
|
extern CRIOMAIN *g_pRIOMain;
|
|
CRIOMAIN *g_pRIOMain;
|
|
|
|
extern int m_gCool;
|
|
BOOL g_bCrouch = FALSE;//han
|
|
//BOOL g_bCool = FALSE;
|
|
BOOL g_SearchLight = FALSE;
|
|
BOOL g_UsingSearchLight = FALSE;//han
|
|
BOOL g_LightAmp = FALSE;
|
|
BOOL g_UsingLightAmp = FALSE;//han
|
|
|
|
LONG *g_lpPadalMode = NULL;
|
|
LONG *g_lpJoystickXMode = NULL;
|
|
|
|
LONG g_Throttle;
|
|
LONG g_LeftPedal;
|
|
LONG g_RightPedal;
|
|
LONG g_JoystickY;
|
|
LONG g_JoystickX;
|
|
|
|
LONG g_ThrottleResult = -1L;
|
|
LONG g_HatResult = -1L;
|
|
|
|
LONG g_ThrottleStart = INT_MIN;
|
|
LONG g_LeftPedalStart = INT_MAX;
|
|
LONG g_RightPedalStart = INT_MAX;
|
|
LONG g_JoystickXLast = 0;
|
|
LONG g_JoystickYLast = 0;
|
|
LONG g_ThrottleLast = 0;
|
|
LONG g_LeftPedalLast = 0;
|
|
LONG g_RightPedalLast = 0;
|
|
BOOL g_StartGame = FALSE;
|
|
|
|
static int g_nOpenComState = 0; // 鉉
|
|
|
|
DWORD g_dwLastAnalogUpdate = 0;
|
|
|
|
#define ASCII_XON 0x11
|
|
#define ASCII_XOFF 0x13
|
|
#define ACK_CHAR 0xFC
|
|
#define NAK_CHAR 0xFD
|
|
#define RESTART_CHAR 0xFE
|
|
#define IDLE_CHAR 0xFF
|
|
|
|
//member 변수처럼 활용할것.
|
|
static HANDLE g_hCom = INVALID_HANDLE_VALUE;
|
|
static OVERLAPPED wos;
|
|
static OVERLAPPED ros;
|
|
static OVERLAPPED wcos;//WaitCommEvent
|
|
|
|
static HANDLE g_hCommWatchThread = NULL, g_hWatchEvent = NULL, g_hLampEvent = NULL;
|
|
static DWORD g_dwThreadID;
|
|
|
|
static BYTE packetbytes[16];
|
|
static packetbyteremain=0;
|
|
static int chinpacket=0;
|
|
static int g_naButtonThrottles[8];
|
|
|
|
// old(original) RIO Board
|
|
static BYTE g_baRIOLengthsA[] = {
|
|
0, // 0.CheckRequest
|
|
0, // 1.VersionRequest
|
|
0, // 2.AnalogRequest
|
|
1, // 3.ResetRequest
|
|
2, // 4.LampRequest
|
|
2, // 5.CheckReply
|
|
2, // 6.VersionReply
|
|
10, // 7.AnalogReply
|
|
1, // 8.ButtonPressed
|
|
1, // 9.ButtonReleased
|
|
2, // 10.KeyPressed
|
|
2, // 11.KeyReleased
|
|
1, // 12.TestModeChange
|
|
};
|
|
int g_nRIOPacketCountA = (sizeof(g_baRIOLengthsA) / sizeof(g_baRIOLengthsA[0]));
|
|
|
|
// new RIO Board
|
|
static BYTE g_baRIOLengthsB[] = {
|
|
0, // 0.CheckRequest
|
|
0, // 1.VersionRequest
|
|
0+1, // 2.AnalogRequest + frequency
|
|
1, // 3.ResetRequest
|
|
2+1, // 4.LampRequest + id
|
|
2, // 5.CheckReply
|
|
2, // 6.VersionReply
|
|
10, // 7.AnalogReply
|
|
1+1, // 8.ButtonPressed + id
|
|
1+1, // 9.ButtonReleased + id
|
|
2, // 10.KeyPressed
|
|
2, // 11.KeyReleased
|
|
1, // 12.TestModeChange
|
|
1, // 13.Ack2 + id
|
|
1, // 14.Nak2 + id
|
|
};
|
|
int g_nRIOPacketCountB = (sizeof(g_baRIOLengthsB) / sizeof(g_baRIOLengthsB[0]));
|
|
|
|
int g_nRIOType = 0; // 0: old(original) type, 1: new type
|
|
DWORD g_dwRIOBaud = 0; // [tbaud] 0: default by RIO type; else COM1 baud forced by -tbaud (high-speed replica of the original RIO board, protocol unchanged)
|
|
int g_nEjectButton = 61; // 61: original, 31: new type
|
|
BYTE* g_pbRIOLengths = NULL;
|
|
int g_nRIOPacketCount = 0;
|
|
|
|
enum RIOCommand {
|
|
rio_CheckRequest = 0x80, // 128
|
|
rio_VersionRequest, // 129
|
|
rio_AnalogRequest, // 130
|
|
rio_ResetRequest, // 131
|
|
rio_LampRequest, // 132
|
|
rio_CheckReply, // 133
|
|
rio_VersionReply, // 134
|
|
rio_AnalogReply, // 135
|
|
rio_ButtonPressed, // 136
|
|
rio_ButtonReleased, // 137
|
|
rio_KeyPressed, // 138
|
|
rio_KeyReleased, // 139
|
|
rio_TestModeChange, // 140
|
|
// new RIO Board Only...
|
|
rio_Ack2, // 141,0x8D
|
|
rio_Nak2, // 142,0x8E
|
|
};
|
|
|
|
enum RIOStatusType {
|
|
BoardOk, BoardMissing, BoardBad, LampBad, RestartCount, AbandonCount, FullBufferCount
|
|
};
|
|
|
|
enum LampState {
|
|
solid=0, flashSlow=1, flashMed=2, flashFast=3,
|
|
state1Off=0x00, state1Dim=0x04, state1Bright=0x0C,
|
|
state2Off=0x00, state2Dim=0x10, state2Bright=0x30,
|
|
};
|
|
|
|
enum {
|
|
LampSolidOff = solid + state1Off + state2Off,
|
|
LampSolidDim = solid + state1Dim + state2Dim,
|
|
LampSolidBright = solid + state1Bright + state2Bright
|
|
};
|
|
|
|
int g_bNoPlasma = 1;
|
|
extern bool g_bCOOP;
|
|
extern int g_nCoinCount;
|
|
extern int g_nCoinCountTemp;
|
|
extern int g_nCoinPerGame;
|
|
|
|
RIOBUTTON CBUTTON_GROUP::s_aButtonTable[] =
|
|
{
|
|
//-------------------------------
|
|
// #Aux Monitor5 (Bottom Right)
|
|
// UP : 7 6 5 4
|
|
// DOWN: 3 2 1 0
|
|
//-------------------------------
|
|
{'P', SYSKEY_NULL, LAMP_DIM}, // 0 48 Assign Group3
|
|
{'P', SYSKEY_NULL, LAMP_DIM}, // 1 49 Assign Group2
|
|
{'P', SYSKEY_NULL, LAMP_DIM}, // 2 50 Assign Group1
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, // 3 51 firing Mode
|
|
{'P', SYSKEY_NULL, LAMP_DIM}, // 4 52 Prev Weapon
|
|
{'P', SYSKEY_NULL, LAMP_DIM}, // 5 53 Next Weapon
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, // 6 54 Chainfire Mode
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, // 7 55 Groupfire Mode
|
|
|
|
//-------------------------------
|
|
// #Aux Monitor4 (Bottom Left)
|
|
// UP : 15 14 13 12
|
|
// DOWN: 11 10 9 8
|
|
//-------------------------------
|
|
{'Q', SYSKEY_NULL, LAMP_DIM}, // 8 Cross Hair Target
|
|
{'E', SYSKEY_CTRL, LAMP_DIM}, // 9
|
|
{'E', SYSKEY_NULL, LAMP_DIM}, //10
|
|
{'E', SYSKEY_SHFT, LAMP_DIM}, //11
|
|
{188, SYSKEY_NULL, LAMP_DIM}, //12 Target Armor State
|
|
{'W', SYSKEY_CTRL, LAMP_DIM}, //13
|
|
{'W', SYSKEY_NULL, LAMP_DIM}, //14
|
|
{'W', SYSKEY_SHFT, LAMP_DIM}, //15
|
|
|
|
//-------------------------------
|
|
// Secondary Screen
|
|
// LEFT: 16 - 21 , RIGHT: 24 - 29
|
|
//-------------------------------
|
|
{'J', SYSKEY_NULL, LAMP_DIM}, //16 Jump Jets
|
|
{'S', SYSKEY_NULL, LAMP_DIM}, //17 ShutDownCommand
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //18 Damage
|
|
{'F', SYSKEY_NULL, LAMP_DIM}, //19 Flush
|
|
{'C', SYSKEY_NULL, LAMP_DIM}, //20 Crouch
|
|
{-1 , SYSKEY_NULL, LAMP_DIM}, //21 Program
|
|
LAMPBLANK, //22
|
|
LAMPBLANK, //23
|
|
{'R', SYSKEY_NULL, LAMP_DIM}, //24 Radar Range
|
|
{'R', SYSKEY_CTRL, LAMP_DIM}, //25 Radar Mode
|
|
{'A', SYSKEY_NULL, LAMP_DIM}, //26 Light Amp
|
|
{'L', SYSKEY_NULL, LAMP_DIM}, //27 Search Light
|
|
{186, SYSKEY_NULL, LAMP_DIM}, //28 AutoCenter
|
|
{-1 , SYSKEY_NULL, LAMP_DIM}, //29 {InputMode}-beginner/middle/advanced
|
|
LAMPBLANK, //30 {Coin Inserted Signal if wired}
|
|
{'Z', SYSKEY_CTRL, LAMP_NONE}, //31 {act as Eject if wired}
|
|
//-------------------------------
|
|
// #Aux Monitor2 (Bottom Center)
|
|
// UP : 39 38 37 36
|
|
// DOWN: 35 34 33 32
|
|
//-------------------------------
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //32 Ammo Dump Magazine
|
|
{'J', SYSKEY_NULL, LAMP_DIM}, //33 Jump Jets
|
|
{'J', SYSKEY_NULL, LAMP_DIM}, //34 Jump Jets
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //35 Ammo Dump Round
|
|
{'O', SYSKEY_CTRL, LAMP_DIM}, //36 Objectives
|
|
{'N', SYSKEY_CTRL, LAMP_DIM}, //37 NAV point
|
|
{'N', SYSKEY_NULL, LAMP_DIM}, //38 NAV point
|
|
LAMPBLANK, //39 Team Speak?
|
|
// {-1, SYSKEY_NULL, LAMP_NONE}, //39 Team Speak?
|
|
//-------------------------------
|
|
// #Aux Monitor1 (Upper Left)
|
|
// UP : 47 46 45 44
|
|
// DOWN: 43 42 41 40
|
|
//-------------------------------
|
|
{KEY_8, SYSKEY_CTRL, LAMP_DIM}, //40 yes/no
|
|
{KEY_7, SYSKEY_CTRL, LAMP_DIM}, //41 ...
|
|
{KEY_6, SYSKEY_CTRL, LAMP_DIM}, //42 ...
|
|
{KEY_5, SYSKEY_CTRL, LAMP_DIM}, //43 ...
|
|
|
|
{KEY_4, SYSKEY_CTRL, LAMP_DIM}, //44 team-mate 3
|
|
{KEY_3, SYSKEY_CTRL, LAMP_DIM}, //45 team-mate 2
|
|
{KEY_2, SYSKEY_CTRL, LAMP_DIM}, //46 team-mate 1
|
|
{KEY_1, SYSKEY_CTRL, LAMP_DIM}, //47 team-mate all
|
|
//-------------------------------
|
|
// #Aux Monitor3 (Upper Right)
|
|
// UP : 55 54 53 52
|
|
// DOWN: 51 50 49 48
|
|
//-------------------------------
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //48 0 Light Amp - Pinky Trigger
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //49 1 Flush - Pinky Trigger
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //50 2 Jump - Pinky Trigger
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //51 3 Zoom - Pinky Trigger
|
|
{190, SYSKEY_NULL, LAMP_DIM}, //52 4 Right MFD - Damage MFD(Armor Mode)
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //53 5 CrossTarget - Pinky Trigger
|
|
{-1, SYSKEY_NULL, LAMP_DIM}, //54 6 NextTarget - Pinky Trigger
|
|
{'O', SYSKEY_NULL, LAMP_DIM}, //55 7 MUTE
|
|
|
|
//-------------------------------
|
|
// #Throttle 56 ~ 63 (8)
|
|
//-------------------------------
|
|
LAMPBLANK, //56 {Coin Inserted Signal if wired}
|
|
LAMPBLANK, //57
|
|
LAMPBLANK, //58
|
|
LAMPBLANK, //59
|
|
LAMPBLANK, //60
|
|
{'Z', SYSKEY_CTRL, LAMP_NONE}, //61 {act as Eject if wired}
|
|
|
|
LAMPBLANK, //62
|
|
{-1, SYSKEY_NULL, LAMP_NONE}, //63 dir toggle or JUMP ==> {'J', SYSKEY_NULL, LAMP_DIM}, //16 Jump Jets
|
|
|
|
//-------------------------------
|
|
// #JoyStick 64 ~ 71 (8)
|
|
//-------------------------------
|
|
|
|
LAMPBLANK,// {KEY_INSERT, SYSKEY_NULL, LAMP_NONE}, //64 Fire Group 1 (Main Triger)
|
|
{-1, SYSKEY_NULL, LAMP_NONE}, //65 Hat_Down
|
|
{-1, SYSKEY_NULL, LAMP_NONE}, //66 Hat_Up
|
|
{-1, SYSKEY_NULL, LAMP_NONE}, //67 Hat_right
|
|
{-1, SYSKEY_NULL, LAMP_NONE}, //68 Hat_left
|
|
{VK_NUMPAD0, SYSKEY_NULL, LAMP_NONE}, //69 ZOOM - Pinky button
|
|
LAMPBLANK,// {KEY_PRIOR, SYSKEY_NULL, LAMP_NONE}, //70 Fire Group 3 (Lower Trigger)
|
|
LAMPBLANK,// {KEY_HOME, SYSKEY_NULL, LAMP_NONE}, //71 Fire Group 2 (Upper Trigger)
|
|
};
|
|
|
|
#define MAXBUTTON_TABLE (sizeof(CBUTTON_GROUP::s_aButtonTable) / sizeof(CBUTTON_GROUP::s_aButtonTable[0]))
|
|
|
|
BYTE CBUTTON_GROUP::s_aSaveLamp[MAXBUTTON_TABLE];
|
|
BYTE CBUTTON_GROUP::s_aCtrlLamp[MAXBUTTON_TABLE];
|
|
|
|
void CRIO_StartFrame();
|
|
void CRIO_StopFrame();
|
|
int IsLampOFF (int n);
|
|
int _stdcall VehGetShutdownState();
|
|
int _stdcall VehGetJumpJetState();
|
|
void DoSaveMechInfos(PMechInfo pDest, PMechInfo pSrc, int nCount);
|
|
|
|
void __stdcall PLASMA_Do(int nMode);
|
|
void __stdcall RIO_Joy(DIJOYSTATE& js);
|
|
void __stdcall RIO_ButEvent (BYTE *by);
|
|
void __stdcall RIO_StartStop (BOOL bStart);
|
|
|
|
BOOL SetupConnection(HANDLE hCom);
|
|
HANDLE OpenConnection(int port);
|
|
BOOL CloseConnection();
|
|
void TransmitCommChar2(HANDLE g_hCom,int ch);
|
|
int ReadCommBlock( LPSTR lpszBlock, int nMaxLength );
|
|
DWORD g_dwLastPacketTime;
|
|
DWORD g_dwLastBytesToWrite = 0;
|
|
DWORD g_dCancelCount = 0;
|
|
BYTE g_baLastPacket[20];
|
|
BOOL WriteCommBlock(LPSTR lpByte , DWORD dwBytesToWrite);
|
|
DWORD FAR PASCAL CommWatchProc( LPSTR lpData );
|
|
|
|
short CombinePair(BYTE low_value, BYTE high_value);
|
|
void AnalogEvent (BYTE *pData);
|
|
BOOL SendPacket (const BYTE *ba,int length);
|
|
BOOL SendCommand (const BYTE* pbPacket);
|
|
BOOL SetLamp(int lampNumber, int state);
|
|
void AnalogAllReset ();
|
|
void GeneralReset();
|
|
void ResetThrottle();
|
|
void ResetLeftPedal();
|
|
void ResetRightPedal();
|
|
void ResetVerticalJoystick();
|
|
void ResetHorizontalJoystick();
|
|
void RequestCheck();
|
|
void RequestVersion();
|
|
void RequestAnalogUpdate(BYTE bFreq = 3);
|
|
|
|
// start - for new RIO Board only...
|
|
//received packet은 각각 다른 스레드에서 처리하므로.. ciritical section이 필요하다..
|
|
BYTE received_buffer[128][16];
|
|
int received_packet=0;//packets count in the received_buffer.
|
|
DWORD received_serial=0;
|
|
|
|
BYTE sent_buffer[128][16];
|
|
int sent_packet=0;//packets count in the sent_buffer.
|
|
int sent_serial=0;
|
|
DWORD ack_timeout=0;
|
|
|
|
bool SaveReceivedPacket(const BYTE*ba,int length);
|
|
bool GetSerialFromReceivedBuffer(char * ba);
|
|
bool QueuePacket(const BYTE *ba,int length);
|
|
int PopPacket(BYTE id);
|
|
int GetPacketLength(BYTE * ba);
|
|
void ReSendPackets(int count);
|
|
void SendAck2(BYTE id);
|
|
void SendNak2(BYTE id);
|
|
int CompareID(int id,int serial);
|
|
// end - for new RIO Board only...
|
|
|
|
class CRIO_Module
|
|
{
|
|
private:
|
|
CRITICAL_SECTION m_csJoyButtons;
|
|
public:
|
|
BYTE m_baButtons[4];
|
|
public:
|
|
CRIO_Module()
|
|
{
|
|
InitializeCriticalSection(&m_csJoyButtons);
|
|
for(int i = 0; i < sizeof(m_baButtons) / sizeof(m_baButtons[0]); i++)
|
|
m_baButtons[i] = 0;
|
|
}
|
|
~CRIO_Module()
|
|
{
|
|
DeleteCriticalSection(&m_csJoyButtons);
|
|
}
|
|
inline void EnterJoyButtons()
|
|
{
|
|
EnterCriticalSection(&m_csJoyButtons);
|
|
}
|
|
inline void LeaveJoyButtons()
|
|
{
|
|
LeaveCriticalSection(&m_csJoyButtons);
|
|
}
|
|
inline void SetJoyButton(int nIndex, BYTE bValue)
|
|
{
|
|
gosASSERT((0 <= nIndex) && (nIndex < sizeof(m_baButtons) / sizeof(m_baButtons[0])));
|
|
EnterCriticalSection(&m_csJoyButtons);
|
|
m_baButtons[nIndex] = bValue;
|
|
LeaveCriticalSection(&m_csJoyButtons);
|
|
}
|
|
inline void GetJoyButtons(BYTE baButtons[])
|
|
{
|
|
EnterCriticalSection(&m_csJoyButtons);
|
|
for(int i = 0; i < sizeof(m_baButtons) / sizeof(m_baButtons[0]); i++)
|
|
baButtons[i] = m_baButtons[i];
|
|
/*
|
|
static DWORD s_dwLT = 0;
|
|
if (baButtons[0] && (!s_dwLT || (s_dwLT + 50 <= GetTickCount()))) {
|
|
//MessageBeep(0);
|
|
s_dwLT = GetTickCount();
|
|
}
|
|
*/
|
|
LeaveCriticalSection(&m_csJoyButtons);
|
|
}
|
|
void DoProcessButtons(const BYTE* pcbData);
|
|
} s_RIO;
|
|
|
|
void CRIO_Module::DoProcessButtons(const BYTE* pcbData)
|
|
{
|
|
BYTE state = pcbData[0];
|
|
BYTE index = pcbData[1];
|
|
|
|
switch(index)
|
|
{
|
|
case 64: // Fire Group 1 (Main Triger)
|
|
SetJoyButton(0, (state == rio_ButtonPressed) ? 0x80: 0);
|
|
break;
|
|
case 70: // Fire Group 3 (Lower Trigger)
|
|
SetJoyButton(3, (state == rio_ButtonPressed) ? 0x80: 0);
|
|
break;
|
|
case 71: // Fire Group 2 (Upper Trigger)
|
|
SetJoyButton(2, (state == rio_ButtonPressed) ? 0x80: 0);
|
|
break;
|
|
default:
|
|
PostMessage(g_hWnd,WM_USER+100,0,*(const DWORD*)pcbData);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CRIO_StartFrame()
|
|
{
|
|
}
|
|
|
|
void CRIO_StopFrame()
|
|
{
|
|
if (g_hLampEvent) {
|
|
if (g_dwLastBytesToWrite == 0) {
|
|
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
|
if (CBUTTON_GROUP::s_aCtrlLamp[b] != CBUTTON_GROUP::s_aButtonTable[b].lamp) {
|
|
SetEvent(g_hLampEvent);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
ResetEvent(g_hLampEvent);
|
|
}
|
|
}
|
|
|
|
int IsLampOFF (int n)
|
|
{
|
|
if (g_pRIOMain) {
|
|
return ((CBUTTON_GROUP::s_aCtrlLamp[n]) == LAMP_OFF) ? 1: 0;
|
|
} else {
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
int _stdcall VehGetShutdownState()
|
|
{
|
|
VehicleInterface* p = VehicleInterface::GetInstance();
|
|
if (p) {
|
|
return p->GetShutdownState();
|
|
} else {
|
|
return -3;
|
|
}
|
|
}
|
|
|
|
int _stdcall VehGetJumpJetState()
|
|
{
|
|
VehicleInterface* p = VehicleInterface::GetInstance();
|
|
if (p) {
|
|
return p->GetJumpJetState();
|
|
} else {
|
|
return -4;
|
|
}
|
|
}
|
|
|
|
void DoSaveMechInfos(PMechInfo pDest, PMechInfo pSrc, int nCount)
|
|
{
|
|
if (nCount > 0) {
|
|
memcpy(&pDest[0], &pSrc[0], sizeof(SMechInfo) * nCount);
|
|
}
|
|
}
|
|
|
|
void __stdcall PLASMA_Do(int nMode)
|
|
{
|
|
g_pRIOMain->DoPlasma((char)nMode);
|
|
}
|
|
|
|
void __stdcall RIO_Joy(DIJOYSTATE& js)
|
|
{
|
|
if (g_pRIOMain) {
|
|
g_pRIOMain->UpdateAnalog(js);
|
|
}
|
|
}
|
|
|
|
void __stdcall RIO_ButEvent(BYTE *by)
|
|
{
|
|
if (g_pRIOMain) {
|
|
#if 0
|
|
if (CTCL_IsConsole()) {
|
|
// console...
|
|
if (!g_bCOOP) {
|
|
if ((by[0] == 255) && (by[1] == 0) && (by[2] == 255) && (by[3] == 0)) {
|
|
g_nCoinCount++;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
#endif
|
|
g_pRIOMain->ButtonEvent(by[0], by[1]);
|
|
} else {
|
|
}
|
|
}
|
|
|
|
void __stdcall RIO_StartStop (BOOL bStart)
|
|
{
|
|
if (g_pRIOMain) {
|
|
g_pRIOMain->m_bGamePlaying = bStart;
|
|
|
|
if (bStart) {
|
|
g_pRIOMain->SetTable(TRUE);
|
|
} else {
|
|
g_pRIOMain->ResetTable(TRUE);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL SetupConnection(HANDLE hCom)
|
|
{
|
|
DCB dcb;
|
|
BOOL fRetVal ;
|
|
dcb.DCBlength = sizeof( DCB ) ;
|
|
|
|
GetCommState( hCom, &dcb);
|
|
if (CTCL_IsConsole()) {
|
|
dcb.BaudRate = CBR_9600;
|
|
} else {
|
|
dcb.BaudRate = (g_nRIOType == 0) ? CBR_9600: CBR_115200;
|
|
}
|
|
if (g_dwRIOBaud != 0) {
|
|
dcb.BaudRate = g_dwRIOBaud; // [tbaud] -tbaud override
|
|
}
|
|
dcb.ByteSize = 8 ;
|
|
dcb.Parity = 0;
|
|
dcb.StopBits = 0;
|
|
dcb.fOutxDsrFlow = 0;
|
|
dcb.fDtrControl = DTR_CONTROL_ENABLE ;
|
|
dcb.fOutxCtsFlow = 0;
|
|
dcb.fRtsControl = RTS_CONTROL_ENABLE;
|
|
dcb.fInX = 0;
|
|
dcb.fOutX = 0;
|
|
dcb.XonChar = ASCII_XON ;
|
|
dcb.XoffChar = ASCII_XOFF ;
|
|
dcb.XonLim = 100 ;
|
|
dcb.XoffLim = 100 ;
|
|
dcb.fBinary = TRUE ;
|
|
dcb.fParity = TRUE ;
|
|
|
|
fRetVal=SetCommState( hCom, &dcb ) ;
|
|
if(fRetVal==0)return FALSE;
|
|
|
|
|
|
// get any early notifications
|
|
fRetVal=SetCommMask(hCom, EV_RXCHAR ) ;
|
|
if(fRetVal==0)return FALSE;
|
|
|
|
// setup device buffers
|
|
// [tbaud] at overridden (higher) rates use real buffers; default 2/2 kept byte-identical for deployed pods
|
|
fRetVal=SetupComm(hCom, (g_dwRIOBaud != 0) ? 1024: 2, (g_dwRIOBaud != 0) ? 1024: 2 );
|
|
if(fRetVal==0)return FALSE;
|
|
|
|
// purge any information in the buffer
|
|
fRetVal=PurgeComm(hCom, PURGE_TXABORT | PURGE_RXABORT |PURGE_TXCLEAR | PURGE_RXCLEAR ) ;
|
|
if(fRetVal==0)return FALSE;
|
|
|
|
// set up for overlapped I/O
|
|
COMMTIMEOUTS CommTimeOuts={0,};
|
|
CommTimeOuts.ReadIntervalTimeout = 1 ;
|
|
CommTimeOuts.ReadTotalTimeoutMultiplier = 1 ;
|
|
CommTimeOuts.ReadTotalTimeoutConstant = 0 ;
|
|
CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
|
|
CommTimeOuts.WriteTotalTimeoutConstant = 0 ;
|
|
fRetVal=SetCommTimeouts(hCom, &CommTimeOuts ) ;
|
|
if(fRetVal==0)return FALSE;
|
|
return TRUE;
|
|
|
|
/*
|
|
원래 처리 루틴..
|
|
NPTTYINFO npTTYInfo=0 ;
|
|
BYTE bset1 = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_DTRDSR) != 0) ;
|
|
BYTE bset2 = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_RTSCTS) != 0) ;
|
|
BYTE bset3 = (BYTE) ((FLOWCTRL( npTTYInfo ) & FC_XONXOFF) != 0) ;
|
|
|
|
dcb.DCBlength = sizeof( DCB ) ;
|
|
|
|
GetCommState( hCom, &dcb ) ;
|
|
|
|
dcb.BaudRate = BAUDRATE( npTTYInfo ) ;
|
|
dcb.ByteSize = BYTESIZE( npTTYInfo ) ;
|
|
dcb.Parity = PARITY( npTTYInfo ) ;
|
|
dcb.StopBits = STOPBITS( npTTYInfo ) ;
|
|
dcb.fOutxDsrFlow = bset1;
|
|
dcb.fDtrControl = bset1 ? DTR_CONTROL_HANDSHAKE : DTR_CONTROL_ENABLE ;
|
|
dcb.fOutxCtsFlow = bset2 ;
|
|
dcb.fRtsControl = bset2?RTS_CONTROL_HANDSHAKE :RTS_CONTROL_ENABLE;
|
|
dcb.fInX = bset3;
|
|
dcb.fOutX = bset3 ;
|
|
dcb.XonChar = ASCII_XON ;
|
|
dcb.XoffChar = ASCII_XOFF ;
|
|
dcb.XonLim = 100 ;
|
|
dcb.XoffLim = 100 ;
|
|
dcb.fBinary = TRUE ;
|
|
dcb.fParity = TRUE ;
|
|
|
|
fRetVal = SetCommState( hCom, &dcb ) ;
|
|
*/
|
|
/*
|
|
return fRetVal;
|
|
|
|
|
|
|
|
//처리되지 않는 항목들.. GetCommState의 기본값으로 처리한다.
|
|
DWORD fDsrSensitivity:1; // DSR sensitivity
|
|
DWORD fTXContinueOnXoff:1; // XOFF continues Tx
|
|
DWORD fErrorChar: 1; // enable error replacement
|
|
DWORD fNull: 1; // enable null stripping
|
|
DWORD fAbortOnError:1; // abort on error
|
|
DWORD fDummy2:17; // reserved
|
|
WORD wReserved; // not currently used
|
|
char ErrorChar; // error replacement character
|
|
char EofChar; // end of input character
|
|
char EvtChar; // received event character
|
|
WORD wReserved1; // reserved; do not use
|
|
*/
|
|
}
|
|
|
|
HANDLE OpenConnection(int port)
|
|
{
|
|
if (g_nRIOType == 0) {
|
|
g_pbRIOLengths = &g_baRIOLengthsA[0];
|
|
g_nRIOPacketCount = g_nRIOPacketCountA;
|
|
g_nEjectButton = 61;
|
|
} else {
|
|
g_pbRIOLengths = &g_baRIOLengthsB[0];
|
|
g_nRIOPacketCount = g_nRIOPacketCountB;
|
|
g_nEjectButton = 31;
|
|
}
|
|
|
|
//port: 1~n
|
|
char portname[8];
|
|
wsprintf(portname,"COM%d",port);
|
|
|
|
DWORD dwFAs = FILE_ATTRIBUTE_NORMAL;
|
|
#ifdef USE_OVRIO
|
|
dwFAs |= FILE_FLAG_OVERLAPPED;
|
|
#endif // USE_OVRIO
|
|
g_hCom = CreateFile( portname, GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING, dwFAs, NULL );
|
|
if (g_hCom != INVALID_HANDLE_VALUE) {
|
|
if (SetupConnection(g_hCom)) {
|
|
ros.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
wos.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
g_hWatchEvent = CreateEvent(0,0,0,0);
|
|
g_hLampEvent = CreateEvent(0,FALSE,0,0);
|
|
g_hCommWatchThread = CreateThread((LPSECURITY_ATTRIBUTES)NULL, 0, (LPTHREAD_START_ROUTINE)CommWatchProc, NULL, CREATE_SUSPENDED, &g_dwThreadID);
|
|
if (g_hCommWatchThread) {
|
|
//Thread까지 정상적으로 생성되었다.
|
|
//////////////////////////////////////////////
|
|
//All OK
|
|
//Exit Point <======
|
|
EscapeCommFunction( g_hCom, SETDTR ) ;
|
|
Sleep(50);
|
|
EscapeCommFunction( g_hCom, CLRDTR ) ;
|
|
Sleep(1000);
|
|
//SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
|
|
SetThreadPriority(g_hCommWatchThread,THREAD_PRIORITY_TIME_CRITICAL);
|
|
ResumeThread(g_hCommWatchThread);
|
|
g_nOpenComState = 1;
|
|
|
|
return g_hCom;
|
|
}
|
|
}
|
|
CloseConnection();
|
|
}
|
|
|
|
return INVALID_HANDLE_VALUE;
|
|
}
|
|
|
|
BOOL CloseConnection()
|
|
{
|
|
if (g_hCom != INVALID_HANDLE_VALUE) {
|
|
SetCommMask(g_hCom, 0);
|
|
|
|
//Terminate Watch Thread
|
|
if (g_hCommWatchThread) {
|
|
SetEvent(g_hWatchEvent);
|
|
WaitForSingleObject(g_hCommWatchThread, INFINITE);
|
|
g_hCommWatchThread = NULL;
|
|
}
|
|
|
|
if (g_hWatchEvent) {
|
|
CloseHandle(g_hWatchEvent);
|
|
g_hWatchEvent = NULL;
|
|
}
|
|
|
|
if (g_hLampEvent) {
|
|
CloseHandle(g_hLampEvent);
|
|
g_hLampEvent = NULL;
|
|
}
|
|
|
|
EscapeCommFunction(g_hCom, CLRDTR);
|
|
|
|
// purge any outstanding reads/writes and close device handle
|
|
PurgeComm(g_hCom, PURGE_TXABORT|PURGE_RXABORT|PURGE_TXCLEAR|PURGE_RXCLEAR);
|
|
CloseHandle(g_hCom);
|
|
g_hCom = INVALID_HANDLE_VALUE;
|
|
|
|
// clean up event objects
|
|
|
|
if (ros.hEvent) {
|
|
CloseHandle(ros.hEvent);
|
|
ros.hEvent = NULL;
|
|
}
|
|
if (wos.hEvent) {
|
|
CloseHandle(wos.hEvent);
|
|
wos.hEvent = NULL;
|
|
}
|
|
g_nOpenComState = 0;
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
void TransmitCommChar2(HANDLE g_hCom,int ch)
|
|
{
|
|
#if 0
|
|
DWORD bytes;
|
|
WriteFile(g_hCom,&ch,1,&bytes,NULL);
|
|
FlushFileBuffers(g_hCom);
|
|
#else
|
|
TransmitCommChar(g_hCom,(char)ch);
|
|
#endif
|
|
}
|
|
|
|
int ReadCommBlock( LPSTR lpszBlock, int nMaxLength )
|
|
{
|
|
BOOL fReadStat ;
|
|
COMSTAT ComStat ;
|
|
DWORD dwErrorFlags;
|
|
DWORD dwLength;
|
|
DWORD dwError;
|
|
|
|
// only try to read number of bytes in queue
|
|
ClearCommError( g_hCom, &dwErrorFlags, &ComStat ) ;
|
|
retry:
|
|
dwLength = __min( (DWORD) nMaxLength, ComStat.cbInQue ) ;
|
|
|
|
if (dwLength > 0){
|
|
fReadStat = ReadFile( g_hCom, lpszBlock,dwLength, &dwLength, &ros);
|
|
for(int i=0;i<(int)dwLength;i++){
|
|
int ch=(BYTE)lpszBlock[i];
|
|
|
|
//받은 문자만큼 루프를 돈다.
|
|
//현재.. 받고 있는 packet이 없고.. 어떤 control문자라도 올 수 있는 상태이다.
|
|
|
|
if(packetbyteremain!=0){
|
|
//패킷에 해당하는 문자가 도착했다.. 나머지 문자들을 받는다.
|
|
if (ch & 0x80) {
|
|
packetbyteremain=0;
|
|
chinpacket=0;
|
|
continue;
|
|
}
|
|
packetbyteremain--;
|
|
packetbytes[chinpacket] = ch;
|
|
chinpacket++;
|
|
if (packetbyteremain == 0) {
|
|
//하나의 패킷이 완성되었다. 도착했다.. 즉시 반응한다.
|
|
chinpacket--; // exclude check byte
|
|
int packettype=packetbytes[0];
|
|
BYTE bCheckByte = 0;
|
|
for(int kkk = 0; kkk < chinpacket; kkk++) {
|
|
bCheckByte += packetbytes[kkk] & 0x7f;
|
|
}
|
|
static bool s_bool = true;
|
|
if (s_bool || (bCheckByte & 0x7f) ==packetbytes[chinpacket]) {
|
|
switch(packettype) {
|
|
//PC to RIO
|
|
case rio_CheckRequest:
|
|
case rio_VersionRequest:
|
|
case rio_AnalogRequest:
|
|
case rio_ResetRequest:
|
|
case rio_LampRequest:
|
|
/*if(ComStat.cbOutQue==0)
|
|
TransmitCommChar2(g_hCom,NAK_CHAR);
|
|
break;
|
|
*/
|
|
//RIO to PC
|
|
case rio_CheckReply:
|
|
case rio_VersionReply:
|
|
case rio_KeyPressed:
|
|
case rio_KeyReleased:
|
|
case rio_TestModeChange:
|
|
if(ComStat.cbOutQue==0)
|
|
TransmitCommChar2(g_hCom,ACK_CHAR);
|
|
break;
|
|
case rio_AnalogReply:
|
|
if(ComStat.cbOutQue==0)
|
|
TransmitCommChar2(g_hCom,ACK_CHAR);
|
|
AnalogEvent (packetbytes);
|
|
g_dwLastAnalogUpdate = 0;
|
|
break;
|
|
case rio_ButtonPressed:
|
|
case rio_ButtonReleased:
|
|
if (g_nRIOType == 0) {
|
|
if(ComStat.cbOutQue==0)
|
|
TransmitCommChar2(g_hCom,ACK_CHAR);
|
|
s_RIO.DoProcessButtons(&packetbytes[0]);
|
|
} else {
|
|
//MessageBeep(0);
|
|
|
|
BYTE id=packetbytes[2];
|
|
//if(CompareID(id,received_serial)==0){
|
|
SendAck2(id);
|
|
//if (packetbytes[1] != 4) {
|
|
// MessageBeep(0);
|
|
s_RIO.DoProcessButtons(&packetbytes[0]);
|
|
//}
|
|
|
|
received_serial++;
|
|
/*
|
|
char buf[16];
|
|
while(GetSerialFromReceivedBuffer(buf)){//check if any more serial packet in the received_buffer.
|
|
//if (packetbytes[1] != 4) {
|
|
// MessageBeep(0);
|
|
s_RIO.DoProcessButtons(&packetbytes[0]);
|
|
//}
|
|
}
|
|
}else{//id is not serial
|
|
if(CompareID(id,received_serial)>0) {
|
|
SendNak2(received_serial & 0x7f);
|
|
//new one..
|
|
SaveReceivedPacket(packetbytes,GetPacketLength(packetbytes));
|
|
} else if(CompareID(id,received_serial)<0) {
|
|
SendAck2(id);
|
|
//old pakcet ignore..
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
break;
|
|
case rio_Nak2:
|
|
#ifdef _DEBUG
|
|
packettype++;
|
|
packettype--;
|
|
#endif // _DEBUG
|
|
case rio_Ack2://◆◆◆◆◆◆◆◆◆◆
|
|
if (g_nRIOType != 0) {
|
|
BYTE id=packetbytes[1];
|
|
int popped_index=PopPacket(id);
|
|
ack_timeout=GetTickCount()+30;
|
|
if(popped_index==0){
|
|
//맨처음것... 정상적인 경우이다.
|
|
}else if(popped_index>0){
|
|
//맨처음것이 아닌것.
|
|
//이전것들이 정상적으로 보내지지 않았으므로 다시 보낸다...
|
|
ReSendPackets(popped_index);//잘못된 개수 만큼..
|
|
}else{
|
|
//실패 했다는것은.. 없는 id가 왔다는 것인데..
|
|
//명백한 에러.. 그러나 특별히 대처할 방법은 없다.
|
|
//그냥 무시한다.
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
} else {
|
|
if (g_nRIOType == 0) {
|
|
if (ComStat.cbOutQue==0) {
|
|
if ((packettype == rio_ButtonPressed) || (packettype == rio_ButtonReleased))
|
|
TransmitCommChar2(g_hCom,NAK_CHAR);
|
|
else
|
|
TransmitCommChar2(g_hCom,ACK_CHAR);
|
|
}
|
|
}
|
|
}
|
|
// TransmitCommChar2(g_hCom,0xFC);
|
|
// WriteTTYBlock(hWnd,"|",1);
|
|
chinpacket=0;
|
|
|
|
//packetbytes버퍼를 지운다.
|
|
} else {
|
|
//아직 패킷 문자들이 다 도착하지 않았다.. 아무것도 하지 않는다.
|
|
;
|
|
}
|
|
}else{
|
|
chinpacket=0;
|
|
if ((rio_CheckRequest <= ch) && (ch < (rio_CheckRequest+g_nRIOPacketCount))) {
|
|
packetbyteremain = g_pbRIOLengths[ch-rio_CheckRequest]+1;
|
|
chinpacket=0;
|
|
packetbytes[chinpacket]=ch;
|
|
chinpacket++;
|
|
} else {
|
|
WriteCommBlock(NULL, ch);
|
|
}
|
|
}
|
|
}//for(int i=0;i<(int)dwLength;i++)
|
|
|
|
|
|
//상훈 뒤
|
|
if (!fReadStat){
|
|
if (GetLastError() == ERROR_IO_PENDING){
|
|
while(!GetOverlappedResult( g_hCom,&ros, &dwLength, TRUE )){
|
|
dwError = GetLastError();
|
|
if(dwError == ERROR_IO_INCOMPLETE)
|
|
// normal result if not finished
|
|
continue;
|
|
else{
|
|
// an error occurred, try to recover
|
|
ClearCommError( g_hCom, &dwErrorFlags, &ComStat ) ;
|
|
break;
|
|
}
|
|
}
|
|
goto retry;
|
|
}else{
|
|
// some other error occurred
|
|
dwLength = 0 ;
|
|
ClearCommError( g_hCom, &dwErrorFlags, &ComStat ) ;
|
|
}
|
|
}
|
|
}
|
|
return dwLength;
|
|
}
|
|
|
|
BOOL WriteCommBlock(LPSTR lpByte, DWORD dwBytesToWrite)
|
|
{
|
|
if (lpByte == NULL) {
|
|
switch(dwBytesToWrite) {
|
|
case ACK_CHAR:
|
|
g_dwLastBytesToWrite = 0;
|
|
break;
|
|
case NAK_CHAR:
|
|
if (g_dwLastBytesToWrite != 0) {
|
|
if (g_baLastPacket[0] == rio_LampRequest) {
|
|
CBUTTON_GROUP::s_aButtonTable[g_baLastPacket[1]].lamp = LAMP_NOTEXIST;
|
|
}
|
|
g_dwLastBytesToWrite = 0;
|
|
}
|
|
break;
|
|
case RESTART_CHAR:
|
|
break;
|
|
case IDLE_CHAR:
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return FALSE;
|
|
}
|
|
//Normal Variables
|
|
BOOL fWriteStat ;
|
|
DWORD dwBytesWritten ;
|
|
DWORD dwBytesSent=0;
|
|
//Error Report
|
|
DWORD dwErrorFlags;
|
|
COMSTAT ComStat;
|
|
|
|
if (g_dwLastBytesToWrite == 0) {
|
|
g_dCancelCount = 0;
|
|
g_dwLastPacketTime = GetTickCount();
|
|
if (g_nRIOType == 0) {
|
|
g_dwLastBytesToWrite = dwBytesToWrite;
|
|
}
|
|
memcpy(g_baLastPacket, lpByte, dwBytesToWrite);
|
|
} else {
|
|
if (lpByte[0] == rio_LampRequest) {
|
|
CBUTTON_GROUP::s_aButtonTable[lpByte[1]].lamp = LAMP_NOTEXIST;
|
|
}
|
|
if (++g_dCancelCount >= 5) {
|
|
g_dwLastBytesToWrite = 0;
|
|
}
|
|
return FALSE;
|
|
}
|
|
fWriteStat = WriteFile(g_hCom, lpByte, dwBytesToWrite,&dwBytesWritten, &wos) ;
|
|
|
|
if (fWriteStat == FALSE) {
|
|
if (GetLastError() == ERROR_IO_PENDING) {
|
|
while(!GetOverlappedResult(g_hCom,&wos, &dwBytesWritten, TRUE)) {
|
|
if(GetLastError() == ERROR_IO_INCOMPLETE){
|
|
dwBytesSent += dwBytesWritten;
|
|
Sleep(0);//Yield the process to the others
|
|
} else {
|
|
ClearCommError(g_hCom, &dwErrorFlags, &ComStat ) ;
|
|
g_dwLastBytesToWrite = 0;
|
|
return FALSE;
|
|
}
|
|
}
|
|
} else {
|
|
ClearCommError(g_hCom, &dwErrorFlags, &ComStat ) ;
|
|
g_dwLastBytesToWrite = 0;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
DWORD FAR PASCAL CommWatchProc( LPSTR lpData )
|
|
{
|
|
wcos.hEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
|
|
HANDLE events[3]={wcos.hEvent,g_hWatchEvent,g_hLampEvent};
|
|
|
|
if (CTCL_IsConsole()) {
|
|
if (!SetCommMask( g_hCom, EV_RXCHAR/*|EV_CTS*/))
|
|
return ( FALSE ) ;
|
|
} else {
|
|
if (!SetCommMask( g_hCom, EV_RXCHAR ))
|
|
return ( FALSE ) ;
|
|
}
|
|
|
|
g_dwLastAnalogUpdate = GetTickCount() + 2800;
|
|
while(1) {
|
|
DWORD dwEvtMask = 0;
|
|
|
|
WaitCommEvent( g_hCom, &dwEvtMask,&wcos );
|
|
|
|
DWORD ret=WaitForMultipleObjects(3,events,FALSE,50/*INFINITE*/);
|
|
if(ret==WAIT_OBJECT_0){
|
|
//An Comm Event has arrived.
|
|
DWORD bytesread;
|
|
#ifdef USE_OVRIO
|
|
GetOverlappedResult(g_hCom,&wcos,&bytesread,FALSE);
|
|
#endif // USE_OVRIO
|
|
BYTE abIn[16] ;
|
|
ReadCommBlock((LPSTR) abIn, 16 );
|
|
//((dwEvtMask & EV_RXCHAR) == EV_RXCHAR)
|
|
/*if (CTCL_IsConsole()) {
|
|
if ((dwEvtMask & EV_CTS) == EV_CTS) {
|
|
static BYTE s_ba4[4] = { 255,0,255,0};
|
|
s_RIO.DoProcessButtons(&s_ba4[0]);
|
|
}
|
|
} else {*/
|
|
if (g_nRIOType != 0) {
|
|
///◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆위의 ReadCommBlock에서 ack를 받았을 경우 duetime을 update시킨다.
|
|
///◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆CheckSentBuffer...
|
|
if(GetTickCount()>ack_timeout)
|
|
ReSendPackets(sent_packet);//sent_buffer에 있는 모든것들을 다시 보내본다.
|
|
}
|
|
/*}*/
|
|
}else if(ret==WAIT_OBJECT_0+1){
|
|
//Terminate This Thread.
|
|
goto terminate;
|
|
}else if(ret==WAIT_OBJECT_0+2){
|
|
//g_hLampEvent is set.
|
|
g_pRIOMain->RunMain();
|
|
}else if(ret==WAIT_FAILED){
|
|
//can't be reached here.!!!
|
|
//break;
|
|
}else if (ret==WAIT_TIMEOUT) {
|
|
if (g_nRIOType != 0) {
|
|
///◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆◆CheckSentBuffer...
|
|
if(GetTickCount()>ack_timeout)
|
|
ReSendPackets(sent_packet);//sent_buffer에 있는 모든것들을 다시 보내본다.
|
|
}
|
|
if (packetbyteremain == 0) {
|
|
RequestAnalogUpdate();
|
|
|
|
/*
|
|
DWORD dwTicks = GetTickCount();
|
|
if ((g_dwLastAnalogUpdate == 0) || ((g_dwLastAnalogUpdate + 200) <= dwTicks)) {
|
|
g_dwLastAnalogUpdate = dwTicks;
|
|
RequestAnalogUpdate();
|
|
}
|
|
*/
|
|
} else {
|
|
}
|
|
}
|
|
}
|
|
terminate:
|
|
// get rid of event handle
|
|
|
|
CloseHandle( wcos.hEvent ) ;
|
|
return( TRUE ) ;
|
|
}
|
|
|
|
short CombinePair(BYTE low_value, BYTE high_value)
|
|
{
|
|
short result;
|
|
result = (short)(((short) (low_value & 0x7F)) | (((short) high_value) << 7));
|
|
if (result & 0x2000)
|
|
{
|
|
result |= ~0x3FFF;
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
void AnalogEvent (BYTE *pData)
|
|
{
|
|
/*
|
|
for (int i = 1; i <= 10; i++) {
|
|
if (pData[i] == 0xFE) {
|
|
//AnalogAllReset ();
|
|
return;
|
|
}
|
|
}
|
|
*/
|
|
g_Throttle = CombinePair (pData[1], pData[2]);
|
|
g_LeftPedal = CombinePair(pData[3], pData[4]);
|
|
g_RightPedal = CombinePair(pData[5], pData[6]);
|
|
g_JoystickY = CombinePair(pData[7], pData[8]);
|
|
g_JoystickX = CombinePair(pData[9], pData[10]);
|
|
/*
|
|
static char s_szStr[256];
|
|
sprintf (s_szStr, "JOYX[%d]\n",g_JoystickX);
|
|
::OutputDebugString(s_szStr);
|
|
*/
|
|
}
|
|
|
|
BOOL SendPacket (const BYTE *ba,int length)
|
|
{
|
|
if (g_nRIOType != 0) {
|
|
if(ba[0]==rio_LampRequest){
|
|
QueuePacket(ba,length);
|
|
}
|
|
}
|
|
return WriteCommBlock((LPSTR)ba,length);
|
|
}
|
|
|
|
BOOL SendCommand (const BYTE* pbPacket)
|
|
{
|
|
BYTE ba[256];
|
|
BYTE bCmd = *pbPacket;
|
|
int cmdindex=bCmd & 0x7F;
|
|
|
|
if (bCmd & 0x80) {
|
|
if (cmdindex < g_nRIOPacketCount) {
|
|
int nLeft = 1/* 1byte command */ + g_pbRIOLengths[cmdindex];
|
|
|
|
BYTE bCheck = 0;
|
|
BYTE * p=ba;
|
|
|
|
while (nLeft > 0) {
|
|
BYTE b = *pbPacket++;
|
|
*p++ = b;
|
|
bCheck += b & 0x7F;
|
|
nLeft--;
|
|
}
|
|
|
|
*p++ = bCheck & 0x7F;
|
|
|
|
return SendPacket (ba, p - ba);
|
|
} else {
|
|
//unknown command
|
|
}
|
|
} else {
|
|
;//error
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
BOOL SetLamp(int lampNumber, int state)
|
|
{
|
|
static BYTE request_lamp_string[] = { rio_LampRequest, 0, 0, 0 };
|
|
|
|
request_lamp_string[1] = (BYTE) (lampNumber & 0x7F);
|
|
request_lamp_string[2] = (BYTE) (state & 0x7F);
|
|
if (g_nRIOType != 0) {
|
|
request_lamp_string[3] = (BYTE) (sent_serial++ & 0x7F);
|
|
}
|
|
|
|
return SendCommand (request_lamp_string);
|
|
}
|
|
|
|
void AnalogAllReset ()
|
|
{
|
|
ResetThrottle ();
|
|
ResetLeftPedal ();
|
|
ResetRightPedal();
|
|
ResetVerticalJoystick();
|
|
ResetHorizontalJoystick();
|
|
}
|
|
|
|
void GeneralReset()
|
|
{
|
|
received_serial = 0;
|
|
static BYTE request_reset_string[] = { rio_ResetRequest, 0 };
|
|
SendCommand (request_reset_string);
|
|
}
|
|
|
|
void ResetThrottle()
|
|
{
|
|
static BYTE request_throttle_string[] = { rio_ResetRequest, 1 };
|
|
SendCommand (request_throttle_string);
|
|
}
|
|
|
|
void ResetLeftPedal()
|
|
{
|
|
static BYTE request_lpedal_string[] = { rio_ResetRequest, 2 };
|
|
SendCommand (request_lpedal_string);
|
|
}
|
|
|
|
void ResetRightPedal()
|
|
{
|
|
static BYTE request_rpedal_string[] = { rio_ResetRequest, 3 };
|
|
SendCommand (request_rpedal_string);
|
|
}
|
|
|
|
void ResetVerticalJoystick()
|
|
{
|
|
static BYTE request_vstick_string[] = { rio_ResetRequest, 4 };
|
|
SendCommand (request_vstick_string);
|
|
}
|
|
|
|
void ResetHorizontalJoystick()
|
|
{
|
|
static BYTE request_hstick_string[] = { rio_ResetRequest, 5 };
|
|
SendCommand (request_hstick_string);
|
|
}
|
|
|
|
void RequestCheck()
|
|
{
|
|
static BYTE request_check_string[] = { rio_CheckRequest };
|
|
SendCommand (request_check_string);
|
|
}
|
|
|
|
void RequestVersion()
|
|
{
|
|
static BYTE request_version_string[] = { rio_VersionRequest };
|
|
SendCommand (request_version_string);
|
|
}
|
|
|
|
void RequestAnalogUpdate(BYTE bFreq/* = 3*/)
|
|
{
|
|
static BYTE request_analog_string[] = { rio_AnalogRequest, 3/* freq */ };
|
|
if (g_nRIOType != 0) {
|
|
request_analog_string[1] = bFreq;
|
|
}
|
|
|
|
SendCommand (request_analog_string);
|
|
}
|
|
|
|
bool SaveReceivedPacket(const BYTE*ba,int length)
|
|
{
|
|
if(received_packet<127){
|
|
//MessageBeep(0);
|
|
CopyMemory(received_buffer[received_packet],ba,length);
|
|
received_packet++;
|
|
return true;
|
|
}else{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool GetSerialFromReceivedBuffer(char * ba)
|
|
{
|
|
//ButtonPressed/Released만 저장해 놓는다..
|
|
//모든 serial packet을 옮긴다.
|
|
if(received_packet>0){
|
|
if(received_buffer[0][2]==received_serial){
|
|
CopyMemory(ba,received_buffer[0],16);
|
|
if(received_packet>1)
|
|
MoveMemory(received_buffer[0],received_buffer[1],(received_packet-1)*16);
|
|
received_packet--;
|
|
received_serial++;
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool QueuePacket(const BYTE *ba,int length)
|
|
{
|
|
if(sent_packet<127){
|
|
CopyMemory(sent_buffer[sent_packet],ba,length);
|
|
sent_packet++;
|
|
return true;
|
|
}else{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int PopPacket(BYTE id)
|
|
{
|
|
//lamp는.. id가..
|
|
//search the packet..
|
|
for(int i=0;i<sent_packet;i++){
|
|
if(sent_buffer[i][3]==id){
|
|
//found the packet..
|
|
int packets_to_move=sent_packet-i-1;
|
|
if(packets_to_move>0)
|
|
MoveMemory(sent_buffer[i],sent_buffer[i+1],packets_to_move*16);
|
|
sent_packet--;
|
|
//if (i == 0)
|
|
// return 0;
|
|
return i;//found the item sucessfully
|
|
}
|
|
}
|
|
return -1;//didn't find the item
|
|
}
|
|
|
|
int GetPacketLength(BYTE * ba)
|
|
{
|
|
return (1+g_pbRIOLengths[ba[0]-rio_CheckRequest]+1);//header+body+CS
|
|
}
|
|
|
|
void ReSendPackets(int count)
|
|
{
|
|
gosASSERT(count<=sent_packet);
|
|
ack_timeout=GetTickCount()+30;
|
|
for(int i=0;i<count;++i){
|
|
BYTE ba[16];
|
|
CopyMemory(ba,sent_buffer[0],16);
|
|
int packets_to_move=sent_packet-1;
|
|
if(packets_to_move)
|
|
MoveMemory(sent_buffer[0],sent_buffer[1],packets_to_move*16);
|
|
sent_packet--;
|
|
int length=1+g_pbRIOLengths[ba[0]-rio_CheckRequest]+1;//header+body+CS
|
|
SendPacket(ba,length);
|
|
}
|
|
}
|
|
|
|
void SendAck2(BYTE id)
|
|
{
|
|
BYTE packet[2]={rio_Ack2,id};
|
|
SendCommand(packet);
|
|
}
|
|
|
|
void SendNak2(BYTE id)
|
|
{
|
|
BYTE packet[2]={rio_Nak2,id};
|
|
SendCommand(packet);
|
|
}
|
|
|
|
int CompareID(int id,int serial)
|
|
{
|
|
serial &= 0x7F;
|
|
if (id !=serial) {
|
|
if (id>serial) {
|
|
if(id-serial<63)
|
|
return 1;
|
|
else
|
|
return -1;
|
|
} else {//if(id<serial)
|
|
if(serial-id<63)
|
|
return -1;
|
|
else
|
|
return 1;
|
|
}
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
CBUTTON_GROUP::CBUTTON_GROUP ()
|
|
{
|
|
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
|
s_aSaveLamp[b] = s_aButtonTable[b].lamp;
|
|
}
|
|
|
|
}
|
|
|
|
CBUTTON_GROUP::~CBUTTON_GROUP ()
|
|
{
|
|
}
|
|
|
|
void CBUTTON_GROUP::SetTable(BOOL bFlag/* = true*/)
|
|
{
|
|
if (bFlag == TRUE)
|
|
{
|
|
if (!g_StartGame) {
|
|
g_StartGame = TRUE;
|
|
|
|
memset(g_naButtonThrottles, 0, sizeof(g_naButtonThrottles));
|
|
//GeneralReset ();
|
|
|
|
m_bFreeForAll = MWApplication::GetInstance()->IsTeamAllowed() ? FALSE: TRUE;
|
|
if (m_bFreeForAll)
|
|
g_nTeamOrderMode = FREEFORALL_MODE;
|
|
else
|
|
g_nTeamOrderMode = TEAM_MODE;
|
|
|
|
MWApplication::GetInstance()->ClearTOC();
|
|
g_fLastStartTime = 0.0;
|
|
g_fLastCameraShipTime = gos_GetElapsedTime();
|
|
g_fLastScoringTime = g_fLastScoringTimeCechk = gos_GetElapsedTime();
|
|
m_bOneFlagShutDown = FALSE;
|
|
|
|
// MSL 5.03 Ammo Dump
|
|
g_nAmmoDump1 = FALSE;
|
|
g_nAmmoDump2 = FALSE;
|
|
|
|
g_nAssignGroup1 = FALSE;
|
|
g_nAssignGroup2 = FALSE;
|
|
g_nAssignGroup3 = FALSE;
|
|
g_nPrevWeapon = FALSE;
|
|
g_nNextWeapon = FALSE;
|
|
|
|
g_nProgramMode = FALSE;
|
|
g_nFiringMode = FALSE;
|
|
MechWarrior4::g_baChainFireMode[0] = MechWarrior4::g_baChainFireMode[1] = MechWarrior4::g_baChainFireMode[2] = FALSE;//han
|
|
// MSL 5.05 Objective Display
|
|
g_bObjMode = false;
|
|
g_bMuteMode = false;
|
|
// MSL 5.03 Secondary Damage Display
|
|
g_nAuxilMode = 0;
|
|
// MSL 5.02 Pinky Button
|
|
if (VehGetJumpJetState() > 0)
|
|
{
|
|
g_bJumpZoom = true; // Secondary button 16 set to Jump
|
|
s_aButtonTable[69].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[16].norm_key = 'J';
|
|
g_bZoomMode = true;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
else
|
|
{
|
|
g_bJumpZoom = false; // Secondary button 16 set to Zoom
|
|
s_aButtonTable[69].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[16].norm_key = VK_NUMPAD0;
|
|
g_bZoomMode = true;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
|
|
g_nInputMode = g_nOldInputMode = _BIGINNER_MODE;
|
|
g_ThrottleResult = -1L;
|
|
g_HatResult = -1L;
|
|
|
|
g_ThrottleStart = INT_MIN;
|
|
g_LeftPedalStart = INT_MAX;
|
|
g_RightPedalStart = INT_MAX;
|
|
g_JoystickXLast = 0;
|
|
g_JoystickYLast = 0;
|
|
g_ThrottleLast = 0;
|
|
g_LeftPedalLast = 0;
|
|
g_RightPedalLast = 0;
|
|
|
|
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
|
s_aCtrlLamp[b] = s_aSaveLamp[b];// = s_aButtonTable[b].lamp;
|
|
// s_aButtonTable는 Old값이므로 초기치는 Off
|
|
s_aButtonTable[b].lamp = LAMP_OFF;
|
|
}
|
|
|
|
PLASMA_Do(2);
|
|
|
|
SetLampState (30, LAMP_BRIGHT);
|
|
SetLampState (59, LAMP_BRIGHT);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 모든 테이블을 원래 상태로
|
|
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
|
s_aCtrlLamp[b] = s_aSaveLamp[b];
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBUTTON_GROUP::ResetTable(BOOL bFlag/* = true*/)
|
|
{
|
|
if (bFlag == TRUE)
|
|
{
|
|
if (g_StartGame) {
|
|
g_StartGame = FALSE;
|
|
PLASMA_Do(1);
|
|
|
|
//GeneralReset ();
|
|
|
|
m_bFreeForAll = FALSE;
|
|
MWApplication::GetInstance()->ClearTOC();
|
|
g_fLastStartTime = 0.0;
|
|
g_fLastCameraShipTime = 0.0;
|
|
g_fLastScoringTimeCechk = 0.0;
|
|
g_fLastScoringTime = 0.0;
|
|
m_bOneFlagShutDown = FALSE;
|
|
|
|
// MSL 5.03 Ammo Dump
|
|
g_nAmmoDump1 = FALSE;
|
|
g_nAmmoDump2 = FALSE;
|
|
|
|
g_nAssignGroup1 = FALSE;
|
|
g_nAssignGroup2 = FALSE;
|
|
g_nAssignGroup3 = FALSE;
|
|
g_nPrevWeapon = FALSE;
|
|
g_nNextWeapon = FALSE;
|
|
|
|
g_nProgramMode = FALSE;
|
|
g_nFiringMode = FALSE;
|
|
MechWarrior4::g_baChainFireMode[0] = MechWarrior4::g_baChainFireMode[2] = MechWarrior4::g_baChainFireMode[2] = FALSE;//han
|
|
// MSL 5.05 Objective Display
|
|
g_bObjMode = false;
|
|
g_bMuteMode = false;
|
|
// MSL 5.03 Secondary Damage Display
|
|
g_nAuxilMode = 0;
|
|
// MSL 5.02 Pinky Button
|
|
if (VehGetJumpJetState() > 0)
|
|
{
|
|
g_bJumpZoom = true; // Secondary button 16 set to Jump
|
|
s_aButtonTable[69].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[16].norm_key = 'J';
|
|
g_bZoomMode = true;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
else
|
|
{
|
|
g_bJumpZoom = false; // Secondary button 16 set to Zoom
|
|
s_aButtonTable[69].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[16].norm_key = VK_NUMPAD0;
|
|
g_bZoomMode = true;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
|
|
g_nInputMode = g_nOldInputMode = _BIGINNER_MODE;
|
|
g_ThrottleResult = -1L;
|
|
g_HatResult = -1L;
|
|
//g_JoystickXStart = INT_MIN;
|
|
//g_JoystickXEnd = INT_MAX;
|
|
//g_JoystickYStart = INT_MAX;
|
|
//g_JoystickYEnd = INT_MIN;
|
|
g_ThrottleStart = INT_MIN;
|
|
g_LeftPedalStart = INT_MAX;
|
|
g_RightPedalStart = INT_MAX;
|
|
g_JoystickXLast = 0;
|
|
g_JoystickYLast = 0;
|
|
g_ThrottleLast = 0;
|
|
g_LeftPedalLast = 0;
|
|
g_RightPedalLast = 0;
|
|
|
|
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
|
s_aCtrlLamp[b] = LAMP_OFF; // s_aSaveLamp[b];
|
|
}
|
|
|
|
SetLampState (59, LAMP_OFF);
|
|
SetLampState (30, LAMP_OFF);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// 모든 테이블을 Off
|
|
for (int b = 0; b < MAXBUTTON_TABLE; b++) {
|
|
switch(b)
|
|
{
|
|
case 17: // ShutDown Command
|
|
case 48: // Pinky Trigger
|
|
case 49: // Pinky Trigger
|
|
case 50: // Pinky Trigger
|
|
case 51: // Pinky Trigger
|
|
case 52: // Right MFD - Damage MFD(Armor Mode)
|
|
case 53: // Pinky Trigger
|
|
case 54: // Pinky Trigger
|
|
case 55: // MUTE
|
|
// case 39: // Team Speak?
|
|
case 36: // Objective Display
|
|
case 12: // Target Armor State
|
|
case 8: // Corss Hair Target
|
|
case 0: // Assign Group3
|
|
case 1: // Assign Group2
|
|
case 2: // Assign Group1
|
|
case 3: // firing Mode
|
|
case 4: // Prev Weapon
|
|
case 5: // Next Weapon
|
|
case 6: // Chainfire Mode
|
|
case 7: // Groupfire Mode
|
|
break;
|
|
default:
|
|
s_aCtrlLamp[b] = LAMP_OFF;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int CBUTTON_GROUP::GetLampState(BYTE b) const
|
|
{
|
|
return s_aCtrlLamp[b];
|
|
}
|
|
|
|
void CBUTTON_GROUP::SetLampState(BYTE b, int State)
|
|
{
|
|
BYTE &lamp = s_aCtrlLamp[b];
|
|
|
|
BYTE Oldlamp = lamp;
|
|
|
|
#ifdef _DEBUG
|
|
static BYTE g_bWatch = 26;
|
|
if (b == g_bWatch) {
|
|
int a = 0;
|
|
a++;
|
|
a--;
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
if (State == LAMP_DEFAULT) { //Defalult Lamp Set
|
|
const BYTE dlamp = s_aSaveLamp[b];
|
|
|
|
lamp = dlamp;
|
|
#ifdef _DEBUG
|
|
State = dlamp;
|
|
#endif // _DEBUG
|
|
} else {
|
|
lamp = (BYTE)State;
|
|
}
|
|
|
|
if (Oldlamp != lamp) {
|
|
#if 0 // def _DEBUG
|
|
char sz[64];
|
|
sprintf(sz, "but: %d, old %d -> new %d\n", b, Oldlamp, State);
|
|
::OutputDebugString(sz);
|
|
#endif // _DEBUG
|
|
//SetEvent(g_hLampEvent);
|
|
}
|
|
}
|
|
|
|
CRIOMAIN::CRIOMAIN (HWND hWnd)
|
|
{
|
|
g_hWnd = hWnd;
|
|
m_bGamePlaying = FALSE;
|
|
m_bFreeForAll = FALSE;
|
|
MWApplication::GetInstance()->ClearTOC();
|
|
g_fLastStartTime = 0.0;
|
|
g_fLastCameraShipTime = 0.0;
|
|
g_fLastScoringTimeCechk = 0.0;
|
|
g_fLastScoringTime = 0.0;
|
|
m_bOneFlagShutDown = FALSE;
|
|
|
|
OpenConnection(1); //
|
|
GeneralReset ();
|
|
RequestAnalogUpdate ();
|
|
|
|
//SetTable ();
|
|
}
|
|
|
|
CRIOMAIN::~CRIOMAIN ()
|
|
{
|
|
GeneralReset ();
|
|
CloseConnection ();
|
|
}
|
|
|
|
int CRIOMAIN::IsLampOFF(int n) const
|
|
{
|
|
if (s_aCtrlLamp[n] == LAMP_OFF) {
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void CRIOMAIN::RunMain ()
|
|
{
|
|
if (this) {
|
|
//RequestAnalogUpdate ();
|
|
if (g_nOpenComState) {
|
|
if (g_dwLastBytesToWrite == 0) {
|
|
for (int b = 0; b < MAXBUTTON_TABLE; b++)
|
|
{
|
|
BYTE Newlamp = s_aCtrlLamp[b];
|
|
|
|
BYTE &Oldlamp = s_aButtonTable[b].lamp;
|
|
|
|
if (Newlamp != Oldlamp)
|
|
{
|
|
Oldlamp = Newlamp;
|
|
LampEvent (b);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOL CRIOMAIN::LampEvent (BYTE b)
|
|
{
|
|
BYTE state = s_aButtonTable[b].lamp;
|
|
|
|
switch (state)
|
|
{
|
|
case LAMP_NONE:
|
|
return TRUE;
|
|
|
|
case LAMP_OFF:
|
|
state = LampSolidOff;
|
|
break;
|
|
|
|
case LAMP_DIM:
|
|
state = LampSolidDim;
|
|
break;
|
|
|
|
case LAMP_BRIGHT:
|
|
state = LampSolidBright;
|
|
break;
|
|
case LAMP_FLASH:
|
|
state = solid + flashMed + state2Bright;
|
|
break;
|
|
|
|
default:
|
|
state = LampSolidOff;
|
|
break;
|
|
|
|
}
|
|
|
|
return SetLamp (b, state);
|
|
}
|
|
|
|
void CRIOMAIN::ButtonEvent(BYTE state, BYTE index)
|
|
{
|
|
if ((index < 0) || (MAXBUTTON_TABLE <= index)) {
|
|
return;
|
|
}
|
|
|
|
if (g_StartGame)
|
|
AnalogButton(state, index);
|
|
|
|
// Is Biginner mode -> disable key
|
|
switch (index)
|
|
{
|
|
//case 16: // Jump Jets
|
|
//case 33: // Jump Jets
|
|
//case 34: // Jump Jets
|
|
case 31: // Eject
|
|
case 61: // Eject
|
|
case 20: // Crouch
|
|
case 17: // ShutDown
|
|
case 25: // radar Mode
|
|
case 26: // light amp
|
|
if (g_nInputMode == _BIGINNER_MODE) {
|
|
return;
|
|
} else {
|
|
break;
|
|
}
|
|
case 30:
|
|
case 56:
|
|
if (g_bCOOP && (state == rio_ButtonPressed)) {
|
|
extern void _stdcall PlayCoinSound(int nSound);
|
|
|
|
g_nCoinCount++;
|
|
PlayCoinSound(0);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!g_StartGame) {
|
|
#if 0 // def _DEBUG
|
|
if (state == rio_ButtonPressed) {
|
|
int n = GetLampState(index);
|
|
if (n < LAMP_FLASH) {
|
|
if (n <= LAMP_OFF)
|
|
n = LAMP_DIM;
|
|
else
|
|
n++;
|
|
} else {
|
|
n = LAMP_OFF;
|
|
}
|
|
//LAMP_OFF, LAMP_DIM, LAMP_BRIGHT, LAMP_FLASH
|
|
SetLampState(index, n);
|
|
}
|
|
#endif // _DEBUG
|
|
return;
|
|
}
|
|
int norm_key = CBUTTON_GROUP::s_aButtonTable[index].norm_key;
|
|
if (norm_key < 0)
|
|
return;
|
|
int mod_key = CBUTTON_GROUP::s_aButtonTable[index].mod_key;
|
|
if (mod_key < 0)
|
|
return;
|
|
|
|
switch (state)
|
|
{
|
|
case rio_ButtonPressed:
|
|
if (mod_key > 0) {
|
|
SendMessage (g_hWnd, WM_KEYDOWN, mod_key, 0);
|
|
}
|
|
SendMessage (g_hWnd, WM_KEYDOWN, norm_key, 0);
|
|
break;
|
|
case rio_ButtonReleased:
|
|
SendMessage (g_hWnd, WM_KEYUP, norm_key, 0);
|
|
if (mod_key > 0) {
|
|
SendMessage (g_hWnd, WM_KEYUP, mod_key, 0);
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
#if defined(_DEBUG) && 0 // watcom
|
|
static char s_szStr[256];
|
|
sprintf (s_szStr, "Key:[%d]\n",index);
|
|
::OutputDebugString(s_szStr);
|
|
#endif // watcom
|
|
}
|
|
|
|
void CRIOMAIN::AnalogButton(const BYTE state, const BYTE index)
|
|
{
|
|
NetMissionParameters::MWNetMissionParameters *params;
|
|
if (MWApplication::GetInstance()->serverFlag)
|
|
params = MWApplication::GetInstance()->GetLocalNetParams();
|
|
else
|
|
params = MWApplication::GetInstance()->GetServerNetParams();
|
|
m_HeatMode = params->m_heatOn;
|
|
int m_AmmoMode = params->m_ammobayfireOn;
|
|
int m_WeaponJamMode = params->m_weaponjamOn;
|
|
|
|
if (state == rio_ButtonPressed)
|
|
{
|
|
switch(index) {
|
|
case 29:
|
|
if (VehGetShutdownState() == 0) {
|
|
if (g_nProgramMode) {
|
|
if (g_nInputMode < _EXPERT_MODE) {
|
|
g_nInputMode++;
|
|
} else {
|
|
g_nInputMode = _BIGINNER_MODE;
|
|
}
|
|
|
|
SetLampState (29, LAMP_BRIGHT);
|
|
}
|
|
} else {
|
|
#if 0 // def _DEBUG
|
|
switch(VehGetShutdownState()) {
|
|
case -3:
|
|
SetLampState (29, flashFast | state1Bright | state2Off);
|
|
break;
|
|
case -2:
|
|
SetLampState (29, flashSlow | state1Dim | state2Off);
|
|
break;
|
|
case -1:
|
|
SetLampState (29, state1Dim | state2Dim);
|
|
break;
|
|
case +1:
|
|
SetLampState (29, state1Dim | state2Bright);
|
|
break;
|
|
}
|
|
#endif // _DEBUG
|
|
}
|
|
break;
|
|
// case 39:
|
|
// {
|
|
// SetLampState (39, LAMP_BRIGHT);
|
|
// SendMessage (HWND_BROADCAST, WM_KEYDOWN, 'T', 0);
|
|
// }
|
|
// break;
|
|
case 48:
|
|
if (g_LightAmp == TRUE)
|
|
{
|
|
if ((g_bJumpMode == true) && (GetLampState(33) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'J', 0);
|
|
if ((g_bFlushMode == true) && (GetLampState(19) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'F', 0);
|
|
s_aButtonTable[69].norm_key = 'A';
|
|
s_aButtonTable[69].mod_key = SYSKEY_NULL;
|
|
SetLampState (48, LAMP_BRIGHT);
|
|
g_bZoomMode = false;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = true;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
break;
|
|
case 49:
|
|
if ((g_bJumpMode == true) && (GetLampState(33) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'J', 0);
|
|
if (m_HeatMode)
|
|
{
|
|
s_aButtonTable[69].norm_key = 'F';
|
|
s_aButtonTable[69].mod_key = SYSKEY_NULL;
|
|
SetLampState (49, LAMP_BRIGHT);
|
|
SetLampState (1, LAMP_BRIGHT);
|
|
g_bZoomMode = false;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = true;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
else
|
|
{
|
|
g_bFlushMode = false;
|
|
SetLampState (49, LAMP_OFF);
|
|
SetLampState (19, LAMP_OFF);
|
|
}
|
|
break;
|
|
case 50:
|
|
if ((g_bFlushMode == true) && (GetLampState(19) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'F', 0);
|
|
SetLampState (50, LAMP_BRIGHT);
|
|
if (VehGetJumpJetState() > 0)
|
|
{
|
|
g_bJumpZoom = false; // Secondary button 16 set to Zoom
|
|
s_aButtonTable[69].norm_key = 'J';
|
|
s_aButtonTable[16].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[69].mod_key = SYSKEY_NULL;
|
|
g_bZoomMode = false;
|
|
g_bJumpMode = true;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
else
|
|
{
|
|
g_bJumpZoom = false; // Secondary button 16 set to Zoom
|
|
s_aButtonTable[16].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[69].mod_key = SYSKEY_NULL;
|
|
}
|
|
break;
|
|
case 51:
|
|
if ((g_bJumpMode == true) && (GetLampState(33) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'J', 0);
|
|
if ((g_bFlushMode == true) && (GetLampState(19) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'F', 0);
|
|
SetLampState (51, LAMP_BRIGHT);
|
|
if (VehGetJumpJetState() > 0)
|
|
{
|
|
g_bJumpZoom = true; // Secondary button 16 set to Jump
|
|
s_aButtonTable[69].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[16].norm_key = 'J';
|
|
s_aButtonTable[69].mod_key = SYSKEY_NULL;
|
|
g_bZoomMode = true;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
else
|
|
{
|
|
g_bJumpZoom = false; // Secondary button 16 set to Zoom
|
|
s_aButtonTable[69].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[16].norm_key = VK_NUMPAD0;
|
|
s_aButtonTable[69].mod_key = SYSKEY_NULL;
|
|
g_bZoomMode = true;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
break;
|
|
case 53: // Crosshair Target
|
|
{
|
|
if ((g_bJumpMode == true) && (GetLampState(33) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'J', 0);
|
|
if ((g_bFlushMode == true) && (GetLampState(19) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'F', 0);
|
|
s_aButtonTable[69].norm_key = 'Q';
|
|
s_aButtonTable[69].mod_key = SYSKEY_NULL;
|
|
SetLampState (53, LAMP_BRIGHT);
|
|
g_bZoomMode = false;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = false;
|
|
g_bCrossTargetMode = true;
|
|
}
|
|
break;
|
|
case 54: // Next Target
|
|
{
|
|
if ((g_bJumpMode == true) && (GetLampState(33) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'J', 0);
|
|
if ((g_bFlushMode == true) && (GetLampState(19) == LAMP_BRIGHT))
|
|
SendMessage (g_hWnd, WM_KEYUP, 'F', 0);
|
|
s_aButtonTable[69].norm_key = 'E';
|
|
s_aButtonTable[69].mod_key = SYSKEY_SHFT;
|
|
SetLampState (54, LAMP_BRIGHT);
|
|
g_bZoomMode = false;
|
|
g_bJumpMode = false;
|
|
g_bFlushMode = false;
|
|
g_bLightAmpMode = false;
|
|
g_bNextTargetMode = true;
|
|
g_bCrossTargetMode = false;
|
|
}
|
|
break;
|
|
// MSL 5.03 Secondary Damage Display
|
|
case 18:
|
|
g_nAuxilMode++;
|
|
if (g_nAuxilMode > 2)
|
|
{
|
|
g_nAuxilMode = 0;
|
|
}
|
|
SetLampState (18, LAMP_BRIGHT);
|
|
break;
|
|
case 21:
|
|
if (VehGetShutdownState() == 0) {
|
|
g_nProgramMode = TRUE;
|
|
SetLampState (21, LAMP_BRIGHT);
|
|
} else {
|
|
#if 0 // def _DEBUG
|
|
switch(VehGetShutdownState()) {
|
|
case -3:
|
|
SetLampState (29, flashFast | state1Bright | state2Off);
|
|
break;
|
|
case -2:
|
|
SetLampState (29, flashSlow | state1Dim | state2Off);
|
|
break;
|
|
case -1:
|
|
SetLampState (29, state1Dim | state2Dim);
|
|
break;
|
|
case +1:
|
|
SetLampState (29, state1Dim | state2Bright);
|
|
break;
|
|
}
|
|
#endif // _DEBUG
|
|
}
|
|
break;
|
|
// MSL 5.03 Dump Ammo
|
|
case 32:
|
|
g_nAmmoDump2 = TRUE;
|
|
SetLampState (32, LAMP_BRIGHT);
|
|
break;
|
|
// MSL 5.03 Dump Ammo
|
|
case 35:
|
|
g_nAmmoDump1 = TRUE;
|
|
SetLampState (35, LAMP_BRIGHT);
|
|
break;
|
|
case 0:
|
|
g_nAssignGroup3 = TRUE;
|
|
break;
|
|
case 1:
|
|
g_nAssignGroup2 = TRUE;
|
|
break;
|
|
case 2:
|
|
g_nAssignGroup1 = TRUE;
|
|
break;
|
|
case 3:
|
|
g_nFiringMode = TRUE;
|
|
SetLampState (3, LAMP_BRIGHT);
|
|
break;
|
|
case 4:
|
|
g_nPrevWeapon = TRUE;
|
|
break;
|
|
case 5:
|
|
g_nNextWeapon = TRUE;
|
|
break;
|
|
case 6: // Chainfire Mode
|
|
MechWarrior4::g_baChainFireMode[0] = MechWarrior4::g_baChainFireMode[1] = MechWarrior4::g_baChainFireMode[2] = TRUE;
|
|
SetLampState(6, LAMP_BRIGHT);
|
|
break;
|
|
case 7: // Groupfire Mode
|
|
MechWarrior4::g_baChainFireMode[0] = MechWarrior4::g_baChainFireMode[1] = MechWarrior4::g_baChainFireMode[2] = FALSE;
|
|
SetLampState(7, LAMP_BRIGHT);
|
|
break;
|
|
case 63: // Throttle Back
|
|
g_ThrottleResult = 1L;
|
|
break;
|
|
case 65: // Hat_Down
|
|
g_HatResult = 18000L;
|
|
break;
|
|
case 66: // Hat_Up
|
|
g_HatResult = 0L;
|
|
break;
|
|
case 67: // Hat_right
|
|
g_HatResult = 9000L;
|
|
break;
|
|
case 68: // Hat_left
|
|
g_HatResult = 27000L;
|
|
break;
|
|
}
|
|
}
|
|
else if (state == rio_ButtonReleased)
|
|
{
|
|
switch(index)
|
|
{
|
|
case 29:
|
|
SetLampState (29, LAMP_DEFAULT);
|
|
break;
|
|
// case 39:
|
|
// {
|
|
// SetLampState (39, LAMP_DEFAULT);
|
|
// SendMessage (HWND_BROADCAST, WM_KEYUP, 'T', 0);
|
|
// }
|
|
// break;
|
|
case 48:
|
|
if (g_LightAmp == TRUE)
|
|
SetLampState (48, LAMP_DEFAULT);
|
|
break;
|
|
case 49:
|
|
if (m_HeatMode)
|
|
SetLampState (49, LAMP_DEFAULT);
|
|
else
|
|
SetLampState (49, LAMP_OFF);
|
|
break;
|
|
case 50:
|
|
if (VehGetJumpJetState() > 0)
|
|
{
|
|
SetLampState (50, LAMP_DEFAULT);
|
|
}
|
|
else
|
|
{
|
|
SetLampState (50, LAMP_OFF);
|
|
}
|
|
break;
|
|
case 51:
|
|
SetLampState (51, LAMP_DEFAULT);
|
|
break;
|
|
case 53:
|
|
SetLampState (53, LAMP_DEFAULT);
|
|
break;
|
|
case 54:
|
|
SetLampState (54, LAMP_DEFAULT);
|
|
break;
|
|
// MSL 5.03 Secondary Damage Display
|
|
case 18:
|
|
SetLampState (18, LAMP_DEFAULT);
|
|
break;
|
|
case 21:
|
|
g_nProgramMode = FALSE;
|
|
SetLampState (21, LAMP_DEFAULT);
|
|
break;
|
|
// MSL 5.03 Dump Ammo
|
|
case 32:
|
|
g_nAmmoDump2 = FALSE;
|
|
SetLampState (32, LAMP_DEFAULT);
|
|
break;
|
|
// MSL 5.03 Dump Ammo
|
|
case 35:
|
|
g_nAmmoDump1 = FALSE;
|
|
SetLampState (35, LAMP_DEFAULT);
|
|
break;
|
|
case 3:
|
|
g_nFiringMode = FALSE;
|
|
SetLampState (3, LAMP_DEFAULT);
|
|
break;
|
|
case 6: // Chainfire Mode
|
|
SetLampState(6, LAMP_DEFAULT);
|
|
break;
|
|
case 7: // Groupfire Mode
|
|
SetLampState(7, LAMP_DEFAULT);
|
|
break;
|
|
case 63:
|
|
g_ThrottleResult = -1L;
|
|
break;
|
|
case 65: // Hat_Down
|
|
case 66: // Hat_Up
|
|
case 67: // Hat_right
|
|
case 68: // Hat_left
|
|
g_HatResult = -1L; // Hat_center
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CRIOMAIN::UpdateAnalog (DIJOYSTATE &js)
|
|
{
|
|
#if 0
|
|
if (!g_StartGame) {
|
|
if (!g_bCOOP) {
|
|
// Analog Values Could be Updated & Used in Menu State(GOSScript)
|
|
return;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
g_lpPadalMode = NULL;
|
|
g_lpJoystickXMode = NULL;
|
|
|
|
switch (g_nInputMode)
|
|
{
|
|
default: // case _BIGINNER_MODE:
|
|
g_lpJoystickXMode = &js.lX;
|
|
g_lpPadalMode = NULL;
|
|
break;
|
|
|
|
case _VETERAN_MODE:
|
|
g_lpJoystickXMode = &js.lX;
|
|
g_lpPadalMode = &js.lRz;
|
|
break;
|
|
|
|
case _EXPERT_MODE:
|
|
g_lpJoystickXMode = &js.lRz;
|
|
g_lpPadalMode = &js.lX;
|
|
break;
|
|
}
|
|
|
|
//if (!g_StartGame && g_bCOOP) {
|
|
s_RIO.GetJoyButtons(js.rgbButtons);
|
|
/*} else {
|
|
js.rgbButtons[0] = 0;
|
|
js.rgbButtons[1] = 0;
|
|
js.rgbButtons[2] = 0;
|
|
js.rgbButtons[3] = 0;
|
|
}*/
|
|
|
|
UpdateHat (js);
|
|
UpdatePadal (js);
|
|
UpdateThrottle (js);
|
|
//UpdateJoystickX (js);
|
|
//UpdateJoystickY (js);
|
|
UpdateJoystick (js);
|
|
}
|
|
|
|
void CRIOMAIN::UpdateHat (DIJOYSTATE &js)
|
|
{
|
|
js.rgdwPOV[0] = g_HatResult;
|
|
}
|
|
|
|
void CRIOMAIN::UpdatePadal (DIJOYSTATE &js)
|
|
{
|
|
#define RANGE_PADAL 500L
|
|
#define DEADZONE_PADAL 10L
|
|
/*
|
|
== PADAL ==
|
|
|
|
Up : (-)
|
|
Down : (+)
|
|
|
|
------------------
|
|
Set Start Position
|
|
------------------
|
|
|
|
Down Up
|
|
======================
|
|
← (+) (-) →
|
|
======================
|
|
↗
|
|
g_LeftPedalStart: INT_MAX (+)
|
|
|
|
lP = (LONG)g_LeftPedalStart - g_LeftPedal;
|
|
lP 결과값은 무조건 음수
|
|
*/
|
|
|
|
LONG lP = 0;
|
|
|
|
//
|
|
// LEFT PADAL
|
|
//
|
|
|
|
if ((g_LeftPedal < -RANGE_PADAL) || (g_LeftPedal > RANGE_PADAL))
|
|
{
|
|
// error!
|
|
//::OutputDebugString ("!!!!! LEFT PEDAL ERROR !!!!!\n");
|
|
|
|
if (g_LeftPedal > RANGE_PADAL) {
|
|
g_LeftPedalLast = -1000L;
|
|
} else {
|
|
g_LeftPedalLast = 0L;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (g_LeftPedalStart > g_LeftPedal) {
|
|
g_LeftPedalStart = g_LeftPedal;
|
|
}
|
|
|
|
lP = (LONG)g_LeftPedalStart - g_LeftPedal;
|
|
if (lP != 0) {
|
|
lP = lP * 1000 / RANGE_PADAL;
|
|
}
|
|
|
|
// Dead Zone
|
|
if (abs(lP) < DEADZONE_PADAL) {
|
|
lP = 0;
|
|
}
|
|
|
|
g_LeftPedalLast = lP;
|
|
}
|
|
|
|
//
|
|
// RIGHT PADAL
|
|
//
|
|
|
|
lP = 0;
|
|
|
|
if ((g_RightPedal < -RANGE_PADAL) || (g_RightPedal > RANGE_PADAL))
|
|
{
|
|
// error!
|
|
//::OutputDebugString ("!!!!! RIGHT PEDAL ERROR !!!!!\n");
|
|
|
|
if (g_RightPedal > RANGE_PADAL) {
|
|
g_RightPedalLast = 1000L;
|
|
} else {
|
|
g_RightPedalLast = 0L;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (g_RightPedalStart > g_RightPedal) {
|
|
g_RightPedalStart = g_RightPedal;
|
|
}
|
|
|
|
lP = (LONG)g_RightPedalStart - g_RightPedal;
|
|
if (lP != 0) {
|
|
lP = lP * 1000 / RANGE_PADAL;
|
|
}
|
|
|
|
// Dead Zone
|
|
if (abs(lP) < DEADZONE_PADAL) {
|
|
lP = 0;
|
|
}
|
|
|
|
g_RightPedalLast = -lP;
|
|
}
|
|
|
|
// Update Analog
|
|
if (g_lpPadalMode)
|
|
{
|
|
if (abs(g_LeftPedalLast) > 0 && abs(g_RightPedalLast) > 0) { // Left + Right
|
|
*g_lpPadalMode = g_RightPedalLast + g_LeftPedalLast;
|
|
} else if (abs(g_LeftPedalLast) > 0) { // Only Left
|
|
*g_lpPadalMode = g_LeftPedalLast;
|
|
} else if (abs(g_RightPedalLast) > 0) { // Only Right
|
|
*g_lpPadalMode = g_RightPedalLast;
|
|
}
|
|
}
|
|
|
|
|
|
#if defined(_DEBUG) && 0 // watcom
|
|
static char s_szStr[256];
|
|
|
|
sprintf (s_szStr, "LEFT: RIO (%ld), START (%ld), LAST (%ld) \n",
|
|
g_LeftPedal, g_LeftPedalStart, g_LeftPedalLast);
|
|
::OutputDebugString(s_szStr);
|
|
|
|
sprintf (s_szStr, "RIGHT: RIO (%ld), START (%ld), LAST (%ld) \n",
|
|
g_RightPedal, g_RightPedalStart, g_RightPedalLast);
|
|
::OutputDebugString(s_szStr);
|
|
|
|
|
|
#endif // watcom
|
|
}
|
|
|
|
void CRIOMAIN::UpdateThrottle (DIJOYSTATE &js)
|
|
{
|
|
// [[RIO button value range]]
|
|
// RIO board spec: (up) -800 ~ +800 (down)
|
|
// actually maximum throttle-value-range is 800, not 1600(-800 ~ 800)
|
|
// possible throttle value (g_ThrottleMax ~ (g_ThrottleMax - 800))
|
|
// g_ThrottleMax will be changedfrom input value...
|
|
//
|
|
// g_Throttle/g_ThrottleMax
|
|
#define RANGE_THROTTLE 800L
|
|
|
|
// [[joy button value range - (0 ~ 1000 <- we use this, one way throttle) or (-1000 ~ +1000)]]
|
|
// g_ThrottleLast
|
|
|
|
// -rbjump // dead zone (200-10 ---- 200+15)
|
|
|
|
#define ZERO_THROTTLE 600L // see,,, control_mapping.cpp, 0.3
|
|
|
|
// CRIOMain will return MW4 as -1000 - +1000
|
|
// & MW4 will convert that value 0.0 = +1.0
|
|
// so around 0.3(from bithrottlecenter-bithrottlelow to bithrottlecenter+bithrottlehigh) will be dead-zone
|
|
// active low zone is from 0.0 to (bithrottlecenter-bithrottlelow)
|
|
// active high zone is from (bithrottlecenter+bithrottlelow) to 1.0
|
|
// so 0.3 is same 600
|
|
//#define DEAD_THROTTLE 50L // see,,, control_mapping.cpp, 0.025
|
|
|
|
|
|
#define DEADZONE_THROTTLE 50L
|
|
|
|
/*
|
|
== THROTTLE ==
|
|
|
|
Up : (-)
|
|
Down : (+)
|
|
|
|
------------------
|
|
Set Start Position
|
|
------------------
|
|
|
|
Up Down
|
|
======================
|
|
← (-) (+) →
|
|
======================
|
|
↗
|
|
g_ThrottleStart: INT_MIN (-)
|
|
*/
|
|
|
|
|
|
LONG lT;
|
|
|
|
if ((g_Throttle < -RANGE_THROTTLE) || (g_Throttle > RANGE_THROTTLE))
|
|
{
|
|
// error
|
|
if (g_Throttle < RANGE_THROTTLE) {
|
|
if (g_ThrottleResult > 0L) { // back
|
|
g_ThrottleLast = 1000L;
|
|
} else {
|
|
g_ThrottleLast = -1000L;
|
|
}
|
|
} else {
|
|
g_ThrottleLast = 600L;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Set StartPosition
|
|
if (g_ThrottleStart < g_Throttle)
|
|
g_ThrottleStart = g_Throttle;
|
|
|
|
lT = (LONG)g_ThrottleStart - g_Throttle;
|
|
|
|
if (lT > 800L)
|
|
lT = 800L;
|
|
|
|
if (lT != 0) {
|
|
lT = lT * 1000L / 800L;
|
|
|
|
if ((lT > -DEADZONE_THROTTLE) && (lT < DEADZONE_THROTTLE)) {
|
|
g_ThrottleLast = ZERO_THROTTLE;
|
|
} else {
|
|
if (g_ThrottleResult > 0L) { // back
|
|
g_ThrottleLast = 900L + (lT * g_ThrottleResult * 0.1L);
|
|
} else { // front
|
|
g_ThrottleLast = lT * g_ThrottleResult;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
js.rglSlider[0] = g_ThrottleLast;
|
|
|
|
#if defined(_DEBUG) && 0 // watcom
|
|
static char s_szStr[256];
|
|
sprintf (s_szStr, "THROTTLE: RIO (%ld), START (%ld), LAST (%ld) \n",
|
|
g_Throttle, g_ThrottleStart, g_ThrottleLast);
|
|
::OutputDebugString(s_szStr);
|
|
#endif // watcom
|
|
}
|
|
|
|
void CRIOMAIN::UpdateJoystick (DIJOYSTATE &js)
|
|
{
|
|
/*
|
|
#define DEADZONE_JOYSTICKX 20L
|
|
#define DEADZONE_JOYSTICKY 20L
|
|
|
|
LONG lJ;
|
|
|
|
lJ = -g_JoystickX;
|
|
|
|
if (lJ > 0) {
|
|
lJ -= DEADZONE_JOYSTICKX;
|
|
} else if (lJ < 0) {
|
|
lJ += DEADZONE_JOYSTICKX;
|
|
}
|
|
|
|
if ((g_JoystickX > DEADZONE_JOYSTICKX) || (g_JoystickX < -DEADZONE_JOYSTICKX)) {
|
|
g_JoystickXLast = lJ * 12.5L;
|
|
if (g_JoystickXLast < -1000L) {
|
|
g_JoystickXLast = -1000L;
|
|
} else if (g_JoystickXLast > 1000L) {
|
|
g_JoystickXLast = 1000L;
|
|
}
|
|
} else {
|
|
g_JoystickXLast = 0L;
|
|
}
|
|
*/
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
80 의 의미
|
|
|
|
RIO (LEFT :120 ~ RIGHT :-80) 까지의 수를 돌려준다고 가정하고
|
|
(LEFT의경우) RIGHT 의 최대값 80 이상인 값을 잘라버리고 나머지는
|
|
버릴경우 LEFT 와 RIGHT가 동일한 속도로 움직일수 있다
|
|
*/
|
|
//////////////////////////////////////////////////////////////////////////////////
|
|
LONG lJ;
|
|
|
|
// MSL 5.03 Joystick Deadzone
|
|
//#define DEADZONE_JOYSTICKX_LEFT 10L
|
|
//#define DEADZONE_JOYSTICKX_RIGHT 10L
|
|
#define DEADZONE_JOYSTICKX_LEFT 5L
|
|
#define DEADZONE_JOYSTICKX_RIGHT 5L
|
|
static const LONG sLeftRate = (LONG)((1000L) / (LONG)(80L - DEADZONE_JOYSTICKX_LEFT));
|
|
static const LONG sRightRate = (LONG)((1000L) / (LONG)(80L - DEADZONE_JOYSTICKX_RIGHT));
|
|
|
|
lJ = g_JoystickX;
|
|
|
|
if (lJ < 0) // LEFT
|
|
{
|
|
lJ += DEADZONE_JOYSTICKX_LEFT;
|
|
|
|
if ((lJ < 0)) {
|
|
if (lJ < (-80 + DEADZONE_JOYSTICKX_LEFT))
|
|
lJ = (-80 + DEADZONE_JOYSTICKX_LEFT);
|
|
|
|
g_JoystickXLast = lJ * sLeftRate;
|
|
|
|
} else {
|
|
g_JoystickXLast = 0L;
|
|
}
|
|
}
|
|
else if (lJ > 0) // RIGHT
|
|
{
|
|
lJ -= DEADZONE_JOYSTICKX_RIGHT;
|
|
|
|
if (lJ > 0) {
|
|
if (lJ > (80 - DEADZONE_JOYSTICKX_RIGHT))
|
|
lJ = (80 - DEADZONE_JOYSTICKX_RIGHT);
|
|
|
|
g_JoystickXLast = lJ * sRightRate;
|
|
} else {
|
|
g_JoystickXLast = 0L;
|
|
}
|
|
}
|
|
|
|
if (g_JoystickXLast < -1000L)
|
|
{
|
|
g_JoystickXLast = -1000L;
|
|
}
|
|
else if (g_JoystickXLast > 1000L)
|
|
{
|
|
g_JoystickXLast = 1000L;
|
|
}
|
|
|
|
g_JoystickXLast = -g_JoystickXLast;
|
|
if (g_lpJoystickXMode)
|
|
{
|
|
*g_lpJoystickXMode = g_JoystickXLast;
|
|
}
|
|
#if 0 // def _DEBUG
|
|
extern char DisplayInfoText[128];
|
|
extern DWORD EndDisplayInfoTime;
|
|
extern DWORD EnableDisplayInfo;
|
|
|
|
if( EnableDisplayInfo==0 ) {
|
|
disp:
|
|
sprintf(DisplayInfoText, "X(%ld) L(%ld)", g_JoystickX, g_JoystickXLast);
|
|
EnableDisplayInfo = 1;
|
|
} else if (EnableDisplayInfo==2) {
|
|
if( timeGetTime() < EndDisplayInfoTime+50 ) {
|
|
} else {
|
|
goto disp;
|
|
}
|
|
} else {
|
|
}
|
|
#endif // _DEBUG
|
|
|
|
/////////////////////////
|
|
/////////////////////////
|
|
/////////////////////////
|
|
// MSL 5.03 Joystick Deadzone
|
|
//#define DEADZONE_JOYSTICKY_UP 10L
|
|
//#define DEADZONE_JOYSTICKY_DOWN 10L
|
|
#define DEADZONE_JOYSTICKY_UP 5L
|
|
#define DEADZONE_JOYSTICKY_DOWN 5L
|
|
static const LONG sUpRate = (LONG)((1000L) / (LONG)(80L - DEADZONE_JOYSTICKY_UP));
|
|
static const LONG sDownRate = (LONG)((1000L) / (LONG)(80L - DEADZONE_JOYSTICKY_DOWN));
|
|
|
|
lJ = g_JoystickY;
|
|
|
|
if (lJ < 0) // UP
|
|
{
|
|
lJ += DEADZONE_JOYSTICKY_UP;
|
|
|
|
if ((lJ < 0)) {
|
|
if (lJ < (-80 + DEADZONE_JOYSTICKY_UP))
|
|
lJ = (-80 + DEADZONE_JOYSTICKY_UP);
|
|
|
|
g_JoystickYLast = lJ * sUpRate;
|
|
} else {
|
|
g_JoystickYLast = 0L;
|
|
}
|
|
}
|
|
else if (lJ > 0) // Down
|
|
{
|
|
lJ -= DEADZONE_JOYSTICKY_DOWN;
|
|
|
|
if (lJ > 0) {
|
|
if (lJ > (80 - DEADZONE_JOYSTICKY_DOWN))
|
|
lJ = (80 - DEADZONE_JOYSTICKY_DOWN);
|
|
|
|
g_JoystickYLast = lJ * sDownRate;
|
|
|
|
} else {
|
|
g_JoystickYLast = 0L;
|
|
}
|
|
}
|
|
|
|
if (g_JoystickYLast < -1000L)
|
|
{
|
|
g_JoystickYLast = -1000L;
|
|
}
|
|
else if (g_JoystickYLast > 1000L)
|
|
{
|
|
g_JoystickYLast = 1000L;
|
|
}
|
|
|
|
|
|
/*
|
|
if (lJ > 0) {
|
|
lJ -= DEADZONE_JOYSTICKY;
|
|
} else if (lJ < 0) {
|
|
lJ += DEADZONE_JOYSTICKY;
|
|
}
|
|
|
|
if ((g_JoystickY > DEADZONE_JOYSTICKY) || (g_JoystickY < -DEADZONE_JOYSTICKY)) {
|
|
if (lJ < 0) { // Up
|
|
g_JoystickYLast = lJ * 15.0L;
|
|
} else if (lJ > 0) { // Down
|
|
g_JoystickYLast = lJ * 12.5L;
|
|
}
|
|
|
|
if (g_JoystickYLast < -1000L) {
|
|
g_JoystickYLast = -1000L;
|
|
} else if (g_JoystickYLast > 1000L) {
|
|
g_JoystickYLast = 1000L;
|
|
}
|
|
} else {
|
|
g_JoystickYLast = 0L;
|
|
}
|
|
*/
|
|
|
|
js.lY = g_JoystickYLast;
|
|
|
|
#if defined(_DEBUG) && 0 // watcom
|
|
static char s_szStr[256];
|
|
sprintf (s_szStr, "@JOY_Y@ RIO (%ld), LAST (%ld) \n",
|
|
g_JoystickY, g_JoystickYLast);
|
|
::OutputDebugString(s_szStr);
|
|
sprintf (s_szStr, "@JOY_X@ RIO (%ld), LAST (%ld) \n",
|
|
g_JoystickX, g_JoystickXLast);
|
|
::OutputDebugString(s_szStr);
|
|
#endif // watcom
|
|
}
|
|
|
|
void CRIOMAIN::Redf_ThrottleMessageHandler (VehicleInterface& vh, BYTE btnIndex, int data)
|
|
{
|
|
if (data > 0) {
|
|
g_naButtonThrottles[btnIndex] = 1;
|
|
//
|
|
} else {
|
|
if (g_naButtonThrottles[btnIndex] <= 0) {
|
|
return;
|
|
}
|
|
g_naButtonThrottles[btnIndex] = 0;
|
|
}
|
|
BYTE button = 47 - btnIndex; // 0 - 47, 1 - 46, 2 - 45...
|
|
|
|
if (vh.GetShutdownState())
|
|
return;
|
|
// m_bFreeForAll, g_nTeamOrderMode, g_TeamOrderCount, g_TeamOrderOthers, g_fLastStartTime
|
|
|
|
SetTeamOrderButtons(true);
|
|
BYTE& bButtonValue = s_aCtrlLamp[button];
|
|
if (bButtonValue != LAMP_OFF) {
|
|
if (data > 0)
|
|
{
|
|
SetLampState (button, LAMP_BRIGHT);
|
|
}
|
|
else
|
|
{
|
|
SetLampState (button, LAMP_DEFAULT);
|
|
DoTeamOrderButton(vh, button);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CRIOMAIN::DoTeamOrderButton(VehicleInterface& vh, int button)
|
|
{
|
|
switch(g_nTeamOrderMode) {
|
|
case FREEFORALL_MODE:
|
|
g_nTeamOrderSelect = button;
|
|
g_TeamOrderCountSave = g_TeamOrderCount;
|
|
g_TeamOrderOthersSave = g_TeamOrderOthers;
|
|
DoSaveMechInfos(&g_aSavedMechInfos[0], &g_aMechInfos[0], 1 + g_TeamOrderCount + g_TeamOrderOthers);
|
|
g_nTeamOrderMode = TEAM_MESSAGE2;
|
|
break;
|
|
case TEAM_MODE:
|
|
g_nTeamOrderSelect = button;
|
|
g_TeamOrderCountSave = g_TeamOrderCount;
|
|
g_TeamOrderOthersSave = g_TeamOrderOthers;
|
|
DoSaveMechInfos(&g_aSavedMechInfos[0], &g_aMechInfos[0], 1 + g_TeamOrderCount + g_TeamOrderOthers);
|
|
if ((40 <= button) && (button <= 41)) {
|
|
if (!g_pCurTOC) {
|
|
break;
|
|
}
|
|
// Affirmative or negative
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
const ServedConnectionData& scd = app->servedConnectionData[g_pCurTOC->m_nFrom];
|
|
if (scd.clientConnected && scd.clientLoaded) {
|
|
MWPlayer* plyr = scd.clientPlayer;
|
|
if (plyr) {
|
|
Vehicle* pv = plyr->GetVehicle();
|
|
if (pv && (pv->GetClassID() == MechClassID)) {
|
|
DynamicMemoryStream stream;
|
|
int nMsgIndex = (button == 41) ? 14: 15; // yes: no
|
|
if (!app->serverFlag) {
|
|
stream.WriteBytes(&g_pCurTOC->m_nFrom, 1); // to
|
|
}
|
|
stream.WriteBytes(&g_aSavedMechInfos[0].connectionID, 1); // from...
|
|
stream.WriteBytes(&nMsgIndex, 1);
|
|
stream.WriteByteAlign();
|
|
stream.Rewind();
|
|
if (app->serverFlag) {
|
|
Network::GetInstance()->SendNetMessage(g_pCurTOC->m_nFrom, MWApplication::RepTeamOrderMessageID, &stream, true);
|
|
} else {
|
|
Network::GetInstance()->SendNetMessage(Connection::Server->GetID(), MWApplication::svrRepTeamOrderMessageID, &stream, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
app->EndTOC();
|
|
if (button == 40) {
|
|
// negative - restore last selection
|
|
if (g_LastTarget != ReplicatorID::Null) {
|
|
Connection *connection = Network::GetInstance()->GetConnection(g_LastTarget.connectionID);
|
|
if (connection != NULL) {
|
|
Check_Object(connection);
|
|
Entity * target_entity = (Entity *)connection->FindReplicator(g_LastTarget);
|
|
if (target_entity) {
|
|
vh.SetGUITarget(target_entity);
|
|
}
|
|
}
|
|
g_LastTarget = ReplicatorID::Null;
|
|
}
|
|
}
|
|
} else if ((44 <= button) && (button <= 47))
|
|
// Do Team Message
|
|
g_nTeamOrderMode = TEAM_MESSAGE1;
|
|
else {
|
|
// Do non-Team Message
|
|
g_nTeamOrderMode = TEAM_MESSAGE2;
|
|
}
|
|
break;
|
|
default: // case TEAM_MESSAGE1, TEAM_MESSAGE2:
|
|
if (40 != button) {
|
|
int nMsgIndex;
|
|
|
|
nMsgIndex = 47 - button; // 47 - 0, 46 - 1 ... 41-6
|
|
if (g_nTeamOrderMode == TEAM_MESSAGE2) {
|
|
nMsgIndex += 7;
|
|
}
|
|
int nMIStart, nMIs;
|
|
SMechInfo aMIs[16];
|
|
|
|
nMIs = g_TeamOrderCountSave;
|
|
nMIStart = 1;
|
|
if (m_bFreeForAll) {
|
|
if (g_nTeamOrderSelect != 40) {
|
|
nMIs = 1;
|
|
nMIStart = 1 + (47 - g_nTeamOrderSelect); // 47 - 1, 46 - 2...
|
|
}
|
|
} else {
|
|
// team mode
|
|
switch(g_nTeamOrderSelect) {
|
|
case 47: // team all
|
|
nMIs = g_TeamOrderCountSave;
|
|
nMIStart = 1;
|
|
break;
|
|
case 46: // team mate 1
|
|
case 45: // team mate 2
|
|
case 44: // team mate 3
|
|
nMIs = 1;
|
|
nMIStart = 47 - g_nTeamOrderSelect; // 46 - 1, 45 - 2, 44 - 3
|
|
break;
|
|
case 43: // all
|
|
nMIs = g_TeamOrderCountSave + g_TeamOrderOthersSave;
|
|
nMIStart = 1;
|
|
break;
|
|
case 42: // all others...
|
|
nMIs = g_TeamOrderOthersSave;
|
|
nMIStart = 1 + g_TeamOrderCountSave;
|
|
break;
|
|
}
|
|
}
|
|
memcpy(aMIs, &g_aSavedMechInfos[nMIStart], sizeof(g_aSavedMechInfos[0]) * nMIs);
|
|
|
|
if (m_bFreeForAll)
|
|
g_nTeamOrderMode = FREEFORALL_MODE;
|
|
else
|
|
g_nTeamOrderMode = TEAM_MODE;
|
|
|
|
Entity* target_entity = NULL;
|
|
if ((nMsgIndex == 0) || (nMsgIndex == 1)) {
|
|
// attack|defend my target
|
|
target_entity = vh.m_interfaceTarget.GetCurrent();
|
|
if (!target_entity) {
|
|
// no target...
|
|
return;
|
|
}
|
|
}
|
|
int i;
|
|
MWApplication *app = MWApplication::GetInstance();
|
|
Network* pNet = Network::GetInstance();
|
|
|
|
bool b1stBOT = true;
|
|
for(i = 0; i < nMIs; i++) {
|
|
if (target_entity) {
|
|
if (target_entity->GetReplicatorID() == aMIs[i])
|
|
continue;
|
|
}
|
|
DynamicMemoryStream stream;
|
|
|
|
if (aMIs[i].m_bBOT) { // always to server directly...
|
|
if (b1stBOT && ((nMsgIndex == 0) || (nMsgIndex == 1) || (nMsgIndex == 2) || (nMsgIndex == 6))) {
|
|
b1stBOT = false;
|
|
|
|
int nBot, nBOTs = 0;
|
|
|
|
for(nBot = i; nBot < nMIs; nBot++) {
|
|
if (aMIs[nBot].m_bBOT) {
|
|
if (target_entity) {
|
|
if (target_entity->GetReplicatorID() == aMIs[nBot])
|
|
continue;
|
|
}
|
|
nBOTs++;
|
|
}
|
|
}
|
|
if (nBOTs <= 0)
|
|
continue;
|
|
stream.WriteBytes(&nBOTs, 1);
|
|
// no meanning... stream.WriteBytes(&g_aSavedMechInfos[0].connectionID, 1); // from...
|
|
stream.WriteBytes(&nMsgIndex, 1);
|
|
for(nBot = i; nBot < nMIs; nBot++) {
|
|
if (aMIs[nBot].m_bBOT) {
|
|
if (target_entity) {
|
|
if (target_entity->GetReplicatorID() == aMIs[nBot])
|
|
continue;
|
|
}
|
|
stream.WriteBytes(&aMIs[nBot].localID, 2);
|
|
}
|
|
}
|
|
} else {
|
|
b1stBOT = false;
|
|
continue;
|
|
}
|
|
} else {
|
|
if (!app->serverFlag) { // to server directly...
|
|
// redirected part
|
|
int nBOTs = 0;
|
|
stream.WriteBytes(&nBOTs, 1);
|
|
stream.WriteBytes(&aMIs[i].connectionID, 1); // to
|
|
}
|
|
// real part
|
|
stream.WriteBytes(&g_aSavedMechInfos[0].connectionID, 1); // from...
|
|
stream.WriteBytes(&nMsgIndex, 1);
|
|
}
|
|
if ((nMsgIndex == 0) || (nMsgIndex == 1)) {
|
|
// attack|defend my target
|
|
ReplicatorID id = target_entity->GetReplicatorID();
|
|
stream.WriteBytes(&id.connectionID, 1);
|
|
stream.WriteBytes(&id.localID, 2);
|
|
}
|
|
stream.WriteByteAlign();
|
|
stream.Rewind();
|
|
//pNet->netStatCollector[Network::OutgoingSystemMessageBitSizeStat].AddToStatistic(aMIs[i].connectionID,stream.GetBufferBytesUsed()*8);
|
|
if (app->serverFlag && !aMIs[i].m_bBOT) {
|
|
pNet->SendNetMessage(aMIs[i].connectionID, MWApplication::TeamOrderMessageID, &stream, true);
|
|
} else {
|
|
pNet->SendNetMessage(Connection::Server->GetID(), MWApplication::svrTeamOrderMessageID, &stream, true);
|
|
//if (app->serverFlag && aMIs[i].m_bBOT) {
|
|
//}
|
|
}
|
|
}
|
|
} else {
|
|
// exit - do nothing
|
|
if (m_bFreeForAll)
|
|
g_nTeamOrderMode = FREEFORALL_MODE;
|
|
else
|
|
g_nTeamOrderMode = TEAM_MODE;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CRIOMAIN::SetTeamOrderButtons(bool bForce/* = false*/)
|
|
{
|
|
if (!hsh_initialized || bForce) {
|
|
if (g_nTeamOrderMode == TEAM_MODE) {
|
|
g_TeamOrderCount=MWApplication::GetInstance()->GetMechInfos(0, g_aMechInfos, g_TeamOrderOthers) - 1;
|
|
} else if(g_nTeamOrderMode == FREEFORALL_MODE) {
|
|
g_TeamOrderCount=MWApplication::GetInstance()->GetMechInfos(2, g_aMechInfos, g_TeamOrderOthers) - 1;
|
|
}
|
|
}
|
|
if (VehGetShutdownState()) {
|
|
BYTE kkkkk;
|
|
for(kkkkk = 40; kkkkk < 48; kkkkk++) {
|
|
SetLampState (kkkkk, LAMP_OFF);
|
|
}
|
|
return;
|
|
}
|
|
int i;
|
|
int TeamOrderCount = g_TeamOrderCount;
|
|
|
|
switch(g_nTeamOrderMode) {
|
|
case FREEFORALL_MODE:
|
|
if (TeamOrderCount > 7)
|
|
TeamOrderCount = 7;
|
|
// all
|
|
if (TeamOrderCount) {
|
|
if (IsLampOFF(40)) {
|
|
SetLampState (40, LAMP_DEFAULT);
|
|
}
|
|
} else {
|
|
if (!IsLampOFF(40)) {
|
|
SetLampState(40, LAMP_OFF);
|
|
}
|
|
}
|
|
// each player
|
|
for(i = 41; i <= 47; i++) {
|
|
if (i <= 47 - TeamOrderCount)
|
|
{
|
|
if (!IsLampOFF(i)) {
|
|
SetLampState (i, LAMP_OFF);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (IsLampOFF(i)) {
|
|
SetLampState (i, LAMP_DEFAULT);
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
case TEAM_MODE:
|
|
if (TeamOrderCount > 3)
|
|
TeamOrderCount = 3;
|
|
// team all
|
|
if (TeamOrderCount) {
|
|
if (IsLampOFF(47)) {
|
|
SetLampState (47, LAMP_DEFAULT);
|
|
}
|
|
} else {
|
|
if (!IsLampOFF(47)) {
|
|
SetLampState(47, LAMP_OFF);
|
|
}
|
|
}
|
|
// each team player
|
|
for(i = 44; i <= 46; i++) {
|
|
if (i <= 46 - TeamOrderCount)
|
|
{
|
|
if (!IsLampOFF(i)) {
|
|
SetLampState (i, LAMP_OFF);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (IsLampOFF(i)) {
|
|
SetLampState (i, LAMP_DEFAULT);
|
|
}
|
|
}
|
|
}
|
|
// all
|
|
if (TeamOrderCount || g_TeamOrderOthers) {
|
|
if (IsLampOFF(43)) {
|
|
SetLampState (43, LAMP_DEFAULT);
|
|
}
|
|
} else {
|
|
if (!IsLampOFF(43)) {
|
|
SetLampState(43, LAMP_OFF);
|
|
}
|
|
}
|
|
// all others...
|
|
if (g_TeamOrderOthers) {
|
|
if (IsLampOFF(42)) {
|
|
SetLampState (42, LAMP_DEFAULT);
|
|
}
|
|
} else {
|
|
if (!IsLampOFF(42)) {
|
|
SetLampState(42, LAMP_OFF);
|
|
}
|
|
}
|
|
// Affirmative or negative
|
|
if (g_pCurTOC)
|
|
{
|
|
Scalar fT = gos_GetElapsedTime();
|
|
if ((fT - g_fLastStartTime) > AUTO_DENY_TIME) {
|
|
g_fLastStartTime = 0.0f;
|
|
MWApplication::GetInstance()->EndTOC(true);
|
|
|
|
// negative - restore last selection
|
|
if (g_LastTarget != ReplicatorID::Null) {
|
|
Connection *connection = Network::GetInstance()->GetConnection(g_LastTarget.connectionID);
|
|
if (connection != NULL) {
|
|
Check_Object(connection);
|
|
Entity * target_entity = (Entity *)connection->FindReplicator(g_LastTarget);
|
|
if (target_entity) {
|
|
VehicleInterface::GetInstance()->SetGUITarget(target_entity);
|
|
}
|
|
}
|
|
g_LastTarget = ReplicatorID::Null;
|
|
}
|
|
goto auto_deny;
|
|
}
|
|
if (IsLampOFF (40))
|
|
SetLampState (40, LAMP_DEFAULT);
|
|
if (IsLampOFF (41))
|
|
SetLampState (41, LAMP_DEFAULT);
|
|
} else {
|
|
auto_deny:
|
|
if (!IsLampOFF (40))
|
|
SetLampState (40, LAMP_OFF);
|
|
if (!IsLampOFF (41))
|
|
SetLampState (41, LAMP_OFF);
|
|
}
|
|
break;
|
|
default: // case TEAM_MESSAGE1, TEAM_MESSAGE2:
|
|
for(i = 40; i <= 47; i++) {
|
|
if (IsLampOFF (i)) {
|
|
SetLampState ((BYTE)i, LAMP_DEFAULT);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
void CPlasma::SendPacket (const BYTE* pbPacket, char nLen)
|
|
{
|
|
if (IsValid())
|
|
txComLoop (pbPacket, nLen);
|
|
}
|
|
|
|
void CPlasma::PlasmaClear ()
|
|
{
|
|
char string[] = { ESC, '@'};
|
|
SendPacket ((BYTE*)string, 2);
|
|
}
|
|
|
|
void CPlasma::PlasmaCursor (char n)
|
|
{
|
|
char string[] = { ESC, 'G', char (n) };
|
|
SendPacket ((BYTE*)string, 3);
|
|
}
|
|
|
|
void CPlasma::PlasmaCursorHome ()
|
|
{
|
|
char string[] = { ESC, 'L'};
|
|
SendPacket ((BYTE*)string, 2);
|
|
}
|
|
|
|
void CPlasma::PlasmaCursorX (char n)
|
|
{
|
|
char string[] = { ESC, 'R', n};
|
|
SendPacket ((BYTE*)string, 3);
|
|
}
|
|
|
|
void CPlasma::PlasmaCursorY (char n)
|
|
{
|
|
char string[] = { ESC, 'Q', n};
|
|
SendPacket ((BYTE*)string, 3);
|
|
}
|
|
|
|
void CPlasma::PlasmaFontAttr (char n)
|
|
{
|
|
char string[] = { ESC, 'H', (BYTE)n };
|
|
SendPacket ((BYTE*)string, 3);
|
|
}
|
|
|
|
void CPlasma::PlasmaFont (char n)
|
|
{
|
|
char string[] = { 27 /*ESC*/, 'K', n};
|
|
SendPacket ((BYTE*)string, 3);
|
|
}
|
|
|
|
void CPlasma::PlasmaText (const char *szText)
|
|
{
|
|
if (!szText)
|
|
return;
|
|
|
|
int len = strlen (szText);
|
|
|
|
if (len >= 256)
|
|
return;
|
|
|
|
SendPacket ((BYTE*)szText, (char)len);
|
|
}
|
|
|
|
POINT CPlasma::GetFontSize (int Font)
|
|
{
|
|
POINT size = {0, 0};
|
|
|
|
switch (Font)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
size.x = 5;
|
|
size.y = 7;
|
|
break;
|
|
case 4:
|
|
case 5:
|
|
size.x = 10;
|
|
size.y = 14;
|
|
break;
|
|
case 6:
|
|
case 7:
|
|
size.x = 5;
|
|
size.y = 7;
|
|
break;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
void CPlasma::PlasmaBoxDraw (RECT tag)
|
|
{
|
|
char string[] = { ESC, 'X', (char)tag.left, (char)tag.top, (char)tag.right, (char)tag.bottom};
|
|
SendPacket ((BYTE*)string, 6);
|
|
}
|
|
|
|
void CPlasma::PlasmaBoxFill (RECT tag)
|
|
{
|
|
char string[] = { ESC, 'x', 0, (char)tag.left, (char)tag.top, (char)tag.right, (char)tag.bottom};
|
|
SendPacket ((BYTE*)string, 7);
|
|
}
|
|
|
|
void CPlasma::PlasmaPosText (const char *szText, char x, char y, char Attr, char Font)
|
|
{
|
|
if (!szText)
|
|
return;
|
|
|
|
int len = strlen (szText);
|
|
|
|
if (len <= 0)
|
|
return;
|
|
if (Font != 2) // !Score
|
|
{
|
|
if (len <= 9) {
|
|
Font = 5;
|
|
} else if (len <= 20) {
|
|
Font = 2;
|
|
} else {
|
|
Font = 2;
|
|
len = 20;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (len > 20)
|
|
len = 20;
|
|
}
|
|
|
|
if (x == 0 && y == 0) {
|
|
x = 56 - ((len * GetFontSize (Font).x) / 2);
|
|
y = 15 - ((GetFontSize (Font).y) / 2);
|
|
}
|
|
|
|
PlasmaCursorX (x);
|
|
PlasmaCursorY (y);
|
|
PlasmaFontAttr (Attr);
|
|
PlasmaFont (Font);
|
|
|
|
if (len >= 256)
|
|
return;
|
|
|
|
SendPacket ((const BYTE*)szText, len);
|
|
}
|
|
|
|
void CPlasma::PlasmaScoreDraw (const char *Rank, const char *Score, BOOL bFlag)
|
|
{
|
|
int CurRank = atoi (Rank);
|
|
int CurScore = atoi (Score);
|
|
|
|
RECT tag1 = {27,19,42,30};
|
|
RECT tag2 = {42,19,93,30};
|
|
|
|
RECT tag3 = {27,19,93,30}; //Fill
|
|
|
|
if (bFlag == TRUE)
|
|
{
|
|
PlasmaBoxFill (tag3);
|
|
|
|
PlasmaBoxDraw (tag1);
|
|
PlasmaBoxDraw (tag2);
|
|
}
|
|
|
|
int len_Rank = strlen (Rank);
|
|
int len_Score = strlen (Score);
|
|
|
|
//{
|
|
if (len_Rank <= 2 && len_Rank > 0)
|
|
if (len_Score <= 8 && len_Score > 0)
|
|
{
|
|
if (CurRank != m_nOldRank)
|
|
{
|
|
PlasmaPosText (" ", 29, 20, 0, 2);
|
|
if (len_Rank == 1)
|
|
PlasmaPosText (Rank, 33, 20, 0, 2);
|
|
else
|
|
PlasmaPosText (Rank, 29, 20, 0, 2);
|
|
}
|
|
|
|
if (m_nOldScore != CurScore)
|
|
{
|
|
PlasmaPosText (" ", 44, 20, 0, 2);
|
|
PlasmaPosText (Score, (char)(85 - (len_Score * 5)), 20, 0, 2);
|
|
}
|
|
}
|
|
|
|
m_nOldRank = CurRank;
|
|
m_nOldScore = CurScore;
|
|
//}
|
|
}
|
|
|
|
void CPlasma::DoPlasma(char nMode)
|
|
{
|
|
if (g_bNoPlasma)
|
|
return;
|
|
|
|
switch(nMode)
|
|
{
|
|
case 0:
|
|
m_nGlobalState = -1;
|
|
break;
|
|
case 1:
|
|
if ((m_nGlobalState != 0) && (m_nGlobalState != 2))
|
|
return;
|
|
break;
|
|
case 2:
|
|
if ((m_nGlobalState != 1) && (m_nGlobalState != 2))
|
|
return;
|
|
break;
|
|
case 9:
|
|
if ((m_nGlobalState != 1) && (m_nGlobalState != 2))
|
|
return;
|
|
if (gos_GetElapsedTime() - m_timeLastPlasma2 < g_PlasmaClearTime)
|
|
return;
|
|
if (MWApplication::GetInstance()->GetApplicationState() != ApplicationStateEngine::WaitingForGameState)
|
|
return;
|
|
PlasmaDisplay(0, NULL, NULL, NULL);
|
|
m_nGlobalState = -1;
|
|
return;
|
|
default:
|
|
return;
|
|
}
|
|
|
|
MWApplication* app = MWApplication::GetInstance();
|
|
if (Connection::Local) {
|
|
int nID = Connection::Local->GetID();
|
|
const ServedConnectionData& scd = app->servedConnectionData[nID];
|
|
if (scd.clientConnected) {
|
|
if (nMode == 0) {
|
|
PlasmaDisplay(0, NULL, NULL, NULL);
|
|
m_nGlobalState = 0;
|
|
} else if (nMode == 1) {
|
|
PlasmaDisplay(1, scd.pilotName, NULL, NULL);
|
|
m_nGlobalState = 1;
|
|
m_timeLastPlasma2 = gos_GetElapsedTime();
|
|
} else {
|
|
Time timeLastPlasma2 = gos_GetElapsedTime();
|
|
Time timeElapsed = timeLastPlasma2 -m_timeLastPlasma2;
|
|
|
|
if (timeElapsed > 1.0f) {
|
|
if (scd.clientLoaded) {
|
|
MWPlayer* plyr = scd.clientPlayer;
|
|
if (plyr) {
|
|
Vehicle* pv = plyr->GetVehicle();
|
|
if (pv && (pv->GetClassID() == MechClassID)) {
|
|
const ReplicatorID& RepID = pv->GetReplicatorID();
|
|
MWGUIManager *manager = MWGUIManager::GetInstance ();
|
|
if (manager)
|
|
{
|
|
if (manager->Component(MWGUIManager::HUD_SCORE))
|
|
{
|
|
HUDScore* hud = Cast_Object (HUDScore *,manager->Component(MWGUIManager::HUD_SCORE));
|
|
if (hud) {
|
|
CHudScoreInfo aScores[16];
|
|
int i, nScore, nCount = hud->GetScoreArray(aScores, *(const ReplicatorID*)NULL, 1);
|
|
for(i = 0; i < nCount; i++) {
|
|
const CHudScoreInfo& HSI = aScores[i];
|
|
if (RepID == HSI) {
|
|
nScore = HSI.m_nScore;
|
|
while(i > 0) {
|
|
if (aScores[i - 1].m_nScore != nScore)
|
|
break;
|
|
i--;
|
|
}
|
|
char szRank[10], szScore[20];
|
|
sprintf(szRank, "%d", i + 1);
|
|
sprintf(szScore, "%d", nScore);
|
|
PlasmaDisplay(2, NULL, szRank, szScore);
|
|
m_nGlobalState = nMode;
|
|
m_timeLastPlasma2 = timeLastPlasma2;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CPlasma::PlasmaDisplay (int Gamestate, const char *szName/*9*/, const char *Rank/*2*/, const char *Score/*8*/)
|
|
{
|
|
static BOOL BoxFlag = FALSE;
|
|
static BOOL NameFlag = FALSE;
|
|
|
|
if (Gamestate == 0) // end
|
|
{
|
|
NameFlag = TRUE;
|
|
PlasmaClear ();
|
|
}
|
|
else if (Gamestate == 1) // ready
|
|
{
|
|
if (NameFlag) {
|
|
PlasmaPosText (" ");
|
|
PlasmaPosText (szName);
|
|
}
|
|
|
|
NameFlag = FALSE;
|
|
BoxFlag = TRUE;
|
|
m_nOldRank = INT_MIN;
|
|
m_nOldScore = INT_MIN;
|
|
}
|
|
else if (Gamestate == 2) // start
|
|
{
|
|
PlasmaScoreDraw (Rank, Score, BoxFlag);
|
|
BoxFlag = FALSE;
|
|
}
|
|
}
|