/*
** Command & Conquer Generals(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 .
*/
/*****************************************************************************
** **
** Westwood Studios Pacific. **
** **
** Confidential Information **
** Copyright (C) 2000 - All Rights Reserved **
** **
******************************************************************************
** **
** Project: Dune Emperor **
** **
** Module: (_) **
** **
** Version: $ID$ **
** **
** File name: audlists.cpp **
** **
** Created by: 04/01/95 TR **
** **
** Description: **
** **
*****************************************************************************/
/*****************************************************************************
** Includes **
*****************************************************************************/
#include
#include
// 'assignment within condition expression'.
#pragma warning(disable : 4706)
/*****************************************************************************
** Externals **
*****************************************************************************/
/*****************************************************************************
** Defines **
*****************************************************************************/
/*****************************************************************************
** Private Types **
*****************************************************************************/
/*****************************************************************************
** Private Data **
*****************************************************************************/
/*****************************************************************************
** Public Data **
*****************************************************************************/
/*****************************************************************************
** Private Prototypes **
*****************************************************************************/
/*****************************************************************************
** Private Functions **
*****************************************************************************/
/*****************************************************************************
** Public Functions **
*****************************************************************************/
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListInit ( ListHead *head )
{
head->prev = head->next = head;
head->pri = (Priority) head; // this identifies the node as a head node
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListNodeInit ( ListNode *node )
{
node->prev = node->next= node;
node->pri = 0;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int ListAddNodeSortAscending( ListHead *head, ListNode *new_node )
{
ListNode *node;
Priority pri;
int index;
index = 0;
pri = new_node->pri;
node = (ListNode*) head;
while( (node = ListNodeNext ( node )))
{
if ( pri <= node->pri )
{
ListNodeInsert ( node, new_node );
return index;
}
index++;
}
ListNodeInsert ( head, new_node );
return index;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListAddNode( ListHead *head, ListNode *new_node )
{
ListNode *node;
Priority pri;
pri = new_node->pri;
node = (ListNode*) head;
while( (node = ListNodeNext ( node )))
{
if (node->pri <= pri )
{
ListNodeInsert ( node, new_node );
return;
}
}
ListNodeInsert ( head, new_node );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListAddNodeAfter( ListHead *head, ListNode *new_node )
{
ListNode *node;
Priority pri;
pri = new_node->pri;
node = (ListNode*) head;
while( (node = ListNodeNext ( node )))
{
if (node->pri < pri )
{
ListNodeInsert ( node, new_node );
return;
}
}
ListNodeInsert ( head, new_node );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListMerge( ListHead *from, ListHead *to )
{
ListNode *first,
*last,
*node;
first = from->next;
last = from->prev;
if ( first == (ListNode*) from )
{
/* the from list is empty so there is nothing to do */
return;
}
node = to->prev;
node->next = first;
first->prev = node;
last->next = (ListNode*) to;
to->prev = last;
ListInit ( from ); /* make the from list empty now */
}
/******************************************************************/
/* */
/* */
/******************************************************************/
int ListCountItems ( ListHead *head )
{
ListNode *node;
int count = 0;
node = head->next;
while(node!=(ListNode*)head)
{
count++;
node = node->next;
}
return count;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
ListNode* ListFirstItem ( ListHead *head )
{
return ListNextItem ((ListNode*) head );
}
/******************************************************************/
/* */
/* */
/******************************************************************/
ListNode* ListNextItem ( ListNode *node )
{
if ( !node )
{
return NULL;
}
return ( ListNodeNext ( node ));
}
/******************************************************************/
/* */
/* */
/******************************************************************/
ListNode* ListGetItem( ListHead *head, int number )
{
ListNode *node;
node = head->next;
while( node != (ListNode*) head )
{
if ( number-- == 0 )
{
return node;
}
node = node->next;
}
return NULL;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListNodeInsert( ListNode *node, ListNode *new_node )
{
new_node->prev = node->prev;
new_node->next = node;
node->prev = new_node;
new_node->prev->next = new_node;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListNodeAppend( ListNode *node, ListNode *new_node )
{
new_node->prev = node;
new_node->next = node->next;
node->next = new_node;
new_node->next->prev = new_node;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
void ListNodeRemove( ListNode *node )
{
node->prev->next = node->next;
node->next->prev = node->prev;
node->prev = node->next = node; // so we know that the node is not in a list
}
/******************************************************************/
/* */
/* */
/******************************************************************/
ListNode* ListNodeNext( ListNode *node )
{
ListNode *next;
next = node->next;
if ( next && ListNodeIsHead ( next ))
{
return NULL;
}
return next;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
ListNode* ListNodePrev (ListNode *node)
{
ListNode *next;
next = node->prev;
if ( ListNodeIsHead ( next ))
{
return NULL;
}
return next;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
ListNode* ListNodeLoopNext (ListNode *node)
{
ListNode *next;
next = node->next;
if ( ListNodeIsHead ( next ))
{
// skip head node
next = next->next;
if ( ListNodeIsHead ( next ))
{
return NULL; // it is an empty list
}
}
return next;
}
/******************************************************************/
/* */
/* */
/******************************************************************/
ListNode* ListNodeLoopPrev (ListNode *node)
{
ListNode *next;
next = node->prev;
if ( ListNodeIsHead ( next ))
{
// skip head node
next = next->prev;
if ( ListNodeIsHead ( next ))
{
return NULL; // it is an empty list
}
}
return next;
}