/* ** Command & Conquer Red Alert(tm) ** Copyright 2025 Electronic Arts Inc. ** ** This program is free software: you can redistribute it and/or modify ** it under the terms of the GNU General Public License as published by ** the Free Software Foundation, either version 3 of the License, or ** (at your option) any later version. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program. If not, see . */ extern "C" { #include "lpc.h" #include "types.h" #include "services.h" #include "rtq.h" #include #include }; #include "mplib.h" #define IDLE_QUEUE 6 #define REC_QUEUE 7 #define SEND_QUEUE 8 void SetLPCData(LPCData *lpc) { lpc->version = 1; lpc->sizeOfArgs = 0; lpc->service = LPC_NOSERVICE; } void GetGameDef(void *gameDef, int* len) { RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); LPCData *p; LPCReturn *r; if (!n) { *len = 0; return; // can't get service! } p = (LPCData *) n->rtqDatum; SetLPCData(p); p->service = LPC_GENGETGAMEDEF; MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); // make call PostWindowsMessage(); // wait for return while ((n = MGenGetNode(REC_QUEUE)) == 0) Yield(); r = (LPCReturn *) n->rtqDatum; if (r->sizeOfReturn > *len || r->error != LPC_NOERROR) { *len = 0; return; } *len = r->sizeOfReturn; memcpy(gameDef, r->Data, r->sizeOfReturn); // get ready for next call MGenMoveTo(REC_QUEUE, IDLE_QUEUE); } int LPCGetMPAddr(void) { RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); LPCData *p; LPCReturn *r; int retVal; p = (LPCData *) n->rtqDatum; SetLPCData(p); p->service = LPC_GETMPADDR; MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); PostWindowsMessage(); while ((n = MGenGetNode(REC_QUEUE)) == 0) Yield(); r = (LPCReturn *) n->rtqDatum; if (r->sizeOfReturn != sizeof(int) || r->error != LPC_NOERROR) { return -1; } retVal = *((int *) r->Data); MGenMoveTo(REC_QUEUE, IDLE_QUEUE); return retVal; } void NullLPC(void) { RTQ_NODE *n = MGenGetNode(IDLE_QUEUE); LPCData *p; p = (LPCData *) n->rtqDatum; SetLPCData(p); p->service = LPC_NULLSERVICE; MGenMoveTo(IDLE_QUEUE, SEND_QUEUE); PostWindowsMessage(); while ((n = MGenGetNode(REC_QUEUE)) == 0) Yield(); MGenMoveTo(REC_QUEUE, IDLE_QUEUE); }