1 /*
2  * Seven Kingdoms: Ancient Adversaries
3  *
4  * Copyright 1997,1998 Enlight Software Ltd.
5  *
6  * This program is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  *
19  */
20 
21 //Filename    : OREMOTE2.CPP
22 //Description : Object Remote - part 2
23 
24 #define DEBUG_LOG_LOCAL 1
25 #include <ALL.h>
26 #include <OVGA.h>
27 #include <OSTR.h>
28 #include <OFONT.h>
29 #include <OSYS.h>
30 #include <OWORLD.h>
31 #include <OPOWER.h>
32 #include <ONATION.h>
33 #include <OREMOTE.h>
34 #include <OERRCTRL.h>
35 #include <OLOG.h>
36 
37 //---------- Define static functions ----------//
38 
39 // static int validate_queue(char* queueBuf, int queuedSize);
40 
41 //-------- Begin of function Remote::new_msg ---------//
42 //
43 // Allocate a RemoteMsg with the specified data size.
44 //
45 // <short> msgId       - id. of the message.
46 // <int>   dataSize    - the data size of the RemoteMsg needed (size of RemoteMsg::data_buf)
47 //
48 // Data structure:
49 //
50 // <short> size of RemoteMsg + <RemoteMsg> RemoteMsg body
51 // ^                           ^
52 // | Allocate starts here      | return variable here to the client function
53 //
new_msg(uint32_t msgId,int dataSize)54 RemoteMsg* Remote::new_msg(uint32_t msgId, int dataSize)
55 {
56 
57    int msgSize = sizeof(uint32_t) + dataSize;
58 	// <uint32_t> is for the message id.
59 
60    char* shortPtr;
61 
62    //--- use common_msg_buf, if the requested one is not bigger than common_msg_buf ---//
63 	int reqSize = sizeof(short) + msgSize;
64 	// <short> for length
65 
66    if(reqSize <= COMMON_MSG_BUF_SIZE )
67 	{
68       shortPtr = common_msg_buf;
69    }
70    else //---- allocate a new RemoteMsg if the requested one is bigger than common_msg_buf ----//
71    {
72       shortPtr = (char *)mem_add( reqSize );
73    }
74 
75    //---------- return RemoteMsg now -----------//
76 
77    *(short *)shortPtr = msgSize;
78 	shortPtr += sizeof(short);
79 
80 	RemoteMsg* remoteMsgPtr = (RemoteMsg*) shortPtr;
81 
82 	remoteMsgPtr->id = msgId;
83 
84 	return remoteMsgPtr;
85 }
86 //--------- End of function Remote::new_msg ---------//
87 
88 
89 //-------- Begin of function Remote::free_msg ---------//
90 //
91 // Free a RemoteMsg previously allocated by remote_msg().
92 //
93 // Data structure:
94 //
95 // <short> size of RemoteMsg + <RemoteMsg> RemoteMsg body
96 // ^                           ^
97 // | Allocate starts here      | return variable here to the client function
98 //
free_msg(RemoteMsg * remoteMsgPtr)99 void Remote::free_msg(RemoteMsg* remoteMsgPtr)
100 {
101    char* memPtr = (char *)remoteMsgPtr - sizeof(short);
102 	// include size of message, sizeof MPMSG_FREE_MSG
103 
104    if( memPtr != common_msg_buf )      // the real allocation block start 2 bytes before remoteMsgPtr
105       mem_del( memPtr );
106 }
107 //--------- End of function Remote::free_msg ---------//
108 
109 
110 //-------- Begin of function Remote::send_msg ---------//
111 //
112 // <RemoteMsg*> remoteMsgPtr - the pointer to RemoteMsg to be sent.
113 // [DPID]       receiverId   - send to whom, 0 for everybody
114 //                             (default : 0)
115 //
116 // <short> size of RemoteMsg + <RemoteMsg> RemoteMsg body
117 // ^                           ^
118 // | Allocate starts here      | return variable here to the client function
119 //
send_msg(RemoteMsg * remoteMsgPtr,uint32_t receiverId)120 void Remote::send_msg(RemoteMsg* remoteMsgPtr, uint32_t receiverId)
121 {
122 	if( handle_vga_lock )
123 		vga_front.temp_unlock();
124 
125 	// structure : <short>, <RemoteMsg>
126    char* memPtr = (char*)remoteMsgPtr - sizeof(short);   // the preceeding <short> is the size of RemoteMsg
127    int msgSize = *(short *)memPtr + sizeof(short);
128 
129 	// mp_ptr->send( receiverId, memPtr, msgSize );
130 	ec_remote.send( ec_remote.get_ec_player_id(receiverId), memPtr, msgSize);
131 
132    packet_send_count++;
133 
134    if( handle_vga_lock )
135       vga_front.temp_restore_lock();
136 }
137 //--------- End of function Remote::send_msg ---------//
138 
139 
140 //-------- Begin of function Remote::send_free_msg ---------//
141 //
142 // <RemoteMsg*> remoteMsgPtr - the pointer to RemoteMsg to be sent.
143 // [DPID]       receiverId   - send to whom, 0 for everybody
144 //                             (default : 0)
145 //
146 // <short> size of RemoteMsg + <RemoteMsg> RemoteMsg body
147 // ^                           ^
148 // | Allocate starts here      | return variable here to the client function
149 //
send_free_msg(RemoteMsg * remoteMsgPtr,uint32_t receiverId)150 void Remote::send_free_msg(RemoteMsg* remoteMsgPtr, uint32_t receiverId)
151 {
152    if( handle_vga_lock )
153 		vga_front.temp_unlock();
154 
155    char* memPtr = (char*)remoteMsgPtr - sizeof(short);   // the preceeding <short> is the size of RemoteMsg
156    int msgSize = *(short *)memPtr + sizeof(short);
157 
158 	// mp_ptr->send( receiverId, memPtr, msgSize );
159 	ec_remote.send( ec_remote.get_ec_player_id(receiverId), memPtr, msgSize);
160 
161    packet_send_count++;
162 
163    if( memPtr != common_msg_buf )      // the real allocation block start 2 bytes before remoteMsgPtr
164       mem_del( memPtr );
165 
166    if( handle_vga_lock )
167       vga_front.temp_restore_lock();
168 }
169 //--------- End of function Remote::send_free_msg ---------//
170 
171 
172 
173 //-------- Begin of function Remote::new_send_queue_msg ---------//
174 //
175 // Add the message into the sending queue.
176 //
177 // <short> msgId    - id. of the message.
178 // <int>   dataSize - the data size of the RemoteMsg needed (size of RemoteMsg::data_buf)
179 //
180 // Queue data structure:
181 //
182 // <1st msg size> + <1st msg body> + <2nd msg size> + ...
183 //
184 // return : <char*> the pointer RemoteMsg::data_buf of the allocated message
185 //
new_send_queue_msg(uint32_t msgId,int dataSize)186 char* Remote::new_send_queue_msg(uint32_t msgId, int dataSize)
187 {
188 	char *dataPtr = send_queue[0].reserve(sizeof(short) + sizeof(uint32_t) + dataSize);
189 
190 	// ----- put the size of message ------//
191 	*(short *)dataPtr = sizeof(uint32_t) + dataSize;
192 	dataPtr += sizeof(short);
193 
194 	// ----- put the message id --------//
195 	((RemoteMsg *)dataPtr)->id  = msgId;
196 
197 	return ((RemoteMsg *)dataPtr)->data_buf;
198 }
199 //--------- End of function Remote::new_send_queue_msg ---------//
200 
201 
202 //-------- Begin of function Remote::send_queue_now ---------//
203 //
204 // Send out all send_queued message.
205 //
206 // [DPID] receiverId - send to whom, 0 for everybody
207 //                     (default: 0)
208 //
209 // return : <int> 1 - sent successfully, the message has been received
210 //                    by the receivers.
211 //                0 - not successful.
212 //
send_queue_now(uint32_t receiverId)213 int Remote::send_queue_now(uint32_t receiverId)
214 {
215    if( send_queue[0].length() ==0 )
216       return 1;
217 
218 	if( !send_queue[0].validate_queue() )
219 		err.run( "Queue Corrupted, Remote::send_queue_now()" );
220 
221 	if( handle_vga_lock )
222 		vga_front.temp_unlock();
223 
224 	//----------------------------------------------//
225 	int sendFlag = 1;
226 	//if(!mp_ptr->send( receiverId, send_queue[0].queue_buf, send_queue[0].length()))
227 	if(ec_remote.send( ec_remote.get_ec_player_id(receiverId), send_queue[0].queue_buf, send_queue[0].length()) <= 0 )
228 		sendFlag = 0;
229 	packet_send_count++;
230 
231 	//---------------------------------------------//
232 
233 	if( handle_vga_lock )
234 		vga_front.temp_restore_lock();
235 
236 	return sendFlag;
237 }
238 //--------- End of function Remote::send_queue_now ---------//
239 
240 
241 //-------- Begin of function Remote::append_send_to_receive ---------//
242 //
243 // Append all send queues to the receiving queue.
244 //
append_send_to_receive()245 void Remote::append_send_to_receive()
246 {
247    if( send_queue[0].length() ==0 )
248 		return;
249 
250 	int n;
251 	for( n = 0; n < RECEIVE_QUEUE_BACKUP; ++n)
252 	{
253 		if( send_frame_count[0] == receive_frame_count[n])
254 		{
255 			receive_queue[n].append_queue(send_queue[0]);
256 			if( !receive_queue[n].validate_queue() )
257 				err.run( "Queue Corrupted, Remote::append_send_to_receive()-3" );
258 			break;
259 		}
260 	}
261 	err_when( n >= RECEIVE_QUEUE_BACKUP );			// not found
262 
263 }
264 //--------- End of function Remote::append_send_to_receive ---------//
265 
266 
267 
268 //-------- Begin of function Remote::poll_msg ---------//
269 
poll_msg()270 int Remote::poll_msg()
271 {
272    if ( !is_enable() || poll_msg_flag <= 0)
273       return 0;
274 
275 	//--------------------------------------------//
276 
277    int        receivedFlag=0;
278    uint32_t   msgListSize;
279    int        loopCount=0;
280 
281    if( handle_vga_lock )
282       vga_front.temp_unlock();
283 
284 	ec_remote.yield();
285 
286 	char *recvBuf;
287 	// DPID from;
288 	char from;
289 	uint32_t recvLen;
290 
291 	// while( (recvBuf = mp_ptr->receive(&from, &recvLen)) != NULL)
292 	while( (recvBuf = ec_remote.receive(&from, &recvLen)) != NULL )
293 	{
294 		err_when(++loopCount > 1000 );
295 		msgListSize = recvLen;
296 
297 		//-------- received successfully ----------//
298 /*
299 		if( !power.enable_flag )		// power.enable_flag determines whether the multiplayer game has started or not
300 		{
301 			int validateLen = receive_queue[0].length();
302 			memcpy( receive_queue[0].reserve(msgListSize), recvBuf, msgListSize );
303 			if( !receive_queue[0].validate_queue(validateLen) )
304 				err.run( "Queue Corrupted, Remote::poll_msg()-99" );
305 
306 			receivedFlag=1;
307 		}
308 		else
309 */
310 		err_when( msgListSize < sizeof(short) + sizeof(uint32_t) );
311 		RemoteMsg *rMsg = (RemoteMsg *)(recvBuf + sizeof(short) );
312 		int	queueToCopy = -1;
313 
314 		//--- if message id !=MSG_QUEUE_HEADER, this packet is sent by send_free_msg(), not by send_queue_now() ---//
315 
316 		if( rMsg->id != MSG_QUEUE_HEADER )
317 		{
318 			// DEBUG_LOG("begin MSG_xxxx received");
319 			// DEBUG_LOG(rMsg->id);
320 			// DEBUG_LOG(sys.frame_count);
321 			// DEBUG_LOG("end MSG_xxxx received");
322 			queueToCopy = 0;
323 		}
324 		else
325 		{
326 
327 			// ------- find which receive queue to hold the message -----//
328 
329 			uint32_t senderFrameCount = *(uint32_t *)rMsg->data_buf;
330 			for(int n = 0; n < RECEIVE_QUEUE_BACKUP; ++n )
331 			{
332 				if( senderFrameCount == receive_frame_count[n] )
333 				{
334 					queueToCopy = n;
335 					break;
336 				}
337 			}
338 			// DEBUG_LOG("begin MSG_QUEUE_HEADER received");
339 			// DEBUG_LOG(senderFrameCount);
340 			// DEBUG_LOG(sys.frame_count);
341 			// DEBUG_LOG(n);
342 			// DEBUG_LOG("end MSG_QUEUE_HEADER received");
343 		}
344 
345 		if( queueToCopy >= 0 && queueToCopy < RECEIVE_QUEUE_BACKUP )
346 		{
347 			RemoteQueue &rq = receive_queue[queueToCopy];
348 			int validateLen = rq.length();
349 			memcpy( rq.reserve(msgListSize), recvBuf, msgListSize );
350 			if( !rq.validate_queue(validateLen) )
351 				err.run( "Queue Corrupted, Remote::poll_msg()-2" );
352 		}
353 		else
354 		{
355 			// discard the frame in non-debug mode
356 			DEBUG_LOG("message is discard" );
357 			if( rMsg->id != MSG_QUEUE_HEADER )
358 			{
359 				DEBUG_LOG(rMsg->id);
360 			}
361 			else
362 			{
363 				uint32_t senderFrameCount = *(uint32_t *)rMsg->data_buf;
364 				DEBUG_LOG("MSG_QUEUE_HEADER message");
365 				DEBUG_LOG(senderFrameCount);
366 			}
367 
368 		}
369 
370 		ec_remote.de_recv_queue();
371 
372 		receivedFlag = 1;
373 
374 		packet_receive_count++;
375 	}
376 
377 	if( handle_vga_lock )
378 		vga_front.temp_restore_lock();
379 
380 	return receivedFlag;
381 }
382 
383 //--------- End of function Remote::poll_msg ---------//
384 
385 
386 //-------- Begin of function Remote::process_receive_queue ---------//
387 //
388 // Process messages in the receive queue.
389 //
process_receive_queue()390 void Remote::process_receive_queue()
391 {
392 	if( !process_queue_flag )			// avoid sys.yield()
393 		return;
394 
395 	int processFlag;
396 	int loopCount=0;
397 
398 	disable_poll_msg();
399 
400 	RemoteQueue &rq = receive_queue[0];
401 	RemoteQueueTraverse rqt(rq);
402 
403 	if( connectivity_mode == MODE_REPLAY )
404 	{
405 		replay.read_queue(&rq);
406 		if( replay.at_eof() )
407 		{
408 			connectivity_mode = MODE_REPLAY_END;
409 			sys.signal_exit_flag = 2;
410 		}
411 	}
412 	else
413 		replay.write_queue(&rq);
414 
415 	if( !rq.validate_queue() )
416 		err.run( "Queue corrupted, Remote::process_receive_queue()" );
417 
418 	//---- if not started yet, process the message without handling the message sequence ----//
419 
420 	if( !power.enable_flag )
421 	{
422 		for( rqt.traverse_set_start(); !rqt.traverse_finish(); rqt.traverse_next() )
423 		{
424 			err_when( ++loopCount > 1000 );
425 			RemoteMsg* remoteMsgPtr = rqt.get_remote_msg();
426 			remoteMsgPtr->process_msg();
427 		}
428 	}
429 	else //--------- process in the order of nation recno --------//
430 	{
431 		LOG_BEGIN;
432 		for( int nationRecno=1 ; nationRecno<=nation_array.size() ; ++nationRecno )
433 		{
434 			if( nation_array.is_deleted(nationRecno) || nation_array[nationRecno]->nation_type==NATION_AI )
435 				continue;
436 
437 			nation_processing = nationRecno;
438 			processFlag=0;
439 
440 			//-------- scan through the message queue --------//
441 
442 			loopCount = 0;
443 			for( rqt.traverse_set_start(); !rqt.traverse_finish(); rqt.traverse_next() )
444 			{
445 				err_when( ++loopCount > 1000 );
446 				RemoteMsg* remoteMsgPtr = rqt.get_remote_msg();
447 
448 				//--- check if this message indicates the start of a new message queue ---//
449 
450 				if( remoteMsgPtr->id == MSG_QUEUE_HEADER )
451 				{
452 					short msgNation = *(short *)(&remoteMsgPtr->data_buf[sizeof(uint32_t)]);
453 
454 					//--- if this is the message queue of the nation we should process now ----//
455 
456 					if(msgNation==nationRecno )   // struct of data_buf: <uint32_t> frameCount + <short> nationRecno
457 					{
458 						processFlag = 1;
459 					}
460 					else  //--- if this is a message queue that should be processed now ---//
461 					{
462 						if( processFlag )  //--- if we were previously processing the right queue, now the processing is complete by this point ---//
463 							break;			// message on next nation is met, stop this nation
464 					}
465 				}
466 				else if( remoteMsgPtr->id == MSG_QUEUE_TRAILER )
467 				{
468 					short msgNation = *(short *)remoteMsgPtr->data_buf;
469 
470 					//--- if this is the message queue of the nation we should process now ----//
471 
472 					if(msgNation==nationRecno )   // struct of data_buf:<short> nationRecno
473 						break;			// end of that nation
474 				}
475 				else
476 				{
477 					//--- if this is the message queue of the nation we should process now ----//
478 
479 					if( processFlag )
480 					{
481 #if defined(DEBUG) && defined(ENABLE_LOG)
482 						String logStr("begin process remote message id:");
483 						logStr += (long) remoteMsgPtr->id;
484 						logStr += " of nation ";
485 						logStr += nation_processing;
486 						LOG_MSG(logStr);
487 #endif
488 						remoteMsgPtr->process_msg();
489 						LOG_MSG("end process remote message");
490 						LOG_MSG(misc.get_random_seed());
491 					}
492 				}
493 			}
494 			nation_processing = 0;
495 		}
496 		LOG_END;
497 	}
498 
499 	//---------- clear receive_queue[0] and shift from next queue ------//
500 	rq.clear();
501 
502 	int n;
503 	for( n = 1; n < RECEIVE_QUEUE_BACKUP; ++n)
504 	{
505 		receive_queue[n-1].swap(receive_queue[n]);
506 		receive_frame_count[n-1] = receive_frame_count[n];
507 	}
508 	receive_frame_count[n-1]++;
509 
510 	enable_poll_msg();
511 }
512 //--------- End of function Remote::process_receive_queue ---------//
513 
514 
515 //-------- Begin of function Remote::process_specific_msg ---------//
516 //
517 // Pre-process a specific message type.
518 //
process_specific_msg(uint32_t msgId)519 void Remote::process_specific_msg(uint32_t msgId)
520 {
521 	if( !process_queue_flag )			// avoid sys.yield()
522 		return;
523 
524 	int loopCount=0;
525 
526 	disable_poll_msg();
527 	RemoteQueue &rq = receive_queue[0];
528 	RemoteQueueTraverse rqt(rq);
529 
530 	if( !rq.validate_queue() )
531 		err.run( "Queue corrupted, Remote::process_specific_msg()" );
532 
533 	for( rqt.traverse_set_start(); !rqt.traverse_finish(); rqt.traverse_next() )
534 	{
535 		err_when( ++loopCount > 1000 );
536 		RemoteMsg* remoteMsgPtr = rqt.get_remote_msg();
537 		if( remoteMsgPtr->id == msgId )
538 		{
539 			remoteMsgPtr->process_msg();
540 			remoteMsgPtr->id = 0;
541 		}
542 	}
543 
544 	enable_poll_msg();
545 }
546 //--------- End of function Remote::process_specific_msg ---------//
547 
548 
549 /*
550 //-------- Begin of function Remote::validate_queue ---------//
551 //
552 // Pre-process a specific message type.
553 //
554 static int validate_queue(char* queueBuf, int queuedSize)
555 {
556    char*      queuePtr = queueBuf;
557    RemoteMsg* remoteMsgPtr;
558    int        msgSize, processedSize=0;
559    int        loopCount=0;
560 
561    while( processedSize < queuedSize )
562 	{
563 		msgSize = *((short*)queuePtr);
564 
565 		remoteMsgPtr = (RemoteMsg*) (queuePtr + sizeof(short));
566 
567 		if( remoteMsgPtr->id )
568 		{
569 			if( remoteMsgPtr->id<FIRST_REMOTE_MSG_ID || remoteMsgPtr->id>LAST_REMOTE_MSG_ID )
570 				return 0;
571 		}
572 
573 		queuePtr       += sizeof(short) + msgSize;
574 		processedSize  += sizeof(short) + msgSize;
575 
576 		err_when( loopCount++ > 10000 );    // deadloop
577 	}
578 
579 	return 1;
580 }
581 //--------- End of function Remote::validate_queue ---------//
582 */
583 
584 
585 //-------- Begin of function Remote::copy_send_to_backup ---------//
586 //
587 // Copy the whole send queue to the backup queue.
588 //
copy_send_to_backup()589 void Remote::copy_send_to_backup()
590 {
591 	// ------ shift send_queue ---------//
592 
593 	send_queue[SEND_QUEUE_BACKUP-1].clear();
594 
595 	for(int n = SEND_QUEUE_BACKUP-1; n > 1; --n)
596 	{
597 		send_queue[n].swap(send_queue[n-1]);
598 		send_frame_count[n] = send_frame_count[n-1];
599 	}
600 	// now send_queue[1] is empty.
601 
602 	send_queue[1] = send_queue[0];
603 	send_frame_count[1] = send_frame_count[0];
604 }
605 //--------- End of function Remote::copy_send_to_backup ---------//
606 
607 
608 //-------- Begin of function Remote::send_backup_now ---------//
609 //
610 // Send out the backup queue now.
611 //
612 // [DPID] receiverId - send to whom, 0 for everybody
613 //                     (default: 0)
614 //
615 // <int> requestFrameCount - need to send the backup buffer of the requested frame count
616 //
617 // return : <int> 1 - sent successfully, the message has been received
618 //                    by the receivers.
619 //                0 - not successful.
620 //
send_backup_now(uint32_t receiverId,uint32_t requestFrameCount)621 int Remote::send_backup_now(uint32_t receiverId, uint32_t requestFrameCount)
622 {
623    //------ determine which backup buffer to send -----//
624 
625 	font_san.disp( ZOOM_X2-100, 4, "", ZOOM_X2);
626 
627 	for( int n = 1; n < SEND_QUEUE_BACKUP; ++n)
628 	{
629 		if( requestFrameCount == send_frame_count[n] )
630 		{
631 			//---------- if nothing to send -------------//
632 
633 			int retFlag = 1;
634 			if( send_queue[n].length() > 0 )
635 			{
636 				if( handle_vga_lock )
637 					vga_front.temp_unlock();
638 				// retFlag = mp_ptr->send(receiverId, send_queue[n].queue_buf, send_queue[n].length());
639 				retFlag = ec_remote.send(ec_remote.get_ec_player_id(receiverId), send_queue[n].queue_buf, send_queue[n].length()) > 0;
640 				packet_send_count++;
641 				if( handle_vga_lock )
642 					vga_front.temp_restore_lock();
643 			}
644 			return retFlag;
645 		}
646 	}
647 
648 	if( requestFrameCount < send_frame_count[SEND_QUEUE_BACKUP-1])
649 		err.run( "requestFrameCount:%u < backup2_frame_count:%u", requestFrameCount, send_frame_count[SEND_QUEUE_BACKUP-1] );
650 	return 0;
651 }
652 //--------- End of function Remote::send_backup_now ---------//
653 
654 
655 //-------- Begin of function Remote::init_send_queue ---------//
656 //
657 // Initialize the header of the sending queue.
658 //
659 // <int>   frameCount  - frame count of this queue
660 // <short> nationCount - nation recno of the sender
661 //
init_send_queue(uint32_t frameCount,short nationRecno)662 void Remote::init_send_queue(uint32_t frameCount, short nationRecno)
663 {
664 	send_queue[0].clear();
665 
666 	// put into the queue : <message length>, MSG_QUEUE_HEADER, <frameCount>, <nationRecno>
667 
668 	int msgSize = sizeof(uint32_t) + sizeof(uint32_t) + sizeof(short);
669 	char *sendPtr = send_queue[0].reserve(sizeof(short) + msgSize);
670 
671 	*(short *)sendPtr = msgSize;
672 	 sendPtr += sizeof(short);
673 	*(uint32_t *)sendPtr = MSG_QUEUE_HEADER;
674 	 sendPtr += sizeof(uint32_t);
675 	*(uint32_t *)sendPtr = send_frame_count[0] = next_send_frame(nationRecno, frameCount + process_frame_delay);
676 	 sendPtr += sizeof(uint32_t);
677 	*(short *)sendPtr = nationRecno;
678 	 sendPtr += sizeof(short);
679 }
680 //--------- End of function Remote::init_send_queue ----------//
681 
682 
683 //-------- Begin of function Remote::init_receive_queue ---------//
684 //
685 // Initialize the header of the receiving queue,
686 // call this only when power is just enabled
687 //
688 // <int>   frameCount  - frame count of this queue
689 // <short> nationCount - nation recno of the receiveer
690 //
init_receive_queue(uint32_t frameCount)691 void Remote::init_receive_queue(uint32_t frameCount)
692 {
693 	int n;
694 
695 	for(n = 0; n < RECEIVE_QUEUE_BACKUP; ++n)
696 	{
697 		receive_queue[n].clear();
698 		receive_frame_count[n] = n+frameCount;
699 	}
700 
701 	for(n = 0; n < process_frame_delay; ++n)
702 	{
703 		// nations are not created yet, put MSG_QUEUE_HEADER/MSG_NEXT_FRAME and MSG_QUEUE_TRAILER
704 		// even though the nation will not exist
705 		for(short nationRecno = 1; nationRecno <= MAX_NATION; ++nationRecno)
706 		{
707 			//if( nation_array.is_deleted(nationRecno) ||
708 			//	nation_array[nationRecno]->nation_type==NATION_AI )
709 			//	continue;
710 
711 			char *receivePtr;
712 			int msgSize;
713 
714 			// put into the queue : <message length>, MSG_QUEUE_HEADER, <frameCount>, <nationRecno>
715 
716 			msgSize = sizeof(uint32_t) + sizeof(uint32_t) + sizeof(short);
717 			receivePtr = receive_queue[n].reserve(sizeof(short) + msgSize);
718 			*(short *)receivePtr = msgSize;
719 			 receivePtr += sizeof(short);
720 			*(uint32_t *)receivePtr = MSG_QUEUE_HEADER;
721 			 receivePtr += sizeof(uint32_t);
722 			*(uint32_t *)receivePtr = frameCount + n;
723 			 receivePtr += sizeof(uint32_t);
724 			*(short *)receivePtr = nationRecno;
725 			 receivePtr += sizeof(short);
726 
727 			// put into the queue : <message length>, MSG_NEXT_FRAME, <nationRecno>
728 
729 			msgSize = sizeof(uint32_t) + sizeof(short);
730 			receivePtr = receive_queue[n].reserve(sizeof(short) + msgSize);
731 
732 			*(short *)receivePtr = msgSize;
733 			 receivePtr += sizeof(short);
734 			*(uint32_t *)receivePtr = MSG_NEXT_FRAME;
735 			 receivePtr += sizeof(uint32_t);
736 			*(short *)receivePtr = nationRecno;
737 			 receivePtr += sizeof(short);
738 
739 			// put into the queue : <message length>, MSG_QUEUE_TRAILER, <nationRecno>
740 
741 			msgSize = sizeof(uint32_t) + sizeof(short);
742 			receivePtr = receive_queue[n].reserve(sizeof(short) + msgSize);
743 
744 			*(short *)receivePtr = msgSize;
745 			 receivePtr += sizeof(short);
746 			*(uint32_t *)receivePtr = MSG_QUEUE_TRAILER;
747 			 receivePtr += sizeof(uint32_t);
748 			*(short *)receivePtr = nationRecno;
749 			 receivePtr += sizeof(short);
750 
751 		}
752 	}
753 }
754 //--------- End of function Remote::init_receive_queue ----------//
755 
756 
757 //--------- Begin of function Remote::init_start_mp ----------//
init_start_mp()758 void Remote::init_start_mp()
759 {
760 	int n;
761 	for( n = 0; n < SEND_QUEUE_BACKUP; ++n)
762 	{
763 		send_queue[n].clear();
764 		send_frame_count[n] = 0;
765 	}
766 
767 	for( n = 0; n < RECEIVE_QUEUE_BACKUP; ++n)
768 	{
769 		receive_queue[n].clear();
770 		receive_frame_count[n] = 0;
771 	}
772 }
773 //--------- End of function Remote::init_start_mp ----------//
774 
775 
776 //--------- Begin of function Remote::enable_process_queue --------//
enable_process_queue()777 void Remote::enable_process_queue()
778 {
779 	process_queue_flag = 1;
780 }
781 //--------- End of function Remote::enable_process_queue --------//
782 
783 
784 //--------- Begin of function Remote::disable_process_queue --------//
disable_process_queue()785 void Remote::disable_process_queue()
786 {
787 	process_queue_flag = 0;
788 }
789 //--------- End of function Remote::disable_process_queue --------//
790 
791 
792 //-------- Begin of function Remote::enable_poll_msg ---------//
enable_poll_msg()793 void Remote::enable_poll_msg()
794 {
795 	poll_msg_flag = 1;
796 }
797 //-------- End of function Remote::enable_poll_msg ---------//
798 
799 
800 //-------- Begin of function Remote::disable_poll_msg ---------//
disable_poll_msg()801 void Remote::disable_poll_msg()
802 {
803 	poll_msg_flag = 0;
804 }
805 //-------- End of function Remote::disable_poll_msg ---------//
806